opentasks 0.0.5 → 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 (311) hide show
  1. package/README.md +40 -0
  2. package/dist/cli.d.ts.map +1 -1
  3. package/dist/cli.js +153 -8
  4. package/dist/cli.js.map +1 -1
  5. package/dist/config/schema.d.ts +54 -0
  6. package/dist/config/schema.d.ts.map +1 -1
  7. package/dist/config/schema.js +52 -0
  8. package/dist/config/schema.js.map +1 -1
  9. package/dist/core/merge-driver.d.ts +6 -2
  10. package/dist/core/merge-driver.d.ts.map +1 -1
  11. package/dist/core/merge-driver.js +11 -7
  12. package/dist/core/merge-driver.js.map +1 -1
  13. package/dist/core/worktree.js +1 -1
  14. package/dist/core/worktree.js.map +1 -1
  15. package/dist/daemon/ipc.d.ts.map +1 -1
  16. package/dist/daemon/ipc.js +4 -1
  17. package/dist/daemon/ipc.js.map +1 -1
  18. package/dist/daemon/lifecycle.d.ts.map +1 -1
  19. package/dist/daemon/lifecycle.js +5 -0
  20. package/dist/daemon/lifecycle.js.map +1 -1
  21. package/dist/graph/git-graph-syncer.js +1 -1
  22. package/dist/graph/git-graph-syncer.js.map +1 -1
  23. package/dist/providers/from-config.d.ts +3 -0
  24. package/dist/providers/from-config.d.ts.map +1 -1
  25. package/dist/providers/from-config.js +29 -0
  26. package/dist/providers/from-config.js.map +1 -1
  27. package/dist/providers/index.d.ts +3 -0
  28. package/dist/providers/index.d.ts.map +1 -1
  29. package/dist/providers/index.js +6 -0
  30. package/dist/providers/index.js.map +1 -1
  31. package/dist/providers/map-client-factory.d.ts +55 -0
  32. package/dist/providers/map-client-factory.d.ts.map +1 -0
  33. package/dist/providers/map-client-factory.js +123 -0
  34. package/dist/providers/map-client-factory.js.map +1 -0
  35. package/dist/providers/map-event-bridge.d.ts +146 -0
  36. package/dist/providers/map-event-bridge.d.ts.map +1 -0
  37. package/dist/providers/map-event-bridge.js +208 -0
  38. package/dist/providers/map-event-bridge.js.map +1 -0
  39. package/dist/providers/map.d.ts +115 -0
  40. package/dist/providers/map.d.ts.map +1 -0
  41. package/dist/providers/map.js +376 -0
  42. package/dist/providers/map.js.map +1 -0
  43. package/package.json +1 -1
  44. package/dist/__tests__/cli-tools.test.d.ts +0 -8
  45. package/dist/__tests__/cli-tools.test.d.ts.map +0 -1
  46. package/dist/__tests__/cli-tools.test.js +0 -546
  47. package/dist/__tests__/cli-tools.test.js.map +0 -1
  48. package/dist/__tests__/cli.test.d.ts +0 -5
  49. package/dist/__tests__/cli.test.d.ts.map +0 -1
  50. package/dist/__tests__/cli.test.js +0 -77
  51. package/dist/__tests__/cli.test.js.map +0 -1
  52. package/dist/__tests__/p1-p3-gaps.test.d.ts +0 -2
  53. package/dist/__tests__/p1-p3-gaps.test.d.ts.map +0 -1
  54. package/dist/__tests__/p1-p3-gaps.test.js +0 -463
  55. package/dist/__tests__/p1-p3-gaps.test.js.map +0 -1
  56. package/dist/client/__tests__/client-crud.test.d.ts +0 -7
  57. package/dist/client/__tests__/client-crud.test.d.ts.map +0 -1
  58. package/dist/client/__tests__/client-crud.test.js +0 -404
  59. package/dist/client/__tests__/client-crud.test.js.map +0 -1
  60. package/dist/client/__tests__/client.test.d.ts +0 -5
  61. package/dist/client/__tests__/client.test.d.ts.map +0 -1
  62. package/dist/client/__tests__/client.test.js +0 -518
  63. package/dist/client/__tests__/client.test.js.map +0 -1
  64. package/dist/config/__tests__/defaults.test.d.ts +0 -2
  65. package/dist/config/__tests__/defaults.test.d.ts.map +0 -1
  66. package/dist/config/__tests__/defaults.test.js +0 -57
  67. package/dist/config/__tests__/defaults.test.js.map +0 -1
  68. package/dist/config/__tests__/env.test.d.ts +0 -2
  69. package/dist/config/__tests__/env.test.d.ts.map +0 -1
  70. package/dist/config/__tests__/env.test.js +0 -136
  71. package/dist/config/__tests__/env.test.js.map +0 -1
  72. package/dist/config/__tests__/index.test.d.ts +0 -2
  73. package/dist/config/__tests__/index.test.d.ts.map +0 -1
  74. package/dist/config/__tests__/index.test.js +0 -113
  75. package/dist/config/__tests__/index.test.js.map +0 -1
  76. package/dist/config/__tests__/loader.test.d.ts +0 -2
  77. package/dist/config/__tests__/loader.test.d.ts.map +0 -1
  78. package/dist/config/__tests__/loader.test.js +0 -128
  79. package/dist/config/__tests__/loader.test.js.map +0 -1
  80. package/dist/config/__tests__/merge.test.d.ts +0 -2
  81. package/dist/config/__tests__/merge.test.d.ts.map +0 -1
  82. package/dist/config/__tests__/merge.test.js +0 -79
  83. package/dist/config/__tests__/merge.test.js.map +0 -1
  84. package/dist/config/__tests__/schema.test.d.ts +0 -2
  85. package/dist/config/__tests__/schema.test.d.ts.map +0 -1
  86. package/dist/config/__tests__/schema.test.js +0 -300
  87. package/dist/config/__tests__/schema.test.js.map +0 -1
  88. package/dist/core/__tests__/conditional-redirects.test.d.ts +0 -2
  89. package/dist/core/__tests__/conditional-redirects.test.d.ts.map +0 -1
  90. package/dist/core/__tests__/conditional-redirects.test.js +0 -83
  91. package/dist/core/__tests__/conditional-redirects.test.js.map +0 -1
  92. package/dist/core/__tests__/connections.test.d.ts +0 -2
  93. package/dist/core/__tests__/connections.test.d.ts.map +0 -1
  94. package/dist/core/__tests__/connections.test.js +0 -158
  95. package/dist/core/__tests__/connections.test.js.map +0 -1
  96. package/dist/core/__tests__/hash.test.d.ts +0 -2
  97. package/dist/core/__tests__/hash.test.d.ts.map +0 -1
  98. package/dist/core/__tests__/hash.test.js +0 -139
  99. package/dist/core/__tests__/hash.test.js.map +0 -1
  100. package/dist/core/__tests__/id.test.d.ts +0 -2
  101. package/dist/core/__tests__/id.test.d.ts.map +0 -1
  102. package/dist/core/__tests__/id.test.js +0 -142
  103. package/dist/core/__tests__/id.test.js.map +0 -1
  104. package/dist/core/__tests__/location.test.d.ts +0 -2
  105. package/dist/core/__tests__/location.test.d.ts.map +0 -1
  106. package/dist/core/__tests__/location.test.js +0 -77
  107. package/dist/core/__tests__/location.test.js.map +0 -1
  108. package/dist/core/__tests__/merge-driver.test.d.ts +0 -2
  109. package/dist/core/__tests__/merge-driver.test.d.ts.map +0 -1
  110. package/dist/core/__tests__/merge-driver.test.js +0 -218
  111. package/dist/core/__tests__/merge-driver.test.js.map +0 -1
  112. package/dist/core/__tests__/redirects.test.d.ts +0 -2
  113. package/dist/core/__tests__/redirects.test.d.ts.map +0 -1
  114. package/dist/core/__tests__/redirects.test.js +0 -123
  115. package/dist/core/__tests__/redirects.test.js.map +0 -1
  116. package/dist/core/__tests__/resolve-location-target.test.d.ts +0 -8
  117. package/dist/core/__tests__/resolve-location-target.test.d.ts.map +0 -1
  118. package/dist/core/__tests__/resolve-location-target.test.js +0 -303
  119. package/dist/core/__tests__/resolve-location-target.test.js.map +0 -1
  120. package/dist/core/__tests__/uri.test.d.ts +0 -2
  121. package/dist/core/__tests__/uri.test.d.ts.map +0 -1
  122. package/dist/core/__tests__/uri.test.js +0 -159
  123. package/dist/core/__tests__/uri.test.js.map +0 -1
  124. package/dist/core/__tests__/worktree.test.d.ts +0 -2
  125. package/dist/core/__tests__/worktree.test.d.ts.map +0 -1
  126. package/dist/core/__tests__/worktree.test.js +0 -120
  127. package/dist/core/__tests__/worktree.test.js.map +0 -1
  128. package/dist/daemon/__tests__/flush.test.d.ts +0 -5
  129. package/dist/daemon/__tests__/flush.test.d.ts.map +0 -1
  130. package/dist/daemon/__tests__/flush.test.js +0 -213
  131. package/dist/daemon/__tests__/flush.test.js.map +0 -1
  132. package/dist/daemon/__tests__/integration.test.d.ts +0 -7
  133. package/dist/daemon/__tests__/integration.test.d.ts.map +0 -1
  134. package/dist/daemon/__tests__/integration.test.js +0 -276
  135. package/dist/daemon/__tests__/integration.test.js.map +0 -1
  136. package/dist/daemon/__tests__/ipc.test.d.ts +0 -5
  137. package/dist/daemon/__tests__/ipc.test.d.ts.map +0 -1
  138. package/dist/daemon/__tests__/ipc.test.js +0 -314
  139. package/dist/daemon/__tests__/ipc.test.js.map +0 -1
  140. package/dist/daemon/__tests__/lifecycle.test.d.ts +0 -5
  141. package/dist/daemon/__tests__/lifecycle.test.d.ts.map +0 -1
  142. package/dist/daemon/__tests__/lifecycle.test.js +0 -301
  143. package/dist/daemon/__tests__/lifecycle.test.js.map +0 -1
  144. package/dist/daemon/__tests__/lock.test.d.ts +0 -5
  145. package/dist/daemon/__tests__/lock.test.d.ts.map +0 -1
  146. package/dist/daemon/__tests__/lock.test.js +0 -192
  147. package/dist/daemon/__tests__/lock.test.js.map +0 -1
  148. package/dist/daemon/__tests__/methods/graph.test.d.ts +0 -5
  149. package/dist/daemon/__tests__/methods/graph.test.d.ts.map +0 -1
  150. package/dist/daemon/__tests__/methods/graph.test.js +0 -309
  151. package/dist/daemon/__tests__/methods/graph.test.js.map +0 -1
  152. package/dist/daemon/__tests__/methods/provider.test.d.ts +0 -7
  153. package/dist/daemon/__tests__/methods/provider.test.d.ts.map +0 -1
  154. package/dist/daemon/__tests__/methods/provider.test.js +0 -181
  155. package/dist/daemon/__tests__/methods/provider.test.js.map +0 -1
  156. package/dist/daemon/__tests__/methods/tools.test.d.ts +0 -5
  157. package/dist/daemon/__tests__/methods/tools.test.d.ts.map +0 -1
  158. package/dist/daemon/__tests__/methods/tools.test.js +0 -587
  159. package/dist/daemon/__tests__/methods/tools.test.js.map +0 -1
  160. package/dist/daemon/__tests__/multi-location.test.d.ts +0 -8
  161. package/dist/daemon/__tests__/multi-location.test.d.ts.map +0 -1
  162. package/dist/daemon/__tests__/multi-location.test.js +0 -669
  163. package/dist/daemon/__tests__/multi-location.test.js.map +0 -1
  164. package/dist/daemon/__tests__/registry.test.d.ts +0 -5
  165. package/dist/daemon/__tests__/registry.test.d.ts.map +0 -1
  166. package/dist/daemon/__tests__/registry.test.js +0 -208
  167. package/dist/daemon/__tests__/registry.test.js.map +0 -1
  168. package/dist/daemon/__tests__/watcher.test.d.ts +0 -5
  169. package/dist/daemon/__tests__/watcher.test.d.ts.map +0 -1
  170. package/dist/daemon/__tests__/watcher.test.js +0 -234
  171. package/dist/daemon/__tests__/watcher.test.js.map +0 -1
  172. package/dist/daemon/methods/__tests__/graph.test.d.ts +0 -5
  173. package/dist/daemon/methods/__tests__/graph.test.d.ts.map +0 -1
  174. package/dist/daemon/methods/__tests__/graph.test.js +0 -274
  175. package/dist/daemon/methods/__tests__/graph.test.js.map +0 -1
  176. package/dist/daemon/methods/__tests__/provider.test.d.ts +0 -5
  177. package/dist/daemon/methods/__tests__/provider.test.d.ts.map +0 -1
  178. package/dist/daemon/methods/__tests__/provider.test.js +0 -184
  179. package/dist/daemon/methods/__tests__/provider.test.js.map +0 -1
  180. package/dist/daemon/methods/__tests__/tools.test.d.ts +0 -5
  181. package/dist/daemon/methods/__tests__/tools.test.d.ts.map +0 -1
  182. package/dist/daemon/methods/__tests__/tools.test.js +0 -295
  183. package/dist/daemon/methods/__tests__/tools.test.js.map +0 -1
  184. package/dist/graph/__tests__/EdgeTypeRegistry.test.d.ts +0 -2
  185. package/dist/graph/__tests__/EdgeTypeRegistry.test.d.ts.map +0 -1
  186. package/dist/graph/__tests__/EdgeTypeRegistry.test.js +0 -212
  187. package/dist/graph/__tests__/EdgeTypeRegistry.test.js.map +0 -1
  188. package/dist/graph/__tests__/FederatedGraph.test.d.ts +0 -2
  189. package/dist/graph/__tests__/FederatedGraph.test.d.ts.map +0 -1
  190. package/dist/graph/__tests__/FederatedGraph.test.js +0 -661
  191. package/dist/graph/__tests__/FederatedGraph.test.js.map +0 -1
  192. package/dist/graph/__tests__/GraphologyAdapter.test.d.ts +0 -2
  193. package/dist/graph/__tests__/GraphologyAdapter.test.d.ts.map +0 -1
  194. package/dist/graph/__tests__/GraphologyAdapter.test.js +0 -326
  195. package/dist/graph/__tests__/GraphologyAdapter.test.js.map +0 -1
  196. package/dist/graph/__tests__/HydratingFederatedGraph.test.d.ts +0 -2
  197. package/dist/graph/__tests__/HydratingFederatedGraph.test.d.ts.map +0 -1
  198. package/dist/graph/__tests__/HydratingFederatedGraph.test.js +0 -587
  199. package/dist/graph/__tests__/HydratingFederatedGraph.test.js.map +0 -1
  200. package/dist/graph/__tests__/debounce.test.d.ts +0 -5
  201. package/dist/graph/__tests__/debounce.test.d.ts.map +0 -1
  202. package/dist/graph/__tests__/debounce.test.js +0 -195
  203. package/dist/graph/__tests__/debounce.test.js.map +0 -1
  204. package/dist/graph/__tests__/edge-cases.test.d.ts +0 -8
  205. package/dist/graph/__tests__/edge-cases.test.d.ts.map +0 -1
  206. package/dist/graph/__tests__/edge-cases.test.js +0 -472
  207. package/dist/graph/__tests__/edge-cases.test.js.map +0 -1
  208. package/dist/graph/__tests__/expansion.test.d.ts +0 -2
  209. package/dist/graph/__tests__/expansion.test.d.ts.map +0 -1
  210. package/dist/graph/__tests__/expansion.test.js +0 -105
  211. package/dist/graph/__tests__/expansion.test.js.map +0 -1
  212. package/dist/graph/__tests__/provider-store.test.d.ts +0 -5
  213. package/dist/graph/__tests__/provider-store.test.d.ts.map +0 -1
  214. package/dist/graph/__tests__/provider-store.test.js +0 -791
  215. package/dist/graph/__tests__/provider-store.test.js.map +0 -1
  216. package/dist/graph/__tests__/query.test.d.ts +0 -5
  217. package/dist/graph/__tests__/query.test.d.ts.map +0 -1
  218. package/dist/graph/__tests__/query.test.js +0 -774
  219. package/dist/graph/__tests__/query.test.js.map +0 -1
  220. package/dist/graph/__tests__/store.test.d.ts +0 -5
  221. package/dist/graph/__tests__/store.test.d.ts.map +0 -1
  222. package/dist/graph/__tests__/store.test.js +0 -489
  223. package/dist/graph/__tests__/store.test.js.map +0 -1
  224. package/dist/graph/__tests__/sync.test.d.ts +0 -5
  225. package/dist/graph/__tests__/sync.test.d.ts.map +0 -1
  226. package/dist/graph/__tests__/sync.test.js +0 -129
  227. package/dist/graph/__tests__/sync.test.js.map +0 -1
  228. package/dist/graph/__tests__/validation.test.d.ts +0 -2
  229. package/dist/graph/__tests__/validation.test.d.ts.map +0 -1
  230. package/dist/graph/__tests__/validation.test.js +0 -521
  231. package/dist/graph/__tests__/validation.test.js.map +0 -1
  232. package/dist/providers/__tests__/beads.test.d.ts +0 -5
  233. package/dist/providers/__tests__/beads.test.d.ts.map +0 -1
  234. package/dist/providers/__tests__/beads.test.js +0 -591
  235. package/dist/providers/__tests__/beads.test.js.map +0 -1
  236. package/dist/providers/__tests__/claude-tasks.test.d.ts +0 -5
  237. package/dist/providers/__tests__/claude-tasks.test.d.ts.map +0 -1
  238. package/dist/providers/__tests__/claude-tasks.test.js +0 -392
  239. package/dist/providers/__tests__/claude-tasks.test.js.map +0 -1
  240. package/dist/providers/__tests__/from-config.test.d.ts +0 -5
  241. package/dist/providers/__tests__/from-config.test.d.ts.map +0 -1
  242. package/dist/providers/__tests__/from-config.test.js +0 -152
  243. package/dist/providers/__tests__/from-config.test.js.map +0 -1
  244. package/dist/providers/__tests__/materialization.test.d.ts +0 -5
  245. package/dist/providers/__tests__/materialization.test.d.ts.map +0 -1
  246. package/dist/providers/__tests__/materialization.test.js +0 -407
  247. package/dist/providers/__tests__/materialization.test.js.map +0 -1
  248. package/dist/providers/__tests__/native.test.d.ts +0 -5
  249. package/dist/providers/__tests__/native.test.d.ts.map +0 -1
  250. package/dist/providers/__tests__/native.test.js +0 -566
  251. package/dist/providers/__tests__/native.test.js.map +0 -1
  252. package/dist/providers/__tests__/registry.test.d.ts +0 -5
  253. package/dist/providers/__tests__/registry.test.d.ts.map +0 -1
  254. package/dist/providers/__tests__/registry.test.js +0 -183
  255. package/dist/providers/__tests__/registry.test.js.map +0 -1
  256. package/dist/providers/traits/__tests__/RelationshipQueryable.test.d.ts +0 -2
  257. package/dist/providers/traits/__tests__/RelationshipQueryable.test.d.ts.map +0 -1
  258. package/dist/providers/traits/__tests__/RelationshipQueryable.test.js +0 -169
  259. package/dist/providers/traits/__tests__/RelationshipQueryable.test.js.map +0 -1
  260. package/dist/providers/traits/__tests__/TaskManageable.test.d.ts +0 -2
  261. package/dist/providers/traits/__tests__/TaskManageable.test.d.ts.map +0 -1
  262. package/dist/providers/traits/__tests__/TaskManageable.test.js +0 -172
  263. package/dist/providers/traits/__tests__/TaskManageable.test.js.map +0 -1
  264. package/dist/schema/__tests__/validation.test.d.ts +0 -2
  265. package/dist/schema/__tests__/validation.test.d.ts.map +0 -1
  266. package/dist/schema/__tests__/validation.test.js +0 -241
  267. package/dist/schema/__tests__/validation.test.js.map +0 -1
  268. package/dist/storage/__tests__/atomic-write.test.d.ts +0 -5
  269. package/dist/storage/__tests__/atomic-write.test.d.ts.map +0 -1
  270. package/dist/storage/__tests__/atomic-write.test.js +0 -170
  271. package/dist/storage/__tests__/atomic-write.test.js.map +0 -1
  272. package/dist/storage/__tests__/file-lock.test.d.ts +0 -2
  273. package/dist/storage/__tests__/file-lock.test.d.ts.map +0 -1
  274. package/dist/storage/__tests__/file-lock.test.js +0 -89
  275. package/dist/storage/__tests__/file-lock.test.js.map +0 -1
  276. package/dist/storage/__tests__/jsonl.test.d.ts +0 -2
  277. package/dist/storage/__tests__/jsonl.test.d.ts.map +0 -1
  278. package/dist/storage/__tests__/jsonl.test.js +0 -228
  279. package/dist/storage/__tests__/jsonl.test.js.map +0 -1
  280. package/dist/storage/__tests__/locked-writer.test.d.ts +0 -2
  281. package/dist/storage/__tests__/locked-writer.test.d.ts.map +0 -1
  282. package/dist/storage/__tests__/locked-writer.test.js +0 -109
  283. package/dist/storage/__tests__/locked-writer.test.js.map +0 -1
  284. package/dist/storage/__tests__/sqlite.test.d.ts +0 -2
  285. package/dist/storage/__tests__/sqlite.test.d.ts.map +0 -1
  286. package/dist/storage/__tests__/sqlite.test.js +0 -470
  287. package/dist/storage/__tests__/sqlite.test.js.map +0 -1
  288. package/dist/tools/__tests__/annotate.test.d.ts +0 -5
  289. package/dist/tools/__tests__/annotate.test.d.ts.map +0 -1
  290. package/dist/tools/__tests__/annotate.test.js +0 -314
  291. package/dist/tools/__tests__/annotate.test.js.map +0 -1
  292. package/dist/tools/__tests__/link.test.d.ts +0 -5
  293. package/dist/tools/__tests__/link.test.d.ts.map +0 -1
  294. package/dist/tools/__tests__/link.test.js +0 -245
  295. package/dist/tools/__tests__/link.test.js.map +0 -1
  296. package/dist/tools/__tests__/query.test.d.ts +0 -5
  297. package/dist/tools/__tests__/query.test.d.ts.map +0 -1
  298. package/dist/tools/__tests__/query.test.js +0 -288
  299. package/dist/tools/__tests__/query.test.js.map +0 -1
  300. package/dist/tools/__tests__/task.test.d.ts +0 -5
  301. package/dist/tools/__tests__/task.test.d.ts.map +0 -1
  302. package/dist/tools/__tests__/task.test.js +0 -178
  303. package/dist/tools/__tests__/task.test.js.map +0 -1
  304. package/dist/tracking/claude-task-reconstructor.d.ts +0 -41
  305. package/dist/tracking/claude-task-reconstructor.d.ts.map +0 -1
  306. package/dist/tracking/claude-task-reconstructor.js +0 -91
  307. package/dist/tracking/claude-task-reconstructor.js.map +0 -1
  308. package/dist/tracking/plan-mode-tracker.d.ts +0 -20
  309. package/dist/tracking/plan-mode-tracker.d.ts.map +0 -1
  310. package/dist/tracking/plan-mode-tracker.js +0 -35
  311. package/dist/tracking/plan-mode-tracker.js.map +0 -1
