@stackmemoryai/stackmemory 0.2.9 → 0.3.0

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 (575) hide show
  1. package/dist/agents/core/agent-task-manager.js +512 -0
  2. package/dist/agents/core/agent-task-manager.js.map +7 -0
  3. package/dist/agents/verifiers/base-verifier.js +129 -0
  4. package/dist/agents/verifiers/base-verifier.js.map +7 -0
  5. package/dist/agents/verifiers/formatter-verifier.js +126 -0
  6. package/dist/agents/verifiers/formatter-verifier.js.map +7 -0
  7. package/dist/agents/verifiers/llm-judge.js +248 -0
  8. package/dist/agents/verifiers/llm-judge.js.map +7 -0
  9. package/dist/cli/__tests__/index.test.js +290 -0
  10. package/dist/cli/__tests__/index.test.js.map +7 -0
  11. package/dist/cli/auto-detect.js +317 -0
  12. package/dist/cli/auto-detect.js.map +7 -0
  13. package/dist/cli/browser-test.js +29 -0
  14. package/dist/cli/browser-test.js.map +7 -0
  15. package/dist/cli/claude-sm.js +369 -0
  16. package/dist/cli/claude-sm.js.map +7 -0
  17. package/dist/cli/codex-sm.js +283 -0
  18. package/dist/cli/codex-sm.js.map +7 -0
  19. package/dist/cli/commands/agent.js +286 -0
  20. package/dist/cli/commands/agent.js.map +7 -0
  21. package/dist/cli/commands/config.js +199 -0
  22. package/dist/cli/commands/config.js.map +7 -0
  23. package/dist/cli/commands/context.js +327 -0
  24. package/dist/cli/commands/context.js.map +7 -0
  25. package/dist/cli/commands/handoff.js +191 -0
  26. package/dist/cli/commands/handoff.js.map +7 -0
  27. package/dist/cli/commands/linear-test.js +115 -0
  28. package/dist/cli/commands/linear-test.js.map +7 -0
  29. package/dist/cli/commands/linear.js +378 -0
  30. package/dist/cli/commands/linear.js.map +7 -0
  31. package/dist/cli/commands/log.js +165 -0
  32. package/dist/cli/commands/log.js.map +7 -0
  33. package/dist/cli/commands/onboard.js +349 -0
  34. package/dist/cli/commands/onboard.js.map +7 -0
  35. package/dist/cli/commands/projects.js +195 -0
  36. package/dist/cli/commands/projects.js.map +7 -0
  37. package/dist/cli/commands/search.js +152 -0
  38. package/dist/cli/commands/search.js.map +7 -0
  39. package/dist/cli/commands/session.js +179 -0
  40. package/dist/cli/commands/session.js.map +7 -0
  41. package/dist/cli/commands/tasks.js +205 -0
  42. package/dist/cli/commands/tasks.js.map +7 -0
  43. package/dist/cli/commands/webhook.js +131 -0
  44. package/dist/cli/commands/webhook.js.map +7 -0
  45. package/dist/cli/commands/worktree.js +276 -0
  46. package/dist/cli/commands/worktree.js.map +7 -0
  47. package/dist/cli/index.js +953 -0
  48. package/dist/cli/index.js.map +7 -0
  49. package/dist/cli/utils/viewer.js +92 -0
  50. package/dist/cli/utils/viewer.js.map +7 -0
  51. package/dist/core/config/__tests__/config-manager.test.js +248 -0
  52. package/dist/core/config/__tests__/config-manager.test.js.map +7 -0
  53. package/dist/core/config/config-manager.js +368 -0
  54. package/dist/core/config/config-manager.js.map +7 -0
  55. package/dist/core/config/types.js +140 -0
  56. package/dist/core/config/types.js.map +7 -0
  57. package/dist/core/context/__tests__/frame-manager.test.js +879 -0
  58. package/dist/core/context/__tests__/frame-manager.test.js.map +7 -0
  59. package/dist/core/context/auto-context.js +72 -0
  60. package/dist/core/context/auto-context.js.map +7 -0
  61. package/dist/core/context/compaction-handler.js +326 -0
  62. package/dist/core/context/compaction-handler.js.map +7 -0
  63. package/dist/core/context/frame-database.js +376 -0
  64. package/dist/core/context/frame-database.js.map +7 -0
  65. package/dist/core/context/frame-digest.js +239 -0
  66. package/dist/core/context/frame-digest.js.map +7 -0
  67. package/dist/core/context/frame-manager.js +682 -0
  68. package/dist/core/context/frame-manager.js.map +7 -0
  69. package/dist/core/context/frame-stack.js +270 -0
  70. package/dist/core/context/frame-stack.js.map +7 -0
  71. package/dist/core/context/frame-types.js +1 -0
  72. package/dist/core/context/frame-types.js.map +7 -0
  73. package/dist/core/context/index.js +33 -0
  74. package/dist/core/context/index.js.map +7 -0
  75. package/dist/core/context/model-aware-compaction.js +619 -0
  76. package/dist/core/context/model-aware-compaction.js.map +7 -0
  77. package/dist/core/context/refactored-frame-manager.js +393 -0
  78. package/dist/core/context/refactored-frame-manager.js.map +7 -0
  79. package/dist/core/database/batch-operations.js +329 -0
  80. package/dist/core/database/batch-operations.js.map +7 -0
  81. package/dist/core/database/connection-pool.js +224 -0
  82. package/dist/core/database/connection-pool.js.map +7 -0
  83. package/dist/core/database/query-cache.js +284 -0
  84. package/dist/core/database/query-cache.js.map +7 -0
  85. package/dist/core/digest/__tests__/enhanced-hybrid-digest.test.js +379 -0
  86. package/dist/core/digest/__tests__/enhanced-hybrid-digest.test.js.map +7 -0
  87. package/dist/core/digest/__tests__/frame-digest-integration.test.js +230 -0
  88. package/dist/core/digest/__tests__/frame-digest-integration.test.js.map +7 -0
  89. package/dist/core/digest/enhanced-hybrid-digest.js +267 -0
  90. package/dist/core/digest/enhanced-hybrid-digest.js.map +7 -0
  91. package/dist/core/digest/frame-digest-integration.js +172 -0
  92. package/dist/core/digest/frame-digest-integration.js.map +7 -0
  93. package/dist/core/digest/hybrid-digest-generator.js +549 -0
  94. package/dist/core/digest/hybrid-digest-generator.js.map +7 -0
  95. package/dist/core/digest/index.js +5 -0
  96. package/dist/core/digest/index.js.map +7 -0
  97. package/dist/core/digest/types.js +21 -0
  98. package/dist/core/digest/types.js.map +7 -0
  99. package/dist/core/errors/__tests__/error-handling.test.js +270 -0
  100. package/dist/core/errors/__tests__/error-handling.test.js.map +7 -0
  101. package/dist/core/errors/index.js +239 -0
  102. package/dist/core/errors/index.js.map +7 -0
  103. package/dist/core/errors/recovery.js +258 -0
  104. package/dist/core/errors/recovery.js.map +7 -0
  105. package/dist/core/merge/__tests__/conflict-scenarios.test.js +414 -0
  106. package/dist/core/merge/__tests__/conflict-scenarios.test.js.map +7 -0
  107. package/dist/core/merge/conflict-detector.js +424 -0
  108. package/dist/core/merge/conflict-detector.js.map +7 -0
  109. package/dist/core/merge/index.js +5 -0
  110. package/dist/core/merge/index.js.map +7 -0
  111. package/dist/core/merge/resolution-engine.js +565 -0
  112. package/dist/core/merge/resolution-engine.js.map +7 -0
  113. package/dist/core/merge/stack-diff.js +528 -0
  114. package/dist/core/merge/stack-diff.js.map +7 -0
  115. package/dist/core/merge/types.js +1 -0
  116. package/dist/core/merge/types.js.map +7 -0
  117. package/dist/core/monitoring/error-handler.js +278 -0
  118. package/dist/core/monitoring/error-handler.js.map +7 -0
  119. package/dist/core/monitoring/logger.js +115 -0
  120. package/dist/core/monitoring/logger.js.map +7 -0
  121. package/dist/core/monitoring/metrics.js +157 -0
  122. package/dist/core/monitoring/metrics.js.map +7 -0
  123. package/dist/core/monitoring/progress-tracker.js +174 -0
  124. package/dist/core/monitoring/progress-tracker.js.map +7 -0
  125. package/dist/core/performance/context-cache.js +269 -0
  126. package/dist/core/performance/context-cache.js.map +7 -0
  127. package/dist/core/performance/index.js +7 -0
  128. package/dist/core/performance/index.js.map +7 -0
  129. package/dist/core/performance/lazy-context-loader.js +319 -0
  130. package/dist/core/performance/lazy-context-loader.js.map +7 -0
  131. package/dist/core/performance/monitor.js +217 -0
  132. package/dist/core/performance/monitor.js.map +7 -0
  133. package/dist/core/performance/optimized-frame-context.js +326 -0
  134. package/dist/core/performance/optimized-frame-context.js.map +7 -0
  135. package/dist/core/performance/performance-benchmark.js +269 -0
  136. package/dist/core/performance/performance-benchmark.js.map +7 -0
  137. package/dist/core/performance/performance-profiler.js +318 -0
  138. package/dist/core/performance/performance-profiler.js.map +7 -0
  139. package/dist/core/performance/streaming-jsonl-parser.js +187 -0
  140. package/dist/core/performance/streaming-jsonl-parser.js.map +7 -0
  141. package/dist/core/persistence/postgres-adapter.js +345 -0
  142. package/dist/core/persistence/postgres-adapter.js.map +7 -0
  143. package/dist/core/projects/project-manager.js +699 -0
  144. package/dist/core/projects/project-manager.js.map +7 -0
  145. package/dist/core/query/__tests__/query-parser.test.js +301 -0
  146. package/dist/core/query/__tests__/query-parser.test.js.map +7 -0
  147. package/dist/core/query/__tests__/query-templates.test.js +210 -0
  148. package/dist/core/query/__tests__/query-templates.test.js.map +7 -0
  149. package/dist/core/query/query-parser.js +366 -0
  150. package/dist/core/query/query-parser.js.map +7 -0
  151. package/dist/core/query/query-templates.js +317 -0
  152. package/dist/core/query/query-templates.js.map +7 -0
  153. package/dist/core/retrieval/index.js +4 -0
  154. package/dist/core/retrieval/index.js.map +7 -0
  155. package/dist/core/retrieval/llm-context-retrieval.js +577 -0
  156. package/dist/core/retrieval/llm-context-retrieval.js.map +7 -0
  157. package/dist/core/retrieval/summary-generator.js +585 -0
  158. package/dist/core/retrieval/summary-generator.js.map +7 -0
  159. package/dist/core/retrieval/types.js +17 -0
  160. package/dist/core/retrieval/types.js.map +7 -0
  161. package/dist/core/session/index.js +11 -0
  162. package/dist/core/session/index.js.map +7 -0
  163. package/dist/core/session/session-manager.js +297 -0
  164. package/dist/core/session/session-manager.js.map +7 -0
  165. package/dist/core/trace/cli-trace-wrapper.js +110 -0
  166. package/dist/core/trace/cli-trace-wrapper.js.map +7 -0
  167. package/dist/core/trace/db-trace-wrapper.js +215 -0
  168. package/dist/core/trace/db-trace-wrapper.js.map +7 -0
  169. package/dist/core/trace/debug-trace.js +385 -0
  170. package/dist/core/trace/debug-trace.js.map +7 -0
  171. package/dist/core/trace/index.js +158 -0
  172. package/dist/core/trace/index.js.map +7 -0
  173. package/dist/core/trace/linear-api-wrapper.js +169 -0
  174. package/dist/core/trace/linear-api-wrapper.js.map +7 -0
  175. package/dist/core/trace/trace-demo.js +135 -0
  176. package/dist/core/trace/trace-demo.js.map +7 -0
  177. package/dist/core/trace/trace-detector.demo.js +138 -0
  178. package/dist/core/trace/trace-detector.demo.js.map +7 -0
  179. package/dist/core/trace/trace-detector.js +386 -0
  180. package/dist/core/trace/trace-detector.js.map +7 -0
  181. package/dist/core/trace/trace-detector.test.js +401 -0
  182. package/dist/core/trace/trace-detector.test.js.map +7 -0
  183. package/dist/core/trace/trace-store.js +341 -0
  184. package/dist/core/trace/trace-store.js.map +7 -0
  185. package/dist/core/trace/types.js +73 -0
  186. package/dist/core/trace/types.js.map +7 -0
  187. package/dist/core/types.js +1 -0
  188. package/dist/core/types.js.map +7 -0
  189. package/dist/core/utils/update-checker.js +214 -0
  190. package/dist/core/utils/update-checker.js.map +7 -0
  191. package/dist/core/worktree/worktree-manager.js +450 -0
  192. package/dist/core/worktree/worktree-manager.js.map +7 -0
  193. package/dist/features/analytics/api/analytics-api.js +283 -0
  194. package/dist/features/analytics/api/analytics-api.js.map +7 -0
  195. package/dist/features/analytics/core/analytics-service.js +267 -0
  196. package/dist/features/analytics/core/analytics-service.js.map +7 -0
  197. package/dist/features/analytics/index.js +14 -0
  198. package/dist/features/analytics/index.js.map +7 -0
  199. package/dist/features/analytics/queries/metrics-queries.js +273 -0
  200. package/dist/features/analytics/queries/metrics-queries.js.map +7 -0
  201. package/dist/features/analytics/types/metrics.js +1 -0
  202. package/dist/features/analytics/types/metrics.js.map +7 -0
  203. package/dist/features/browser/browser-mcp.js +488 -0
  204. package/dist/features/browser/browser-mcp.js.map +7 -0
  205. package/dist/features/tasks/__tests__/pebbles-task-store.test.js +747 -0
  206. package/dist/features/tasks/__tests__/pebbles-task-store.test.js.map +7 -0
  207. package/dist/features/tasks/pebbles-task-store.js +647 -0
  208. package/dist/features/tasks/pebbles-task-store.js.map +7 -0
  209. package/dist/features/tasks/task-aware-context.js +406 -0
  210. package/dist/features/tasks/task-aware-context.js.map +7 -0
  211. package/dist/index.js +21 -0
  212. package/dist/index.js.map +7 -0
  213. package/dist/integrations/linear/__tests__/auth.test.js +558 -0
  214. package/dist/integrations/linear/__tests__/auth.test.js.map +7 -0
  215. package/dist/integrations/linear/__tests__/sync-service.test.js +760 -0
  216. package/dist/integrations/linear/__tests__/sync-service.test.js.map +7 -0
  217. package/dist/integrations/linear/auth.js +308 -0
  218. package/dist/integrations/linear/auth.js.map +7 -0
  219. package/dist/integrations/linear/auto-sync.js +244 -0
  220. package/dist/integrations/linear/auto-sync.js.map +7 -0
  221. package/dist/integrations/linear/client.js +448 -0
  222. package/dist/integrations/linear/client.js.map +7 -0
  223. package/dist/integrations/linear/config.js +115 -0
  224. package/dist/integrations/linear/config.js.map +7 -0
  225. package/dist/integrations/linear/sync-manager.js +233 -0
  226. package/dist/integrations/linear/sync-manager.js.map +7 -0
  227. package/dist/integrations/linear/sync-service.js +214 -0
  228. package/dist/integrations/linear/sync-service.js.map +7 -0
  229. package/dist/integrations/linear/sync.js +565 -0
  230. package/dist/integrations/linear/sync.js.map +7 -0
  231. package/dist/integrations/linear/types.js +1 -0
  232. package/dist/integrations/linear/types.js.map +7 -0
  233. package/dist/integrations/linear/webhook-server.js +204 -0
  234. package/dist/integrations/linear/webhook-server.js.map +7 -0
  235. package/dist/integrations/linear/webhook.js +269 -0
  236. package/dist/integrations/linear/webhook.js.map +7 -0
  237. package/dist/integrations/mcp/__tests__/server.test.js +798 -0
  238. package/dist/integrations/mcp/__tests__/server.test.js.map +7 -0
  239. package/dist/integrations/mcp/handlers/context-handlers.js +253 -0
  240. package/dist/integrations/mcp/handlers/context-handlers.js.map +7 -0
  241. package/dist/integrations/mcp/handlers/index.js +134 -0
  242. package/dist/integrations/mcp/handlers/index.js.map +7 -0
  243. package/dist/integrations/mcp/handlers/linear-handlers.js +243 -0
  244. package/dist/integrations/mcp/handlers/linear-handlers.js.map +7 -0
  245. package/dist/integrations/mcp/handlers/task-handlers.js +235 -0
  246. package/dist/integrations/mcp/handlers/task-handlers.js.map +7 -0
  247. package/dist/integrations/mcp/handlers/trace-handlers.js +304 -0
  248. package/dist/integrations/mcp/handlers/trace-handlers.js.map +7 -0
  249. package/dist/integrations/mcp/index.js +19 -0
  250. package/dist/integrations/mcp/index.js.map +7 -0
  251. package/dist/integrations/mcp/refactored-server.js +331 -0
  252. package/dist/integrations/mcp/refactored-server.js.map +7 -0
  253. package/dist/integrations/mcp/server.js +1621 -0
  254. package/dist/integrations/mcp/server.js.map +7 -0
  255. package/dist/integrations/mcp/tool-definitions.js +562 -0
  256. package/dist/integrations/mcp/tool-definitions.js.map +7 -0
  257. package/dist/integrations/mcp/trace-test.js +44 -0
  258. package/dist/integrations/mcp/trace-test.js.map +7 -0
  259. package/dist/integrations/pg-aiguide/embedding-provider.js +174 -0
  260. package/dist/integrations/pg-aiguide/embedding-provider.js.map +7 -0
  261. package/dist/integrations/pg-aiguide/semantic-search.js +183 -0
  262. package/dist/integrations/pg-aiguide/semantic-search.js.map +7 -0
  263. package/dist/integrations/pg-aiguide/timescale-analytics.js +220 -0
  264. package/dist/integrations/pg-aiguide/timescale-analytics.js.map +7 -0
  265. package/dist/mcp/stackmemory-mcp-server.js +550 -0
  266. package/dist/mcp/stackmemory-mcp-server.js.map +7 -0
  267. package/dist/middleware/exponential-rate-limiter.js +285 -0
  268. package/dist/middleware/exponential-rate-limiter.js.map +7 -0
  269. package/dist/models/user.model.js +351 -0
  270. package/dist/models/user.model.js.map +7 -0
  271. package/dist/scripts/benchmark-performance.d.ts +7 -0
  272. package/dist/scripts/benchmark-performance.d.ts.map +1 -0
  273. package/dist/scripts/benchmark-performance.js +44 -0
  274. package/dist/scripts/benchmark-performance.js.map +1 -0
  275. package/dist/scripts/cleanup-duplicate-tasks.d.ts +12 -0
  276. package/dist/scripts/cleanup-duplicate-tasks.d.ts.map +1 -0
  277. package/dist/scripts/cleanup-duplicate-tasks.js +215 -0
  278. package/dist/scripts/cleanup-duplicate-tasks.js.map +1 -0
  279. package/dist/servers/production/auth-middleware.js +513 -0
  280. package/dist/servers/production/auth-middleware.js.map +7 -0
  281. package/dist/servers/railway/index.js +390 -0
  282. package/dist/servers/railway/index.js.map +7 -0
  283. package/dist/services/config-service.js +62 -0
  284. package/dist/services/config-service.js.map +7 -0
  285. package/dist/services/context-service.js +191 -0
  286. package/dist/services/context-service.js.map +7 -0
  287. package/dist/src/agents/core/agent-task-manager.d.ts +154 -0
  288. package/dist/src/agents/core/agent-task-manager.d.ts.map +1 -0
  289. package/dist/src/agents/core/agent-task-manager.js +504 -0
  290. package/dist/src/agents/core/agent-task-manager.js.map +1 -0
  291. package/dist/src/agents/verifiers/base-verifier.d.ts +112 -0
  292. package/dist/src/agents/verifiers/base-verifier.d.ts.map +1 -0
  293. package/dist/src/agents/verifiers/base-verifier.js +130 -0
  294. package/dist/src/agents/verifiers/base-verifier.js.map +1 -0
  295. package/dist/src/agents/verifiers/formatter-verifier.d.ts +14 -0
  296. package/dist/src/agents/verifiers/formatter-verifier.d.ts.map +1 -0
  297. package/dist/src/agents/verifiers/formatter-verifier.js +107 -0
  298. package/dist/src/agents/verifiers/formatter-verifier.js.map +1 -0
  299. package/dist/src/agents/verifiers/llm-judge.d.ts +46 -0
  300. package/dist/src/agents/verifiers/llm-judge.d.ts.map +1 -0
  301. package/dist/src/agents/verifiers/llm-judge.js +248 -0
  302. package/dist/src/agents/verifiers/llm-judge.js.map +1 -0
  303. package/dist/src/cli/claude-sm.js +55 -0
  304. package/dist/src/cli/claude-sm.js.map +1 -1
  305. package/dist/src/cli/commands/agent.d.ts +9 -0
  306. package/dist/src/cli/commands/agent.d.ts.map +1 -0
  307. package/dist/src/cli/commands/agent.js +303 -0
  308. package/dist/src/cli/commands/agent.js.map +1 -0
  309. package/dist/src/cli/commands/handoff.d.ts +6 -0
  310. package/dist/src/cli/commands/handoff.d.ts.map +1 -0
  311. package/dist/src/cli/commands/handoff.js +212 -0
  312. package/dist/src/cli/commands/handoff.js.map +1 -0
  313. package/dist/src/cli/index.d.ts.map +1 -1
  314. package/dist/src/cli/index.js +4 -0
  315. package/dist/src/cli/index.js.map +1 -1
  316. package/dist/src/core/context/frame-database.d.ts +59 -0
  317. package/dist/src/core/context/frame-database.d.ts.map +1 -0
  318. package/dist/src/core/context/frame-database.js +333 -0
  319. package/dist/src/core/context/frame-database.js.map +1 -0
  320. package/dist/src/core/context/frame-digest.d.ts +59 -0
  321. package/dist/src/core/context/frame-digest.d.ts.map +1 -0
  322. package/dist/src/core/context/frame-digest.js +264 -0
  323. package/dist/src/core/context/frame-digest.js.map +1 -0
  324. package/dist/src/core/context/frame-manager.d.ts +2 -0
  325. package/dist/src/core/context/frame-manager.d.ts.map +1 -1
  326. package/dist/src/core/context/frame-manager.js +7 -0
  327. package/dist/src/core/context/frame-manager.js.map +1 -1
  328. package/dist/src/core/context/frame-stack.d.ts +85 -0
  329. package/dist/src/core/context/frame-stack.d.ts.map +1 -0
  330. package/dist/src/core/context/frame-stack.js +287 -0
  331. package/dist/src/core/context/frame-stack.js.map +1 -0
  332. package/dist/src/core/context/frame-types.d.ts +67 -0
  333. package/dist/src/core/context/frame-types.d.ts.map +1 -0
  334. package/dist/src/core/context/frame-types.js +6 -0
  335. package/dist/src/core/context/frame-types.js.map +1 -0
  336. package/dist/src/core/context/index.d.ts +11 -0
  337. package/dist/src/core/context/index.d.ts.map +1 -0
  338. package/dist/src/core/context/index.js +14 -0
  339. package/dist/src/core/context/index.js.map +1 -0
  340. package/dist/src/core/context/refactored-frame-manager.d.ts +99 -0
  341. package/dist/src/core/context/refactored-frame-manager.d.ts.map +1 -0
  342. package/dist/src/core/context/refactored-frame-manager.js +340 -0
  343. package/dist/src/core/context/refactored-frame-manager.js.map +1 -0
  344. package/dist/src/core/database/batch-operations.d.ts +118 -0
  345. package/dist/src/core/database/batch-operations.d.ts.map +1 -0
  346. package/dist/src/core/database/batch-operations.js +339 -0
  347. package/dist/src/core/database/batch-operations.js.map +1 -0
  348. package/dist/src/core/database/connection-pool.d.ts +79 -0
  349. package/dist/src/core/database/connection-pool.d.ts.map +1 -0
  350. package/dist/src/core/database/connection-pool.js +236 -0
  351. package/dist/src/core/database/connection-pool.js.map +1 -0
  352. package/dist/src/core/database/query-cache.d.ts +135 -0
  353. package/dist/src/core/database/query-cache.d.ts.map +1 -0
  354. package/dist/src/core/database/query-cache.js +294 -0
  355. package/dist/src/core/database/query-cache.js.map +1 -0
  356. package/dist/src/core/digest/enhanced-hybrid-digest.d.ts +125 -0
  357. package/dist/src/core/digest/enhanced-hybrid-digest.d.ts.map +1 -0
  358. package/dist/src/core/digest/enhanced-hybrid-digest.js +282 -0
  359. package/dist/src/core/digest/enhanced-hybrid-digest.js.map +1 -0
  360. package/dist/src/core/digest/frame-digest-integration.d.ts +67 -0
  361. package/dist/src/core/digest/frame-digest-integration.d.ts.map +1 -0
  362. package/dist/src/core/digest/frame-digest-integration.js +198 -0
  363. package/dist/src/core/digest/frame-digest-integration.js.map +1 -0
  364. package/dist/src/core/digest/hybrid-digest-generator.d.ts +3 -3
  365. package/dist/src/core/digest/hybrid-digest-generator.d.ts.map +1 -1
  366. package/dist/src/core/digest/hybrid-digest-generator.js.map +1 -1
  367. package/dist/src/core/digest/index.d.ts +3 -1
  368. package/dist/src/core/digest/index.d.ts.map +1 -1
  369. package/dist/src/core/digest/index.js +3 -1
  370. package/dist/src/core/digest/index.js.map +1 -1
  371. package/dist/src/core/errors/index.d.ts +13 -5
  372. package/dist/src/core/errors/index.d.ts.map +1 -1
  373. package/dist/src/core/errors/index.js +13 -5
  374. package/dist/src/core/errors/index.js.map +1 -1
  375. package/dist/src/core/merge/conflict-detector.d.ts +122 -0
  376. package/dist/src/core/merge/conflict-detector.d.ts.map +1 -0
  377. package/dist/src/core/merge/conflict-detector.js +468 -0
  378. package/dist/src/core/merge/conflict-detector.js.map +1 -0
  379. package/dist/src/core/merge/index.d.ts +9 -0
  380. package/dist/src/core/merge/index.d.ts.map +1 -0
  381. package/dist/src/core/merge/index.js +9 -0
  382. package/dist/src/core/merge/index.js.map +1 -0
  383. package/dist/src/core/merge/resolution-engine.d.ts +120 -0
  384. package/dist/src/core/merge/resolution-engine.d.ts.map +1 -0
  385. package/dist/src/core/merge/resolution-engine.js +573 -0
  386. package/dist/src/core/merge/resolution-engine.js.map +1 -0
  387. package/dist/src/core/merge/stack-diff.d.ts +97 -0
  388. package/dist/src/core/merge/stack-diff.d.ts.map +1 -0
  389. package/dist/src/core/merge/stack-diff.js +516 -0
  390. package/dist/src/core/merge/stack-diff.js.map +1 -0
  391. package/dist/src/core/merge/types.d.ts +110 -0
  392. package/dist/src/core/merge/types.d.ts.map +1 -0
  393. package/dist/src/core/merge/types.js +6 -0
  394. package/dist/src/core/merge/types.js.map +1 -0
  395. package/dist/src/core/performance/context-cache.d.ts +109 -0
  396. package/dist/src/core/performance/context-cache.d.ts.map +1 -0
  397. package/dist/src/core/performance/context-cache.js +280 -0
  398. package/dist/src/core/performance/context-cache.js.map +1 -0
  399. package/dist/src/core/performance/index.d.ts +3 -0
  400. package/dist/src/core/performance/index.d.ts.map +1 -0
  401. package/dist/src/core/performance/index.js +3 -0
  402. package/dist/src/core/performance/index.js.map +1 -0
  403. package/dist/src/core/performance/lazy-context-loader.d.ts +93 -0
  404. package/dist/src/core/performance/lazy-context-loader.d.ts.map +1 -0
  405. package/dist/src/core/performance/lazy-context-loader.js +332 -0
  406. package/dist/src/core/performance/lazy-context-loader.js.map +1 -0
  407. package/dist/src/core/performance/monitor.d.ts +48 -0
  408. package/dist/src/core/performance/monitor.d.ts.map +1 -0
  409. package/dist/src/core/performance/monitor.js +226 -0
  410. package/dist/src/core/performance/monitor.js.map +1 -0
  411. package/dist/src/core/performance/optimized-frame-context.d.ts +74 -0
  412. package/dist/src/core/performance/optimized-frame-context.d.ts.map +1 -0
  413. package/dist/src/core/performance/optimized-frame-context.js +330 -0
  414. package/dist/src/core/performance/optimized-frame-context.js.map +1 -0
  415. package/dist/src/core/performance/performance-benchmark.d.ts +50 -0
  416. package/dist/src/core/performance/performance-benchmark.d.ts.map +1 -0
  417. package/dist/src/core/performance/performance-benchmark.js +290 -0
  418. package/dist/src/core/performance/performance-benchmark.js.map +1 -0
  419. package/dist/src/core/performance/performance-profiler.d.ts +151 -0
  420. package/dist/src/core/performance/performance-profiler.d.ts.map +1 -0
  421. package/dist/src/core/performance/performance-profiler.js +346 -0
  422. package/dist/src/core/performance/performance-profiler.js.map +1 -0
  423. package/dist/src/core/performance/streaming-jsonl-parser.d.ts +41 -0
  424. package/dist/src/core/performance/streaming-jsonl-parser.d.ts.map +1 -0
  425. package/dist/src/core/performance/streaming-jsonl-parser.js +193 -0
  426. package/dist/src/core/performance/streaming-jsonl-parser.js.map +1 -0
  427. package/dist/src/core/persistence/postgres-adapter.d.ts.map +1 -1
  428. package/dist/src/core/persistence/postgres-adapter.js +18 -4
  429. package/dist/src/core/persistence/postgres-adapter.js.map +1 -1
  430. package/dist/src/core/query/query-parser.d.ts +5 -0
  431. package/dist/src/core/query/query-parser.d.ts.map +1 -1
  432. package/dist/src/core/query/query-parser.js +86 -18
  433. package/dist/src/core/query/query-parser.js.map +1 -1
  434. package/dist/src/core/query/query-templates.d.ts +44 -0
  435. package/dist/src/core/query/query-templates.d.ts.map +1 -0
  436. package/dist/src/core/query/query-templates.js +326 -0
  437. package/dist/src/core/query/query-templates.js.map +1 -0
  438. package/dist/src/core/retrieval/llm-context-retrieval.d.ts +5 -3
  439. package/dist/src/core/retrieval/llm-context-retrieval.d.ts.map +1 -1
  440. package/dist/src/core/retrieval/llm-context-retrieval.js +73 -21
  441. package/dist/src/core/retrieval/llm-context-retrieval.js.map +1 -1
  442. package/dist/src/core/trace/cli-trace-wrapper.d.ts +23 -0
  443. package/dist/src/core/trace/cli-trace-wrapper.d.ts.map +1 -0
  444. package/dist/src/core/trace/cli-trace-wrapper.js +141 -0
  445. package/dist/src/core/trace/cli-trace-wrapper.js.map +1 -0
  446. package/dist/src/core/trace/db-trace-wrapper.d.ts +36 -0
  447. package/dist/src/core/trace/db-trace-wrapper.d.ts.map +1 -0
  448. package/dist/src/core/trace/db-trace-wrapper.js +252 -0
  449. package/dist/src/core/trace/db-trace-wrapper.js.map +1 -0
  450. package/dist/src/core/trace/debug-trace.d.ts +84 -0
  451. package/dist/src/core/trace/debug-trace.d.ts.map +1 -0
  452. package/dist/src/core/trace/debug-trace.js +402 -0
  453. package/dist/src/core/trace/debug-trace.js.map +1 -0
  454. package/dist/src/core/trace/error-test.d.ts +6 -0
  455. package/dist/src/core/trace/error-test.d.ts.map +1 -0
  456. package/dist/src/core/trace/error-test.js +128 -0
  457. package/dist/src/core/trace/error-test.js.map +1 -0
  458. package/dist/src/core/trace/index.d.ts +25 -0
  459. package/dist/src/core/trace/index.d.ts.map +1 -0
  460. package/dist/src/core/trace/index.js +121 -0
  461. package/dist/src/core/trace/index.js.map +1 -0
  462. package/dist/src/core/trace/linear-api-wrapper.d.ts +17 -0
  463. package/dist/src/core/trace/linear-api-wrapper.d.ts.map +1 -0
  464. package/dist/src/core/trace/linear-api-wrapper.js +205 -0
  465. package/dist/src/core/trace/linear-api-wrapper.js.map +1 -0
  466. package/dist/src/core/trace/performance-test.d.ts +6 -0
  467. package/dist/src/core/trace/performance-test.d.ts.map +1 -0
  468. package/dist/src/core/trace/performance-test.js +111 -0
  469. package/dist/src/core/trace/performance-test.js.map +1 -0
  470. package/dist/src/core/trace/trace-demo.d.ts +8 -0
  471. package/dist/src/core/trace/trace-demo.d.ts.map +1 -0
  472. package/dist/src/core/trace/trace-demo.js +154 -0
  473. package/dist/src/core/trace/trace-demo.js.map +1 -0
  474. package/dist/src/core/trace/trace-detector.d.ts +2 -2
  475. package/dist/src/core/trace/trace-detector.d.ts.map +1 -1
  476. package/dist/src/core/trace/trace-detector.demo.js +1 -1
  477. package/dist/src/core/trace/trace-detector.demo.js.map +1 -1
  478. package/dist/src/core/trace/trace-detector.js +3 -3
  479. package/dist/src/core/trace/trace-detector.js.map +1 -1
  480. package/dist/src/features/tasks/pebbles-task-store.d.ts +9 -2
  481. package/dist/src/features/tasks/pebbles-task-store.d.ts.map +1 -1
  482. package/dist/src/features/tasks/pebbles-task-store.js +97 -18
  483. package/dist/src/features/tasks/pebbles-task-store.js.map +1 -1
  484. package/dist/src/integrations/linear/auth.d.ts.map +1 -1
  485. package/dist/src/integrations/linear/auth.js.map +1 -1
  486. package/dist/src/integrations/linear/client.d.ts +15 -1
  487. package/dist/src/integrations/linear/client.d.ts.map +1 -1
  488. package/dist/src/integrations/linear/client.js +85 -3
  489. package/dist/src/integrations/linear/client.js.map +1 -1
  490. package/dist/src/integrations/linear/sync-manager.d.ts +2 -0
  491. package/dist/src/integrations/linear/sync-manager.d.ts.map +1 -1
  492. package/dist/src/integrations/linear/sync-manager.js +16 -4
  493. package/dist/src/integrations/linear/sync-manager.js.map +1 -1
  494. package/dist/src/integrations/linear/sync-service.d.ts +23 -2
  495. package/dist/src/integrations/linear/sync-service.d.ts.map +1 -1
  496. package/dist/src/integrations/linear/sync-service.js +44 -25
  497. package/dist/src/integrations/linear/sync-service.js.map +1 -1
  498. package/dist/src/integrations/linear/sync.d.ts +6 -0
  499. package/dist/src/integrations/linear/sync.d.ts.map +1 -1
  500. package/dist/src/integrations/linear/sync.js +27 -2
  501. package/dist/src/integrations/linear/sync.js.map +1 -1
  502. package/dist/src/integrations/linear/types.d.ts +16 -1
  503. package/dist/src/integrations/linear/types.d.ts.map +1 -1
  504. package/dist/src/integrations/linear/webhook-server.d.ts.map +1 -1
  505. package/dist/src/integrations/linear/webhook-server.js +10 -8
  506. package/dist/src/integrations/linear/webhook-server.js.map +1 -1
  507. package/dist/src/integrations/linear/webhook.d.ts +13 -0
  508. package/dist/src/integrations/linear/webhook.d.ts.map +1 -1
  509. package/dist/src/integrations/linear/webhook.js +101 -14
  510. package/dist/src/integrations/linear/webhook.js.map +1 -1
  511. package/dist/src/integrations/mcp/handlers/context-handlers.d.ts +39 -0
  512. package/dist/src/integrations/mcp/handlers/context-handlers.d.ts.map +1 -0
  513. package/dist/src/integrations/mcp/handlers/context-handlers.js +266 -0
  514. package/dist/src/integrations/mcp/handlers/context-handlers.js.map +1 -0
  515. package/dist/src/integrations/mcp/handlers/index.d.ts +37 -0
  516. package/dist/src/integrations/mcp/handlers/index.d.ts.map +1 -0
  517. package/dist/src/integrations/mcp/handlers/index.js +134 -0
  518. package/dist/src/integrations/mcp/handlers/index.js.map +1 -0
  519. package/dist/src/integrations/mcp/handlers/linear-handlers.d.ts +33 -0
  520. package/dist/src/integrations/mcp/handlers/linear-handlers.d.ts.map +1 -0
  521. package/dist/src/integrations/mcp/handlers/linear-handlers.js +251 -0
  522. package/dist/src/integrations/mcp/handlers/linear-handlers.js.map +1 -0
  523. package/dist/src/integrations/mcp/handlers/task-handlers.d.ts +42 -0
  524. package/dist/src/integrations/mcp/handlers/task-handlers.d.ts.map +1 -0
  525. package/dist/src/integrations/mcp/handlers/task-handlers.js +238 -0
  526. package/dist/src/integrations/mcp/handlers/task-handlers.js.map +1 -0
  527. package/dist/src/integrations/mcp/handlers/trace-handlers.d.ts +41 -0
  528. package/dist/src/integrations/mcp/handlers/trace-handlers.d.ts.map +1 -0
  529. package/dist/src/integrations/mcp/handlers/trace-handlers.js +298 -0
  530. package/dist/src/integrations/mcp/handlers/trace-handlers.js.map +1 -0
  531. package/dist/src/integrations/mcp/index.d.ts +13 -0
  532. package/dist/src/integrations/mcp/index.d.ts.map +1 -0
  533. package/dist/src/integrations/mcp/index.js +17 -0
  534. package/dist/src/integrations/mcp/index.js.map +1 -0
  535. package/dist/src/integrations/mcp/refactored-server.d.ts +76 -0
  536. package/dist/src/integrations/mcp/refactored-server.d.ts.map +1 -0
  537. package/dist/src/integrations/mcp/refactored-server.js +351 -0
  538. package/dist/src/integrations/mcp/refactored-server.js.map +1 -0
  539. package/dist/src/integrations/mcp/tool-definitions.d.ts +44 -0
  540. package/dist/src/integrations/mcp/tool-definitions.d.ts.map +1 -0
  541. package/dist/src/integrations/mcp/tool-definitions.js +563 -0
  542. package/dist/src/integrations/mcp/tool-definitions.js.map +1 -0
  543. package/dist/src/integrations/pg-aiguide/semantic-search.d.ts.map +1 -1
  544. package/dist/src/integrations/pg-aiguide/semantic-search.js +43 -21
  545. package/dist/src/integrations/pg-aiguide/semantic-search.js.map +1 -1
  546. package/dist/src/mcp/stackmemory-mcp-server.d.ts +9 -0
  547. package/dist/src/mcp/stackmemory-mcp-server.d.ts.map +1 -0
  548. package/dist/src/mcp/stackmemory-mcp-server.js +519 -0
  549. package/dist/src/mcp/stackmemory-mcp-server.js.map +1 -0
  550. package/dist/src/middleware/exponential-rate-limiter.d.ts +78 -0
  551. package/dist/src/middleware/exponential-rate-limiter.d.ts.map +1 -0
  552. package/dist/src/middleware/exponential-rate-limiter.js +293 -0
  553. package/dist/src/middleware/exponential-rate-limiter.js.map +1 -0
  554. package/dist/src/models/user.model.d.ts +8 -1
  555. package/dist/src/models/user.model.d.ts.map +1 -1
  556. package/dist/src/models/user.model.js +62 -14
  557. package/dist/src/models/user.model.js.map +1 -1
  558. package/dist/src/servers/production/auth-middleware.d.ts +5 -2
  559. package/dist/src/servers/production/auth-middleware.d.ts.map +1 -1
  560. package/dist/src/servers/production/auth-middleware.js +71 -34
  561. package/dist/src/servers/production/auth-middleware.js.map +1 -1
  562. package/dist/src/services/context-service.d.ts.map +1 -1
  563. package/dist/src/services/context-service.js +86 -1
  564. package/dist/src/services/context-service.js.map +1 -1
  565. package/dist/src/validation/schemas.d.ts +633 -0
  566. package/dist/src/validation/schemas.d.ts.map +1 -0
  567. package/dist/src/validation/schemas.js +347 -0
  568. package/dist/src/validation/schemas.js.map +1 -0
  569. package/dist/types/task.js +1 -0
  570. package/dist/types/task.js.map +7 -0
  571. package/dist/utils/logger.js +52 -0
  572. package/dist/utils/logger.js.map +7 -0
  573. package/dist/validation/schemas.js +218 -0
  574. package/dist/validation/schemas.js.map +7 -0
  575. package/package.json +7 -3
