opentasks 0.0.4 → 0.0.6

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 (373) hide show
  1. package/README.md +40 -0
  2. package/dist/cli.d.ts.map +1 -1
  3. package/dist/cli.js +183 -21
  4. package/dist/cli.js.map +1 -1
  5. package/dist/client/client.d.ts.map +1 -1
  6. package/dist/client/client.js +14 -1
  7. package/dist/client/client.js.map +1 -1
  8. package/dist/config/schema.d.ts +139 -3
  9. package/dist/config/schema.d.ts.map +1 -1
  10. package/dist/config/schema.js +118 -2
  11. package/dist/config/schema.js.map +1 -1
  12. package/dist/core/discover.d.ts.map +1 -1
  13. package/dist/core/discover.js +55 -39
  14. package/dist/core/discover.js.map +1 -1
  15. package/dist/core/init.js +1 -1
  16. package/dist/core/init.js.map +1 -1
  17. package/dist/core/merge-driver.d.ts +6 -2
  18. package/dist/core/merge-driver.d.ts.map +1 -1
  19. package/dist/core/merge-driver.js +11 -7
  20. package/dist/core/merge-driver.js.map +1 -1
  21. package/dist/core/worktree.js +1 -1
  22. package/dist/core/worktree.js.map +1 -1
  23. package/dist/daemon/entire-linker.d.ts.map +1 -1
  24. package/dist/daemon/entire-linker.js +48 -42
  25. package/dist/daemon/entire-linker.js.map +1 -1
  26. package/dist/daemon/entire-watcher.d.ts +12 -1
  27. package/dist/daemon/entire-watcher.d.ts.map +1 -1
  28. package/dist/daemon/entire-watcher.js +34 -3
  29. package/dist/daemon/entire-watcher.js.map +1 -1
  30. package/dist/daemon/ipc.d.ts +9 -1
  31. package/dist/daemon/ipc.d.ts.map +1 -1
  32. package/dist/daemon/ipc.js +45 -2
  33. package/dist/daemon/ipc.js.map +1 -1
  34. package/dist/daemon/lifecycle.d.ts.map +1 -1
  35. package/dist/daemon/lifecycle.js +77 -3
  36. package/dist/daemon/lifecycle.js.map +1 -1
  37. package/dist/daemon/location-state.d.ts +3 -0
  38. package/dist/daemon/location-state.d.ts.map +1 -1
  39. package/dist/daemon/location-state.js +49 -2
  40. package/dist/daemon/location-state.js.map +1 -1
  41. package/dist/daemon/methods/watch.d.ts +23 -0
  42. package/dist/daemon/methods/watch.d.ts.map +1 -0
  43. package/dist/daemon/methods/watch.js +172 -0
  44. package/dist/daemon/methods/watch.js.map +1 -0
  45. package/dist/daemon/registry.d.ts.map +1 -1
  46. package/dist/daemon/registry.js +2 -1
  47. package/dist/daemon/registry.js.map +1 -1
  48. package/dist/entire/index.d.ts +1 -0
  49. package/dist/entire/index.d.ts.map +1 -1
  50. package/dist/entire/index.js.map +1 -1
  51. package/dist/entire/store/native-store.d.ts +1 -1
  52. package/dist/entire/store/native-store.d.ts.map +1 -1
  53. package/dist/entire/store/provider-types.d.ts +78 -0
  54. package/dist/entire/store/provider-types.d.ts.map +1 -0
  55. package/dist/entire/store/provider-types.js +12 -0
  56. package/dist/entire/store/provider-types.js.map +1 -0
  57. package/dist/graph/expansion.d.ts +3 -1
  58. package/dist/graph/expansion.d.ts.map +1 -1
  59. package/dist/graph/expansion.js +32 -2
  60. package/dist/graph/expansion.js.map +1 -1
  61. package/dist/graph/git-graph-syncer.d.ts +72 -0
  62. package/dist/graph/git-graph-syncer.d.ts.map +1 -0
  63. package/dist/graph/git-graph-syncer.js +205 -0
  64. package/dist/graph/git-graph-syncer.js.map +1 -0
  65. package/dist/graph/store.d.ts +4 -0
  66. package/dist/graph/store.d.ts.map +1 -1
  67. package/dist/graph/store.js +97 -2
  68. package/dist/graph/store.js.map +1 -1
  69. package/dist/providers/entire.d.ts +34 -69
  70. package/dist/providers/entire.d.ts.map +1 -1
  71. package/dist/providers/entire.js +63 -9
  72. package/dist/providers/entire.js.map +1 -1
  73. package/dist/providers/from-config.d.ts +3 -0
  74. package/dist/providers/from-config.d.ts.map +1 -1
  75. package/dist/providers/from-config.js +45 -20
  76. package/dist/providers/from-config.js.map +1 -1
  77. package/dist/providers/global.d.ts +2 -1
  78. package/dist/providers/global.d.ts.map +1 -1
  79. package/dist/providers/global.js +52 -1
  80. package/dist/providers/global.js.map +1 -1
  81. package/dist/providers/index.d.ts +3 -0
  82. package/dist/providers/index.d.ts.map +1 -1
  83. package/dist/providers/index.js +6 -0
  84. package/dist/providers/index.js.map +1 -1
  85. package/dist/providers/map-client-factory.d.ts +55 -0
  86. package/dist/providers/map-client-factory.d.ts.map +1 -0
  87. package/dist/providers/map-client-factory.js +123 -0
  88. package/dist/providers/map-client-factory.js.map +1 -0
  89. package/dist/providers/map-event-bridge.d.ts +146 -0
  90. package/dist/providers/map-event-bridge.d.ts.map +1 -0
  91. package/dist/providers/map-event-bridge.js +208 -0
  92. package/dist/providers/map-event-bridge.js.map +1 -0
  93. package/dist/providers/map.d.ts +115 -0
  94. package/dist/providers/map.d.ts.map +1 -0
  95. package/dist/providers/map.js +376 -0
  96. package/dist/providers/map.js.map +1 -0
  97. package/dist/tracking/index.d.ts +0 -4
  98. package/dist/tracking/index.d.ts.map +1 -1
  99. package/dist/tracking/index.js +0 -2
  100. package/dist/tracking/index.js.map +1 -1
  101. package/dist/tracking/transcript-extractor.d.ts +0 -6
  102. package/dist/tracking/transcript-extractor.d.ts.map +1 -1
  103. package/dist/tracking/transcript-extractor.js +3 -12
  104. package/dist/tracking/transcript-extractor.js.map +1 -1
  105. package/package.json +3 -1
  106. package/dist/__tests__/cli-tools.test.d.ts +0 -8
  107. package/dist/__tests__/cli-tools.test.d.ts.map +0 -1
  108. package/dist/__tests__/cli-tools.test.js +0 -546
  109. package/dist/__tests__/cli-tools.test.js.map +0 -1
  110. package/dist/__tests__/cli.test.d.ts +0 -5
  111. package/dist/__tests__/cli.test.d.ts.map +0 -1
  112. package/dist/__tests__/cli.test.js +0 -77
  113. package/dist/__tests__/cli.test.js.map +0 -1
  114. package/dist/__tests__/p1-p3-gaps.test.d.ts +0 -2
  115. package/dist/__tests__/p1-p3-gaps.test.d.ts.map +0 -1
  116. package/dist/__tests__/p1-p3-gaps.test.js +0 -463
  117. package/dist/__tests__/p1-p3-gaps.test.js.map +0 -1
  118. package/dist/client/__tests__/client-crud.test.d.ts +0 -7
  119. package/dist/client/__tests__/client-crud.test.d.ts.map +0 -1
  120. package/dist/client/__tests__/client-crud.test.js +0 -404
  121. package/dist/client/__tests__/client-crud.test.js.map +0 -1
  122. package/dist/client/__tests__/client.test.d.ts +0 -5
  123. package/dist/client/__tests__/client.test.d.ts.map +0 -1
  124. package/dist/client/__tests__/client.test.js +0 -518
  125. package/dist/client/__tests__/client.test.js.map +0 -1
  126. package/dist/config/__tests__/defaults.test.d.ts +0 -2
  127. package/dist/config/__tests__/defaults.test.d.ts.map +0 -1
  128. package/dist/config/__tests__/defaults.test.js +0 -57
  129. package/dist/config/__tests__/defaults.test.js.map +0 -1
  130. package/dist/config/__tests__/env.test.d.ts +0 -2
  131. package/dist/config/__tests__/env.test.d.ts.map +0 -1
  132. package/dist/config/__tests__/env.test.js +0 -136
  133. package/dist/config/__tests__/env.test.js.map +0 -1
  134. package/dist/config/__tests__/index.test.d.ts +0 -2
  135. package/dist/config/__tests__/index.test.d.ts.map +0 -1
  136. package/dist/config/__tests__/index.test.js +0 -113
  137. package/dist/config/__tests__/index.test.js.map +0 -1
  138. package/dist/config/__tests__/loader.test.d.ts +0 -2
  139. package/dist/config/__tests__/loader.test.d.ts.map +0 -1
  140. package/dist/config/__tests__/loader.test.js +0 -128
  141. package/dist/config/__tests__/loader.test.js.map +0 -1
  142. package/dist/config/__tests__/merge.test.d.ts +0 -2
  143. package/dist/config/__tests__/merge.test.d.ts.map +0 -1
  144. package/dist/config/__tests__/merge.test.js +0 -79
  145. package/dist/config/__tests__/merge.test.js.map +0 -1
  146. package/dist/config/__tests__/schema.test.d.ts +0 -2
  147. package/dist/config/__tests__/schema.test.d.ts.map +0 -1
  148. package/dist/config/__tests__/schema.test.js +0 -300
  149. package/dist/config/__tests__/schema.test.js.map +0 -1
  150. package/dist/core/__tests__/conditional-redirects.test.d.ts +0 -2
  151. package/dist/core/__tests__/conditional-redirects.test.d.ts.map +0 -1
  152. package/dist/core/__tests__/conditional-redirects.test.js +0 -83
  153. package/dist/core/__tests__/conditional-redirects.test.js.map +0 -1
  154. package/dist/core/__tests__/connections.test.d.ts +0 -2
  155. package/dist/core/__tests__/connections.test.d.ts.map +0 -1
  156. package/dist/core/__tests__/connections.test.js +0 -158
  157. package/dist/core/__tests__/connections.test.js.map +0 -1
  158. package/dist/core/__tests__/hash.test.d.ts +0 -2
  159. package/dist/core/__tests__/hash.test.d.ts.map +0 -1
  160. package/dist/core/__tests__/hash.test.js +0 -139
  161. package/dist/core/__tests__/hash.test.js.map +0 -1
  162. package/dist/core/__tests__/id.test.d.ts +0 -2
  163. package/dist/core/__tests__/id.test.d.ts.map +0 -1
  164. package/dist/core/__tests__/id.test.js +0 -142
  165. package/dist/core/__tests__/id.test.js.map +0 -1
  166. package/dist/core/__tests__/location.test.d.ts +0 -2
  167. package/dist/core/__tests__/location.test.d.ts.map +0 -1
  168. package/dist/core/__tests__/location.test.js +0 -77
  169. package/dist/core/__tests__/location.test.js.map +0 -1
  170. package/dist/core/__tests__/merge-driver.test.d.ts +0 -2
  171. package/dist/core/__tests__/merge-driver.test.d.ts.map +0 -1
  172. package/dist/core/__tests__/merge-driver.test.js +0 -218
  173. package/dist/core/__tests__/merge-driver.test.js.map +0 -1
  174. package/dist/core/__tests__/redirects.test.d.ts +0 -2
  175. package/dist/core/__tests__/redirects.test.d.ts.map +0 -1
  176. package/dist/core/__tests__/redirects.test.js +0 -123
  177. package/dist/core/__tests__/redirects.test.js.map +0 -1
  178. package/dist/core/__tests__/resolve-location-target.test.d.ts +0 -8
  179. package/dist/core/__tests__/resolve-location-target.test.d.ts.map +0 -1
  180. package/dist/core/__tests__/resolve-location-target.test.js +0 -303
  181. package/dist/core/__tests__/resolve-location-target.test.js.map +0 -1
  182. package/dist/core/__tests__/uri.test.d.ts +0 -2
  183. package/dist/core/__tests__/uri.test.d.ts.map +0 -1
  184. package/dist/core/__tests__/uri.test.js +0 -159
  185. package/dist/core/__tests__/uri.test.js.map +0 -1
  186. package/dist/core/__tests__/worktree.test.d.ts +0 -2
  187. package/dist/core/__tests__/worktree.test.d.ts.map +0 -1
  188. package/dist/core/__tests__/worktree.test.js +0 -120
  189. package/dist/core/__tests__/worktree.test.js.map +0 -1
  190. package/dist/daemon/__tests__/flush.test.d.ts +0 -5
  191. package/dist/daemon/__tests__/flush.test.d.ts.map +0 -1
  192. package/dist/daemon/__tests__/flush.test.js +0 -213
  193. package/dist/daemon/__tests__/flush.test.js.map +0 -1
  194. package/dist/daemon/__tests__/integration.test.d.ts +0 -7
  195. package/dist/daemon/__tests__/integration.test.d.ts.map +0 -1
  196. package/dist/daemon/__tests__/integration.test.js +0 -276
  197. package/dist/daemon/__tests__/integration.test.js.map +0 -1
  198. package/dist/daemon/__tests__/ipc.test.d.ts +0 -5
  199. package/dist/daemon/__tests__/ipc.test.d.ts.map +0 -1
  200. package/dist/daemon/__tests__/ipc.test.js +0 -314
  201. package/dist/daemon/__tests__/ipc.test.js.map +0 -1
  202. package/dist/daemon/__tests__/lifecycle.test.d.ts +0 -5
  203. package/dist/daemon/__tests__/lifecycle.test.d.ts.map +0 -1
  204. package/dist/daemon/__tests__/lifecycle.test.js +0 -301
  205. package/dist/daemon/__tests__/lifecycle.test.js.map +0 -1
  206. package/dist/daemon/__tests__/lock.test.d.ts +0 -5
  207. package/dist/daemon/__tests__/lock.test.d.ts.map +0 -1
  208. package/dist/daemon/__tests__/lock.test.js +0 -192
  209. package/dist/daemon/__tests__/lock.test.js.map +0 -1
  210. package/dist/daemon/__tests__/methods/graph.test.d.ts +0 -5
  211. package/dist/daemon/__tests__/methods/graph.test.d.ts.map +0 -1
  212. package/dist/daemon/__tests__/methods/graph.test.js +0 -309
  213. package/dist/daemon/__tests__/methods/graph.test.js.map +0 -1
  214. package/dist/daemon/__tests__/methods/provider.test.d.ts +0 -7
  215. package/dist/daemon/__tests__/methods/provider.test.d.ts.map +0 -1
  216. package/dist/daemon/__tests__/methods/provider.test.js +0 -181
  217. package/dist/daemon/__tests__/methods/provider.test.js.map +0 -1
  218. package/dist/daemon/__tests__/methods/tools.test.d.ts +0 -5
  219. package/dist/daemon/__tests__/methods/tools.test.d.ts.map +0 -1
  220. package/dist/daemon/__tests__/methods/tools.test.js +0 -587
  221. package/dist/daemon/__tests__/methods/tools.test.js.map +0 -1
  222. package/dist/daemon/__tests__/multi-location.test.d.ts +0 -8
  223. package/dist/daemon/__tests__/multi-location.test.d.ts.map +0 -1
  224. package/dist/daemon/__tests__/multi-location.test.js +0 -669
  225. package/dist/daemon/__tests__/multi-location.test.js.map +0 -1
  226. package/dist/daemon/__tests__/registry.test.d.ts +0 -5
  227. package/dist/daemon/__tests__/registry.test.d.ts.map +0 -1
  228. package/dist/daemon/__tests__/registry.test.js +0 -208
  229. package/dist/daemon/__tests__/registry.test.js.map +0 -1
  230. package/dist/daemon/__tests__/watcher.test.d.ts +0 -5
  231. package/dist/daemon/__tests__/watcher.test.d.ts.map +0 -1
  232. package/dist/daemon/__tests__/watcher.test.js +0 -234
  233. package/dist/daemon/__tests__/watcher.test.js.map +0 -1
  234. package/dist/daemon/methods/__tests__/graph.test.d.ts +0 -5
  235. package/dist/daemon/methods/__tests__/graph.test.d.ts.map +0 -1
  236. package/dist/daemon/methods/__tests__/graph.test.js +0 -274
  237. package/dist/daemon/methods/__tests__/graph.test.js.map +0 -1
  238. package/dist/daemon/methods/__tests__/provider.test.d.ts +0 -5
  239. package/dist/daemon/methods/__tests__/provider.test.d.ts.map +0 -1
  240. package/dist/daemon/methods/__tests__/provider.test.js +0 -184
  241. package/dist/daemon/methods/__tests__/provider.test.js.map +0 -1
  242. package/dist/daemon/methods/__tests__/tools.test.d.ts +0 -5
  243. package/dist/daemon/methods/__tests__/tools.test.d.ts.map +0 -1
  244. package/dist/daemon/methods/__tests__/tools.test.js +0 -295
  245. package/dist/daemon/methods/__tests__/tools.test.js.map +0 -1
  246. package/dist/graph/__tests__/EdgeTypeRegistry.test.d.ts +0 -2
  247. package/dist/graph/__tests__/EdgeTypeRegistry.test.d.ts.map +0 -1
  248. package/dist/graph/__tests__/EdgeTypeRegistry.test.js +0 -212
  249. package/dist/graph/__tests__/EdgeTypeRegistry.test.js.map +0 -1
  250. package/dist/graph/__tests__/FederatedGraph.test.d.ts +0 -2
  251. package/dist/graph/__tests__/FederatedGraph.test.d.ts.map +0 -1
  252. package/dist/graph/__tests__/FederatedGraph.test.js +0 -661
  253. package/dist/graph/__tests__/FederatedGraph.test.js.map +0 -1
  254. package/dist/graph/__tests__/GraphologyAdapter.test.d.ts +0 -2
  255. package/dist/graph/__tests__/GraphologyAdapter.test.d.ts.map +0 -1
  256. package/dist/graph/__tests__/GraphologyAdapter.test.js +0 -326
  257. package/dist/graph/__tests__/GraphologyAdapter.test.js.map +0 -1
  258. package/dist/graph/__tests__/HydratingFederatedGraph.test.d.ts +0 -2
  259. package/dist/graph/__tests__/HydratingFederatedGraph.test.d.ts.map +0 -1
  260. package/dist/graph/__tests__/HydratingFederatedGraph.test.js +0 -587
  261. package/dist/graph/__tests__/HydratingFederatedGraph.test.js.map +0 -1
  262. package/dist/graph/__tests__/debounce.test.d.ts +0 -5
  263. package/dist/graph/__tests__/debounce.test.d.ts.map +0 -1
  264. package/dist/graph/__tests__/debounce.test.js +0 -195
  265. package/dist/graph/__tests__/debounce.test.js.map +0 -1
  266. package/dist/graph/__tests__/edge-cases.test.d.ts +0 -8
  267. package/dist/graph/__tests__/edge-cases.test.d.ts.map +0 -1
  268. package/dist/graph/__tests__/edge-cases.test.js +0 -472
  269. package/dist/graph/__tests__/edge-cases.test.js.map +0 -1
  270. package/dist/graph/__tests__/expansion.test.d.ts +0 -2
  271. package/dist/graph/__tests__/expansion.test.d.ts.map +0 -1
  272. package/dist/graph/__tests__/expansion.test.js +0 -105
  273. package/dist/graph/__tests__/expansion.test.js.map +0 -1
  274. package/dist/graph/__tests__/provider-store.test.d.ts +0 -5
  275. package/dist/graph/__tests__/provider-store.test.d.ts.map +0 -1
  276. package/dist/graph/__tests__/provider-store.test.js +0 -791
  277. package/dist/graph/__tests__/provider-store.test.js.map +0 -1
  278. package/dist/graph/__tests__/query.test.d.ts +0 -5
  279. package/dist/graph/__tests__/query.test.d.ts.map +0 -1
  280. package/dist/graph/__tests__/query.test.js +0 -774
  281. package/dist/graph/__tests__/query.test.js.map +0 -1
  282. package/dist/graph/__tests__/store.test.d.ts +0 -5
  283. package/dist/graph/__tests__/store.test.d.ts.map +0 -1
  284. package/dist/graph/__tests__/store.test.js +0 -489
  285. package/dist/graph/__tests__/store.test.js.map +0 -1
  286. package/dist/graph/__tests__/sync.test.d.ts +0 -5
  287. package/dist/graph/__tests__/sync.test.d.ts.map +0 -1
  288. package/dist/graph/__tests__/sync.test.js +0 -129
  289. package/dist/graph/__tests__/sync.test.js.map +0 -1
  290. package/dist/graph/__tests__/validation.test.d.ts +0 -2
  291. package/dist/graph/__tests__/validation.test.d.ts.map +0 -1
  292. package/dist/graph/__tests__/validation.test.js +0 -521
  293. package/dist/graph/__tests__/validation.test.js.map +0 -1
  294. package/dist/providers/__tests__/beads.test.d.ts +0 -5
  295. package/dist/providers/__tests__/beads.test.d.ts.map +0 -1
  296. package/dist/providers/__tests__/beads.test.js +0 -591
  297. package/dist/providers/__tests__/beads.test.js.map +0 -1
  298. package/dist/providers/__tests__/claude-tasks.test.d.ts +0 -5
  299. package/dist/providers/__tests__/claude-tasks.test.d.ts.map +0 -1
  300. package/dist/providers/__tests__/claude-tasks.test.js +0 -392
  301. package/dist/providers/__tests__/claude-tasks.test.js.map +0 -1
  302. package/dist/providers/__tests__/from-config.test.d.ts +0 -5
  303. package/dist/providers/__tests__/from-config.test.d.ts.map +0 -1
  304. package/dist/providers/__tests__/from-config.test.js +0 -152
  305. package/dist/providers/__tests__/from-config.test.js.map +0 -1
  306. package/dist/providers/__tests__/materialization.test.d.ts +0 -5
  307. package/dist/providers/__tests__/materialization.test.d.ts.map +0 -1
  308. package/dist/providers/__tests__/materialization.test.js +0 -407
  309. package/dist/providers/__tests__/materialization.test.js.map +0 -1
  310. package/dist/providers/__tests__/native.test.d.ts +0 -5
  311. package/dist/providers/__tests__/native.test.d.ts.map +0 -1
  312. package/dist/providers/__tests__/native.test.js +0 -566
  313. package/dist/providers/__tests__/native.test.js.map +0 -1
  314. package/dist/providers/__tests__/registry.test.d.ts +0 -5
  315. package/dist/providers/__tests__/registry.test.d.ts.map +0 -1
  316. package/dist/providers/__tests__/registry.test.js +0 -183
  317. package/dist/providers/__tests__/registry.test.js.map +0 -1
  318. package/dist/providers/traits/__tests__/RelationshipQueryable.test.d.ts +0 -2
  319. package/dist/providers/traits/__tests__/RelationshipQueryable.test.d.ts.map +0 -1
  320. package/dist/providers/traits/__tests__/RelationshipQueryable.test.js +0 -169
  321. package/dist/providers/traits/__tests__/RelationshipQueryable.test.js.map +0 -1
  322. package/dist/providers/traits/__tests__/TaskManageable.test.d.ts +0 -2
  323. package/dist/providers/traits/__tests__/TaskManageable.test.d.ts.map +0 -1
  324. package/dist/providers/traits/__tests__/TaskManageable.test.js +0 -172
  325. package/dist/providers/traits/__tests__/TaskManageable.test.js.map +0 -1
  326. package/dist/schema/__tests__/validation.test.d.ts +0 -2
  327. package/dist/schema/__tests__/validation.test.d.ts.map +0 -1
  328. package/dist/schema/__tests__/validation.test.js +0 -241
  329. package/dist/schema/__tests__/validation.test.js.map +0 -1
  330. package/dist/storage/__tests__/atomic-write.test.d.ts +0 -5
  331. package/dist/storage/__tests__/atomic-write.test.d.ts.map +0 -1
  332. package/dist/storage/__tests__/atomic-write.test.js +0 -170
  333. package/dist/storage/__tests__/atomic-write.test.js.map +0 -1
  334. package/dist/storage/__tests__/file-lock.test.d.ts +0 -2
  335. package/dist/storage/__tests__/file-lock.test.d.ts.map +0 -1
  336. package/dist/storage/__tests__/file-lock.test.js +0 -89
  337. package/dist/storage/__tests__/file-lock.test.js.map +0 -1
  338. package/dist/storage/__tests__/jsonl.test.d.ts +0 -2
  339. package/dist/storage/__tests__/jsonl.test.d.ts.map +0 -1
  340. package/dist/storage/__tests__/jsonl.test.js +0 -228
  341. package/dist/storage/__tests__/jsonl.test.js.map +0 -1
  342. package/dist/storage/__tests__/locked-writer.test.d.ts +0 -2
  343. package/dist/storage/__tests__/locked-writer.test.d.ts.map +0 -1
  344. package/dist/storage/__tests__/locked-writer.test.js +0 -109
  345. package/dist/storage/__tests__/locked-writer.test.js.map +0 -1
  346. package/dist/storage/__tests__/sqlite.test.d.ts +0 -2
  347. package/dist/storage/__tests__/sqlite.test.d.ts.map +0 -1
  348. package/dist/storage/__tests__/sqlite.test.js +0 -470
  349. package/dist/storage/__tests__/sqlite.test.js.map +0 -1
  350. package/dist/tools/__tests__/annotate.test.d.ts +0 -5
  351. package/dist/tools/__tests__/annotate.test.d.ts.map +0 -1
  352. package/dist/tools/__tests__/annotate.test.js +0 -314
  353. package/dist/tools/__tests__/annotate.test.js.map +0 -1
  354. package/dist/tools/__tests__/link.test.d.ts +0 -5
  355. package/dist/tools/__tests__/link.test.d.ts.map +0 -1
  356. package/dist/tools/__tests__/link.test.js +0 -245
  357. package/dist/tools/__tests__/link.test.js.map +0 -1
  358. package/dist/tools/__tests__/query.test.d.ts +0 -5
  359. package/dist/tools/__tests__/query.test.d.ts.map +0 -1
  360. package/dist/tools/__tests__/query.test.js +0 -288
  361. package/dist/tools/__tests__/query.test.js.map +0 -1
  362. package/dist/tools/__tests__/task.test.d.ts +0 -5
  363. package/dist/tools/__tests__/task.test.d.ts.map +0 -1
  364. package/dist/tools/__tests__/task.test.js +0 -178
  365. package/dist/tools/__tests__/task.test.js.map +0 -1
  366. package/dist/tracking/claude-task-reconstructor.d.ts +0 -41
  367. package/dist/tracking/claude-task-reconstructor.d.ts.map +0 -1
  368. package/dist/tracking/claude-task-reconstructor.js +0 -91
  369. package/dist/tracking/claude-task-reconstructor.js.map +0 -1
  370. package/dist/tracking/plan-mode-tracker.d.ts +0 -20
  371. package/dist/tracking/plan-mode-tracker.d.ts.map +0 -1
  372. package/dist/tracking/plan-mode-tracker.js +0 -35
  373. package/dist/tracking/plan-mode-tracker.js.map +0 -1
