project-graph-mcp 2.3.2 → 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 (279) 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/engine/AgentUICommands.js +0 -100
  148. package/vendor/symbiote-node/engine/Executor.js +0 -371
  149. package/vendor/symbiote-node/engine/Graph.js +0 -314
  150. package/vendor/symbiote-node/engine/GraphServer.js +0 -353
  151. package/vendor/symbiote-node/engine/HandlerLoader.js +0 -145
  152. package/vendor/symbiote-node/engine/History.js +0 -83
  153. package/vendor/symbiote-node/engine/Lifecycle.js +0 -118
  154. package/vendor/symbiote-node/engine/Persistence.js +0 -84
  155. package/vendor/symbiote-node/engine/Registry.js +0 -264
  156. package/vendor/symbiote-node/engine/SocketTypes.js +0 -79
  157. package/vendor/symbiote-node/engine/cli.js +0 -404
  158. package/vendor/symbiote-node/engine/index.js +0 -56
  159. package/vendor/symbiote-node/engine/nanoid.js +0 -28
  160. package/vendor/symbiote-node/engine/package.json +0 -26
  161. package/vendor/symbiote-node/engine/packs/ai/beat-detect.handler.js +0 -215
  162. package/vendor/symbiote-node/engine/packs/ai/content-adapt.handler.js +0 -238
  163. package/vendor/symbiote-node/engine/packs/ai/face-detect.handler.js +0 -287
  164. package/vendor/symbiote-node/engine/packs/ai/grok-generate.handler.js +0 -565
  165. package/vendor/symbiote-node/engine/packs/ai/kling-lipsync.handler.js +0 -414
  166. package/vendor/symbiote-node/engine/packs/ai/lesson-generate.handler.js +0 -343
  167. package/vendor/symbiote-node/engine/packs/ai/opencode.handler.js +0 -164
  168. package/vendor/symbiote-node/engine/packs/ai/replicate-lipsync.handler.js +0 -341
  169. package/vendor/symbiote-node/engine/packs/ai/tts.handler.js +0 -241
  170. package/vendor/symbiote-node/engine/packs/ai/whisper.handler.js +0 -191
  171. package/vendor/symbiote-node/engine/packs/data/db-query.handler.js +0 -67
  172. package/vendor/symbiote-node/engine/packs/data/news-accumulate.handler.js +0 -281
  173. package/vendor/symbiote-node/engine/packs/data/personas.handler.js +0 -160
  174. package/vendor/symbiote-node/engine/packs/data/prompt-loader.handler.js +0 -193
  175. package/vendor/symbiote-node/engine/packs/data/roles.handler.js +0 -216
  176. package/vendor/symbiote-node/engine/packs/data/rss-feed.handler.js +0 -244
  177. package/vendor/symbiote-node/engine/packs/debug/inject.handler.js +0 -52
  178. package/vendor/symbiote-node/engine/packs/flow/agent.handler.js +0 -73
  179. package/vendor/symbiote-node/engine/packs/flow/if.handler.js +0 -107
  180. package/vendor/symbiote-node/engine/packs/flow/loop.handler.js +0 -58
  181. package/vendor/symbiote-node/engine/packs/flow/merge.handler.js +0 -60
  182. package/vendor/symbiote-node/engine/packs/flow/retry.handler.js +0 -65
  183. package/vendor/symbiote-node/engine/packs/flow/switch.handler.js +0 -64
  184. package/vendor/symbiote-node/engine/packs/flow/wait-all.handler.js +0 -39
  185. package/vendor/symbiote-node/engine/packs/io/http-request.handler.js +0 -82
  186. package/vendor/symbiote-node/engine/packs/io/read-file.handler.js +0 -60
  187. package/vendor/symbiote-node/engine/packs/io/write-file.handler.js +0 -63
  188. package/vendor/symbiote-node/engine/packs/transform/anchor-match.handler.js +0 -494
  189. package/vendor/symbiote-node/engine/packs/transform/effects-skeleton.handler.js +0 -417
  190. package/vendor/symbiote-node/engine/packs/transform/json-parse.handler.js +0 -43
  191. package/vendor/symbiote-node/engine/packs/transform/lipsync-select.handler.js +0 -339
  192. package/vendor/symbiote-node/engine/packs/transform/riopla-adapt.handler.js +0 -432
  193. package/vendor/symbiote-node/engine/packs/transform/set.handler.js +0 -57
  194. package/vendor/symbiote-node/engine/packs/transform/template-builder.handler.js +0 -134
  195. package/vendor/symbiote-node/engine/packs/transform/template.handler.js +0 -79
  196. package/vendor/symbiote-node/engine/packs/transform/timeline-build.handler.js +0 -399
  197. package/vendor/symbiote-node/engine/packs/util/delay.handler.js +0 -39
  198. package/vendor/symbiote-node/engine/packs/util/log.handler.js +0 -44
  199. package/vendor/symbiote-node/engine/packs/video-pack.js +0 -323
  200. package/vendor/symbiote-node/index.js +0 -103
  201. package/vendor/symbiote-node/inspector/InspectorPanel/InspectorPanel.css.js +0 -361
  202. package/vendor/symbiote-node/inspector/InspectorPanel/InspectorPanel.js +0 -332
  203. package/vendor/symbiote-node/inspector/InspectorPanel/InspectorPanel.tpl.js +0 -96
  204. package/vendor/symbiote-node/inspector/TemplatePreview/TemplatePreview.css.js +0 -104
  205. package/vendor/symbiote-node/inspector/TemplatePreview/TemplatePreview.js +0 -133
  206. package/vendor/symbiote-node/inspector/TemplatePreview/TemplatePreview.tpl.js +0 -33
  207. package/vendor/symbiote-node/interactions/ConnectFlow.js +0 -307
  208. package/vendor/symbiote-node/interactions/Drag.js +0 -102
  209. package/vendor/symbiote-node/interactions/Selector.js +0 -132
  210. package/vendor/symbiote-node/interactions/SnapGrid.js +0 -65
  211. package/vendor/symbiote-node/interactions/Zoom.js +0 -140
  212. package/vendor/symbiote-node/layout/ActionZone/ActionZone.css.js +0 -88
  213. package/vendor/symbiote-node/layout/ActionZone/ActionZone.js +0 -254
  214. package/vendor/symbiote-node/layout/ActionZone/ActionZone.tpl.js +0 -11
  215. package/vendor/symbiote-node/layout/Layout/Layout.css.js +0 -88
  216. package/vendor/symbiote-node/layout/Layout/Layout.js +0 -622
  217. package/vendor/symbiote-node/layout/Layout/Layout.tpl.js +0 -25
  218. package/vendor/symbiote-node/layout/LayoutNode/LayoutNode.css.js +0 -293
  219. package/vendor/symbiote-node/layout/LayoutNode/LayoutNode.js +0 -467
  220. package/vendor/symbiote-node/layout/LayoutNode/LayoutNode.tpl.js +0 -33
  221. package/vendor/symbiote-node/layout/LayoutPreview/LayoutPreview.css.js +0 -46
  222. package/vendor/symbiote-node/layout/LayoutPreview/LayoutPreview.js +0 -102
  223. package/vendor/symbiote-node/layout/LayoutPreview/LayoutPreview.tpl.js +0 -6
  224. package/vendor/symbiote-node/layout/LayoutRouter/LayoutRouter.js +0 -156
  225. package/vendor/symbiote-node/layout/LayoutRouter/routerSync.js +0 -250
  226. package/vendor/symbiote-node/layout/LayoutSidebar/LayoutSidebar.css.js +0 -379
  227. package/vendor/symbiote-node/layout/LayoutSidebar/LayoutSidebar.js +0 -263
  228. package/vendor/symbiote-node/layout/LayoutSidebar/LayoutSidebar.tpl.js +0 -20
  229. package/vendor/symbiote-node/layout/LayoutSidebar/SidebarSection.js +0 -183
  230. package/vendor/symbiote-node/layout/LayoutTree.js +0 -246
  231. package/vendor/symbiote-node/layout/PanelMenu/PanelMenu.css.js +0 -43
  232. package/vendor/symbiote-node/layout/PanelMenu/PanelMenu.js +0 -89
  233. package/vendor/symbiote-node/layout/PanelMenu/PanelMenu.tpl.js +0 -14
  234. package/vendor/symbiote-node/layout/index.js +0 -16
  235. package/vendor/symbiote-node/menu/ContextMenu/ContextMenu.css.js +0 -61
  236. package/vendor/symbiote-node/menu/ContextMenu/ContextMenu.js +0 -79
  237. package/vendor/symbiote-node/menu/ContextMenu/ContextMenu.tpl.js +0 -19
  238. package/vendor/symbiote-node/node/CtrlItem/CtrlItem.css.js +0 -41
  239. package/vendor/symbiote-node/node/CtrlItem/CtrlItem.js +0 -24
  240. package/vendor/symbiote-node/node/CtrlItem/CtrlItem.tpl.js +0 -16
  241. package/vendor/symbiote-node/node/GraphFrame/GraphFrame.css.js +0 -65
  242. package/vendor/symbiote-node/node/GraphFrame/GraphFrame.js +0 -29
  243. package/vendor/symbiote-node/node/GraphFrame/GraphFrame.tpl.js +0 -13
  244. package/vendor/symbiote-node/node/GraphNode/GraphNode.css.js +0 -683
  245. package/vendor/symbiote-node/node/GraphNode/GraphNode.js +0 -92
  246. package/vendor/symbiote-node/node/GraphNode/GraphNode.tpl.js +0 -17
  247. package/vendor/symbiote-node/node/NodeSocket/NodeSocket.js +0 -25
  248. package/vendor/symbiote-node/node/NodeSocket/NodeSocket.tpl.js +0 -7
  249. package/vendor/symbiote-node/node/PortItem/PortItem.css.js +0 -90
  250. package/vendor/symbiote-node/node/PortItem/PortItem.js +0 -87
  251. package/vendor/symbiote-node/node/PortItem/PortItem.tpl.js +0 -10
  252. package/vendor/symbiote-node/package.json +0 -59
  253. package/vendor/symbiote-node/palette/PaletteBrowser/PaletteBrowser.css.js +0 -143
  254. package/vendor/symbiote-node/palette/PaletteBrowser/PaletteBrowser.js +0 -131
  255. package/vendor/symbiote-node/palette/PaletteBrowser/PaletteBrowser.tpl.js +0 -16
  256. package/vendor/symbiote-node/plugins/History.js +0 -384
  257. package/vendor/symbiote-node/plugins/Readonly.js +0 -59
  258. package/vendor/symbiote-node/shapes/CircleShape.js +0 -80
  259. package/vendor/symbiote-node/shapes/CommentShape.js +0 -35
  260. package/vendor/symbiote-node/shapes/DiamondShape.js +0 -115
  261. package/vendor/symbiote-node/shapes/NodeShape.js +0 -80
  262. package/vendor/symbiote-node/shapes/PillShape.js +0 -91
  263. package/vendor/symbiote-node/shapes/RectShape.js +0 -72
  264. package/vendor/symbiote-node/shapes/SVGShape.js +0 -494
  265. package/vendor/symbiote-node/shapes/index.js +0 -53
  266. package/vendor/symbiote-node/themes/Palette.js +0 -32
  267. package/vendor/symbiote-node/themes/Skin.js +0 -113
  268. package/vendor/symbiote-node/themes/Theme.js +0 -84
  269. package/vendor/symbiote-node/themes/carbon.js +0 -137
  270. package/vendor/symbiote-node/themes/dark.js +0 -137
  271. package/vendor/symbiote-node/themes/ebook.js +0 -138
  272. package/vendor/symbiote-node/themes/grey.js +0 -137
  273. package/vendor/symbiote-node/themes/light.js +0 -137
  274. package/vendor/symbiote-node/themes/neon.js +0 -138
  275. package/vendor/symbiote-node/themes/pcb.js +0 -273
  276. package/vendor/symbiote-node/themes/synthwave.js +0 -137
  277. package/vendor/symbiote-node/toolbar/QuickToolbar/QuickToolbar.css.js +0 -86
  278. package/vendor/symbiote-node/toolbar/QuickToolbar/QuickToolbar.js +0 -128
  279. package/vendor/symbiote-node/toolbar/QuickToolbar/QuickToolbar.tpl.js +0 -29
