obsidian-accomplishments-mcp 0.1.9 → 0.1.11

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 (269) hide show
  1. package/README.md +154 -182
  2. package/dist/index.js +207 -38
  3. package/dist/index.js.map +1 -1
  4. package/dist/integration.test.d.ts +8 -0
  5. package/dist/integration.test.d.ts.map +1 -0
  6. package/dist/integration.test.js +979 -0
  7. package/dist/integration.test.js.map +1 -0
  8. package/dist/models/types.d.ts +1 -2
  9. package/dist/models/types.d.ts.map +1 -1
  10. package/dist/models/types.js.map +1 -1
  11. package/dist/models/v2-types.d.ts +460 -0
  12. package/dist/models/v2-types.d.ts.map +1 -0
  13. package/dist/models/v2-types.js +137 -0
  14. package/dist/models/v2-types.js.map +1 -0
  15. package/dist/models/v2-types.test.d.ts +5 -0
  16. package/dist/models/v2-types.test.d.ts.map +1 -0
  17. package/dist/models/v2-types.test.js +133 -0
  18. package/dist/models/v2-types.test.js.map +1 -0
  19. package/dist/parsers/canvas-parser.d.ts +1 -1
  20. package/dist/parsers/canvas-parser.d.ts.map +1 -1
  21. package/dist/parsers/canvas-parser.js +1 -1
  22. package/dist/parsers/canvas-parser.js.map +1 -1
  23. package/dist/parsers/markdown-parser.js +9 -9
  24. package/dist/parsers/markdown-parser.js.map +1 -1
  25. package/dist/services/v2/archive-manager.d.ts +96 -0
  26. package/dist/services/v2/archive-manager.d.ts.map +1 -0
  27. package/dist/services/v2/archive-manager.js +281 -0
  28. package/dist/services/v2/archive-manager.js.map +1 -0
  29. package/dist/services/v2/canvas-manager.d.ts +155 -0
  30. package/dist/services/v2/canvas-manager.d.ts.map +1 -0
  31. package/dist/services/v2/canvas-manager.js +540 -0
  32. package/dist/services/v2/canvas-manager.js.map +1 -0
  33. package/dist/services/v2/canvas-manager.test.d.ts +5 -0
  34. package/dist/services/v2/canvas-manager.test.d.ts.map +1 -0
  35. package/dist/services/v2/canvas-manager.test.js +327 -0
  36. package/dist/services/v2/canvas-manager.test.js.map +1 -0
  37. package/dist/services/v2/cascade-manager.d.ts +54 -0
  38. package/dist/services/v2/cascade-manager.d.ts.map +1 -0
  39. package/dist/services/v2/cascade-manager.js +220 -0
  40. package/dist/services/v2/cascade-manager.js.map +1 -0
  41. package/dist/services/v2/cycle-detector.d.ts +76 -0
  42. package/dist/services/v2/cycle-detector.d.ts.map +1 -0
  43. package/dist/services/v2/cycle-detector.js +183 -0
  44. package/dist/services/v2/cycle-detector.js.map +1 -0
  45. package/dist/services/v2/cycle-detector.test.d.ts +7 -0
  46. package/dist/services/v2/cycle-detector.test.d.ts.map +1 -0
  47. package/dist/services/v2/cycle-detector.test.js +125 -0
  48. package/dist/services/v2/cycle-detector.test.js.map +1 -0
  49. package/dist/services/v2/entity-parser.d.ts +54 -0
  50. package/dist/services/v2/entity-parser.d.ts.map +1 -0
  51. package/dist/services/v2/entity-parser.js +418 -0
  52. package/dist/services/v2/entity-parser.js.map +1 -0
  53. package/dist/services/v2/entity-parser.test.d.ts +5 -0
  54. package/dist/services/v2/entity-parser.test.d.ts.map +1 -0
  55. package/dist/services/v2/entity-parser.test.js +637 -0
  56. package/dist/services/v2/entity-parser.test.js.map +1 -0
  57. package/dist/services/v2/entity-serializer.d.ts +94 -0
  58. package/dist/services/v2/entity-serializer.d.ts.map +1 -0
  59. package/dist/services/v2/entity-serializer.js +583 -0
  60. package/dist/services/v2/entity-serializer.js.map +1 -0
  61. package/dist/services/v2/entity-serializer.test.d.ts +5 -0
  62. package/dist/services/v2/entity-serializer.test.d.ts.map +1 -0
  63. package/dist/services/v2/entity-serializer.test.js +241 -0
  64. package/dist/services/v2/entity-serializer.test.js.map +1 -0
  65. package/dist/services/v2/entity-validator.d.ts +65 -0
  66. package/dist/services/v2/entity-validator.d.ts.map +1 -0
  67. package/dist/services/v2/entity-validator.js +573 -0
  68. package/dist/services/v2/entity-validator.js.map +1 -0
  69. package/dist/services/v2/entity-validator.test.d.ts +5 -0
  70. package/dist/services/v2/entity-validator.test.d.ts.map +1 -0
  71. package/dist/services/v2/entity-validator.test.js +519 -0
  72. package/dist/services/v2/entity-validator.test.js.map +1 -0
  73. package/dist/services/v2/file-manager.d.ts +73 -0
  74. package/dist/services/v2/file-manager.d.ts.map +1 -0
  75. package/dist/services/v2/file-manager.js +310 -0
  76. package/dist/services/v2/file-manager.js.map +1 -0
  77. package/dist/services/v2/file-manager.test.d.ts +5 -0
  78. package/dist/services/v2/file-manager.test.d.ts.map +1 -0
  79. package/dist/services/v2/file-manager.test.js +339 -0
  80. package/dist/services/v2/file-manager.test.js.map +1 -0
  81. package/dist/services/v2/index-manager.d.ts +68 -0
  82. package/dist/services/v2/index-manager.d.ts.map +1 -0
  83. package/dist/services/v2/index-manager.js +228 -0
  84. package/dist/services/v2/index-manager.js.map +1 -0
  85. package/dist/services/v2/index-manager.test.d.ts +5 -0
  86. package/dist/services/v2/index-manager.test.d.ts.map +1 -0
  87. package/dist/services/v2/index-manager.test.js +386 -0
  88. package/dist/services/v2/index-manager.test.js.map +1 -0
  89. package/dist/services/v2/index-service.d.ts +82 -0
  90. package/dist/services/v2/index-service.d.ts.map +1 -0
  91. package/dist/services/v2/index-service.js +274 -0
  92. package/dist/services/v2/index-service.js.map +1 -0
  93. package/dist/services/v2/index-service.test.d.ts +5 -0
  94. package/dist/services/v2/index-service.test.d.ts.map +1 -0
  95. package/dist/services/v2/index-service.test.js +117 -0
  96. package/dist/services/v2/index-service.test.js.map +1 -0
  97. package/dist/services/v2/lifecycle-manager.d.ts +59 -0
  98. package/dist/services/v2/lifecycle-manager.d.ts.map +1 -0
  99. package/dist/services/v2/lifecycle-manager.js +310 -0
  100. package/dist/services/v2/lifecycle-manager.js.map +1 -0
  101. package/dist/services/v2/lifecycle-manager.test.d.ts +5 -0
  102. package/dist/services/v2/lifecycle-manager.test.d.ts.map +1 -0
  103. package/dist/services/v2/lifecycle-manager.test.js +141 -0
  104. package/dist/services/v2/lifecycle-manager.test.js.map +1 -0
  105. package/dist/services/v2/path-resolver.d.ts +64 -0
  106. package/dist/services/v2/path-resolver.d.ts.map +1 -0
  107. package/dist/services/v2/path-resolver.js +174 -0
  108. package/dist/services/v2/path-resolver.js.map +1 -0
  109. package/dist/services/v2/progress-computer.d.ts +46 -0
  110. package/dist/services/v2/progress-computer.d.ts.map +1 -0
  111. package/dist/services/v2/progress-computer.js +200 -0
  112. package/dist/services/v2/progress-computer.js.map +1 -0
  113. package/dist/services/v2/search-service.d.ts +68 -0
  114. package/dist/services/v2/search-service.d.ts.map +1 -0
  115. package/dist/services/v2/search-service.js +194 -0
  116. package/dist/services/v2/search-service.js.map +1 -0
  117. package/dist/services/v2/transitive-dependency-remover.d.ts +54 -0
  118. package/dist/services/v2/transitive-dependency-remover.d.ts.map +1 -0
  119. package/dist/services/v2/transitive-dependency-remover.js +156 -0
  120. package/dist/services/v2/transitive-dependency-remover.js.map +1 -0
  121. package/dist/services/v2/transitive-dependency-remover.test.d.ts +7 -0
  122. package/dist/services/v2/transitive-dependency-remover.test.d.ts.map +1 -0
  123. package/dist/services/v2/transitive-dependency-remover.test.js +119 -0
  124. package/dist/services/v2/transitive-dependency-remover.test.js.map +1 -0
  125. package/dist/services/v2/v2-runtime.d.ts +374 -0
  126. package/dist/services/v2/v2-runtime.d.ts.map +1 -0
  127. package/dist/services/v2/v2-runtime.js +1908 -0
  128. package/dist/services/v2/v2-runtime.js.map +1 -0
  129. package/dist/services/v2/v2-runtime.test.d.ts +5 -0
  130. package/dist/services/v2/v2-runtime.test.d.ts.map +1 -0
  131. package/dist/services/v2/v2-runtime.test.js +658 -0
  132. package/dist/services/v2/v2-runtime.test.js.map +1 -0
  133. package/dist/services/v2/workstream-normalizer.d.ts +59 -0
  134. package/dist/services/v2/workstream-normalizer.d.ts.map +1 -0
  135. package/dist/services/v2/workstream-normalizer.js +137 -0
  136. package/dist/services/v2/workstream-normalizer.js.map +1 -0
  137. package/dist/services/v2/workstream-normalizer.test.d.ts +7 -0
  138. package/dist/services/v2/workstream-normalizer.test.d.ts.map +1 -0
  139. package/dist/services/v2/workstream-normalizer.test.js +130 -0
  140. package/dist/services/v2/workstream-normalizer.test.js.map +1 -0
  141. package/dist/test-runner.d.ts +4 -1
  142. package/dist/test-runner.d.ts.map +1 -1
  143. package/dist/test-runner.js +44 -249
  144. package/dist/test-runner.js.map +1 -1
  145. package/dist/tools/batch-operations-tools.d.ts +54 -0
  146. package/dist/tools/batch-operations-tools.d.ts.map +1 -0
  147. package/dist/tools/batch-operations-tools.js +370 -0
  148. package/dist/tools/batch-operations-tools.js.map +1 -0
  149. package/dist/tools/decision-document-tools.d.ts +78 -0
  150. package/dist/tools/decision-document-tools.d.ts.map +1 -0
  151. package/dist/tools/decision-document-tools.js +260 -0
  152. package/dist/tools/decision-document-tools.js.map +1 -0
  153. package/dist/tools/entity-management-tools.d.ts +79 -0
  154. package/dist/tools/entity-management-tools.d.ts.map +1 -0
  155. package/dist/tools/entity-management-tools.js +851 -0
  156. package/dist/tools/entity-management-tools.js.map +1 -0
  157. package/dist/tools/entity-management-tools.test.d.ts +5 -0
  158. package/dist/tools/entity-management-tools.test.d.ts.map +1 -0
  159. package/dist/tools/entity-management-tools.test.js +530 -0
  160. package/dist/tools/entity-management-tools.test.js.map +1 -0
  161. package/dist/tools/index.d.ts +15 -271
  162. package/dist/tools/index.d.ts.map +1 -1
  163. package/dist/tools/index.js +510 -47
  164. package/dist/tools/index.js.map +1 -1
  165. package/dist/tools/index.test.d.ts +8 -0
  166. package/dist/tools/index.test.d.ts.map +1 -0
  167. package/dist/tools/index.test.js +429 -0
  168. package/dist/tools/index.test.js.map +1 -0
  169. package/dist/tools/project-understanding-tools.d.ts +75 -0
  170. package/dist/tools/project-understanding-tools.d.ts.map +1 -0
  171. package/dist/tools/project-understanding-tools.js +751 -0
  172. package/dist/tools/project-understanding-tools.js.map +1 -0
  173. package/dist/tools/search-navigation-tools.d.ts +77 -0
  174. package/dist/tools/search-navigation-tools.d.ts.map +1 -0
  175. package/dist/tools/search-navigation-tools.js +379 -0
  176. package/dist/tools/search-navigation-tools.js.map +1 -0
  177. package/dist/tools/tool-types.d.ts +703 -0
  178. package/dist/tools/tool-types.d.ts.map +1 -0
  179. package/dist/tools/tool-types.js +7 -0
  180. package/dist/tools/tool-types.js.map +1 -0
  181. package/dist/utils/config.d.ts +0 -4
  182. package/dist/utils/config.d.ts.map +1 -1
  183. package/dist/utils/config.js +2 -19
  184. package/dist/utils/config.js.map +1 -1
  185. package/package.json +16 -1
  186. package/dist/services/accomplishment-service.d.ts +0 -33
  187. package/dist/services/accomplishment-service.d.ts.map +0 -1
  188. package/dist/services/accomplishment-service.js +0 -293
  189. package/dist/services/accomplishment-service.js.map +0 -1
  190. package/dist/services/canvas-service.d.ts +0 -96
  191. package/dist/services/canvas-service.d.ts.map +0 -1
  192. package/dist/services/canvas-service.js +0 -231
  193. package/dist/services/canvas-service.js.map +0 -1
  194. package/dist/services/context-doc-service.d.ts +0 -70
  195. package/dist/services/context-doc-service.d.ts.map +0 -1
  196. package/dist/services/context-doc-service.js +0 -229
  197. package/dist/services/context-doc-service.js.map +0 -1
  198. package/dist/services/dependency-service.d.ts +0 -22
  199. package/dist/services/dependency-service.d.ts.map +0 -1
  200. package/dist/services/dependency-service.js +0 -99
  201. package/dist/services/dependency-service.js.map +0 -1
  202. package/dist/services/status-indicator-service.d.ts +0 -40
  203. package/dist/services/status-indicator-service.d.ts.map +0 -1
  204. package/dist/services/status-indicator-service.js +0 -173
  205. package/dist/services/status-indicator-service.js.map +0 -1
  206. package/dist/services/task-service.d.ts +0 -32
  207. package/dist/services/task-service.d.ts.map +0 -1
  208. package/dist/services/task-service.js +0 -152
  209. package/dist/services/task-service.js.map +0 -1
  210. package/dist/test-real-vault.d.ts +0 -6
  211. package/dist/test-real-vault.d.ts.map +0 -1
  212. package/dist/test-real-vault.js +0 -30
  213. package/dist/test-real-vault.js.map +0 -1
  214. package/dist/tools/batch-operations.d.ts +0 -246
  215. package/dist/tools/batch-operations.d.ts.map +0 -1
  216. package/dist/tools/batch-operations.js +0 -235
  217. package/dist/tools/batch-operations.js.map +0 -1
  218. package/dist/tools/get-accomplishment.d.ts +0 -26
  219. package/dist/tools/get-accomplishment.d.ts.map +0 -1
  220. package/dist/tools/get-accomplishment.js +0 -53
  221. package/dist/tools/get-accomplishment.js.map +0 -1
  222. package/dist/tools/get-accomplishments-graph.d.ts +0 -26
  223. package/dist/tools/get-accomplishments-graph.d.ts.map +0 -1
  224. package/dist/tools/get-accomplishments-graph.js +0 -137
  225. package/dist/tools/get-accomplishments-graph.js.map +0 -1
  226. package/dist/tools/get-blocked-items.d.ts +0 -15
  227. package/dist/tools/get-blocked-items.d.ts.map +0 -1
  228. package/dist/tools/get-blocked-items.js +0 -73
  229. package/dist/tools/get-blocked-items.js.map +0 -1
  230. package/dist/tools/get-current-work.d.ts +0 -15
  231. package/dist/tools/get-current-work.d.ts.map +0 -1
  232. package/dist/tools/get-current-work.js +0 -68
  233. package/dist/tools/get-current-work.js.map +0 -1
  234. package/dist/tools/get-project-status.d.ts +0 -26
  235. package/dist/tools/get-project-status.d.ts.map +0 -1
  236. package/dist/tools/get-project-status.js +0 -98
  237. package/dist/tools/get-project-status.js.map +0 -1
  238. package/dist/tools/get-ready-to-start.d.ts +0 -15
  239. package/dist/tools/get-ready-to-start.d.ts.map +0 -1
  240. package/dist/tools/get-ready-to-start.js +0 -47
  241. package/dist/tools/get-ready-to-start.js.map +0 -1
  242. package/dist/tools/list-accomplishments.d.ts +0 -34
  243. package/dist/tools/list-accomplishments.d.ts.map +0 -1
  244. package/dist/tools/list-accomplishments.js +0 -34
  245. package/dist/tools/list-accomplishments.js.map +0 -1
  246. package/dist/tools/manage-accomplishment.d.ts +0 -147
  247. package/dist/tools/manage-accomplishment.d.ts.map +0 -1
  248. package/dist/tools/manage-accomplishment.js +0 -153
  249. package/dist/tools/manage-accomplishment.js.map +0 -1
  250. package/dist/tools/manage-dependency.d.ts +0 -41
  251. package/dist/tools/manage-dependency.d.ts.map +0 -1
  252. package/dist/tools/manage-dependency.js +0 -66
  253. package/dist/tools/manage-dependency.js.map +0 -1
  254. package/dist/tools/manage-task.d.ts +0 -119
  255. package/dist/tools/manage-task.d.ts.map +0 -1
  256. package/dist/tools/manage-task.js +0 -126
  257. package/dist/tools/manage-task.js.map +0 -1
  258. package/dist/tools/reconcile-canvas.d.ts +0 -33
  259. package/dist/tools/reconcile-canvas.d.ts.map +0 -1
  260. package/dist/tools/reconcile-canvas.js +0 -41
  261. package/dist/tools/reconcile-canvas.js.map +0 -1
  262. package/dist/tools/set-work-focus.d.ts +0 -48
  263. package/dist/tools/set-work-focus.d.ts.map +0 -1
  264. package/dist/tools/set-work-focus.js +0 -78
  265. package/dist/tools/set-work-focus.js.map +0 -1
  266. package/dist/tools/sync-dependencies.d.ts +0 -33
  267. package/dist/tools/sync-dependencies.d.ts.map +0 -1
  268. package/dist/tools/sync-dependencies.js +0 -144
  269. package/dist/tools/sync-dependencies.js.map +0 -1
