@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,700 +0,0 @@
1
- /**
2
- * Tests for LinearSyncService - Bidirectional sync with Linear
3
- */
4
- import { describe, it, expect, beforeEach, afterEach, vi } from 'vitest';
5
- import { LinearSyncService } from '../sync-service.js';
6
- import { LinearClient } from '../client.js';
7
- import { ContextService } from '../../../services/context-service.js';
8
- import { ConfigService } from '../../../services/config-service.js';
9
- // Mock dependencies
10
- vi.mock('../client.js', () => ({
11
- LinearClient: vi.fn()
12
- }));
13
- vi.mock('../../../services/context-service.js', () => ({
14
- ContextService: vi.fn()
15
- }));
16
- vi.mock('../../../services/config-service.js', () => ({
17
- ConfigService: vi.fn()
18
- }));
19
- vi.mock('../../../utils/logger.js', () => ({
20
- Logger: vi.fn().mockImplementation(() => ({
21
- info: vi.fn(),
22
- error: vi.fn(),
23
- debug: vi.fn(),
24
- warn: vi.fn()
25
- }))
26
- }));
27
- describe('LinearSyncService', () => {
28
- let syncService;
29
- let mockLinearClient;
30
- let mockContextService;
31
- let mockConfigService;
32
- let originalEnv;
33
- beforeEach(() => {
34
- // Store original environment
35
- originalEnv = process.env;
36
- // Set required environment variable
37
- process.env.LINEAR_API_KEY = 'test-api-key';
38
- // Setup mocks
39
- mockLinearClient = {
40
- getIssues: vi.fn(),
41
- updateIssue: vi.fn(),
42
- createIssue: vi.fn()
43
- };
44
- mockContextService = {
45
- getTaskByExternalId: vi.fn(),
46
- updateTask: vi.fn(),
47
- createTask: vi.fn(),
48
- getTask: vi.fn(),
49
- deleteTask: vi.fn(),
50
- getAllTasks: vi.fn()
51
- };
52
- mockConfigService = {
53
- getConfig: vi.fn()
54
- };
55
- // Configure mock constructors
56
- LinearClient.mockImplementation(() => mockLinearClient);
57
- ContextService.mockImplementation(() => mockContextService);
58
- ConfigService.mockImplementation(() => mockConfigService);
59
- // Create sync service instance
60
- syncService = new LinearSyncService();
61
- });
62
- afterEach(() => {
63
- // Restore environment
64
- process.env = originalEnv;
65
- vi.clearAllMocks();
66
- });
67
- describe('Initialization', () => {
68
- it('should initialize with Linear API key from environment', () => {
69
- expect(LinearClient).toHaveBeenCalledWith({ apiKey: 'test-api-key' });
70
- });
71
- it('should throw error when LINEAR_API_KEY is not set', () => {
72
- delete process.env.LINEAR_API_KEY;
73
- expect(() => {
74
- new LinearSyncService();
75
- }).toThrow('LINEAR_API_KEY environment variable not set');
76
- });
77
- it('should initialize services correctly', () => {
78
- expect(ContextService).toHaveBeenCalled();
79
- expect(ConfigService).toHaveBeenCalled();
80
- });
81
- });
82
- describe('syncAllIssues', () => {
83
- beforeEach(() => {
84
- mockConfigService.getConfig.mockResolvedValue({
85
- integrations: {
86
- linear: {
87
- teamId: 'test-team-id'
88
- }
89
- }
90
- });
91
- });
92
- it('should sync all issues from Linear successfully', async () => {
93
- const mockIssues = [
94
- {
95
- id: 'issue-1',
96
- identifier: 'STA-1',
97
- title: 'Test Issue 1',
98
- description: 'Description 1',
99
- state: { type: 'unstarted' },
100
- priority: 2,
101
- url: 'https://linear.app/issue-1',
102
- team: { id: 'team-1', key: 'STA' },
103
- labels: [{ name: 'bug' }],
104
- updatedAt: new Date().toISOString()
105
- },
106
- {
107
- id: 'issue-2',
108
- identifier: 'STA-2',
109
- title: 'Test Issue 2',
110
- description: 'Description 2',
111
- state: { type: 'completed' },
112
- priority: 3,
113
- url: 'https://linear.app/issue-2',
114
- team: { id: 'team-1', key: 'STA' },
115
- labels: [],
116
- updatedAt: new Date().toISOString()
117
- }
118
- ];
119
- mockLinearClient.getIssues.mockResolvedValue(mockIssues);
120
- mockContextService.getTaskByExternalId.mockResolvedValue(null); // No existing tasks
121
- const result = await syncService.syncAllIssues();
122
- expect(result.created).toBe(2);
123
- expect(result.updated).toBe(0);
124
- expect(result.errors).toHaveLength(0);
125
- expect(mockContextService.createTask).toHaveBeenCalledTimes(2);
126
- });
127
- it('should update existing tasks when they have changes', async () => {
128
- const mockIssue = {
129
- id: 'issue-1',
130
- identifier: 'STA-1',
131
- title: 'Updated Title',
132
- description: 'Updated Description',
133
- state: { type: 'completed' },
134
- priority: 3,
135
- url: 'https://linear.app/issue-1',
136
- team: { id: 'team-1', key: 'STA' },
137
- labels: [{ name: 'feature' }],
138
- updatedAt: new Date().toISOString()
139
- };
140
- const existingTask = {
141
- id: 'local-task-1',
142
- title: 'Old Title',
143
- description: 'Old Description',
144
- status: 'todo',
145
- priority: 'high',
146
- externalId: 'issue-1'
147
- };
148
- mockLinearClient.getIssues.mockResolvedValue([mockIssue]);
149
- mockContextService.getTaskByExternalId.mockResolvedValue(existingTask);
150
- const result = await syncService.syncAllIssues();
151
- expect(result.created).toBe(0);
152
- expect(result.updated).toBe(1);
153
- expect(mockContextService.updateTask).toHaveBeenCalledWith('local-task-1', expect.objectContaining({
154
- title: 'Updated Title',
155
- description: 'Updated Description',
156
- status: 'done',
157
- priority: 'medium'
158
- }));
159
- });
160
- it('should skip tasks without changes', async () => {
161
- const mockIssue = {
162
- id: 'issue-1',
163
- identifier: 'STA-1',
164
- title: 'Same Title',
165
- description: 'Same Description',
166
- state: { type: 'unstarted' },
167
- priority: 2,
168
- url: 'https://linear.app/issue-1',
169
- team: { id: 'team-1', key: 'STA' },
170
- labels: [{ name: 'bug' }],
171
- updatedAt: new Date().toISOString()
172
- };
173
- const existingTask = {
174
- id: 'local-task-1',
175
- title: 'Same Title',
176
- description: 'Same Description',
177
- status: 'todo',
178
- priority: 'high',
179
- tags: ['bug'],
180
- externalId: 'issue-1'
181
- };
182
- mockLinearClient.getIssues.mockResolvedValue([mockIssue]);
183
- mockContextService.getTaskByExternalId.mockResolvedValue(existingTask);
184
- const result = await syncService.syncAllIssues();
185
- expect(result.created).toBe(0);
186
- expect(result.updated).toBe(0);
187
- expect(mockContextService.updateTask).not.toHaveBeenCalled();
188
- });
189
- it('should handle sync errors gracefully', async () => {
190
- const mockIssues = [
191
- {
192
- id: 'issue-1',
193
- identifier: 'STA-1',
194
- title: 'Test Issue',
195
- state: { type: 'unstarted' },
196
- team: { id: 'team-1', key: 'STA' },
197
- updatedAt: new Date().toISOString()
198
- }
199
- ];
200
- mockLinearClient.getIssues.mockResolvedValue(mockIssues);
201
- mockContextService.getTaskByExternalId.mockRejectedValue(new Error('Database error'));
202
- const result = await syncService.syncAllIssues();
203
- expect(result.errors).toHaveLength(1);
204
- expect(result.errors[0]).toContain('Failed to sync STA-1');
205
- });
206
- it('should throw error when Linear team ID is not configured', async () => {
207
- mockConfigService.getConfig.mockResolvedValue({
208
- integrations: {}
209
- });
210
- const result = await syncService.syncAllIssues();
211
- expect(result.errors).toContain('Linear team ID not configured');
212
- });
213
- it('should handle Linear API errors', async () => {
214
- mockConfigService.getConfig.mockResolvedValue({
215
- integrations: {
216
- linear: { teamId: 'test-team-id' }
217
- }
218
- });
219
- mockLinearClient.getIssues.mockRejectedValue(new Error('Linear API error'));
220
- const result = await syncService.syncAllIssues();
221
- expect(result.errors).toContain('Linear API error');
222
- });
223
- });
224
- describe('syncIssueToLocal', () => {
225
- it('should create new local task from Linear issue', async () => {
226
- const mockIssue = {
227
- id: 'issue-1',
228
- identifier: 'STA-1',
229
- title: 'New Issue',
230
- description: 'Issue description',
231
- state: { type: 'unstarted', id: 'state-1', name: 'Todo' },
232
- priority: 1,
233
- url: 'https://linear.app/issue-1',
234
- team: { id: 'team-1', key: 'STA' },
235
- labels: [{ name: 'bug' }, { name: 'urgent' }],
236
- project: { id: 'proj-1', name: 'Main Project' },
237
- assignee: { id: 'user-1', name: 'John Doe' },
238
- updatedAt: new Date().toISOString()
239
- };
240
- mockContextService.getTaskByExternalId.mockResolvedValue(null);
241
- const result = await syncService.syncIssueToLocal(mockIssue);
242
- expect(result).toBe('created');
243
- expect(mockContextService.createTask).toHaveBeenCalledWith({
244
- title: 'New Issue',
245
- description: 'Issue description',
246
- status: 'todo',
247
- priority: 'urgent',
248
- externalId: 'issue-1',
249
- externalIdentifier: 'STA-1',
250
- externalUrl: 'https://linear.app/issue-1',
251
- tags: ['bug', 'urgent'],
252
- metadata: {
253
- linear: {
254
- teamId: 'team-1',
255
- teamKey: 'STA',
256
- stateId: 'state-1',
257
- stateName: 'Todo',
258
- projectId: 'proj-1',
259
- projectName: 'Main Project',
260
- assigneeId: 'user-1',
261
- assigneeName: 'John Doe'
262
- }
263
- },
264
- updatedAt: expect.any(Date)
265
- });
266
- });
267
- it('should update existing local task', async () => {
268
- const mockIssue = {
269
- id: 'issue-1',
270
- identifier: 'STA-1',
271
- title: 'Updated Issue',
272
- description: 'Updated description',
273
- state: { type: 'started', id: 'state-2', name: 'In Progress' },
274
- priority: 2,
275
- url: 'https://linear.app/issue-1',
276
- team: { id: 'team-1', key: 'STA' },
277
- labels: [{ name: 'feature' }],
278
- updatedAt: new Date().toISOString()
279
- };
280
- const existingTask = {
281
- id: 'local-1',
282
- title: 'Old Title',
283
- description: 'Old description',
284
- status: 'todo',
285
- priority: 'low',
286
- tags: ['old-tag'],
287
- externalId: 'issue-1',
288
- createdAt: new Date(),
289
- updatedAt: new Date()
290
- };
291
- mockContextService.getTaskByExternalId.mockResolvedValue(existingTask);
292
- const result = await syncService.syncIssueToLocal(mockIssue);
293
- expect(result).toBe('updated');
294
- expect(mockContextService.updateTask).toHaveBeenCalledWith('local-1', {
295
- title: 'Updated Issue',
296
- description: 'Updated description',
297
- status: 'in_progress',
298
- priority: 'high',
299
- externalId: 'issue-1',
300
- externalIdentifier: 'STA-1',
301
- externalUrl: 'https://linear.app/issue-1',
302
- tags: ['feature'],
303
- metadata: {
304
- linear: {
305
- teamId: 'team-1',
306
- teamKey: 'STA',
307
- stateId: 'state-2',
308
- stateName: 'In Progress',
309
- projectId: undefined,
310
- projectName: undefined,
311
- assigneeId: undefined,
312
- assigneeName: undefined
313
- }
314
- },
315
- updatedAt: expect.any(Date)
316
- });
317
- });
318
- it('should handle sync errors and rethrow', async () => {
319
- const mockIssue = {
320
- id: 'issue-1',
321
- identifier: 'STA-1',
322
- title: 'Error Issue',
323
- state: { type: 'unstarted' },
324
- team: { id: 'team-1', key: 'STA' },
325
- updatedAt: new Date().toISOString()
326
- };
327
- mockContextService.getTaskByExternalId.mockRejectedValue(new Error('Database error'));
328
- await expect(syncService.syncIssueToLocal(mockIssue)).rejects.toThrow('Database error');
329
- });
330
- });
331
- describe('syncLocalToLinear', () => {
332
- it('should create new Linear issue from local task', async () => {
333
- const mockTask = {
334
- id: 'local-1',
335
- title: 'Local Task',
336
- description: 'Local description',
337
- status: 'todo',
338
- priority: 'high',
339
- tags: [],
340
- createdAt: new Date(),
341
- updatedAt: new Date()
342
- };
343
- const mockCreatedIssue = {
344
- id: 'issue-1',
345
- identifier: 'STA-1',
346
- title: 'Local Task',
347
- url: 'https://linear.app/issue-1'
348
- };
349
- mockContextService.getTask.mockResolvedValue(mockTask);
350
- mockLinearClient.createIssue.mockResolvedValue(mockCreatedIssue);
351
- const result = await syncService.syncLocalToLinear('local-1');
352
- expect(result).toEqual(mockCreatedIssue);
353
- expect(mockLinearClient.createIssue).toHaveBeenCalledWith({
354
- title: 'Local Task',
355
- description: 'Local description',
356
- priority: 3, // high -> 3
357
- stateId: undefined,
358
- projectId: undefined,
359
- assigneeId: undefined
360
- });
361
- expect(mockContextService.updateTask).toHaveBeenCalledWith('local-1', {
362
- externalId: 'issue-1'
363
- });
364
- });
365
- it('should update existing Linear issue', async () => {
366
- const mockTask = {
367
- id: 'local-1',
368
- title: 'Updated Local Task',
369
- description: 'Updated description',
370
- status: 'in_progress',
371
- priority: 'medium',
372
- tags: [],
373
- externalId: 'issue-1',
374
- metadata: {
375
- linear: {
376
- stateId: 'state-1',
377
- projectId: 'proj-1',
378
- assigneeId: 'user-1'
379
- }
380
- },
381
- createdAt: new Date(),
382
- updatedAt: new Date()
383
- };
384
- const mockUpdatedIssue = {
385
- id: 'issue-1',
386
- identifier: 'STA-1',
387
- title: 'Updated Local Task'
388
- };
389
- mockContextService.getTask.mockResolvedValue(mockTask);
390
- mockLinearClient.updateIssue.mockResolvedValue(mockUpdatedIssue);
391
- const result = await syncService.syncLocalToLinear('local-1');
392
- expect(result).toEqual(mockUpdatedIssue);
393
- expect(mockLinearClient.updateIssue).toHaveBeenCalledWith('issue-1', {
394
- title: 'Updated Local Task',
395
- description: 'Updated description',
396
- priority: 2, // medium -> 2
397
- stateId: 'state-1',
398
- projectId: 'proj-1',
399
- assigneeId: 'user-1'
400
- });
401
- });
402
- it('should throw error for non-existent task', async () => {
403
- mockContextService.getTask.mockResolvedValue(null);
404
- await expect(syncService.syncLocalToLinear('non-existent')).rejects.toThrow('Task non-existent not found');
405
- });
406
- it('should handle Linear API errors', async () => {
407
- const mockTask = {
408
- id: 'local-1',
409
- title: 'Task',
410
- description: 'Test task description',
411
- status: 'todo',
412
- priority: 'medium',
413
- tags: [],
414
- createdAt: new Date(),
415
- updatedAt: new Date()
416
- };
417
- mockContextService.getTask.mockResolvedValue(mockTask);
418
- mockLinearClient.createIssue.mockRejectedValue(new Error('Linear API error'));
419
- await expect(syncService.syncLocalToLinear('local-1')).rejects.toThrow('Linear API error');
420
- });
421
- });
422
- describe('removeLocalIssue', () => {
423
- it('should remove local task by Linear identifier', async () => {
424
- const mockTasks = [
425
- {
426
- id: 'local-1',
427
- title: 'Task 1',
428
- description: 'Task 1 description',
429
- status: 'todo',
430
- priority: 'medium',
431
- tags: [],
432
- externalIdentifier: 'STA-1',
433
- createdAt: new Date(),
434
- updatedAt: new Date()
435
- },
436
- {
437
- id: 'local-2',
438
- title: 'Task 2',
439
- description: 'Task 2 description',
440
- status: 'todo',
441
- priority: 'medium',
442
- tags: [],
443
- externalIdentifier: 'STA-2',
444
- createdAt: new Date(),
445
- updatedAt: new Date()
446
- }
447
- ];
448
- mockContextService.getAllTasks.mockResolvedValue(mockTasks);
449
- await syncService.removeLocalIssue('STA-1');
450
- expect(mockContextService.deleteTask).toHaveBeenCalledWith('local-1');
451
- });
452
- it('should handle non-existent identifier gracefully', async () => {
453
- mockContextService.getAllTasks.mockResolvedValue([]);
454
- await expect(syncService.removeLocalIssue('NON-EXISTENT')).resolves.not.toThrow();
455
- expect(mockContextService.deleteTask).not.toHaveBeenCalled();
456
- });
457
- it('should handle deletion errors', async () => {
458
- const mockTasks = [{
459
- id: 'local-1',
460
- title: 'Task',
461
- description: 'Task description',
462
- status: 'todo',
463
- priority: 'medium',
464
- tags: [],
465
- externalIdentifier: 'STA-1',
466
- createdAt: new Date(),
467
- updatedAt: new Date()
468
- }];
469
- mockContextService.getAllTasks.mockResolvedValue(mockTasks);
470
- mockContextService.deleteTask.mockRejectedValue(new Error('Delete error'));
471
- await expect(syncService.removeLocalIssue('STA-1')).rejects.toThrow('Delete error');
472
- });
473
- });
474
- describe('Status and Priority Mapping', () => {
475
- it('should map Linear states to task statuses correctly', () => {
476
- const testCases = [
477
- { linearState: 'backlog', expectedStatus: 'todo' },
478
- { linearState: 'triage', expectedStatus: 'todo' },
479
- { linearState: 'unstarted', expectedStatus: 'todo' },
480
- { linearState: 'todo', expectedStatus: 'todo' },
481
- { linearState: 'started', expectedStatus: 'in_progress' },
482
- { linearState: 'in_progress', expectedStatus: 'in_progress' },
483
- { linearState: 'completed', expectedStatus: 'done' },
484
- { linearState: 'done', expectedStatus: 'done' },
485
- { linearState: 'canceled', expectedStatus: 'cancelled' },
486
- { linearState: 'cancelled', expectedStatus: 'cancelled' },
487
- { linearState: 'unknown', expectedStatus: 'todo' }
488
- ];
489
- testCases.forEach(({ linearState, expectedStatus }) => {
490
- const mockIssue = {
491
- id: 'test-issue',
492
- identifier: 'TEST-1',
493
- title: 'Test',
494
- state: { type: linearState },
495
- team: { id: 'team-1', key: 'TEST' },
496
- updatedAt: new Date().toISOString()
497
- };
498
- mockContextService.getTaskByExternalId.mockResolvedValue(null);
499
- syncService.syncIssueToLocal(mockIssue);
500
- expect(mockContextService.createTask).toHaveBeenCalledWith(expect.objectContaining({ status: expectedStatus }));
501
- vi.clearAllMocks();
502
- });
503
- });
504
- it('should map Linear priorities to task priorities correctly', () => {
505
- const testCases = [
506
- { linearPriority: 1, expectedPriority: 'urgent' },
507
- { linearPriority: 2, expectedPriority: 'high' },
508
- { linearPriority: 3, expectedPriority: 'medium' },
509
- { linearPriority: 4, expectedPriority: 'low' },
510
- { linearPriority: undefined, expectedPriority: undefined }
511
- ];
512
- testCases.forEach(({ linearPriority, expectedPriority }) => {
513
- const mockIssue = {
514
- id: 'test-issue',
515
- identifier: 'TEST-1',
516
- title: 'Test',
517
- state: { type: 'unstarted' },
518
- priority: linearPriority,
519
- team: { id: 'team-1', key: 'TEST' },
520
- updatedAt: new Date().toISOString()
521
- };
522
- mockContextService.getTaskByExternalId.mockResolvedValue(null);
523
- syncService.syncIssueToLocal(mockIssue);
524
- expect(mockContextService.createTask).toHaveBeenCalledWith(expect.objectContaining({ priority: expectedPriority }));
525
- vi.clearAllMocks();
526
- });
527
- });
528
- it('should map task priorities to Linear priorities correctly', () => {
529
- const testCases = [
530
- { taskPriority: 'urgent', expectedLinearPriority: 4 },
531
- { taskPriority: 'high', expectedLinearPriority: 3 },
532
- { taskPriority: 'medium', expectedLinearPriority: 2 },
533
- { taskPriority: 'low', expectedLinearPriority: 1 },
534
- { taskPriority: undefined, expectedLinearPriority: 0 }
535
- ];
536
- testCases.forEach(({ taskPriority, expectedLinearPriority }) => {
537
- const mockTask = {
538
- id: 'local-1',
539
- title: 'Test Task',
540
- description: 'Test description',
541
- status: 'todo',
542
- priority: taskPriority,
543
- tags: [],
544
- createdAt: new Date(),
545
- updatedAt: new Date()
546
- };
547
- mockContextService.getTask.mockResolvedValue(mockTask);
548
- mockLinearClient.createIssue.mockResolvedValue({ id: 'created', identifier: 'TEST-1' });
549
- syncService.syncLocalToLinear('local-1');
550
- expect(mockLinearClient.createIssue).toHaveBeenCalledWith(expect.objectContaining({ priority: expectedLinearPriority }));
551
- vi.clearAllMocks();
552
- });
553
- });
554
- });
555
- describe('Change Detection', () => {
556
- it('should detect changes in title', () => {
557
- const existing = {
558
- id: '1',
559
- title: 'Old Title',
560
- description: 'Same',
561
- status: 'todo',
562
- priority: 'medium',
563
- tags: [],
564
- createdAt: new Date(),
565
- updatedAt: new Date()
566
- };
567
- const updated = {
568
- title: 'New Title',
569
- description: 'Same',
570
- status: 'todo',
571
- priority: 'medium',
572
- tags: []
573
- };
574
- mockContextService.getTaskByExternalId.mockResolvedValue(existing);
575
- const mockIssue = {
576
- id: 'issue-1',
577
- identifier: 'STA-1',
578
- title: 'New Title',
579
- description: 'Same',
580
- state: { type: 'unstarted' },
581
- priority: 2,
582
- team: { id: 'team-1', key: 'STA' },
583
- labels: [],
584
- updatedAt: new Date().toISOString()
585
- };
586
- syncService.syncIssueToLocal(mockIssue);
587
- expect(mockContextService.updateTask).toHaveBeenCalled();
588
- });
589
- it('should detect changes in tags', () => {
590
- const existing = {
591
- id: '1',
592
- title: 'Same',
593
- description: 'Same',
594
- status: 'todo',
595
- priority: 'medium',
596
- tags: ['old-tag'],
597
- createdAt: new Date(),
598
- updatedAt: new Date()
599
- };
600
- mockContextService.getTaskByExternalId.mockResolvedValue(existing);
601
- const mockIssue = {
602
- id: 'issue-1',
603
- identifier: 'STA-1',
604
- title: 'Same',
605
- description: 'Same',
606
- state: { type: 'unstarted' },
607
- priority: 2,
608
- team: { id: 'team-1', key: 'STA' },
609
- labels: [{ name: 'new-tag' }],
610
- updatedAt: new Date().toISOString()
611
- };
612
- syncService.syncIssueToLocal(mockIssue);
613
- expect(mockContextService.updateTask).toHaveBeenCalled();
614
- });
615
- it('should not update when no changes detected', () => {
616
- const existing = {
617
- id: '1',
618
- title: 'Same Title',
619
- description: 'Same Description',
620
- status: 'todo',
621
- priority: 'medium',
622
- tags: ['tag1'],
623
- createdAt: new Date(),
624
- updatedAt: new Date()
625
- };
626
- mockContextService.getTaskByExternalId.mockResolvedValue(existing);
627
- const mockIssue = {
628
- id: 'issue-1',
629
- identifier: 'STA-1',
630
- title: 'Same Title',
631
- description: 'Same Description',
632
- state: { type: 'unstarted' },
633
- priority: 2,
634
- team: { id: 'team-1', key: 'STA' },
635
- labels: [{ name: 'tag1' }],
636
- updatedAt: new Date().toISOString()
637
- };
638
- syncService.syncIssueToLocal(mockIssue);
639
- expect(mockContextService.updateTask).not.toHaveBeenCalled();
640
- });
641
- });
642
- describe('Error Recovery and Edge Cases', () => {
643
- it('should handle partial sync failures gracefully', async () => {
644
- const mockIssues = [
645
- { id: 'issue-1', identifier: 'STA-1', title: 'Good Issue', state: { type: 'unstarted' }, team: { id: 'team-1', key: 'STA' }, updatedAt: new Date().toISOString() },
646
- { id: 'issue-2', identifier: 'STA-2', title: 'Bad Issue', state: { type: 'unstarted' }, team: { id: 'team-1', key: 'STA' }, updatedAt: new Date().toISOString() }
647
- ];
648
- mockConfigService.getConfig.mockResolvedValue({
649
- integrations: { linear: { teamId: 'test-team-id' } }
650
- });
651
- mockLinearClient.getIssues.mockResolvedValue(mockIssues);
652
- mockContextService.getTaskByExternalId.mockResolvedValue(null);
653
- // First issue succeeds, second fails
654
- mockContextService.createTask
655
- .mockResolvedValueOnce('success')
656
- .mockRejectedValueOnce(new Error('Creation failed'));
657
- const result = await syncService.syncAllIssues();
658
- expect(result.created).toBe(1);
659
- expect(result.errors).toHaveLength(1);
660
- expect(result.errors[0]).toContain('Failed to sync STA-2');
661
- });
662
- it('should handle empty issues list', async () => {
663
- mockConfigService.getConfig.mockResolvedValue({
664
- integrations: { linear: { teamId: 'test-team-id' } }
665
- });
666
- mockLinearClient.getIssues.mockResolvedValue([]);
667
- const result = await syncService.syncAllIssues();
668
- expect(result.created).toBe(0);
669
- expect(result.updated).toBe(0);
670
- expect(result.errors).toHaveLength(0);
671
- });
672
- it('should handle malformed Linear issues', async () => {
673
- const malformedIssue = {
674
- // Missing required fields
675
- id: 'issue-1',
676
- title: null,
677
- state: null,
678
- team: null
679
- };
680
- mockConfigService.getConfig.mockResolvedValue({
681
- integrations: { linear: { teamId: 'test-team-id' } }
682
- });
683
- mockLinearClient.getIssues.mockResolvedValue([malformedIssue]);
684
- const result = await syncService.syncAllIssues();
685
- expect(result.errors).toHaveLength(1);
686
- });
687
- it('should handle network timeouts gracefully', async () => {
688
- mockConfigService.getConfig.mockResolvedValue({
689
- integrations: { linear: { teamId: 'test-team-id' } }
690
- });
691
- const timeoutError = new Error('Request timeout');
692
- timeoutError.name = 'TimeoutError';
693
- mockLinearClient.getIssues.mockRejectedValue(timeoutError);
694
- const result = await syncService.syncAllIssues();
695
- expect(result.errors).toHaveLength(1);
696
- expect(result.errors[0]).toContain('Request timeout');
697
- });
698
- });
699
- });
700
- //# sourceMappingURL=sync-service.test.js.map