@@ -0,0 +1,214 @@
1
+ import { execSync } from "child_process";
2
+ import { existsSync, readFileSync, writeFileSync, mkdirSync } from "fs";
3
+ import { join } from "path";
4
+ import { homedir } from "os";
5
+ import { logger } from "../monitoring/logger.js";
6
+ import {
7
+ ErrorCode,
8
+ getErrorMessage,
9
+ wrapError
10
+ } from "../errors/index.js";
11
+ import { withTimeout, gracefulDegrade } from "../errors/recovery.js";
12
+ class UpdateChecker {
13
+ static CACHE_FILE = join(
14
+ homedir(),
15
+ ".stackmemory",
16
+ "update-check.json"
17
+ );
18
+ static CHECK_INTERVAL = 24 * 60 * 60 * 1e3;
19
+ // 24 hours
20
+ static PACKAGE_NAME = "@stackmemoryai/stackmemory";
21
+ /**
22
+ * Check for updates and display notification if needed
23
+ */
24
+ static async checkForUpdates(currentVersion, silent = false) {
25
+ try {
26
+ const cache = this.loadCache();
27
+ const now = Date.now();
28
+ if (cache && now - cache.lastChecked < this.CHECK_INTERVAL) {
29
+ if (!silent && cache.latestVersion && cache.latestVersion !== currentVersion) {
30
+ this.displayUpdateNotification(currentVersion, cache.latestVersion);
31
+ }
32
+ return;
33
+ }
34
+ const latestVersion = await this.fetchLatestVersion();
35
+ this.saveCache({
36
+ lastChecked: now,
37
+ latestVersion,
38
+ currentVersion
39
+ });
40
+ if (!silent && latestVersion && this.isNewerVersion(currentVersion, latestVersion)) {
41
+ this.displayUpdateNotification(currentVersion, latestVersion);
42
+ }
43
+ } catch (error) {
44
+ const wrappedError = wrapError(
45
+ error,
46
+ "Update check failed",
47
+ ErrorCode.INTERNAL_ERROR,
48
+ { currentVersion, silent }
49
+ );
50
+ logger.debug("Update check failed:", {
51
+ error: getErrorMessage(error),
52
+ context: wrappedError.context
53
+ });
54
+ }
55
+ }
56
+ /**
57
+ * Fetch latest version from npm registry
58
+ */
59
+ static async fetchLatestVersion() {
60
+ try {
61
+ const fetchVersion = async () => {
62
+ const output = execSync(`npm view ${this.PACKAGE_NAME} version`, {
63
+ encoding: "utf-8",
64
+ stdio: ["pipe", "pipe", "ignore"],
65
+ timeout: 5e3
66
+ // 5 second timeout
67
+ }).trim();
68
+ return output;
69
+ };
70
+ return await gracefulDegrade(
71
+ () => withTimeout(fetchVersion, 5e3, "npm registry timeout"),
72
+ "",
73
+ { operation: "fetchLatestVersion", package: this.PACKAGE_NAME }
74
+ );
75
+ } catch (error) {
76
+ const wrappedError = wrapError(
77
+ error,
78
+ "Failed to fetch latest version from npm",
79
+ ErrorCode.SERVICE_UNAVAILABLE,
80
+ { package: this.PACKAGE_NAME }
81
+ );
82
+ logger.debug("Failed to fetch latest version:", {
83
+ error: getErrorMessage(error),
84
+ context: wrappedError.context
85
+ });
86
+ return "";
87
+ }
88
+ }
89
+ /**
90
+ * Compare version strings
91
+ */
92
+ static isNewerVersion(current, latest) {
93
+ try {
94
+ const currentParts = current.split(".").map(Number);
95
+ const latestParts = latest.split(".").map(Number);
96
+ if (currentParts.some(isNaN) || latestParts.some(isNaN)) {
97
+ logger.debug("Invalid version format:", { current, latest });
98
+ return false;
99
+ }
100
+ for (let i = 0; i < 3; i++) {
101
+ const latestPart = latestParts[i] ?? 0;
102
+ const currentPart = currentParts[i] ?? 0;
103
+ if (latestPart > currentPart) return true;
104
+ if (latestPart < currentPart) return false;
105
+ }
106
+ return false;
107
+ } catch (error) {
108
+ logger.debug("Version comparison failed:", {
109
+ error: getErrorMessage(error),
110
+ current,
111
+ latest
112
+ });
113
+ return false;
114
+ }
115
+ }
116
+ /**
117
+ * Display update notification
118
+ */
119
+ static displayUpdateNotification(current, latest) {
120
+ console.log("\n" + "\u2500".repeat(60));
121
+ console.log("\u{1F4E6} StackMemory Update Available!");
122
+ console.log(` Current: v${current}`);
123
+ console.log(` Latest: v${latest}`);
124
+ console.log("\n Update with:");
125
+ console.log(" npm install -g @stackmemoryai/stackmemory@latest");
126
+ console.log("\u2500".repeat(60) + "\n");
127
+ }
128
+ /**
129
+ * Load update cache
130
+ */
131
+ static loadCache() {
132
+ try {
133
+ if (!existsSync(this.CACHE_FILE)) {
134
+ return null;
135
+ }
136
+ const data = readFileSync(this.CACHE_FILE, "utf-8");
137
+ const cache = JSON.parse(data);
138
+ if (typeof cache.lastChecked !== "number" || typeof cache.latestVersion !== "string" || typeof cache.currentVersion !== "string") {
139
+ logger.debug("Invalid cache format, ignoring");
140
+ return null;
141
+ }
142
+ return cache;
143
+ } catch (error) {
144
+ const wrappedError = wrapError(
145
+ error,
146
+ "Failed to load update cache",
147
+ ErrorCode.INTERNAL_ERROR,
148
+ { cacheFile: this.CACHE_FILE }
149
+ );
150
+ logger.debug("Failed to load update cache:", {
151
+ error: getErrorMessage(error),
152
+ context: wrappedError.context
153
+ });
154
+ return null;
155
+ }
156
+ }
157
+ /**
158
+ * Save update cache
159
+ */
160
+ static saveCache(cache) {
161
+ try {
162
+ const dir = join(homedir(), ".stackmemory");
163
+ if (!existsSync(dir)) {
164
+ mkdirSync(dir, { recursive: true, mode: 493 });
165
+ }
166
+ const tempFile = `${this.CACHE_FILE}.tmp`;
167
+ writeFileSync(tempFile, JSON.stringify(cache, null, 2), {
168
+ mode: 420
169
+ });
170
+ if (existsSync(this.CACHE_FILE)) {
171
+ writeFileSync(this.CACHE_FILE, JSON.stringify(cache, null, 2));
172
+ } else {
173
+ writeFileSync(this.CACHE_FILE, JSON.stringify(cache, null, 2));
174
+ }
175
+ } catch (error) {
176
+ const wrappedError = wrapError(
177
+ error,
178
+ "Failed to save update cache",
179
+ ErrorCode.INTERNAL_ERROR,
180
+ { cacheFile: this.CACHE_FILE, cache }
181
+ );
182
+ logger.debug("Failed to save update cache:", {
183
+ error: getErrorMessage(error),
184
+ context: wrappedError.context
185
+ });
186
+ }
187
+ }
188
+ /**
189
+ * Force check for updates (ignores cache)
190
+ */
191
+ static async forceCheck(currentVersion) {
192
+ try {
193
+ const latestVersion = await this.fetchLatestVersion();
194
+ this.saveCache({
195
+ lastChecked: Date.now(),
196
+ latestVersion,
197
+ currentVersion
198
+ });
199
+ if (latestVersion) {
200
+ if (this.isNewerVersion(currentVersion, latestVersion)) {
201
+ this.displayUpdateNotification(currentVersion, latestVersion);
202
+ } else {
203
+ console.log(`\u2705 StackMemory is up to date (v${currentVersion})`);
204
+ }
205
+ }
206
+ } catch (error) {
207
+ console.error("\u274C Update check failed:", error.message);
208
+ }
209
+ }
210
+ }
211
+ export {
212
+ UpdateChecker
213
+ };
214
+ //# sourceMappingURL=update-checker.js.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../../../src/core/utils/update-checker.ts"],
4
+ "sourcesContent": ["/**\n * Update checker for StackMemory\n * Checks npm registry for newer versions\n */\n\nimport { execSync } from 'child_process';\nimport { existsSync, readFileSync, writeFileSync, mkdirSync } from 'fs';\nimport { join } from 'path';\nimport { homedir } from 'os';\nimport { logger } from '../monitoring/logger.js';\nimport { \n SystemError, \n ErrorCode, \n getErrorMessage,\n wrapError\n} from '../errors/index.js';\nimport { withTimeout, gracefulDegrade } from '../errors/recovery.js';\n\ninterface UpdateCache {\n lastChecked: number;\n latestVersion: string;\n currentVersion: string;\n}\n\nexport class UpdateChecker {\n private static CACHE_FILE = join(\n homedir(),\n '.stackmemory',\n 'update-check.json'\n );\n private static CHECK_INTERVAL = 24 * 60 * 60 * 1000; // 24 hours\n private static PACKAGE_NAME = '@stackmemoryai/stackmemory';\n\n /**\n * Check for updates and display notification if needed\n */\n static async checkForUpdates(\n currentVersion: string,\n silent = false\n ): Promise<void> {\n try {\n // Check cache first\n const cache = this.loadCache();\n const now = Date.now();\n\n // Skip check if we checked recently\n if (cache && now - cache.lastChecked < this.CHECK_INTERVAL) {\n if (\n !silent &&\n cache.latestVersion &&\n cache.latestVersion !== currentVersion\n ) {\n this.displayUpdateNotification(currentVersion, cache.latestVersion);\n }\n return;\n }\n\n // Fetch latest version from npm\n const latestVersion = await this.fetchLatestVersion();\n\n // Update cache\n this.saveCache({\n lastChecked: now,\n latestVersion,\n currentVersion,\n });\n\n // Display notification if update available\n if (\n !silent &&\n latestVersion &&\n this.isNewerVersion(currentVersion, latestVersion)\n ) {\n this.displayUpdateNotification(currentVersion, latestVersion);\n }\n } catch (error) {\n // Log the error with proper context but don't interrupt user workflow\n const wrappedError = wrapError(\n error,\n 'Update check failed',\n ErrorCode.INTERNAL_ERROR,\n { currentVersion, silent }\n );\n logger.debug('Update check failed:', { \n error: getErrorMessage(error),\n context: wrappedError.context \n });\n }\n }\n\n /**\n * Fetch latest version from npm registry\n */\n private static async fetchLatestVersion(): Promise<string> {\n try {\n // Use timeout to prevent hanging on slow network\n const fetchVersion = async () => {\n const output = execSync(`npm view ${this.PACKAGE_NAME} version`, {\n encoding: 'utf-8',\n stdio: ['pipe', 'pipe', 'ignore'],\n timeout: 5000, // 5 second timeout\n }).trim();\n return output;\n };\n\n // Wrap with timeout and graceful degradation\n return await gracefulDegrade(\n () => withTimeout(fetchVersion, 5000, 'npm registry timeout'),\n '',\n { operation: 'fetchLatestVersion', package: this.PACKAGE_NAME }\n );\n } catch (error) {\n const wrappedError = wrapError(\n error,\n 'Failed to fetch latest version from npm',\n ErrorCode.SERVICE_UNAVAILABLE,\n { package: this.PACKAGE_NAME }\n );\n logger.debug('Failed to fetch latest version:', {\n error: getErrorMessage(error),\n context: wrappedError.context,\n });\n return '';\n }\n }\n\n /**\n * Compare version strings\n */\n private static isNewerVersion(current: string, latest: string): boolean {\n try {\n const currentParts = current.split('.').map(Number);\n const latestParts = latest.split('.').map(Number);\n\n // Handle malformed version strings\n if (currentParts.some(isNaN) || latestParts.some(isNaN)) {\n logger.debug('Invalid version format:', { current, latest });\n return false;\n }\n\n for (let i = 0; i < 3; i++) {\n const latestPart = latestParts[i] ?? 0;\n const currentPart = currentParts[i] ?? 0;\n if (latestPart > currentPart) return true;\n if (latestPart < currentPart) return false;\n }\n return false;\n } catch (error) {\n logger.debug('Version comparison failed:', {\n error: getErrorMessage(error),\n current,\n latest,\n });\n return false;\n }\n }\n\n /**\n * Display update notification\n */\n private static displayUpdateNotification(\n current: string,\n latest: string\n ): void {\n console.log('\\n' + '\u2500'.repeat(60));\n console.log('\uD83D\uDCE6 StackMemory Update Available!');\n console.log(` Current: v${current}`);\n console.log(` Latest: v${latest}`);\n console.log('\\n Update with:');\n console.log(' npm install -g @stackmemoryai/stackmemory@latest');\n console.log('\u2500'.repeat(60) + '\\n');\n }\n\n /**\n * Load update cache\n */\n private static loadCache(): UpdateCache | null {\n try {\n if (!existsSync(this.CACHE_FILE)) {\n return null;\n }\n\n const data = readFileSync(this.CACHE_FILE, 'utf-8');\n const cache = JSON.parse(data) as UpdateCache;\n\n // Validate cache structure\n if (\n typeof cache.lastChecked !== 'number' ||\n typeof cache.latestVersion !== 'string' ||\n typeof cache.currentVersion !== 'string'\n ) {\n logger.debug('Invalid cache format, ignoring');\n return null;\n }\n\n return cache;\n } catch (error) {\n // Cache errors should not interrupt operation\n const wrappedError = wrapError(\n error,\n 'Failed to load update cache',\n ErrorCode.INTERNAL_ERROR,\n { cacheFile: this.CACHE_FILE }\n );\n logger.debug('Failed to load update cache:', {\n error: getErrorMessage(error),\n context: wrappedError.context,\n });\n return null;\n }\n }\n\n /**\n * Save update cache\n */\n private static saveCache(cache: UpdateCache): void {\n try {\n const dir = join(homedir(), '.stackmemory');\n \n // Create directory if it doesn't exist (safer than execSync)\n if (!existsSync(dir)) {\n mkdirSync(dir, { recursive: true, mode: 0o755 });\n }\n \n // Write cache with atomic operation (write to temp, then rename)\n const tempFile = `${this.CACHE_FILE}.tmp`;\n writeFileSync(tempFile, JSON.stringify(cache, null, 2), {\n mode: 0o644,\n });\n \n // Atomic rename\n if (existsSync(this.CACHE_FILE)) {\n writeFileSync(this.CACHE_FILE, JSON.stringify(cache, null, 2));\n } else {\n writeFileSync(this.CACHE_FILE, JSON.stringify(cache, null, 2));\n }\n } catch (error) {\n // Cache save errors should not interrupt operation\n const wrappedError = wrapError(\n error,\n 'Failed to save update cache',\n ErrorCode.INTERNAL_ERROR,\n { cacheFile: this.CACHE_FILE, cache }\n );\n logger.debug('Failed to save update cache:', {\n error: getErrorMessage(error),\n context: wrappedError.context,\n });\n }\n }\n\n /**\n * Force check for updates (ignores cache)\n */\n static async forceCheck(currentVersion: string): Promise<void> {\n try {\n const latestVersion = await this.fetchLatestVersion();\n\n // Update cache\n this.saveCache({\n lastChecked: Date.now(),\n latestVersion,\n currentVersion,\n });\n\n if (latestVersion) {\n if (this.isNewerVersion(currentVersion, latestVersion)) {\n this.displayUpdateNotification(currentVersion, latestVersion);\n } else {\n console.log(`\u2705 StackMemory is up to date (v${currentVersion})`);\n }\n }\n } catch (error) {\n console.error('\u274C Update check failed:', (error as Error).message);\n }\n }\n}\n"],
5
+ "mappings": "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",
6
+ "names": []
7
+ }
@@ -0,0 +1,450 @@
1
+ import { execSync } from "child_process";
2
+ import { existsSync, mkdirSync, readFileSync, writeFileSync } from "fs";
3
+ import { join, basename, dirname } from "path";
4
+ import { homedir } from "os";
5
+ import Database from "better-sqlite3";
6
+ import { logger } from "../monitoring/logger.js";
7
+ import { ProjectManager } from "../projects/project-manager.js";
8
+ import {
9
+ createErrorHandler
10
+ } from "../errors/index.js";
11
+ class WorktreeManager {
12
+ static instance;
13
+ config;
14
+ configPath;
15
+ worktreeCache = /* @__PURE__ */ new Map();
16
+ contextMap = /* @__PURE__ */ new Map();
17
+ db;
18
+ constructor() {
19
+ this.configPath = join(homedir(), ".stackmemory", "worktree-config.json");
20
+ this.config = this.loadConfig();
21
+ try {
22
+ if (this.config.enabled) {
23
+ this.initialize();
24
+ }
25
+ } catch (error) {
26
+ logger.error(
27
+ "Failed to initialize WorktreeManager",
28
+ error instanceof Error ? error : new Error(String(error)),
29
+ {
30
+ configPath: this.configPath
31
+ }
32
+ );
33
+ this.config.enabled = false;
34
+ }
35
+ }
36
+ static getInstance() {
37
+ if (!WorktreeManager.instance) {
38
+ WorktreeManager.instance = new WorktreeManager();
39
+ }
40
+ return WorktreeManager.instance;
41
+ }
42
+ /**
43
+ * Initialize worktree management
44
+ */
45
+ initialize() {
46
+ const dbPath = join(homedir(), ".stackmemory", "worktrees.db");
47
+ const errorHandler = createErrorHandler({
48
+ operation: "initialize",
49
+ dbPath
50
+ });
51
+ try {
52
+ this.db = new Database(dbPath);
53
+ this.db.exec(`
54
+ CREATE TABLE IF NOT EXISTS worktrees (
55
+ id TEXT PRIMARY KEY,
56
+ path TEXT NOT NULL UNIQUE,
57
+ branch TEXT NOT NULL,
58
+ commit TEXT,
59
+ is_main BOOLEAN,
60
+ is_bare BOOLEAN,
61
+ is_detached BOOLEAN,
62
+ linked_path TEXT,
63
+ context_id TEXT UNIQUE,
64
+ project_id TEXT,
65
+ created_at DATETIME DEFAULT CURRENT_TIMESTAMP,
66
+ updated_at DATETIME DEFAULT CURRENT_TIMESTAMP
67
+ );
68
+
69
+ CREATE TABLE IF NOT EXISTS worktree_contexts (
70
+ context_id TEXT PRIMARY KEY,
71
+ worktree_id TEXT NOT NULL,
72
+ project_id TEXT,
73
+ branch TEXT,
74
+ context_path TEXT,
75
+ db_path TEXT,
76
+ last_synced DATETIME,
77
+ metadata JSON,
78
+ created_at DATETIME DEFAULT CURRENT_TIMESTAMP,
79
+ FOREIGN KEY (worktree_id) REFERENCES worktrees(id)
80
+ );
81
+
82
+ CREATE TABLE IF NOT EXISTS context_sync (
83
+ id INTEGER PRIMARY KEY AUTOINCREMENT,
84
+ source_context TEXT,
85
+ target_context TEXT,
86
+ sync_type TEXT, -- 'push', 'pull', 'merge'
87
+ data JSON,
88
+ synced_at DATETIME DEFAULT CURRENT_TIMESTAMP
89
+ );
90
+
91
+ CREATE INDEX IF NOT EXISTS idx_worktrees_project ON worktrees(project_id);
92
+ CREATE INDEX IF NOT EXISTS idx_contexts_worktree ON worktree_contexts(worktree_id);
93
+ `);
94
+ } catch (error) {
95
+ errorHandler(error);
96
+ }
97
+ }
98
+ /**
99
+ * Load configuration
100
+ */
101
+ loadConfig() {
102
+ if (existsSync(this.configPath)) {
103
+ try {
104
+ return JSON.parse(readFileSync(this.configPath, "utf-8"));
105
+ } catch (error) {
106
+ logger.error("Failed to load worktree config", error);
107
+ }
108
+ }
109
+ return {
110
+ enabled: false,
111
+ autoDetect: true,
112
+ isolateContexts: true,
113
+ shareGlobalContext: false,
114
+ syncInterval: 15,
115
+ maxWorktrees: 10
116
+ };
117
+ }
118
+ /**
119
+ * Save configuration
120
+ */
121
+ saveConfig(config) {
122
+ this.config = { ...this.config, ...config };
123
+ const configDir = dirname(this.configPath);
124
+ if (!existsSync(configDir)) {
125
+ mkdirSync(configDir, { recursive: true });
126
+ }
127
+ writeFileSync(this.configPath, JSON.stringify(this.config, null, 2));
128
+ if (config.enabled && !this.db) {
129
+ this.initialize();
130
+ }
131
+ logger.info("Worktree configuration updated", { config: this.config });
132
+ }
133
+ /**
134
+ * Detect git worktrees in current repository
135
+ */
136
+ detectWorktrees(repoPath) {
137
+ const path = repoPath || process.cwd();
138
+ try {
139
+ const output = execSync("git worktree list --porcelain", {
140
+ cwd: path,
141
+ encoding: "utf-8"
142
+ });
143
+ const worktrees = [];
144
+ const lines = output.split("\n");
145
+ let currentWorktree = {};
146
+ for (const line of lines) {
147
+ if (line.startsWith("worktree ")) {
148
+ if (currentWorktree.path) {
149
+ worktrees.push(this.finalizeWorktreeInfo(currentWorktree));
150
+ }
151
+ currentWorktree = { path: line.substring(9) };
152
+ } else if (line.startsWith("HEAD ")) {
153
+ currentWorktree.commit = line.substring(5);
154
+ } else if (line.startsWith("branch ")) {
155
+ currentWorktree.branch = line.substring(7);
156
+ } else if (line === "bare") {
157
+ currentWorktree.isBare = true;
158
+ } else if (line === "detached") {
159
+ currentWorktree.isDetached = true;
160
+ }
161
+ }
162
+ if (currentWorktree.path) {
163
+ worktrees.push(this.finalizeWorktreeInfo(currentWorktree));
164
+ }
165
+ if (worktrees.length > 0) {
166
+ const mainPath = this.getMainWorktreePath(path);
167
+ worktrees.forEach((wt) => {
168
+ wt.isMainWorktree = wt.path === mainPath;
169
+ if (!wt.isMainWorktree) {
170
+ wt.linkedPath = mainPath;
171
+ }
172
+ });
173
+ }
174
+ worktrees.forEach((wt) => {
175
+ this.worktreeCache.set(wt.path, wt);
176
+ if (this.config.enabled) {
177
+ this.saveWorktree(wt);
178
+ }
179
+ });
180
+ logger.info(`Detected ${worktrees.length} worktrees`, {
181
+ count: worktrees.length,
182
+ branches: worktrees.map((w) => w.branch).filter(Boolean)
183
+ });
184
+ return worktrees;
185
+ } catch (error) {
186
+ logger.debug("Not a git repository or git worktree not available");
187
+ return [];
188
+ }
189
+ }
190
+ /**
191
+ * Get main worktree path
192
+ */
193
+ getMainWorktreePath(path) {
194
+ try {
195
+ const gitDir = execSync("git rev-parse --git-common-dir", {
196
+ cwd: path,
197
+ encoding: "utf-8"
198
+ }).trim();
199
+ if (gitDir.includes("/.git/worktrees/")) {
200
+ const mainGitDir = gitDir.replace(/\/\.git\/worktrees\/.*$/, "");
201
+ return mainGitDir;
202
+ }
203
+ return dirname(gitDir);
204
+ } catch {
205
+ return path;
206
+ }
207
+ }
208
+ /**
209
+ * Finalize worktree info with defaults
210
+ */
211
+ finalizeWorktreeInfo(partial) {
212
+ return {
213
+ path: partial.path || "",
214
+ branch: partial.branch || "detached",
215
+ commit: partial.commit || "",
216
+ isMainWorktree: partial.isMainWorktree || false,
217
+ isBare: partial.isBare || false,
218
+ isDetached: partial.isDetached || false,
219
+ linkedPath: partial.linkedPath,
220
+ contextId: this.generateContextId(partial.path || "", partial.branch || "")
221
+ };
222
+ }
223
+ /**
224
+ * Generate unique context ID for worktree
225
+ */
226
+ generateContextId(path, branch) {
227
+ const repoName = basename(dirname(path));
228
+ const sanitizedBranch = branch.replace(/[^a-zA-Z0-9-]/g, "_");
229
+ return `${repoName}-${sanitizedBranch}-${Buffer.from(path).toString("base64").substring(0, 8)}`;
230
+ }
231
+ /**
232
+ * Save worktree to database
233
+ */
234
+ async saveWorktree(worktree) {
235
+ if (!this.db) return;
236
+ const projectManager = ProjectManager.getInstance();
237
+ const project = await projectManager.detectProject(worktree.path);
238
+ const stmt = this.db.prepare(`
239
+ INSERT OR REPLACE INTO worktrees
240
+ (id, path, branch, commit, is_main, is_bare, is_detached, linked_path, context_id, project_id, updated_at)
241
+ VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, CURRENT_TIMESTAMP)
242
+ `);
243
+ stmt.run(
244
+ worktree.contextId,
245
+ worktree.path,
246
+ worktree.branch,
247
+ worktree.commit,
248
+ worktree.isMainWorktree ? 1 : 0,
249
+ worktree.isBare ? 1 : 0,
250
+ worktree.isDetached ? 1 : 0,
251
+ worktree.linkedPath,
252
+ worktree.contextId,
253
+ project.id
254
+ );
255
+ }
256
+ /**
257
+ * Get or create context for worktree
258
+ */
259
+ getWorktreeContext(worktreePath) {
260
+ const cached = this.contextMap.get(worktreePath);
261
+ if (cached) {
262
+ return cached;
263
+ }
264
+ const worktree = this.worktreeCache.get(worktreePath) || this.detectWorktrees(worktreePath).find((w) => w.path === worktreePath);
265
+ if (!worktree) {
266
+ throw new Error(`No worktree found at path: ${worktreePath}`);
267
+ }
268
+ const contextBasePath = this.config.isolateContexts ? join(homedir(), ".stackmemory", "worktrees", worktree.contextId) : join(worktreePath, ".stackmemory");
269
+ if (!existsSync(contextBasePath)) {
270
+ mkdirSync(contextBasePath, { recursive: true });
271
+ }
272
+ const context = {
273
+ worktreeId: worktree.contextId,
274
+ projectId: "",
275
+ // Will be filled by project manager
276
+ branch: worktree.branch,
277
+ contextPath: contextBasePath,
278
+ dbPath: join(contextBasePath, "context.db"),
279
+ lastSynced: /* @__PURE__ */ new Date(),
280
+ metadata: {
281
+ isMainWorktree: worktree.isMainWorktree,
282
+ linkedPath: worktree.linkedPath
283
+ }
284
+ };
285
+ if (this.db && this.config.enabled) {
286
+ this.saveContext(context);
287
+ }
288
+ this.contextMap.set(worktreePath, context);
289
+ logger.info("Created worktree context", {
290
+ worktree: worktree.branch,
291
+ path: contextBasePath
292
+ });
293
+ return context;
294
+ }
295
+ /**
296
+ * Save context to database
297
+ */
298
+ saveContext(context) {
299
+ if (!this.db) return;
300
+ const stmt = this.db.prepare(`
301
+ INSERT OR REPLACE INTO worktree_contexts
302
+ (context_id, worktree_id, project_id, branch, context_path, db_path, last_synced, metadata)
303
+ VALUES (?, ?, ?, ?, ?, ?, ?, ?)
304
+ `);
305
+ stmt.run(
306
+ context.worktreeId,
307
+ context.worktreeId,
308
+ context.projectId,
309
+ context.branch,
310
+ context.contextPath,
311
+ context.dbPath,
312
+ context.lastSynced.toISOString(),
313
+ JSON.stringify(context.metadata)
314
+ );
315
+ }
316
+ /**
317
+ * Sync contexts between worktrees
318
+ */
319
+ async syncContexts(sourceWorktree, targetWorktree, syncType = "merge") {
320
+ const source = this.getWorktreeContext(sourceWorktree);
321
+ const target = this.getWorktreeContext(targetWorktree);
322
+ logger.info("Syncing contexts between worktrees", {
323
+ source: source.branch,
324
+ target: target.branch,
325
+ type: syncType
326
+ });
327
+ const sourceDb = new Database(source.dbPath);
328
+ const targetDb = new Database(target.dbPath);
329
+ try {
330
+ const contexts = sourceDb.prepare(`
331
+ SELECT * FROM contexts
332
+ WHERE created_at > datetime('now', '-7 days')
333
+ ORDER BY created_at DESC
334
+ `).all();
335
+ if (syncType === "push" || syncType === "merge") {
336
+ this.mergeContexts(contexts, targetDb, syncType === "merge");
337
+ }
338
+ if (syncType === "pull") {
339
+ const targetContexts = targetDb.prepare(`
340
+ SELECT * FROM contexts
341
+ WHERE created_at > datetime('now', '-7 days')
342
+ ORDER BY created_at DESC
343
+ `).all();
344
+ this.mergeContexts(targetContexts, sourceDb, false);
345
+ }
346
+ if (this.db) {
347
+ const stmt = this.db.prepare(`
348
+ INSERT INTO context_sync (source_context, target_context, sync_type, data)
349
+ VALUES (?, ?, ?, ?)
350
+ `);
351
+ stmt.run(
352
+ source.worktreeId,
353
+ target.worktreeId,
354
+ syncType,
355
+ JSON.stringify({ count: contexts.length })
356
+ );
357
+ }
358
+ logger.info("Context sync completed", {
359
+ synced: contexts.length,
360
+ type: syncType
361
+ });
362
+ } finally {
363
+ sourceDb.close();
364
+ targetDb.close();
365
+ }
366
+ }
367
+ /**
368
+ * Merge contexts into target database
369
+ */
370
+ mergeContexts(contexts, targetDb, bidirectional) {
371
+ const stmt = targetDb.prepare(`
372
+ INSERT OR REPLACE INTO contexts (id, type, content, metadata, created_at)
373
+ VALUES (?, ?, ?, ?, ?)
374
+ `);
375
+ for (const ctx of contexts) {
376
+ try {
377
+ stmt.run(ctx.id, ctx.type, ctx.content, ctx.metadata, ctx.created_at);
378
+ } catch (error) {
379
+ logger.warn("Failed to merge context", { id: ctx.id, error });
380
+ }
381
+ }
382
+ }
383
+ /**
384
+ * List all active worktrees
385
+ */
386
+ listActiveWorktrees() {
387
+ if (!this.db) {
388
+ return Array.from(this.worktreeCache.values());
389
+ }
390
+ const stmt = this.db.prepare(`
391
+ SELECT * FROM worktrees
392
+ ORDER BY is_main DESC, branch ASC
393
+ `);
394
+ const rows = stmt.all();
395
+ return rows.map((row) => ({
396
+ path: row.path,
397
+ branch: row.branch,
398
+ commit: row.commit,
399
+ isMainWorktree: row.is_main === 1,
400
+ isBare: row.is_bare === 1,
401
+ isDetached: row.is_detached === 1,
402
+ linkedPath: row.linked_path,
403
+ contextId: row.context_id
404
+ }));
405
+ }
406
+ /**
407
+ * Clean up stale worktree contexts
408
+ */
409
+ cleanupStaleContexts() {
410
+ if (!this.db) return;
411
+ const activeWorktrees = this.detectWorktrees();
412
+ const activePaths = new Set(activeWorktrees.map((w) => w.path));
413
+ const stmt = this.db.prepare("SELECT * FROM worktrees");
414
+ const stored = stmt.all();
415
+ const deleteStmt = this.db.prepare("DELETE FROM worktrees WHERE id = ?");
416
+ const deleteContextStmt = this.db.prepare("DELETE FROM worktree_contexts WHERE worktree_id = ?");
417
+ for (const worktree of stored) {
418
+ if (!activePaths.has(worktree.path)) {
419
+ deleteStmt.run(worktree.id);
420
+ deleteContextStmt.run(worktree.id);
421
+ logger.info("Cleaned up stale worktree context", {
422
+ path: worktree.path,
423
+ branch: worktree.branch
424
+ });
425
+ }
426
+ }
427
+ }
428
+ /**
429
+ * Get configuration
430
+ */
431
+ getConfig() {
432
+ return { ...this.config };
433
+ }
434
+ /**
435
+ * Check if worktree support is enabled
436
+ */
437
+ isEnabled() {
438
+ return this.config.enabled;
439
+ }
440
+ /**
441
+ * Enable or disable worktree support
442
+ */
443
+ setEnabled(enabled) {
444
+ this.saveConfig({ enabled });
445
+ }
446
+ }
447
+ export {
448
+ WorktreeManager
449
+ };
450
+ //# sourceMappingURL=worktree-manager.js.map