@@ -0,0 +1,327 @@
1
+ /**
2
+ * Tests for V2 Canvas Manager
3
+ */
4
+ import { describe, it, expect, beforeEach, vi, afterEach } from 'vitest';
5
+ import { CanvasManager } from './canvas-manager.js';
6
+ import * as fs from 'fs/promises';
7
+ import { writeFileAtomic, triggerObsidianReload } from '../../utils/file-utils.js';
8
+ // Mock fs module
9
+ vi.mock('fs/promises');
10
+ // Mock file-utils module (for writeFileAtomic and triggerObsidianReload)
11
+ vi.mock('../../utils/file-utils.js', () => ({
12
+ writeFileAtomic: vi.fn().mockResolvedValue(undefined),
13
+ triggerObsidianReload: vi.fn(),
14
+ }));
15
+ describe('CanvasManager', () => {
16
+ let manager;
17
+ let mockEntityPathResolver;
18
+ let mockCanvasData;
19
+ const VAULT_PATH = '/test-vault';
20
+ const DEFAULT_CANVAS = 'projects/main.canvas';
21
+ beforeEach(() => {
22
+ vi.resetAllMocks();
23
+ mockEntityPathResolver = vi.fn().mockResolvedValue(null);
24
+ manager = new CanvasManager(VAULT_PATH, DEFAULT_CANVAS, mockEntityPathResolver);
25
+ // Default empty canvas
26
+ mockCanvasData = { nodes: [], edges: [] };
27
+ // Setup fs mocks
28
+ vi.mocked(fs.readFile).mockImplementation(async () => JSON.stringify(mockCanvasData));
29
+ vi.mocked(fs.access).mockResolvedValue(undefined);
30
+ // Reset file-utils mocks
31
+ vi.mocked(writeFileAtomic).mockResolvedValue(undefined);
32
+ vi.mocked(triggerObsidianReload).mockReturnValue(undefined);
33
+ });
34
+ afterEach(() => {
35
+ vi.restoreAllMocks();
36
+ });
37
+ describe('addNode', () => {
38
+ it('should add a new node to empty canvas', async () => {
39
+ const filePath = 'accomplishments/stories/S-001.md';
40
+ const nodeId = await manager.addNode(filePath);
41
+ expect(nodeId).toBeTruthy();
42
+ expect(writeFileAtomic).toHaveBeenCalledTimes(1);
43
+ const writtenData = JSON.parse(vi.mocked(writeFileAtomic).mock.calls[0][1]);
44
+ expect(writtenData.nodes).toHaveLength(1);
45
+ expect(writtenData.nodes[0].file).toBe(filePath);
46
+ expect(writtenData.nodes[0].type).toBe('file');
47
+ });
48
+ it('should return existing node ID if node already exists', async () => {
49
+ const filePath = 'accomplishments/stories/S-001.md';
50
+ const existingNodeId = 'existing-node-123';
51
+ mockCanvasData = {
52
+ nodes: [{ id: existingNodeId, type: 'file', file: filePath, x: 0, y: 0, width: 400, height: 300 }],
53
+ edges: [],
54
+ };
55
+ const nodeId = await manager.addNode(filePath);
56
+ expect(nodeId).toBe(existingNodeId);
57
+ expect(writeFileAtomic).not.toHaveBeenCalled();
58
+ });
59
+ it('should use custom position and dimensions', async () => {
60
+ const filePath = 'accomplishments/stories/S-001.md';
61
+ const position = { x: 100, y: 200 };
62
+ const dimensions = { width: 500, height: 400 };
63
+ await manager.addNode(filePath, undefined, position, dimensions);
64
+ const writtenData = JSON.parse(vi.mocked(writeFileAtomic).mock.calls[0][1]);
65
+ expect(writtenData.nodes[0].x).toBe(100);
66
+ expect(writtenData.nodes[0].y).toBe(200);
67
+ expect(writtenData.nodes[0].width).toBe(500);
68
+ expect(writtenData.nodes[0].height).toBe(400);
69
+ });
70
+ it('should use specified canvas path', async () => {
71
+ const filePath = 'accomplishments/stories/S-001.md';
72
+ const customCanvas = 'projects/custom.canvas';
73
+ await manager.addNode(filePath, customCanvas);
74
+ expect(fs.readFile).toHaveBeenCalledWith(expect.stringContaining('custom.canvas'), 'utf-8');
75
+ });
76
+ });
77
+ describe('removeNode', () => {
78
+ it('should remove existing node', async () => {
79
+ const filePath = 'accomplishments/stories/S-001.md';
80
+ const nodeId = 'node-to-remove';
81
+ mockCanvasData = {
82
+ nodes: [{ id: nodeId, type: 'file', file: filePath, x: 0, y: 0, width: 400, height: 300 }],
83
+ edges: [],
84
+ };
85
+ const result = await manager.removeNode(filePath);
86
+ expect(result).toBe(true);
87
+ const writtenData = JSON.parse(vi.mocked(writeFileAtomic).mock.calls[0][1]);
88
+ expect(writtenData.nodes).toHaveLength(0);
89
+ });
90
+ it('should return false if node does not exist', async () => {
91
+ const result = await manager.removeNode('nonexistent.md');
92
+ expect(result).toBe(false);
93
+ expect(writeFileAtomic).not.toHaveBeenCalled();
94
+ });
95
+ it('should remove connected edges when removing node', async () => {
96
+ const filePath = 'accomplishments/stories/S-001.md';
97
+ const nodeId = 'node-to-remove';
98
+ const otherNodeId = 'other-node';
99
+ mockCanvasData = {
100
+ nodes: [
101
+ { id: nodeId, type: 'file', file: filePath, x: 0, y: 0, width: 400, height: 300 },
102
+ { id: otherNodeId, type: 'file', file: 'other.md', x: 500, y: 0, width: 400, height: 300 },
103
+ ],
104
+ edges: [
105
+ { id: 'edge-1', fromNode: nodeId, toNode: otherNodeId, fromSide: 'right', toSide: 'left' },
106
+ { id: 'edge-2', fromNode: otherNodeId, toNode: nodeId, fromSide: 'right', toSide: 'left' },
107
+ ],
108
+ };
109
+ await manager.removeNode(filePath);
110
+ const writtenData = JSON.parse(vi.mocked(writeFileAtomic).mock.calls[0][1]);
111
+ expect(writtenData.edges).toHaveLength(0);
112
+ });
113
+ });
114
+ describe('updateNodePath', () => {
115
+ it('should update node file path', async () => {
116
+ const oldPath = 'accomplishments/S-001.md';
117
+ const newPath = 'accomplishments/stories/S-001.md';
118
+ const nodeId = 'node-123';
119
+ mockCanvasData = {
120
+ nodes: [{ id: nodeId, type: 'file', file: oldPath, x: 0, y: 0, width: 400, height: 300 }],
121
+ edges: [],
122
+ };
123
+ const result = await manager.updateNodePath(oldPath, newPath);
124
+ expect(result).toBe(true);
125
+ const writtenData = JSON.parse(vi.mocked(writeFileAtomic).mock.calls[0][1]);
126
+ expect(writtenData.nodes[0].file).toBe(newPath);
127
+ });
128
+ it('should return false if node does not exist', async () => {
129
+ const result = await manager.updateNodePath('nonexistent.md', 'new-path.md');
130
+ expect(result).toBe(false);
131
+ expect(writeFileAtomic).not.toHaveBeenCalled();
132
+ });
133
+ });
134
+ describe('addEdge', () => {
135
+ it('should add edge between two existing nodes', async () => {
136
+ const fromPath = 'accomplishments/stories/S-001.md';
137
+ const toPath = 'accomplishments/stories/S-002.md';
138
+ mockCanvasData = {
139
+ nodes: [
140
+ { id: 'node-1', type: 'file', file: fromPath, x: 0, y: 0, width: 400, height: 300 },
141
+ { id: 'node-2', type: 'file', file: toPath, x: 500, y: 0, width: 400, height: 300 },
142
+ ],
143
+ edges: [],
144
+ };
145
+ const edgeId = await manager.addEdge(fromPath, toPath);
146
+ expect(edgeId).toBeTruthy();
147
+ const writtenData = JSON.parse(vi.mocked(writeFileAtomic).mock.calls[0][1]);
148
+ expect(writtenData.edges).toHaveLength(1);
149
+ expect(writtenData.edges[0].fromNode).toBe('node-1');
150
+ expect(writtenData.edges[0].toNode).toBe('node-2');
151
+ });
152
+ it('should return null if from node does not exist', async () => {
153
+ mockCanvasData = {
154
+ nodes: [{ id: 'node-2', type: 'file', file: 'to.md', x: 0, y: 0, width: 400, height: 300 }],
155
+ edges: [],
156
+ };
157
+ const edgeId = await manager.addEdge('from.md', 'to.md');
158
+ expect(edgeId).toBeNull();
159
+ });
160
+ it('should return existing edge ID if edge already exists', async () => {
161
+ const fromPath = 'from.md';
162
+ const toPath = 'to.md';
163
+ const existingEdgeId = 'existing-edge';
164
+ mockCanvasData = {
165
+ nodes: [
166
+ { id: 'node-1', type: 'file', file: fromPath, x: 0, y: 0, width: 400, height: 300 },
167
+ { id: 'node-2', type: 'file', file: toPath, x: 500, y: 0, width: 400, height: 300 },
168
+ ],
169
+ edges: [
170
+ { id: existingEdgeId, fromNode: 'node-1', toNode: 'node-2', fromSide: 'right', toSide: 'left' },
171
+ ],
172
+ };
173
+ const edgeId = await manager.addEdge(fromPath, toPath);
174
+ expect(edgeId).toBe(existingEdgeId);
175
+ expect(writeFileAtomic).not.toHaveBeenCalled();
176
+ });
177
+ });
178
+ describe('removeEdge', () => {
179
+ it('should remove existing edge', async () => {
180
+ const fromPath = 'from.md';
181
+ const toPath = 'to.md';
182
+ mockCanvasData = {
183
+ nodes: [
184
+ { id: 'node-1', type: 'file', file: fromPath, x: 0, y: 0, width: 400, height: 300 },
185
+ { id: 'node-2', type: 'file', file: toPath, x: 500, y: 0, width: 400, height: 300 },
186
+ ],
187
+ edges: [
188
+ { id: 'edge-1', fromNode: 'node-1', toNode: 'node-2', fromSide: 'right', toSide: 'left' },
189
+ ],
190
+ };
191
+ const result = await manager.removeEdge(fromPath, toPath);
192
+ expect(result).toBe(true);
193
+ const writtenData = JSON.parse(vi.mocked(writeFileAtomic).mock.calls[0][1]);
194
+ expect(writtenData.edges).toHaveLength(0);
195
+ });
196
+ it('should return false if edge does not exist', async () => {
197
+ mockCanvasData = {
198
+ nodes: [
199
+ { id: 'node-1', type: 'file', file: 'from.md', x: 0, y: 0, width: 400, height: 300 },
200
+ { id: 'node-2', type: 'file', file: 'to.md', x: 500, y: 0, width: 400, height: 300 },
201
+ ],
202
+ edges: [],
203
+ };
204
+ const result = await manager.removeEdge('from.md', 'to.md');
205
+ expect(result).toBe(false);
206
+ });
207
+ });
208
+ describe('batchUpdate', () => {
209
+ it('should apply multiple operations atomically', async () => {
210
+ const operations = [
211
+ { type: 'add_node', filePath: 'file1.md' },
212
+ { type: 'add_node', filePath: 'file2.md' },
213
+ ];
214
+ const result = await manager.batchUpdate(operations);
215
+ expect(result.success).toBe(true);
216
+ expect(result.nodesAdded).toBe(2);
217
+ expect(writeFileAtomic).toHaveBeenCalledTimes(1); // Single write
218
+ const writtenData = JSON.parse(vi.mocked(writeFileAtomic).mock.calls[0][1]);
219
+ expect(writtenData.nodes).toHaveLength(2);
220
+ });
221
+ it('should handle mixed operations', async () => {
222
+ mockCanvasData = {
223
+ nodes: [
224
+ { id: 'node-1', type: 'file', file: 'existing.md', x: 0, y: 0, width: 400, height: 300 },
225
+ ],
226
+ edges: [],
227
+ };
228
+ const operations = [
229
+ { type: 'add_node', filePath: 'new.md' },
230
+ { type: 'update_node_path', oldPath: 'existing.md', newPath: 'renamed.md' },
231
+ ];
232
+ const result = await manager.batchUpdate(operations);
233
+ expect(result.success).toBe(true);
234
+ expect(result.nodesAdded).toBe(1);
235
+ expect(result.nodesUpdated).toBe(1);
236
+ });
237
+ it('should track removed nodes and edges', async () => {
238
+ mockCanvasData = {
239
+ nodes: [
240
+ { id: 'node-1', type: 'file', file: 'file1.md', x: 0, y: 0, width: 400, height: 300 },
241
+ { id: 'node-2', type: 'file', file: 'file2.md', x: 500, y: 0, width: 400, height: 300 },
242
+ ],
243
+ edges: [
244
+ { id: 'edge-1', fromNode: 'node-1', toNode: 'node-2', fromSide: 'right', toSide: 'left' },
245
+ ],
246
+ };
247
+ const operations = [
248
+ { type: 'remove_node', filePath: 'file1.md' },
249
+ ];
250
+ const result = await manager.batchUpdate(operations);
251
+ expect(result.nodesRemoved).toBe(1);
252
+ // Edge should also be removed since node was removed
253
+ const writtenData = JSON.parse(vi.mocked(writeFileAtomic).mock.calls[0][1]);
254
+ expect(writtenData.edges).toHaveLength(0);
255
+ });
256
+ });
257
+ describe('Query Methods', () => {
258
+ it('should get node by file path', async () => {
259
+ const filePath = 'test.md';
260
+ mockCanvasData = {
261
+ nodes: [{ id: 'node-1', type: 'file', file: filePath, x: 0, y: 0, width: 400, height: 300 }],
262
+ edges: [],
263
+ };
264
+ const node = await manager.getNodeByFilePath(filePath);
265
+ expect(node).not.toBeNull();
266
+ expect(node?.id).toBe('node-1');
267
+ });
268
+ it('should return null for non-existent node', async () => {
269
+ const node = await manager.getNodeByFilePath('nonexistent.md');
270
+ expect(node).toBeNull();
271
+ });
272
+ it('should get all file nodes', async () => {
273
+ mockCanvasData = {
274
+ nodes: [
275
+ { id: 'node-1', type: 'file', file: 'file1.md', x: 0, y: 0, width: 400, height: 300 },
276
+ { id: 'node-2', type: 'file', file: 'file2.md', x: 500, y: 0, width: 400, height: 300 },
277
+ { id: 'node-3', type: 'text', text: 'Some text', x: 1000, y: 0, width: 200, height: 100 },
278
+ ],
279
+ edges: [],
280
+ };
281
+ const nodes = await manager.getAllFileNodes();
282
+ expect(nodes).toHaveLength(2);
283
+ expect(nodes.every(n => n.type === 'file')).toBe(true);
284
+ });
285
+ it('should check if canvas exists', async () => {
286
+ const exists = await manager.canvasExists();
287
+ expect(exists).toBe(true);
288
+ vi.mocked(fs.access).mockRejectedValueOnce(new Error('ENOENT'));
289
+ const notExists = await manager.canvasExists('nonexistent.canvas');
290
+ expect(notExists).toBe(false);
291
+ });
292
+ });
293
+ describe('getDimensionsForType', () => {
294
+ it('should return correct dimensions for milestone', () => {
295
+ const dims = manager.getDimensionsForType('milestone');
296
+ expect(dims.width).toBe(500);
297
+ expect(dims.height).toBe(400);
298
+ });
299
+ it('should return correct dimensions for story', () => {
300
+ const dims = manager.getDimensionsForType('story');
301
+ expect(dims.width).toBe(400);
302
+ expect(dims.height).toBe(300);
303
+ });
304
+ it('should return default dimensions for unknown type', () => {
305
+ const dims = manager.getDimensionsForType('unknown');
306
+ expect(dims.width).toBe(400);
307
+ expect(dims.height).toBe(300);
308
+ });
309
+ });
310
+ describe('Canvas I/O Edge Cases', () => {
311
+ it('should return empty canvas when file does not exist', async () => {
312
+ const error = new Error('ENOENT');
313
+ error.code = 'ENOENT';
314
+ vi.mocked(fs.readFile).mockRejectedValueOnce(error);
315
+ // Should not throw, should work with empty canvas
316
+ const nodeId = await manager.addNode('new-file.md');
317
+ expect(nodeId).toBeTruthy();
318
+ });
319
+ it('should throw on other read errors', async () => {
320
+ const error = new Error('Permission denied');
321
+ error.code = 'EACCES';
322
+ vi.mocked(fs.readFile).mockRejectedValueOnce(error);
323
+ await expect(manager.addNode('file.md')).rejects.toThrow('Permission denied');
324
+ });
325
+ });
326
+ });
327
+ //# sourceMappingURL=canvas-manager.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"canvas-manager.test.js","sourceRoot":"","sources":["../../../src/services/v2/canvas-manager.test.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,54 @@
1
+ /**
2
+ * V2 Cascade Manager
3
+ *
4
+ * Handles cascade effects when entity status changes.
5
+ * Propagates status changes up (to parents) and down (to children).
6
+ */
7
+ import { Entity, EntityId, EntityType, EntityStatus } from '../../models/v2-types.js';
8
+ export interface CascadeRule {
9
+ trigger_type: EntityType;
10
+ trigger_status: EntityStatus;
11
+ target_relation: 'parent' | 'children';
12
+ target_type?: EntityType;
13
+ action: CascadeAction;
14
+ condition?: string;
15
+ }
16
+ export type CascadeAction = 'set_in_progress' | 'check_completion' | 'notify_ready_for_archive' | 'recompute_progress' | 'check_blocked';
17
+ export interface CascadeResult {
18
+ source_id: EntityId;
19
+ affected_entities: EntityId[];
20
+ actions_taken: string[];
21
+ }
22
+ /**
23
+ * Manages cascade effects when entity status changes.
24
+ */
25
+ export declare class CascadeManager {
26
+ private getEntity;
27
+ private getParent;
28
+ private getChildren;
29
+ private updateEntity;
30
+ setEntityCallback(fn: (id: EntityId) => Entity | undefined): void;
31
+ setParentCallback(fn: (id: EntityId) => Entity | undefined): void;
32
+ setChildrenCallback(fn: (id: EntityId, type?: EntityType) => Entity[]): void;
33
+ setUpdateCallback(fn: (entity: Entity) => Promise<void>): void;
34
+ /** Handle status change and apply cascade effects */
35
+ handleStatusChange(entity: Entity, oldStatus: EntityStatus, newStatus: EntityStatus): Promise<CascadeResult>;
36
+ private applyRule;
37
+ private checkCondition;
38
+ private applyAction;
39
+ /** Compute progress percentage for an entity */
40
+ computeProgress(entity: Entity): number;
41
+ /** Compute task progress for a story */
42
+ computeTaskProgress(storyId: EntityId): {
43
+ total: number;
44
+ completed: number;
45
+ percentage: number;
46
+ };
47
+ /** Compute story progress for a milestone */
48
+ computeStoryProgress(milestoneId: EntityId): {
49
+ total: number;
50
+ completed: number;
51
+ percentage: number;
52
+ };
53
+ }
54
+ //# sourceMappingURL=cascade-manager.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cascade-manager.d.ts","sourceRoot":"","sources":["../../../src/services/v2/cascade-manager.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,EACL,MAAM,EACN,QAAQ,EACR,UAAU,EACV,YAAY,EACb,MAAM,0BAA0B,CAAC;AAMlC,MAAM,WAAW,WAAW;IAC1B,YAAY,EAAE,UAAU,CAAC;IACzB,cAAc,EAAE,YAAY,CAAC;IAC7B,eAAe,EAAE,QAAQ,GAAG,UAAU,CAAC;IACvC,WAAW,CAAC,EAAE,UAAU,CAAC;IACzB,MAAM,EAAE,aAAa,CAAC;IACtB,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED,MAAM,MAAM,aAAa,GACrB,iBAAiB,GACjB,kBAAkB,GAClB,0BAA0B,GAC1B,oBAAoB,GACpB,eAAe,CAAC;AAEpB,MAAM,WAAW,aAAa;IAC5B,SAAS,EAAE,QAAQ,CAAC;IACpB,iBAAiB,EAAE,QAAQ,EAAE,CAAC;IAC9B,aAAa,EAAE,MAAM,EAAE,CAAC;CACzB;AAoED;;GAEG;AACH,qBAAa,cAAc;IAEzB,OAAO,CAAC,SAAS,CAAyD;IAC1E,OAAO,CAAC,SAAS,CAAyD;IAC1E,OAAO,CAAC,WAAW,CAA2D;IAC9E,OAAO,CAAC,YAAY,CAAqD;IAMzE,iBAAiB,CAAC,EAAE,EAAE,CAAC,EAAE,EAAE,QAAQ,KAAK,MAAM,GAAG,SAAS,GAAG,IAAI;IAIjE,iBAAiB,CAAC,EAAE,EAAE,CAAC,EAAE,EAAE,QAAQ,KAAK,MAAM,GAAG,SAAS,GAAG,IAAI;IAIjE,mBAAmB,CAAC,EAAE,EAAE,CAAC,EAAE,EAAE,QAAQ,EAAE,IAAI,CAAC,EAAE,UAAU,KAAK,MAAM,EAAE,GAAG,IAAI;IAI5E,iBAAiB,CAAC,EAAE,EAAE,CAAC,MAAM,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,GAAG,IAAI;IAQ9D,qDAAqD;IAC/C,kBAAkB,CACtB,MAAM,EAAE,MAAM,EACd,SAAS,EAAE,YAAY,EACvB,SAAS,EAAE,YAAY,GACtB,OAAO,CAAC,aAAa,CAAC;YAyBX,SAAS;IA8BvB,OAAO,CAAC,cAAc;YAYR,WAAW;IAoDzB,gDAAgD;IAChD,eAAe,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM;IASvC,wCAAwC;IACxC,mBAAmB,CAAC,OAAO,EAAE,QAAQ,GAAG;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,SAAS,EAAE,MAAM,CAAC;QAAC,UAAU,EAAE,MAAM,CAAA;KAAE;IAUhG,6CAA6C;IAC7C,oBAAoB,CAAC,WAAW,EAAE,QAAQ,GAAG;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,SAAS,EAAE,MAAM,CAAC;QAAC,UAAU,EAAE,MAAM,CAAA;KAAE;CAStG"}
@@ -0,0 +1,220 @@
1
+ /**
2
+ * V2 Cascade Manager
3
+ *
4
+ * Handles cascade effects when entity status changes.
5
+ * Propagates status changes up (to parents) and down (to children).
6
+ */
7
+ // =============================================================================
8
+ // Cascade Rules
9
+ // =============================================================================
10
+ const CASCADE_RULES = [
11
+ // Task started → Story in progress
12
+ {
13
+ trigger_type: 'task',
14
+ trigger_status: 'In Progress',
15
+ target_relation: 'parent',
16
+ target_type: 'story',
17
+ action: 'set_in_progress',
18
+ condition: 'parent_not_started',
19
+ },
20
+ // Task completed → Check story completion
21
+ {
22
+ trigger_type: 'task',
23
+ trigger_status: 'Completed',
24
+ target_relation: 'parent',
25
+ target_type: 'story',
26
+ action: 'check_completion',
27
+ },
28
+ // Story started → Milestone in progress
29
+ {
30
+ trigger_type: 'story',
31
+ trigger_status: 'In Progress',
32
+ target_relation: 'parent',
33
+ target_type: 'milestone',
34
+ action: 'set_in_progress',
35
+ condition: 'parent_not_started',
36
+ },
37
+ // Story completed → Check milestone completion
38
+ {
39
+ trigger_type: 'story',
40
+ trigger_status: 'Completed',
41
+ target_relation: 'parent',
42
+ target_type: 'milestone',
43
+ action: 'check_completion',
44
+ },
45
+ // Milestone completed → Notify ready for archive
46
+ {
47
+ trigger_type: 'milestone',
48
+ trigger_status: 'Completed',
49
+ target_relation: 'children',
50
+ target_type: 'story',
51
+ action: 'notify_ready_for_archive',
52
+ },
53
+ // Any status change → Recompute progress
54
+ {
55
+ trigger_type: 'task',
56
+ trigger_status: 'Completed',
57
+ target_relation: 'parent',
58
+ action: 'recompute_progress',
59
+ },
60
+ {
61
+ trigger_type: 'story',
62
+ trigger_status: 'Completed',
63
+ target_relation: 'parent',
64
+ action: 'recompute_progress',
65
+ },
66
+ ];
67
+ // =============================================================================
68
+ // Cascade Manager Class
69
+ // =============================================================================
70
+ /**
71
+ * Manages cascade effects when entity status changes.
72
+ */
73
+ export class CascadeManager {
74
+ // Callbacks for external dependencies
75
+ getEntity = () => undefined;
76
+ getParent = () => undefined;
77
+ getChildren = () => [];
78
+ updateEntity = async () => { };
79
+ // ---------------------------------------------------------------------------
80
+ // Configuration
81
+ // ---------------------------------------------------------------------------
82
+ setEntityCallback(fn) {
83
+ this.getEntity = fn;
84
+ }
85
+ setParentCallback(fn) {
86
+ this.getParent = fn;
87
+ }
88
+ setChildrenCallback(fn) {
89
+ this.getChildren = fn;
90
+ }
91
+ setUpdateCallback(fn) {
92
+ this.updateEntity = fn;
93
+ }
94
+ // ---------------------------------------------------------------------------
95
+ // Cascade Execution
96
+ // ---------------------------------------------------------------------------
97
+ /** Handle status change and apply cascade effects */
98
+ async handleStatusChange(entity, oldStatus, newStatus) {
99
+ const result = {
100
+ source_id: entity.id,
101
+ affected_entities: [],
102
+ actions_taken: [],
103
+ };
104
+ // Find applicable rules
105
+ const rules = CASCADE_RULES.filter(r => r.trigger_type === entity.type && r.trigger_status === newStatus);
106
+ for (const rule of rules) {
107
+ const cascadeResult = await this.applyRule(entity, rule);
108
+ result.affected_entities.push(...cascadeResult.affected);
109
+ result.actions_taken.push(...cascadeResult.actions);
110
+ }
111
+ return result;
112
+ }
113
+ // ---------------------------------------------------------------------------
114
+ // Rule Application
115
+ // ---------------------------------------------------------------------------
116
+ async applyRule(entity, rule) {
117
+ const affected = [];
118
+ const actions = [];
119
+ // Get target entities
120
+ const targets = rule.target_relation === 'parent'
121
+ ? [this.getParent(entity.id)].filter((e) => !!e)
122
+ : this.getChildren(entity.id, rule.target_type);
123
+ for (const target of targets) {
124
+ // Check condition
125
+ if (rule.condition && !this.checkCondition(target, rule.condition)) {
126
+ continue;
127
+ }
128
+ // Apply action
129
+ const actionResult = await this.applyAction(target, rule.action);
130
+ if (actionResult.applied) {
131
+ affected.push(target.id);
132
+ actions.push(actionResult.description);
133
+ }
134
+ }
135
+ return { affected, actions };
136
+ }
137
+ checkCondition(entity, condition) {
138
+ switch (condition) {
139
+ case 'parent_not_started':
140
+ return entity.status === 'Not Started';
141
+ case 'all_children_complete':
142
+ const children = this.getChildren(entity.id);
143
+ return children.every(c => c.status === 'Completed');
144
+ default:
145
+ return true;
146
+ }
147
+ }
148
+ async applyAction(entity, action) {
149
+ switch (action) {
150
+ case 'set_in_progress': {
151
+ if (entity.status === 'Not Started') {
152
+ entity.status = 'In Progress';
153
+ entity.updated_at = new Date().toISOString();
154
+ await this.updateEntity(entity);
155
+ return { applied: true, description: `${entity.id} set to In Progress` };
156
+ }
157
+ return { applied: false, description: '' };
158
+ }
159
+ case 'check_completion': {
160
+ const children = this.getChildren(entity.id);
161
+ const allComplete = children.every(c => c.status === 'Completed');
162
+ if (allComplete && children.length > 0) {
163
+ return {
164
+ applied: true,
165
+ description: `${entity.id} ready for completion (all children complete)`,
166
+ };
167
+ }
168
+ return { applied: false, description: '' };
169
+ }
170
+ case 'notify_ready_for_archive': {
171
+ return {
172
+ applied: true,
173
+ description: `${entity.id} ready for archive`,
174
+ };
175
+ }
176
+ case 'recompute_progress': {
177
+ const progress = this.computeProgress(entity);
178
+ return {
179
+ applied: true,
180
+ description: `${entity.id} progress: ${progress}%`,
181
+ };
182
+ }
183
+ case 'check_blocked': {
184
+ return { applied: false, description: '' };
185
+ }
186
+ }
187
+ }
188
+ // ---------------------------------------------------------------------------
189
+ // Progress Computation
190
+ // ---------------------------------------------------------------------------
191
+ /** Compute progress percentage for an entity */
192
+ computeProgress(entity) {
193
+ const children = this.getChildren(entity.id);
194
+ if (children.length === 0)
195
+ return 0;
196
+ const completed = children.filter(c => c.status === 'Completed').length;
197
+ return Math.round((completed / children.length) * 100);
198
+ }
199
+ /** Compute task progress for a story */
200
+ computeTaskProgress(storyId) {
201
+ const tasks = this.getChildren(storyId, 'task');
202
+ const completed = tasks.filter(t => t.status === 'Completed').length;
203
+ return {
204
+ total: tasks.length,
205
+ completed,
206
+ percentage: tasks.length > 0 ? Math.round((completed / tasks.length) * 100) : 0,
207
+ };
208
+ }
209
+ /** Compute story progress for a milestone */
210
+ computeStoryProgress(milestoneId) {
211
+ const stories = this.getChildren(milestoneId, 'story');
212
+ const completed = stories.filter(s => s.status === 'Completed').length;
213
+ return {
214
+ total: stories.length,
215
+ completed,
216
+ percentage: stories.length > 0 ? Math.round((completed / stories.length) * 100) : 0,
217
+ };
218
+ }
219
+ }
220
+ //# sourceMappingURL=cascade-manager.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cascade-manager.js","sourceRoot":"","sources":["../../../src/services/v2/cascade-manager.ts"],"names":[],"mappings":"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"}