@stackmemoryai/stackmemory 0.2.7 → 0.2.9

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 (346) hide show
  1. package/README.md +25 -8
  2. package/dist/scripts/cancel-duplicate-tasks.js +2 -1
  3. package/dist/scripts/cancel-duplicate-tasks.js.map +1 -1
  4. package/dist/scripts/list-linear-tasks.js +3 -4
  5. package/dist/scripts/list-linear-tasks.js.map +1 -1
  6. package/dist/scripts/merge-linear-duplicates-safe.js +4 -2
  7. package/dist/scripts/merge-linear-duplicates-safe.js.map +1 -1
  8. package/dist/scripts/show-linear-summary.js +4 -1
  9. package/dist/scripts/show-linear-summary.js.map +1 -1
  10. package/dist/scripts/status.js +6 -2
  11. package/dist/scripts/status.js.map +1 -1
  12. package/dist/src/cli/auto-detect.js.map +1 -1
  13. package/dist/src/cli/claude-sm.js.map +1 -1
  14. package/dist/src/cli/commands/config.d.ts +6 -0
  15. package/dist/src/cli/commands/config.d.ts.map +1 -0
  16. package/dist/src/cli/commands/config.js +224 -0
  17. package/dist/src/cli/commands/config.js.map +1 -0
  18. package/dist/src/cli/commands/linear.d.ts.map +1 -1
  19. package/dist/src/cli/commands/linear.js +123 -47
  20. package/dist/src/cli/commands/linear.js.map +1 -1
  21. package/dist/src/cli/index.d.ts.map +1 -1
  22. package/dist/src/cli/index.js +48 -1
  23. package/dist/src/cli/index.js.map +1 -1
  24. package/dist/src/core/config/config-manager.d.ts +95 -0
  25. package/dist/src/core/config/config-manager.d.ts.map +1 -0
  26. package/dist/src/core/config/config-manager.js +359 -0
  27. package/dist/src/core/config/config-manager.js.map +1 -0
  28. package/dist/src/core/config/types.d.ts +72 -0
  29. package/dist/src/core/config/types.d.ts.map +1 -0
  30. package/dist/src/core/config/types.js +127 -0
  31. package/dist/src/core/config/types.js.map +1 -0
  32. package/dist/src/core/context/compaction-handler.d.ts +119 -0
  33. package/dist/src/core/context/compaction-handler.d.ts.map +1 -0
  34. package/dist/src/core/context/compaction-handler.js +306 -0
  35. package/dist/src/core/context/compaction-handler.js.map +1 -0
  36. package/dist/src/core/context/model-aware-compaction.d.ts +101 -0
  37. package/dist/src/core/context/model-aware-compaction.d.ts.map +1 -0
  38. package/dist/src/core/context/model-aware-compaction.js +616 -0
  39. package/dist/src/core/context/model-aware-compaction.js.map +1 -0
  40. package/dist/src/core/digest/hybrid-digest-generator.d.ts +76 -0
  41. package/dist/src/core/digest/hybrid-digest-generator.d.ts.map +1 -0
  42. package/dist/src/core/digest/hybrid-digest-generator.js +629 -0
  43. package/dist/src/core/digest/hybrid-digest-generator.js.map +1 -0
  44. package/dist/src/core/digest/index.d.ts +7 -0
  45. package/dist/src/core/digest/index.d.ts.map +1 -0
  46. package/dist/src/core/digest/index.js +7 -0
  47. package/dist/src/core/digest/index.js.map +1 -0
  48. package/dist/src/core/digest/types.d.ts +154 -0
  49. package/dist/src/core/digest/types.d.ts.map +1 -0
  50. package/dist/src/core/digest/types.js +18 -0
  51. package/dist/src/core/digest/types.js.map +1 -0
  52. package/dist/src/core/monitoring/logger.d.ts +2 -2
  53. package/dist/src/core/monitoring/logger.d.ts.map +1 -1
  54. package/dist/src/core/monitoring/logger.js +10 -5
  55. package/dist/src/core/monitoring/logger.js.map +1 -1
  56. package/dist/src/core/monitoring/metrics.d.ts +3 -0
  57. package/dist/src/core/monitoring/metrics.d.ts.map +1 -1
  58. package/dist/src/core/monitoring/metrics.js +142 -3
  59. package/dist/src/core/monitoring/metrics.js.map +1 -1
  60. package/dist/src/core/persistence/postgres-adapter.d.ts +31 -0
  61. package/dist/src/core/persistence/postgres-adapter.d.ts.map +1 -0
  62. package/dist/src/core/persistence/postgres-adapter.js +316 -0
  63. package/dist/src/core/persistence/postgres-adapter.js.map +1 -0
  64. package/dist/src/core/query/query-parser.d.ts +104 -0
  65. package/dist/src/core/query/query-parser.d.ts.map +1 -0
  66. package/dist/src/core/query/query-parser.js +347 -0
  67. package/dist/src/core/query/query-parser.js.map +1 -0
  68. package/dist/src/core/retrieval/index.d.ts +8 -0
  69. package/dist/src/core/retrieval/index.d.ts.map +1 -0
  70. package/dist/src/core/retrieval/index.js +8 -0
  71. package/dist/src/core/retrieval/index.js.map +1 -0
  72. package/dist/src/core/retrieval/llm-context-retrieval.d.ts +71 -0
  73. package/dist/src/core/retrieval/llm-context-retrieval.d.ts.map +1 -0
  74. package/dist/src/core/retrieval/llm-context-retrieval.js +545 -0
  75. package/dist/src/core/retrieval/llm-context-retrieval.js.map +1 -0
  76. package/dist/src/core/retrieval/summary-generator.d.ts +63 -0
  77. package/dist/src/core/retrieval/summary-generator.d.ts.map +1 -0
  78. package/dist/src/core/retrieval/summary-generator.js +622 -0
  79. package/dist/src/core/retrieval/summary-generator.js.map +1 -0
  80. package/dist/src/core/retrieval/types.d.ts +257 -0
  81. package/dist/src/core/retrieval/types.d.ts.map +1 -0
  82. package/dist/src/core/retrieval/types.js +18 -0
  83. package/dist/src/core/retrieval/types.js.map +1 -0
  84. package/dist/src/core/trace/trace-detector.d.ts +108 -0
  85. package/dist/src/core/trace/trace-detector.d.ts.map +1 -0
  86. package/dist/src/core/trace/trace-detector.demo.d.ts +5 -0
  87. package/dist/src/core/trace/trace-detector.demo.d.ts.map +1 -0
  88. package/dist/src/core/trace/trace-detector.demo.js +145 -0
  89. package/dist/src/core/trace/trace-detector.demo.js.map +1 -0
  90. package/dist/src/core/trace/trace-detector.js +425 -0
  91. package/dist/src/core/trace/trace-detector.js.map +1 -0
  92. package/dist/src/core/trace/trace-store.d.ts +60 -0
  93. package/dist/src/core/trace/trace-store.d.ts.map +1 -0
  94. package/dist/src/core/trace/trace-store.js +323 -0
  95. package/dist/src/core/trace/trace-store.js.map +1 -0
  96. package/dist/src/core/trace/types.d.ts +81 -0
  97. package/dist/src/core/trace/types.d.ts.map +1 -0
  98. package/dist/src/core/trace/types.js +70 -0
  99. package/dist/src/core/trace/types.js.map +1 -0
  100. package/dist/src/core/types.d.ts +35 -0
  101. package/dist/src/core/types.d.ts.map +1 -0
  102. package/dist/src/core/types.js +2 -0
  103. package/dist/src/core/types.js.map +1 -0
  104. package/dist/src/integrations/linear/sync-manager.d.ts +76 -0
  105. package/dist/src/integrations/linear/sync-manager.d.ts.map +1 -0
  106. package/dist/src/integrations/linear/sync-manager.js +223 -0
  107. package/dist/src/integrations/linear/sync-manager.js.map +1 -0
  108. package/dist/src/integrations/mcp/server.d.ts +8 -0
  109. package/dist/src/integrations/mcp/server.d.ts.map +1 -1
  110. package/dist/src/integrations/mcp/server.js +369 -17
  111. package/dist/src/integrations/mcp/server.js.map +1 -1
  112. package/dist/src/integrations/mcp/trace-test.d.ts +5 -0
  113. package/dist/src/integrations/mcp/trace-test.d.ts.map +1 -0
  114. package/dist/src/integrations/mcp/trace-test.js +54 -0
  115. package/dist/src/integrations/mcp/trace-test.js.map +1 -0
  116. package/dist/src/integrations/pg-aiguide/embedding-provider.d.ts +48 -0
  117. package/dist/src/integrations/pg-aiguide/embedding-provider.d.ts.map +1 -0
  118. package/dist/src/integrations/pg-aiguide/embedding-provider.js +190 -0
  119. package/dist/src/integrations/pg-aiguide/embedding-provider.js.map +1 -0
  120. package/dist/src/integrations/pg-aiguide/semantic-search.d.ts +34 -0
  121. package/dist/src/integrations/pg-aiguide/semantic-search.d.ts.map +1 -0
  122. package/dist/src/integrations/pg-aiguide/semantic-search.js +154 -0
  123. package/dist/src/integrations/pg-aiguide/semantic-search.js.map +1 -0
  124. package/dist/src/integrations/pg-aiguide/timescale-analytics.d.ts +44 -0
  125. package/dist/src/integrations/pg-aiguide/timescale-analytics.d.ts.map +1 -0
  126. package/dist/src/integrations/pg-aiguide/timescale-analytics.js +215 -0
  127. package/dist/src/integrations/pg-aiguide/timescale-analytics.js.map +1 -0
  128. package/dist/src/models/user.model.d.ts +55 -0
  129. package/dist/src/models/user.model.d.ts.map +1 -0
  130. package/dist/src/models/user.model.js +263 -0
  131. package/dist/src/models/user.model.js.map +1 -0
  132. package/dist/src/servers/production/auth-middleware.d.ts +7 -0
  133. package/dist/src/servers/production/auth-middleware.d.ts.map +1 -1
  134. package/dist/src/servers/production/auth-middleware.js +201 -26
  135. package/dist/src/servers/production/auth-middleware.js.map +1 -1
  136. package/dist/src/servers/railway/index.js.map +1 -1
  137. package/dist/src/services/config-service.d.ts +1 -1
  138. package/dist/src/services/config-service.d.ts.map +1 -1
  139. package/dist/src/services/config-service.js.map +1 -1
  140. package/dist/src/types/task.d.ts +11 -1
  141. package/dist/src/types/task.d.ts.map +1 -1
  142. package/dist/src/utils/logger.d.ts +4 -4
  143. package/dist/src/utils/logger.d.ts.map +1 -1
  144. package/dist/src/utils/logger.js.map +1 -1
  145. package/package.json +14 -8
  146. package/dist/attention-scoring/src/attention-tracker.d.ts +0 -79
  147. package/dist/attention-scoring/src/attention-tracker.d.ts.map +0 -1
  148. package/dist/attention-scoring/src/attention-tracker.js +0 -488
  149. package/dist/attention-scoring/src/attention-tracker.js.map +0 -1
  150. package/dist/attention-scoring/src/mcp-integration.d.ts +0 -56
  151. package/dist/attention-scoring/src/mcp-integration.d.ts.map +0 -1
  152. package/dist/attention-scoring/src/mcp-integration.js +0 -369
  153. package/dist/attention-scoring/src/mcp-integration.js.map +0 -1
  154. package/dist/index.js +0 -382
  155. package/dist/p2p-sync/src/p2p-sync.d.ts +0 -81
  156. package/dist/p2p-sync/src/p2p-sync.d.ts.map +0 -1
  157. package/dist/p2p-sync/src/p2p-sync.js +0 -457
  158. package/dist/p2p-sync/src/p2p-sync.js.map +0 -1
  159. package/dist/p2p-sync/src/team-context-sync.d.ts +0 -99
  160. package/dist/p2p-sync/src/team-context-sync.d.ts.map +0 -1
  161. package/dist/p2p-sync/src/team-context-sync.js +0 -491
  162. package/dist/p2p-sync/src/team-context-sync.js.map +0 -1
  163. package/dist/scripts/merge-linear-duplicates.d.ts +0 -7
  164. package/dist/scripts/merge-linear-duplicates.d.ts.map +0 -1
  165. package/dist/scripts/merge-linear-duplicates.js +0 -126
  166. package/dist/scripts/merge-linear-duplicates.js.map +0 -1
  167. package/dist/src/analytics/api/analytics-api.d.ts +0 -24
  168. package/dist/src/analytics/api/analytics-api.d.ts.map +0 -1
  169. package/dist/src/analytics/api/analytics-api.js +0 -279
  170. package/dist/src/analytics/api/analytics-api.js.map +0 -1
  171. package/dist/src/analytics/core/analytics-service.d.ts +0 -23
  172. package/dist/src/analytics/core/analytics-service.d.ts.map +0 -1
  173. package/dist/src/analytics/core/analytics-service.js +0 -160
  174. package/dist/src/analytics/core/analytics-service.js.map +0 -1
  175. package/dist/src/analytics/index.d.ts +0 -12
  176. package/dist/src/analytics/index.d.ts.map +0 -1
  177. package/dist/src/analytics/index.js +0 -11
  178. package/dist/src/analytics/index.js.map +0 -1
  179. package/dist/src/analytics/queries/metrics-queries.d.ts +0 -11
  180. package/dist/src/analytics/queries/metrics-queries.d.ts.map +0 -1
  181. package/dist/src/analytics/queries/metrics-queries.js +0 -179
  182. package/dist/src/analytics/queries/metrics-queries.js.map +0 -1
  183. package/dist/src/analytics/types/metrics.d.ts +0 -60
  184. package/dist/src/analytics/types/metrics.d.ts.map +0 -1
  185. package/dist/src/analytics/types/metrics.js +0 -2
  186. package/dist/src/analytics/types/metrics.js.map +0 -1
  187. package/dist/src/beads/beads-task-store.d.ts +0 -117
  188. package/dist/src/beads/beads-task-store.d.ts.map +0 -1
  189. package/dist/src/beads/beads-task-store.js +0 -318
  190. package/dist/src/beads/beads-task-store.js.map +0 -1
  191. package/dist/src/beads/task-aware-context.d.ts +0 -103
  192. package/dist/src/beads/task-aware-context.d.ts.map +0 -1
  193. package/dist/src/beads/task-aware-context.js +0 -395
  194. package/dist/src/beads/task-aware-context.js.map +0 -1
  195. package/dist/src/beads-task-store.d.ts +0 -117
  196. package/dist/src/beads-task-store.d.ts.map +0 -1
  197. package/dist/src/beads-task-store.js +0 -318
  198. package/dist/src/beads-task-store.js.map +0 -1
  199. package/dist/src/cli/__tests__/index.test.d.ts +0 -5
  200. package/dist/src/cli/__tests__/index.test.d.ts.map +0 -1
  201. package/dist/src/cli/__tests__/index.test.js +0 -726
  202. package/dist/src/cli/__tests__/index.test.js.map +0 -1
  203. package/dist/src/cli/analytics-viewer.d.ts +0 -3
  204. package/dist/src/cli/analytics-viewer.d.ts.map +0 -1
  205. package/dist/src/cli/analytics-viewer.js +0 -89
  206. package/dist/src/cli/analytics-viewer.js.map +0 -1
  207. package/dist/src/cli/cli.d.ts +0 -7
  208. package/dist/src/cli/cli.d.ts.map +0 -1
  209. package/dist/src/cli/cli.js +0 -704
  210. package/dist/src/cli/cli.js.map +0 -1
  211. package/dist/src/cli/project-commands.d.ts +0 -8
  212. package/dist/src/cli/project-commands.d.ts.map +0 -1
  213. package/dist/src/cli/project-commands.js +0 -212
  214. package/dist/src/cli/project-commands.js.map +0 -1
  215. package/dist/src/cli.d.ts +0 -7
  216. package/dist/src/cli.d.ts.map +0 -1
  217. package/dist/src/cli.js +0 -73
  218. package/dist/src/cli.js.map +0 -1
  219. package/dist/src/core/context/__tests__/frame-manager.test.d.ts +0 -5
  220. package/dist/src/core/context/__tests__/frame-manager.test.d.ts.map +0 -1
  221. package/dist/src/core/context/__tests__/frame-manager.test.js +0 -892
  222. package/dist/src/core/context/__tests__/frame-manager.test.js.map +0 -1
  223. package/dist/src/core/error-handler.d.ts +0 -46
  224. package/dist/src/core/error-handler.d.ts.map +0 -1
  225. package/dist/src/core/error-handler.js +0 -212
  226. package/dist/src/core/error-handler.js.map +0 -1
  227. package/dist/src/core/errors/__tests__/error-handling.test.d.ts +0 -5
  228. package/dist/src/core/errors/__tests__/error-handling.test.d.ts.map +0 -1
  229. package/dist/src/core/errors/__tests__/error-handling.test.js +0 -239
  230. package/dist/src/core/errors/__tests__/error-handling.test.js.map +0 -1
  231. package/dist/src/core/frame-manager.d.ts +0 -106
  232. package/dist/src/core/frame-manager.d.ts.map +0 -1
  233. package/dist/src/core/frame-manager.js +0 -387
  234. package/dist/src/core/frame-manager.js.map +0 -1
  235. package/dist/src/core/logger.d.ts +0 -24
  236. package/dist/src/core/logger.d.ts.map +0 -1
  237. package/dist/src/core/logger.js +0 -121
  238. package/dist/src/core/logger.js.map +0 -1
  239. package/dist/src/core/logger.test.d.ts +0 -2
  240. package/dist/src/core/logger.test.d.ts.map +0 -1
  241. package/dist/src/core/logger.test.js +0 -31
  242. package/dist/src/core/logger.test.js.map +0 -1
  243. package/dist/src/core/progress-tracker.d.ts +0 -95
  244. package/dist/src/core/progress-tracker.d.ts.map +0 -1
  245. package/dist/src/core/progress-tracker.js +0 -178
  246. package/dist/src/core/progress-tracker.js.map +0 -1
  247. package/dist/src/core/project-manager.d.ts +0 -130
  248. package/dist/src/core/project-manager.d.ts.map +0 -1
  249. package/dist/src/core/project-manager.js +0 -582
  250. package/dist/src/core/project-manager.js.map +0 -1
  251. package/dist/src/core/update-checker.d.ts +0 -38
  252. package/dist/src/core/update-checker.d.ts.map +0 -1
  253. package/dist/src/core/update-checker.js +0 -156
  254. package/dist/src/core/update-checker.js.map +0 -1
  255. package/dist/src/error-handler.d.ts +0 -42
  256. package/dist/src/error-handler.d.ts.map +0 -1
  257. package/dist/src/error-handler.js +0 -155
  258. package/dist/src/error-handler.js.map +0 -1
  259. package/dist/src/features/tasks/__tests__/pebbles-task-store.test.d.ts +0 -5
  260. package/dist/src/features/tasks/__tests__/pebbles-task-store.test.d.ts.map +0 -1
  261. package/dist/src/features/tasks/__tests__/pebbles-task-store.test.js +0 -712
  262. package/dist/src/features/tasks/__tests__/pebbles-task-store.test.js.map +0 -1
  263. package/dist/src/frame-manager.d.ts +0 -106
  264. package/dist/src/frame-manager.d.ts.map +0 -1
  265. package/dist/src/frame-manager.js +0 -361
  266. package/dist/src/frame-manager.js.map +0 -1
  267. package/dist/src/integrations/browser-mcp.d.ts +0 -94
  268. package/dist/src/integrations/browser-mcp.d.ts.map +0 -1
  269. package/dist/src/integrations/browser-mcp.js +0 -431
  270. package/dist/src/integrations/browser-mcp.js.map +0 -1
  271. package/dist/src/integrations/linear/__tests__/auth.test.d.ts +0 -5
  272. package/dist/src/integrations/linear/__tests__/auth.test.d.ts.map +0 -1
  273. package/dist/src/integrations/linear/__tests__/auth.test.js +0 -517
  274. package/dist/src/integrations/linear/__tests__/auth.test.js.map +0 -1
  275. package/dist/src/integrations/linear/__tests__/sync-service.test.d.ts +0 -5
  276. package/dist/src/integrations/linear/__tests__/sync-service.test.d.ts.map +0 -1
  277. package/dist/src/integrations/linear/__tests__/sync-service.test.js +0 -700
  278. package/dist/src/integrations/linear/__tests__/sync-service.test.js.map +0 -1
  279. package/dist/src/integrations/linear-auth.d.ts +0 -99
  280. package/dist/src/integrations/linear-auth.d.ts.map +0 -1
  281. package/dist/src/integrations/linear-auth.js +0 -319
  282. package/dist/src/integrations/linear-auth.js.map +0 -1
  283. package/dist/src/integrations/linear-auto-sync.d.ts +0 -77
  284. package/dist/src/integrations/linear-auto-sync.d.ts.map +0 -1
  285. package/dist/src/integrations/linear-auto-sync.js +0 -268
  286. package/dist/src/integrations/linear-auto-sync.js.map +0 -1
  287. package/dist/src/integrations/linear-client.d.ts +0 -86
  288. package/dist/src/integrations/linear-client.d.ts.map +0 -1
  289. package/dist/src/integrations/linear-client.js +0 -277
  290. package/dist/src/integrations/linear-client.js.map +0 -1
  291. package/dist/src/integrations/linear-config.d.ts +0 -51
  292. package/dist/src/integrations/linear-config.d.ts.map +0 -1
  293. package/dist/src/integrations/linear-config.js +0 -103
  294. package/dist/src/integrations/linear-config.js.map +0 -1
  295. package/dist/src/integrations/linear-sync.d.ts +0 -97
  296. package/dist/src/integrations/linear-sync.d.ts.map +0 -1
  297. package/dist/src/integrations/linear-sync.js +0 -391
  298. package/dist/src/integrations/linear-sync.js.map +0 -1
  299. package/dist/src/integrations/mcp/__tests__/server.test.d.ts +0 -5
  300. package/dist/src/integrations/mcp/__tests__/server.test.d.ts.map +0 -1
  301. package/dist/src/integrations/mcp/__tests__/server.test.js +0 -790
  302. package/dist/src/integrations/mcp/__tests__/server.test.js.map +0 -1
  303. package/dist/src/logger.d.ts +0 -24
  304. package/dist/src/logger.d.ts.map +0 -1
  305. package/dist/src/logger.js +0 -120
  306. package/dist/src/logger.js.map +0 -1
  307. package/dist/src/mcp/mcp-server.d.ts +0 -40
  308. package/dist/src/mcp/mcp-server.d.ts.map +0 -1
  309. package/dist/src/mcp/mcp-server.js +0 -828
  310. package/dist/src/mcp/mcp-server.js.map +0 -1
  311. package/dist/src/mcp-server.d.ts +0 -32
  312. package/dist/src/mcp-server.d.ts.map +0 -1
  313. package/dist/src/mcp-server.js +0 -441
  314. package/dist/src/mcp-server.js.map +0 -1
  315. package/dist/src/pebbles/pebbles-task-store.d.ts +0 -117
  316. package/dist/src/pebbles/pebbles-task-store.d.ts.map +0 -1
  317. package/dist/src/pebbles/pebbles-task-store.js +0 -335
  318. package/dist/src/pebbles/pebbles-task-store.js.map +0 -1
  319. package/dist/src/pebbles/task-aware-context.d.ts +0 -103
  320. package/dist/src/pebbles/task-aware-context.d.ts.map +0 -1
  321. package/dist/src/pebbles/task-aware-context.js +0 -412
  322. package/dist/src/pebbles/task-aware-context.js.map +0 -1
  323. package/dist/src/railway/index.d.ts +0 -7
  324. package/dist/src/railway/index.d.ts.map +0 -1
  325. package/dist/src/railway/index.js +0 -401
  326. package/dist/src/railway/index.js.map +0 -1
  327. package/dist/src/runway/auth/auth-middleware.d.ts +0 -66
  328. package/dist/src/runway/auth/auth-middleware.d.ts.map +0 -1
  329. package/dist/src/runway/auth/auth-middleware.js +0 -337
  330. package/dist/src/runway/auth/auth-middleware.js.map +0 -1
  331. package/dist/src/runway/server/runway-mcp-server.d.ts +0 -46
  332. package/dist/src/runway/server/runway-mcp-server.d.ts.map +0 -1
  333. package/dist/src/runway/server/runway-mcp-server.js +0 -601
  334. package/dist/src/runway/server/runway-mcp-server.js.map +0 -1
  335. package/dist/src/runway.bak/auth/auth-middleware.d.ts +0 -66
  336. package/dist/src/runway.bak/auth/auth-middleware.d.ts.map +0 -1
  337. package/dist/src/runway.bak/auth/auth-middleware.js +0 -337
  338. package/dist/src/runway.bak/auth/auth-middleware.js.map +0 -1
  339. package/dist/src/runway.bak/server/runway-mcp-server.d.ts +0 -46
  340. package/dist/src/runway.bak/server/runway-mcp-server.d.ts.map +0 -1
  341. package/dist/src/runway.bak/server/runway-mcp-server.js +0 -601
  342. package/dist/src/runway.bak/server/runway-mcp-server.js.map +0 -1
  343. package/dist/src/task-aware-context.d.ts +0 -103
  344. package/dist/src/task-aware-context.d.ts.map +0 -1
  345. package/dist/src/task-aware-context.js +0 -395
  346. package/dist/src/task-aware-context.js.map +0 -1
