@stackmemoryai/stackmemory 0.3.1 → 0.3.5

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 (744) hide show
  1. package/README.md +69 -288
  2. package/dist/cli/commands/chromadb.js +267 -0
  3. package/dist/cli/commands/chromadb.js.map +7 -0
  4. package/dist/cli/commands/clear.js +191 -0
  5. package/dist/cli/commands/clear.js.map +7 -0
  6. package/dist/cli/commands/config.js +152 -1
  7. package/dist/cli/commands/config.js.map +2 -2
  8. package/dist/cli/commands/context.js +15 -5
  9. package/dist/cli/commands/context.js.map +2 -2
  10. package/dist/cli/commands/dashboard.js +178 -0
  11. package/dist/cli/commands/dashboard.js.map +7 -0
  12. package/dist/cli/commands/handoff.js +125 -8
  13. package/dist/cli/commands/handoff.js.map +2 -2
  14. package/dist/cli/commands/linear-create.js +132 -0
  15. package/dist/cli/commands/linear-create.js.map +7 -0
  16. package/dist/cli/commands/linear-list.js +69 -0
  17. package/dist/cli/commands/linear-list.js.map +7 -0
  18. package/dist/cli/commands/linear-migrate.js +40 -0
  19. package/dist/cli/commands/linear-migrate.js.map +7 -0
  20. package/dist/cli/commands/linear.js +185 -36
  21. package/dist/cli/commands/linear.js.map +2 -2
  22. package/dist/cli/commands/monitor.js +309 -0
  23. package/dist/cli/commands/monitor.js.map +7 -0
  24. package/dist/cli/commands/quality.js +414 -0
  25. package/dist/cli/commands/quality.js.map +7 -0
  26. package/dist/cli/commands/skills.js +262 -0
  27. package/dist/cli/commands/skills.js.map +7 -0
  28. package/dist/cli/commands/storage.js +275 -0
  29. package/dist/cli/commands/storage.js.map +7 -0
  30. package/dist/cli/commands/tui.js +66 -0
  31. package/dist/cli/commands/tui.js.map +7 -0
  32. package/dist/cli/commands/workflow.js +134 -0
  33. package/dist/cli/commands/workflow.js.map +7 -0
  34. package/dist/cli/index.js +109 -8
  35. package/dist/cli/index.js.map +3 -3
  36. package/dist/core/analytics/team-analytics.js +374 -0
  37. package/dist/core/analytics/team-analytics.js.map +7 -0
  38. package/dist/core/context/context-bridge.js +234 -0
  39. package/dist/core/context/context-bridge.js.map +7 -0
  40. package/dist/core/context/dual-stack-manager.js +850 -0
  41. package/dist/core/context/dual-stack-manager.js.map +7 -0
  42. package/dist/core/context/frame-handoff-manager.js +774 -0
  43. package/dist/core/context/frame-handoff-manager.js.map +7 -0
  44. package/dist/core/context/frame-manager.js +142 -13
  45. package/dist/core/context/frame-manager.js.map +2 -2
  46. package/dist/core/context/permission-manager.js +181 -0
  47. package/dist/core/context/permission-manager.js.map +7 -0
  48. package/dist/core/context/shared-context-layer.js +386 -0
  49. package/dist/core/context/shared-context-layer.js.map +7 -0
  50. package/dist/core/context/stack-merge-resolver.js +600 -0
  51. package/dist/core/context/stack-merge-resolver.js.map +7 -0
  52. package/dist/core/context/validation.js +121 -0
  53. package/dist/core/context/validation.js.map +7 -0
  54. package/dist/core/database/connection-pool.js +266 -175
  55. package/dist/core/database/connection-pool.js.map +2 -2
  56. package/dist/core/database/database-adapter.js +51 -0
  57. package/dist/core/database/database-adapter.js.map +7 -0
  58. package/dist/core/database/migration-manager.js +514 -0
  59. package/dist/core/database/migration-manager.js.map +7 -0
  60. package/dist/core/database/paradedb-adapter.js +970 -0
  61. package/dist/core/database/paradedb-adapter.js.map +7 -0
  62. package/dist/core/database/query-router.js +421 -0
  63. package/dist/core/database/query-router.js.map +7 -0
  64. package/dist/core/database/sqlite-adapter.js +547 -0
  65. package/dist/core/database/sqlite-adapter.js.map +7 -0
  66. package/dist/core/errors/index.js +21 -1
  67. package/dist/core/errors/index.js.map +2 -2
  68. package/dist/core/frame/workflow-templates-stub.js +42 -0
  69. package/dist/core/frame/workflow-templates-stub.js.map +7 -0
  70. package/dist/core/frame/workflow-templates.js +276 -0
  71. package/dist/core/frame/workflow-templates.js.map +7 -0
  72. package/dist/core/merge/conflict-detector.js +5 -2
  73. package/dist/core/merge/conflict-detector.js.map +2 -2
  74. package/dist/core/merge/resolution-engine.js +3 -14
  75. package/dist/core/merge/resolution-engine.js.map +2 -2
  76. package/dist/core/merge/stack-diff.js.map +2 -2
  77. package/dist/core/monitoring/logger.js +18 -3
  78. package/dist/core/monitoring/logger.js.map +2 -2
  79. package/dist/core/monitoring/session-monitor.js +296 -0
  80. package/dist/core/monitoring/session-monitor.js.map +7 -0
  81. package/dist/core/retrieval/context-retriever.js +475 -0
  82. package/dist/core/retrieval/context-retriever.js.map +7 -0
  83. package/dist/core/retrieval/graph-retrieval.js +658 -0
  84. package/dist/core/retrieval/graph-retrieval.js.map +7 -0
  85. package/dist/core/retrieval/hierarchical-retrieval.js +652 -0
  86. package/dist/core/retrieval/hierarchical-retrieval.js.map +7 -0
  87. package/dist/core/retrieval/retrieval-benchmarks.js +517 -0
  88. package/dist/core/retrieval/retrieval-benchmarks.js.map +7 -0
  89. package/dist/core/session/clear-survival-stub.js +49 -0
  90. package/dist/core/session/clear-survival-stub.js.map +7 -0
  91. package/dist/core/session/clear-survival.js +426 -0
  92. package/dist/core/session/clear-survival.js.map +7 -0
  93. package/dist/core/session/handoff-generator.js +339 -0
  94. package/dist/core/session/handoff-generator.js.map +7 -0
  95. package/dist/core/session/session-manager.js +61 -26
  96. package/dist/core/session/session-manager.js.map +3 -3
  97. package/dist/core/skills/index.js +3 -0
  98. package/dist/core/skills/index.js.map +7 -0
  99. package/dist/core/skills/skill-storage.js +749 -0
  100. package/dist/core/skills/skill-storage.js.map +7 -0
  101. package/dist/core/skills/types.js +189 -0
  102. package/dist/core/skills/types.js.map +7 -0
  103. package/dist/core/storage/chromadb-adapter.js +346 -0
  104. package/dist/core/storage/chromadb-adapter.js.map +7 -0
  105. package/dist/core/storage/railway-optimized-storage.js +550 -0
  106. package/dist/core/storage/railway-optimized-storage.js.map +7 -0
  107. package/dist/core/storage/remote-storage.js +456 -0
  108. package/dist/core/storage/remote-storage.js.map +7 -0
  109. package/dist/core/trace/trace-detector.js +136 -5
  110. package/dist/core/trace/trace-detector.js.map +2 -2
  111. package/dist/core/trace/trace-store.js.map +2 -2
  112. package/dist/features/tui/components/analytics-panel.js +136 -0
  113. package/dist/features/tui/components/analytics-panel.js.map +7 -0
  114. package/dist/features/tui/components/frame-visualizer.js +377 -0
  115. package/dist/features/tui/components/frame-visualizer.js.map +7 -0
  116. package/dist/features/tui/components/pr-tracker.js +123 -0
  117. package/dist/features/tui/components/pr-tracker.js.map +7 -0
  118. package/dist/features/tui/components/session-monitor.js +286 -0
  119. package/dist/features/tui/components/session-monitor.js.map +7 -0
  120. package/dist/features/tui/components/subagent-fleet.js +388 -0
  121. package/dist/features/tui/components/subagent-fleet.js.map +7 -0
  122. package/dist/features/tui/components/task-board.js +475 -0
  123. package/dist/features/tui/components/task-board.js.map +7 -0
  124. package/dist/features/tui/index.js +397 -0
  125. package/dist/features/tui/index.js.map +7 -0
  126. package/dist/features/tui/services/data-service.js +654 -0
  127. package/dist/features/tui/services/data-service.js.map +7 -0
  128. package/dist/features/tui/services/websocket-client.js +149 -0
  129. package/dist/features/tui/services/websocket-client.js.map +7 -0
  130. package/dist/features/tui/terminal-compat.js +205 -0
  131. package/dist/features/tui/terminal-compat.js.map +7 -0
  132. package/dist/features/tui/types.js +1 -0
  133. package/dist/features/tui/types.js.map +7 -0
  134. package/dist/integrations/claude-code/enhanced-pre-clear-hooks.js +455 -0
  135. package/dist/integrations/claude-code/enhanced-pre-clear-hooks.js.map +7 -0
  136. package/dist/integrations/claude-code/lifecycle-hooks.js +250 -0
  137. package/dist/integrations/claude-code/lifecycle-hooks.js.map +7 -0
  138. package/dist/integrations/claude-code/post-task-hooks.js +541 -0
  139. package/dist/integrations/claude-code/post-task-hooks.js.map +7 -0
  140. package/dist/integrations/linear/client.js +22 -4
  141. package/dist/integrations/linear/client.js.map +2 -2
  142. package/dist/integrations/linear/migration.js +299 -0
  143. package/dist/integrations/linear/migration.js.map +7 -0
  144. package/dist/integrations/linear/oauth-server.js +396 -0
  145. package/dist/integrations/linear/oauth-server.js.map +7 -0
  146. package/dist/integrations/linear/rest-client.js +199 -0
  147. package/dist/integrations/linear/rest-client.js.map +7 -0
  148. package/dist/integrations/linear/sync.js +14 -2
  149. package/dist/integrations/linear/sync.js.map +2 -2
  150. package/dist/integrations/linear/webhook-handler.js +200 -0
  151. package/dist/integrations/linear/webhook-handler.js.map +7 -0
  152. package/dist/integrations/mcp/handlers/skill-handlers.js +514 -0
  153. package/dist/integrations/mcp/handlers/skill-handlers.js.map +7 -0
  154. package/dist/integrations/mcp/middleware/tool-scoring.js +352 -0
  155. package/dist/integrations/mcp/middleware/tool-scoring.js.map +7 -0
  156. package/dist/integrations/mcp/refactored-server.js +31 -3
  157. package/dist/integrations/mcp/refactored-server.js.map +2 -2
  158. package/dist/integrations/mcp/server.js +25 -7
  159. package/dist/integrations/mcp/server.js.map +2 -2
  160. package/dist/mcp/stackmemory-mcp-server.js.map +1 -1
  161. package/dist/models/user.model.js +3 -0
  162. package/dist/models/user.model.js.map +2 -2
  163. package/dist/services/context-service.js.map +2 -2
  164. package/dist/skills/claude-skills.js +666 -0
  165. package/dist/skills/claude-skills.js.map +7 -0
  166. package/dist/utils/formatting.js +58 -0
  167. package/dist/utils/formatting.js.map +7 -0
  168. package/package.json +30 -24
  169. package/dist/cli/__tests__/index.test.js +0 -290
  170. package/dist/cli/__tests__/index.test.js.map +0 -7
  171. package/dist/core/config/__tests__/config-manager.test.js +0 -248
  172. package/dist/core/config/__tests__/config-manager.test.js.map +0 -7
  173. package/dist/core/context/__tests__/frame-manager.test.js +0 -879
  174. package/dist/core/context/__tests__/frame-manager.test.js.map +0 -7
  175. package/dist/core/digest/__tests__/enhanced-hybrid-digest.test.js +0 -379
  176. package/dist/core/digest/__tests__/enhanced-hybrid-digest.test.js.map +0 -7
  177. package/dist/core/digest/__tests__/frame-digest-integration.test.js +0 -230
  178. package/dist/core/digest/__tests__/frame-digest-integration.test.js.map +0 -7
  179. package/dist/core/errors/__tests__/error-handling.test.js +0 -270
  180. package/dist/core/errors/__tests__/error-handling.test.js.map +0 -7
  181. package/dist/core/merge/__tests__/conflict-scenarios.test.js +0 -414
  182. package/dist/core/merge/__tests__/conflict-scenarios.test.js.map +0 -7
  183. package/dist/core/query/__tests__/query-parser.test.js +0 -301
  184. package/dist/core/query/__tests__/query-parser.test.js.map +0 -7
  185. package/dist/core/query/__tests__/query-templates.test.js +0 -210
  186. package/dist/core/query/__tests__/query-templates.test.js.map +0 -7
  187. package/dist/core/trace/trace-detector.test.js +0 -401
  188. package/dist/core/trace/trace-detector.test.js.map +0 -7
  189. package/dist/features/tasks/__tests__/pebbles-task-store.test.js +0 -747
  190. package/dist/features/tasks/__tests__/pebbles-task-store.test.js.map +0 -7
  191. package/dist/integrations/linear/__tests__/auth.test.js +0 -558
  192. package/dist/integrations/linear/__tests__/auth.test.js.map +0 -7
  193. package/dist/integrations/linear/__tests__/sync-service.test.js +0 -760
  194. package/dist/integrations/linear/__tests__/sync-service.test.js.map +0 -7
  195. package/dist/integrations/mcp/__tests__/server.test.js +0 -798
  196. package/dist/integrations/mcp/__tests__/server.test.js.map +0 -7
  197. package/dist/scripts/benchmark-performance.d.ts +0 -7
  198. package/dist/scripts/benchmark-performance.d.ts.map +0 -1
  199. package/dist/scripts/benchmark-performance.js +0 -44
  200. package/dist/scripts/benchmark-performance.js.map +0 -1
  201. package/dist/scripts/cancel-duplicate-tasks.d.ts +0 -7
  202. package/dist/scripts/cancel-duplicate-tasks.d.ts.map +0 -1
  203. package/dist/scripts/cancel-duplicate-tasks.js +0 -172
  204. package/dist/scripts/cancel-duplicate-tasks.js.map +0 -1
  205. package/dist/scripts/cleanup-duplicate-tasks.d.ts +0 -12
  206. package/dist/scripts/cleanup-duplicate-tasks.d.ts.map +0 -1
  207. package/dist/scripts/cleanup-duplicate-tasks.js +0 -215
  208. package/dist/scripts/cleanup-duplicate-tasks.js.map +0 -1
  209. package/dist/scripts/initialize.d.ts +0 -6
  210. package/dist/scripts/initialize.d.ts.map +0 -1
  211. package/dist/scripts/initialize.js +0 -93
  212. package/dist/scripts/initialize.js.map +0 -1
  213. package/dist/scripts/list-linear-tasks.d.ts +0 -6
  214. package/dist/scripts/list-linear-tasks.d.ts.map +0 -1
  215. package/dist/scripts/list-linear-tasks.js +0 -121
  216. package/dist/scripts/list-linear-tasks.js.map +0 -1
  217. package/dist/scripts/merge-linear-duplicates-safe.d.ts +0 -7
  218. package/dist/scripts/merge-linear-duplicates-safe.d.ts.map +0 -1
  219. package/dist/scripts/merge-linear-duplicates-safe.js +0 -267
  220. package/dist/scripts/merge-linear-duplicates-safe.js.map +0 -1
  221. package/dist/scripts/show-linear-summary.d.ts +0 -6
  222. package/dist/scripts/show-linear-summary.d.ts.map +0 -1
  223. package/dist/scripts/show-linear-summary.js +0 -120
  224. package/dist/scripts/show-linear-summary.js.map +0 -1
  225. package/dist/scripts/status.d.ts +0 -6
  226. package/dist/scripts/status.d.ts.map +0 -1
  227. package/dist/scripts/status.js +0 -101
  228. package/dist/scripts/status.js.map +0 -1
  229. package/dist/src/agents/core/agent-task-manager.d.ts +0 -154
  230. package/dist/src/agents/core/agent-task-manager.d.ts.map +0 -1
  231. package/dist/src/agents/core/agent-task-manager.js +0 -504
  232. package/dist/src/agents/core/agent-task-manager.js.map +0 -1
  233. package/dist/src/agents/verifiers/base-verifier.d.ts +0 -112
  234. package/dist/src/agents/verifiers/base-verifier.d.ts.map +0 -1
  235. package/dist/src/agents/verifiers/base-verifier.js +0 -130
  236. package/dist/src/agents/verifiers/base-verifier.js.map +0 -1
  237. package/dist/src/agents/verifiers/formatter-verifier.d.ts +0 -14
  238. package/dist/src/agents/verifiers/formatter-verifier.d.ts.map +0 -1
  239. package/dist/src/agents/verifiers/formatter-verifier.js +0 -107
  240. package/dist/src/agents/verifiers/formatter-verifier.js.map +0 -1
  241. package/dist/src/agents/verifiers/llm-judge.d.ts +0 -46
  242. package/dist/src/agents/verifiers/llm-judge.d.ts.map +0 -1
  243. package/dist/src/agents/verifiers/llm-judge.js +0 -248
  244. package/dist/src/agents/verifiers/llm-judge.js.map +0 -1
  245. package/dist/src/cli/auto-detect.d.ts +0 -61
  246. package/dist/src/cli/auto-detect.d.ts.map +0 -1
  247. package/dist/src/cli/auto-detect.js +0 -350
  248. package/dist/src/cli/auto-detect.js.map +0 -1
  249. package/dist/src/cli/browser-test.d.ts +0 -6
  250. package/dist/src/cli/browser-test.d.ts.map +0 -1
  251. package/dist/src/cli/browser-test.js +0 -32
  252. package/dist/src/cli/browser-test.js.map +0 -1
  253. package/dist/src/cli/claude-sm.d.ts +0 -7
  254. package/dist/src/cli/claude-sm.d.ts.map +0 -1
  255. package/dist/src/cli/claude-sm.js +0 -412
  256. package/dist/src/cli/claude-sm.js.map +0 -1
  257. package/dist/src/cli/commands/agent.d.ts +0 -9
  258. package/dist/src/cli/commands/agent.d.ts.map +0 -1
  259. package/dist/src/cli/commands/agent.js +0 -303
  260. package/dist/src/cli/commands/agent.js.map +0 -1
  261. package/dist/src/cli/commands/config.d.ts +0 -6
  262. package/dist/src/cli/commands/config.d.ts.map +0 -1
  263. package/dist/src/cli/commands/config.js +0 -224
  264. package/dist/src/cli/commands/config.js.map +0 -1
  265. package/dist/src/cli/commands/context.d.ts +0 -7
  266. package/dist/src/cli/commands/context.d.ts.map +0 -1
  267. package/dist/src/cli/commands/context.js +0 -365
  268. package/dist/src/cli/commands/context.js.map +0 -1
  269. package/dist/src/cli/commands/handoff.d.ts +0 -6
  270. package/dist/src/cli/commands/handoff.d.ts.map +0 -1
  271. package/dist/src/cli/commands/handoff.js +0 -212
  272. package/dist/src/cli/commands/handoff.js.map +0 -1
  273. package/dist/src/cli/commands/linear-test.d.ts +0 -6
  274. package/dist/src/cli/commands/linear-test.d.ts.map +0 -1
  275. package/dist/src/cli/commands/linear-test.js +0 -123
  276. package/dist/src/cli/commands/linear-test.js.map +0 -1
  277. package/dist/src/cli/commands/linear.d.ts +0 -6
  278. package/dist/src/cli/commands/linear.d.ts.map +0 -1
  279. package/dist/src/cli/commands/linear.js +0 -393
  280. package/dist/src/cli/commands/linear.js.map +0 -1
  281. package/dist/src/cli/commands/log.d.ts +0 -7
  282. package/dist/src/cli/commands/log.d.ts.map +0 -1
  283. package/dist/src/cli/commands/log.js +0 -168
  284. package/dist/src/cli/commands/log.js.map +0 -1
  285. package/dist/src/cli/commands/onboard.d.ts +0 -8
  286. package/dist/src/cli/commands/onboard.d.ts.map +0 -1
  287. package/dist/src/cli/commands/onboard.js +0 -363
  288. package/dist/src/cli/commands/onboard.js.map +0 -1
  289. package/dist/src/cli/commands/projects.d.ts +0 -8
  290. package/dist/src/cli/commands/projects.d.ts.map +0 -1
  291. package/dist/src/cli/commands/projects.js +0 -220
  292. package/dist/src/cli/commands/projects.js.map +0 -1
  293. package/dist/src/cli/commands/search.d.ts +0 -7
  294. package/dist/src/cli/commands/search.d.ts.map +0 -1
  295. package/dist/src/cli/commands/search.js +0 -162
  296. package/dist/src/cli/commands/search.js.map +0 -1
  297. package/dist/src/cli/commands/session.d.ts +0 -7
  298. package/dist/src/cli/commands/session.d.ts.map +0 -1
  299. package/dist/src/cli/commands/session.js +0 -222
  300. package/dist/src/cli/commands/session.js.map +0 -1
  301. package/dist/src/cli/commands/tasks.d.ts +0 -7
  302. package/dist/src/cli/commands/tasks.d.ts.map +0 -1
  303. package/dist/src/cli/commands/tasks.js +0 -229
  304. package/dist/src/cli/commands/tasks.js.map +0 -1
  305. package/dist/src/cli/commands/webhook.d.ts +0 -3
  306. package/dist/src/cli/commands/webhook.d.ts.map +0 -1
  307. package/dist/src/cli/commands/webhook.js +0 -157
  308. package/dist/src/cli/commands/webhook.js.map +0 -1
  309. package/dist/src/cli/commands/worktree.d.ts +0 -8
  310. package/dist/src/cli/commands/worktree.d.ts.map +0 -1
  311. package/dist/src/cli/commands/worktree.js +0 -339
  312. package/dist/src/cli/commands/worktree.js.map +0 -1
  313. package/dist/src/cli/index.d.ts +0 -8
  314. package/dist/src/cli/index.d.ts.map +0 -1
  315. package/dist/src/cli/index.js +0 -995
  316. package/dist/src/cli/index.js.map +0 -1
  317. package/dist/src/cli/utils/viewer.d.ts +0 -3
  318. package/dist/src/cli/utils/viewer.d.ts.map +0 -1
  319. package/dist/src/cli/utils/viewer.js +0 -91
  320. package/dist/src/cli/utils/viewer.js.map +0 -1
  321. package/dist/src/core/config/config-manager.d.ts +0 -95
  322. package/dist/src/core/config/config-manager.d.ts.map +0 -1
  323. package/dist/src/core/config/config-manager.js +0 -359
  324. package/dist/src/core/config/config-manager.js.map +0 -1
  325. package/dist/src/core/config/types.d.ts +0 -72
  326. package/dist/src/core/config/types.d.ts.map +0 -1
  327. package/dist/src/core/config/types.js +0 -127
  328. package/dist/src/core/config/types.js.map +0 -1
  329. package/dist/src/core/context/auto-context.d.ts +0 -22
  330. package/dist/src/core/context/auto-context.d.ts.map +0 -1
  331. package/dist/src/core/context/auto-context.js +0 -77
  332. package/dist/src/core/context/auto-context.js.map +0 -1
  333. package/dist/src/core/context/compaction-handler.d.ts +0 -119
  334. package/dist/src/core/context/compaction-handler.d.ts.map +0 -1
  335. package/dist/src/core/context/compaction-handler.js +0 -306
  336. package/dist/src/core/context/compaction-handler.js.map +0 -1
  337. package/dist/src/core/context/frame-database.d.ts +0 -59
  338. package/dist/src/core/context/frame-database.d.ts.map +0 -1
  339. package/dist/src/core/context/frame-database.js +0 -333
  340. package/dist/src/core/context/frame-database.js.map +0 -1
  341. package/dist/src/core/context/frame-digest.d.ts +0 -59
  342. package/dist/src/core/context/frame-digest.d.ts.map +0 -1
  343. package/dist/src/core/context/frame-digest.js +0 -264
  344. package/dist/src/core/context/frame-digest.js.map +0 -1
  345. package/dist/src/core/context/frame-manager.d.ts +0 -112
  346. package/dist/src/core/context/frame-manager.d.ts.map +0 -1
  347. package/dist/src/core/context/frame-manager.js +0 -600
  348. package/dist/src/core/context/frame-manager.js.map +0 -1
  349. package/dist/src/core/context/frame-stack.d.ts +0 -85
  350. package/dist/src/core/context/frame-stack.d.ts.map +0 -1
  351. package/dist/src/core/context/frame-stack.js +0 -287
  352. package/dist/src/core/context/frame-stack.js.map +0 -1
  353. package/dist/src/core/context/frame-types.d.ts +0 -67
  354. package/dist/src/core/context/frame-types.d.ts.map +0 -1
  355. package/dist/src/core/context/frame-types.js +0 -6
  356. package/dist/src/core/context/frame-types.js.map +0 -1
  357. package/dist/src/core/context/index.d.ts +0 -11
  358. package/dist/src/core/context/index.d.ts.map +0 -1
  359. package/dist/src/core/context/index.js +0 -14
  360. package/dist/src/core/context/index.js.map +0 -1
  361. package/dist/src/core/context/model-aware-compaction.d.ts +0 -101
  362. package/dist/src/core/context/model-aware-compaction.d.ts.map +0 -1
  363. package/dist/src/core/context/model-aware-compaction.js +0 -616
  364. package/dist/src/core/context/model-aware-compaction.js.map +0 -1
  365. package/dist/src/core/context/refactored-frame-manager.d.ts +0 -99
  366. package/dist/src/core/context/refactored-frame-manager.d.ts.map +0 -1
  367. package/dist/src/core/context/refactored-frame-manager.js +0 -340
  368. package/dist/src/core/context/refactored-frame-manager.js.map +0 -1
  369. package/dist/src/core/database/batch-operations.d.ts +0 -118
  370. package/dist/src/core/database/batch-operations.d.ts.map +0 -1
  371. package/dist/src/core/database/batch-operations.js +0 -339
  372. package/dist/src/core/database/batch-operations.js.map +0 -1
  373. package/dist/src/core/database/connection-pool.d.ts +0 -79
  374. package/dist/src/core/database/connection-pool.d.ts.map +0 -1
  375. package/dist/src/core/database/connection-pool.js +0 -236
  376. package/dist/src/core/database/connection-pool.js.map +0 -1
  377. package/dist/src/core/database/query-cache.d.ts +0 -135
  378. package/dist/src/core/database/query-cache.d.ts.map +0 -1
  379. package/dist/src/core/database/query-cache.js +0 -294
  380. package/dist/src/core/database/query-cache.js.map +0 -1
  381. package/dist/src/core/digest/enhanced-hybrid-digest.d.ts +0 -125
  382. package/dist/src/core/digest/enhanced-hybrid-digest.d.ts.map +0 -1
  383. package/dist/src/core/digest/enhanced-hybrid-digest.js +0 -282
  384. package/dist/src/core/digest/enhanced-hybrid-digest.js.map +0 -1
  385. package/dist/src/core/digest/frame-digest-integration.d.ts +0 -67
  386. package/dist/src/core/digest/frame-digest-integration.d.ts.map +0 -1
  387. package/dist/src/core/digest/frame-digest-integration.js +0 -198
  388. package/dist/src/core/digest/frame-digest-integration.js.map +0 -1
  389. package/dist/src/core/digest/hybrid-digest-generator.d.ts +0 -76
  390. package/dist/src/core/digest/hybrid-digest-generator.d.ts.map +0 -1
  391. package/dist/src/core/digest/hybrid-digest-generator.js +0 -629
  392. package/dist/src/core/digest/hybrid-digest-generator.js.map +0 -1
  393. package/dist/src/core/digest/index.d.ts +0 -9
  394. package/dist/src/core/digest/index.d.ts.map +0 -1
  395. package/dist/src/core/digest/index.js +0 -9
  396. package/dist/src/core/digest/index.js.map +0 -1
  397. package/dist/src/core/digest/types.d.ts +0 -154
  398. package/dist/src/core/digest/types.d.ts.map +0 -1
  399. package/dist/src/core/digest/types.js +0 -18
  400. package/dist/src/core/digest/types.js.map +0 -1
  401. package/dist/src/core/errors/index.d.ts +0 -143
  402. package/dist/src/core/errors/index.d.ts.map +0 -1
  403. package/dist/src/core/errors/index.js +0 -282
  404. package/dist/src/core/errors/index.js.map +0 -1
  405. package/dist/src/core/errors/recovery.d.ts +0 -86
  406. package/dist/src/core/errors/recovery.d.ts.map +0 -1
  407. package/dist/src/core/errors/recovery.js +0 -274
  408. package/dist/src/core/errors/recovery.js.map +0 -1
  409. package/dist/src/core/merge/conflict-detector.d.ts +0 -122
  410. package/dist/src/core/merge/conflict-detector.d.ts.map +0 -1
  411. package/dist/src/core/merge/conflict-detector.js +0 -468
  412. package/dist/src/core/merge/conflict-detector.js.map +0 -1
  413. package/dist/src/core/merge/index.d.ts +0 -9
  414. package/dist/src/core/merge/index.d.ts.map +0 -1
  415. package/dist/src/core/merge/index.js +0 -9
  416. package/dist/src/core/merge/index.js.map +0 -1
  417. package/dist/src/core/merge/resolution-engine.d.ts +0 -120
  418. package/dist/src/core/merge/resolution-engine.d.ts.map +0 -1
  419. package/dist/src/core/merge/resolution-engine.js +0 -573
  420. package/dist/src/core/merge/resolution-engine.js.map +0 -1
  421. package/dist/src/core/merge/stack-diff.d.ts +0 -97
  422. package/dist/src/core/merge/stack-diff.d.ts.map +0 -1
  423. package/dist/src/core/merge/stack-diff.js +0 -516
  424. package/dist/src/core/merge/stack-diff.js.map +0 -1
  425. package/dist/src/core/merge/types.d.ts +0 -110
  426. package/dist/src/core/merge/types.d.ts.map +0 -1
  427. package/dist/src/core/merge/types.js +0 -6
  428. package/dist/src/core/merge/types.js.map +0 -1
  429. package/dist/src/core/monitoring/error-handler.d.ts +0 -46
  430. package/dist/src/core/monitoring/error-handler.d.ts.map +0 -1
  431. package/dist/src/core/monitoring/error-handler.js +0 -212
  432. package/dist/src/core/monitoring/error-handler.js.map +0 -1
  433. package/dist/src/core/monitoring/logger.d.ts +0 -24
  434. package/dist/src/core/monitoring/logger.d.ts.map +0 -1
  435. package/dist/src/core/monitoring/logger.js +0 -126
  436. package/dist/src/core/monitoring/logger.js.map +0 -1
  437. package/dist/src/core/monitoring/metrics.d.ts +0 -10
  438. package/dist/src/core/monitoring/metrics.d.ts.map +0 -1
  439. package/dist/src/core/monitoring/metrics.js +0 -152
  440. package/dist/src/core/monitoring/metrics.js.map +0 -1
  441. package/dist/src/core/monitoring/progress-tracker.d.ts +0 -95
  442. package/dist/src/core/monitoring/progress-tracker.d.ts.map +0 -1
  443. package/dist/src/core/monitoring/progress-tracker.js +0 -178
  444. package/dist/src/core/monitoring/progress-tracker.js.map +0 -1
  445. package/dist/src/core/performance/context-cache.d.ts +0 -109
  446. package/dist/src/core/performance/context-cache.d.ts.map +0 -1
  447. package/dist/src/core/performance/context-cache.js +0 -280
  448. package/dist/src/core/performance/context-cache.js.map +0 -1
  449. package/dist/src/core/performance/index.d.ts +0 -3
  450. package/dist/src/core/performance/index.d.ts.map +0 -1
  451. package/dist/src/core/performance/index.js +0 -3
  452. package/dist/src/core/performance/index.js.map +0 -1
  453. package/dist/src/core/performance/lazy-context-loader.d.ts +0 -93
  454. package/dist/src/core/performance/lazy-context-loader.d.ts.map +0 -1
  455. package/dist/src/core/performance/lazy-context-loader.js +0 -332
  456. package/dist/src/core/performance/lazy-context-loader.js.map +0 -1
  457. package/dist/src/core/performance/monitor.d.ts +0 -48
  458. package/dist/src/core/performance/monitor.d.ts.map +0 -1
  459. package/dist/src/core/performance/monitor.js +0 -226
  460. package/dist/src/core/performance/monitor.js.map +0 -1
  461. package/dist/src/core/performance/optimized-frame-context.d.ts +0 -74
  462. package/dist/src/core/performance/optimized-frame-context.d.ts.map +0 -1
  463. package/dist/src/core/performance/optimized-frame-context.js +0 -330
  464. package/dist/src/core/performance/optimized-frame-context.js.map +0 -1
  465. package/dist/src/core/performance/performance-benchmark.d.ts +0 -50
  466. package/dist/src/core/performance/performance-benchmark.d.ts.map +0 -1
  467. package/dist/src/core/performance/performance-benchmark.js +0 -290
  468. package/dist/src/core/performance/performance-benchmark.js.map +0 -1
  469. package/dist/src/core/performance/performance-profiler.d.ts +0 -151
  470. package/dist/src/core/performance/performance-profiler.d.ts.map +0 -1
  471. package/dist/src/core/performance/performance-profiler.js +0 -346
  472. package/dist/src/core/performance/performance-profiler.js.map +0 -1
  473. package/dist/src/core/performance/streaming-jsonl-parser.d.ts +0 -41
  474. package/dist/src/core/performance/streaming-jsonl-parser.d.ts.map +0 -1
  475. package/dist/src/core/performance/streaming-jsonl-parser.js +0 -193
  476. package/dist/src/core/performance/streaming-jsonl-parser.js.map +0 -1
  477. package/dist/src/core/persistence/postgres-adapter.d.ts +0 -31
  478. package/dist/src/core/persistence/postgres-adapter.d.ts.map +0 -1
  479. package/dist/src/core/persistence/postgres-adapter.js +0 -330
  480. package/dist/src/core/persistence/postgres-adapter.js.map +0 -1
  481. package/dist/src/core/projects/project-manager.d.ts +0 -130
  482. package/dist/src/core/projects/project-manager.d.ts.map +0 -1
  483. package/dist/src/core/projects/project-manager.js +0 -709
  484. package/dist/src/core/projects/project-manager.js.map +0 -1
  485. package/dist/src/core/query/query-parser.d.ts +0 -109
  486. package/dist/src/core/query/query-parser.d.ts.map +0 -1
  487. package/dist/src/core/query/query-parser.js +0 -415
  488. package/dist/src/core/query/query-parser.js.map +0 -1
  489. package/dist/src/core/query/query-templates.d.ts +0 -44
  490. package/dist/src/core/query/query-templates.d.ts.map +0 -1
  491. package/dist/src/core/query/query-templates.js +0 -326
  492. package/dist/src/core/query/query-templates.js.map +0 -1
  493. package/dist/src/core/retrieval/index.d.ts +0 -8
  494. package/dist/src/core/retrieval/index.d.ts.map +0 -1
  495. package/dist/src/core/retrieval/index.js +0 -8
  496. package/dist/src/core/retrieval/index.js.map +0 -1
  497. package/dist/src/core/retrieval/llm-context-retrieval.d.ts +0 -73
  498. package/dist/src/core/retrieval/llm-context-retrieval.d.ts.map +0 -1
  499. package/dist/src/core/retrieval/llm-context-retrieval.js +0 -597
  500. package/dist/src/core/retrieval/llm-context-retrieval.js.map +0 -1
  501. package/dist/src/core/retrieval/summary-generator.d.ts +0 -63
  502. package/dist/src/core/retrieval/summary-generator.d.ts.map +0 -1
  503. package/dist/src/core/retrieval/summary-generator.js +0 -622
  504. package/dist/src/core/retrieval/summary-generator.js.map +0 -1
  505. package/dist/src/core/retrieval/types.d.ts +0 -257
  506. package/dist/src/core/retrieval/types.d.ts.map +0 -1
  507. package/dist/src/core/retrieval/types.js +0 -18
  508. package/dist/src/core/retrieval/types.js.map +0 -1
  509. package/dist/src/core/session/index.d.ts +0 -2
  510. package/dist/src/core/session/index.d.ts.map +0 -1
  511. package/dist/src/core/session/index.js +0 -2
  512. package/dist/src/core/session/index.js.map +0 -1
  513. package/dist/src/core/session/session-manager.d.ts +0 -69
  514. package/dist/src/core/session/session-manager.d.ts.map +0 -1
  515. package/dist/src/core/session/session-manager.js +0 -311
  516. package/dist/src/core/session/session-manager.js.map +0 -1
  517. package/dist/src/core/trace/cli-trace-wrapper.d.ts +0 -23
  518. package/dist/src/core/trace/cli-trace-wrapper.d.ts.map +0 -1
  519. package/dist/src/core/trace/cli-trace-wrapper.js +0 -141
  520. package/dist/src/core/trace/cli-trace-wrapper.js.map +0 -1
  521. package/dist/src/core/trace/db-trace-wrapper.d.ts +0 -36
  522. package/dist/src/core/trace/db-trace-wrapper.d.ts.map +0 -1
  523. package/dist/src/core/trace/db-trace-wrapper.js +0 -252
  524. package/dist/src/core/trace/db-trace-wrapper.js.map +0 -1
  525. package/dist/src/core/trace/debug-trace.d.ts +0 -84
  526. package/dist/src/core/trace/debug-trace.d.ts.map +0 -1
  527. package/dist/src/core/trace/debug-trace.js +0 -402
  528. package/dist/src/core/trace/debug-trace.js.map +0 -1
  529. package/dist/src/core/trace/error-test.d.ts +0 -6
  530. package/dist/src/core/trace/error-test.d.ts.map +0 -1
  531. package/dist/src/core/trace/error-test.js +0 -128
  532. package/dist/src/core/trace/error-test.js.map +0 -1
  533. package/dist/src/core/trace/index.d.ts +0 -25
  534. package/dist/src/core/trace/index.d.ts.map +0 -1
  535. package/dist/src/core/trace/index.js +0 -121
  536. package/dist/src/core/trace/index.js.map +0 -1
  537. package/dist/src/core/trace/linear-api-wrapper.d.ts +0 -17
  538. package/dist/src/core/trace/linear-api-wrapper.d.ts.map +0 -1
  539. package/dist/src/core/trace/linear-api-wrapper.js +0 -205
  540. package/dist/src/core/trace/linear-api-wrapper.js.map +0 -1
  541. package/dist/src/core/trace/performance-test.d.ts +0 -6
  542. package/dist/src/core/trace/performance-test.d.ts.map +0 -1
  543. package/dist/src/core/trace/performance-test.js +0 -111
  544. package/dist/src/core/trace/performance-test.js.map +0 -1
  545. package/dist/src/core/trace/trace-demo.d.ts +0 -8
  546. package/dist/src/core/trace/trace-demo.d.ts.map +0 -1
  547. package/dist/src/core/trace/trace-demo.js +0 -154
  548. package/dist/src/core/trace/trace-demo.js.map +0 -1
  549. package/dist/src/core/trace/trace-detector.d.ts +0 -108
  550. package/dist/src/core/trace/trace-detector.d.ts.map +0 -1
  551. package/dist/src/core/trace/trace-detector.demo.d.ts +0 -5
  552. package/dist/src/core/trace/trace-detector.demo.d.ts.map +0 -1
  553. package/dist/src/core/trace/trace-detector.demo.js +0 -145
  554. package/dist/src/core/trace/trace-detector.demo.js.map +0 -1
  555. package/dist/src/core/trace/trace-detector.js +0 -425
  556. package/dist/src/core/trace/trace-detector.js.map +0 -1
  557. package/dist/src/core/trace/trace-store.d.ts +0 -60
  558. package/dist/src/core/trace/trace-store.d.ts.map +0 -1
  559. package/dist/src/core/trace/trace-store.js +0 -323
  560. package/dist/src/core/trace/trace-store.js.map +0 -1
  561. package/dist/src/core/trace/types.d.ts +0 -81
  562. package/dist/src/core/trace/types.d.ts.map +0 -1
  563. package/dist/src/core/trace/types.js +0 -70
  564. package/dist/src/core/trace/types.js.map +0 -1
  565. package/dist/src/core/types.d.ts +0 -35
  566. package/dist/src/core/types.d.ts.map +0 -1
  567. package/dist/src/core/types.js +0 -2
  568. package/dist/src/core/types.js.map +0 -1
  569. package/dist/src/core/utils/update-checker.d.ts +0 -38
  570. package/dist/src/core/utils/update-checker.d.ts.map +0 -1
  571. package/dist/src/core/utils/update-checker.js +0 -213
  572. package/dist/src/core/utils/update-checker.js.map +0 -1
  573. package/dist/src/core/worktree/worktree-manager.d.ts +0 -110
  574. package/dist/src/core/worktree/worktree-manager.d.ts.map +0 -1
  575. package/dist/src/core/worktree/worktree-manager.js +0 -456
  576. package/dist/src/core/worktree/worktree-manager.js.map +0 -1
  577. package/dist/src/features/analytics/api/analytics-api.d.ts +0 -24
  578. package/dist/src/features/analytics/api/analytics-api.d.ts.map +0 -1
  579. package/dist/src/features/analytics/api/analytics-api.js +0 -289
  580. package/dist/src/features/analytics/api/analytics-api.js.map +0 -1
  581. package/dist/src/features/analytics/core/analytics-service.d.ts +0 -29
  582. package/dist/src/features/analytics/core/analytics-service.d.ts.map +0 -1
  583. package/dist/src/features/analytics/core/analytics-service.js +0 -275
  584. package/dist/src/features/analytics/core/analytics-service.js.map +0 -1
  585. package/dist/src/features/analytics/index.d.ts +0 -12
  586. package/dist/src/features/analytics/index.d.ts.map +0 -1
  587. package/dist/src/features/analytics/index.js +0 -11
  588. package/dist/src/features/analytics/index.js.map +0 -1
  589. package/dist/src/features/analytics/queries/metrics-queries.d.ts +0 -11
  590. package/dist/src/features/analytics/queries/metrics-queries.d.ts.map +0 -1
  591. package/dist/src/features/analytics/queries/metrics-queries.js +0 -240
  592. package/dist/src/features/analytics/queries/metrics-queries.js.map +0 -1
  593. package/dist/src/features/analytics/types/metrics.d.ts +0 -60
  594. package/dist/src/features/analytics/types/metrics.d.ts.map +0 -1
  595. package/dist/src/features/analytics/types/metrics.js +0 -2
  596. package/dist/src/features/analytics/types/metrics.js.map +0 -1
  597. package/dist/src/features/browser/browser-mcp.d.ts +0 -94
  598. package/dist/src/features/browser/browser-mcp.d.ts.map +0 -1
  599. package/dist/src/features/browser/browser-mcp.js +0 -459
  600. package/dist/src/features/browser/browser-mcp.js.map +0 -1
  601. package/dist/src/features/tasks/pebbles-task-store.d.ts +0 -128
  602. package/dist/src/features/tasks/pebbles-task-store.d.ts.map +0 -1
  603. package/dist/src/features/tasks/pebbles-task-store.js +0 -572
  604. package/dist/src/features/tasks/pebbles-task-store.js.map +0 -1
  605. package/dist/src/features/tasks/task-aware-context.d.ts +0 -103
  606. package/dist/src/features/tasks/task-aware-context.d.ts.map +0 -1
  607. package/dist/src/features/tasks/task-aware-context.js +0 -412
  608. package/dist/src/features/tasks/task-aware-context.js.map +0 -1
  609. package/dist/src/index.d.ts +0 -21
  610. package/dist/src/index.d.ts.map +0 -1
  611. package/dist/src/index.js +0 -9
  612. package/dist/src/index.js.map +0 -1
  613. package/dist/src/integrations/linear/auth.d.ts +0 -99
  614. package/dist/src/integrations/linear/auth.d.ts.map +0 -1
  615. package/dist/src/integrations/linear/auth.js +0 -319
  616. package/dist/src/integrations/linear/auth.js.map +0 -1
  617. package/dist/src/integrations/linear/auto-sync.d.ts +0 -77
  618. package/dist/src/integrations/linear/auto-sync.d.ts.map +0 -1
  619. package/dist/src/integrations/linear/auto-sync.js +0 -268
  620. package/dist/src/integrations/linear/auto-sync.js.map +0 -1
  621. package/dist/src/integrations/linear/client.d.ts +0 -127
  622. package/dist/src/integrations/linear/client.d.ts.map +0 -1
  623. package/dist/src/integrations/linear/client.js +0 -446
  624. package/dist/src/integrations/linear/client.js.map +0 -1
  625. package/dist/src/integrations/linear/config.d.ts +0 -51
  626. package/dist/src/integrations/linear/config.d.ts.map +0 -1
  627. package/dist/src/integrations/linear/config.js +0 -103
  628. package/dist/src/integrations/linear/config.js.map +0 -1
  629. package/dist/src/integrations/linear/sync-manager.d.ts +0 -78
  630. package/dist/src/integrations/linear/sync-manager.d.ts.map +0 -1
  631. package/dist/src/integrations/linear/sync-manager.js +0 -235
  632. package/dist/src/integrations/linear/sync-manager.js.map +0 -1
  633. package/dist/src/integrations/linear/sync-service.d.ts +0 -46
  634. package/dist/src/integrations/linear/sync-service.d.ts.map +0 -1
  635. package/dist/src/integrations/linear/sync-service.js +0 -217
  636. package/dist/src/integrations/linear/sync-service.js.map +0 -1
  637. package/dist/src/integrations/linear/sync.d.ts +0 -125
  638. package/dist/src/integrations/linear/sync.d.ts.map +0 -1
  639. package/dist/src/integrations/linear/sync.js +0 -563
  640. package/dist/src/integrations/linear/sync.js.map +0 -1
  641. package/dist/src/integrations/linear/types.d.ts +0 -90
  642. package/dist/src/integrations/linear/types.d.ts.map +0 -1
  643. package/dist/src/integrations/linear/types.js +0 -2
  644. package/dist/src/integrations/linear/types.js.map +0 -1
  645. package/dist/src/integrations/linear/webhook-server.d.ts +0 -32
  646. package/dist/src/integrations/linear/webhook-server.d.ts.map +0 -1
  647. package/dist/src/integrations/linear/webhook-server.js +0 -190
  648. package/dist/src/integrations/linear/webhook-server.js.map +0 -1
  649. package/dist/src/integrations/linear/webhook.d.ts +0 -108
  650. package/dist/src/integrations/linear/webhook.d.ts.map +0 -1
  651. package/dist/src/integrations/linear/webhook.js +0 -291
  652. package/dist/src/integrations/linear/webhook.js.map +0 -1
  653. package/dist/src/integrations/mcp/handlers/context-handlers.d.ts +0 -39
  654. package/dist/src/integrations/mcp/handlers/context-handlers.d.ts.map +0 -1
  655. package/dist/src/integrations/mcp/handlers/context-handlers.js +0 -266
  656. package/dist/src/integrations/mcp/handlers/context-handlers.js.map +0 -1
  657. package/dist/src/integrations/mcp/handlers/index.d.ts +0 -37
  658. package/dist/src/integrations/mcp/handlers/index.d.ts.map +0 -1
  659. package/dist/src/integrations/mcp/handlers/index.js +0 -134
  660. package/dist/src/integrations/mcp/handlers/index.js.map +0 -1
  661. package/dist/src/integrations/mcp/handlers/linear-handlers.d.ts +0 -33
  662. package/dist/src/integrations/mcp/handlers/linear-handlers.d.ts.map +0 -1
  663. package/dist/src/integrations/mcp/handlers/linear-handlers.js +0 -251
  664. package/dist/src/integrations/mcp/handlers/linear-handlers.js.map +0 -1
  665. package/dist/src/integrations/mcp/handlers/task-handlers.d.ts +0 -42
  666. package/dist/src/integrations/mcp/handlers/task-handlers.d.ts.map +0 -1
  667. package/dist/src/integrations/mcp/handlers/task-handlers.js +0 -238
  668. package/dist/src/integrations/mcp/handlers/task-handlers.js.map +0 -1
  669. package/dist/src/integrations/mcp/handlers/trace-handlers.d.ts +0 -41
  670. package/dist/src/integrations/mcp/handlers/trace-handlers.d.ts.map +0 -1
  671. package/dist/src/integrations/mcp/handlers/trace-handlers.js +0 -298
  672. package/dist/src/integrations/mcp/handlers/trace-handlers.js.map +0 -1
  673. package/dist/src/integrations/mcp/index.d.ts +0 -13
  674. package/dist/src/integrations/mcp/index.d.ts.map +0 -1
  675. package/dist/src/integrations/mcp/index.js +0 -17
  676. package/dist/src/integrations/mcp/index.js.map +0 -1
  677. package/dist/src/integrations/mcp/refactored-server.d.ts +0 -76
  678. package/dist/src/integrations/mcp/refactored-server.d.ts.map +0 -1
  679. package/dist/src/integrations/mcp/refactored-server.js +0 -351
  680. package/dist/src/integrations/mcp/refactored-server.js.map +0 -1
  681. package/dist/src/integrations/mcp/server.d.ts +0 -54
  682. package/dist/src/integrations/mcp/server.d.ts.map +0 -1
  683. package/dist/src/integrations/mcp/server.js +0 -1616
  684. package/dist/src/integrations/mcp/server.js.map +0 -1
  685. package/dist/src/integrations/mcp/tool-definitions.d.ts +0 -44
  686. package/dist/src/integrations/mcp/tool-definitions.d.ts.map +0 -1
  687. package/dist/src/integrations/mcp/tool-definitions.js +0 -563
  688. package/dist/src/integrations/mcp/tool-definitions.js.map +0 -1
  689. package/dist/src/integrations/mcp/trace-test.d.ts +0 -5
  690. package/dist/src/integrations/mcp/trace-test.d.ts.map +0 -1
  691. package/dist/src/integrations/mcp/trace-test.js +0 -54
  692. package/dist/src/integrations/mcp/trace-test.js.map +0 -1
  693. package/dist/src/integrations/pg-aiguide/embedding-provider.d.ts +0 -48
  694. package/dist/src/integrations/pg-aiguide/embedding-provider.d.ts.map +0 -1
  695. package/dist/src/integrations/pg-aiguide/embedding-provider.js +0 -190
  696. package/dist/src/integrations/pg-aiguide/embedding-provider.js.map +0 -1
  697. package/dist/src/integrations/pg-aiguide/semantic-search.d.ts +0 -34
  698. package/dist/src/integrations/pg-aiguide/semantic-search.d.ts.map +0 -1
  699. package/dist/src/integrations/pg-aiguide/semantic-search.js +0 -176
  700. package/dist/src/integrations/pg-aiguide/semantic-search.js.map +0 -1
  701. package/dist/src/integrations/pg-aiguide/timescale-analytics.d.ts +0 -44
  702. package/dist/src/integrations/pg-aiguide/timescale-analytics.d.ts.map +0 -1
  703. package/dist/src/integrations/pg-aiguide/timescale-analytics.js +0 -215
  704. package/dist/src/integrations/pg-aiguide/timescale-analytics.js.map +0 -1
  705. package/dist/src/mcp/stackmemory-mcp-server.d.ts +0 -9
  706. package/dist/src/mcp/stackmemory-mcp-server.d.ts.map +0 -1
  707. package/dist/src/mcp/stackmemory-mcp-server.js +0 -519
  708. package/dist/src/mcp/stackmemory-mcp-server.js.map +0 -1
  709. package/dist/src/middleware/exponential-rate-limiter.d.ts +0 -78
  710. package/dist/src/middleware/exponential-rate-limiter.d.ts.map +0 -1
  711. package/dist/src/middleware/exponential-rate-limiter.js +0 -293
  712. package/dist/src/middleware/exponential-rate-limiter.js.map +0 -1
  713. package/dist/src/models/user.model.d.ts +0 -62
  714. package/dist/src/models/user.model.d.ts.map +0 -1
  715. package/dist/src/models/user.model.js +0 -311
  716. package/dist/src/models/user.model.js.map +0 -1
  717. package/dist/src/servers/production/auth-middleware.d.ts +0 -76
  718. package/dist/src/servers/production/auth-middleware.d.ts.map +0 -1
  719. package/dist/src/servers/production/auth-middleware.js +0 -558
  720. package/dist/src/servers/production/auth-middleware.js.map +0 -1
  721. package/dist/src/servers/railway/index.d.ts +0 -7
  722. package/dist/src/servers/railway/index.d.ts.map +0 -1
  723. package/dist/src/servers/railway/index.js +0 -401
  724. package/dist/src/servers/railway/index.js.map +0 -1
  725. package/dist/src/services/config-service.d.ts +0 -44
  726. package/dist/src/services/config-service.d.ts.map +0 -1
  727. package/dist/src/services/config-service.js +0 -61
  728. package/dist/src/services/config-service.js.map +0 -1
  729. package/dist/src/services/context-service.d.ts +0 -17
  730. package/dist/src/services/context-service.d.ts.map +0 -1
  731. package/dist/src/services/context-service.js +0 -173
  732. package/dist/src/services/context-service.js.map +0 -1
  733. package/dist/src/types/task.d.ts +0 -27
  734. package/dist/src/types/task.d.ts.map +0 -1
  735. package/dist/src/types/task.js +0 -2
  736. package/dist/src/types/task.js.map +0 -1
  737. package/dist/src/utils/logger.d.ts +0 -13
  738. package/dist/src/utils/logger.d.ts.map +0 -1
  739. package/dist/src/utils/logger.js +0 -52
  740. package/dist/src/utils/logger.js.map +0 -1
  741. package/dist/src/validation/schemas.d.ts +0 -633
  742. package/dist/src/validation/schemas.d.ts.map +0 -1
  743. package/dist/src/validation/schemas.js +0 -347
  744. package/dist/src/validation/schemas.js.map +0 -1