@@ -1,241 +0,0 @@
1
- import { describe, it, expect } from 'vitest';
2
- import { isSpec, isIssue, isFeedback, isExternal, validateStoredNode, parseNode, tryParseNode, ValidationError, } from '../validation.js';
3
- // Test fixtures
4
- const baseFields = {
5
- id: 's-a2b3',
6
- uuid: '550e8400-e29b-41d4-a716-446655440000',
7
- title: 'Test Node',
8
- created_at: '2025-01-26T10:00:00Z',
9
- updated_at: '2025-01-26T10:00:00Z',
10
- };
11
- const validSpec = {
12
- ...baseFields,
13
- type: 'spec',
14
- content: '## Overview\n\nThis is a spec.',
15
- };
16
- const validIssue = {
17
- ...baseFields,
18
- id: 'i-x7k9',
19
- type: 'issue',
20
- status: 'open',
21
- };
22
- const validFeedback = {
23
- ...baseFields,
24
- id: 'f-m4n5',
25
- type: 'feedback',
26
- target_id: 's-a2b3',
27
- feedback_type: 'suggestion',
28
- };
29
- const validExternal = {
30
- ...baseFields,
31
- id: 'e-p6q7',
32
- type: 'external',
33
- uri: 'jira://PROJ-123',
34
- source: 'jira',
35
- materialized: false,
36
- };
37
- describe('Type Guards', () => {
38
- it('isSpec returns true for spec nodes', () => {
39
- const node = parseNode(validSpec);
40
- expect(isSpec(node)).toBe(true);
41
- expect(isIssue(node)).toBe(false);
42
- expect(isFeedback(node)).toBe(false);
43
- expect(isExternal(node)).toBe(false);
44
- });
45
- it('isIssue returns true for issue nodes', () => {
46
- const node = parseNode(validIssue);
47
- expect(isIssue(node)).toBe(true);
48
- expect(isSpec(node)).toBe(false);
49
- });
50
- it('isFeedback returns true for feedback nodes', () => {
51
- const node = parseNode(validFeedback);
52
- expect(isFeedback(node)).toBe(true);
53
- expect(isSpec(node)).toBe(false);
54
- });
55
- it('isExternal returns true for external nodes', () => {
56
- const node = parseNode(validExternal);
57
- expect(isExternal(node)).toBe(true);
58
- expect(isSpec(node)).toBe(false);
59
- });
60
- });
61
- describe('validateStoredNode', () => {
62
- it('validates a valid spec', () => {
63
- const result = validateStoredNode(validSpec);
64
- expect(result.valid).toBe(true);
65
- expect(result.errors).toHaveLength(0);
66
- });
67
- it('validates a valid issue', () => {
68
- const result = validateStoredNode(validIssue);
69
- expect(result.valid).toBe(true);
70
- expect(result.errors).toHaveLength(0);
71
- });
72
- it('validates a valid feedback', () => {
73
- const result = validateStoredNode(validFeedback);
74
- expect(result.valid).toBe(true);
75
- expect(result.errors).toHaveLength(0);
76
- });
77
- it('validates a valid external node', () => {
78
- const result = validateStoredNode(validExternal);
79
- expect(result.valid).toBe(true);
80
- expect(result.errors).toHaveLength(0);
81
- });
82
- it('rejects node missing required core fields', () => {
83
- const invalid = {
84
- id: 's-a2b3',
85
- uuid: '',
86
- type: 'spec',
87
- title: '',
88
- created_at: '',
89
- updated_at: '2025-01-26T10:00:00Z',
90
- };
91
- const result = validateStoredNode(invalid);
92
- expect(result.valid).toBe(false);
93
- expect(result.errors.length).toBeGreaterThan(0);
94
- expect(result.errors.some((e) => e.field === 'uuid')).toBe(true);
95
- expect(result.errors.some((e) => e.field === 'title')).toBe(true);
96
- });
97
- it('rejects issue missing status', () => {
98
- const invalid = {
99
- ...baseFields,
100
- type: 'issue',
101
- // missing status
102
- };
103
- const result = validateStoredNode(invalid);
104
- expect(result.valid).toBe(false);
105
- expect(result.errors.some((e) => e.field === 'status')).toBe(true);
106
- });
107
- it('rejects feedback missing target_id', () => {
108
- const invalid = {
109
- ...baseFields,
110
- type: 'feedback',
111
- feedback_type: 'comment',
112
- // missing target_id
113
- };
114
- const result = validateStoredNode(invalid);
115
- expect(result.valid).toBe(false);
116
- expect(result.errors.some((e) => e.field === 'target_id')).toBe(true);
117
- });
118
- it('rejects feedback missing feedback_type', () => {
119
- const invalid = {
120
- ...baseFields,
121
- type: 'feedback',
122
- target_id: 's-a2b3',
123
- // missing feedback_type
124
- };
125
- const result = validateStoredNode(invalid);
126
- expect(result.valid).toBe(false);
127
- expect(result.errors.some((e) => e.field === 'feedback_type')).toBe(true);
128
- });
129
- it('rejects external missing uri', () => {
130
- const invalid = {
131
- ...baseFields,
132
- type: 'external',
133
- source: 'jira',
134
- materialized: false,
135
- // missing uri
136
- };
137
- const result = validateStoredNode(invalid);
138
- expect(result.valid).toBe(false);
139
- expect(result.errors.some((e) => e.field === 'uri')).toBe(true);
140
- });
141
- it('rejects external missing source', () => {
142
- const invalid = {
143
- ...baseFields,
144
- type: 'external',
145
- uri: 'jira://PROJ-123',
146
- materialized: false,
147
- // missing source
148
- };
149
- const result = validateStoredNode(invalid);
150
- expect(result.valid).toBe(false);
151
- expect(result.errors.some((e) => e.field === 'source')).toBe(true);
152
- });
153
- it('rejects external missing materialized', () => {
154
- const invalid = {
155
- ...baseFields,
156
- type: 'external',
157
- uri: 'jira://PROJ-123',
158
- source: 'jira',
159
- // missing materialized
160
- };
161
- const result = validateStoredNode(invalid);
162
- expect(result.valid).toBe(false);
163
- expect(result.errors.some((e) => e.field === 'materialized')).toBe(true);
164
- });
165
- });
166
- describe('parseNode', () => {
167
- it('parses a valid spec', () => {
168
- const node = parseNode(validSpec);
169
- expect(node.type).toBe('spec');
170
- expect(isSpec(node)).toBe(true);
171
- });
172
- it('parses a valid issue', () => {
173
- const node = parseNode(validIssue);
174
- expect(node.type).toBe('issue');
175
- expect(isIssue(node)).toBe(true);
176
- if (isIssue(node)) {
177
- expect(node.status).toBe('open');
178
- }
179
- });
180
- it('throws ValidationError for invalid node', () => {
181
- const invalid = {
182
- ...baseFields,
183
- type: 'issue',
184
- // missing status
185
- };
186
- expect(() => parseNode(invalid)).toThrow(ValidationError);
187
- });
188
- it('preserves unknown fields', () => {
189
- const withExtra = {
190
- ...validSpec,
191
- customField: 'custom value',
192
- anotherField: 123,
193
- };
194
- const node = parseNode(withExtra);
195
- expect(node.customField).toBe('custom value');
196
- expect(node.anotherField).toBe(123);
197
- });
198
- });
199
- describe('tryParseNode', () => {
200
- it('returns node for valid input', () => {
201
- const node = tryParseNode(validSpec);
202
- expect(node).not.toBeNull();
203
- expect(node?.type).toBe('spec');
204
- });
205
- it('returns null for invalid input', () => {
206
- const invalid = {
207
- ...baseFields,
208
- type: 'issue',
209
- // missing status
210
- };
211
- const node = tryParseNode(invalid);
212
- expect(node).toBeNull();
213
- });
214
- });
215
- describe('Node type narrowing', () => {
216
- it('allows type-safe access after guard', () => {
217
- const node = parseNode(validIssue);
218
- if (isIssue(node)) {
219
- // TypeScript should allow access to issue-specific fields
220
- expect(node.status).toBe('open');
221
- // assignee is optional on issues
222
- expect(node.assignee).toBeUndefined();
223
- }
224
- });
225
- it('allows type-safe access to feedback fields', () => {
226
- const node = parseNode(validFeedback);
227
- if (isFeedback(node)) {
228
- expect(node.target_id).toBe('s-a2b3');
229
- expect(node.feedback_type).toBe('suggestion');
230
- }
231
- });
232
- it('allows type-safe access to external fields', () => {
233
- const node = parseNode(validExternal);
234
- if (isExternal(node)) {
235
- expect(node.uri).toBe('jira://PROJ-123');
236
- expect(node.source).toBe('jira');
237
- expect(node.materialized).toBe(false);
238
- }
239
- });
240
- });
241
- //# sourceMappingURL=validation.test.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"validation.test.js","sourceRoot":"","sources":["../../../src/schema/__tests__/validation.test.ts"],"names":[],"mappings":"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"}
@@ -1,5 +0,0 @@
1
- /**
2
- * Tests for Atomic Write Utilities
3
- */
4
- export {};
5
- //# sourceMappingURL=atomic-write.test.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"atomic-write.test.d.ts","sourceRoot":"","sources":["../../../src/storage/__tests__/atomic-write.test.ts"],"names":[],"mappings":"AAAA;;GAEG"}
@@ -1,170 +0,0 @@
1
- /**
2
- * Tests for Atomic Write Utilities
3
- */
4
- import { describe, it, expect, beforeEach, afterEach } from 'vitest';
5
- import * as fs from 'node:fs/promises';
6
- import * as path from 'node:path';
7
- import * as os from 'node:os';
8
- import { atomicWrite, appendToFile, fileExists, readFileOrEmpty, } from '../atomic-write.js';
9
- describe('atomic-write', () => {
10
- let tempDir;
11
- beforeEach(async () => {
12
- tempDir = await fs.mkdtemp(path.join(os.tmpdir(), 'opentasks-atomic-test-'));
13
- });
14
- afterEach(async () => {
15
- try {
16
- await fs.rm(tempDir, { recursive: true, force: true });
17
- }
18
- catch {
19
- // Ignore cleanup errors
20
- }
21
- });
22
- describe('atomicWrite', () => {
23
- it('should write content to file', async () => {
24
- const filePath = path.join(tempDir, 'test.txt');
25
- const content = 'Hello, World!';
26
- await atomicWrite(filePath, content);
27
- const result = await fs.readFile(filePath, 'utf-8');
28
- expect(result).toBe(content);
29
- });
30
- it('should overwrite existing file', async () => {
31
- const filePath = path.join(tempDir, 'test.txt');
32
- await atomicWrite(filePath, 'First content');
33
- await atomicWrite(filePath, 'Second content');
34
- const result = await fs.readFile(filePath, 'utf-8');
35
- expect(result).toBe('Second content');
36
- });
37
- it('should create parent directories if they do not exist', async () => {
38
- const filePath = path.join(tempDir, 'nested', 'dir', 'test.txt');
39
- const content = 'Nested content';
40
- await atomicWrite(filePath, content);
41
- const result = await fs.readFile(filePath, 'utf-8');
42
- expect(result).toBe(content);
43
- });
44
- it('should not leave temp file on success', async () => {
45
- const filePath = path.join(tempDir, 'test.txt');
46
- await atomicWrite(filePath, 'content');
47
- const files = await fs.readdir(tempDir);
48
- expect(files).toEqual(['test.txt']);
49
- });
50
- it.skipIf(process.getuid?.() === 0)('should clean up temp file on write failure', async () => {
51
- const readOnlyDir = path.join(tempDir, 'readonly');
52
- await fs.mkdir(readOnlyDir);
53
- // Create a subdirectory that we'll make read-only
54
- const filePath = path.join(readOnlyDir, 'subdir', 'test.txt');
55
- // Make the directory read-only (can't create files in it)
56
- await fs.chmod(readOnlyDir, 0o444);
57
- try {
58
- await expect(atomicWrite(filePath, 'content')).rejects.toThrow();
59
- // Check no temp files left (the directory itself should be clean)
60
- await fs.chmod(readOnlyDir, 0o755);
61
- const files = await fs.readdir(readOnlyDir);
62
- expect(files.filter((f) => f.endsWith('.tmp'))).toEqual([]);
63
- }
64
- finally {
65
- // Restore permissions for cleanup
66
- await fs.chmod(readOnlyDir, 0o755);
67
- }
68
- });
69
- it('should handle unicode content', async () => {
70
- const filePath = path.join(tempDir, 'unicode.txt');
71
- const content = '你好世界 🌍 Привет мир';
72
- await atomicWrite(filePath, content);
73
- const result = await fs.readFile(filePath, 'utf-8');
74
- expect(result).toBe(content);
75
- });
76
- it('should handle empty content', async () => {
77
- const filePath = path.join(tempDir, 'empty.txt');
78
- await atomicWrite(filePath, '');
79
- const result = await fs.readFile(filePath, 'utf-8');
80
- expect(result).toBe('');
81
- });
82
- it('should handle large content', async () => {
83
- const filePath = path.join(tempDir, 'large.txt');
84
- const content = 'x'.repeat(1024 * 1024); // 1MB
85
- await atomicWrite(filePath, content);
86
- const result = await fs.readFile(filePath, 'utf-8');
87
- expect(result.length).toBe(content.length);
88
- });
89
- });
90
- describe('appendToFile', () => {
91
- it('should append content to existing file', async () => {
92
- const filePath = path.join(tempDir, 'append.txt');
93
- await fs.writeFile(filePath, 'Line 1\n');
94
- await appendToFile(filePath, 'Line 2\n');
95
- const result = await fs.readFile(filePath, 'utf-8');
96
- expect(result).toBe('Line 1\nLine 2\n');
97
- });
98
- it('should create file if it does not exist', async () => {
99
- const filePath = path.join(tempDir, 'new.txt');
100
- await appendToFile(filePath, 'First line\n');
101
- const result = await fs.readFile(filePath, 'utf-8');
102
- expect(result).toBe('First line\n');
103
- });
104
- it('should create parent directories', async () => {
105
- const filePath = path.join(tempDir, 'nested', 'append.txt');
106
- await appendToFile(filePath, 'content');
107
- const result = await fs.readFile(filePath, 'utf-8');
108
- expect(result).toBe('content');
109
- });
110
- it('should handle multiple appends', async () => {
111
- const filePath = path.join(tempDir, 'multi.txt');
112
- await appendToFile(filePath, 'A');
113
- await appendToFile(filePath, 'B');
114
- await appendToFile(filePath, 'C');
115
- const result = await fs.readFile(filePath, 'utf-8');
116
- expect(result).toBe('ABC');
117
- });
118
- });
119
- describe('fileExists', () => {
120
- it('should return true for existing file', async () => {
121
- const filePath = path.join(tempDir, 'exists.txt');
122
- await fs.writeFile(filePath, 'content');
123
- const result = await fileExists(filePath);
124
- expect(result).toBe(true);
125
- });
126
- it('should return false for non-existing file', async () => {
127
- const filePath = path.join(tempDir, 'nonexistent.txt');
128
- const result = await fileExists(filePath);
129
- expect(result).toBe(false);
130
- });
131
- it('should return true for existing directory', async () => {
132
- const result = await fileExists(tempDir);
133
- expect(result).toBe(true);
134
- });
135
- it('should return false for non-existing directory', async () => {
136
- const dirPath = path.join(tempDir, 'nonexistent-dir');
137
- const result = await fileExists(dirPath);
138
- expect(result).toBe(false);
139
- });
140
- });
141
- describe('readFileOrEmpty', () => {
142
- it('should return file content for existing file', async () => {
143
- const filePath = path.join(tempDir, 'read.txt');
144
- await fs.writeFile(filePath, 'Hello');
145
- const result = await readFileOrEmpty(filePath);
146
- expect(result).toBe('Hello');
147
- });
148
- it('should return empty string for non-existing file', async () => {
149
- const filePath = path.join(tempDir, 'nonexistent.txt');
150
- const result = await readFileOrEmpty(filePath);
151
- expect(result).toBe('');
152
- });
153
- it.skipIf(process.getuid?.() === 0)('should throw for permission errors', async () => {
154
- const filePath = path.join(tempDir, 'noperm.txt');
155
- await fs.writeFile(filePath, 'content');
156
- await fs.chmod(filePath, 0o000);
157
- try {
158
- await expect(readFileOrEmpty(filePath)).rejects.toThrow();
159
- }
160
- finally {
161
- // Restore permissions for cleanup
162
- await fs.chmod(filePath, 0o644);
163
- }
164
- });
165
- it('should throw for directory path', async () => {
166
- await expect(readFileOrEmpty(tempDir)).rejects.toThrow();
167
- });
168
- });
169
- });
170
- //# sourceMappingURL=atomic-write.test.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"atomic-write.test.js","sourceRoot":"","sources":["../../../src/storage/__tests__/atomic-write.test.ts"],"names":[],"mappings":"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"}
@@ -1,2 +0,0 @@
1
- export {};
2
- //# sourceMappingURL=file-lock.test.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"file-lock.test.d.ts","sourceRoot":"","sources":["../../../src/storage/__tests__/file-lock.test.ts"],"names":[],"mappings":""}
@@ -1,89 +0,0 @@
1
- import { describe, it, expect, beforeEach, afterEach } from 'vitest';
2
- import * as fs from 'node:fs';
3
- import * as path from 'node:path';
4
- import * as os from 'node:os';
5
- import { FileLock, withFileLock } from '../file-lock.js';
6
- let tmpDir;
7
- let lockPath;
8
- beforeEach(() => {
9
- tmpDir = fs.mkdtempSync(path.join(os.tmpdir(), 'opentasks-lock-test-'));
10
- lockPath = path.join(tmpDir, 'write.lock');
11
- });
12
- afterEach(() => {
13
- fs.rmSync(tmpDir, { recursive: true, force: true });
14
- });
15
- describe('FileLock', () => {
16
- it('acquires and releases lock', async () => {
17
- const lock = new FileLock({ lockPath });
18
- await lock.acquire();
19
- expect(lock.isLocked).toBe(true);
20
- expect(fs.existsSync(lockPath)).toBe(true);
21
- lock.release();
22
- expect(lock.isLocked).toBe(false);
23
- expect(fs.existsSync(lockPath)).toBe(false);
24
- });
25
- it('throws when acquiring already-acquired lock', async () => {
26
- const lock = new FileLock({ lockPath });
27
- await lock.acquire();
28
- await expect(lock.acquire()).rejects.toThrow('Lock already acquired');
29
- lock.release();
30
- });
31
- it('blocks until lock is released', async () => {
32
- const lock1 = new FileLock({ lockPath, timeout: 2000 });
33
- const lock2 = new FileLock({ lockPath, timeout: 2000 });
34
- await lock1.acquire();
35
- // Release after 100ms
36
- setTimeout(() => lock1.release(), 100);
37
- // lock2 should block then succeed
38
- await lock2.acquire();
39
- expect(lock2.isLocked).toBe(true);
40
- lock2.release();
41
- });
42
- it('times out when lock is held', async () => {
43
- const lock1 = new FileLock({ lockPath, timeout: 5000 });
44
- const lock2 = new FileLock({ lockPath, timeout: 200, retryInterval: 50 });
45
- await lock1.acquire();
46
- await expect(lock2.acquire()).rejects.toThrow('Failed to acquire lock');
47
- lock1.release();
48
- });
49
- it('detects and breaks stale locks', async () => {
50
- // Create a stale lock file with a non-existent PID
51
- fs.mkdirSync(path.dirname(lockPath), { recursive: true });
52
- fs.writeFileSync(lockPath, `999999999\n${Date.now() - 60000}\n`);
53
- const lock = new FileLock({ lockPath, staleTimeout: 1000 });
54
- await lock.acquire();
55
- expect(lock.isLocked).toBe(true);
56
- lock.release();
57
- });
58
- it('release is idempotent', async () => {
59
- const lock = new FileLock({ lockPath });
60
- await lock.acquire();
61
- lock.release();
62
- lock.release(); // Should not throw
63
- expect(lock.isLocked).toBe(false);
64
- });
65
- });
66
- describe('withFileLock', () => {
67
- it('executes function while holding lock', async () => {
68
- let executed = false;
69
- await withFileLock(lockPath, async () => {
70
- executed = true;
71
- expect(fs.existsSync(lockPath)).toBe(true);
72
- });
73
- expect(executed).toBe(true);
74
- expect(fs.existsSync(lockPath)).toBe(false);
75
- });
76
- it('releases lock on function error', async () => {
77
- await expect(withFileLock(lockPath, async () => {
78
- throw new Error('test error');
79
- })).rejects.toThrow('test error');
80
- expect(fs.existsSync(lockPath)).toBe(false);
81
- });
82
- it('returns function result', async () => {
83
- const result = await withFileLock(lockPath, async () => {
84
- return 42;
85
- });
86
- expect(result).toBe(42);
87
- });
88
- });
89
- //# sourceMappingURL=file-lock.test.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"file-lock.test.js","sourceRoot":"","sources":["../../../src/storage/__tests__/file-lock.test.ts"],"names":[],"mappings":"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"}
@@ -1,2 +0,0 @@
1
- export {};
2
- //# sourceMappingURL=jsonl.test.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"jsonl.test.d.ts","sourceRoot":"","sources":["../../../src/storage/__tests__/jsonl.test.ts"],"names":[],"mappings":""}