@@ -1,712 +0,0 @@
1
- /**
2
- * Tests for PebblesTaskStore - Git-native JSONL storage with SQLite cache
3
- */
4
- import { describe, it, expect, beforeEach, afterEach, vi } from 'vitest';
5
- import Database from 'better-sqlite3';
6
- import { PebblesTaskStore } from '../pebbles-task-store.js';
7
- import { DatabaseError, TaskError } from '../../../core/errors/index.js';
8
- import { join } from 'path';
9
- import { mkdtempSync, rmSync, existsSync, readFileSync, writeFileSync } from 'fs';
10
- import { tmpdir } from 'os';
11
- describe('PebblesTaskStore', () => {
12
- let db;
13
- let taskStore;
14
- let tempDir;
15
- let projectRoot;
16
- beforeEach(() => {
17
- // Create a temporary directory for test
18
- tempDir = mkdtempSync(join(tmpdir(), 'stackmemory-task-test-'));
19
- projectRoot = tempDir;
20
- // Initialize database
21
- const dbPath = join(tempDir, '.stackmemory', 'context.db');
22
- db = new Database(dbPath);
23
- // Create task store
24
- taskStore = new PebblesTaskStore(projectRoot, db);
25
- });
26
- afterEach(() => {
27
- // Clean up
28
- if (db) {
29
- db.close();
30
- }
31
- if (tempDir) {
32
- rmSync(tempDir, { recursive: true, force: true });
33
- }
34
- });
35
- describe('Initialization', () => {
36
- it('should create .stackmemory directory if it does not exist', () => {
37
- const stackmemoryDir = join(projectRoot, '.stackmemory');
38
- expect(existsSync(stackmemoryDir)).toBe(true);
39
- });
40
- it('should initialize cache database schema correctly', () => {
41
- // Check if task_cache table exists
42
- const tables = db.prepare(`
43
- SELECT name FROM sqlite_master
44
- WHERE type='table' AND name='task_cache'
45
- `).all();
46
- expect(tables).toHaveLength(1);
47
- });
48
- it('should create required indexes', () => {
49
- const indexes = db.prepare(`
50
- SELECT name FROM sqlite_master
51
- WHERE type='index' AND name LIKE 'idx_task_%'
52
- `).all();
53
- const expectedIndexes = [
54
- 'idx_task_status',
55
- 'idx_task_priority',
56
- 'idx_task_frame',
57
- 'idx_task_timestamp',
58
- 'idx_task_parent'
59
- ];
60
- expectedIndexes.forEach(expectedIndex => {
61
- expect(indexes.some((idx) => idx.name === expectedIndex)).toBe(true);
62
- });
63
- });
64
- it('should load existing tasks from JSONL file', () => {
65
- // Create pre-existing JSONL file
66
- const tasksFile = join(projectRoot, '.stackmemory', 'tasks.jsonl');
67
- const existingTask = {
68
- id: 'test-123',
69
- type: 'task_create',
70
- timestamp: Math.floor(Date.now() / 1000),
71
- frame_id: 'frame-123',
72
- title: 'Existing Task',
73
- description: 'Pre-existing task',
74
- status: 'pending',
75
- priority: 'medium',
76
- created_at: Math.floor(Date.now() / 1000),
77
- depends_on: [],
78
- blocks: [],
79
- tags: ['test'],
80
- context_score: 0.5
81
- };
82
- writeFileSync(tasksFile, JSON.stringify(existingTask) + '\n');
83
- // Create new task store instance
84
- const newTaskStore = new PebblesTaskStore(projectRoot, db);
85
- // Should load the existing task
86
- const loadedTask = newTaskStore.getTask('test-123');
87
- expect(loadedTask).toBeDefined();
88
- expect(loadedTask.title).toBe('Existing Task');
89
- });
90
- it('should handle corrupted JSONL lines gracefully', () => {
91
- const tasksFile = join(projectRoot, '.stackmemory', 'tasks.jsonl');
92
- const content = `
93
- {"valid": "task", "id": "valid-1", "type": "task_create", "timestamp": 1, "frame_id": "f1", "title": "Valid", "status": "pending", "priority": "medium", "created_at": 1, "depends_on": [], "blocks": [], "tags": []}
94
- {invalid json line
95
- {"id": "valid-2", "type": "task_create", "timestamp": 2, "frame_id": "f2", "title": "Valid 2", "status": "pending", "priority": "high", "created_at": 2, "depends_on": [], "blocks": [], "tags": []}
96
- `.trim();
97
- writeFileSync(tasksFile, content);
98
- // Should load only valid tasks and skip corrupted lines
99
- const newTaskStore = new PebblesTaskStore(projectRoot, db);
100
- expect(newTaskStore.getTask('valid-1')).toBeDefined();
101
- expect(newTaskStore.getTask('valid-2')).toBeDefined();
102
- });
103
- });
104
- describe('Task Creation', () => {
105
- it('should create a new task successfully', () => {
106
- const taskId = taskStore.createTask({
107
- title: 'Test Task',
108
- description: 'A test task',
109
- priority: 'high',
110
- frameId: 'frame-123',
111
- tags: ['test', 'urgent'],
112
- estimatedEffort: 60,
113
- assignee: 'developer'
114
- });
115
- expect(taskId).toBeDefined();
116
- expect(taskId).toMatch(/^tsk-[a-f0-9]{8}$/);
117
- const task = taskStore.getTask(taskId);
118
- expect(task).toBeDefined();
119
- expect(task.title).toBe('Test Task');
120
- expect(task.description).toBe('A test task');
121
- expect(task.priority).toBe('high');
122
- expect(task.status).toBe('pending');
123
- expect(task.frame_id).toBe('frame-123');
124
- expect(task.tags).toEqual(['test', 'urgent']);
125
- expect(task.estimated_effort).toBe(60);
126
- expect(task.assignee).toBe('developer');
127
- expect(task.depends_on).toEqual([]);
128
- expect(task.blocks).toEqual([]);
129
- });
130
- it('should create task with minimal required fields', () => {
131
- const taskId = taskStore.createTask({
132
- title: 'Minimal Task',
133
- frameId: 'frame-456'
134
- });
135
- const task = taskStore.getTask(taskId);
136
- expect(task).toBeDefined();
137
- expect(task.title).toBe('Minimal Task');
138
- expect(task.frame_id).toBe('frame-456');
139
- expect(task.priority).toBe('medium');
140
- expect(task.status).toBe('pending');
141
- expect(task.description).toBeUndefined();
142
- expect(task.tags).toEqual([]);
143
- });
144
- it('should create task with parent relationship', () => {
145
- const parentId = taskStore.createTask({
146
- title: 'Parent Task',
147
- frameId: 'frame-parent'
148
- });
149
- const childId = taskStore.createTask({
150
- title: 'Child Task',
151
- frameId: 'frame-child',
152
- parentId
153
- });
154
- const childTask = taskStore.getTask(childId);
155
- expect(childTask.parent_id).toBe(parentId);
156
- });
157
- it('should create task with dependencies', () => {
158
- const dep1Id = taskStore.createTask({
159
- title: 'Dependency 1',
160
- frameId: 'frame-dep1'
161
- });
162
- const dep2Id = taskStore.createTask({
163
- title: 'Dependency 2',
164
- frameId: 'frame-dep2'
165
- });
166
- const taskId = taskStore.createTask({
167
- title: 'Dependent Task',
168
- frameId: 'frame-main',
169
- dependsOn: [dep1Id, dep2Id]
170
- });
171
- const task = taskStore.getTask(taskId);
172
- expect(task.depends_on).toEqual([dep1Id, dep2Id]);
173
- });
174
- it('should append task to JSONL file', () => {
175
- const taskId = taskStore.createTask({
176
- title: 'JSONL Test',
177
- frameId: 'frame-jsonl'
178
- });
179
- const tasksFile = join(projectRoot, '.stackmemory', 'tasks.jsonl');
180
- expect(existsSync(tasksFile)).toBe(true);
181
- const content = readFileSync(tasksFile, 'utf-8');
182
- expect(content).toContain(taskId);
183
- expect(content).toContain('JSONL Test');
184
- });
185
- });
186
- describe('Task Status Updates', () => {
187
- let taskId;
188
- beforeEach(() => {
189
- taskId = taskStore.createTask({
190
- title: 'Status Test Task',
191
- frameId: 'frame-status'
192
- });
193
- });
194
- it('should update task status from pending to in_progress', () => {
195
- taskStore.updateTaskStatus(taskId, 'in_progress');
196
- const task = taskStore.getTask(taskId);
197
- expect(task.status).toBe('in_progress');
198
- expect(task.started_at).toBeDefined();
199
- });
200
- it('should update task status from in_progress to completed', () => {
201
- // First set to in_progress
202
- taskStore.updateTaskStatus(taskId, 'in_progress');
203
- // Then complete it
204
- taskStore.updateTaskStatus(taskId, 'completed');
205
- const task = taskStore.getTask(taskId);
206
- expect(task.status).toBe('completed');
207
- expect(task.completed_at).toBeDefined();
208
- expect(task.actual_effort).toBeDefined();
209
- });
210
- it('should update task status to blocked', () => {
211
- taskStore.updateTaskStatus(taskId, 'blocked', 'Waiting for external API');
212
- const task = taskStore.getTask(taskId);
213
- expect(task.status).toBe('blocked');
214
- expect(task.type).toBe('task_block');
215
- });
216
- it('should update task status to cancelled', () => {
217
- taskStore.updateTaskStatus(taskId, 'cancelled');
218
- const task = taskStore.getTask(taskId);
219
- expect(task.status).toBe('cancelled');
220
- });
221
- it('should throw error when updating non-existent task', () => {
222
- expect(() => {
223
- taskStore.updateTaskStatus('non-existent', 'completed');
224
- }).toThrow(TaskError);
225
- });
226
- it('should throw error when changing completed task status', () => {
227
- taskStore.updateTaskStatus(taskId, 'in_progress');
228
- taskStore.updateTaskStatus(taskId, 'completed');
229
- expect(() => {
230
- taskStore.updateTaskStatus(taskId, 'in_progress');
231
- }).toThrow(TaskError);
232
- });
233
- it('should allow changing completed task to cancelled', () => {
234
- taskStore.updateTaskStatus(taskId, 'in_progress');
235
- taskStore.updateTaskStatus(taskId, 'completed');
236
- // Should allow completed -> cancelled
237
- expect(() => {
238
- taskStore.updateTaskStatus(taskId, 'cancelled');
239
- }).not.toThrow();
240
- const task = taskStore.getTask(taskId);
241
- expect(task.status).toBe('cancelled');
242
- });
243
- it('should calculate actual effort correctly', () => {
244
- const startTime = Date.now();
245
- taskStore.updateTaskStatus(taskId, 'in_progress');
246
- // Simulate some work time
247
- vi.useFakeTimers();
248
- vi.advanceTimersByTime(30 * 60 * 1000); // 30 minutes
249
- taskStore.updateTaskStatus(taskId, 'completed');
250
- const task = taskStore.getTask(taskId);
251
- expect(task.actual_effort).toBe(30); // 30 minutes
252
- vi.useRealTimers();
253
- });
254
- it('should update task type based on status change', () => {
255
- const task1 = taskStore.getTask(taskId);
256
- expect(task1.type).toBe('task_create');
257
- taskStore.updateTaskStatus(taskId, 'in_progress');
258
- const task2 = taskStore.getTask(taskId);
259
- expect(task2.type).toBe('task_update');
260
- taskStore.updateTaskStatus(taskId, 'completed');
261
- const task3 = taskStore.getTask(taskId);
262
- expect(task3.type).toBe('task_complete');
263
- const blockedTaskId = taskStore.createTask({
264
- title: 'Blocked Task',
265
- frameId: 'frame-blocked'
266
- });
267
- taskStore.updateTaskStatus(blockedTaskId, 'blocked');
268
- const task4 = taskStore.getTask(blockedTaskId);
269
- expect(task4.type).toBe('task_block');
270
- });
271
- });
272
- describe('Task Dependencies', () => {
273
- let task1Id;
274
- let task2Id;
275
- beforeEach(() => {
276
- task1Id = taskStore.createTask({
277
- title: 'Task 1',
278
- frameId: 'frame-1'
279
- });
280
- task2Id = taskStore.createTask({
281
- title: 'Task 2',
282
- frameId: 'frame-2'
283
- });
284
- });
285
- it('should add dependency relationship', () => {
286
- taskStore.addDependency(task2Id, task1Id);
287
- const task2 = taskStore.getTask(task2Id);
288
- const task1 = taskStore.getTask(task1Id);
289
- expect(task2.depends_on).toContain(task1Id);
290
- expect(task1.blocks).toContain(task2Id);
291
- });
292
- it('should prevent duplicate dependencies', () => {
293
- taskStore.addDependency(task2Id, task1Id);
294
- taskStore.addDependency(task2Id, task1Id); // Add again
295
- const task2 = taskStore.getTask(task2Id);
296
- expect(task2.depends_on.filter(id => id === task1Id)).toHaveLength(1);
297
- });
298
- it('should throw error for non-existent task', () => {
299
- expect(() => {
300
- taskStore.addDependency('non-existent', task1Id);
301
- }).toThrow(TaskError);
302
- expect(() => {
303
- taskStore.addDependency(task2Id, 'non-existent');
304
- }).toThrow(TaskError);
305
- });
306
- it('should detect circular dependencies', () => {
307
- taskStore.addDependency(task2Id, task1Id); // task2 depends on task1
308
- // Try to make task1 depend on task2 (circular)
309
- expect(() => {
310
- taskStore.addDependency(task1Id, task2Id);
311
- }).toThrow(TaskError);
312
- });
313
- it('should detect complex circular dependencies', () => {
314
- const task3Id = taskStore.createTask({
315
- title: 'Task 3',
316
- frameId: 'frame-3'
317
- });
318
- const task4Id = taskStore.createTask({
319
- title: 'Task 4',
320
- frameId: 'frame-4'
321
- });
322
- // Create chain: task1 -> task2 -> task3 -> task4
323
- taskStore.addDependency(task2Id, task1Id);
324
- taskStore.addDependency(task3Id, task2Id);
325
- taskStore.addDependency(task4Id, task3Id);
326
- // Try to make task1 depend on task4 (circular)
327
- expect(() => {
328
- taskStore.addDependency(task1Id, task4Id);
329
- }).toThrow(TaskError);
330
- });
331
- it('should handle self-dependency prevention', () => {
332
- expect(() => {
333
- taskStore.addDependency(task1Id, task1Id);
334
- }).toThrow(TaskError);
335
- });
336
- });
337
- describe('Task Queries', () => {
338
- beforeEach(() => {
339
- // Create various tasks for testing
340
- const tasks = [
341
- { title: 'Active Task 1', status: 'pending', priority: 'high', frameId: 'frame-1' },
342
- { title: 'Active Task 2', status: 'in_progress', priority: 'medium', frameId: 'frame-1' },
343
- { title: 'Completed Task', status: 'completed', priority: 'low', frameId: 'frame-2' },
344
- { title: 'Blocked Task', status: 'blocked', priority: 'urgent', frameId: 'frame-3' },
345
- { title: 'Cancelled Task', status: 'cancelled', priority: 'medium', frameId: 'frame-3' }
346
- ];
347
- tasks.forEach(task => {
348
- const taskId = taskStore.createTask(task);
349
- if (task.status !== 'pending') {
350
- taskStore.updateTaskStatus(taskId, task.status);
351
- }
352
- });
353
- });
354
- it('should get all active tasks', () => {
355
- const activeTasks = taskStore.getActiveTasks();
356
- expect(activeTasks).toHaveLength(3); // pending, in_progress, blocked
357
- expect(activeTasks.every(t => ['pending', 'in_progress'].includes(t.status))).toBe(true);
358
- });
359
- it('should get active tasks filtered by frame', () => {
360
- const frame1Tasks = taskStore.getActiveTasks('frame-1');
361
- expect(frame1Tasks).toHaveLength(2);
362
- expect(frame1Tasks.every(t => t.frame_id === 'frame-1')).toBe(true);
363
- });
364
- it('should order active tasks by priority and creation time', () => {
365
- const activeTasks = taskStore.getActiveTasks();
366
- // Should be ordered by priority desc, created_at asc
367
- const priorities = activeTasks.map(t => t.priority);
368
- expect(priorities[0]).toBe('high'); // Highest priority first
369
- });
370
- it('should get blocking tasks', () => {
371
- // Create tasks with blocking relationships
372
- const blockingTaskId = taskStore.createTask({
373
- title: 'Blocking Task',
374
- frameId: 'frame-blocker'
375
- });
376
- const dependentTaskId = taskStore.createTask({
377
- title: 'Dependent Task',
378
- frameId: 'frame-dependent'
379
- });
380
- taskStore.addDependency(dependentTaskId, blockingTaskId);
381
- const blockingTasks = taskStore.getBlockingTasks();
382
- expect(blockingTasks.length).toBeGreaterThan(0);
383
- const foundBlocking = blockingTasks.find(t => t.id === blockingTaskId);
384
- expect(foundBlocking).toBeDefined();
385
- });
386
- it('should return empty array when no active tasks exist', () => {
387
- // Complete all tasks
388
- const activeTasks = taskStore.getActiveTasks();
389
- activeTasks.forEach(task => {
390
- if (task.status === 'pending') {
391
- taskStore.updateTaskStatus(task.id, 'in_progress');
392
- }
393
- if (task.status === 'in_progress') {
394
- taskStore.updateTaskStatus(task.id, 'completed');
395
- }
396
- if (task.status === 'blocked') {
397
- taskStore.updateTaskStatus(task.id, 'cancelled');
398
- }
399
- });
400
- const remainingActive = taskStore.getActiveTasks();
401
- expect(remainingActive).toHaveLength(0);
402
- });
403
- });
404
- describe('Task Metrics', () => {
405
- beforeEach(() => {
406
- // Create tasks with various states for metrics testing
407
- const tasks = [
408
- { title: 'Task 1', status: 'pending', priority: 'high' },
409
- { title: 'Task 2', status: 'pending', priority: 'medium' },
410
- { title: 'Task 3', status: 'completed', priority: 'low', effort: 30 },
411
- { title: 'Task 4', status: 'completed', priority: 'high', effort: 60 },
412
- { title: 'Task 5', status: 'blocked', priority: 'urgent' },
413
- { title: 'Task 6', status: 'cancelled', priority: 'medium' }
414
- ];
415
- tasks.forEach(task => {
416
- const taskId = taskStore.createTask({
417
- title: task.title,
418
- frameId: 'frame-metrics',
419
- priority: task.priority,
420
- estimatedEffort: task.effort
421
- });
422
- if (task.status !== 'pending') {
423
- if (task.status === 'completed') {
424
- taskStore.updateTaskStatus(taskId, 'in_progress');
425
- }
426
- taskStore.updateTaskStatus(taskId, task.status);
427
- }
428
- });
429
- });
430
- it('should calculate basic metrics correctly', () => {
431
- const metrics = taskStore.getMetrics();
432
- expect(metrics.total_tasks).toBe(6);
433
- expect(metrics.by_status.pending).toBe(2);
434
- expect(metrics.by_status.completed).toBe(2);
435
- expect(metrics.by_status.blocked).toBe(1);
436
- expect(metrics.by_status.cancelled).toBe(1);
437
- expect(metrics.by_priority.high).toBe(2);
438
- expect(metrics.by_priority.medium).toBe(2);
439
- expect(metrics.by_priority.low).toBe(1);
440
- expect(metrics.by_priority.urgent).toBe(1);
441
- expect(metrics.completion_rate).toBe(2 / 6); // 2 completed out of 6 total
442
- expect(metrics.blocked_tasks).toBe(1);
443
- });
444
- it('should handle metrics when no tasks exist', () => {
445
- // Create empty task store
446
- const emptyDb = new Database(':memory:');
447
- const emptyStore = new PebblesTaskStore(projectRoot, emptyDb);
448
- const metrics = emptyStore.getMetrics();
449
- expect(metrics.total_tasks).toBe(0);
450
- expect(metrics.completion_rate).toBe(0);
451
- expect(metrics.blocked_tasks).toBe(0);
452
- emptyDb.close();
453
- });
454
- it('should calculate effort accuracy', () => {
455
- // Create task with estimated effort for accuracy calculation
456
- const taskId = taskStore.createTask({
457
- title: 'Effort Test',
458
- frameId: 'frame-effort',
459
- estimatedEffort: 60 // 1 hour estimate
460
- });
461
- taskStore.updateTaskStatus(taskId, 'in_progress');
462
- // Mock actual effort to be close to estimate
463
- const task = taskStore.getTask(taskId);
464
- if (task) {
465
- // Manually update actual effort for testing
466
- const stmt = db.prepare(`
467
- UPDATE task_cache
468
- SET actual_effort = ?
469
- WHERE id = ?
470
- `);
471
- stmt.run(50, taskId); // Actual: 50 min vs Estimate: 60 min
472
- }
473
- const metrics = taskStore.getMetrics();
474
- expect(metrics.avg_effort_accuracy).toBeGreaterThan(0);
475
- });
476
- });
477
- describe('Linear Integration Export', () => {
478
- beforeEach(() => {
479
- // Create tasks without Linear integration
480
- taskStore.createTask({
481
- title: 'Local Task 1',
482
- frameId: 'frame-1',
483
- description: 'Task for Linear export',
484
- priority: 'high',
485
- estimatedEffort: 120
486
- });
487
- taskStore.createTask({
488
- title: 'Local Task 2',
489
- frameId: 'frame-2',
490
- priority: 'medium'
491
- });
492
- // Create task with existing Linear reference (should be excluded)
493
- const taskWithLinear = taskStore.createTask({
494
- title: 'Already Synced',
495
- frameId: 'frame-3'
496
- });
497
- // Manually add Linear external reference
498
- db.prepare(`
499
- UPDATE task_cache
500
- SET external_refs = ?
501
- WHERE id = ?
502
- `).run(JSON.stringify({ linear: { id: 'LIN-123' } }), taskWithLinear);
503
- });
504
- it('should export tasks for Linear integration', () => {
505
- const exported = taskStore.exportForLinear();
506
- expect(exported).toHaveLength(2); // Should exclude task with existing Linear ref
507
- const task1 = exported.find(t => t.title === 'Local Task 1');
508
- expect(task1).toBeDefined();
509
- expect(task1.description).toBe('Task for Linear export');
510
- expect(task1.priority).toBe(3); // high -> 3 in Linear
511
- expect(task1.estimate).toBe(120);
512
- const task2 = exported.find(t => t.title === 'Local Task 2');
513
- expect(task2).toBeDefined();
514
- expect(task2.priority).toBe(2); // medium -> 2 in Linear
515
- });
516
- it('should map priorities correctly for Linear', () => {
517
- const priorities = {
518
- low: 1,
519
- medium: 2,
520
- high: 3,
521
- urgent: 4
522
- };
523
- Object.entries(priorities).forEach(([priority, expectedValue]) => {
524
- const taskId = taskStore.createTask({
525
- title: `Priority ${priority}`,
526
- frameId: 'frame-priority',
527
- priority: priority
528
- });
529
- const exported = taskStore.exportForLinear();
530
- const task = exported.find(t => t.title === `Priority ${priority}`);
531
- expect(task.priority).toBe(expectedValue);
532
- });
533
- });
534
- it('should map statuses correctly for Linear', () => {
535
- const statusMappings = {
536
- pending: 'Backlog',
537
- in_progress: 'In Progress',
538
- completed: 'Done',
539
- blocked: 'Blocked',
540
- cancelled: 'Cancelled'
541
- };
542
- Object.entries(statusMappings).forEach(([status, expectedLinearStatus]) => {
543
- const taskId = taskStore.createTask({
544
- title: `Status ${status}`,
545
- frameId: 'frame-status'
546
- });
547
- if (status !== 'pending') {
548
- taskStore.updateTaskStatus(taskId, status);
549
- }
550
- const exported = taskStore.exportForLinear();
551
- const task = exported.find(t => t.title === `Status ${status}`);
552
- expect(task.status).toBe(expectedLinearStatus);
553
- });
554
- });
555
- });
556
- describe('Error Handling and Edge Cases', () => {
557
- it('should handle database errors gracefully', () => {
558
- const taskId = taskStore.createTask({
559
- title: 'Error Test',
560
- frameId: 'frame-error'
561
- });
562
- // Close database to simulate error
563
- db.close();
564
- expect(() => {
565
- taskStore.getTask(taskId);
566
- }).toThrow(DatabaseError);
567
- expect(() => {
568
- taskStore.updateTaskStatus(taskId, 'completed');
569
- }).toThrow();
570
- });
571
- it('should handle JSONL file write errors gracefully', () => {
572
- // Mock fs.appendFile to throw error
573
- const originalAppendFile = require('fs').appendFile;
574
- require('fs').appendFile = vi.fn((path, data, callback) => {
575
- callback(new Error('Write failed'));
576
- });
577
- // Should not throw but should log error
578
- expect(() => {
579
- taskStore.createTask({
580
- title: 'Write Error Test',
581
- frameId: 'frame-write-error'
582
- });
583
- }).not.toThrow();
584
- // Restore original
585
- require('fs').appendFile = originalAppendFile;
586
- });
587
- it('should handle concurrent task operations', () => {
588
- const tasks = [];
589
- // Create multiple tasks quickly
590
- for (let i = 0; i < 20; i++) {
591
- const taskId = taskStore.createTask({
592
- title: `Concurrent Task ${i}`,
593
- frameId: `frame-${i}`,
594
- priority: i % 2 === 0 ? 'high' : 'low'
595
- });
596
- tasks.push(taskId);
597
- }
598
- expect(tasks).toHaveLength(20);
599
- // Update all tasks concurrently
600
- tasks.forEach(taskId => {
601
- taskStore.updateTaskStatus(taskId, 'completed');
602
- });
603
- // Verify all updates
604
- const allCompleted = tasks.every(taskId => {
605
- const task = taskStore.getTask(taskId);
606
- return task?.status === 'completed';
607
- });
608
- expect(allCompleted).toBe(true);
609
- });
610
- it('should handle empty or malformed task IDs', () => {
611
- expect(taskStore.getTask('')).toBeUndefined();
612
- expect(taskStore.getTask('invalid-format')).toBeUndefined();
613
- expect(taskStore.getTask('null')).toBeUndefined();
614
- });
615
- it('should validate task status transitions', () => {
616
- const taskId = taskStore.createTask({
617
- title: 'Status Validation',
618
- frameId: 'frame-validation'
619
- });
620
- // Valid transitions should work
621
- expect(() => {
622
- taskStore.updateTaskStatus(taskId, 'in_progress');
623
- }).not.toThrow();
624
- expect(() => {
625
- taskStore.updateTaskStatus(taskId, 'blocked');
626
- }).not.toThrow();
627
- expect(() => {
628
- taskStore.updateTaskStatus(taskId, 'in_progress');
629
- }).not.toThrow();
630
- expect(() => {
631
- taskStore.updateTaskStatus(taskId, 'completed');
632
- }).not.toThrow();
633
- // Invalid transition: completed -> in_progress
634
- expect(() => {
635
- taskStore.updateTaskStatus(taskId, 'in_progress');
636
- }).toThrow(TaskError);
637
- });
638
- it('should handle tasks with complex metadata', () => {
639
- const taskId = taskStore.createTask({
640
- title: 'Complex Metadata Task',
641
- frameId: 'frame-complex',
642
- tags: ['complex', 'metadata', 'test'],
643
- dependsOn: [],
644
- });
645
- // Add dependency to test complex relationships
646
- const depTaskId = taskStore.createTask({
647
- title: 'Dependency Task',
648
- frameId: 'frame-dep'
649
- });
650
- taskStore.addDependency(taskId, depTaskId);
651
- const task = taskStore.getTask(taskId);
652
- expect(task.tags).toEqual(['complex', 'metadata', 'test']);
653
- expect(task.depends_on).toContain(depTaskId);
654
- });
655
- });
656
- describe('Data Integrity and Consistency', () => {
657
- it('should maintain referential integrity in dependencies', () => {
658
- const task1Id = taskStore.createTask({
659
- title: 'Task 1',
660
- frameId: 'frame-1'
661
- });
662
- const task2Id = taskStore.createTask({
663
- title: 'Task 2',
664
- frameId: 'frame-2'
665
- });
666
- taskStore.addDependency(task2Id, task1Id);
667
- // Check both sides of relationship
668
- const task1 = taskStore.getTask(task1Id);
669
- const task2 = taskStore.getTask(task2Id);
670
- expect(task2.depends_on).toContain(task1Id);
671
- expect(task1.blocks).toContain(task2Id);
672
- });
673
- it('should ensure content-based task IDs are deterministic for same content', () => {
674
- const now = Math.floor(Date.now() / 1000);
675
- // Mock Math.random to return consistent value
676
- const originalRandom = Math.random;
677
- Math.random = vi.fn(() => 0.5);
678
- // Mock Date.now to return consistent value
679
- vi.spyOn(Date, 'now').mockReturnValue(now * 1000);
680
- try {
681
- const taskId1 = taskStore.createTask({
682
- title: 'Deterministic Task',
683
- frameId: 'frame-det'
684
- });
685
- const taskId2 = taskStore.createTask({
686
- title: 'Deterministic Task',
687
- frameId: 'frame-det'
688
- });
689
- // Should be different due to timestamp and random components
690
- expect(taskId1).not.toBe(taskId2);
691
- // But should follow consistent format
692
- expect(taskId1).toMatch(/^tsk-[a-f0-9]{8}$/);
693
- expect(taskId2).toMatch(/^tsk-[a-f0-9]{8}$/);
694
- }
695
- finally {
696
- Math.random = originalRandom;
697
- vi.restoreAllMocks();
698
- }
699
- });
700
- it('should handle JSON serialization edge cases', () => {
701
- const taskId = taskStore.createTask({
702
- title: 'JSON Edge Cases',
703
- frameId: 'frame-json',
704
- tags: ['tag with spaces', 'tag"with"quotes', 'tag\\with\\slashes'],
705
- dependsOn: []
706
- });
707
- const task = taskStore.getTask(taskId);
708
- expect(task.tags).toEqual(['tag with spaces', 'tag"with"quotes', 'tag\\with\\slashes']);
709
- });
710
- });
711
- });
712
- //# sourceMappingURL=pebbles-task-store.test.js.map