@@ -33,7 +33,12 @@ class LinearSyncEngine {
33
33
  );
34
34
  }
35
35
  this.linearClient = new LinearClient({
36
- apiKey: tokens.accessToken
36
+ apiKey: tokens.accessToken,
37
+ useBearer: true,
38
+ onUnauthorized: async () => {
39
+ const refreshed = await this.authManager.refreshAccessToken();
40
+ return refreshed.accessToken;
41
+ }
37
42
  });
38
43
  }
39
44
  this.loadMappings();
@@ -66,7 +71,14 @@ class LinearSyncEngine {
66
71
  const apiKey = process.env.LINEAR_API_KEY;
67
72
  if (!apiKey) {
68
73
  const token = await this.authManager.getValidToken();
69
- this.linearClient = new LinearClient({ apiKey: token });
74
+ this.linearClient = new LinearClient({
75
+ apiKey: token,
76
+ useBearer: true,
77
+ onUnauthorized: async () => {
78
+ const refreshed = await this.authManager.refreshAccessToken();
79
+ return refreshed.accessToken;
80
+ }
81
+ });
70
82
  }
71
83
  if (!this.config.defaultTeamId) {
72
84
  const team = await this.linearClient.getTeam();
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../src/integrations/linear/sync.ts"],
4
- "sourcesContent": ["/**\n * Linear Bi-directional Sync Engine\n * Handles syncing tasks between StackMemory and Linear\n */\n\nimport { readFileSync, writeFileSync, existsSync } from 'fs';\nimport { join } from 'path';\nimport { logger } from '../../core/monitoring/logger.js';\nimport {\n PebblesTask,\n PebblesTaskStore,\n TaskStatus,\n TaskPriority,\n} from '../../features/tasks/pebbles-task-store.js';\nimport { LinearClient, LinearIssue, LinearCreateIssueInput } from './client.js';\nimport { LinearAuthManager } from './auth.js';\n\nexport interface SyncConfig {\n enabled: boolean;\n direction: 'bidirectional' | 'to_linear' | 'from_linear';\n defaultTeamId?: string;\n autoSync: boolean;\n conflictResolution:\n | 'linear_wins'\n | 'stackmemory_wins'\n | 'manual'\n | 'newest_wins';\n syncInterval?: number; // minutes\n maxBatchSize?: number; // max tasks to sync per batch\n rateLimitDelay?: number; // ms delay between API calls\n}\n\nexport interface SyncResult {\n success: boolean;\n synced: {\n toLinear: number;\n fromLinear: number;\n updated: number;\n };\n conflicts: Array<{\n taskId: string;\n linearId: string;\n reason: string;\n }>;\n errors: string[];\n}\n\nexport interface TaskMapping {\n stackmemoryId: string;\n linearId: string;\n linearIdentifier: string;\n lastSyncTimestamp: number;\n lastLinearUpdate: string;\n lastStackMemoryUpdate: number;\n}\n\nexport class LinearSyncEngine {\n private taskStore: PebblesTaskStore;\n private linearClient: LinearClient;\n private authManager: LinearAuthManager;\n private config: SyncConfig;\n private mappings: Map<string, TaskMapping> = new Map();\n private projectRoot: string;\n private mappingsPath: string;\n\n constructor(\n taskStore: PebblesTaskStore,\n authManager: LinearAuthManager,\n config: SyncConfig,\n projectRoot?: string\n ) {\n this.taskStore = taskStore;\n this.authManager = authManager;\n this.config = config;\n this.projectRoot = projectRoot || process.cwd();\n this.mappingsPath = join(\n this.projectRoot,\n '.stackmemory',\n 'linear-mappings.json'\n );\n\n // Check for API key from environment variable first\n const apiKey = process.env.LINEAR_API_KEY;\n\n if (apiKey) {\n // Use API key from environment\n this.linearClient = new LinearClient({\n apiKey: apiKey,\n });\n } else {\n // Fall back to OAuth tokens\n const tokens = this.authManager.loadTokens();\n if (!tokens) {\n throw new Error(\n 'Linear API key or authentication tokens not found. Set LINEAR_API_KEY environment variable or run \"stackmemory linear setup\" first.'\n );\n }\n\n this.linearClient = new LinearClient({\n apiKey: tokens.accessToken,\n });\n }\n\n this.loadMappings();\n }\n\n /**\n * Update sync configuration\n */\n updateConfig(newConfig: Partial<SyncConfig>): void {\n this.config = { ...this.config, ...newConfig };\n }\n\n /**\n * Perform bi-directional sync\n */\n async sync(): Promise<SyncResult> {\n if (!this.config.enabled) {\n return {\n success: false,\n synced: { toLinear: 0, fromLinear: 0, updated: 0 },\n conflicts: [],\n errors: ['Sync is disabled'],\n };\n }\n\n const result: SyncResult = {\n success: true,\n synced: { toLinear: 0, fromLinear: 0, updated: 0 },\n conflicts: [],\n errors: [],\n };\n\n try {\n // Update client with valid token if not using environment API key\n const apiKey = process.env.LINEAR_API_KEY;\n if (!apiKey) {\n const token = await this.authManager.getValidToken();\n this.linearClient = new LinearClient({ apiKey: token });\n }\n\n // Get team info if not configured\n if (!this.config.defaultTeamId) {\n const team = await this.linearClient.getTeam();\n this.config.defaultTeamId = team.id;\n logger.info(`Using Linear team: ${team.name} (${team.key})`);\n }\n\n // Sync in both directions based on configuration\n if (\n this.config.direction === 'bidirectional' ||\n this.config.direction === 'to_linear'\n ) {\n const toLinearResult = await this.syncToLinear();\n result.synced.toLinear = toLinearResult.created;\n result.synced.updated += toLinearResult.updated;\n result.errors.push(...toLinearResult.errors);\n }\n\n if (\n this.config.direction === 'bidirectional' ||\n this.config.direction === 'from_linear'\n ) {\n const fromLinearResult = await this.syncFromLinear();\n result.synced.fromLinear = fromLinearResult.created;\n result.synced.updated += fromLinearResult.updated;\n result.conflicts.push(...fromLinearResult.conflicts);\n result.errors.push(...fromLinearResult.errors);\n }\n\n this.saveMappings();\n } catch (error) {\n result.success = false;\n result.errors.push(`Sync failed: ${String(error)}`);\n logger.error('Linear sync failed:', error as Error);\n }\n\n return result;\n }\n\n /**\n * Delay helper for rate limiting\n */\n private async delay(ms: number): Promise<void> {\n return new Promise((resolve) => setTimeout(resolve, ms));\n }\n\n /**\n * Sync tasks from StackMemory to Linear\n */\n private async syncToLinear(): Promise<{\n created: number;\n updated: number;\n errors: string[];\n }> {\n const result = { created: 0, updated: 0, errors: [] as string[] };\n const maxBatchSize = this.config.maxBatchSize || 10;\n const rateLimitDelay = this.config.rateLimitDelay || 500;\n\n // Get unsynced tasks from StackMemory\n const unsyncedTasks = this.getUnsyncedTasks();\n\n // Limit batch size to avoid rate limits\n const tasksToSync = unsyncedTasks.slice(0, maxBatchSize);\n\n if (unsyncedTasks.length > maxBatchSize) {\n logger.info(\n `Syncing ${tasksToSync.length} of ${unsyncedTasks.length} unsynced tasks (batch limit)`\n );\n }\n\n for (const task of tasksToSync) {\n try {\n const linearIssue = await this.createLinearIssueFromTask(task);\n\n // Create mapping\n const mapping: TaskMapping = {\n stackmemoryId: task.id,\n linearId: linearIssue.id,\n linearIdentifier: linearIssue.identifier,\n lastSyncTimestamp: Date.now(),\n lastLinearUpdate: linearIssue.updatedAt,\n lastStackMemoryUpdate: task.timestamp * 1000,\n };\n\n this.mappings.set(task.id, mapping);\n\n // Update task with Linear reference\n this.updateTaskWithLinearRef(task.id, linearIssue);\n\n result.created++;\n logger.info(\n `Synced task to Linear: ${task.title} \u2192 ${linearIssue.identifier}`\n );\n\n // Rate limit delay between creates\n await this.delay(rateLimitDelay);\n } catch (error) {\n const errorMsg = String(error);\n // Stop syncing on rate limit errors\n if (\n errorMsg.includes('rate limit') ||\n errorMsg.includes('usage limit')\n ) {\n logger.warn('Rate limit hit, stopping sync batch');\n result.errors.push('Rate limit reached - sync paused');\n break;\n }\n result.errors.push(`Failed to sync task ${task.id}: ${errorMsg}`);\n logger.error(\n `Failed to sync task ${task.id} to Linear:`,\n error as Error\n );\n }\n }\n\n // Update existing Linear issues for modified StackMemory tasks\n const modifiedTasks = this.getModifiedTasks();\n\n for (const task of modifiedTasks) {\n try {\n const mapping = this.mappings.get(task.id);\n if (!mapping) continue;\n\n await this.updateLinearIssueFromTask(task, mapping);\n\n mapping.lastSyncTimestamp = Date.now();\n mapping.lastStackMemoryUpdate = task.timestamp * 1000;\n\n result.updated++;\n logger.info(`Updated Linear issue: ${mapping.linearIdentifier}`);\n } catch (error) {\n result.errors.push(\n `Failed to update Linear issue for task ${task.id}: ${String(error)}`\n );\n logger.error(\n `Failed to update Linear issue for task ${task.id}:`,\n error as Error\n );\n }\n }\n\n return result;\n }\n\n /**\n * Sync tasks from Linear to StackMemory\n */\n private async syncFromLinear(): Promise<{\n created: number;\n updated: number;\n conflicts: Array<{ taskId: string; linearId: string; reason: string }>;\n errors: string[];\n }> {\n const result = {\n created: 0,\n updated: 0,\n conflicts: [] as Array<{\n taskId: string;\n linearId: string;\n reason: string;\n }>,\n errors: [] as string[],\n };\n\n // First, import any new issues from Linear that aren't mapped yet\n const importResult = await this.importFromLinear();\n result.created = importResult.imported;\n result.errors.push(...importResult.errors);\n\n // Then update existing mapped tasks\n for (const [taskId, mapping] of this.mappings) {\n try {\n const linearIssue = await this.linearClient.getIssue(mapping.linearId);\n\n if (!linearIssue) {\n result.errors.push(`Linear issue ${mapping.linearId} not found`);\n continue;\n }\n\n // Check if Linear issue was updated since last sync\n const linearUpdateTime = new Date(linearIssue.updatedAt).getTime();\n if (linearUpdateTime <= mapping.lastSyncTimestamp) {\n continue; // No changes in Linear\n }\n\n // Check for conflicts\n const task = this.taskStore.getTask(taskId);\n if (!task) {\n result.errors.push(`StackMemory task ${taskId} not found`);\n continue;\n }\n\n const stackMemoryUpdateTime = task.timestamp * 1000;\n\n if (\n stackMemoryUpdateTime > mapping.lastSyncTimestamp &&\n linearUpdateTime > mapping.lastSyncTimestamp\n ) {\n // Conflict: both sides updated since last sync\n result.conflicts.push({\n taskId,\n linearId: mapping.linearId,\n reason: 'Both StackMemory and Linear were updated since last sync',\n });\n\n if (this.config.conflictResolution === 'manual') {\n continue; // Skip, let user resolve manually\n }\n }\n\n // Apply conflict resolution\n const shouldUpdateFromLinear = this.shouldUpdateFromLinear(\n task,\n linearIssue,\n mapping,\n stackMemoryUpdateTime,\n linearUpdateTime\n );\n\n if (shouldUpdateFromLinear) {\n this.updateTaskFromLinearIssue(task, linearIssue);\n\n mapping.lastSyncTimestamp = Date.now();\n mapping.lastLinearUpdate = linearIssue.updatedAt;\n\n result.updated++;\n logger.info(`Updated StackMemory task from Linear: ${task.title}`);\n }\n } catch (error) {\n result.errors.push(\n `Failed to sync from Linear for task ${taskId}: ${String(error)}`\n );\n logger.error(\n `Failed to sync from Linear for task ${taskId}:`,\n error as Error\n );\n }\n }\n\n return result;\n }\n\n /**\n * Create Linear issue from StackMemory task\n */\n private async createLinearIssueFromTask(\n task: PebblesTask\n ): Promise<LinearIssue> {\n const input: LinearCreateIssueInput = {\n title: task.title,\n description: this.formatDescriptionForLinear(task),\n teamId: this.config.defaultTeamId!,\n priority: this.mapPriorityToLinear(task.priority),\n estimate: task.estimated_effort\n ? Math.ceil(task.estimated_effort / 60)\n : undefined, // Convert minutes to hours\n labelIds: this.mapTagsToLinear(task.tags),\n };\n\n return await this.linearClient.createIssue(input);\n }\n\n /**\n * Update Linear issue from StackMemory task\n */\n private async updateLinearIssueFromTask(\n task: PebblesTask,\n mapping: TaskMapping\n ): Promise<void> {\n const updates: Partial<LinearCreateIssueInput> & { stateId?: string } = {\n title: task.title,\n description: this.formatDescriptionForLinear(task),\n priority: this.mapPriorityToLinear(task.priority),\n estimate: task.estimated_effort\n ? Math.ceil(task.estimated_effort / 60)\n : undefined,\n stateId: await this.mapStatusToLinearState(task.status),\n };\n\n await this.linearClient.updateIssue(mapping.linearId, updates);\n }\n\n /**\n * Update StackMemory task from Linear issue\n */\n private updateTaskFromLinearIssue(\n task: PebblesTask,\n linearIssue: LinearIssue\n ): void {\n // Map Linear state to StackMemory status\n const newStatus = this.mapLinearStateToStatus(linearIssue.state.type);\n\n if (newStatus !== task.status) {\n this.taskStore.updateTaskStatus(\n task.id,\n newStatus,\n 'Updated from Linear'\n );\n }\n\n // Note: Other fields like title, description could be updated here\n // but require careful consideration of conflict resolution\n }\n\n /**\n * Check if task should be updated from Linear based on conflict resolution strategy\n */\n private shouldUpdateFromLinear(\n task: PebblesTask,\n linearIssue: LinearIssue,\n mapping: TaskMapping,\n stackMemoryUpdateTime: number,\n linearUpdateTime: number\n ): boolean {\n switch (this.config.conflictResolution) {\n case 'linear_wins':\n return true;\n case 'stackmemory_wins':\n return false;\n case 'newest_wins':\n return linearUpdateTime > stackMemoryUpdateTime;\n case 'manual':\n return false;\n default:\n return false;\n }\n }\n\n /**\n * Get tasks that haven't been synced to Linear yet\n */\n private getUnsyncedTasks(): PebblesTask[] {\n const activeTasks = this.taskStore.getActiveTasks();\n return activeTasks.filter(\n (task) => !this.mappings.has(task.id) && !task.external_refs?.linear\n );\n }\n\n /**\n * Get tasks that have been modified since last sync\n */\n private getModifiedTasks(): PebblesTask[] {\n const tasks: PebblesTask[] = [];\n\n for (const [taskId, mapping] of this.mappings) {\n const task = this.taskStore.getTask(taskId);\n if (task && task.timestamp * 1000 > mapping.lastSyncTimestamp) {\n tasks.push(task);\n }\n }\n\n return tasks;\n }\n\n /**\n * Update task with Linear reference\n */\n private updateTaskWithLinearRef(\n taskId: string,\n linearIssue: LinearIssue\n ): void {\n const task = this.taskStore.getTask(taskId);\n if (!task) return;\n\n // This would need a method in PebblesTaskStore to update external_refs\n // For now, we'll track this in our mappings\n logger.info(`Task ${taskId} mapped to Linear ${linearIssue.identifier}`);\n }\n\n // Mapping utilities\n\n private formatDescriptionForLinear(task: PebblesTask): string {\n let description = task.description || '';\n\n description += `\\n\\n---\\n**StackMemory Context:**\\n`;\n description += `- Task ID: ${task.id}\\n`;\n description += `- Frame: ${task.frame_id}\\n`;\n description += `- Created: ${new Date(task.created_at * 1000).toISOString()}\\n`;\n\n if (task.tags.length > 0) {\n description += `- Tags: ${task.tags.join(', ')}\\n`;\n }\n\n if (task.depends_on.length > 0) {\n description += `- Dependencies: ${task.depends_on.join(', ')}\\n`;\n }\n\n return description;\n }\n\n private mapPriorityToLinear(priority: TaskPriority): number {\n const map: Record<TaskPriority, number> = {\n low: 1, // Low priority in Linear\n medium: 2, // Medium priority in Linear\n high: 3, // High priority in Linear\n urgent: 4, // Urgent priority in Linear\n };\n return map[priority] || 2;\n }\n\n private mapTagsToLinear(_tags: string[]): string[] | undefined {\n // In a full implementation, this would map StackMemory tags to Linear label IDs\n // For now, return undefined to skip label assignment\n return undefined;\n }\n\n private mapLinearStateToStatus(linearStateType: string): TaskStatus {\n switch (linearStateType) {\n case 'backlog':\n case 'unstarted':\n return 'pending';\n case 'started':\n return 'in_progress';\n case 'completed':\n return 'completed';\n case 'cancelled':\n return 'cancelled';\n default:\n return 'pending';\n }\n }\n\n private async mapStatusToLinearState(\n status: TaskStatus\n ): Promise<string | undefined> {\n // Get available states for the team\n try {\n const team = await this.linearClient.getTeam();\n const states = await this.linearClient.getWorkflowStates(team.id);\n\n // Map StackMemory status to Linear state types\n const targetStateType = this.getLinearStateTypeFromStatus(status);\n\n // Find the first state that matches the target type\n const matchingState = states.find(\n (state) => state.type === targetStateType\n );\n return matchingState?.id;\n } catch (error) {\n logger.warn(\n 'Failed to map status to Linear state:',\n error instanceof Error ? { error } : undefined\n );\n return undefined;\n }\n }\n\n private getLinearStateTypeFromStatus(status: TaskStatus): string {\n switch (status) {\n case 'pending':\n return 'unstarted';\n case 'in_progress':\n return 'started';\n case 'completed':\n return 'completed';\n case 'cancelled':\n return 'cancelled';\n case 'blocked':\n return 'unstarted'; // Map blocked to unstarted in Linear\n default:\n return 'unstarted';\n }\n }\n\n // Persistence for mappings\n\n private loadMappings(): void {\n this.mappings.clear();\n\n if (existsSync(this.mappingsPath)) {\n try {\n const data = readFileSync(this.mappingsPath, 'utf8');\n const mappingsArray: TaskMapping[] = JSON.parse(data);\n for (const mapping of mappingsArray) {\n this.mappings.set(mapping.stackmemoryId, mapping);\n }\n logger.info(`Loaded ${this.mappings.size} task mappings from disk`);\n } catch (error) {\n logger.warn('Failed to load mappings, starting fresh');\n }\n }\n }\n\n private saveMappings(): void {\n try {\n const mappingsArray = Array.from(this.mappings.values());\n writeFileSync(this.mappingsPath, JSON.stringify(mappingsArray, null, 2));\n logger.info(`Saved ${this.mappings.size} task mappings to disk`);\n } catch (error) {\n logger.error('Failed to save mappings:', error as Error);\n }\n }\n\n /**\n * Import all issues from Linear to local task store\n */\n async importFromLinear(): Promise<{\n imported: number;\n skipped: number;\n errors: string[];\n }> {\n const result = { imported: 0, skipped: 0, errors: [] as string[] };\n\n try {\n // Get team info\n if (!this.config.defaultTeamId) {\n const team = await this.linearClient.getTeam();\n this.config.defaultTeamId = team.id;\n logger.info(`Using Linear team: ${team.name} (${team.key})`);\n }\n\n // Fetch all issues from Linear (excluding completed/cancelled)\n const issues = await this.linearClient.getIssues({\n teamId: this.config.defaultTeamId,\n limit: 100,\n });\n\n logger.info(`Found ${issues.length} issues in Linear`);\n\n // Build reverse mapping (linearId -> stackmemoryId)\n const linearIdToTaskId = new Map<string, string>();\n for (const [taskId, mapping] of this.mappings) {\n linearIdToTaskId.set(mapping.linearId, taskId);\n }\n\n for (const issue of issues) {\n try {\n // Skip if already mapped\n if (linearIdToTaskId.has(issue.id)) {\n result.skipped++;\n continue;\n }\n\n // Create local task from Linear issue\n const taskId = await this.createTaskFromLinearIssue(issue);\n\n if (taskId) {\n // Create mapping\n const mapping: TaskMapping = {\n stackmemoryId: taskId,\n linearId: issue.id,\n linearIdentifier: issue.identifier,\n lastSyncTimestamp: Date.now(),\n lastLinearUpdate: issue.updatedAt,\n lastStackMemoryUpdate: Date.now(),\n };\n this.mappings.set(taskId, mapping);\n result.imported++;\n logger.info(`Imported ${issue.identifier}: ${issue.title}`);\n }\n } catch (error) {\n result.errors.push(\n `Failed to import ${issue.identifier}: ${String(error)}`\n );\n logger.error(`Failed to import ${issue.identifier}:`, error as Error);\n }\n }\n\n this.saveMappings();\n } catch (error) {\n result.errors.push(`Import failed: ${String(error)}`);\n logger.error('Linear import failed:', error as Error);\n }\n\n return result;\n }\n\n /**\n * Create a local task from a Linear issue\n */\n private async createTaskFromLinearIssue(\n issue: LinearIssue\n ): Promise<string | null> {\n try {\n const priority = this.mapLinearPriorityToLocal(issue.priority);\n\n // Build description with Linear context\n let description = issue.description || '';\n description += `\\n\\n---\\n**Linear:** ${issue.identifier} | ${issue.url}`;\n\n // Extract labels (handle both array and {nodes: [...]} formats)\n const labels = Array.isArray(issue.labels)\n ? issue.labels\n : (issue.labels as unknown as { nodes: Array<{ name: string }> })\n ?.nodes || [];\n const tags = labels.map((l) => l.name);\n if (tags.length === 0) tags.push('linear');\n\n // Create the task via the task store\n const taskId = this.taskStore.createTask({\n title: `[${issue.identifier}] ${issue.title}`,\n description,\n priority,\n frameId: 'linear-import',\n tags,\n estimatedEffort: issue.estimate ? issue.estimate * 60 : undefined,\n });\n\n // Update status if not pending\n const status = this.mapLinearStateToStatus(issue.state.type);\n if (status !== 'pending') {\n this.taskStore.updateTaskStatus(\n taskId,\n status,\n `Imported from Linear as ${status}`\n );\n }\n\n return taskId;\n } catch (error) {\n logger.error(\n `Failed to create task from Linear issue ${issue.identifier}: ${String(error)}`\n );\n return null;\n }\n }\n\n /**\n * Map Linear priority (0-4) to local TaskPriority\n */\n private mapLinearPriorityToLocal(priority: number): TaskPriority {\n switch (priority) {\n case 1:\n return 'urgent';\n case 2:\n return 'high';\n case 3:\n return 'medium';\n case 4:\n return 'low';\n default:\n return 'medium';\n }\n }\n}\n\n/**\n * Default sync configuration\n */\nexport const DEFAULT_SYNC_CONFIG: SyncConfig = {\n enabled: false,\n direction: 'bidirectional',\n autoSync: true,\n conflictResolution: 'newest_wins',\n syncInterval: 15, // minutes\n maxBatchSize: 10, // max tasks per sync batch\n rateLimitDelay: 500, // 500ms between API calls\n};\n"],
5
- "mappings": "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",
4
+ "sourcesContent": ["/**\n * Linear Bi-directional Sync Engine\n * Handles syncing tasks between StackMemory and Linear\n */\n\nimport { readFileSync, writeFileSync, existsSync } from 'fs';\nimport { join } from 'path';\nimport { logger } from '../../core/monitoring/logger.js';\nimport {\n PebblesTask,\n PebblesTaskStore,\n TaskStatus,\n TaskPriority,\n} from '../../features/tasks/pebbles-task-store.js';\nimport { LinearClient, LinearIssue, LinearCreateIssueInput } from './client.js';\nimport { LinearAuthManager } from './auth.js';\n\nexport interface SyncConfig {\n enabled: boolean;\n direction: 'bidirectional' | 'to_linear' | 'from_linear';\n defaultTeamId?: string;\n autoSync: boolean;\n conflictResolution:\n | 'linear_wins'\n | 'stackmemory_wins'\n | 'manual'\n | 'newest_wins';\n syncInterval?: number; // minutes\n maxBatchSize?: number; // max tasks to sync per batch\n rateLimitDelay?: number; // ms delay between API calls\n}\n\nexport interface SyncResult {\n success: boolean;\n synced: {\n toLinear: number;\n fromLinear: number;\n updated: number;\n };\n conflicts: Array<{\n taskId: string;\n linearId: string;\n reason: string;\n }>;\n errors: string[];\n}\n\nexport interface TaskMapping {\n stackmemoryId: string;\n linearId: string;\n linearIdentifier: string;\n lastSyncTimestamp: number;\n lastLinearUpdate: string;\n lastStackMemoryUpdate: number;\n}\n\nexport class LinearSyncEngine {\n private taskStore: PebblesTaskStore;\n private linearClient: LinearClient;\n private authManager: LinearAuthManager;\n private config: SyncConfig;\n private mappings: Map<string, TaskMapping> = new Map();\n private projectRoot: string;\n private mappingsPath: string;\n\n constructor(\n taskStore: PebblesTaskStore,\n authManager: LinearAuthManager,\n config: SyncConfig,\n projectRoot?: string\n ) {\n this.taskStore = taskStore;\n this.authManager = authManager;\n this.config = config;\n this.projectRoot = projectRoot || process.cwd();\n this.mappingsPath = join(\n this.projectRoot,\n '.stackmemory',\n 'linear-mappings.json'\n );\n\n // Check for API key from environment variable first\n const apiKey = process.env.LINEAR_API_KEY;\n\n if (apiKey) {\n // Use API key from environment\n this.linearClient = new LinearClient({\n apiKey: apiKey,\n });\n } else {\n // Fall back to OAuth tokens\n const tokens = this.authManager.loadTokens();\n if (!tokens) {\n throw new Error(\n 'Linear API key or authentication tokens not found. Set LINEAR_API_KEY environment variable or run \"stackmemory linear setup\" first.'\n );\n }\n\n this.linearClient = new LinearClient({\n apiKey: tokens.accessToken,\n useBearer: true,\n onUnauthorized: async () => {\n const refreshed = await this.authManager.refreshAccessToken();\n return refreshed.accessToken;\n },\n });\n }\n\n this.loadMappings();\n }\n\n /**\n * Update sync configuration\n */\n updateConfig(newConfig: Partial<SyncConfig>): void {\n this.config = { ...this.config, ...newConfig };\n }\n\n /**\n * Perform bi-directional sync\n */\n async sync(): Promise<SyncResult> {\n if (!this.config.enabled) {\n return {\n success: false,\n synced: { toLinear: 0, fromLinear: 0, updated: 0 },\n conflicts: [],\n errors: ['Sync is disabled'],\n };\n }\n\n const result: SyncResult = {\n success: true,\n synced: { toLinear: 0, fromLinear: 0, updated: 0 },\n conflicts: [],\n errors: [],\n };\n\n try {\n // Update client with valid token if not using environment API key\n const apiKey = process.env.LINEAR_API_KEY;\n if (!apiKey) {\n const token = await this.authManager.getValidToken();\n this.linearClient = new LinearClient({\n apiKey: token,\n useBearer: true,\n onUnauthorized: async () => {\n const refreshed = await this.authManager.refreshAccessToken();\n return refreshed.accessToken;\n },\n });\n }\n\n // Get team info if not configured\n if (!this.config.defaultTeamId) {\n const team = await this.linearClient.getTeam();\n this.config.defaultTeamId = team.id;\n logger.info(`Using Linear team: ${team.name} (${team.key})`);\n }\n\n // Sync in both directions based on configuration\n if (\n this.config.direction === 'bidirectional' ||\n this.config.direction === 'to_linear'\n ) {\n const toLinearResult = await this.syncToLinear();\n result.synced.toLinear = toLinearResult.created;\n result.synced.updated += toLinearResult.updated;\n result.errors.push(...toLinearResult.errors);\n }\n\n if (\n this.config.direction === 'bidirectional' ||\n this.config.direction === 'from_linear'\n ) {\n const fromLinearResult = await this.syncFromLinear();\n result.synced.fromLinear = fromLinearResult.created;\n result.synced.updated += fromLinearResult.updated;\n result.conflicts.push(...fromLinearResult.conflicts);\n result.errors.push(...fromLinearResult.errors);\n }\n\n this.saveMappings();\n } catch (error) {\n result.success = false;\n result.errors.push(`Sync failed: ${String(error)}`);\n logger.error('Linear sync failed:', error as Error);\n }\n\n return result;\n }\n\n /**\n * Delay helper for rate limiting\n */\n private async delay(ms: number): Promise<void> {\n return new Promise((resolve) => setTimeout(resolve, ms));\n }\n\n /**\n * Sync tasks from StackMemory to Linear\n */\n private async syncToLinear(): Promise<{\n created: number;\n updated: number;\n errors: string[];\n }> {\n const result = { created: 0, updated: 0, errors: [] as string[] };\n const maxBatchSize = this.config.maxBatchSize || 10;\n const rateLimitDelay = this.config.rateLimitDelay || 500;\n\n // Get unsynced tasks from StackMemory\n const unsyncedTasks = this.getUnsyncedTasks();\n\n // Limit batch size to avoid rate limits\n const tasksToSync = unsyncedTasks.slice(0, maxBatchSize);\n\n if (unsyncedTasks.length > maxBatchSize) {\n logger.info(\n `Syncing ${tasksToSync.length} of ${unsyncedTasks.length} unsynced tasks (batch limit)`\n );\n }\n\n for (const task of tasksToSync) {\n try {\n const linearIssue = await this.createLinearIssueFromTask(task);\n\n // Create mapping\n const mapping: TaskMapping = {\n stackmemoryId: task.id,\n linearId: linearIssue.id,\n linearIdentifier: linearIssue.identifier,\n lastSyncTimestamp: Date.now(),\n lastLinearUpdate: linearIssue.updatedAt,\n lastStackMemoryUpdate: task.timestamp * 1000,\n };\n\n this.mappings.set(task.id, mapping);\n\n // Update task with Linear reference\n this.updateTaskWithLinearRef(task.id, linearIssue);\n\n result.created++;\n logger.info(\n `Synced task to Linear: ${task.title} \u2192 ${linearIssue.identifier}`\n );\n\n // Rate limit delay between creates\n await this.delay(rateLimitDelay);\n } catch (error) {\n const errorMsg = String(error);\n // Stop syncing on rate limit errors\n if (\n errorMsg.includes('rate limit') ||\n errorMsg.includes('usage limit')\n ) {\n logger.warn('Rate limit hit, stopping sync batch');\n result.errors.push('Rate limit reached - sync paused');\n break;\n }\n result.errors.push(`Failed to sync task ${task.id}: ${errorMsg}`);\n logger.error(\n `Failed to sync task ${task.id} to Linear:`,\n error as Error\n );\n }\n }\n\n // Update existing Linear issues for modified StackMemory tasks\n const modifiedTasks = this.getModifiedTasks();\n\n for (const task of modifiedTasks) {\n try {\n const mapping = this.mappings.get(task.id);\n if (!mapping) continue;\n\n await this.updateLinearIssueFromTask(task, mapping);\n\n mapping.lastSyncTimestamp = Date.now();\n mapping.lastStackMemoryUpdate = task.timestamp * 1000;\n\n result.updated++;\n logger.info(`Updated Linear issue: ${mapping.linearIdentifier}`);\n } catch (error) {\n result.errors.push(\n `Failed to update Linear issue for task ${task.id}: ${String(error)}`\n );\n logger.error(\n `Failed to update Linear issue for task ${task.id}:`,\n error as Error\n );\n }\n }\n\n return result;\n }\n\n /**\n * Sync tasks from Linear to StackMemory\n */\n private async syncFromLinear(): Promise<{\n created: number;\n updated: number;\n conflicts: Array<{ taskId: string; linearId: string; reason: string }>;\n errors: string[];\n }> {\n const result = {\n created: 0,\n updated: 0,\n conflicts: [] as Array<{\n taskId: string;\n linearId: string;\n reason: string;\n }>,\n errors: [] as string[],\n };\n\n // First, import any new issues from Linear that aren't mapped yet\n const importResult = await this.importFromLinear();\n result.created = importResult.imported;\n result.errors.push(...importResult.errors);\n\n // Then update existing mapped tasks\n for (const [taskId, mapping] of this.mappings) {\n try {\n const linearIssue = await this.linearClient.getIssue(mapping.linearId);\n\n if (!linearIssue) {\n result.errors.push(`Linear issue ${mapping.linearId} not found`);\n continue;\n }\n\n // Check if Linear issue was updated since last sync\n const linearUpdateTime = new Date(linearIssue.updatedAt).getTime();\n if (linearUpdateTime <= mapping.lastSyncTimestamp) {\n continue; // No changes in Linear\n }\n\n // Check for conflicts\n const task = this.taskStore.getTask(taskId);\n if (!task) {\n result.errors.push(`StackMemory task ${taskId} not found`);\n continue;\n }\n\n const stackMemoryUpdateTime = task.timestamp * 1000;\n\n if (\n stackMemoryUpdateTime > mapping.lastSyncTimestamp &&\n linearUpdateTime > mapping.lastSyncTimestamp\n ) {\n // Conflict: both sides updated since last sync\n result.conflicts.push({\n taskId,\n linearId: mapping.linearId,\n reason: 'Both StackMemory and Linear were updated since last sync',\n });\n\n if (this.config.conflictResolution === 'manual') {\n continue; // Skip, let user resolve manually\n }\n }\n\n // Apply conflict resolution\n const shouldUpdateFromLinear = this.shouldUpdateFromLinear(\n task,\n linearIssue,\n mapping,\n stackMemoryUpdateTime,\n linearUpdateTime\n );\n\n if (shouldUpdateFromLinear) {\n this.updateTaskFromLinearIssue(task, linearIssue);\n\n mapping.lastSyncTimestamp = Date.now();\n mapping.lastLinearUpdate = linearIssue.updatedAt;\n\n result.updated++;\n logger.info(`Updated StackMemory task from Linear: ${task.title}`);\n }\n } catch (error) {\n result.errors.push(\n `Failed to sync from Linear for task ${taskId}: ${String(error)}`\n );\n logger.error(\n `Failed to sync from Linear for task ${taskId}:`,\n error as Error\n );\n }\n }\n\n return result;\n }\n\n /**\n * Create Linear issue from StackMemory task\n */\n private async createLinearIssueFromTask(\n task: PebblesTask\n ): Promise<LinearIssue> {\n const input: LinearCreateIssueInput = {\n title: task.title,\n description: this.formatDescriptionForLinear(task),\n teamId: this.config.defaultTeamId!,\n priority: this.mapPriorityToLinear(task.priority),\n estimate: task.estimated_effort\n ? Math.ceil(task.estimated_effort / 60)\n : undefined, // Convert minutes to hours\n labelIds: this.mapTagsToLinear(task.tags),\n };\n\n return await this.linearClient.createIssue(input);\n }\n\n /**\n * Update Linear issue from StackMemory task\n */\n private async updateLinearIssueFromTask(\n task: PebblesTask,\n mapping: TaskMapping\n ): Promise<void> {\n const updates: Partial<LinearCreateIssueInput> & { stateId?: string } = {\n title: task.title,\n description: this.formatDescriptionForLinear(task),\n priority: this.mapPriorityToLinear(task.priority),\n estimate: task.estimated_effort\n ? Math.ceil(task.estimated_effort / 60)\n : undefined,\n stateId: await this.mapStatusToLinearState(task.status),\n };\n\n await this.linearClient.updateIssue(mapping.linearId, updates);\n }\n\n /**\n * Update StackMemory task from Linear issue\n */\n private updateTaskFromLinearIssue(\n task: PebblesTask,\n linearIssue: LinearIssue\n ): void {\n // Map Linear state to StackMemory status\n const newStatus = this.mapLinearStateToStatus(linearIssue.state.type);\n\n if (newStatus !== task.status) {\n this.taskStore.updateTaskStatus(\n task.id,\n newStatus,\n 'Updated from Linear'\n );\n }\n\n // Note: Other fields like title, description could be updated here\n // but require careful consideration of conflict resolution\n }\n\n /**\n * Check if task should be updated from Linear based on conflict resolution strategy\n */\n private shouldUpdateFromLinear(\n task: PebblesTask,\n linearIssue: LinearIssue,\n mapping: TaskMapping,\n stackMemoryUpdateTime: number,\n linearUpdateTime: number\n ): boolean {\n switch (this.config.conflictResolution) {\n case 'linear_wins':\n return true;\n case 'stackmemory_wins':\n return false;\n case 'newest_wins':\n return linearUpdateTime > stackMemoryUpdateTime;\n case 'manual':\n return false;\n default:\n return false;\n }\n }\n\n /**\n * Get tasks that haven't been synced to Linear yet\n */\n private getUnsyncedTasks(): PebblesTask[] {\n const activeTasks = this.taskStore.getActiveTasks();\n return activeTasks.filter(\n (task) => !this.mappings.has(task.id) && !task.external_refs?.linear\n );\n }\n\n /**\n * Get tasks that have been modified since last sync\n */\n private getModifiedTasks(): PebblesTask[] {\n const tasks: PebblesTask[] = [];\n\n for (const [taskId, mapping] of this.mappings) {\n const task = this.taskStore.getTask(taskId);\n if (task && task.timestamp * 1000 > mapping.lastSyncTimestamp) {\n tasks.push(task);\n }\n }\n\n return tasks;\n }\n\n /**\n * Update task with Linear reference\n */\n private updateTaskWithLinearRef(\n taskId: string,\n linearIssue: LinearIssue\n ): void {\n const task = this.taskStore.getTask(taskId);\n if (!task) return;\n\n // This would need a method in PebblesTaskStore to update external_refs\n // For now, we'll track this in our mappings\n logger.info(`Task ${taskId} mapped to Linear ${linearIssue.identifier}`);\n }\n\n // Mapping utilities\n\n private formatDescriptionForLinear(task: PebblesTask): string {\n let description = task.description || '';\n\n description += `\\n\\n---\\n**StackMemory Context:**\\n`;\n description += `- Task ID: ${task.id}\\n`;\n description += `- Frame: ${task.frame_id}\\n`;\n description += `- Created: ${new Date(task.created_at * 1000).toISOString()}\\n`;\n\n if (task.tags.length > 0) {\n description += `- Tags: ${task.tags.join(', ')}\\n`;\n }\n\n if (task.depends_on.length > 0) {\n description += `- Dependencies: ${task.depends_on.join(', ')}\\n`;\n }\n\n return description;\n }\n\n private mapPriorityToLinear(priority: TaskPriority): number {\n const map: Record<TaskPriority, number> = {\n low: 1, // Low priority in Linear\n medium: 2, // Medium priority in Linear\n high: 3, // High priority in Linear\n urgent: 4, // Urgent priority in Linear\n };\n return map[priority] || 2;\n }\n\n private mapTagsToLinear(_tags: string[]): string[] | undefined {\n // In a full implementation, this would map StackMemory tags to Linear label IDs\n // For now, return undefined to skip label assignment\n return undefined;\n }\n\n private mapLinearStateToStatus(linearStateType: string): TaskStatus {\n switch (linearStateType) {\n case 'backlog':\n case 'unstarted':\n return 'pending';\n case 'started':\n return 'in_progress';\n case 'completed':\n return 'completed';\n case 'cancelled':\n return 'cancelled';\n default:\n return 'pending';\n }\n }\n\n private async mapStatusToLinearState(\n status: TaskStatus\n ): Promise<string | undefined> {\n // Get available states for the team\n try {\n const team = await this.linearClient.getTeam();\n const states = await this.linearClient.getWorkflowStates(team.id);\n\n // Map StackMemory status to Linear state types\n const targetStateType = this.getLinearStateTypeFromStatus(status);\n\n // Find the first state that matches the target type\n const matchingState = states.find(\n (state) => state.type === targetStateType\n );\n return matchingState?.id;\n } catch (error) {\n logger.warn(\n 'Failed to map status to Linear state:',\n error instanceof Error ? { error } : undefined\n );\n return undefined;\n }\n }\n\n private getLinearStateTypeFromStatus(status: TaskStatus): string {\n switch (status) {\n case 'pending':\n return 'unstarted';\n case 'in_progress':\n return 'started';\n case 'completed':\n return 'completed';\n case 'cancelled':\n return 'cancelled';\n case 'blocked':\n return 'unstarted'; // Map blocked to unstarted in Linear\n default:\n return 'unstarted';\n }\n }\n\n // Persistence for mappings\n\n private loadMappings(): void {\n this.mappings.clear();\n\n if (existsSync(this.mappingsPath)) {\n try {\n const data = readFileSync(this.mappingsPath, 'utf8');\n const mappingsArray: TaskMapping[] = JSON.parse(data);\n for (const mapping of mappingsArray) {\n this.mappings.set(mapping.stackmemoryId, mapping);\n }\n logger.info(`Loaded ${this.mappings.size} task mappings from disk`);\n } catch (error) {\n logger.warn('Failed to load mappings, starting fresh');\n }\n }\n }\n\n private saveMappings(): void {\n try {\n const mappingsArray = Array.from(this.mappings.values());\n writeFileSync(this.mappingsPath, JSON.stringify(mappingsArray, null, 2));\n logger.info(`Saved ${this.mappings.size} task mappings to disk`);\n } catch (error) {\n logger.error('Failed to save mappings:', error as Error);\n }\n }\n\n /**\n * Import all issues from Linear to local task store\n */\n async importFromLinear(): Promise<{\n imported: number;\n skipped: number;\n errors: string[];\n }> {\n const result = { imported: 0, skipped: 0, errors: [] as string[] };\n\n try {\n // Get team info\n if (!this.config.defaultTeamId) {\n const team = await this.linearClient.getTeam();\n this.config.defaultTeamId = team.id;\n logger.info(`Using Linear team: ${team.name} (${team.key})`);\n }\n\n // Fetch all issues from Linear (excluding completed/cancelled)\n const issues = await this.linearClient.getIssues({\n teamId: this.config.defaultTeamId,\n limit: 100,\n });\n\n logger.info(`Found ${issues.length} issues in Linear`);\n\n // Build reverse mapping (linearId -> stackmemoryId)\n const linearIdToTaskId = new Map<string, string>();\n for (const [taskId, mapping] of this.mappings) {\n linearIdToTaskId.set(mapping.linearId, taskId);\n }\n\n for (const issue of issues) {\n try {\n // Skip if already mapped\n if (linearIdToTaskId.has(issue.id)) {\n result.skipped++;\n continue;\n }\n\n // Create local task from Linear issue\n const taskId = await this.createTaskFromLinearIssue(issue);\n\n if (taskId) {\n // Create mapping\n const mapping: TaskMapping = {\n stackmemoryId: taskId,\n linearId: issue.id,\n linearIdentifier: issue.identifier,\n lastSyncTimestamp: Date.now(),\n lastLinearUpdate: issue.updatedAt,\n lastStackMemoryUpdate: Date.now(),\n };\n this.mappings.set(taskId, mapping);\n result.imported++;\n logger.info(`Imported ${issue.identifier}: ${issue.title}`);\n }\n } catch (error) {\n result.errors.push(\n `Failed to import ${issue.identifier}: ${String(error)}`\n );\n logger.error(`Failed to import ${issue.identifier}:`, error as Error);\n }\n }\n\n this.saveMappings();\n } catch (error) {\n result.errors.push(`Import failed: ${String(error)}`);\n logger.error('Linear import failed:', error as Error);\n }\n\n return result;\n }\n\n /**\n * Create a local task from a Linear issue\n */\n private async createTaskFromLinearIssue(\n issue: LinearIssue\n ): Promise<string | null> {\n try {\n const priority = this.mapLinearPriorityToLocal(issue.priority);\n\n // Build description with Linear context\n let description = issue.description || '';\n description += `\\n\\n---\\n**Linear:** ${issue.identifier} | ${issue.url}`;\n\n // Extract labels (handle both array and {nodes: [...]} formats)\n const labels = Array.isArray(issue.labels)\n ? issue.labels\n : (issue.labels as unknown as { nodes: Array<{ name: string }> })\n ?.nodes || [];\n const tags = labels.map((l) => l.name);\n if (tags.length === 0) tags.push('linear');\n\n // Create the task via the task store\n const taskId = this.taskStore.createTask({\n title: `[${issue.identifier}] ${issue.title}`,\n description,\n priority,\n frameId: 'linear-import',\n tags,\n estimatedEffort: issue.estimate ? issue.estimate * 60 : undefined,\n });\n\n // Update status if not pending\n const status = this.mapLinearStateToStatus(issue.state.type);\n if (status !== 'pending') {\n this.taskStore.updateTaskStatus(\n taskId,\n status,\n `Imported from Linear as ${status}`\n );\n }\n\n return taskId;\n } catch (error) {\n logger.error(\n `Failed to create task from Linear issue ${issue.identifier}: ${String(error)}`\n );\n return null;\n }\n }\n\n /**\n * Map Linear priority (0-4) to local TaskPriority\n */\n private mapLinearPriorityToLocal(priority: number): TaskPriority {\n switch (priority) {\n case 1:\n return 'urgent';\n case 2:\n return 'high';\n case 3:\n return 'medium';\n case 4:\n return 'low';\n default:\n return 'medium';\n }\n }\n}\n\n/**\n * Default sync configuration\n */\nexport const DEFAULT_SYNC_CONFIG: SyncConfig = {\n enabled: false,\n direction: 'bidirectional',\n autoSync: true,\n conflictResolution: 'newest_wins',\n syncInterval: 15, // minutes\n maxBatchSize: 10, // max tasks per sync batch\n rateLimitDelay: 500, // 500ms between API calls\n};\n"],
5
+ "mappings": "AAKA,SAAS,cAAc,eAAe,kBAAkB;AACxD,SAAS,YAAY;AACrB,SAAS,cAAc;AAOvB,SAAS,oBAAyD;AA0C3D,MAAM,iBAAiB;AAAA,EACpB;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA,WAAqC,oBAAI,IAAI;AAAA,EAC7C;AAAA,EACA;AAAA,EAER,YACE,WACA,aACA,QACA,aACA;AACA,SAAK,YAAY;AACjB,SAAK,cAAc;AACnB,SAAK,SAAS;AACd,SAAK,cAAc,eAAe,QAAQ,IAAI;AAC9C,SAAK,eAAe;AAAA,MAClB,KAAK;AAAA,MACL;AAAA,MACA;AAAA,IACF;AAGA,UAAM,SAAS,QAAQ,IAAI;AAE3B,QAAI,QAAQ;AAEV,WAAK,eAAe,IAAI,aAAa;AAAA,QACnC;AAAA,MACF,CAAC;AAAA,IACH,OAAO;AAEL,YAAM,SAAS,KAAK,YAAY,WAAW;AAC3C,UAAI,CAAC,QAAQ;AACX,cAAM,IAAI;AAAA,UACR;AAAA,QACF;AAAA,MACF;AAEA,WAAK,eAAe,IAAI,aAAa;AAAA,QACnC,QAAQ,OAAO;AAAA,QACf,WAAW;AAAA,QACX,gBAAgB,YAAY;AAC1B,gBAAM,YAAY,MAAM,KAAK,YAAY,mBAAmB;AAC5D,iBAAO,UAAU;AAAA,QACnB;AAAA,MACF,CAAC;AAAA,IACH;AAEA,SAAK,aAAa;AAAA,EACpB;AAAA;AAAA;AAAA;AAAA,EAKA,aAAa,WAAsC;AACjD,SAAK,SAAS,EAAE,GAAG,KAAK,QAAQ,GAAG,UAAU;AAAA,EAC/C;AAAA;AAAA;AAAA;AAAA,EAKA,MAAM,OAA4B;AAChC,QAAI,CAAC,KAAK,OAAO,SAAS;AACxB,aAAO;AAAA,QACL,SAAS;AAAA,QACT,QAAQ,EAAE,UAAU,GAAG,YAAY,GAAG,SAAS,EAAE;AAAA,QACjD,WAAW,CAAC;AAAA,QACZ,QAAQ,CAAC,kBAAkB;AAAA,MAC7B;AAAA,IACF;AAEA,UAAM,SAAqB;AAAA,MACzB,SAAS;AAAA,MACT,QAAQ,EAAE,UAAU,GAAG,YAAY,GAAG,SAAS,EAAE;AAAA,MACjD,WAAW,CAAC;AAAA,MACZ,QAAQ,CAAC;AAAA,IACX;AAEA,QAAI;AAEF,YAAM,SAAS,QAAQ,IAAI;AAC3B,UAAI,CAAC,QAAQ;AACX,cAAM,QAAQ,MAAM,KAAK,YAAY,cAAc;AACnD,aAAK,eAAe,IAAI,aAAa;AAAA,UACnC,QAAQ;AAAA,UACR,WAAW;AAAA,UACX,gBAAgB,YAAY;AAC1B,kBAAM,YAAY,MAAM,KAAK,YAAY,mBAAmB;AAC5D,mBAAO,UAAU;AAAA,UACnB;AAAA,QACF,CAAC;AAAA,MACH;AAGA,UAAI,CAAC,KAAK,OAAO,eAAe;AAC9B,cAAM,OAAO,MAAM,KAAK,aAAa,QAAQ;AAC7C,aAAK,OAAO,gBAAgB,KAAK;AACjC,eAAO,KAAK,sBAAsB,KAAK,IAAI,KAAK,KAAK,GAAG,GAAG;AAAA,MAC7D;AAGA,UACE,KAAK,OAAO,cAAc,mBAC1B,KAAK,OAAO,cAAc,aAC1B;AACA,cAAM,iBAAiB,MAAM,KAAK,aAAa;AAC/C,eAAO,OAAO,WAAW,eAAe;AACxC,eAAO,OAAO,WAAW,eAAe;AACxC,eAAO,OAAO,KAAK,GAAG,eAAe,MAAM;AAAA,MAC7C;AAEA,UACE,KAAK,OAAO,cAAc,mBAC1B,KAAK,OAAO,cAAc,eAC1B;AACA,cAAM,mBAAmB,MAAM,KAAK,eAAe;AACnD,eAAO,OAAO,aAAa,iBAAiB;AAC5C,eAAO,OAAO,WAAW,iBAAiB;AAC1C,eAAO,UAAU,KAAK,GAAG,iBAAiB,SAAS;AACnD,eAAO,OAAO,KAAK,GAAG,iBAAiB,MAAM;AAAA,MAC/C;AAEA,WAAK,aAAa;AAAA,IACpB,SAAS,OAAO;AACd,aAAO,UAAU;AACjB,aAAO,OAAO,KAAK,gBAAgB,OAAO,KAAK,CAAC,EAAE;AAClD,aAAO,MAAM,uBAAuB,KAAc;AAAA,IACpD;AAEA,WAAO;AAAA,EACT;AAAA;AAAA;AAAA;AAAA,EAKA,MAAc,MAAM,IAA2B;AAC7C,WAAO,IAAI,QAAQ,CAAC,YAAY,WAAW,SAAS,EAAE,CAAC;AAAA,EACzD;AAAA;AAAA;AAAA;AAAA,EAKA,MAAc,eAIX;AACD,UAAM,SAAS,EAAE,SAAS,GAAG,SAAS,GAAG,QAAQ,CAAC,EAAc;AAChE,UAAM,eAAe,KAAK,OAAO,gBAAgB;AACjD,UAAM,iBAAiB,KAAK,OAAO,kBAAkB;AAGrD,UAAM,gBAAgB,KAAK,iBAAiB;AAG5C,UAAM,cAAc,cAAc,MAAM,GAAG,YAAY;AAEvD,QAAI,cAAc,SAAS,cAAc;AACvC,aAAO;AAAA,QACL,WAAW,YAAY,MAAM,OAAO,cAAc,MAAM;AAAA,MAC1D;AAAA,IACF;AAEA,eAAW,QAAQ,aAAa;AAC9B,UAAI;AACF,cAAM,cAAc,MAAM,KAAK,0BAA0B,IAAI;AAG7D,cAAM,UAAuB;AAAA,UAC3B,eAAe,KAAK;AAAA,UACpB,UAAU,YAAY;AAAA,UACtB,kBAAkB,YAAY;AAAA,UAC9B,mBAAmB,KAAK,IAAI;AAAA,UAC5B,kBAAkB,YAAY;AAAA,UAC9B,uBAAuB,KAAK,YAAY;AAAA,QAC1C;AAEA,aAAK,SAAS,IAAI,KAAK,IAAI,OAAO;AAGlC,aAAK,wBAAwB,KAAK,IAAI,WAAW;AAEjD,eAAO;AACP,eAAO;AAAA,UACL,0BAA0B,KAAK,KAAK,WAAM,YAAY,UAAU;AAAA,QAClE;AAGA,cAAM,KAAK,MAAM,cAAc;AAAA,MACjC,SAAS,OAAO;AACd,cAAM,WAAW,OAAO,KAAK;AAE7B,YACE,SAAS,SAAS,YAAY,KAC9B,SAAS,SAAS,aAAa,GAC/B;AACA,iBAAO,KAAK,qCAAqC;AACjD,iBAAO,OAAO,KAAK,kCAAkC;AACrD;AAAA,QACF;AACA,eAAO,OAAO,KAAK,uBAAuB,KAAK,EAAE,KAAK,QAAQ,EAAE;AAChE,eAAO;AAAA,UACL,uBAAuB,KAAK,EAAE;AAAA,UAC9B;AAAA,QACF;AAAA,MACF;AAAA,IACF;AAGA,UAAM,gBAAgB,KAAK,iBAAiB;AAE5C,eAAW,QAAQ,eAAe;AAChC,UAAI;AACF,cAAM,UAAU,KAAK,SAAS,IAAI,KAAK,EAAE;AACzC,YAAI,CAAC,QAAS;AAEd,cAAM,KAAK,0BAA0B,MAAM,OAAO;AAElD,gBAAQ,oBAAoB,KAAK,IAAI;AACrC,gBAAQ,wBAAwB,KAAK,YAAY;AAEjD,eAAO;AACP,eAAO,KAAK,yBAAyB,QAAQ,gBAAgB,EAAE;AAAA,MACjE,SAAS,OAAO;AACd,eAAO,OAAO;AAAA,UACZ,0CAA0C,KAAK,EAAE,KAAK,OAAO,KAAK,CAAC;AAAA,QACrE;AACA,eAAO;AAAA,UACL,0CAA0C,KAAK,EAAE;AAAA,UACjD;AAAA,QACF;AAAA,MACF;AAAA,IACF;AAEA,WAAO;AAAA,EACT;AAAA;AAAA;AAAA;AAAA,EAKA,MAAc,iBAKX;AACD,UAAM,SAAS;AAAA,MACb,SAAS;AAAA,MACT,SAAS;AAAA,MACT,WAAW,CAAC;AAAA,MAKZ,QAAQ,CAAC;AAAA,IACX;AAGA,UAAM,eAAe,MAAM,KAAK,iBAAiB;AACjD,WAAO,UAAU,aAAa;AAC9B,WAAO,OAAO,KAAK,GAAG,aAAa,MAAM;AAGzC,eAAW,CAAC,QAAQ,OAAO,KAAK,KAAK,UAAU;AAC7C,UAAI;AACF,cAAM,cAAc,MAAM,KAAK,aAAa,SAAS,QAAQ,QAAQ;AAErE,YAAI,CAAC,aAAa;AAChB,iBAAO,OAAO,KAAK,gBAAgB,QAAQ,QAAQ,YAAY;AAC/D;AAAA,QACF;AAGA,cAAM,mBAAmB,IAAI,KAAK,YAAY,SAAS,EAAE,QAAQ;AACjE,YAAI,oBAAoB,QAAQ,mBAAmB;AACjD;AAAA,QACF;AAGA,cAAM,OAAO,KAAK,UAAU,QAAQ,MAAM;AAC1C,YAAI,CAAC,MAAM;AACT,iBAAO,OAAO,KAAK,oBAAoB,MAAM,YAAY;AACzD;AAAA,QACF;AAEA,cAAM,wBAAwB,KAAK,YAAY;AAE/C,YACE,wBAAwB,QAAQ,qBAChC,mBAAmB,QAAQ,mBAC3B;AAEA,iBAAO,UAAU,KAAK;AAAA,YACpB;AAAA,YACA,UAAU,QAAQ;AAAA,YAClB,QAAQ;AAAA,UACV,CAAC;AAED,cAAI,KAAK,OAAO,uBAAuB,UAAU;AAC/C;AAAA,UACF;AAAA,QACF;AAGA,cAAM,yBAAyB,KAAK;AAAA,UAClC;AAAA,UACA;AAAA,UACA;AAAA,UACA;AAAA,UACA;AAAA,QACF;AAEA,YAAI,wBAAwB;AAC1B,eAAK,0BAA0B,MAAM,WAAW;AAEhD,kBAAQ,oBAAoB,KAAK,IAAI;AACrC,kBAAQ,mBAAmB,YAAY;AAEvC,iBAAO;AACP,iBAAO,KAAK,yCAAyC,KAAK,KAAK,EAAE;AAAA,QACnE;AAAA,MACF,SAAS,OAAO;AACd,eAAO,OAAO;AAAA,UACZ,uCAAuC,MAAM,KAAK,OAAO,KAAK,CAAC;AAAA,QACjE;AACA,eAAO;AAAA,UACL,uCAAuC,MAAM;AAAA,UAC7C;AAAA,QACF;AAAA,MACF;AAAA,IACF;AAEA,WAAO;AAAA,EACT;AAAA;AAAA;AAAA;AAAA,EAKA,MAAc,0BACZ,MACsB;AACtB,UAAM,QAAgC;AAAA,MACpC,OAAO,KAAK;AAAA,MACZ,aAAa,KAAK,2BAA2B,IAAI;AAAA,MACjD,QAAQ,KAAK,OAAO;AAAA,MACpB,UAAU,KAAK,oBAAoB,KAAK,QAAQ;AAAA,MAChD,UAAU,KAAK,mBACX,KAAK,KAAK,KAAK,mBAAmB,EAAE,IACpC;AAAA;AAAA,MACJ,UAAU,KAAK,gBAAgB,KAAK,IAAI;AAAA,IAC1C;AAEA,WAAO,MAAM,KAAK,aAAa,YAAY,KAAK;AAAA,EAClD;AAAA;AAAA;AAAA;AAAA,EAKA,MAAc,0BACZ,MACA,SACe;AACf,UAAM,UAAkE;AAAA,MACtE,OAAO,KAAK;AAAA,MACZ,aAAa,KAAK,2BAA2B,IAAI;AAAA,MACjD,UAAU,KAAK,oBAAoB,KAAK,QAAQ;AAAA,MAChD,UAAU,KAAK,mBACX,KAAK,KAAK,KAAK,mBAAmB,EAAE,IACpC;AAAA,MACJ,SAAS,MAAM,KAAK,uBAAuB,KAAK,MAAM;AAAA,IACxD;AAEA,UAAM,KAAK,aAAa,YAAY,QAAQ,UAAU,OAAO;AAAA,EAC/D;AAAA;AAAA;AAAA;AAAA,EAKQ,0BACN,MACA,aACM;AAEN,UAAM,YAAY,KAAK,uBAAuB,YAAY,MAAM,IAAI;AAEpE,QAAI,cAAc,KAAK,QAAQ;AAC7B,WAAK,UAAU;AAAA,QACb,KAAK;AAAA,QACL;AAAA,QACA;AAAA,MACF;AAAA,IACF;AAAA,EAIF;AAAA;AAAA;AAAA;AAAA,EAKQ,uBACN,MACA,aACA,SACA,uBACA,kBACS;AACT,YAAQ,KAAK,OAAO,oBAAoB;AAAA,MACtC,KAAK;AACH,eAAO;AAAA,MACT,KAAK;AACH,eAAO;AAAA,MACT,KAAK;AACH,eAAO,mBAAmB;AAAA,MAC5B,KAAK;AACH,eAAO;AAAA,MACT;AACE,eAAO;AAAA,IACX;AAAA,EACF;AAAA;AAAA;AAAA;AAAA,EAKQ,mBAAkC;AACxC,UAAM,cAAc,KAAK,UAAU,eAAe;AAClD,WAAO,YAAY;AAAA,MACjB,CAAC,SAAS,CAAC,KAAK,SAAS,IAAI,KAAK,EAAE,KAAK,CAAC,KAAK,eAAe;AAAA,IAChE;AAAA,EACF;AAAA;AAAA;AAAA;AAAA,EAKQ,mBAAkC;AACxC,UAAM,QAAuB,CAAC;AAE9B,eAAW,CAAC,QAAQ,OAAO,KAAK,KAAK,UAAU;AAC7C,YAAM,OAAO,KAAK,UAAU,QAAQ,MAAM;AAC1C,UAAI,QAAQ,KAAK,YAAY,MAAO,QAAQ,mBAAmB;AAC7D,cAAM,KAAK,IAAI;AAAA,MACjB;AAAA,IACF;AAEA,WAAO;AAAA,EACT;AAAA;AAAA;AAAA;AAAA,EAKQ,wBACN,QACA,aACM;AACN,UAAM,OAAO,KAAK,UAAU,QAAQ,MAAM;AAC1C,QAAI,CAAC,KAAM;AAIX,WAAO,KAAK,QAAQ,MAAM,qBAAqB,YAAY,UAAU,EAAE;AAAA,EACzE;AAAA;AAAA,EAIQ,2BAA2B,MAA2B;AAC5D,QAAI,cAAc,KAAK,eAAe;AAEtC,mBAAe;AAAA;AAAA;AAAA;AAAA;AACf,mBAAe,cAAc,KAAK,EAAE;AAAA;AACpC,mBAAe,YAAY,KAAK,QAAQ;AAAA;AACxC,mBAAe,cAAc,IAAI,KAAK,KAAK,aAAa,GAAI,EAAE,YAAY,CAAC;AAAA;AAE3E,QAAI,KAAK,KAAK,SAAS,GAAG;AACxB,qBAAe,WAAW,KAAK,KAAK,KAAK,IAAI,CAAC;AAAA;AAAA,IAChD;AAEA,QAAI,KAAK,WAAW,SAAS,GAAG;AAC9B,qBAAe,mBAAmB,KAAK,WAAW,KAAK,IAAI,CAAC;AAAA;AAAA,IAC9D;AAEA,WAAO;AAAA,EACT;AAAA,EAEQ,oBAAoB,UAAgC;AAC1D,UAAM,MAAoC;AAAA,MACxC,KAAK;AAAA;AAAA,MACL,QAAQ;AAAA;AAAA,MACR,MAAM;AAAA;AAAA,MACN,QAAQ;AAAA;AAAA,IACV;AACA,WAAO,IAAI,QAAQ,KAAK;AAAA,EAC1B;AAAA,EAEQ,gBAAgB,OAAuC;AAG7D,WAAO;AAAA,EACT;AAAA,EAEQ,uBAAuB,iBAAqC;AAClE,YAAQ,iBAAiB;AAAA,MACvB,KAAK;AAAA,MACL,KAAK;AACH,eAAO;AAAA,MACT,KAAK;AACH,eAAO;AAAA,MACT,KAAK;AACH,eAAO;AAAA,MACT,KAAK;AACH,eAAO;AAAA,MACT;AACE,eAAO;AAAA,IACX;AAAA,EACF;AAAA,EAEA,MAAc,uBACZ,QAC6B;AAE7B,QAAI;AACF,YAAM,OAAO,MAAM,KAAK,aAAa,QAAQ;AAC7C,YAAM,SAAS,MAAM,KAAK,aAAa,kBAAkB,KAAK,EAAE;AAGhE,YAAM,kBAAkB,KAAK,6BAA6B,MAAM;AAGhE,YAAM,gBAAgB,OAAO;AAAA,QAC3B,CAAC,UAAU,MAAM,SAAS;AAAA,MAC5B;AACA,aAAO,eAAe;AAAA,IACxB,SAAS,OAAO;AACd,aAAO;AAAA,QACL;AAAA,QACA,iBAAiB,QAAQ,EAAE,MAAM,IAAI;AAAA,MACvC;AACA,aAAO;AAAA,IACT;AAAA,EACF;AAAA,EAEQ,6BAA6B,QAA4B;AAC/D,YAAQ,QAAQ;AAAA,MACd,KAAK;AACH,eAAO;AAAA,MACT,KAAK;AACH,eAAO;AAAA,MACT,KAAK;AACH,eAAO;AAAA,MACT,KAAK;AACH,eAAO;AAAA,MACT,KAAK;AACH,eAAO;AAAA;AAAA,MACT;AACE,eAAO;AAAA,IACX;AAAA,EACF;AAAA;AAAA,EAIQ,eAAqB;AAC3B,SAAK,SAAS,MAAM;AAEpB,QAAI,WAAW,KAAK,YAAY,GAAG;AACjC,UAAI;AACF,cAAM,OAAO,aAAa,KAAK,cAAc,MAAM;AACnD,cAAM,gBAA+B,KAAK,MAAM,IAAI;AACpD,mBAAW,WAAW,eAAe;AACnC,eAAK,SAAS,IAAI,QAAQ,eAAe,OAAO;AAAA,QAClD;AACA,eAAO,KAAK,UAAU,KAAK,SAAS,IAAI,0BAA0B;AAAA,MACpE,SAAS,OAAO;AACd,eAAO,KAAK,yCAAyC;AAAA,MACvD;AAAA,IACF;AAAA,EACF;AAAA,EAEQ,eAAqB;AAC3B,QAAI;AACF,YAAM,gBAAgB,MAAM,KAAK,KAAK,SAAS,OAAO,CAAC;AACvD,oBAAc,KAAK,cAAc,KAAK,UAAU,eAAe,MAAM,CAAC,CAAC;AACvE,aAAO,KAAK,SAAS,KAAK,SAAS,IAAI,wBAAwB;AAAA,IACjE,SAAS,OAAO;AACd,aAAO,MAAM,4BAA4B,KAAc;AAAA,IACzD;AAAA,EACF;AAAA;AAAA;AAAA;AAAA,EAKA,MAAM,mBAIH;AACD,UAAM,SAAS,EAAE,UAAU,GAAG,SAAS,GAAG,QAAQ,CAAC,EAAc;AAEjE,QAAI;AAEF,UAAI,CAAC,KAAK,OAAO,eAAe;AAC9B,cAAM,OAAO,MAAM,KAAK,aAAa,QAAQ;AAC7C,aAAK,OAAO,gBAAgB,KAAK;AACjC,eAAO,KAAK,sBAAsB,KAAK,IAAI,KAAK,KAAK,GAAG,GAAG;AAAA,MAC7D;AAGA,YAAM,SAAS,MAAM,KAAK,aAAa,UAAU;AAAA,QAC/C,QAAQ,KAAK,OAAO;AAAA,QACpB,OAAO;AAAA,MACT,CAAC;AAED,aAAO,KAAK,SAAS,OAAO,MAAM,mBAAmB;AAGrD,YAAM,mBAAmB,oBAAI,IAAoB;AACjD,iBAAW,CAAC,QAAQ,OAAO,KAAK,KAAK,UAAU;AAC7C,yBAAiB,IAAI,QAAQ,UAAU,MAAM;AAAA,MAC/C;AAEA,iBAAW,SAAS,QAAQ;AAC1B,YAAI;AAEF,cAAI,iBAAiB,IAAI,MAAM,EAAE,GAAG;AAClC,mBAAO;AACP;AAAA,UACF;AAGA,gBAAM,SAAS,MAAM,KAAK,0BAA0B,KAAK;AAEzD,cAAI,QAAQ;AAEV,kBAAM,UAAuB;AAAA,cAC3B,eAAe;AAAA,cACf,UAAU,MAAM;AAAA,cAChB,kBAAkB,MAAM;AAAA,cACxB,mBAAmB,KAAK,IAAI;AAAA,cAC5B,kBAAkB,MAAM;AAAA,cACxB,uBAAuB,KAAK,IAAI;AAAA,YAClC;AACA,iBAAK,SAAS,IAAI,QAAQ,OAAO;AACjC,mBAAO;AACP,mBAAO,KAAK,YAAY,MAAM,UAAU,KAAK,MAAM,KAAK,EAAE;AAAA,UAC5D;AAAA,QACF,SAAS,OAAO;AACd,iBAAO,OAAO;AAAA,YACZ,oBAAoB,MAAM,UAAU,KAAK,OAAO,KAAK,CAAC;AAAA,UACxD;AACA,iBAAO,MAAM,oBAAoB,MAAM,UAAU,KAAK,KAAc;AAAA,QACtE;AAAA,MACF;AAEA,WAAK,aAAa;AAAA,IACpB,SAAS,OAAO;AACd,aAAO,OAAO,KAAK,kBAAkB,OAAO,KAAK,CAAC,EAAE;AACpD,aAAO,MAAM,yBAAyB,KAAc;AAAA,IACtD;AAEA,WAAO;AAAA,EACT;AAAA;AAAA;AAAA;AAAA,EAKA,MAAc,0BACZ,OACwB;AACxB,QAAI;AACF,YAAM,WAAW,KAAK,yBAAyB,MAAM,QAAQ;AAG7D,UAAI,cAAc,MAAM,eAAe;AACvC,qBAAe;AAAA;AAAA;AAAA,cAAwB,MAAM,UAAU,MAAM,MAAM,GAAG;AAGtE,YAAM,SAAS,MAAM,QAAQ,MAAM,MAAM,IACrC,MAAM,SACL,MAAM,QACH,SAAS,CAAC;AAClB,YAAM,OAAO,OAAO,IAAI,CAAC,MAAM,EAAE,IAAI;AACrC,UAAI,KAAK,WAAW,EAAG,MAAK,KAAK,QAAQ;AAGzC,YAAM,SAAS,KAAK,UAAU,WAAW;AAAA,QACvC,OAAO,IAAI,MAAM,UAAU,KAAK,MAAM,KAAK;AAAA,QAC3C;AAAA,QACA;AAAA,QACA,SAAS;AAAA,QACT;AAAA,QACA,iBAAiB,MAAM,WAAW,MAAM,WAAW,KAAK;AAAA,MAC1D,CAAC;AAGD,YAAM,SAAS,KAAK,uBAAuB,MAAM,MAAM,IAAI;AAC3D,UAAI,WAAW,WAAW;AACxB,aAAK,UAAU;AAAA,UACb;AAAA,UACA;AAAA,UACA,2BAA2B,MAAM;AAAA,QACnC;AAAA,MACF;AAEA,aAAO;AAAA,IACT,SAAS,OAAO;AACd,aAAO;AAAA,QACL,2CAA2C,MAAM,UAAU,KAAK,OAAO,KAAK,CAAC;AAAA,MAC/E;AACA,aAAO;AAAA,IACT;AAAA,EACF;AAAA;AAAA;AAAA;AAAA,EAKQ,yBAAyB,UAAgC;AAC/D,YAAQ,UAAU;AAAA,MAChB,KAAK;AACH,eAAO;AAAA,MACT,KAAK;AACH,eAAO;AAAA,MACT,KAAK;AACH,eAAO;AAAA,MACT,KAAK;AACH,eAAO;AAAA,MACT;AACE,eAAO;AAAA,IACX;AAAA,EACF;AACF;AAKO,MAAM,sBAAkC;AAAA,EAC7C,SAAS;AAAA,EACT,WAAW;AAAA,EACX,UAAU;AAAA,EACV,oBAAoB;AAAA,EACpB,cAAc;AAAA;AAAA,EACd,cAAc;AAAA;AAAA,EACd,gBAAgB;AAAA;AAClB;",
6
6
  "names": []
7
7
  }
@@ -0,0 +1,200 @@
1
+ import { createHmac } from "crypto";
2
+ import { LinearSyncEngine } from "./sync.js";
3
+ import { LinearAuthManager } from "./auth.js";
4
+ import { logger } from "../../core/monitoring/logger.js";
5
+ class LinearWebhookHandler {
6
+ taskStore;
7
+ syncEngine = null;
8
+ webhookSecret;
9
+ constructor(taskStore, webhookSecret) {
10
+ this.taskStore = taskStore;
11
+ this.webhookSecret = webhookSecret;
12
+ if (process.env.LINEAR_API_KEY) {
13
+ const authManager = new LinearAuthManager();
14
+ this.syncEngine = new LinearSyncEngine(taskStore, authManager, {
15
+ enabled: true,
16
+ direction: "from_linear",
17
+ autoSync: false,
18
+ conflictResolution: "linear_wins"
19
+ });
20
+ }
21
+ }
22
+ /**
23
+ * Verify webhook signature
24
+ */
25
+ verifySignature(payload, signature) {
26
+ const hmac = createHmac("sha256", this.webhookSecret);
27
+ hmac.update(payload);
28
+ const expectedSignature = hmac.digest("hex");
29
+ return signature === expectedSignature;
30
+ }
31
+ /**
32
+ * Handle incoming webhook from Linear
33
+ */
34
+ async handleWebhook(req, res) {
35
+ try {
36
+ const rawBody = JSON.stringify(req.body);
37
+ const signature = req.headers["linear-signature"];
38
+ if (!this.verifySignature(rawBody, signature)) {
39
+ logger.error("Invalid webhook signature");
40
+ res.status(401).json({ error: "Invalid signature" });
41
+ return;
42
+ }
43
+ const payload = req.body;
44
+ if (payload.type !== "Issue") {
45
+ res.status(200).json({ message: "Ignored non-issue webhook" });
46
+ return;
47
+ }
48
+ switch (payload.action) {
49
+ case "create":
50
+ await this.handleIssueCreate(payload);
51
+ break;
52
+ case "update":
53
+ await this.handleIssueUpdate(payload);
54
+ break;
55
+ case "remove":
56
+ await this.handleIssueRemove(payload);
57
+ break;
58
+ default:
59
+ logger.warn(`Unknown webhook action: ${payload.action}`);
60
+ }
61
+ res.status(200).json({ message: "Webhook processed successfully" });
62
+ } catch (error) {
63
+ logger.error("Failed to process webhook:", error);
64
+ res.status(500).json({ error: "Failed to process webhook" });
65
+ }
66
+ }
67
+ /**
68
+ * Handle issue creation
69
+ */
70
+ async handleIssueCreate(payload) {
71
+ const issue = payload.data;
72
+ const existingTasks = this.taskStore.getActiveTasks();
73
+ const exists = existingTasks.some(
74
+ (t) => t.title.includes(issue.identifier) || t.external_refs?.linear === issue.id
75
+ );
76
+ if (exists) {
77
+ logger.info(`Task ${issue.identifier} already exists locally`);
78
+ return;
79
+ }
80
+ const taskId = this.taskStore.createTask({
81
+ title: `[${issue.identifier}] ${issue.title}`,
82
+ description: issue.description || "",
83
+ priority: this.mapLinearPriorityToLocal(issue.priority),
84
+ frameId: "linear-webhook",
85
+ tags: issue.labels?.map((l) => l.name) || ["linear"],
86
+ estimatedEffort: issue.estimate ? issue.estimate * 60 : void 0,
87
+ assignee: issue.assignee?.name
88
+ });
89
+ const status = this.mapLinearStateToLocalStatus(issue.state.type);
90
+ if (status !== "pending") {
91
+ this.taskStore.updateTaskStatus(
92
+ taskId,
93
+ status,
94
+ `Synced from Linear (${issue.state.name})`
95
+ );
96
+ }
97
+ await this.storeLinearMapping(taskId, issue.id, issue.identifier);
98
+ logger.info(`Created task ${taskId} from Linear issue ${issue.identifier}`);
99
+ }
100
+ /**
101
+ * Handle issue update
102
+ */
103
+ async handleIssueUpdate(payload) {
104
+ const issue = payload.data;
105
+ const tasks = this.taskStore.getActiveTasks();
106
+ const localTask = tasks.find(
107
+ (t) => t.title.includes(issue.identifier) || t.external_refs?.linear === issue.id
108
+ );
109
+ if (!localTask) {
110
+ await this.handleIssueCreate(payload);
111
+ return;
112
+ }
113
+ const newStatus = this.mapLinearStateToLocalStatus(issue.state.type);
114
+ if (newStatus !== localTask.status) {
115
+ this.taskStore.updateTaskStatus(
116
+ localTask.id,
117
+ newStatus,
118
+ `Updated from Linear (${issue.state.name})`
119
+ );
120
+ }
121
+ const newPriority = this.mapLinearPriorityToLocal(issue.priority);
122
+ if (newPriority !== localTask.priority) {
123
+ logger.info(
124
+ `Priority changed for ${issue.identifier}: ${localTask.priority} -> ${newPriority}`
125
+ );
126
+ }
127
+ logger.info(
128
+ `Updated task ${localTask.id} from Linear issue ${issue.identifier}`
129
+ );
130
+ }
131
+ /**
132
+ * Handle issue removal
133
+ */
134
+ async handleIssueRemove(payload) {
135
+ const issue = payload.data;
136
+ const tasks = this.taskStore.getActiveTasks();
137
+ const localTask = tasks.find(
138
+ (t) => t.title.includes(issue.identifier) || t.external_refs?.linear === issue.id
139
+ );
140
+ if (localTask) {
141
+ this.taskStore.updateTaskStatus(
142
+ localTask.id,
143
+ "cancelled",
144
+ `Removed in Linear`
145
+ );
146
+ logger.info(
147
+ `Cancelled task ${localTask.id} (Linear issue ${issue.identifier} was removed)`
148
+ );
149
+ }
150
+ }
151
+ /**
152
+ * Store Linear mapping for a task
153
+ */
154
+ async storeLinearMapping(taskId, linearId, linearIdentifier) {
155
+ logger.info(
156
+ `Mapped task ${taskId} to Linear ${linearIdentifier} (${linearId})`
157
+ );
158
+ }
159
+ /**
160
+ * Map Linear priority to local priority
161
+ */
162
+ mapLinearPriorityToLocal(priority) {
163
+ if (!priority) return "medium";
164
+ switch (priority) {
165
+ case 0:
166
+ return "urgent";
167
+ case 1:
168
+ return "high";
169
+ case 2:
170
+ return "medium";
171
+ case 3:
172
+ case 4:
173
+ return "low";
174
+ default:
175
+ return "medium";
176
+ }
177
+ }
178
+ /**
179
+ * Map Linear state to local status
180
+ */
181
+ mapLinearStateToLocalStatus(state) {
182
+ switch (state) {
183
+ case "backlog":
184
+ case "unstarted":
185
+ return "pending";
186
+ case "started":
187
+ return "in_progress";
188
+ case "completed":
189
+ return "completed";
190
+ case "cancelled":
191
+ return "cancelled";
192
+ default:
193
+ return "pending";
194
+ }
195
+ }
196
+ }
197
+ export {
198
+ LinearWebhookHandler
199
+ };
200
+ //# sourceMappingURL=webhook-handler.js.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../../../src/integrations/linear/webhook-handler.ts"],
4
+ "sourcesContent": ["/**\n * Linear Webhook Handler\n * Processes incoming webhooks from Linear to update local task store\n */\n\nimport { createHmac } from 'crypto';\nimport { PebblesTaskStore } from '../../features/tasks/pebbles-task-store.js';\nimport { LinearSyncEngine } from './sync.js';\nimport { LinearAuthManager } from './auth.js';\nimport { LinearClient } from './client.js';\nimport { logger } from '../../core/monitoring/logger.js';\nimport type { Request, Response } from 'express';\n\nexport interface LinearWebhookPayload {\n action: 'create' | 'update' | 'remove';\n createdAt: string;\n data: {\n id: string;\n identifier: string;\n title: string;\n description?: string;\n state: {\n id: string;\n name: string;\n type: 'backlog' | 'unstarted' | 'started' | 'completed' | 'cancelled';\n };\n priority?: number;\n estimate?: number;\n assignee?: {\n id: string;\n name: string;\n email: string;\n };\n labels?: Array<{ id: string; name: string }>;\n updatedAt: string;\n url: string;\n };\n type: 'Issue';\n organizationId: string;\n webhookId: string;\n}\n\nexport class LinearWebhookHandler {\n private taskStore: PebblesTaskStore;\n private syncEngine: LinearSyncEngine | null = null;\n private webhookSecret: string;\n\n constructor(taskStore: PebblesTaskStore, webhookSecret: string) {\n this.taskStore = taskStore;\n this.webhookSecret = webhookSecret;\n\n // Initialize sync engine if API key is available\n if (process.env.LINEAR_API_KEY) {\n const authManager = new LinearAuthManager();\n this.syncEngine = new LinearSyncEngine(taskStore, authManager, {\n enabled: true,\n direction: 'from_linear',\n autoSync: false,\n conflictResolution: 'linear_wins',\n });\n }\n }\n\n /**\n * Verify webhook signature\n */\n private verifySignature(payload: string, signature: string): boolean {\n const hmac = createHmac('sha256', this.webhookSecret);\n hmac.update(payload);\n const expectedSignature = hmac.digest('hex');\n return signature === expectedSignature;\n }\n\n /**\n * Handle incoming webhook from Linear\n */\n async handleWebhook(req: Request, res: Response): Promise<void> {\n try {\n // Get raw body for signature verification\n const rawBody = JSON.stringify(req.body);\n const signature = req.headers['linear-signature'] as string;\n\n // Verify signature\n if (!this.verifySignature(rawBody, signature)) {\n logger.error('Invalid webhook signature');\n res.status(401).json({ error: 'Invalid signature' });\n return;\n }\n\n const payload = req.body as LinearWebhookPayload;\n\n // Only process Issue webhooks\n if (payload.type !== 'Issue') {\n res.status(200).json({ message: 'Ignored non-issue webhook' });\n return;\n }\n\n // Process based on action\n switch (payload.action) {\n case 'create':\n await this.handleIssueCreate(payload);\n break;\n case 'update':\n await this.handleIssueUpdate(payload);\n break;\n case 'remove':\n await this.handleIssueRemove(payload);\n break;\n default:\n logger.warn(`Unknown webhook action: ${payload.action}`);\n }\n\n res.status(200).json({ message: 'Webhook processed successfully' });\n } catch (error) {\n logger.error('Failed to process webhook:', error as Error);\n res.status(500).json({ error: 'Failed to process webhook' });\n }\n }\n\n /**\n * Handle issue creation\n */\n private async handleIssueCreate(\n payload: LinearWebhookPayload\n ): Promise<void> {\n const issue = payload.data;\n\n // Check if task already exists locally\n const existingTasks = this.taskStore.getActiveTasks();\n const exists = existingTasks.some(\n (t) =>\n t.title.includes(issue.identifier) ||\n t.external_refs?.linear === issue.id\n );\n\n if (exists) {\n logger.info(`Task ${issue.identifier} already exists locally`);\n return;\n }\n\n // Create local task\n const taskId = this.taskStore.createTask({\n title: `[${issue.identifier}] ${issue.title}`,\n description: issue.description || '',\n priority: this.mapLinearPriorityToLocal(issue.priority),\n frameId: 'linear-webhook',\n tags: issue.labels?.map((l) => l.name) || ['linear'],\n estimatedEffort: issue.estimate ? issue.estimate * 60 : undefined,\n assignee: issue.assignee?.name,\n });\n\n // Update task status if not pending\n const status = this.mapLinearStateToLocalStatus(issue.state.type);\n if (status !== 'pending') {\n this.taskStore.updateTaskStatus(\n taskId,\n status,\n `Synced from Linear (${issue.state.name})`\n );\n }\n\n // Store Linear mapping\n await this.storeLinearMapping(taskId, issue.id, issue.identifier);\n\n logger.info(`Created task ${taskId} from Linear issue ${issue.identifier}`);\n }\n\n /**\n * Handle issue update\n */\n private async handleIssueUpdate(\n payload: LinearWebhookPayload\n ): Promise<void> {\n const issue = payload.data;\n\n // Find local task by Linear ID or identifier\n const tasks = this.taskStore.getActiveTasks();\n const localTask = tasks.find(\n (t) =>\n t.title.includes(issue.identifier) ||\n t.external_refs?.linear === issue.id\n );\n\n if (!localTask) {\n // Task doesn't exist locally, create it\n await this.handleIssueCreate(payload);\n return;\n }\n\n // Update task status\n const newStatus = this.mapLinearStateToLocalStatus(issue.state.type);\n if (newStatus !== localTask.status) {\n this.taskStore.updateTaskStatus(\n localTask.id,\n newStatus,\n `Updated from Linear (${issue.state.name})`\n );\n }\n\n // Update priority if changed\n const newPriority = this.mapLinearPriorityToLocal(issue.priority);\n if (newPriority !== localTask.priority) {\n // Note: Would need to add updateTaskPriority method to taskStore\n logger.info(\n `Priority changed for ${issue.identifier}: ${localTask.priority} -> ${newPriority}`\n );\n }\n\n logger.info(\n `Updated task ${localTask.id} from Linear issue ${issue.identifier}`\n );\n }\n\n /**\n * Handle issue removal\n */\n private async handleIssueRemove(\n payload: LinearWebhookPayload\n ): Promise<void> {\n const issue = payload.data;\n\n // Find and cancel local task\n const tasks = this.taskStore.getActiveTasks();\n const localTask = tasks.find(\n (t) =>\n t.title.includes(issue.identifier) ||\n t.external_refs?.linear === issue.id\n );\n\n if (localTask) {\n this.taskStore.updateTaskStatus(\n localTask.id,\n 'cancelled',\n `Removed in Linear`\n );\n logger.info(\n `Cancelled task ${localTask.id} (Linear issue ${issue.identifier} was removed)`\n );\n }\n }\n\n /**\n * Store Linear mapping for a task\n */\n private async storeLinearMapping(\n taskId: string,\n linearId: string,\n linearIdentifier: string\n ): Promise<void> {\n // This would update the linear-mappings.json file\n // For now, just log it\n logger.info(\n `Mapped task ${taskId} to Linear ${linearIdentifier} (${linearId})`\n );\n }\n\n /**\n * Map Linear priority to local priority\n */\n private mapLinearPriorityToLocal(\n priority?: number\n ): 'urgent' | 'high' | 'medium' | 'low' {\n if (!priority) return 'medium';\n switch (priority) {\n case 0:\n return 'urgent';\n case 1:\n return 'high';\n case 2:\n return 'medium';\n case 3:\n case 4:\n return 'low';\n default:\n return 'medium';\n }\n }\n\n /**\n * Map Linear state to local status\n */\n private mapLinearStateToLocalStatus(\n state: string\n ): 'pending' | 'in_progress' | 'completed' | 'cancelled' | 'blocked' {\n switch (state) {\n case 'backlog':\n case 'unstarted':\n return 'pending';\n case 'started':\n return 'in_progress';\n case 'completed':\n return 'completed';\n case 'cancelled':\n return 'cancelled';\n default:\n return 'pending';\n }\n }\n}\n"],
5
+ "mappings": "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",
6
+ "names": []
7
+ }