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,97 +0,0 @@
1
- /**
2
- * GraphTabs styles
3
- * @module symbiote-node/canvas/GraphTabs.css
4
- */
5
- import { css } from '@symbiotejs/symbiote';
6
-
7
- export const styles = css`
8
- graph-tabs {
9
- display: flex;
10
- align-items: stretch;
11
- height: 32px;
12
- background: var(--sn-ctx-bg, #1e1e2e);
13
- border-bottom: 1px solid var(--sn-node-border, rgba(255, 255, 255, 0.08));
14
- font-family: var(--sn-font, 'Inter', sans-serif);
15
- font-size: 12px;
16
- color: var(--sn-text-dim, #a0a0a0);
17
- overflow-x: auto;
18
- overflow-y: hidden;
19
- user-select: none;
20
- scrollbar-width: none;
21
-
22
- &::-webkit-scrollbar {
23
- display: none;
24
- }
25
- }
26
-
27
- tab-item {
28
- display: flex;
29
- align-items: center;
30
- gap: 6px;
31
- padding: 0 14px;
32
- cursor: pointer;
33
- white-space: nowrap;
34
- border-right: 1px solid var(--sn-node-border, rgba(255, 255, 255, 0.06));
35
- transition: background 0.15s ease-out, color 0.15s ease-out;
36
- position: relative;
37
-
38
- &:hover {
39
- background: color-mix(in srgb, currentColor 4%, transparent);
40
- color: var(--sn-text, #cdd6f4);
41
- }
42
-
43
- &[data-active] {
44
- background: var(--sn-node-bg, #2d2d3d);
45
- color: var(--sn-text, #cdd6f4);
46
-
47
- &::after {
48
- content: '';
49
- position: absolute;
50
- bottom: 0;
51
- left: 0;
52
- right: 0;
53
- height: 2px;
54
- background: var(--sn-node-selected, #4a9eff);
55
- }
56
- }
57
-
58
- & .material-symbols-outlined {
59
- font-size: 14px;
60
- }
61
-
62
- & .tab-close {
63
- font-size: 14px;
64
- opacity: 0;
65
- transition: opacity 0.15s;
66
- padding: 2px;
67
- border-radius: 3px;
68
-
69
- &:hover {
70
- background: color-mix(in srgb, currentColor 10%, transparent);
71
- }
72
- }
73
-
74
- &:hover .tab-close {
75
- opacity: 0.7;
76
- }
77
- }
78
-
79
- .tab-add {
80
- display: flex;
81
- align-items: center;
82
- justify-content: center;
83
- width: 32px;
84
- cursor: pointer;
85
- color: var(--sn-text-dim, #a0a0a0);
86
- transition: background 0.15s ease-out, color 0.15s ease-out;
87
-
88
- &:hover {
89
- background: color-mix(in srgb, currentColor 4%, transparent);
90
- color: var(--sn-text, #cdd6f4);
91
- }
92
-
93
- & .material-symbols-outlined {
94
- font-size: 16px;
95
- }
96
- }
97
- `;
@@ -1,176 +0,0 @@
1
- /**
2
- * GraphTabs — Tab/Page management for multi-canvas workflows
3
- *
4
- * Each tab represents an independent graph page with its own
5
- * set of nodes and connections. Provides tab bar UI and
6
- * state switching for the NodeCanvas.
7
- *
8
- * @module symbiote-node/canvas/GraphTabs
9
- */
10
-
11
- import Symbiote, { html } from '@symbiotejs/symbiote';
12
- import { template } from './GraphTabs.tpl.js';
13
- import { styles } from './GraphTabs.css.js';
14
-
15
- /**
16
- * @typedef {Object} TabPage
17
- * @property {string} id
18
- * @property {string} name
19
- * @property {Object} state - Serialized editor state
20
- */
21
-
22
- class TabItem extends Symbiote {
23
- init$ = {
24
- id: '',
25
- name: '',
26
- isActive: false,
27
- showClose: false,
28
- };
29
-
30
- renderCallback() {
31
- this.sub('isActive', (val) => {
32
- this.toggleAttribute('data-active', val);
33
- });
34
- }
35
- }
36
-
37
- TabItem.template = html`
38
- <span class="material-symbols-outlined">description</span>
39
- <span ${{ textContent: 'name' }}></span>
40
- <span
41
- class="tab-close material-symbols-outlined"
42
- ${{ onclick: '^onCloseTab', '@hidden': '!showClose' }}
43
- >close</span>
44
- `;
45
-
46
- TabItem.reg('tab-item');
47
-
48
- export class GraphTabs extends Symbiote {
49
-
50
- init$ = {
51
- tabItems: [],
52
- };
53
-
54
- /** @type {TabPage[]} */
55
- #tabs = [];
56
-
57
- /** @type {string} */
58
- #activeTabId = '';
59
-
60
- /** @type {function|null} */
61
- #onSwitch = null;
62
-
63
- /** @type {function|null} */
64
- #onAdd = null;
65
-
66
- /** @type {function|null} */
67
- #onClose = null;
68
-
69
- /**
70
- * Set callbacks for tab events
71
- * @param {object} callbacks
72
- * @param {function} callbacks.onSwitch - (tabId) => void
73
- * @param {function} callbacks.onAdd - () => TabPage
74
- * @param {function} callbacks.onClose - (tabId) => void
75
- */
76
- setCallbacks(callbacks) {
77
- this.#onSwitch = callbacks.onSwitch;
78
- this.#onAdd = callbacks.onAdd;
79
- this.#onClose = callbacks.onClose;
80
- }
81
-
82
- /**
83
- * Add a tab
84
- * @param {string} id
85
- * @param {string} name
86
- * @param {Object} [state={}]
87
- */
88
- addTab(id, name, state = {}) {
89
- this.#tabs.push({ id, name, state });
90
- this.#syncItems();
91
- this.switchTo(id);
92
- }
93
-
94
- /**
95
- * Switch to a tab
96
- * @param {string} id
97
- */
98
- switchTo(id) {
99
- this.#activeTabId = id;
100
- this.#syncItems();
101
- if (this.#onSwitch) this.#onSwitch(id);
102
- }
103
-
104
- /**
105
- * Remove a tab
106
- * @param {string} id
107
- */
108
- removeTab(id) {
109
- const idx = this.#tabs.findIndex(t => t.id === id);
110
- if (idx === -1) return;
111
- this.#tabs.splice(idx, 1);
112
- if (this.#activeTabId === id && this.#tabs.length > 0) {
113
- this.switchTo(this.#tabs[Math.max(0, idx - 1)].id);
114
- }
115
- this.#syncItems();
116
- if (this.#onClose) this.#onClose(id);
117
- }
118
-
119
- /** @returns {string} */
120
- get activeTab() { return this.#activeTabId; }
121
-
122
- /** @returns {TabPage[]} */
123
- get tabs() { return [...this.#tabs]; }
124
-
125
- /**
126
- * Update tab state (for saving before switch)
127
- * @param {string} id
128
- * @param {Object} state
129
- */
130
- setTabState(id, state) {
131
- const tab = this.#tabs.find(t => t.id === id);
132
- if (tab) tab.state = state;
133
- }
134
-
135
- /**
136
- * Get tab state
137
- * @param {string} id
138
- * @returns {Object|undefined}
139
- */
140
- getTabState(id) {
141
- return this.#tabs.find(t => t.id === id)?.state;
142
- }
143
-
144
- #syncItems() {
145
- const showClose = this.#tabs.length > 1;
146
- this.$.tabItems = this.#tabs.map(t => ({
147
- id: t.id,
148
- name: t.name,
149
- isActive: t.id === this.#activeTabId,
150
- showClose,
151
- }));
152
- }
153
-
154
- onTabClick(e) {
155
- const item = e.target.closest('tab-item');
156
- if (!item) return;
157
- this.switchTo(item.$.id);
158
- }
159
-
160
- onCloseTab(e) {
161
- e.stopPropagation();
162
- const item = e.target.closest('tab-item');
163
- if (item) this.removeTab(item.$.id);
164
- }
165
-
166
- onAddTab() {
167
- if (this.#onAdd) {
168
- const newTab = this.#onAdd();
169
- if (newTab) this.addTab(newTab.id, newTab.name, newTab.state);
170
- }
171
- }
172
- }
173
-
174
- GraphTabs.template = template;
175
- GraphTabs.rootStyles = styles;
176
- GraphTabs.reg('graph-tabs');
@@ -1,12 +0,0 @@
1
- /**
2
- * GraphTabs template
3
- * @module symbiote-node/canvas/GraphTabs.tpl
4
- */
5
- import { html } from '@symbiotejs/symbiote';
6
-
7
- export const template = html`
8
- <div ${{ itemize: 'tabItems', 'item-tag': 'tab-item', onclick: 'onTabClick' }}></div>
9
- <div class="tab-add" title="New tab" ${{ onclick: 'onAddTab' }}>
10
- <span class="material-symbols-outlined">add</span>
11
- </div>
12
- `;
@@ -1,88 +0,0 @@
1
- export class LODManager {
2
- /** @type {import('./NodeCanvas/NodeCanvas.js').NodeCanvas} */
3
- #canvas;
4
-
5
- /** @type {number} */
6
- #threshold;
7
-
8
- /** @type {string} */
9
- #currentLod = 'collapsed';
10
-
11
- /** @type {boolean} */
12
- #attached = false;
13
-
14
- #listeners = [];
15
-
16
- /**
17
- * @param {import('./NodeCanvas/NodeCanvas.js').NodeCanvas} canvas
18
- * @param {object} config
19
- * @param {number} [config.threshold=0.7] - Zoom level at which LOD expands
20
- */
21
- constructor(canvas, { threshold = 0.7 } = {}) {
22
- this.#canvas = canvas;
23
- this.#threshold = threshold;
24
- }
25
-
26
- get currentLod() {
27
- return this.#currentLod;
28
- }
29
-
30
- /**
31
- * Attach LOD tracking to the canvas.
32
- * Note: Symbiote's sub() does not return an unsubscribe handle —
33
- * subscriptions are auto-cleaned when the canvas component is destroyed.
34
- */
35
- attach() {
36
- if (this.#attached || !this.#canvas) return;
37
- this.#attached = true;
38
-
39
- const initialZoom = this.#canvas.$.zoom || 1;
40
- this.#currentLod = initialZoom >= this.#threshold ? 'expanded' : 'collapsed';
41
-
42
- this.#canvas.sub('zoom', (zoom) => {
43
- if (!this.#attached) return; // guard after destroy
44
- const newLod = zoom >= this.#threshold ? 'expanded' : 'collapsed';
45
- if (newLod === this.#currentLod) return;
46
-
47
- this.#currentLod = newLod;
48
- this.#emit(newLod);
49
- });
50
- }
51
-
52
- /**
53
- * Perform immediate LOD update evaluation (e.g. after manual navigation or fitView)
54
- */
55
- update() {
56
- if (!this.#canvas || !this.#attached) return;
57
- const zoom = this.#canvas.$.zoom || 1;
58
- const newLod = zoom >= this.#threshold ? 'expanded' : 'collapsed';
59
- if (newLod !== this.#currentLod) {
60
- this.#currentLod = newLod;
61
- this.#emit(newLod);
62
- }
63
- }
64
-
65
- /**
66
- * @param {Function} callback
67
- */
68
- onLodChange(callback) {
69
- this.#listeners.push(callback);
70
- // Immediately notify new listener of current state
71
- if (this.#attached) {
72
- callback(this.#currentLod);
73
- }
74
- }
75
-
76
- #emit(lod) {
77
- for (const fn of this.#listeners) {
78
- fn(lod);
79
- }
80
- }
81
-
82
- destroy() {
83
- // Symbiote sub() auto-cleans on component disconnect.
84
- // We just disable the guard flag so the callback becomes a no-op.
85
- this.#listeners = [];
86
- this.#attached = false;
87
- }
88
- }
@@ -1,71 +0,0 @@
1
- /**
2
- * Minimap styles
3
- * @module symbiote-node/canvas/Minimap.css
4
- */
5
- import { css } from '@symbiotejs/symbiote';
6
-
7
- export const styles = css`
8
- node-minimap {
9
- position: absolute;
10
- bottom: 16px;
11
- right: 16px;
12
- width: 200px;
13
- height: 140px;
14
- border-radius: 8px;
15
- overflow: hidden;
16
- border: 1px solid var(--sn-node-border, rgba(255,255,255,0.08));
17
- box-shadow: 0 4px 16px var(--sn-shadow-color, rgba(0,0,0,0.3));
18
- z-index: 90;
19
- cursor: crosshair;
20
- opacity: 1;
21
- transition: opacity 0.4s ease;
22
-
23
- &[hidden] {
24
- display: none;
25
- }
26
-
27
- &[data-fading] {
28
- opacity: 0;
29
- pointer-events: none;
30
- }
31
-
32
- & canvas {
33
- display: block;
34
- width: 100%;
35
- height: 100%;
36
- }
37
- }
38
-
39
- .sn-minimap-toggle {
40
- position: absolute;
41
- bottom: 16px;
42
- right: 16px;
43
- width: 32px;
44
- height: 32px;
45
- border-radius: 6px;
46
- border: 1px solid var(--sn-node-border, rgba(255,255,255,0.08));
47
- background: var(--sn-node-bg, #2a2a3e);
48
- color: var(--sn-text-dim, #888);
49
- cursor: pointer;
50
- z-index: 89;
51
- display: flex;
52
- align-items: center;
53
- justify-content: center;
54
- padding: 0;
55
- transition: color 0.15s, border-color 0.15s;
56
-
57
- & .material-symbols-outlined {
58
- font-size: 18px;
59
- }
60
-
61
- &:hover {
62
- color: var(--sn-text, #ddd);
63
- border-color: var(--sn-node-selected, #4a9eff);
64
- }
65
-
66
- &[data-active] {
67
- color: var(--sn-node-selected, #4a9eff);
68
- border-color: var(--sn-node-selected, #4a9eff);
69
- }
70
- }
71
- `;
@@ -1,207 +0,0 @@
1
- /**
2
- * Minimap — small overview of the entire node graph
3
- *
4
- * Shows a scaled-down view of all nodes and connections.
5
- * The viewport rectangle shows current visible area and can be dragged to pan.
6
- * Positioned bottom-right of the canvas.
7
- *
8
- * @module symbiote-node/canvas/Minimap
9
- */
10
-
11
- import Symbiote from '@symbiotejs/symbiote';
12
- import { template } from './Minimap.tpl.js';
13
- import { styles } from './Minimap.css.js';
14
-
15
- export class Minimap extends Symbiote {
16
-
17
- init$ = {
18
- visible: true,
19
- };
20
-
21
- /** @type {HTMLCanvasElement|null} */
22
- #canvas2d = null;
23
-
24
- /** @type {CanvasRenderingContext2D|null} */
25
- #ctx = null;
26
-
27
- /** @type {function|null} */
28
- #getState = null;
29
-
30
- /** @type {boolean} */
31
- #isDragging = false;
32
-
33
- /** @type {number} */
34
- #rafId = 0;
35
-
36
- renderCallback() {
37
- this.#canvas2d = this.querySelector('canvas');
38
- this.#ctx = this.#canvas2d?.getContext('2d');
39
-
40
- // Pointer events for viewport drag
41
- this.#canvas2d?.addEventListener('pointerdown', (e) => this.#onPointerDown(e));
42
- window.addEventListener('pointermove', (e) => this.#onPointerMove(e));
43
- window.addEventListener('pointerup', () => this.#onPointerUp());
44
- }
45
-
46
- /**
47
- * Set state getter for reading canvas state
48
- * @param {function} fn - returns { nodes, transform, containerSize }
49
- */
50
- setStateGetter(fn) {
51
- this.#getState = fn;
52
- this.#startLoop();
53
- }
54
-
55
- #startLoop() {
56
- const draw = () => {
57
- this.#draw();
58
- this.#rafId = requestAnimationFrame(draw);
59
- };
60
- this.#rafId = requestAnimationFrame(draw);
61
- }
62
-
63
- #draw() {
64
- const ctx = this.#ctx;
65
- const canvas = this.#canvas2d;
66
- if (!ctx || !canvas || !this.#getState) return;
67
-
68
- const state = this.#getState();
69
- if (!state) return;
70
-
71
- const { nodes, transform, containerSize } = state;
72
- const w = canvas.width;
73
- const h = canvas.height;
74
-
75
- // Read theme colors from CSS variables
76
- const cs = getComputedStyle(this);
77
- const bgColor = cs.getPropertyValue('--sn-minimap-bg').trim()
78
- || cs.getPropertyValue('--sn-bg').trim()
79
- || 'rgba(20, 20, 35, 0.85)';
80
- const nodeColor = cs.getPropertyValue('--sn-minimap-node').trim()
81
- || 'rgba(80, 130, 200, 0.6)';
82
- const nodeStroke = cs.getPropertyValue('--sn-minimap-node-stroke').trim()
83
- || cs.getPropertyValue('--sn-node-border').trim()
84
- || 'rgba(120, 170, 255, 0.3)';
85
- const vpStroke = cs.getPropertyValue('--sn-minimap-viewport').trim()
86
- || 'rgba(255, 255, 255, 0.6)';
87
- const vpFill = cs.getPropertyValue('--sn-minimap-viewport-fill').trim()
88
- || 'rgba(255, 255, 255, 0.04)';
89
-
90
- // Clear
91
- ctx.clearRect(0, 0, w, h);
92
-
93
- // Background
94
- ctx.fillStyle = bgColor;
95
- ctx.fillRect(0, 0, w, h);
96
-
97
- if (nodes.length === 0) return;
98
-
99
- // Calculate bounds of all nodes
100
- let minX = Infinity, minY = Infinity, maxX = -Infinity, maxY = -Infinity;
101
- for (const n of nodes) {
102
- minX = Math.min(minX, n.x);
103
- minY = Math.min(minY, n.y);
104
- maxX = Math.max(maxX, n.x + (n.width || 200));
105
- maxY = Math.max(maxY, n.y + (n.height || 100));
106
- }
107
-
108
- // Add padding
109
- const pad = 100;
110
- minX -= pad; minY -= pad;
111
- maxX += pad; maxY += pad;
112
-
113
- const graphW = maxX - minX;
114
- const graphH = maxY - minY;
115
-
116
- // Scale to fit
117
- const scaleX = w / graphW;
118
- const scaleY = h / graphH;
119
- const scale = Math.min(scaleX, scaleY);
120
-
121
- const offsetX = (w - graphW * scale) / 2;
122
- const offsetY = (h - graphH * scale) / 2;
123
-
124
- // Store for viewport drag
125
- this._mapMinX = minX;
126
- this._mapMinY = minY;
127
- this._mapScale = scale;
128
- this._mapOffsetX = offsetX;
129
- this._mapOffsetY = offsetY;
130
-
131
- // Draw nodes as rectangles
132
- for (const n of nodes) {
133
- const x = (n.x - minX) * scale + offsetX;
134
- const y = (n.y - minY) * scale + offsetY;
135
- const nw = (n.width || 200) * scale;
136
- const nh = (n.height || 80) * scale;
137
-
138
- ctx.fillStyle = n.bypassed ? 'rgba(100, 100, 100, 0.5)' : nodeColor;
139
- ctx.fillRect(x, y, nw, nh);
140
- ctx.strokeStyle = nodeStroke;
141
- ctx.lineWidth = 0.5;
142
- ctx.strokeRect(x, y, nw, nh);
143
- }
144
-
145
- // Draw viewport rectangle
146
- if (containerSize && transform) {
147
- const vx = (-transform.x / transform.zoom - minX) * scale + offsetX;
148
- const vy = (-transform.y / transform.zoom - minY) * scale + offsetY;
149
- const vw = (containerSize.width / transform.zoom) * scale;
150
- const vh = (containerSize.height / transform.zoom) * scale;
151
-
152
- ctx.strokeStyle = vpStroke;
153
- ctx.lineWidth = 1.5;
154
- ctx.strokeRect(vx, vy, vw, vh);
155
- ctx.fillStyle = vpFill;
156
- ctx.fillRect(vx, vy, vw, vh);
157
- }
158
- }
159
-
160
- #onPointerDown(e) {
161
- this.#isDragging = true;
162
- this.#navigateTo(e);
163
- e.preventDefault();
164
- }
165
-
166
- #onPointerMove(e) {
167
- if (!this.#isDragging) return;
168
- this.#navigateTo(e);
169
- }
170
-
171
- #onPointerUp() {
172
- this.#isDragging = false;
173
- }
174
-
175
- #navigateTo(e) {
176
- if (!this.#getState || !this.#canvas2d) return;
177
- const rect = this.#canvas2d.getBoundingClientRect();
178
- const mx = e.clientX - rect.left;
179
- const my = e.clientY - rect.top;
180
-
181
- const state = this.#getState();
182
- if (!state?.containerSize || !state?.transform) return;
183
-
184
- // Convert minimap coords to graph coords
185
- const graphX = (mx - this._mapOffsetX) / this._mapScale + this._mapMinX;
186
- const graphY = (my - this._mapOffsetY) / this._mapScale + this._mapMinY;
187
-
188
- // Center the viewport on that point
189
- const zoom = state.transform.zoom;
190
- const newX = -(graphX * zoom - state.containerSize.width / 2);
191
- const newY = -(graphY * zoom - state.containerSize.height / 2);
192
-
193
- // Dispatch event so NodeCanvas can update its transform
194
- this.dispatchEvent(new CustomEvent('minimap-navigate', {
195
- detail: { x: newX, y: newY },
196
- bubbles: true,
197
- }));
198
- }
199
-
200
- destroyCallback() {
201
- cancelAnimationFrame(this.#rafId);
202
- }
203
- }
204
-
205
- Minimap.template = template;
206
- Minimap.rootStyles = styles;
207
- Minimap.reg('node-minimap');
@@ -1,9 +0,0 @@
1
- /**
2
- * Minimap template
3
- * @module symbiote-node/canvas/Minimap.tpl
4
- */
5
- import { html } from '@symbiotejs/symbiote';
6
-
7
- export const template = html`
8
- <canvas width="200" height="140"></canvas>
9
- `;