project-graph-mcp 2.3.1 → 2.4.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 (226) hide show
  1. package/package.json +3 -2
  2. package/src/analysis/analysis-cache.ctx +9 -0
  3. package/src/analysis/analysis-cache.js +1 -1
  4. package/src/analysis/complexity.ctx +6 -0
  5. package/src/analysis/complexity.js +1 -1
  6. package/src/analysis/custom-rules.ctx +14 -0
  7. package/src/analysis/custom-rules.js +1 -1
  8. package/src/analysis/db-analysis.ctx +7 -0
  9. package/src/analysis/db-analysis.js +1 -1
  10. package/src/analysis/dead-code.ctx +6 -0
  11. package/src/analysis/dead-code.js +1 -1
  12. package/src/analysis/full-analysis.ctx +9 -0
  13. package/src/analysis/full-analysis.js +1 -1
  14. package/src/analysis/jsdoc-checker.ctx +10 -0
  15. package/src/analysis/jsdoc-checker.js +1 -1
  16. package/src/analysis/jsdoc-generator.ctx +9 -0
  17. package/src/analysis/jsdoc-generator.js +1 -1
  18. package/src/analysis/large-files.ctx +6 -0
  19. package/src/analysis/large-files.js +1 -1
  20. package/src/analysis/outdated-patterns.ctx +7 -0
  21. package/src/analysis/outdated-patterns.js +1 -1
  22. package/src/analysis/similar-functions.ctx +6 -0
  23. package/src/analysis/similar-functions.js +1 -1
  24. package/src/analysis/test-annotations.ctx +11 -0
  25. package/src/analysis/test-annotations.js +1 -1
  26. package/src/analysis/type-checker.ctx +6 -0
  27. package/src/analysis/type-checker.js +1 -1
  28. package/src/analysis/undocumented.ctx +8 -0
  29. package/src/analysis/undocumented.js +1 -1
  30. package/src/cli/cli-handlers.ctx +7 -0
  31. package/src/cli/cli-handlers.js +1 -1
  32. package/src/cli/cli.ctx +6 -0
  33. package/src/cli/cli.js +1 -1
  34. package/src/compact/ai-context.ctx +6 -0
  35. package/src/compact/ai-context.js +1 -1
  36. package/src/compact/compact-migrate.ctx +8 -0
  37. package/src/compact/compact-migrate.js +1 -1
  38. package/src/compact/compact.ctx +11 -0
  39. package/src/compact/compact.js +1 -1
  40. package/src/compact/compress.ctx +7 -0
  41. package/src/compact/compress.js +1 -1
  42. package/src/compact/ctx-resolver.ctx +2 -0
  43. package/src/compact/ctx-resolver.js +1 -1
  44. package/src/compact/ctx-to-jsdoc.ctx +11 -0
  45. package/src/compact/ctx-to-jsdoc.js +1 -1
  46. package/src/compact/doc-dialect.ctx +11 -0
  47. package/src/compact/doc-dialect.js +2 -2
  48. package/src/compact/expand.ctx +14 -0
  49. package/src/compact/expand.js +1 -1
  50. package/src/compact/framework-references.ctx +7 -0
  51. package/src/compact/framework-references.js +1 -1
  52. package/src/compact/instructions.ctx +6 -0
  53. package/src/compact/instructions.js +1 -1
  54. package/src/compact/jsdoc-builder.ctx +4 -0
  55. package/src/compact/jsdoc-builder.js +1 -1
  56. package/src/compact/mode-config.ctx +8 -0
  57. package/src/compact/mode-config.js +1 -1
  58. package/src/compact/split-declarations.ctx +6 -0
  59. package/src/compact/split-declarations.js +1 -1
  60. package/src/compact/validate-pipeline.ctx +12 -0
  61. package/src/compact/validate-pipeline.js +1 -1
  62. package/src/core/event-bus.ctx +9 -0
  63. package/src/core/event-bus.js +1 -1
  64. package/src/core/file-walker.ctx +1 -0
  65. package/src/core/file-walker.js +1 -1
  66. package/src/core/filters.ctx +12 -0
  67. package/src/core/filters.js +1 -1
  68. package/src/core/graph-builder.ctx +7 -0
  69. package/src/core/graph-builder.js +1 -1
  70. package/src/core/parser.ctx +12 -0
  71. package/src/core/parser.js +1 -1
  72. package/src/core/utils.ctx +1 -0
  73. package/src/core/utils.js +1 -1
  74. package/src/core/workspace.ctx +7 -0
  75. package/src/core/workspace.js +1 -1
  76. package/src/lang/lang-go.ctx +8 -0
  77. package/src/lang/lang-go.js +1 -1
  78. package/src/lang/lang-python.ctx +5 -0
  79. package/src/lang/lang-python.js +1 -1
  80. package/src/lang/lang-sql.ctx +10 -0
  81. package/src/lang/lang-sql.js +1 -1
  82. package/src/lang/lang-typescript.ctx +6 -0
  83. package/src/lang/lang-typescript.js +1 -1
  84. package/src/lang/lang-utils.ctx +5 -0
  85. package/src/lang/lang-utils.js +1 -1
  86. package/src/mcp/mcp-server.ctx +6 -0
  87. package/src/mcp/mcp-server.js +1 -1
  88. package/src/mcp/tool-defs.ctx +2 -0
  89. package/src/mcp/tool-defs.js +1 -1
  90. package/src/mcp/tools.ctx +13 -0
  91. package/src/mcp/tools.js +1 -1
  92. package/src/network/backend-lifecycle.ctx +10 -0
  93. package/src/network/backend-lifecycle.js +1 -1
  94. package/src/network/backend.ctx +5 -0
  95. package/src/network/backend.js +1 -1
  96. package/src/network/local-gateway.ctx +9 -0
  97. package/src/network/local-gateway.js +1 -1
  98. package/src/network/mdns.ctx +6 -0
  99. package/src/network/mdns.js +1 -1
  100. package/src/network/server.ctx +2 -0
  101. package/src/network/server.js +2 -2
  102. package/src/network/web-server.ctx +17 -0
  103. package/src/network/web-server.js +2 -2
  104. package/web/follow-controller.js +94 -25
  105. package/web/panels/dep-graph.js +207 -21
  106. package/project-graph-mcp-2.3.0.tgz +0 -0
  107. package/vendor/symbiote-node/CHANGELOG.md +0 -31
  108. package/vendor/symbiote-node/LICENSE +0 -21
  109. package/vendor/symbiote-node/README.md +0 -206
  110. package/vendor/symbiote-node/canvas/AutoLayout.js +0 -725
  111. package/vendor/symbiote-node/canvas/Breadcrumb/Breadcrumb.css.js +0 -73
  112. package/vendor/symbiote-node/canvas/Breadcrumb/Breadcrumb.js +0 -93
  113. package/vendor/symbiote-node/canvas/Breadcrumb/Breadcrumb.tpl.js +0 -9
  114. package/vendor/symbiote-node/canvas/CanvasConnectionRenderer.js +0 -962
  115. package/vendor/symbiote-node/canvas/ConnectionRenderer.js +0 -1468
  116. package/vendor/symbiote-node/canvas/FlowSimulator.js +0 -323
  117. package/vendor/symbiote-node/canvas/ForceLayout.js +0 -189
  118. package/vendor/symbiote-node/canvas/ForceWorker.js +0 -1325
  119. package/vendor/symbiote-node/canvas/GraphTabs/GraphTabs.css.js +0 -97
  120. package/vendor/symbiote-node/canvas/GraphTabs/GraphTabs.js +0 -176
  121. package/vendor/symbiote-node/canvas/GraphTabs/GraphTabs.tpl.js +0 -12
  122. package/vendor/symbiote-node/canvas/LODManager.js +0 -88
  123. package/vendor/symbiote-node/canvas/Minimap/Minimap.css.js +0 -71
  124. package/vendor/symbiote-node/canvas/Minimap/Minimap.js +0 -207
  125. package/vendor/symbiote-node/canvas/Minimap/Minimap.tpl.js +0 -9
  126. package/vendor/symbiote-node/canvas/NodeCanvas/NodeCanvas.css.js +0 -261
  127. package/vendor/symbiote-node/canvas/NodeCanvas/NodeCanvas.js +0 -1840
  128. package/vendor/symbiote-node/canvas/NodeCanvas/NodeCanvas.tpl.js +0 -22
  129. package/vendor/symbiote-node/canvas/NodeSearch/NodeSearch.css.js +0 -97
  130. package/vendor/symbiote-node/canvas/NodeSearch/NodeSearch.js +0 -132
  131. package/vendor/symbiote-node/canvas/NodeSearch/NodeSearch.tpl.js +0 -21
  132. package/vendor/symbiote-node/canvas/NodeViewManager.js +0 -584
  133. package/vendor/symbiote-node/canvas/PinExpansion.js +0 -131
  134. package/vendor/symbiote-node/canvas/PseudoConnection.js +0 -80
  135. package/vendor/symbiote-node/canvas/SubgraphManager.js +0 -201
  136. package/vendor/symbiote-node/canvas/SubgraphRouter.js +0 -443
  137. package/vendor/symbiote-node/canvas/ViewportActions.js +0 -446
  138. package/vendor/symbiote-node/core/Connection.js +0 -45
  139. package/vendor/symbiote-node/core/Editor.js +0 -451
  140. package/vendor/symbiote-node/core/Frame.js +0 -31
  141. package/vendor/symbiote-node/core/GraphMermaid.js +0 -348
  142. package/vendor/symbiote-node/core/GraphText.js +0 -210
  143. package/vendor/symbiote-node/core/Node.js +0 -143
  144. package/vendor/symbiote-node/core/Portal.js +0 -104
  145. package/vendor/symbiote-node/core/Socket.js +0 -185
  146. package/vendor/symbiote-node/core/SubgraphNode.js +0 -125
  147. package/vendor/symbiote-node/index.js +0 -103
  148. package/vendor/symbiote-node/inspector/InspectorPanel/InspectorPanel.css.js +0 -361
  149. package/vendor/symbiote-node/inspector/InspectorPanel/InspectorPanel.js +0 -332
  150. package/vendor/symbiote-node/inspector/InspectorPanel/InspectorPanel.tpl.js +0 -96
  151. package/vendor/symbiote-node/inspector/TemplatePreview/TemplatePreview.css.js +0 -104
  152. package/vendor/symbiote-node/inspector/TemplatePreview/TemplatePreview.js +0 -133
  153. package/vendor/symbiote-node/inspector/TemplatePreview/TemplatePreview.tpl.js +0 -33
  154. package/vendor/symbiote-node/interactions/ConnectFlow.js +0 -307
  155. package/vendor/symbiote-node/interactions/Drag.js +0 -102
  156. package/vendor/symbiote-node/interactions/Selector.js +0 -132
  157. package/vendor/symbiote-node/interactions/SnapGrid.js +0 -65
  158. package/vendor/symbiote-node/interactions/Zoom.js +0 -140
  159. package/vendor/symbiote-node/layout/ActionZone/ActionZone.css.js +0 -88
  160. package/vendor/symbiote-node/layout/ActionZone/ActionZone.js +0 -254
  161. package/vendor/symbiote-node/layout/ActionZone/ActionZone.tpl.js +0 -11
  162. package/vendor/symbiote-node/layout/Layout/Layout.css.js +0 -88
  163. package/vendor/symbiote-node/layout/Layout/Layout.js +0 -622
  164. package/vendor/symbiote-node/layout/Layout/Layout.tpl.js +0 -25
  165. package/vendor/symbiote-node/layout/LayoutNode/LayoutNode.css.js +0 -293
  166. package/vendor/symbiote-node/layout/LayoutNode/LayoutNode.js +0 -467
  167. package/vendor/symbiote-node/layout/LayoutNode/LayoutNode.tpl.js +0 -33
  168. package/vendor/symbiote-node/layout/LayoutPreview/LayoutPreview.css.js +0 -46
  169. package/vendor/symbiote-node/layout/LayoutPreview/LayoutPreview.js +0 -102
  170. package/vendor/symbiote-node/layout/LayoutPreview/LayoutPreview.tpl.js +0 -6
  171. package/vendor/symbiote-node/layout/LayoutRouter/LayoutRouter.js +0 -156
  172. package/vendor/symbiote-node/layout/LayoutRouter/routerSync.js +0 -250
  173. package/vendor/symbiote-node/layout/LayoutSidebar/LayoutSidebar.css.js +0 -379
  174. package/vendor/symbiote-node/layout/LayoutSidebar/LayoutSidebar.js +0 -263
  175. package/vendor/symbiote-node/layout/LayoutSidebar/LayoutSidebar.tpl.js +0 -20
  176. package/vendor/symbiote-node/layout/LayoutSidebar/SidebarSection.js +0 -183
  177. package/vendor/symbiote-node/layout/LayoutTree.js +0 -246
  178. package/vendor/symbiote-node/layout/PanelMenu/PanelMenu.css.js +0 -43
  179. package/vendor/symbiote-node/layout/PanelMenu/PanelMenu.js +0 -89
  180. package/vendor/symbiote-node/layout/PanelMenu/PanelMenu.tpl.js +0 -14
  181. package/vendor/symbiote-node/layout/index.js +0 -16
  182. package/vendor/symbiote-node/menu/ContextMenu/ContextMenu.css.js +0 -61
  183. package/vendor/symbiote-node/menu/ContextMenu/ContextMenu.js +0 -79
  184. package/vendor/symbiote-node/menu/ContextMenu/ContextMenu.tpl.js +0 -19
  185. package/vendor/symbiote-node/node/CtrlItem/CtrlItem.css.js +0 -41
  186. package/vendor/symbiote-node/node/CtrlItem/CtrlItem.js +0 -24
  187. package/vendor/symbiote-node/node/CtrlItem/CtrlItem.tpl.js +0 -16
  188. package/vendor/symbiote-node/node/GraphFrame/GraphFrame.css.js +0 -65
  189. package/vendor/symbiote-node/node/GraphFrame/GraphFrame.js +0 -29
  190. package/vendor/symbiote-node/node/GraphFrame/GraphFrame.tpl.js +0 -13
  191. package/vendor/symbiote-node/node/GraphNode/GraphNode.css.js +0 -683
  192. package/vendor/symbiote-node/node/GraphNode/GraphNode.js +0 -92
  193. package/vendor/symbiote-node/node/GraphNode/GraphNode.tpl.js +0 -17
  194. package/vendor/symbiote-node/node/NodeSocket/NodeSocket.js +0 -25
  195. package/vendor/symbiote-node/node/NodeSocket/NodeSocket.tpl.js +0 -7
  196. package/vendor/symbiote-node/node/PortItem/PortItem.css.js +0 -90
  197. package/vendor/symbiote-node/node/PortItem/PortItem.js +0 -87
  198. package/vendor/symbiote-node/node/PortItem/PortItem.tpl.js +0 -10
  199. package/vendor/symbiote-node/package.json +0 -59
  200. package/vendor/symbiote-node/palette/PaletteBrowser/PaletteBrowser.css.js +0 -143
  201. package/vendor/symbiote-node/palette/PaletteBrowser/PaletteBrowser.js +0 -131
  202. package/vendor/symbiote-node/palette/PaletteBrowser/PaletteBrowser.tpl.js +0 -16
  203. package/vendor/symbiote-node/plugins/History.js +0 -384
  204. package/vendor/symbiote-node/plugins/Readonly.js +0 -59
  205. package/vendor/symbiote-node/shapes/CircleShape.js +0 -80
  206. package/vendor/symbiote-node/shapes/CommentShape.js +0 -35
  207. package/vendor/symbiote-node/shapes/DiamondShape.js +0 -115
  208. package/vendor/symbiote-node/shapes/NodeShape.js +0 -80
  209. package/vendor/symbiote-node/shapes/PillShape.js +0 -91
  210. package/vendor/symbiote-node/shapes/RectShape.js +0 -72
  211. package/vendor/symbiote-node/shapes/SVGShape.js +0 -494
  212. package/vendor/symbiote-node/shapes/index.js +0 -53
  213. package/vendor/symbiote-node/themes/Palette.js +0 -32
  214. package/vendor/symbiote-node/themes/Skin.js +0 -113
  215. package/vendor/symbiote-node/themes/Theme.js +0 -84
  216. package/vendor/symbiote-node/themes/carbon.js +0 -137
  217. package/vendor/symbiote-node/themes/dark.js +0 -137
  218. package/vendor/symbiote-node/themes/ebook.js +0 -138
  219. package/vendor/symbiote-node/themes/grey.js +0 -137
  220. package/vendor/symbiote-node/themes/light.js +0 -137
  221. package/vendor/symbiote-node/themes/neon.js +0 -138
  222. package/vendor/symbiote-node/themes/pcb.js +0 -273
  223. package/vendor/symbiote-node/themes/synthwave.js +0 -137
  224. package/vendor/symbiote-node/toolbar/QuickToolbar/QuickToolbar.css.js +0 -86
  225. package/vendor/symbiote-node/toolbar/QuickToolbar/QuickToolbar.js +0 -128
  226. package/vendor/symbiote-node/toolbar/QuickToolbar/QuickToolbar.tpl.js +0 -29