@@ -1,451 +0,0 @@
1
- /**
2
- * NodeEditor — central graph manager with event system
3
- *
4
- * Provides CRUD operations for nodes and connections with
5
- * pre/post event hooks via callback-based event emitter.
6
- * Replaces Rete.js Scope/Signal with simpler emit pattern.
7
- *
8
- * @module symbiote-node/core/Editor
9
- */
10
-
11
- import { Connection } from './Connection.js';
12
- import { Node } from './Node.js';
13
- import { Socket, Input, Output, InputControl } from './Socket.js';
14
- import { Frame } from './Frame.js';
15
-
16
- /**
17
- * @typedef {'nodecreate'|'nodecreated'|'noderemove'|'noderemoved'|
18
- * 'connectioncreate'|'connectioncreated'|'connectionremove'|'connectionremoved'|
19
- * 'framecreate'|'framecreated'|'frameremove'|'frameremoved'|
20
- * 'clear'|'cleared'|'nodeselect'|'nodedeselect'} EditorEvent
21
- */
22
-
23
- export class NodeEditor {
24
- constructor() {
25
- /** @type {Map<string, import('./Node.js').Node>} */
26
- this.nodes = new Map();
27
-
28
- /** @type {Map<string, Connection>} */
29
- this.connections = new Map();
30
-
31
- /** @type {Map<string, import('./Frame.js').Frame>} */
32
- this.frames = new Map();
33
-
34
- /** @type {Object<string, Set<function>>} */
35
- this._listeners = {};
36
- }
37
-
38
- // --- Event System ---
39
-
40
- /**
41
- * Subscribe to editor event
42
- * @param {EditorEvent} event
43
- * @param {function} handler
44
- * @returns {function} Unsubscribe function
45
- */
46
- on(event, handler) {
47
- if (!this._listeners[event]) {
48
- this._listeners[event] = new Set();
49
- }
50
- this._listeners[event].add(handler);
51
- return () => this._listeners[event].delete(handler);
52
- }
53
-
54
- /**
55
- * Emit event to all listeners
56
- * @param {EditorEvent} event
57
- * @param {*} data
58
- * @returns {boolean} - false if any listener returned false (cancel)
59
- */
60
- emit(event, data) {
61
- const handlers = this._listeners[event];
62
- if (!handlers) return true;
63
- for (const handler of handlers) {
64
- if (handler(data) === false) return false;
65
- }
66
- return true;
67
- }
68
-
69
- /**
70
- * Remove all event listeners (for clean teardown)
71
- */
72
- removeAllListeners() {
73
- this._listeners = {};
74
- }
75
-
76
- // --- Node CRUD ---
77
-
78
- /**
79
- * Get node by ID
80
- * @param {string} id
81
- * @returns {import('./Node.js').Node|undefined}
82
- */
83
- getNode(id) {
84
- return this.nodes.get(id);
85
- }
86
-
87
- /**
88
- * Get all nodes
89
- * @returns {import('./Node.js').Node[]}
90
- */
91
- getNodes() {
92
- return [...this.nodes.values()];
93
- }
94
-
95
- /**
96
- * Add node to editor
97
- * @param {import('./Node.js').Node} node
98
- * @returns {boolean}
99
- */
100
- addNode(node) {
101
- if (this.nodes.has(node.id)) throw new Error('node already added');
102
- if (!this.emit('nodecreate', node)) return false;
103
- this.nodes.set(node.id, node);
104
- this.emit('nodecreated', node);
105
- return true;
106
- }
107
-
108
- /**
109
- * Remove node and all its connections
110
- * @param {string} id
111
- * @returns {boolean}
112
- */
113
- removeNode(id) {
114
- const node = this.nodes.get(id);
115
- if (!node) throw new Error('node not found');
116
- if (!this.emit('noderemove', node)) return false;
117
-
118
- // Remove all connections to/from this node
119
- for (const [connId, conn] of this.connections) {
120
- if (conn.from === id || conn.to === id) {
121
- this.removeConnection(connId);
122
- }
123
- }
124
-
125
- this.nodes.delete(id);
126
- this.emit('noderemoved', node);
127
- return true;
128
- }
129
-
130
- // --- Connection CRUD ---
131
-
132
- /**
133
- * Get connection by ID
134
- * @param {string} id
135
- * @returns {Connection|undefined}
136
- */
137
- getConnection(id) {
138
- return this.connections.get(id);
139
- }
140
-
141
- /**
142
- * Get all connections
143
- * @returns {Connection[]}
144
- */
145
- getConnections() {
146
- return [...this.connections.values()];
147
- }
148
-
149
- /**
150
- * Get connections for a specific node
151
- * @param {string} nodeId
152
- * @returns {Connection[]}
153
- */
154
- getNodeConnections(nodeId) {
155
- return this.getConnections().filter(c => c.from === nodeId || c.to === nodeId);
156
- }
157
-
158
- /**
159
- * Add connection
160
- * @param {Connection} connection
161
- * @returns {boolean}
162
- */
163
- addConnection(connection) {
164
- if (this.connections.has(connection.id)) throw new Error('connection already added');
165
- if (!this.emit('connectioncreate', connection)) return false;
166
- this.connections.set(connection.id, connection);
167
- this.emit('connectioncreated', connection);
168
- return true;
169
- }
170
-
171
- /**
172
- * Remove connection
173
- * @param {string} id
174
- * @returns {boolean}
175
- */
176
- removeConnection(id) {
177
- const conn = this.connections.get(id);
178
- if (!conn) return false;
179
- if (!this.emit('connectionremove', conn)) return false;
180
- this.connections.delete(id);
181
- this.emit('connectionremoved', conn);
182
- return true;
183
- }
184
-
185
- // --- Bulk Operations ---
186
-
187
- /**
188
- * Clear all nodes and connections
189
- * @returns {boolean}
190
- */
191
- clear() {
192
- if (!this.emit('clear', null)) return false;
193
- for (const id of [...this.connections.keys()]) {
194
- this.removeConnection(id);
195
- }
196
- for (const id of [...this.nodes.keys()]) {
197
- this.removeNode(id);
198
- }
199
- this.emit('cleared', null);
200
- return true;
201
- }
202
-
203
- // --- Frame CRUD ---
204
-
205
- /**
206
- * Get frame by ID
207
- * @param {string} id
208
- * @returns {import('./Frame.js').Frame|undefined}
209
- */
210
- getFrame(id) {
211
- return this.frames.get(id);
212
- }
213
-
214
- /**
215
- * Get all frames
216
- * @returns {import('./Frame.js').Frame[]}
217
- */
218
- getFrames() {
219
- return [...this.frames.values()];
220
- }
221
-
222
- /**
223
- * Add frame
224
- * @param {import('./Frame.js').Frame} frame
225
- * @returns {boolean}
226
- */
227
- addFrame(frame) {
228
- if (this.frames.has(frame.id)) throw new Error('frame already added');
229
- if (!this.emit('framecreate', frame)) return false;
230
- this.frames.set(frame.id, frame);
231
- this.emit('framecreated', frame);
232
- return true;
233
- }
234
-
235
- /**
236
- * Remove frame
237
- * @param {string} id
238
- * @returns {boolean}
239
- */
240
- removeFrame(id) {
241
- const frame = this.frames.get(id);
242
- if (!frame) return false;
243
- if (!this.emit('frameremove', frame)) return false;
244
- this.frames.delete(id);
245
- this.emit('frameremoved', frame);
246
- return true;
247
- }
248
-
249
- // --- Serialization (agi-graph isomorphic bridge) ---
250
-
251
- /**
252
- * Serialize editor state to agi-graph workflow JSON format.
253
- * Output is directly compatible with engine/Graph.fromJSON().
254
- * @param {Object<string, number[]>} [positions] - Node positions {nodeId: [x, y]}
255
- * @returns {object} Workflow JSON
256
- */
257
- toJSON(positions = {}) {
258
- return {
259
- version: 1,
260
- nodes: this.getNodes().map((n) => {
261
- const obj = {
262
- id: n.id,
263
- type: n.type,
264
- name: n.label,
265
- params: { ...n.params },
266
- };
267
- if (n.category && n.category !== 'default') obj.category = n.category;
268
- if (n.shape && n.shape !== 'rect') obj.shape = n.shape;
269
- if (n.icon) obj.icon = n.icon;
270
- if (n.cacheMode && n.cacheMode !== 'auto') obj.cacheMode = n.cacheMode;
271
-
272
- // Serialize port definitions for round-trip
273
- const inputs = Object.entries(n.inputs);
274
- if (inputs.length > 0) {
275
- obj.inputs = inputs.map(([key, inp]) => ({
276
- name: key,
277
- type: inp.socket?.name || 'any',
278
- label: inp.label || '',
279
- }));
280
- }
281
- const outputs = Object.entries(n.outputs);
282
- if (outputs.length > 0) {
283
- obj.outputs = outputs.map(([key, out]) => ({
284
- name: key,
285
- type: out.socket?.name || 'any',
286
- label: out.label || '',
287
- }));
288
- }
289
- return obj;
290
- }),
291
- connections: this.getConnections().map((c) => ({
292
- id: c.id,
293
- from: c.from,
294
- out: c.out,
295
- to: c.to,
296
- in: c.in,
297
- })),
298
- frames: this.getFrames().map((f) => ({
299
- id: f.id,
300
- label: f.label,
301
- x: f.x,
302
- y: f.y,
303
- width: f.width,
304
- height: f.height,
305
- color: f.color,
306
- })),
307
- ui: {
308
- positions: { ...positions },
309
- },
310
- };
311
- }
312
-
313
- /**
314
- * Reconstruct editor state from agi-graph workflow JSON.
315
- * Enables round-trip: Editor → toJSON → fromJSON → Editor.
316
- * Also accepts output from engine/Graph.toJSON().
317
- * @param {object} data - Workflow JSON
318
- * @param {Object<string, number[]>} [positionsOut] - Optional object to populate with positions
319
- * @returns {NodeEditor} this
320
- */
321
- fromJSON(data, positionsOut) {
322
- // Clear existing state (bypass events for bulk load)
323
- this.nodes.clear();
324
- this.connections.clear();
325
- this.frames.clear();
326
-
327
- // Restore nodes
328
- for (const nd of (data.nodes || [])) {
329
- const node = new Node(nd.name || nd.type, {
330
- id: nd.id,
331
- type: nd.type,
332
- category: nd.category || 'default',
333
- shape: nd.shape || 'rect',
334
- icon: nd.icon || '',
335
- });
336
- node.params = { ...nd.params };
337
- if (nd.cacheMode) node.cacheMode = nd.cacheMode;
338
-
339
- // Auto-create InputControls from params for Inspector display
340
- // Merge driver defaults into params (fills missing keys from handler definitions)
341
- const driverParams = nd.driver?.params;
342
- if (driverParams && !nd.params) nd.params = {};
343
- if (driverParams) {
344
- for (const [key, def] of Object.entries(driverParams)) {
345
- if (!(key in nd.params) && def.default !== undefined) {
346
- nd.params[key] = def.default;
347
- }
348
- }
349
- }
350
-
351
- if (nd.params) {
352
- for (const [key, value] of Object.entries(nd.params)) {
353
- /** @type {'text'|'number'|'textarea'|'select'|'boolean'} */
354
- let controlType = 'text';
355
- let displayValue = value;
356
- let controlOptions = [];
357
-
358
- // Use driver metadata for richer control type detection
359
- const paramMeta = driverParams?.[key];
360
- if (paramMeta?.type === 'boolean' || typeof value === 'boolean') {
361
- controlType = 'boolean';
362
- } else if (paramMeta?.type === 'number' || typeof value === 'number') {
363
- controlType = 'number';
364
- } else if (typeof value === 'string' && value.includes('\n')) {
365
- controlType = 'textarea';
366
- } else if (typeof value === 'object') {
367
- controlType = 'textarea';
368
- displayValue = JSON.stringify(value, null, 2);
369
- }
370
-
371
- // Select type from driver options
372
- if (paramMeta?.options) {
373
- controlType = 'select';
374
- controlOptions = paramMeta.options;
375
- }
376
-
377
- node.addControl(key, new InputControl(controlType, {
378
- initial: displayValue,
379
- label: paramMeta?.description || key,
380
- options: controlOptions,
381
- }));
382
- }
383
- }
384
-
385
- // Restore ports from serialized definitions
386
- if (nd.inputs) {
387
- for (const inp of nd.inputs) {
388
- node.addInput(inp.name, new Input(new Socket(inp.type || 'any'), inp.label || ''));
389
- }
390
- }
391
- if (nd.outputs) {
392
- for (const out of nd.outputs) {
393
- node.addOutput(out.name, new Output(new Socket(out.type || 'any'), out.label || ''));
394
- }
395
- }
396
-
397
- this.nodes.set(node.id, node);
398
- }
399
-
400
- // Restore connections
401
- for (const cd of (data.connections || [])) {
402
- const srcNode = this.nodes.get(cd.from);
403
- const tgtNode = this.nodes.get(cd.to);
404
- if (!srcNode || !tgtNode) continue;
405
-
406
- // Ensure ports exist (auto-create if coming from engine format without port defs)
407
- if (!srcNode.outputs[cd.out]) {
408
- srcNode.addOutput(cd.out, new Output(new Socket('any'), cd.out));
409
- }
410
- if (!tgtNode.inputs[cd.in]) {
411
- tgtNode.addInput(cd.in, new Input(new Socket('any'), cd.in));
412
- }
413
-
414
- const conn = new Connection(srcNode, cd.out, tgtNode, cd.in);
415
- if (cd.id) conn.id = cd.id;
416
- this.connections.set(conn.id, conn);
417
- }
418
-
419
- // Restore frames
420
- for (const fd of (data.frames || [])) {
421
- const frame = new Frame(fd.label, {
422
- id: fd.id,
423
- x: fd.x,
424
- y: fd.y,
425
- width: fd.width,
426
- height: fd.height,
427
- color: fd.color,
428
- });
429
- this.frames.set(frame.id, frame);
430
- }
431
-
432
- // Extract positions
433
- if (positionsOut && data.ui?.positions) {
434
- Object.assign(positionsOut, data.ui.positions);
435
- }
436
-
437
- return this;
438
- }
439
-
440
- /**
441
- * Convert editor state to an engine Graph instance for server-side execution.
442
- * The Graph can be passed directly to Executor.run().
443
- * @param {Object<string, number[]>} [positions] - Node positions
444
- * @returns {import('../engine/Graph.js').Graph}
445
- */
446
- async toGraph(positions = {}) {
447
- const { Graph } = await import('../engine/Graph.js');
448
- const json = this.toJSON(positions);
449
- return new Graph(json);
450
- }
451
- }
@@ -1,31 +0,0 @@
1
- /**
2
- * Frame — visual grouping rectangle for nodes
3
- *
4
- * Pure data class (like Node). Stores position, size, color, label.
5
- * Frame does not own nodes — containment is determined by spatial overlap.
6
- *
7
- * @module symbiote-node/core/Frame
8
- */
9
-
10
- import { uid } from './Socket.js';
11
-
12
- export class Frame {
13
- /**
14
- * @param {string} label - Display label
15
- * @param {object} [options]
16
- * @param {string} [options.color='#4a9eff'] - Border/header color
17
- * @param {number} [options.x=0] - X position
18
- * @param {number} [options.y=0] - Y position
19
- * @param {number} [options.width=400] - Width
20
- * @param {number} [options.height=300] - Height
21
- */
22
- constructor(label, options = {}) {
23
- this.id = options.id || uid();
24
- this.label = label;
25
- this.color = options.color || '#4a9eff';
26
- this.x = options.x || 0;
27
- this.y = options.y || 0;
28
- this.width = options.width || 400;
29
- this.height = options.height || 300;
30
- }
31
- }