@@ -1,129 +0,0 @@
1
- /**
2
- * Tests for Sync Manager
3
- */
4
- import { describe, it, expect, beforeEach, vi, afterEach } from 'vitest';
5
- import { createSyncManager } from '../sync.js';
6
- describe('SyncManager', () => {
7
- let storage;
8
- let syncManager;
9
- let flushCallback;
10
- const config = {
11
- debounceMs: 100,
12
- maxDelayMs: 500,
13
- };
14
- beforeEach(() => {
15
- vi.useFakeTimers();
16
- // Create mock storage
17
- const dirtyNodes = new Set();
18
- storage = {
19
- markDirty: vi.fn().mockImplementation(async (nodeId) => {
20
- dirtyNodes.add(nodeId);
21
- }),
22
- getDirtyNodes: vi.fn().mockImplementation(async () => {
23
- return Array.from(dirtyNodes);
24
- }),
25
- clearDirty: vi.fn().mockImplementation(async (nodeIds) => {
26
- for (const id of nodeIds) {
27
- dirtyNodes.delete(id);
28
- }
29
- }),
30
- };
31
- flushCallback = vi.fn().mockResolvedValue(undefined);
32
- syncManager = createSyncManager(config, storage, flushCallback);
33
- });
34
- afterEach(() => {
35
- vi.useRealTimers();
36
- syncManager.cancel();
37
- });
38
- describe('markDirty', () => {
39
- it('should track dirty nodes', () => {
40
- syncManager.markDirty('s-abc1');
41
- syncManager.markDirty('s-abc2');
42
- expect(syncManager.hasPendingChanges()).toBe(true);
43
- });
44
- });
45
- describe('scheduleFlush', () => {
46
- it('should flush after debounce delay', async () => {
47
- syncManager.markDirty('s-abc1');
48
- syncManager.scheduleFlush();
49
- expect(flushCallback).not.toHaveBeenCalled();
50
- // Advance past debounce
51
- await vi.advanceTimersByTimeAsync(config.debounceMs + 10);
52
- expect(flushCallback).toHaveBeenCalled();
53
- });
54
- it('should reset debounce timer on multiple calls', async () => {
55
- syncManager.markDirty('s-abc1');
56
- syncManager.scheduleFlush();
57
- // Advance halfway
58
- await vi.advanceTimersByTimeAsync(config.debounceMs / 2);
59
- syncManager.markDirty('s-abc2');
60
- syncManager.scheduleFlush();
61
- // Advance halfway again (would be past original debounce)
62
- await vi.advanceTimersByTimeAsync(config.debounceMs / 2);
63
- // Should not have flushed yet (debounce was reset)
64
- expect(flushCallback).not.toHaveBeenCalled();
65
- // Advance remaining time
66
- await vi.advanceTimersByTimeAsync(config.debounceMs / 2 + 10);
67
- expect(flushCallback).toHaveBeenCalled();
68
- });
69
- it('should force flush at max delay', async () => {
70
- syncManager.markDirty('s-abc1');
71
- syncManager.scheduleFlush();
72
- // Keep resetting debounce but stay under max delay
73
- // debounceMs = 100, maxDelayMs = 500
74
- // Advance 80ms at a time, which is less than debounce
75
- // After 4 iterations: 320ms total (still under 500ms max)
76
- for (let i = 0; i < 4; i++) {
77
- await vi.advanceTimersByTimeAsync(80);
78
- syncManager.scheduleFlush();
79
- }
80
- // Should not have flushed yet (320ms < 500ms maxDelay)
81
- expect(flushCallback).not.toHaveBeenCalled();
82
- // Advance to max delay (need another 180ms to reach 500ms)
83
- await vi.advanceTimersByTimeAsync(200);
84
- expect(flushCallback).toHaveBeenCalled();
85
- });
86
- });
87
- describe('flush', () => {
88
- it('should flush immediately', async () => {
89
- syncManager.markDirty('s-abc1');
90
- await syncManager.flush();
91
- expect(flushCallback).toHaveBeenCalled();
92
- });
93
- it('should clear pending changes after flush', async () => {
94
- syncManager.markDirty('s-abc1');
95
- await syncManager.flush();
96
- expect(syncManager.hasPendingChanges()).toBe(false);
97
- });
98
- it('should not flush when no pending changes', async () => {
99
- await syncManager.flush();
100
- expect(flushCallback).not.toHaveBeenCalled();
101
- });
102
- it('should deduplicate concurrent flush calls', async () => {
103
- syncManager.markDirty('s-abc1');
104
- // Call flush multiple times concurrently
105
- const promise1 = syncManager.flush();
106
- const promise2 = syncManager.flush();
107
- const promise3 = syncManager.flush();
108
- await Promise.all([promise1, promise2, promise3]);
109
- // Should only call flush callback once
110
- expect(flushCallback).toHaveBeenCalledTimes(1);
111
- });
112
- });
113
- describe('cancel', () => {
114
- it('should cancel pending flush', async () => {
115
- syncManager.markDirty('s-abc1');
116
- syncManager.scheduleFlush();
117
- syncManager.cancel();
118
- // Advance past debounce
119
- await vi.advanceTimersByTimeAsync(config.debounceMs + 10);
120
- expect(flushCallback).not.toHaveBeenCalled();
121
- });
122
- it('should clear pending changes', () => {
123
- syncManager.markDirty('s-abc1');
124
- syncManager.cancel();
125
- expect(syncManager.hasPendingChanges()).toBe(false);
126
- });
127
- });
128
- });
129
- //# sourceMappingURL=sync.test.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"sync.test.js","sourceRoot":"","sources":["../../../src/graph/__tests__/sync.test.ts"],"names":[],"mappings":"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"}
@@ -1,2 +0,0 @@
1
- export {};
2
- //# sourceMappingURL=validation.test.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"validation.test.d.ts","sourceRoot":"","sources":["../../../src/graph/__tests__/validation.test.ts"],"names":[],"mappings":""}
@@ -1,521 +0,0 @@
1
- import { describe, it, expect } from 'vitest';
2
- import { createValidationService } from '../validation.js';
3
- describe('ValidationService', () => {
4
- const service = createValidationService();
5
- // =========================================================================
6
- // Node Creation Validation
7
- // =========================================================================
8
- describe('validateCreateNode', () => {
9
- describe('common fields', () => {
10
- it('requires type', () => {
11
- const input = { title: 'Test' };
12
- const result = service.validateCreateNode(input);
13
- expect(result.valid).toBe(false);
14
- expect(result.errors).toContainEqual(expect.objectContaining({ code: 'REQUIRED', field: 'type' }));
15
- });
16
- it('rejects invalid type', () => {
17
- const input = { type: 'invalid', title: 'Test' };
18
- const result = service.validateCreateNode(input);
19
- expect(result.valid).toBe(false);
20
- expect(result.errors).toContainEqual(expect.objectContaining({ code: 'INVALID_TYPE', field: 'type' }));
21
- });
22
- it('requires title', () => {
23
- const input = { type: 'spec' };
24
- const result = service.validateCreateNode(input);
25
- expect(result.valid).toBe(false);
26
- expect(result.errors).toContainEqual(expect.objectContaining({ code: 'REQUIRED', field: 'title' }));
27
- });
28
- it('rejects empty title', () => {
29
- const input = { type: 'spec', title: '' };
30
- const result = service.validateCreateNode(input);
31
- expect(result.valid).toBe(false);
32
- expect(result.errors).toContainEqual(expect.objectContaining({ code: 'REQUIRED', field: 'title' }));
33
- });
34
- it('rejects title exceeding max length', () => {
35
- const input = {
36
- type: 'spec',
37
- title: 'a'.repeat(501),
38
- };
39
- const result = service.validateCreateNode(input);
40
- expect(result.valid).toBe(false);
41
- expect(result.errors).toContainEqual(expect.objectContaining({ code: 'MAX_LENGTH', field: 'title' }));
42
- });
43
- it('rejects content exceeding max length', () => {
44
- const input = {
45
- type: 'spec',
46
- title: 'Test',
47
- content: 'a'.repeat(100_001),
48
- };
49
- const result = service.validateCreateNode(input);
50
- expect(result.valid).toBe(false);
51
- expect(result.errors).toContainEqual(expect.objectContaining({ code: 'MAX_LENGTH', field: 'content' }));
52
- });
53
- it('rejects invalid priority (out of range)', () => {
54
- const input = {
55
- type: 'spec',
56
- title: 'Test',
57
- priority: 5,
58
- };
59
- const result = service.validateCreateNode(input);
60
- expect(result.valid).toBe(false);
61
- expect(result.errors).toContainEqual(expect.objectContaining({ code: 'INVALID_RANGE', field: 'priority' }));
62
- });
63
- it('rejects negative priority', () => {
64
- const input = {
65
- type: 'spec',
66
- title: 'Test',
67
- priority: -1,
68
- };
69
- const result = service.validateCreateNode(input);
70
- expect(result.valid).toBe(false);
71
- expect(result.errors).toContainEqual(expect.objectContaining({ code: 'INVALID_RANGE', field: 'priority' }));
72
- });
73
- it('accepts valid priority', () => {
74
- const input = {
75
- type: 'spec',
76
- title: 'Test',
77
- priority: 2,
78
- };
79
- const result = service.validateCreateNode(input);
80
- expect(result.valid).toBe(true);
81
- });
82
- });
83
- describe('spec validation', () => {
84
- it('accepts valid spec', () => {
85
- const input = {
86
- type: 'spec',
87
- title: 'Test Spec',
88
- content: 'Some content',
89
- };
90
- const result = service.validateCreateNode(input);
91
- expect(result.valid).toBe(true);
92
- expect(result.errors).toHaveLength(0);
93
- });
94
- it('accepts spec with optional status', () => {
95
- const input = {
96
- type: 'spec',
97
- title: 'Test Spec',
98
- status: 'draft',
99
- };
100
- const result = service.validateCreateNode(input);
101
- expect(result.valid).toBe(true);
102
- });
103
- });
104
- describe('issue validation', () => {
105
- it('requires status for issues', () => {
106
- const input = {
107
- type: 'issue',
108
- title: 'Test Issue',
109
- };
110
- const result = service.validateCreateNode(input);
111
- expect(result.valid).toBe(false);
112
- expect(result.errors).toContainEqual(expect.objectContaining({ code: 'REQUIRED', field: 'status' }));
113
- });
114
- it('accepts valid issue', () => {
115
- const input = {
116
- type: 'issue',
117
- title: 'Test Issue',
118
- status: 'open',
119
- };
120
- const result = service.validateCreateNode(input);
121
- expect(result.valid).toBe(true);
122
- });
123
- it('warns for non-standard status', () => {
124
- const input = {
125
- type: 'issue',
126
- title: 'Test Issue',
127
- status: 'custom_status',
128
- };
129
- const result = service.validateCreateNode(input);
130
- expect(result.valid).toBe(true); // Warnings don't fail validation
131
- expect(result.warnings).toContainEqual(expect.objectContaining({
132
- code: 'NON_STANDARD_STATUS',
133
- field: 'status',
134
- }));
135
- });
136
- });
137
- describe('feedback validation', () => {
138
- it('requires target_id for feedback', () => {
139
- const input = {
140
- type: 'feedback',
141
- title: 'Test Feedback',
142
- feedback_type: 'comment',
143
- };
144
- const result = service.validateCreateNode(input);
145
- expect(result.valid).toBe(false);
146
- expect(result.errors).toContainEqual(expect.objectContaining({ code: 'REQUIRED', field: 'target_id' }));
147
- });
148
- it('requires feedback_type for feedback', () => {
149
- const input = {
150
- type: 'feedback',
151
- title: 'Test Feedback',
152
- target_id: 's-abc123',
153
- };
154
- const result = service.validateCreateNode(input);
155
- expect(result.valid).toBe(false);
156
- expect(result.errors).toContainEqual(expect.objectContaining({ code: 'REQUIRED', field: 'feedback_type' }));
157
- });
158
- it('accepts valid feedback', () => {
159
- const input = {
160
- type: 'feedback',
161
- title: 'Test Feedback',
162
- target_id: 's-abc123',
163
- feedback_type: 'comment',
164
- };
165
- const result = service.validateCreateNode(input);
166
- expect(result.valid).toBe(true);
167
- });
168
- });
169
- describe('external validation', () => {
170
- it('requires uri for external', () => {
171
- const input = {
172
- type: 'external',
173
- title: 'External Node',
174
- source: 'jira',
175
- };
176
- const result = service.validateCreateNode(input);
177
- expect(result.valid).toBe(false);
178
- expect(result.errors).toContainEqual(expect.objectContaining({ code: 'REQUIRED', field: 'uri' }));
179
- });
180
- it('requires source for external', () => {
181
- const input = {
182
- type: 'external',
183
- title: 'External Node',
184
- uri: 'jira://PROJ-123',
185
- };
186
- const result = service.validateCreateNode(input);
187
- expect(result.valid).toBe(false);
188
- expect(result.errors).toContainEqual(expect.objectContaining({ code: 'REQUIRED', field: 'source' }));
189
- });
190
- it('accepts valid external node', () => {
191
- const input = {
192
- type: 'external',
193
- title: 'External Node',
194
- uri: 'jira://PROJ-123',
195
- source: 'jira',
196
- };
197
- const result = service.validateCreateNode(input);
198
- expect(result.valid).toBe(true);
199
- });
200
- });
201
- });
202
- // =========================================================================
203
- // Node Update Validation
204
- // =========================================================================
205
- describe('validateUpdateNode', () => {
206
- const existingIssue = {
207
- id: 'i-test',
208
- uuid: 'test-uuid',
209
- type: 'issue',
210
- title: 'Existing Issue',
211
- status: 'open',
212
- created_at: '2025-01-26T10:00:00Z',
213
- updated_at: '2025-01-26T10:00:00Z',
214
- };
215
- it('accepts valid update', () => {
216
- const result = service.validateUpdateNode(existingIssue, {
217
- title: 'Updated Title',
218
- });
219
- expect(result.valid).toBe(true);
220
- });
221
- it('rejects title exceeding max length', () => {
222
- const result = service.validateUpdateNode(existingIssue, {
223
- title: 'a'.repeat(501),
224
- });
225
- expect(result.valid).toBe(false);
226
- expect(result.errors).toContainEqual(expect.objectContaining({ code: 'MAX_LENGTH', field: 'title' }));
227
- });
228
- it('warns for non-standard status on issues', () => {
229
- const result = service.validateUpdateNode(existingIssue, {
230
- status: 'custom',
231
- });
232
- expect(result.valid).toBe(true);
233
- expect(result.warnings).toContainEqual(expect.objectContaining({ code: 'NON_STANDARD_STATUS' }));
234
- });
235
- });
236
- // =========================================================================
237
- // Edge Validation
238
- // =========================================================================
239
- describe('validateCreateEdge', () => {
240
- const mockGetNode = async (id) => {
241
- const nodes = {
242
- 's-spec1': {
243
- id: 's-spec1',
244
- uuid: 'spec-uuid',
245
- type: 'spec',
246
- title: 'Test Spec',
247
- created_at: '2025-01-26T10:00:00Z',
248
- updated_at: '2025-01-26T10:00:00Z',
249
- },
250
- 'i-issue1': {
251
- id: 'i-issue1',
252
- uuid: 'issue-uuid',
253
- type: 'issue',
254
- title: 'Test Issue',
255
- status: 'open',
256
- created_at: '2025-01-26T10:00:00Z',
257
- updated_at: '2025-01-26T10:00:00Z',
258
- },
259
- };
260
- return nodes[id] || null;
261
- };
262
- it('requires from_id', async () => {
263
- const input = { to_id: 's-spec1', type: 'blocks' };
264
- const result = await service.validateCreateEdge(input, mockGetNode);
265
- expect(result.valid).toBe(false);
266
- expect(result.errors).toContainEqual(expect.objectContaining({ code: 'REQUIRED', field: 'from_id' }));
267
- });
268
- it('requires to_id', async () => {
269
- const input = { from_id: 'i-issue1', type: 'blocks' };
270
- const result = await service.validateCreateEdge(input, mockGetNode);
271
- expect(result.valid).toBe(false);
272
- expect(result.errors).toContainEqual(expect.objectContaining({ code: 'REQUIRED', field: 'to_id' }));
273
- });
274
- it('requires type', async () => {
275
- const input = { from_id: 'i-issue1', to_id: 's-spec1' };
276
- const result = await service.validateCreateEdge(input, mockGetNode);
277
- expect(result.valid).toBe(false);
278
- expect(result.errors).toContainEqual(expect.objectContaining({ code: 'REQUIRED', field: 'type' }));
279
- });
280
- it('rejects self-reference', async () => {
281
- const input = {
282
- from_id: 'i-issue1',
283
- to_id: 'i-issue1',
284
- type: 'blocks',
285
- };
286
- const result = await service.validateCreateEdge(input, mockGetNode);
287
- expect(result.valid).toBe(false);
288
- expect(result.errors).toContainEqual(expect.objectContaining({ code: 'SELF_REFERENCE' }));
289
- });
290
- it('errors when source node not found', async () => {
291
- const input = {
292
- from_id: 'i-nonexistent',
293
- to_id: 's-spec1',
294
- type: 'implements',
295
- };
296
- const result = await service.validateCreateEdge(input, mockGetNode);
297
- expect(result.valid).toBe(false);
298
- expect(result.errors).toContainEqual(expect.objectContaining({ code: 'NOT_FOUND', field: 'from_id' }));
299
- });
300
- it('errors when target node not found', async () => {
301
- const input = {
302
- from_id: 'i-issue1',
303
- to_id: 's-nonexistent',
304
- type: 'implements',
305
- };
306
- const result = await service.validateCreateEdge(input, mockGetNode);
307
- expect(result.valid).toBe(false);
308
- expect(result.errors).toContainEqual(expect.objectContaining({ code: 'NOT_FOUND', field: 'to_id' }));
309
- });
310
- it('accepts valid edge', async () => {
311
- const input = {
312
- from_id: 'i-issue1',
313
- to_id: 's-spec1',
314
- type: 'implements',
315
- };
316
- const result = await service.validateCreateEdge(input, mockGetNode);
317
- expect(result.valid).toBe(true);
318
- });
319
- it('warns when implements edge has non-issue source', async () => {
320
- const input = {
321
- from_id: 's-spec1',
322
- to_id: 'i-issue1',
323
- type: 'implements',
324
- };
325
- const result = await service.validateCreateEdge(input, mockGetNode);
326
- expect(result.valid).toBe(true); // Warning, not error
327
- expect(result.warnings).toContainEqual(expect.objectContaining({ code: 'IMPLEMENTS_FROM_NON_ISSUE' }));
328
- });
329
- it('warns when implements edge has non-spec target', async () => {
330
- const input = {
331
- from_id: 'i-issue1',
332
- to_id: 'i-issue1',
333
- type: 'implements',
334
- };
335
- // Note: This will hit self-reference first, so use different nodes
336
- const getNodeWithTwoIssues = async (id) => {
337
- const nodes = {
338
- 'i-issue1': {
339
- id: 'i-issue1',
340
- uuid: 'issue-uuid-1',
341
- type: 'issue',
342
- title: 'Test Issue 1',
343
- status: 'open',
344
- created_at: '2025-01-26T10:00:00Z',
345
- updated_at: '2025-01-26T10:00:00Z',
346
- },
347
- 'i-issue2': {
348
- id: 'i-issue2',
349
- uuid: 'issue-uuid-2',
350
- type: 'issue',
351
- title: 'Test Issue 2',
352
- status: 'open',
353
- created_at: '2025-01-26T10:00:00Z',
354
- updated_at: '2025-01-26T10:00:00Z',
355
- },
356
- };
357
- return nodes[id] || null;
358
- };
359
- const input2 = {
360
- from_id: 'i-issue1',
361
- to_id: 'i-issue2',
362
- type: 'implements',
363
- };
364
- const result = await service.validateCreateEdge(input2, getNodeWithTwoIssues);
365
- expect(result.valid).toBe(true);
366
- expect(result.warnings).toContainEqual(expect.objectContaining({ code: 'IMPLEMENTS_TO_NON_SPEC' }));
367
- });
368
- it('allows external URIs without node lookup', async () => {
369
- const input = {
370
- from_id: 'i-issue1',
371
- to_id: 'jira://PROJ-123',
372
- type: 'references',
373
- };
374
- const result = await service.validateCreateEdge(input, mockGetNode);
375
- expect(result.valid).toBe(true);
376
- });
377
- });
378
- // =========================================================================
379
- // Cycle Detection
380
- // =========================================================================
381
- describe('detectCycle', () => {
382
- it('detects simple cycle (A→B, adding B→A)', async () => {
383
- // A blocks B already exists
384
- const getBlocksEdges = async (nodeId) => {
385
- if (nodeId === 'i-b') {
386
- return []; // B doesn't block anything yet
387
- }
388
- if (nodeId === 'i-a') {
389
- return [
390
- {
391
- id: 'x-1',
392
- uuid: 'edge-uuid-1',
393
- from_id: 'i-a',
394
- to_id: 'i-b',
395
- type: 'blocks',
396
- created_at: '2025-01-26T10:00:00Z',
397
- },
398
- ];
399
- }
400
- return [];
401
- };
402
- // Adding B→A would create cycle
403
- const result = await service.detectCycle('i-b', 'i-a', getBlocksEdges);
404
- expect(result.hasCycle).toBe(true);
405
- expect(result.cycle).toEqual(['i-b', 'i-a']);
406
- });
407
- it('detects transitive cycle (A→B→C, adding C→A)', async () => {
408
- // A→B, B→C exists
409
- const getBlocksEdges = async (nodeId) => {
410
- const edges = {
411
- 'i-a': [
412
- {
413
- id: 'x-1',
414
- uuid: 'edge-1',
415
- from_id: 'i-a',
416
- to_id: 'i-b',
417
- type: 'blocks',
418
- created_at: '2025-01-26T10:00:00Z',
419
- },
420
- ],
421
- 'i-b': [
422
- {
423
- id: 'x-2',
424
- uuid: 'edge-2',
425
- from_id: 'i-b',
426
- to_id: 'i-c',
427
- type: 'blocks',
428
- created_at: '2025-01-26T10:00:00Z',
429
- },
430
- ],
431
- 'i-c': [],
432
- };
433
- return edges[nodeId] || [];
434
- };
435
- // Adding C→A would create cycle
436
- const result = await service.detectCycle('i-c', 'i-a', getBlocksEdges);
437
- expect(result.hasCycle).toBe(true);
438
- expect(result.cycle).toContain('i-a');
439
- expect(result.cycle).toContain('i-b');
440
- expect(result.cycle).toContain('i-c');
441
- });
442
- it('returns no cycle for valid edge', async () => {
443
- // A→B exists
444
- const getBlocksEdges = async (nodeId) => {
445
- if (nodeId === 'i-a') {
446
- return [
447
- {
448
- id: 'x-1',
449
- uuid: 'edge-uuid-1',
450
- from_id: 'i-a',
451
- to_id: 'i-b',
452
- type: 'blocks',
453
- created_at: '2025-01-26T10:00:00Z',
454
- },
455
- ];
456
- }
457
- return [];
458
- };
459
- // Adding A→C is fine (no cycle)
460
- const result = await service.detectCycle('i-a', 'i-c', getBlocksEdges);
461
- expect(result.hasCycle).toBe(false);
462
- expect(result.cycle).toBeUndefined();
463
- });
464
- it('handles no existing edges', async () => {
465
- const getBlocksEdges = async () => [];
466
- const result = await service.detectCycle('i-a', 'i-b', getBlocksEdges);
467
- expect(result.hasCycle).toBe(false);
468
- });
469
- it('handles complex graph without cycle', async () => {
470
- // Diamond: A→B, A→C, B→D, C→D
471
- const getBlocksEdges = async (nodeId) => {
472
- const edges = {
473
- 'i-a': [
474
- {
475
- id: 'x-1',
476
- uuid: 'e1',
477
- from_id: 'i-a',
478
- to_id: 'i-b',
479
- type: 'blocks',
480
- created_at: '2025-01-26T10:00:00Z',
481
- },
482
- {
483
- id: 'x-2',
484
- uuid: 'e2',
485
- from_id: 'i-a',
486
- to_id: 'i-c',
487
- type: 'blocks',
488
- created_at: '2025-01-26T10:00:00Z',
489
- },
490
- ],
491
- 'i-b': [
492
- {
493
- id: 'x-3',
494
- uuid: 'e3',
495
- from_id: 'i-b',
496
- to_id: 'i-d',
497
- type: 'blocks',
498
- created_at: '2025-01-26T10:00:00Z',
499
- },
500
- ],
501
- 'i-c': [
502
- {
503
- id: 'x-4',
504
- uuid: 'e4',
505
- from_id: 'i-c',
506
- to_id: 'i-d',
507
- type: 'blocks',
508
- created_at: '2025-01-26T10:00:00Z',
509
- },
510
- ],
511
- 'i-d': [],
512
- };
513
- return edges[nodeId] || [];
514
- };
515
- // Adding D→E is fine
516
- const result = await service.detectCycle('i-d', 'i-e', getBlocksEdges);
517
- expect(result.hasCycle).toBe(false);
518
- });
519
- });
520
- });
521
- //# sourceMappingURL=validation.test.js.map