@@ -1,183 +0,0 @@
1
- /**
2
- * SidebarSection — itemize sub-component for sidebar section items
3
- *
4
- * Renders a master panel entry with icon, label.
5
- * Edit mode: shows visibility toggle + drag handle.
6
- * Shows sub-panel list with close buttons for non-master panels.
7
- *
8
- * @module symbiote-node/layout/LayoutSidebar/SidebarSection
9
- */
10
- import Symbiote, { html } from '@symbiotejs/symbiote';
11
- import { navigate } from '../LayoutRouter/LayoutRouter.js';
12
-
13
- export class SidebarSection extends Symbiote {
14
- isoMode = true;
15
-
16
- init$ = {
17
- sectionId: '',
18
- icon: 'dashboard',
19
- label: '',
20
- isActive: false,
21
- isVisible: true,
22
- isDisabled: false,
23
- eyeIcon: 'visibility',
24
- hasSubPanels: false,
25
- isExpanded: false,
26
- subPanels: [],
27
-
28
- onSectionClick: () => {
29
- if (!this.$.isVisible || this.$.isDisabled) return;
30
- navigate(this.$.sectionId);
31
- },
32
-
33
- onExpandToggle: (e) => {
34
- e.stopPropagation();
35
- if (!this.$.hasSubPanels) return;
36
- this.$.isExpanded = !this.$.isExpanded;
37
- },
38
-
39
- onToggleVisibility: (e) => {
40
- e.stopPropagation();
41
- const sidebar = this.closest('layout-sidebar');
42
- if (sidebar) sidebar.toggleVisibility(this.$.sectionId);
43
- },
44
- };
45
-
46
- renderCallback() {
47
- this.sub('isActive', (val) => {
48
- this.toggleAttribute('data-active', val);
49
- });
50
-
51
- this.sub('isExpanded', (val) => {
52
- this.toggleAttribute('data-expanded', val);
53
- });
54
-
55
- this.sub('isVisible', (val) => {
56
- this.toggleAttribute('data-hidden', !val);
57
- this.$.eyeIcon = val ? 'visibility' : 'visibility_off';
58
- });
59
-
60
- this.sub('isDisabled', (val) => {
61
- this.toggleAttribute('data-disabled', val);
62
- });
63
-
64
- this.sub('subPanels', (panels) => {
65
- const has = panels && panels.length > 0;
66
- this.$.hasSubPanels = has;
67
- this.toggleAttribute('data-has-sub', has);
68
- // Collapse if no sub-panels
69
- if (!has) this.$.isExpanded = false;
70
- });
71
-
72
- // Drag support
73
- this.setAttribute('draggable', 'true');
74
-
75
- this.addEventListener('dragstart', (e) => {
76
- const sidebar = this.closest('layout-sidebar');
77
- if (!sidebar?.hasAttribute('edit-mode')) {
78
- e.preventDefault();
79
- return;
80
- }
81
- const sections = Array.from(this.parentElement.children);
82
- const idx = sections.indexOf(this);
83
- e.dataTransfer.setData('text/plain', String(idx));
84
- e.dataTransfer.effectAllowed = 'move';
85
- this.setAttribute('data-dragging', '');
86
- });
87
-
88
- this.addEventListener('dragend', () => {
89
- this.removeAttribute('data-dragging');
90
- });
91
-
92
- this.addEventListener('dragover', (e) => {
93
- const sidebar = this.closest('layout-sidebar');
94
- if (!sidebar?.hasAttribute('edit-mode')) return;
95
- e.preventDefault();
96
- e.dataTransfer.dropEffect = 'move';
97
- this.setAttribute('data-dragover', '');
98
- });
99
-
100
- this.addEventListener('dragleave', () => {
101
- this.removeAttribute('data-dragover');
102
- });
103
-
104
- this.addEventListener('drop', (e) => {
105
- e.preventDefault();
106
- this.removeAttribute('data-dragover');
107
- const sidebar = this.closest('layout-sidebar');
108
- if (!sidebar?.hasAttribute('edit-mode')) return;
109
-
110
- const fromIdx = parseInt(e.dataTransfer.getData('text/plain'), 10);
111
- const sections = Array.from(this.parentElement.children);
112
- const toIdx = sections.indexOf(this);
113
- if (fromIdx !== toIdx) {
114
- sidebar.moveSection(fromIdx, toIdx);
115
- }
116
- });
117
- }
118
- }
119
-
120
- SidebarSection.template = html`
121
- <div class="sec-drag-handle">
122
- <span class="material-symbols-outlined">drag_indicator</span>
123
- </div>
124
- <div class="sec-item" ${{ onclick: 'onSectionClick' }}>
125
- <span class="material-symbols-outlined sec-icon" ${{ textContent: 'icon' }}></span>
126
- <span class="sec-label" ${{ textContent: 'label' }}></span>
127
- <span class="material-symbols-outlined sec-expand" ${{ onclick: 'onExpandToggle' }}>chevron_right</span>
128
- </div>
129
- <button class="sec-eye" ${{ onclick: 'onToggleVisibility' }}>
130
- <span class="material-symbols-outlined" ${{ textContent: 'eyeIcon' }}></span>
131
- </button>
132
- <div class="sec-sub-panels" itemize="subPanels" item-tag="sidebar-sub-item"></div>
133
- `;
134
-
135
- SidebarSection.reg('sidebar-section');
136
-
137
- /**
138
- * SidebarSubItem — sub-panel entry inside a section
139
- * Shows close button for non-master panels (isMaster=false)
140
- */
141
- export class SidebarSubItem extends Symbiote {
142
- isoMode = true;
143
-
144
- init$ = {
145
- title: '',
146
- icon: 'web_asset',
147
- panelId: '',
148
- isMaster: false,
149
-
150
- onClose: (e) => {
151
- e.stopPropagation();
152
- const panelId = this.$.panelId;
153
- if (!panelId) return;
154
-
155
- // Find the panel-layout and call joinPanels
156
- const sidebar = this.closest('layout-sidebar');
157
- if (sidebar) {
158
- sidebar.dispatchEvent(new CustomEvent('panel-close', {
159
- bubbles: true,
160
- detail: { panelId },
161
- }));
162
- }
163
- },
164
- };
165
-
166
- renderCallback() {
167
- this.sub('isMaster', (val) => {
168
- this.toggleAttribute('data-master', val);
169
- });
170
- }
171
- }
172
-
173
- SidebarSubItem.template = html`
174
- <div class="sub-panel-item">
175
- <span class="material-symbols-outlined" ${{ textContent: 'icon' }}></span>
176
- <span ${{ textContent: 'title' }}></span>
177
- <button class="sub-panel-close" ${{ onclick: 'onClose' }}>
178
- <span class="material-symbols-outlined">close</span>
179
- </button>
180
- </div>
181
- `;
182
-
183
- SidebarSubItem.reg('sidebar-sub-item');
@@ -1,246 +0,0 @@
1
- /**
2
- * @fileoverview BSP (Binary Space Partitioning) Layout Tree
3
- * Implements Blender-style area splitting/joining mechanics.
4
- */
5
-
6
- /**
7
- * @typedef {'horizontal' | 'vertical'} SplitDirection
8
- */
9
-
10
- /**
11
- * @typedef {Object} PanelNode
12
- * @property {string} id - Unique node ID
13
- * @property {'panel'} type - Node type
14
- * @property {string} panelType - Panel content type (e.g., 'viewport', 'timeline')
15
- * @property {boolean} [collapsed] - Whether panel is collapsed
16
- * @property {Object} [panelState] - Panel-specific state
17
- */
18
-
19
- /**
20
- * @typedef {Object} SplitNode
21
- * @property {string} id - Unique node ID
22
- * @property {'split'} type - Node type
23
- * @property {SplitDirection} direction - Split direction
24
- * @property {number} ratio - Split ratio (0-1), size of first child
25
- * @property {LayoutNode} first - First child node
26
- * @property {LayoutNode} second - Second child node
27
- */
28
-
29
- /**
30
- * @typedef {PanelNode | SplitNode} LayoutNode
31
- */
32
-
33
- let idCounter = 0;
34
-
35
- /**
36
- * Generate unique node ID
37
- * @returns {string}
38
- */
39
- export function generateId() {
40
- return `node_${++idCounter}_${Date.now().toString(36)}`;
41
- }
42
-
43
- /**
44
- * Create a panel node
45
- * @param {string} panelType - Panel content type
46
- * @param {Object} [panelState] - Initial panel state
47
- * @returns {PanelNode}
48
- */
49
- export function createPanel(panelType, panelState = {}) {
50
- return {
51
- id: generateId(),
52
- type: 'panel',
53
- panelType,
54
- panelState,
55
- collapsed: false
56
- };
57
- }
58
-
59
- /**
60
- * Create a split node
61
- * @param {SplitDirection} direction - Split direction
62
- * @param {LayoutNode} first - First child
63
- * @param {LayoutNode} second - Second child
64
- * @param {number} [ratio=0.5] - Split ratio
65
- * @returns {SplitNode}
66
- */
67
- export function createSplit(direction, first, second, ratio = 0.5) {
68
- return {
69
- id: generateId(),
70
- type: 'split',
71
- direction,
72
- ratio,
73
- first,
74
- second
75
- };
76
- }
77
-
78
- /**
79
- * Find a node by ID in the tree
80
- * @param {LayoutNode} root - Root node
81
- * @param {string} id - Node ID to find
82
- * @returns {LayoutNode | null}
83
- */
84
- export function findNode(root, id) {
85
- if (root.id === id) return root;
86
- if (root.type === 'split') {
87
- return findNode(root.first, id) || findNode(root.second, id);
88
- }
89
- return null;
90
- }
91
-
92
- /**
93
- * Find parent of a node
94
- * @param {LayoutNode} root - Root node
95
- * @param {string} id - Child node ID
96
- * @returns {{ parent: SplitNode, which: 'first' | 'second' } | null}
97
- */
98
- export function findParent(root, id) {
99
- if (root.type !== 'split') return null;
100
-
101
- if (root.first.id === id) return { parent: root, which: 'first' };
102
- if (root.second.id === id) return { parent: root, which: 'second' };
103
-
104
- return findParent(root.first, id) || findParent(root.second, id);
105
- }
106
-
107
- /**
108
- * Split a panel into two
109
- * @param {LayoutNode} root - Root node
110
- * @param {string} panelId - Panel ID to split
111
- * @param {SplitDirection} direction - Split direction
112
- * @param {number} [ratio=0.5] - Split ratio
113
- * @param {string} [newPanelType] - Type for new panel (defaults to same as original)
114
- * @returns {LayoutNode} - New root node
115
- */
116
- export function splitPanel(root, panelId, direction, ratio = 0.5, newPanelType) {
117
- const node = findNode(root, panelId);
118
- if (!node || node.type !== 'panel') {
119
- console.warn(`Cannot split: panel ${panelId} not found`);
120
- return root;
121
- }
122
-
123
- const newPanel = createPanel(newPanelType || node.panelType);
124
- const splitNode = createSplit(direction, node, newPanel, ratio);
125
-
126
- // If splitting the root
127
- if (root.id === panelId) {
128
- return splitNode;
129
- }
130
-
131
- // Find parent and replace
132
- const parentInfo = findParent(root, panelId);
133
- if (parentInfo) {
134
- parentInfo.parent[parentInfo.which] = splitNode;
135
- }
136
-
137
- return root;
138
- }
139
-
140
- /**
141
- * Join two panels (remove one panel and its parent split)
142
- * @param {LayoutNode} root - Root node
143
- * @param {string} panelToRemove - Panel ID to remove
144
- * @returns {LayoutNode} - New root node
145
- */
146
- export function joinPanels(root, panelToRemove) {
147
- const parentInfo = findParent(root, panelToRemove);
148
- if (!parentInfo) {
149
- // Trying to remove root - not allowed
150
- console.warn('Cannot join: panel is root');
151
- return root;
152
- }
153
-
154
- const { parent, which } = parentInfo;
155
- const survivor = which === 'first' ? parent.second : parent.first;
156
-
157
- // If parent is root, survivor becomes new root
158
- const grandparentInfo = findParent(root, parent.id);
159
- if (!grandparentInfo) {
160
- return survivor;
161
- }
162
-
163
- // Replace parent with survivor in grandparent
164
- grandparentInfo.parent[grandparentInfo.which] = survivor;
165
- return root;
166
- }
167
-
168
- /**
169
- * Update split ratio
170
- * @param {LayoutNode} root - Root node
171
- * @param {string} splitId - Split node ID
172
- * @param {number} ratio - New ratio (0-1)
173
- * @returns {LayoutNode} - Same root (mutated)
174
- */
175
- export function resizeSplit(root, splitId, ratio) {
176
- const node = findNode(root, splitId);
177
- if (!node || node.type !== 'split') {
178
- console.warn(`Cannot resize: split ${splitId} not found`);
179
- return root;
180
- }
181
-
182
- node.ratio = Math.max(0.1, Math.min(0.9, ratio));
183
- return root;
184
- }
185
-
186
- /**
187
- * Serialize layout to JSON string
188
- * @param {LayoutNode} root - Root node
189
- * @returns {string}
190
- */
191
- export function serialize(root) {
192
- return JSON.stringify(root);
193
- }
194
-
195
- /**
196
- * Deserialize layout from JSON string
197
- * @param {string} json - JSON string
198
- * @returns {LayoutNode}
199
- */
200
- export function deserialize(json) {
201
- return JSON.parse(json);
202
- }
203
-
204
- /**
205
- * Clone a layout tree (deep copy)
206
- * @param {LayoutNode} root - Root node
207
- * @returns {LayoutNode}
208
- */
209
- export function clone(root) {
210
- return deserialize(serialize(root));
211
- }
212
-
213
- /**
214
- * Get all panel nodes in tree
215
- * @param {LayoutNode} root - Root node
216
- * @returns {PanelNode[]}
217
- */
218
- export function getAllPanels(root) {
219
- if (root.type === 'panel') return [root];
220
- return [...getAllPanels(root.first), ...getAllPanels(root.second)];
221
- }
222
-
223
- /**
224
- * Update a node's properties by ID
225
- * @param {LayoutNode} root - Root node
226
- * @param {string} nodeId - Node ID to update
227
- * @param {Object} updates - Properties to update
228
- * @returns {boolean} - True if node was found and updated
229
- */
230
- export function updateNode(root, nodeId, updates) {
231
- const node = findNode(root, nodeId);
232
- if (!node) return false;
233
- Object.assign(node, updates);
234
- return true;
235
- }
236
-
237
- /**
238
- * Get neighbor panel IDs for a panel
239
- * @param {LayoutNode} root - Root node
240
- * @param {string} panelId - Panel ID
241
- * @returns {{ left?: string, right?: string, top?: string, bottom?: string }}
242
- */
243
- export function getNeighbors(root, panelId) {
244
- // TODO: Implement neighbor detection for join preview
245
- return {};
246
- }
@@ -1,43 +0,0 @@
1
- import { css } from '@symbiotejs/symbiote';
2
-
3
- export const styles = css`
4
- panel-menu {
5
- position: fixed;
6
- z-index: 1000;
7
- pointer-events: none;
8
-
9
- .menu-container {
10
- pointer-events: auto;
11
- background: var(--bg-popup, #2a2a2a);
12
- border: 1px solid var(--border-popup, #444);
13
- border-radius: 6px;
14
- box-shadow: 0 4px 12px var(--sn-shadow-color, rgba(0, 0, 0, 0.4));
15
- min-width: 160px;
16
- padding: 4px 0;
17
- }
18
-
19
- .menu-item {
20
- display: flex;
21
- align-items: center;
22
- gap: 8px;
23
- padding: 8px 12px;
24
- cursor: pointer;
25
- color: var(--text-main, #e0e0e0);
26
- font-size: 0.85rem;
27
- transition: background 0.1s;
28
-
29
- &:hover {
30
- background: var(--bg-hover, #3a3a3a);
31
- }
32
-
33
- &[active] {
34
- color: var(--accent, #4a9eff);
35
- }
36
-
37
- .material-symbols-outlined {
38
- font-size: 18px;
39
- opacity: 0.8;
40
- }
41
- }
42
- }
43
- `;
@@ -1,89 +0,0 @@
1
- /**
2
- * @fileoverview PanelMenu - Dropdown menu for panel type selection
3
- */
4
-
5
- import Symbiote from '@symbiotejs/symbiote';
6
- import { template } from './PanelMenu.tpl.js';
7
- import { styles } from './PanelMenu.css.js';
8
-
9
- export class PanelMenu extends Symbiote {
10
- static isoMode = true;
11
-
12
- init$ = {
13
- visible: false,
14
- panelId: '',
15
- items: [],
16
- currentType: '',
17
-
18
- onItemClick: (e) => {
19
- const type = e.target.closest('[data-type]')?.dataset.type;
20
- if (type) {
21
- this.dispatchEvent(new CustomEvent('panel-type-select', {
22
- bubbles: true,
23
- composed: true,
24
- detail: { panelId: this.$.panelId, type }
25
- }));
26
- this.hide();
27
- }
28
- },
29
- };
30
-
31
- /**
32
- * Show menu at position
33
- * @param {number} x
34
- * @param {number} y
35
- * @param {string} panelId
36
- * @param {string} currentType
37
- * @param {Array<{type: string, title: string, icon: string}>} items
38
- */
39
- show(x, y, panelId, currentType, items) {
40
- this.$.panelId = panelId;
41
- this.$.currentType = currentType;
42
-
43
- // Transform items to include isActive flag for template binding
44
- this.$.items = items.map(item => ({
45
- ...item,
46
- icon: item.icon || 'dashboard',
47
- title: item.title || item.type,
48
- isActive: item.type === currentType
49
- }));
50
-
51
- this.style.left = `${x}px`;
52
- this.style.top = `${y}px`;
53
- this.$.visible = true;
54
-
55
- // Close on outside click
56
- if (typeof setTimeout !== 'undefined') {
57
- setTimeout(() => {
58
- if (typeof document !== 'undefined') {
59
- document.addEventListener('pointerdown', this._onOutsideClick);
60
- }
61
- }, 0);
62
- }
63
- }
64
-
65
- hide() {
66
- this.$.visible = false;
67
- if (typeof document !== 'undefined') {
68
- document.removeEventListener('pointerdown', this._onOutsideClick);
69
- }
70
- }
71
-
72
- _onOutsideClick = (e) => {
73
- if (!this.contains(e.target)) {
74
- this.hide();
75
- }
76
- };
77
-
78
- disconnectedCallback() {
79
- if (typeof document !== 'undefined') {
80
- document.removeEventListener('pointerdown', this._onOutsideClick);
81
- }
82
- }
83
- }
84
-
85
- PanelMenu.template = template;
86
- PanelMenu.rootStyles = styles;
87
-
88
- PanelMenu.reg('panel-menu');
89
-
@@ -1,14 +0,0 @@
1
- import { html } from '@symbiotejs/symbiote';
2
-
3
- export const template = html`
4
- <div class="menu-container" ${{ '@hidden': '!visible' }}>
5
- <div class="menu-items" itemize="items">
6
- <template>
7
- <div class="menu-item" ${{ onclick: '^onItemClick', '@data-type': 'type', '@active': 'isActive' }}>
8
- <span class="material-symbols-outlined">{{icon}}</span>
9
- <span>{{title}}</span>
10
- </div>
11
- </template>
12
- </div>
13
- </div>
14
- `;
@@ -1,16 +0,0 @@
1
- /**
2
- * @fileoverview Layout module exports
3
- * Blender-style panel layout system for Symbiote.js
4
- */
5
-
6
- export { Layout } from './Layout/Layout.js';
7
- export { LayoutNode } from './LayoutNode/LayoutNode.js';
8
- export { ActionZone } from './ActionZone/ActionZone.js';
9
- export { LayoutPreview } from './LayoutPreview/LayoutPreview.js';
10
- export { LayoutSidebar } from './LayoutSidebar/LayoutSidebar.js';
11
- export * as LayoutTree from './LayoutTree.js';
12
- export {
13
- navigate, updateParams, parseQuery, buildHash, buildQuery,
14
- getRoute, setDefaultPanel,
15
- } from './LayoutRouter/LayoutRouter.js';
16
- export { syncWithRouter } from './LayoutRouter/routerSync.js';
@@ -1,61 +0,0 @@
1
- /**
2
- * ContextMenu styles
3
- * @module symbiote-node/menu/ContextMenu.css
4
- */
5
- import { css } from '@symbiotejs/symbiote';
6
-
7
- export const styles = css`
8
- context-menu {
9
- position: absolute;
10
- inset: 0;
11
- z-index: 200;
12
- pointer-events: none;
13
-
14
- &[hidden] {
15
- display: none;
16
- }
17
-
18
- & .sn-ctx-backdrop {
19
- position: absolute;
20
- inset: 0;
21
- pointer-events: all;
22
- }
23
-
24
- & .sn-ctx-menu {
25
- position: absolute;
26
- pointer-events: all;
27
- min-width: 160px;
28
- background: var(--sn-ctx-bg, #1e1e3a);
29
- border: 1px solid var(--sn-ctx-border, #3a3a6a);
30
- border-radius: 8px;
31
- box-shadow: 0 8px 24px var(--sn-shadow-color, rgba(0, 0, 0, 0.5));
32
- padding: 4px;
33
- overflow: hidden;
34
- }
35
- }
36
-
37
- .sn-ctx-btn {
38
- display: flex;
39
- align-items: center;
40
- gap: 8px;
41
- width: 100%;
42
- padding: 8px 12px;
43
- border: none;
44
- background: transparent;
45
- color: var(--sn-ctx-color, #e0e0e0);
46
- font-family: var(--sn-font, 'Inter', sans-serif);
47
- font-size: 13px;
48
- cursor: pointer;
49
- border-radius: 4px;
50
- transition: background 0.1s;
51
-
52
- &:hover {
53
- background: var(--sn-ctx-hover, rgba(74, 158, 255, 0.15));
54
- }
55
- }
56
-
57
- .sn-ctx-icon {
58
- font-size: 18px;
59
- opacity: 0.7;
60
- }
61
- `;