@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,513 @@
1
+ import jwt from "jsonwebtoken";
2
+ import jwksRsa from "jwks-rsa";
3
+ import { RateLimiterRedis } from "rate-limiter-flexible";
4
+ import Redis from "ioredis";
5
+ import BetterSqlite3 from "better-sqlite3";
6
+ import { logger } from "../../core/monitoring/logger.js";
7
+ import { metrics } from "../../core/monitoring/metrics.js";
8
+ import { getUserModel } from "../../models/user.model.js";
9
+ class AuthMiddleware {
10
+ constructor(config) {
11
+ this.config = config;
12
+ this.redis = new Redis(config.redisUrl);
13
+ const dbPath = config.dbPath || process.env.STACKMEMORY_DB || ".stackmemory/auth.db";
14
+ this.db = new BetterSqlite3(dbPath);
15
+ this.userModel = getUserModel(this.db);
16
+ this.jwksClient = jwksRsa({
17
+ jwksUri: `https://${config.auth0Domain}/.well-known/jwks.json`,
18
+ cache: true,
19
+ cacheMaxAge: 6e5,
20
+ // 10 minutes
21
+ rateLimit: true,
22
+ jwksRequestsPerMinute: 5
23
+ });
24
+ this.initializeRateLimiters();
25
+ this.setupTokenBlacklistSync();
26
+ }
27
+ jwksClient;
28
+ redis;
29
+ rateLimiters;
30
+ blacklistedTokens = /* @__PURE__ */ new Set();
31
+ userModel;
32
+ db;
33
+ mockUser;
34
+ mockUserInitializing = false;
35
+ initializeRateLimiters() {
36
+ this.rateLimiters = /* @__PURE__ */ new Map([
37
+ [
38
+ "free",
39
+ new RateLimiterRedis({
40
+ storeClient: this.redis,
41
+ keyPrefix: "rl:free",
42
+ points: 100,
43
+ // requests
44
+ duration: 900,
45
+ // per 15 minutes
46
+ blockDuration: 900
47
+ // block for 15 minutes
48
+ })
49
+ ],
50
+ [
51
+ "pro",
52
+ new RateLimiterRedis({
53
+ storeClient: this.redis,
54
+ keyPrefix: "rl:pro",
55
+ points: 1e3,
56
+ duration: 900,
57
+ blockDuration: 300
58
+ })
59
+ ],
60
+ [
61
+ "enterprise",
62
+ new RateLimiterRedis({
63
+ storeClient: this.redis,
64
+ keyPrefix: "rl:enterprise",
65
+ points: 1e4,
66
+ duration: 900,
67
+ blockDuration: 60
68
+ })
69
+ ]
70
+ ]);
71
+ this.rateLimiters.set(
72
+ "auth",
73
+ new RateLimiterRedis({
74
+ storeClient: this.redis,
75
+ keyPrefix: "rl:auth",
76
+ points: 10,
77
+ // Only 10 auth attempts
78
+ duration: 900,
79
+ blockDuration: 3600
80
+ // Block for 1 hour on excessive auth attempts
81
+ })
82
+ );
83
+ }
84
+ setupTokenBlacklistSync() {
85
+ const subscriber = new Redis(this.config.redisUrl);
86
+ subscriber.subscribe("token:revoked");
87
+ subscriber.on("message", (channel, token) => {
88
+ if (channel === "token:revoked") {
89
+ this.blacklistedTokens.add(token);
90
+ if (this.blacklistedTokens.size > 1e4) {
91
+ this.blacklistedTokens.clear();
92
+ }
93
+ }
94
+ });
95
+ }
96
+ async getSigningKey(kid) {
97
+ return new Promise((resolve, reject) => {
98
+ this.jwksClient.getSigningKey(kid, (err, key) => {
99
+ if (err) {
100
+ reject(err);
101
+ } else {
102
+ const signingKey = key?.getPublicKey();
103
+ if (!signingKey) {
104
+ reject(new Error("No signing key found"));
105
+ } else {
106
+ resolve(signingKey);
107
+ }
108
+ }
109
+ });
110
+ });
111
+ }
112
+ /**
113
+ * Main authentication middleware
114
+ */
115
+ authenticate = async (req, res, next) => {
116
+ const startTime = Date.now();
117
+ try {
118
+ if (req.path === "/health" || req.path === "/metrics") {
119
+ return next();
120
+ }
121
+ if (this.config.bypassAuth && process.env.NODE_ENV === "development") {
122
+ req.user = this.getMockUser();
123
+ return next();
124
+ }
125
+ const token = this.extractToken(req);
126
+ const apiKey = this.extractApiKey(req);
127
+ if (!token && !apiKey) {
128
+ metrics.increment("auth.missing_credentials");
129
+ return res.status(401).json({
130
+ error: "Authentication required",
131
+ code: "MISSING_CREDENTIALS"
132
+ });
133
+ }
134
+ if (apiKey) {
135
+ const user2 = await this.userModel.validateApiKey(apiKey);
136
+ if (!user2) {
137
+ metrics.increment("auth.invalid_api_key");
138
+ return res.status(401).json({
139
+ error: "Invalid API key",
140
+ code: "INVALID_API_KEY"
141
+ });
142
+ }
143
+ req.user = {
144
+ id: user2.id,
145
+ sub: user2.sub,
146
+ email: user2.email,
147
+ name: user2.name,
148
+ picture: user2.avatar,
149
+ tier: user2.tier,
150
+ permissions: user2.permissions,
151
+ organizations: user2.organizations.map((org) => org.id),
152
+ metadata: { ...user2.metadata, authMethod: "api_key" }
153
+ };
154
+ metrics.increment("auth.api_key_success");
155
+ await metrics.timing("auth.api_key_duration", Date.now() - startTime);
156
+ return next();
157
+ }
158
+ if (token && this.blacklistedTokens.has(token)) {
159
+ metrics.increment("auth.blacklisted_token");
160
+ return res.status(401).json({
161
+ error: "Token has been revoked",
162
+ code: "TOKEN_REVOKED"
163
+ });
164
+ }
165
+ if (!token) {
166
+ return res.status(401).json({
167
+ error: "No token provided",
168
+ code: "NO_TOKEN"
169
+ });
170
+ }
171
+ const decoded = jwt.decode(token, { complete: true });
172
+ if (!decoded) {
173
+ metrics.increment("auth.invalid_token");
174
+ return res.status(401).json({
175
+ error: "Invalid token format",
176
+ code: "INVALID_TOKEN"
177
+ });
178
+ }
179
+ const signingKey = await this.getSigningKey(decoded.header.kid);
180
+ const verified = jwt.verify(token, signingKey, {
181
+ algorithms: ["RS256"],
182
+ audience: this.config.auth0Audience,
183
+ issuer: `https://${this.config.auth0Domain}/`
184
+ });
185
+ const user = await this.loadUser(verified.sub, verified);
186
+ if (!user) {
187
+ metrics.increment("auth.user_not_found");
188
+ return res.status(403).json({
189
+ error: "User not found",
190
+ code: "USER_NOT_FOUND"
191
+ });
192
+ }
193
+ if (user.metadata?.suspended) {
194
+ metrics.increment("auth.user_suspended");
195
+ return res.status(403).json({
196
+ error: "Account suspended",
197
+ code: "ACCOUNT_SUSPENDED"
198
+ });
199
+ }
200
+ const rateLimiter = this.rateLimiters.get(user.tier) || this.rateLimiters.get("free");
201
+ try {
202
+ const rateLimitRes = await rateLimiter.consume(user.id);
203
+ req.rateLimitInfo = rateLimitRes;
204
+ res.setHeader("X-RateLimit-Limit", rateLimiter.points.toString());
205
+ res.setHeader(
206
+ "X-RateLimit-Remaining",
207
+ rateLimitRes.remainingPoints.toString()
208
+ );
209
+ res.setHeader(
210
+ "X-RateLimit-Reset",
211
+ new Date(Date.now() + rateLimitRes.msBeforeNext).toISOString()
212
+ );
213
+ } catch (rateLimitError) {
214
+ metrics.increment("auth.rate_limited");
215
+ res.setHeader(
216
+ "Retry-After",
217
+ Math.round(rateLimitError.msBeforeNext / 1e3).toString()
218
+ );
219
+ return res.status(429).json({
220
+ error: "Too many requests",
221
+ code: "RATE_LIMITED",
222
+ retryAfter: rateLimitError.msBeforeNext
223
+ });
224
+ }
225
+ req.user = user;
226
+ metrics.increment("auth.success", { tier: user.tier });
227
+ metrics.timing("auth.duration", Date.now() - startTime);
228
+ logger.info("Authentication successful", {
229
+ userId: user.id,
230
+ tier: user.tier,
231
+ path: req.path
232
+ });
233
+ next();
234
+ } catch (error) {
235
+ metrics.increment("auth.error");
236
+ logger.error("Authentication error", error);
237
+ if (error.name === "TokenExpiredError") {
238
+ return res.status(401).json({
239
+ error: "Token expired",
240
+ code: "TOKEN_EXPIRED"
241
+ });
242
+ }
243
+ if (error.name === "JsonWebTokenError") {
244
+ return res.status(401).json({
245
+ error: "Invalid token",
246
+ code: "INVALID_TOKEN"
247
+ });
248
+ }
249
+ res.status(500).json({
250
+ error: "Authentication failed",
251
+ code: "AUTH_ERROR"
252
+ });
253
+ }
254
+ };
255
+ /**
256
+ * WebSocket authentication handler
257
+ */
258
+ authenticateWebSocket = async (token) => {
259
+ try {
260
+ const decoded = jwt.decode(token, { complete: true });
261
+ if (!decoded || this.blacklistedTokens.has(token)) {
262
+ return null;
263
+ }
264
+ const signingKey = await this.getSigningKey(decoded.header.kid);
265
+ const verified = jwt.verify(token, signingKey, {
266
+ algorithms: ["RS256"],
267
+ audience: this.config.auth0Audience,
268
+ issuer: `https://${this.config.auth0Domain}/`
269
+ });
270
+ return await this.loadUser(verified.sub, verified);
271
+ } catch (error) {
272
+ logger.error(
273
+ "WebSocket authentication failed",
274
+ error instanceof Error ? error : void 0
275
+ );
276
+ return null;
277
+ }
278
+ };
279
+ /**
280
+ * Permission checking middleware
281
+ */
282
+ requirePermission = (permission) => {
283
+ return (req, res, next) => {
284
+ if (!req.user) {
285
+ return res.status(401).json({
286
+ error: "Authentication required",
287
+ code: "NOT_AUTHENTICATED"
288
+ });
289
+ }
290
+ if (!req.user.permissions.includes(permission)) {
291
+ metrics.increment("auth.permission_denied", { permission });
292
+ return res.status(403).json({
293
+ error: "Insufficient permissions",
294
+ code: "PERMISSION_DENIED",
295
+ required: permission
296
+ });
297
+ }
298
+ return next();
299
+ };
300
+ };
301
+ /**
302
+ * Organization access middleware
303
+ */
304
+ requireOrganization = (req, res, next) => {
305
+ const orgId = req.params.orgId || req.query.orgId;
306
+ if (!req.user || !orgId) {
307
+ return res.status(401).json({
308
+ error: "Authentication required",
309
+ code: "NOT_AUTHENTICATED"
310
+ });
311
+ }
312
+ if (!req.user.organizations?.includes(orgId)) {
313
+ return res.status(403).json({
314
+ error: "Organization access denied",
315
+ code: "ORG_ACCESS_DENIED"
316
+ });
317
+ }
318
+ return next();
319
+ };
320
+ extractApiKey(req) {
321
+ const authHeader = req.headers.authorization;
322
+ if (authHeader?.startsWith("Bearer sk-")) {
323
+ return authHeader.substring(7);
324
+ }
325
+ const apiKeyHeader = req.headers["x-api-key"];
326
+ if (apiKeyHeader?.startsWith("sk-")) {
327
+ return apiKeyHeader;
328
+ }
329
+ return null;
330
+ }
331
+ extractToken(req) {
332
+ const authHeader = req.headers.authorization;
333
+ if (authHeader?.startsWith("Bearer ") && !authHeader.startsWith("Bearer sk-")) {
334
+ return authHeader.substring(7);
335
+ }
336
+ return req.cookies?.access_token || null;
337
+ }
338
+ async loadUser(sub, tokenPayload) {
339
+ const cached = await this.redis.get(`user:${sub}`);
340
+ if (cached) {
341
+ const cachedUser = JSON.parse(cached);
342
+ this.userModel.updateLastLogin(cachedUser.id).catch((err) => logger.error("Failed to update last login", err));
343
+ return cachedUser;
344
+ }
345
+ let dbUser = await this.userModel.findUserBySub(sub);
346
+ if (!dbUser && tokenPayload) {
347
+ dbUser = await this.userModel.createUser({
348
+ sub,
349
+ email: tokenPayload.email || `${sub}@auth.local`,
350
+ name: tokenPayload.name,
351
+ avatar: tokenPayload.picture,
352
+ tier: this.determineTier(tokenPayload),
353
+ permissions: this.determinePermissions(tokenPayload),
354
+ organizations: this.extractOrganizations(tokenPayload),
355
+ metadata: {
356
+ auth0: tokenPayload,
357
+ signupSource: "auth0",
358
+ createdVia: "auth-middleware"
359
+ }
360
+ });
361
+ logger.info("Auto-created user from auth token", {
362
+ sub,
363
+ email: dbUser.email
364
+ });
365
+ }
366
+ if (!dbUser) {
367
+ return null;
368
+ }
369
+ await this.userModel.updateLastLogin(dbUser.id);
370
+ const user = {
371
+ id: dbUser.id,
372
+ sub: dbUser.sub,
373
+ email: dbUser.email,
374
+ name: dbUser.name,
375
+ picture: dbUser.avatar,
376
+ tier: dbUser.tier,
377
+ permissions: dbUser.permissions,
378
+ organizations: dbUser.organizations.map((org) => org.id),
379
+ metadata: dbUser.metadata
380
+ };
381
+ await this.redis.setex(`user:${sub}`, 300, JSON.stringify(user));
382
+ return user;
383
+ }
384
+ determineTier(tokenPayload) {
385
+ if (tokenPayload["https://stackmemory.ai/tier"]) {
386
+ return tokenPayload["https://stackmemory.ai/tier"];
387
+ }
388
+ if (tokenPayload.subscription?.plan) {
389
+ const plan = tokenPayload.subscription.plan.toLowerCase();
390
+ if (plan.includes("enterprise")) return "enterprise";
391
+ if (plan.includes("pro") || plan.includes("premium")) return "pro";
392
+ }
393
+ return "free";
394
+ }
395
+ determinePermissions(tokenPayload) {
396
+ const permissions = ["read", "write"];
397
+ if (tokenPayload["https://stackmemory.ai/permissions"]) {
398
+ return tokenPayload["https://stackmemory.ai/permissions"];
399
+ }
400
+ if (tokenPayload.permissions && Array.isArray(tokenPayload.permissions)) {
401
+ return tokenPayload.permissions;
402
+ }
403
+ if (tokenPayload.roles && Array.isArray(tokenPayload.roles)) {
404
+ if (tokenPayload.roles.includes("admin")) {
405
+ permissions.push("admin", "delete");
406
+ }
407
+ if (tokenPayload.roles.includes("moderator")) {
408
+ permissions.push("moderate");
409
+ }
410
+ }
411
+ return permissions;
412
+ }
413
+ extractOrganizations(tokenPayload) {
414
+ const orgs = [];
415
+ if (tokenPayload["https://stackmemory.ai/organizations"]) {
416
+ return tokenPayload["https://stackmemory.ai/organizations"];
417
+ }
418
+ if (tokenPayload.org_id) {
419
+ orgs.push({
420
+ id: tokenPayload.org_id,
421
+ name: tokenPayload.org_name || tokenPayload.org_id,
422
+ role: tokenPayload.org_role || "member"
423
+ });
424
+ }
425
+ return orgs;
426
+ }
427
+ async initializeMockUser() {
428
+ const mockSub = "dev-sub";
429
+ let dbUser = await this.userModel.findUserBySub(mockSub);
430
+ if (!dbUser) {
431
+ dbUser = await this.userModel.createUser({
432
+ sub: mockSub,
433
+ email: "dev@stackmemory.local",
434
+ name: "Development User",
435
+ tier: "enterprise",
436
+ permissions: ["read", "write", "admin", "delete"],
437
+ organizations: [
438
+ {
439
+ id: "dev-org",
440
+ name: "Development Organization",
441
+ role: "admin"
442
+ }
443
+ ],
444
+ metadata: {
445
+ isDevelopmentUser: true,
446
+ createdAt: (/* @__PURE__ */ new Date()).toISOString()
447
+ }
448
+ });
449
+ logger.info("Created development mock user");
450
+ }
451
+ return {
452
+ id: dbUser.id,
453
+ sub: dbUser.sub,
454
+ email: dbUser.email,
455
+ name: dbUser.name,
456
+ picture: dbUser.avatar,
457
+ tier: dbUser.tier,
458
+ permissions: dbUser.permissions,
459
+ organizations: dbUser.organizations.map((org) => org.id),
460
+ metadata: dbUser.metadata
461
+ };
462
+ }
463
+ getMockUser() {
464
+ if (this.mockUser) {
465
+ return this.mockUser;
466
+ }
467
+ if (!this.mockUserInitializing) {
468
+ this.mockUserInitializing = true;
469
+ this.initializeMockUser().then((user) => {
470
+ this.mockUser = user;
471
+ this.mockUserInitializing = false;
472
+ logger.info("Mock user initialized and cached");
473
+ }).catch((err) => {
474
+ logger.error("Failed to initialize mock user", err);
475
+ this.mockUserInitializing = false;
476
+ });
477
+ }
478
+ return {
479
+ id: "temp-dev-user-id",
480
+ sub: "dev-sub",
481
+ email: "dev@stackmemory.local",
482
+ name: "Development User",
483
+ tier: "enterprise",
484
+ permissions: ["read", "write", "admin", "delete"],
485
+ organizations: ["dev-org"],
486
+ metadata: { temporary: true }
487
+ };
488
+ }
489
+ /**
490
+ * Revoke a token (add to blacklist)
491
+ */
492
+ async revokeToken(token) {
493
+ this.blacklistedTokens.add(token);
494
+ await this.redis.publish("token:revoked", token);
495
+ const decoded = jwt.decode(token);
496
+ if (decoded?.exp) {
497
+ const ttl = decoded.exp - Math.floor(Date.now() / 1e3);
498
+ if (ttl > 0) {
499
+ await this.redis.setex(`blacklist:${token}`, ttl, "1");
500
+ }
501
+ }
502
+ }
503
+ /**
504
+ * Cleanup resources
505
+ */
506
+ async close() {
507
+ await this.redis.quit();
508
+ }
509
+ }
510
+ export {
511
+ AuthMiddleware
512
+ };
513
+ //# sourceMappingURL=auth-middleware.js.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../../../src/servers/production/auth-middleware.ts"],
4
+ "sourcesContent": ["/**\n * Production Authentication Middleware for Runway MCP Server\n * Implements JWT validation with Auth0, refresh tokens, and rate limiting\n */\n\nimport jwt from 'jsonwebtoken';\nimport jwksRsa from 'jwks-rsa';\nimport { Request, Response, NextFunction } from 'express';\nimport { RateLimiterRedis, RateLimiterRes } from 'rate-limiter-flexible';\nimport Redis from 'ioredis';\nimport BetterSqlite3 from 'better-sqlite3';\nimport { logger } from '../../core/monitoring/logger.js';\nimport { metrics } from '../../core/monitoring/metrics.js';\nimport { getUserModel, UserModel, User } from '../../models/user.model.js';\n\nexport interface AuthUser {\n id: string;\n email: string;\n sub: string;\n name?: string;\n picture?: string;\n tier: 'free' | 'pro' | 'enterprise';\n organizations?: string[];\n permissions: string[];\n metadata?: Record<string, any>;\n}\n\nexport interface AuthRequest extends Request {\n user?: AuthUser;\n rateLimitInfo?: RateLimiterRes;\n}\n\nexport class AuthMiddleware {\n private jwksClient: jwksRsa.JwksClient;\n private redis: Redis;\n private rateLimiters!: Map<string, RateLimiterRedis>;\n private blacklistedTokens: Set<string> = new Set();\n private userModel: UserModel;\n private db: BetterSqlite3.Database;\n private mockUser?: AuthUser;\n private mockUserInitializing = false;\n\n constructor(\n private config: {\n auth0Domain: string;\n auth0Audience: string;\n redisUrl: string;\n jwtSecret?: string;\n bypassAuth?: boolean; // For testing\n dbPath?: string; // Path to SQLite database\n }\n ) {\n this.redis = new Redis(config.redisUrl);\n\n // Initialize database\n const dbPath =\n config.dbPath || process.env.STACKMEMORY_DB || '.stackmemory/auth.db';\n this.db = new BetterSqlite3(dbPath);\n this.userModel = getUserModel(this.db);\n\n this.jwksClient = jwksRsa({\n jwksUri: `https://${config.auth0Domain}/.well-known/jwks.json`,\n cache: true,\n cacheMaxAge: 600000, // 10 minutes\n rateLimit: true,\n jwksRequestsPerMinute: 5,\n });\n\n this.initializeRateLimiters();\n this.setupTokenBlacklistSync();\n }\n\n private initializeRateLimiters(): void {\n // Different rate limits for different tiers\n this.rateLimiters = new Map([\n [\n 'free',\n new RateLimiterRedis({\n storeClient: this.redis,\n keyPrefix: 'rl:free',\n points: 100, // requests\n duration: 900, // per 15 minutes\n blockDuration: 900, // block for 15 minutes\n }),\n ],\n [\n 'pro',\n new RateLimiterRedis({\n storeClient: this.redis,\n keyPrefix: 'rl:pro',\n points: 1000,\n duration: 900,\n blockDuration: 300,\n }),\n ],\n [\n 'enterprise',\n new RateLimiterRedis({\n storeClient: this.redis,\n keyPrefix: 'rl:enterprise',\n points: 10000,\n duration: 900,\n blockDuration: 60,\n }),\n ],\n ]);\n\n // Special rate limiter for auth endpoints\n this.rateLimiters.set(\n 'auth',\n new RateLimiterRedis({\n storeClient: this.redis,\n keyPrefix: 'rl:auth',\n points: 10, // Only 10 auth attempts\n duration: 900,\n blockDuration: 3600, // Block for 1 hour on excessive auth attempts\n })\n );\n }\n\n private setupTokenBlacklistSync(): void {\n // Subscribe to token revocation events\n const subscriber = new Redis(this.config.redisUrl);\n subscriber.subscribe('token:revoked');\n\n subscriber.on('message', (channel, token) => {\n if (channel === 'token:revoked') {\n this.blacklistedTokens.add(token);\n // Clean up old tokens periodically\n if (this.blacklistedTokens.size > 10000) {\n this.blacklistedTokens.clear();\n }\n }\n });\n }\n\n private async getSigningKey(kid: string): Promise<string> {\n return new Promise((resolve, reject) => {\n this.jwksClient.getSigningKey(kid, (err, key) => {\n if (err) {\n reject(err);\n } else {\n const signingKey = key?.getPublicKey();\n if (!signingKey) {\n reject(new Error('No signing key found'));\n } else {\n resolve(signingKey);\n }\n }\n });\n });\n }\n\n /**\n * Main authentication middleware\n */\n public authenticate = async (\n req: AuthRequest,\n res: Response,\n next: NextFunction\n ): Promise<any> => {\n const startTime = Date.now();\n\n try {\n // Bypass auth for health checks\n if (req.path === '/health' || req.path === '/metrics') {\n return next();\n }\n\n // Development bypass\n if (this.config.bypassAuth && process.env.NODE_ENV === 'development') {\n req.user = this.getMockUser();\n return next();\n }\n\n // Extract token or API key\n const token = this.extractToken(req);\n const apiKey = this.extractApiKey(req);\n\n if (!token && !apiKey) {\n metrics.increment('auth.missing_credentials');\n return res.status(401).json({\n error: 'Authentication required',\n code: 'MISSING_CREDENTIALS',\n });\n }\n\n // API Key authentication\n if (apiKey) {\n const user = await this.userModel.validateApiKey(apiKey);\n if (!user) {\n metrics.increment('auth.invalid_api_key');\n return res.status(401).json({\n error: 'Invalid API key',\n code: 'INVALID_API_KEY',\n });\n }\n\n // Convert to AuthUser format\n req.user = {\n id: user.id,\n sub: user.sub,\n email: user.email,\n name: user.name,\n picture: user.avatar,\n tier: user.tier,\n permissions: user.permissions,\n organizations: user.organizations.map((org) => org.id),\n metadata: { ...user.metadata, authMethod: 'api_key' },\n };\n\n metrics.increment('auth.api_key_success');\n await metrics.timing('auth.api_key_duration', Date.now() - startTime);\n return next();\n }\n\n // Check blacklist for JWT tokens\n if (token && this.blacklistedTokens.has(token)) {\n metrics.increment('auth.blacklisted_token');\n return res.status(401).json({\n error: 'Token has been revoked',\n code: 'TOKEN_REVOKED',\n });\n }\n\n // Ensure token exists for JWT processing\n if (!token) {\n // This should not happen as we checked earlier, but TypeScript needs this\n return res.status(401).json({\n error: 'No token provided',\n code: 'NO_TOKEN',\n });\n }\n\n // Decode and verify token\n const decoded = jwt.decode(token, { complete: true }) as any;\n if (!decoded) {\n metrics.increment('auth.invalid_token');\n return res.status(401).json({\n error: 'Invalid token format',\n code: 'INVALID_TOKEN',\n });\n }\n\n // Get signing key and verify\n const signingKey = await this.getSigningKey(decoded.header.kid);\n const verified = jwt.verify(token, signingKey, {\n algorithms: ['RS256'],\n audience: this.config.auth0Audience,\n issuer: `https://${this.config.auth0Domain}/`,\n }) as any;\n\n // Load user from database or cache\n const user = await this.loadUser(verified.sub, verified);\n if (!user) {\n metrics.increment('auth.user_not_found');\n return res.status(403).json({\n error: 'User not found',\n code: 'USER_NOT_FOUND',\n });\n }\n\n // Check user suspension\n if (user.metadata?.suspended) {\n metrics.increment('auth.user_suspended');\n return res.status(403).json({\n error: 'Account suspended',\n code: 'ACCOUNT_SUSPENDED',\n });\n }\n\n // Apply rate limiting\n const rateLimiter =\n this.rateLimiters.get(user.tier) || this.rateLimiters.get('free')!;\n try {\n const rateLimitRes = await rateLimiter.consume(user.id);\n req.rateLimitInfo = rateLimitRes;\n\n // Add rate limit headers\n res.setHeader('X-RateLimit-Limit', rateLimiter.points.toString());\n res.setHeader(\n 'X-RateLimit-Remaining',\n rateLimitRes.remainingPoints.toString()\n );\n res.setHeader(\n 'X-RateLimit-Reset',\n new Date(Date.now() + rateLimitRes.msBeforeNext).toISOString()\n );\n } catch (rateLimitError: any) {\n metrics.increment('auth.rate_limited');\n res.setHeader(\n 'Retry-After',\n Math.round(rateLimitError.msBeforeNext / 1000).toString()\n );\n return res.status(429).json({\n error: 'Too many requests',\n code: 'RATE_LIMITED',\n retryAfter: rateLimitError.msBeforeNext,\n });\n }\n\n // Attach user to request\n req.user = user;\n\n // Track metrics\n metrics.increment('auth.success', { tier: user.tier });\n metrics.timing('auth.duration', Date.now() - startTime);\n\n logger.info('Authentication successful', {\n userId: user.id,\n tier: user.tier,\n path: req.path,\n });\n\n next();\n } catch (error: any) {\n metrics.increment('auth.error');\n logger.error('Authentication error', error);\n\n if (error.name === 'TokenExpiredError') {\n return res.status(401).json({\n error: 'Token expired',\n code: 'TOKEN_EXPIRED',\n });\n }\n\n if (error.name === 'JsonWebTokenError') {\n return res.status(401).json({\n error: 'Invalid token',\n code: 'INVALID_TOKEN',\n });\n }\n\n res.status(500).json({\n error: 'Authentication failed',\n code: 'AUTH_ERROR',\n });\n }\n };\n\n /**\n * WebSocket authentication handler\n */\n public authenticateWebSocket = async (\n token: string\n ): Promise<AuthUser | null> => {\n try {\n const decoded = jwt.decode(token, { complete: true }) as any;\n if (!decoded || this.blacklistedTokens.has(token)) {\n return null;\n }\n\n const signingKey = await this.getSigningKey(decoded.header.kid);\n const verified = jwt.verify(token, signingKey, {\n algorithms: ['RS256'],\n audience: this.config.auth0Audience,\n issuer: `https://${this.config.auth0Domain}/`,\n }) as any;\n\n return await this.loadUser(verified.sub, verified);\n } catch (error) {\n logger.error(\n 'WebSocket authentication failed',\n error instanceof Error ? error : undefined\n );\n return null;\n }\n };\n\n /**\n * Permission checking middleware\n */\n public requirePermission = (permission: string) => {\n return (req: AuthRequest, res: Response, next: NextFunction) => {\n if (!req.user) {\n return res.status(401).json({\n error: 'Authentication required',\n code: 'NOT_AUTHENTICATED',\n });\n }\n\n if (!req.user.permissions.includes(permission)) {\n metrics.increment('auth.permission_denied', { permission });\n return res.status(403).json({\n error: 'Insufficient permissions',\n code: 'PERMISSION_DENIED',\n required: permission,\n });\n }\n\n return next();\n };\n };\n\n /**\n * Organization access middleware\n */\n public requireOrganization = (\n req: AuthRequest,\n res: Response,\n next: NextFunction\n ) => {\n const orgId = req.params.orgId || req.query.orgId;\n\n if (!req.user || !orgId) {\n return res.status(401).json({\n error: 'Authentication required',\n code: 'NOT_AUTHENTICATED',\n });\n }\n\n if (!req.user.organizations?.includes(orgId as string)) {\n return res.status(403).json({\n error: 'Organization access denied',\n code: 'ORG_ACCESS_DENIED',\n });\n }\n\n return next();\n };\n\n private extractApiKey(req: Request): string | null {\n // Check Authorization header for API key\n const authHeader = req.headers.authorization;\n if (authHeader?.startsWith('Bearer sk-')) {\n return authHeader.substring(7);\n }\n\n // Check X-API-Key header\n const apiKeyHeader = req.headers['x-api-key'] as string;\n if (apiKeyHeader?.startsWith('sk-')) {\n return apiKeyHeader;\n }\n\n // Query parameter support removed for security reasons\n // API keys should only be sent via headers to prevent:\n // - URL logging exposure\n // - Browser history leakage\n // - Referer header transmission\n\n return null;\n }\n\n private extractToken(req: Request): string | null {\n const authHeader = req.headers.authorization;\n if (\n authHeader?.startsWith('Bearer ') &&\n !authHeader.startsWith('Bearer sk-')\n ) {\n return authHeader.substring(7);\n }\n\n // Also check cookie for web clients\n return req.cookies?.access_token || null;\n }\n\n private async loadUser(\n sub: string,\n tokenPayload?: any\n ): Promise<AuthUser | null> {\n // Try cache first\n const cached = await this.redis.get(`user:${sub}`);\n if (cached) {\n const cachedUser = JSON.parse(cached);\n // Update last login time in background\n this.userModel\n .updateLastLogin(cachedUser.id)\n .catch((err) => logger.error('Failed to update last login', err));\n return cachedUser;\n }\n\n // Load from database\n let dbUser = await this.userModel.findUserBySub(sub);\n\n // If user doesn't exist, create from token payload\n if (!dbUser && tokenPayload) {\n dbUser = await this.userModel.createUser({\n sub,\n email: tokenPayload.email || `${sub}@auth.local`,\n name: tokenPayload.name,\n avatar: tokenPayload.picture,\n tier: this.determineTier(tokenPayload),\n permissions: this.determinePermissions(tokenPayload),\n organizations: this.extractOrganizations(tokenPayload),\n metadata: {\n auth0: tokenPayload,\n signupSource: 'auth0',\n createdVia: 'auth-middleware',\n },\n });\n logger.info('Auto-created user from auth token', {\n sub,\n email: dbUser.email,\n });\n }\n\n if (!dbUser) {\n return null;\n }\n\n // Update last login\n await this.userModel.updateLastLogin(dbUser.id);\n\n // Convert to AuthUser format\n const user: AuthUser = {\n id: dbUser.id,\n sub: dbUser.sub,\n email: dbUser.email,\n name: dbUser.name,\n picture: dbUser.avatar,\n tier: dbUser.tier,\n permissions: dbUser.permissions,\n organizations: dbUser.organizations.map((org) => org.id),\n metadata: dbUser.metadata,\n };\n\n // Cache for 5 minutes\n await this.redis.setex(`user:${sub}`, 300, JSON.stringify(user));\n\n return user;\n }\n\n private determineTier(tokenPayload: any): 'free' | 'pro' | 'enterprise' {\n // Check custom claims or metadata\n if (tokenPayload['https://stackmemory.ai/tier']) {\n return tokenPayload['https://stackmemory.ai/tier'];\n }\n\n // Check for subscription info\n if (tokenPayload.subscription?.plan) {\n const plan = tokenPayload.subscription.plan.toLowerCase();\n if (plan.includes('enterprise')) return 'enterprise';\n if (plan.includes('pro') || plan.includes('premium')) return 'pro';\n }\n\n // Default to free\n return 'free';\n }\n\n private determinePermissions(tokenPayload: any): string[] {\n const permissions: string[] = ['read', 'write'];\n\n // Check custom permissions claim\n if (tokenPayload['https://stackmemory.ai/permissions']) {\n return tokenPayload['https://stackmemory.ai/permissions'];\n }\n\n // Check standard permissions\n if (tokenPayload.permissions && Array.isArray(tokenPayload.permissions)) {\n return tokenPayload.permissions;\n }\n\n // Check roles\n if (tokenPayload.roles && Array.isArray(tokenPayload.roles)) {\n if (tokenPayload.roles.includes('admin')) {\n permissions.push('admin', 'delete');\n }\n if (tokenPayload.roles.includes('moderator')) {\n permissions.push('moderate');\n }\n }\n\n return permissions;\n }\n\n private extractOrganizations(\n tokenPayload: any\n ): Array<{ id: string; name: string; role: string }> {\n const orgs: Array<{ id: string; name: string; role: string }> = [];\n\n // Check custom organization claim\n if (tokenPayload['https://stackmemory.ai/organizations']) {\n return tokenPayload['https://stackmemory.ai/organizations'];\n }\n\n // Check Auth0 organizations\n if (tokenPayload.org_id) {\n orgs.push({\n id: tokenPayload.org_id,\n name: tokenPayload.org_name || tokenPayload.org_id,\n role: tokenPayload.org_role || 'member',\n });\n }\n\n return orgs;\n }\n\n private async initializeMockUser(): Promise<AuthUser> {\n const mockSub = 'dev-sub';\n\n // Check if user exists in database\n let dbUser = await this.userModel.findUserBySub(mockSub);\n\n if (!dbUser) {\n // Create mock user in database\n dbUser = await this.userModel.createUser({\n sub: mockSub,\n email: 'dev@stackmemory.local',\n name: 'Development User',\n tier: 'enterprise',\n permissions: ['read', 'write', 'admin', 'delete'],\n organizations: [\n {\n id: 'dev-org',\n name: 'Development Organization',\n role: 'admin',\n },\n ],\n metadata: {\n isDevelopmentUser: true,\n createdAt: new Date().toISOString(),\n },\n });\n logger.info('Created development mock user');\n }\n\n return {\n id: dbUser.id,\n sub: dbUser.sub,\n email: dbUser.email,\n name: dbUser.name,\n picture: dbUser.avatar,\n tier: dbUser.tier,\n permissions: dbUser.permissions,\n organizations: dbUser.organizations.map((org) => org.id),\n metadata: dbUser.metadata,\n };\n }\n\n private getMockUser(): AuthUser {\n // Return cached mock user if available\n if (this.mockUser) {\n return this.mockUser;\n }\n\n // Initialize mock user synchronously to prevent race conditions\n // This runs during constructor or first use\n if (!this.mockUserInitializing) {\n this.mockUserInitializing = true;\n\n // Initialize asynchronously but return a temporary user immediately\n this.initializeMockUser()\n .then((user) => {\n this.mockUser = user;\n this.mockUserInitializing = false;\n logger.info('Mock user initialized and cached');\n })\n .catch((err) => {\n logger.error('Failed to initialize mock user', err);\n this.mockUserInitializing = false;\n });\n }\n\n // Return temporary mock user while initialization is in progress\n return {\n id: 'temp-dev-user-id',\n sub: 'dev-sub',\n email: 'dev@stackmemory.local',\n name: 'Development User',\n tier: 'enterprise',\n permissions: ['read', 'write', 'admin', 'delete'],\n organizations: ['dev-org'],\n metadata: { temporary: true },\n };\n }\n\n /**\n * Revoke a token (add to blacklist)\n */\n public async revokeToken(token: string): Promise<void> {\n this.blacklistedTokens.add(token);\n await this.redis.publish('token:revoked', token);\n\n // Also store in Redis with TTL matching token expiry\n const decoded = jwt.decode(token) as any;\n if (decoded?.exp) {\n const ttl = decoded.exp - Math.floor(Date.now() / 1000);\n if (ttl > 0) {\n await this.redis.setex(`blacklist:${token}`, ttl, '1');\n }\n }\n }\n\n /**\n * Cleanup resources\n */\n public async close(): Promise<void> {\n await this.redis.quit();\n }\n}\n"],
5
+ "mappings": "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",
6
+ "names": ["user"]
7
+ }