@stackmemoryai/stackmemory 0.2.8 → 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 (608) 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/compaction-handler.d.ts.map +1 -1
  317. package/dist/src/core/context/compaction-handler.js +1 -1
  318. package/dist/src/core/context/compaction-handler.js.map +1 -1
  319. package/dist/src/core/context/frame-database.d.ts +59 -0
  320. package/dist/src/core/context/frame-database.d.ts.map +1 -0
  321. package/dist/src/core/context/frame-database.js +333 -0
  322. package/dist/src/core/context/frame-database.js.map +1 -0
  323. package/dist/src/core/context/frame-digest.d.ts +59 -0
  324. package/dist/src/core/context/frame-digest.d.ts.map +1 -0
  325. package/dist/src/core/context/frame-digest.js +264 -0
  326. package/dist/src/core/context/frame-digest.js.map +1 -0
  327. package/dist/src/core/context/frame-manager.d.ts +2 -0
  328. package/dist/src/core/context/frame-manager.d.ts.map +1 -1
  329. package/dist/src/core/context/frame-manager.js +7 -0
  330. package/dist/src/core/context/frame-manager.js.map +1 -1
  331. package/dist/src/core/context/frame-stack.d.ts +85 -0
  332. package/dist/src/core/context/frame-stack.d.ts.map +1 -0
  333. package/dist/src/core/context/frame-stack.js +287 -0
  334. package/dist/src/core/context/frame-stack.js.map +1 -0
  335. package/dist/src/core/context/frame-types.d.ts +67 -0
  336. package/dist/src/core/context/frame-types.d.ts.map +1 -0
  337. package/dist/src/core/context/frame-types.js +6 -0
  338. package/dist/src/core/context/frame-types.js.map +1 -0
  339. package/dist/src/core/context/index.d.ts +11 -0
  340. package/dist/src/core/context/index.d.ts.map +1 -0
  341. package/dist/src/core/context/index.js +14 -0
  342. package/dist/src/core/context/index.js.map +1 -0
  343. package/dist/src/core/context/refactored-frame-manager.d.ts +99 -0
  344. package/dist/src/core/context/refactored-frame-manager.d.ts.map +1 -0
  345. package/dist/src/core/context/refactored-frame-manager.js +340 -0
  346. package/dist/src/core/context/refactored-frame-manager.js.map +1 -0
  347. package/dist/src/core/database/batch-operations.d.ts +118 -0
  348. package/dist/src/core/database/batch-operations.d.ts.map +1 -0
  349. package/dist/src/core/database/batch-operations.js +339 -0
  350. package/dist/src/core/database/batch-operations.js.map +1 -0
  351. package/dist/src/core/database/connection-pool.d.ts +79 -0
  352. package/dist/src/core/database/connection-pool.d.ts.map +1 -0
  353. package/dist/src/core/database/connection-pool.js +236 -0
  354. package/dist/src/core/database/connection-pool.js.map +1 -0
  355. package/dist/src/core/database/query-cache.d.ts +135 -0
  356. package/dist/src/core/database/query-cache.d.ts.map +1 -0
  357. package/dist/src/core/database/query-cache.js +294 -0
  358. package/dist/src/core/database/query-cache.js.map +1 -0
  359. package/dist/src/core/digest/enhanced-hybrid-digest.d.ts +125 -0
  360. package/dist/src/core/digest/enhanced-hybrid-digest.d.ts.map +1 -0
  361. package/dist/src/core/digest/enhanced-hybrid-digest.js +282 -0
  362. package/dist/src/core/digest/enhanced-hybrid-digest.js.map +1 -0
  363. package/dist/src/core/digest/frame-digest-integration.d.ts +67 -0
  364. package/dist/src/core/digest/frame-digest-integration.d.ts.map +1 -0
  365. package/dist/src/core/digest/frame-digest-integration.js +198 -0
  366. package/dist/src/core/digest/frame-digest-integration.js.map +1 -0
  367. package/dist/src/core/digest/hybrid-digest-generator.d.ts +76 -0
  368. package/dist/src/core/digest/hybrid-digest-generator.d.ts.map +1 -0
  369. package/dist/src/core/digest/hybrid-digest-generator.js +629 -0
  370. package/dist/src/core/digest/hybrid-digest-generator.js.map +1 -0
  371. package/dist/src/core/digest/index.d.ts +9 -0
  372. package/dist/src/core/digest/index.d.ts.map +1 -0
  373. package/dist/src/core/digest/index.js +9 -0
  374. package/dist/src/core/digest/index.js.map +1 -0
  375. package/dist/src/core/digest/types.d.ts +154 -0
  376. package/dist/src/core/digest/types.d.ts.map +1 -0
  377. package/dist/src/core/digest/types.js +18 -0
  378. package/dist/src/core/digest/types.js.map +1 -0
  379. package/dist/src/core/errors/index.d.ts +13 -5
  380. package/dist/src/core/errors/index.d.ts.map +1 -1
  381. package/dist/src/core/errors/index.js +13 -5
  382. package/dist/src/core/errors/index.js.map +1 -1
  383. package/dist/src/core/merge/conflict-detector.d.ts +122 -0
  384. package/dist/src/core/merge/conflict-detector.d.ts.map +1 -0
  385. package/dist/src/core/merge/conflict-detector.js +468 -0
  386. package/dist/src/core/merge/conflict-detector.js.map +1 -0
  387. package/dist/src/core/merge/index.d.ts +9 -0
  388. package/dist/src/core/merge/index.d.ts.map +1 -0
  389. package/dist/src/core/merge/index.js +9 -0
  390. package/dist/src/core/merge/index.js.map +1 -0
  391. package/dist/src/core/merge/resolution-engine.d.ts +120 -0
  392. package/dist/src/core/merge/resolution-engine.d.ts.map +1 -0
  393. package/dist/src/core/merge/resolution-engine.js +573 -0
  394. package/dist/src/core/merge/resolution-engine.js.map +1 -0
  395. package/dist/src/core/merge/stack-diff.d.ts +97 -0
  396. package/dist/src/core/merge/stack-diff.d.ts.map +1 -0
  397. package/dist/src/core/merge/stack-diff.js +516 -0
  398. package/dist/src/core/merge/stack-diff.js.map +1 -0
  399. package/dist/src/core/merge/types.d.ts +110 -0
  400. package/dist/src/core/merge/types.d.ts.map +1 -0
  401. package/dist/src/core/merge/types.js +6 -0
  402. package/dist/src/core/merge/types.js.map +1 -0
  403. package/dist/src/core/monitoring/logger.d.ts +2 -2
  404. package/dist/src/core/monitoring/logger.d.ts.map +1 -1
  405. package/dist/src/core/monitoring/logger.js +10 -5
  406. package/dist/src/core/monitoring/logger.js.map +1 -1
  407. package/dist/src/core/monitoring/metrics.d.ts +3 -0
  408. package/dist/src/core/monitoring/metrics.d.ts.map +1 -1
  409. package/dist/src/core/monitoring/metrics.js +142 -3
  410. package/dist/src/core/monitoring/metrics.js.map +1 -1
  411. package/dist/src/core/performance/context-cache.d.ts +109 -0
  412. package/dist/src/core/performance/context-cache.d.ts.map +1 -0
  413. package/dist/src/core/performance/context-cache.js +280 -0
  414. package/dist/src/core/performance/context-cache.js.map +1 -0
  415. package/dist/src/core/performance/index.d.ts +3 -0
  416. package/dist/src/core/performance/index.d.ts.map +1 -0
  417. package/dist/src/core/performance/index.js +3 -0
  418. package/dist/src/core/performance/index.js.map +1 -0
  419. package/dist/src/core/performance/lazy-context-loader.d.ts +93 -0
  420. package/dist/src/core/performance/lazy-context-loader.d.ts.map +1 -0
  421. package/dist/src/core/performance/lazy-context-loader.js +332 -0
  422. package/dist/src/core/performance/lazy-context-loader.js.map +1 -0
  423. package/dist/src/core/performance/monitor.d.ts +48 -0
  424. package/dist/src/core/performance/monitor.d.ts.map +1 -0
  425. package/dist/src/core/performance/monitor.js +226 -0
  426. package/dist/src/core/performance/monitor.js.map +1 -0
  427. package/dist/src/core/performance/optimized-frame-context.d.ts +74 -0
  428. package/dist/src/core/performance/optimized-frame-context.d.ts.map +1 -0
  429. package/dist/src/core/performance/optimized-frame-context.js +330 -0
  430. package/dist/src/core/performance/optimized-frame-context.js.map +1 -0
  431. package/dist/src/core/performance/performance-benchmark.d.ts +50 -0
  432. package/dist/src/core/performance/performance-benchmark.d.ts.map +1 -0
  433. package/dist/src/core/performance/performance-benchmark.js +290 -0
  434. package/dist/src/core/performance/performance-benchmark.js.map +1 -0
  435. package/dist/src/core/performance/performance-profiler.d.ts +151 -0
  436. package/dist/src/core/performance/performance-profiler.d.ts.map +1 -0
  437. package/dist/src/core/performance/performance-profiler.js +346 -0
  438. package/dist/src/core/performance/performance-profiler.js.map +1 -0
  439. package/dist/src/core/performance/streaming-jsonl-parser.d.ts +41 -0
  440. package/dist/src/core/performance/streaming-jsonl-parser.d.ts.map +1 -0
  441. package/dist/src/core/performance/streaming-jsonl-parser.js +193 -0
  442. package/dist/src/core/performance/streaming-jsonl-parser.js.map +1 -0
  443. package/dist/src/core/persistence/postgres-adapter.d.ts +31 -0
  444. package/dist/src/core/persistence/postgres-adapter.d.ts.map +1 -0
  445. package/dist/src/core/persistence/postgres-adapter.js +330 -0
  446. package/dist/src/core/persistence/postgres-adapter.js.map +1 -0
  447. package/dist/src/core/query/query-parser.d.ts +5 -0
  448. package/dist/src/core/query/query-parser.d.ts.map +1 -1
  449. package/dist/src/core/query/query-parser.js +86 -18
  450. package/dist/src/core/query/query-parser.js.map +1 -1
  451. package/dist/src/core/query/query-templates.d.ts +44 -0
  452. package/dist/src/core/query/query-templates.d.ts.map +1 -0
  453. package/dist/src/core/query/query-templates.js +326 -0
  454. package/dist/src/core/query/query-templates.js.map +1 -0
  455. package/dist/src/core/retrieval/llm-context-retrieval.d.ts +5 -3
  456. package/dist/src/core/retrieval/llm-context-retrieval.d.ts.map +1 -1
  457. package/dist/src/core/retrieval/llm-context-retrieval.js +73 -21
  458. package/dist/src/core/retrieval/llm-context-retrieval.js.map +1 -1
  459. package/dist/src/core/trace/cli-trace-wrapper.d.ts +23 -0
  460. package/dist/src/core/trace/cli-trace-wrapper.d.ts.map +1 -0
  461. package/dist/src/core/trace/cli-trace-wrapper.js +141 -0
  462. package/dist/src/core/trace/cli-trace-wrapper.js.map +1 -0
  463. package/dist/src/core/trace/db-trace-wrapper.d.ts +36 -0
  464. package/dist/src/core/trace/db-trace-wrapper.d.ts.map +1 -0
  465. package/dist/src/core/trace/db-trace-wrapper.js +252 -0
  466. package/dist/src/core/trace/db-trace-wrapper.js.map +1 -0
  467. package/dist/src/core/trace/debug-trace.d.ts +84 -0
  468. package/dist/src/core/trace/debug-trace.d.ts.map +1 -0
  469. package/dist/src/core/trace/debug-trace.js +402 -0
  470. package/dist/src/core/trace/debug-trace.js.map +1 -0
  471. package/dist/src/core/trace/error-test.d.ts +6 -0
  472. package/dist/src/core/trace/error-test.d.ts.map +1 -0
  473. package/dist/src/core/trace/error-test.js +128 -0
  474. package/dist/src/core/trace/error-test.js.map +1 -0
  475. package/dist/src/core/trace/index.d.ts +25 -0
  476. package/dist/src/core/trace/index.d.ts.map +1 -0
  477. package/dist/src/core/trace/index.js +121 -0
  478. package/dist/src/core/trace/index.js.map +1 -0
  479. package/dist/src/core/trace/linear-api-wrapper.d.ts +17 -0
  480. package/dist/src/core/trace/linear-api-wrapper.d.ts.map +1 -0
  481. package/dist/src/core/trace/linear-api-wrapper.js +205 -0
  482. package/dist/src/core/trace/linear-api-wrapper.js.map +1 -0
  483. package/dist/src/core/trace/performance-test.d.ts +6 -0
  484. package/dist/src/core/trace/performance-test.d.ts.map +1 -0
  485. package/dist/src/core/trace/performance-test.js +111 -0
  486. package/dist/src/core/trace/performance-test.js.map +1 -0
  487. package/dist/src/core/trace/trace-demo.d.ts +8 -0
  488. package/dist/src/core/trace/trace-demo.d.ts.map +1 -0
  489. package/dist/src/core/trace/trace-demo.js +154 -0
  490. package/dist/src/core/trace/trace-demo.js.map +1 -0
  491. package/dist/src/core/trace/trace-detector.d.ts +2 -2
  492. package/dist/src/core/trace/trace-detector.d.ts.map +1 -1
  493. package/dist/src/core/trace/trace-detector.demo.js +6 -6
  494. package/dist/src/core/trace/trace-detector.demo.js.map +1 -1
  495. package/dist/src/core/trace/trace-detector.js +3 -3
  496. package/dist/src/core/trace/trace-detector.js.map +1 -1
  497. package/dist/src/core/types.d.ts +35 -0
  498. package/dist/src/core/types.d.ts.map +1 -0
  499. package/dist/src/core/types.js +2 -0
  500. package/dist/src/core/types.js.map +1 -0
  501. package/dist/src/features/tasks/pebbles-task-store.d.ts +9 -2
  502. package/dist/src/features/tasks/pebbles-task-store.d.ts.map +1 -1
  503. package/dist/src/features/tasks/pebbles-task-store.js +97 -18
  504. package/dist/src/features/tasks/pebbles-task-store.js.map +1 -1
  505. package/dist/src/integrations/linear/auth.d.ts.map +1 -1
  506. package/dist/src/integrations/linear/auth.js.map +1 -1
  507. package/dist/src/integrations/linear/client.d.ts +15 -1
  508. package/dist/src/integrations/linear/client.d.ts.map +1 -1
  509. package/dist/src/integrations/linear/client.js +85 -3
  510. package/dist/src/integrations/linear/client.js.map +1 -1
  511. package/dist/src/integrations/linear/sync-manager.d.ts +2 -0
  512. package/dist/src/integrations/linear/sync-manager.d.ts.map +1 -1
  513. package/dist/src/integrations/linear/sync-manager.js +16 -4
  514. package/dist/src/integrations/linear/sync-manager.js.map +1 -1
  515. package/dist/src/integrations/linear/sync-service.d.ts +23 -2
  516. package/dist/src/integrations/linear/sync-service.d.ts.map +1 -1
  517. package/dist/src/integrations/linear/sync-service.js +44 -25
  518. package/dist/src/integrations/linear/sync-service.js.map +1 -1
  519. package/dist/src/integrations/linear/sync.d.ts +6 -0
  520. package/dist/src/integrations/linear/sync.d.ts.map +1 -1
  521. package/dist/src/integrations/linear/sync.js +27 -2
  522. package/dist/src/integrations/linear/sync.js.map +1 -1
  523. package/dist/src/integrations/linear/types.d.ts +16 -1
  524. package/dist/src/integrations/linear/types.d.ts.map +1 -1
  525. package/dist/src/integrations/linear/webhook-server.d.ts.map +1 -1
  526. package/dist/src/integrations/linear/webhook-server.js +10 -8
  527. package/dist/src/integrations/linear/webhook-server.js.map +1 -1
  528. package/dist/src/integrations/linear/webhook.d.ts +13 -0
  529. package/dist/src/integrations/linear/webhook.d.ts.map +1 -1
  530. package/dist/src/integrations/linear/webhook.js +101 -14
  531. package/dist/src/integrations/linear/webhook.js.map +1 -1
  532. package/dist/src/integrations/mcp/handlers/context-handlers.d.ts +39 -0
  533. package/dist/src/integrations/mcp/handlers/context-handlers.d.ts.map +1 -0
  534. package/dist/src/integrations/mcp/handlers/context-handlers.js +266 -0
  535. package/dist/src/integrations/mcp/handlers/context-handlers.js.map +1 -0
  536. package/dist/src/integrations/mcp/handlers/index.d.ts +37 -0
  537. package/dist/src/integrations/mcp/handlers/index.d.ts.map +1 -0
  538. package/dist/src/integrations/mcp/handlers/index.js +134 -0
  539. package/dist/src/integrations/mcp/handlers/index.js.map +1 -0
  540. package/dist/src/integrations/mcp/handlers/linear-handlers.d.ts +33 -0
  541. package/dist/src/integrations/mcp/handlers/linear-handlers.d.ts.map +1 -0
  542. package/dist/src/integrations/mcp/handlers/linear-handlers.js +251 -0
  543. package/dist/src/integrations/mcp/handlers/linear-handlers.js.map +1 -0
  544. package/dist/src/integrations/mcp/handlers/task-handlers.d.ts +42 -0
  545. package/dist/src/integrations/mcp/handlers/task-handlers.d.ts.map +1 -0
  546. package/dist/src/integrations/mcp/handlers/task-handlers.js +238 -0
  547. package/dist/src/integrations/mcp/handlers/task-handlers.js.map +1 -0
  548. package/dist/src/integrations/mcp/handlers/trace-handlers.d.ts +41 -0
  549. package/dist/src/integrations/mcp/handlers/trace-handlers.d.ts.map +1 -0
  550. package/dist/src/integrations/mcp/handlers/trace-handlers.js +298 -0
  551. package/dist/src/integrations/mcp/handlers/trace-handlers.js.map +1 -0
  552. package/dist/src/integrations/mcp/index.d.ts +13 -0
  553. package/dist/src/integrations/mcp/index.d.ts.map +1 -0
  554. package/dist/src/integrations/mcp/index.js +17 -0
  555. package/dist/src/integrations/mcp/index.js.map +1 -0
  556. package/dist/src/integrations/mcp/refactored-server.d.ts +76 -0
  557. package/dist/src/integrations/mcp/refactored-server.d.ts.map +1 -0
  558. package/dist/src/integrations/mcp/refactored-server.js +351 -0
  559. package/dist/src/integrations/mcp/refactored-server.js.map +1 -0
  560. package/dist/src/integrations/mcp/server.js +2 -2
  561. package/dist/src/integrations/mcp/server.js.map +1 -1
  562. package/dist/src/integrations/mcp/tool-definitions.d.ts +44 -0
  563. package/dist/src/integrations/mcp/tool-definitions.d.ts.map +1 -0
  564. package/dist/src/integrations/mcp/tool-definitions.js +563 -0
  565. package/dist/src/integrations/mcp/tool-definitions.js.map +1 -0
  566. package/dist/src/integrations/pg-aiguide/embedding-provider.d.ts +48 -0
  567. package/dist/src/integrations/pg-aiguide/embedding-provider.d.ts.map +1 -0
  568. package/dist/src/integrations/pg-aiguide/embedding-provider.js +190 -0
  569. package/dist/src/integrations/pg-aiguide/embedding-provider.js.map +1 -0
  570. package/dist/src/integrations/pg-aiguide/semantic-search.d.ts +34 -0
  571. package/dist/src/integrations/pg-aiguide/semantic-search.d.ts.map +1 -0
  572. package/dist/src/integrations/pg-aiguide/semantic-search.js +176 -0
  573. package/dist/src/integrations/pg-aiguide/semantic-search.js.map +1 -0
  574. package/dist/src/integrations/pg-aiguide/timescale-analytics.d.ts +44 -0
  575. package/dist/src/integrations/pg-aiguide/timescale-analytics.d.ts.map +1 -0
  576. package/dist/src/integrations/pg-aiguide/timescale-analytics.js +215 -0
  577. package/dist/src/integrations/pg-aiguide/timescale-analytics.js.map +1 -0
  578. package/dist/src/mcp/stackmemory-mcp-server.d.ts +9 -0
  579. package/dist/src/mcp/stackmemory-mcp-server.d.ts.map +1 -0
  580. package/dist/src/mcp/stackmemory-mcp-server.js +519 -0
  581. package/dist/src/mcp/stackmemory-mcp-server.js.map +1 -0
  582. package/dist/src/middleware/exponential-rate-limiter.d.ts +78 -0
  583. package/dist/src/middleware/exponential-rate-limiter.d.ts.map +1 -0
  584. package/dist/src/middleware/exponential-rate-limiter.js +293 -0
  585. package/dist/src/middleware/exponential-rate-limiter.js.map +1 -0
  586. package/dist/src/models/user.model.d.ts +62 -0
  587. package/dist/src/models/user.model.d.ts.map +1 -0
  588. package/dist/src/models/user.model.js +311 -0
  589. package/dist/src/models/user.model.js.map +1 -0
  590. package/dist/src/servers/production/auth-middleware.d.ts +12 -2
  591. package/dist/src/servers/production/auth-middleware.d.ts.map +1 -1
  592. package/dist/src/servers/production/auth-middleware.js +240 -28
  593. package/dist/src/servers/production/auth-middleware.js.map +1 -1
  594. package/dist/src/servers/railway/index.js.map +1 -1
  595. package/dist/src/services/context-service.d.ts.map +1 -1
  596. package/dist/src/services/context-service.js +86 -1
  597. package/dist/src/services/context-service.js.map +1 -1
  598. package/dist/src/validation/schemas.d.ts +633 -0
  599. package/dist/src/validation/schemas.d.ts.map +1 -0
  600. package/dist/src/validation/schemas.js +347 -0
  601. package/dist/src/validation/schemas.js.map +1 -0
  602. package/dist/types/task.js +1 -0
  603. package/dist/types/task.js.map +7 -0
  604. package/dist/utils/logger.js +52 -0
  605. package/dist/utils/logger.js.map +7 -0
  606. package/dist/validation/schemas.js +218 -0
  607. package/dist/validation/schemas.js.map +7 -0
  608. package/package.json +12 -3
@@ -0,0 +1,1621 @@
1
+ #!/usr/bin/env node
2
+ import { Server } from "@modelcontextprotocol/sdk/server/index.js";
3
+ import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
4
+ import { z } from "zod";
5
+ import Database from "better-sqlite3";
6
+ import { readFileSync, existsSync, mkdirSync } from "fs";
7
+ import { join, dirname } from "path";
8
+ import { execSync } from "child_process";
9
+ import { FrameManager } from "../../core/context/frame-manager.js";
10
+ import {
11
+ PebblesTaskStore
12
+ } from "../../features/tasks/pebbles-task-store.js";
13
+ import { LinearAuthManager } from "../linear/auth.js";
14
+ import { LinearSyncEngine, DEFAULT_SYNC_CONFIG } from "../linear/sync.js";
15
+ import { logger } from "../../core/monitoring/logger.js";
16
+ import { BrowserMCPIntegration } from "../../features/browser/browser-mcp.js";
17
+ import { TraceDetector } from "../../core/trace/trace-detector.js";
18
+ import { LLMContextRetrieval } from "../../core/retrieval/index.js";
19
+ import { v4 as uuidv4 } from "uuid";
20
+ class LocalStackMemoryMCP {
21
+ server;
22
+ db;
23
+ projectRoot;
24
+ frameManager;
25
+ taskStore;
26
+ linearAuthManager;
27
+ linearSync;
28
+ projectId;
29
+ contexts = /* @__PURE__ */ new Map();
30
+ browserMCP;
31
+ traceDetector;
32
+ contextRetrieval;
33
+ constructor() {
34
+ this.projectRoot = this.findProjectRoot();
35
+ this.projectId = this.getProjectId();
36
+ const dbDir = join(this.projectRoot, ".stackmemory");
37
+ if (!existsSync(dbDir)) {
38
+ mkdirSync(dbDir, { recursive: true });
39
+ }
40
+ const dbPath = join(dbDir, "context.db");
41
+ this.db = new Database(dbPath);
42
+ this.initDB();
43
+ this.frameManager = new FrameManager(this.db, this.projectId);
44
+ this.taskStore = new PebblesTaskStore(this.projectRoot, this.db);
45
+ this.linearAuthManager = new LinearAuthManager(this.projectRoot);
46
+ this.linearSync = new LinearSyncEngine(
47
+ this.taskStore,
48
+ this.linearAuthManager,
49
+ DEFAULT_SYNC_CONFIG
50
+ );
51
+ this.server = new Server(
52
+ {
53
+ name: "stackmemory-local",
54
+ version: "0.1.0"
55
+ },
56
+ {
57
+ capabilities: {
58
+ tools: {}
59
+ }
60
+ }
61
+ );
62
+ this.browserMCP = new BrowserMCPIntegration({
63
+ headless: process.env.BROWSER_HEADLESS !== "false",
64
+ defaultViewport: { width: 1280, height: 720 }
65
+ });
66
+ this.traceDetector = new TraceDetector({}, void 0, this.db);
67
+ this.contextRetrieval = new LLMContextRetrieval(
68
+ this.db,
69
+ this.frameManager,
70
+ this.projectId
71
+ );
72
+ this.setupHandlers();
73
+ this.loadInitialContext();
74
+ this.browserMCP.initialize(this.server).catch((error) => {
75
+ logger.error("Failed to initialize Browser MCP", error);
76
+ });
77
+ logger.info("StackMemory MCP Server initialized", {
78
+ projectRoot: this.projectRoot,
79
+ projectId: this.projectId
80
+ });
81
+ }
82
+ findProjectRoot() {
83
+ let dir = process.cwd();
84
+ while (dir !== "/") {
85
+ if (existsSync(join(dir, ".git"))) {
86
+ return dir;
87
+ }
88
+ dir = dirname(dir);
89
+ }
90
+ return process.cwd();
91
+ }
92
+ initDB() {
93
+ this.db.exec(`
94
+ CREATE TABLE IF NOT EXISTS contexts (
95
+ id TEXT PRIMARY KEY,
96
+ type TEXT NOT NULL,
97
+ content TEXT NOT NULL,
98
+ importance REAL DEFAULT 0.5,
99
+ created_at INTEGER DEFAULT (unixepoch()),
100
+ last_accessed INTEGER DEFAULT (unixepoch()),
101
+ access_count INTEGER DEFAULT 1
102
+ );
103
+
104
+ CREATE TABLE IF NOT EXISTS attention_log (
105
+ id INTEGER PRIMARY KEY AUTOINCREMENT,
106
+ context_id TEXT,
107
+ query TEXT,
108
+ response TEXT,
109
+ influence_score REAL,
110
+ timestamp INTEGER DEFAULT (unixepoch())
111
+ );
112
+ `);
113
+ }
114
+ loadInitialContext() {
115
+ const projectInfo = this.getProjectInfo();
116
+ this.addContext(
117
+ "project",
118
+ `Project: ${projectInfo.name}
119
+ Path: ${projectInfo.path}`,
120
+ 0.9
121
+ );
122
+ try {
123
+ const recentCommits = execSync("git log --oneline -10", {
124
+ cwd: this.projectRoot
125
+ }).toString();
126
+ this.addContext("git_history", `Recent commits:
127
+ ${recentCommits}`, 0.6);
128
+ } catch {
129
+ }
130
+ const readmePath = join(this.projectRoot, "README.md");
131
+ if (existsSync(readmePath)) {
132
+ const readme = readFileSync(readmePath, "utf-8");
133
+ const summary = readme.substring(0, 500);
134
+ this.addContext("readme", `Project README:
135
+ ${summary}...`, 0.8);
136
+ }
137
+ this.loadStoredContexts();
138
+ }
139
+ getProjectId() {
140
+ try {
141
+ const remoteUrl = execSync("git config --get remote.origin.url", {
142
+ cwd: this.projectRoot,
143
+ stdio: "pipe"
144
+ }).toString().trim();
145
+ return remoteUrl || this.projectRoot.split("/").pop() || "unknown";
146
+ } catch {
147
+ return this.projectRoot.split("/").pop() || "unknown";
148
+ }
149
+ }
150
+ getProjectInfo() {
151
+ const packageJsonPath = join(this.projectRoot, "package.json");
152
+ if (existsSync(packageJsonPath)) {
153
+ const pkg = JSON.parse(readFileSync(packageJsonPath, "utf-8"));
154
+ return {
155
+ name: pkg.name || "unknown",
156
+ path: this.projectRoot
157
+ };
158
+ }
159
+ return {
160
+ name: this.projectRoot.split("/").pop() || "unknown",
161
+ path: this.projectRoot
162
+ };
163
+ }
164
+ addContext(type, content, importance = 0.5) {
165
+ const id = `${type}_${Date.now()}`;
166
+ this.db.prepare(
167
+ `
168
+ INSERT OR REPLACE INTO contexts (id, type, content, importance)
169
+ VALUES (?, ?, ?, ?)
170
+ `
171
+ ).run(id, type, content, importance);
172
+ this.contexts.set(id, { type, content, importance });
173
+ return id;
174
+ }
175
+ loadStoredContexts() {
176
+ const stored = this.db.prepare(
177
+ `
178
+ SELECT * FROM contexts
179
+ ORDER BY importance DESC, last_accessed DESC
180
+ LIMIT 50
181
+ `
182
+ ).all();
183
+ stored.forEach((ctx) => {
184
+ this.contexts.set(ctx.id, ctx);
185
+ });
186
+ }
187
+ setupHandlers() {
188
+ this.server.setRequestHandler(
189
+ z.object({
190
+ method: z.literal("tools/list")
191
+ }),
192
+ async () => {
193
+ return {
194
+ tools: [
195
+ {
196
+ name: "get_context",
197
+ description: "Get current project context",
198
+ inputSchema: {
199
+ type: "object",
200
+ properties: {
201
+ query: {
202
+ type: "string",
203
+ description: "What you want to know"
204
+ },
205
+ limit: {
206
+ type: "number",
207
+ description: "Max contexts to return"
208
+ }
209
+ }
210
+ }
211
+ },
212
+ {
213
+ name: "add_decision",
214
+ description: "Record a decision or important information",
215
+ inputSchema: {
216
+ type: "object",
217
+ properties: {
218
+ content: {
219
+ type: "string",
220
+ description: "The decision or information"
221
+ },
222
+ type: {
223
+ type: "string",
224
+ enum: ["decision", "constraint", "learning"]
225
+ }
226
+ },
227
+ required: ["content", "type"]
228
+ }
229
+ },
230
+ {
231
+ name: "start_frame",
232
+ description: "Start a new frame (task/subtask) on the call stack",
233
+ inputSchema: {
234
+ type: "object",
235
+ properties: {
236
+ name: { type: "string", description: "Frame name/goal" },
237
+ type: {
238
+ type: "string",
239
+ enum: [
240
+ "task",
241
+ "subtask",
242
+ "tool_scope",
243
+ "review",
244
+ "write",
245
+ "debug"
246
+ ],
247
+ description: "Frame type"
248
+ },
249
+ constraints: {
250
+ type: "array",
251
+ items: { type: "string" },
252
+ description: "Constraints for this frame"
253
+ }
254
+ },
255
+ required: ["name", "type"]
256
+ }
257
+ },
258
+ {
259
+ name: "close_frame",
260
+ description: "Close current frame and generate digest",
261
+ inputSchema: {
262
+ type: "object",
263
+ properties: {
264
+ result: {
265
+ type: "string",
266
+ description: "Frame completion result"
267
+ },
268
+ outputs: {
269
+ type: "object",
270
+ description: "Final outputs from frame"
271
+ }
272
+ }
273
+ }
274
+ },
275
+ {
276
+ name: "add_anchor",
277
+ description: "Add anchored fact/decision/constraint to current frame",
278
+ inputSchema: {
279
+ type: "object",
280
+ properties: {
281
+ type: {
282
+ type: "string",
283
+ enum: [
284
+ "FACT",
285
+ "DECISION",
286
+ "CONSTRAINT",
287
+ "INTERFACE_CONTRACT",
288
+ "TODO",
289
+ "RISK"
290
+ ],
291
+ description: "Anchor type"
292
+ },
293
+ text: { type: "string", description: "Anchor content" },
294
+ priority: {
295
+ type: "number",
296
+ description: "Priority (0-10)",
297
+ minimum: 0,
298
+ maximum: 10
299
+ }
300
+ },
301
+ required: ["type", "text"]
302
+ }
303
+ },
304
+ {
305
+ name: "get_hot_stack",
306
+ description: "Get current active frames and context",
307
+ inputSchema: {
308
+ type: "object",
309
+ properties: {
310
+ maxEvents: {
311
+ type: "number",
312
+ description: "Max recent events per frame",
313
+ default: 20
314
+ }
315
+ }
316
+ }
317
+ },
318
+ {
319
+ name: "create_task",
320
+ description: "Create a new task in git-tracked JSONL storage",
321
+ inputSchema: {
322
+ type: "object",
323
+ properties: {
324
+ title: { type: "string", description: "Task title" },
325
+ description: {
326
+ type: "string",
327
+ description: "Task description"
328
+ },
329
+ priority: {
330
+ type: "string",
331
+ enum: ["low", "medium", "high", "urgent"],
332
+ description: "Task priority"
333
+ },
334
+ estimatedEffort: {
335
+ type: "number",
336
+ description: "Estimated effort in minutes"
337
+ },
338
+ dependsOn: {
339
+ type: "array",
340
+ items: { type: "string" },
341
+ description: "Task IDs this depends on"
342
+ },
343
+ tags: {
344
+ type: "array",
345
+ items: { type: "string" },
346
+ description: "Tags for categorization"
347
+ }
348
+ },
349
+ required: ["title"]
350
+ }
351
+ },
352
+ {
353
+ name: "update_task_status",
354
+ description: "Update task status with automatic time tracking",
355
+ inputSchema: {
356
+ type: "object",
357
+ properties: {
358
+ taskId: { type: "string", description: "Task ID to update" },
359
+ status: {
360
+ type: "string",
361
+ enum: [
362
+ "pending",
363
+ "in_progress",
364
+ "completed",
365
+ "blocked",
366
+ "cancelled"
367
+ ],
368
+ description: "New status"
369
+ },
370
+ reason: {
371
+ type: "string",
372
+ description: "Reason for status change (especially for blocked)"
373
+ }
374
+ },
375
+ required: ["taskId", "status"]
376
+ }
377
+ },
378
+ {
379
+ name: "get_active_tasks",
380
+ description: "Get currently active tasks synced from Linear",
381
+ inputSchema: {
382
+ type: "object",
383
+ properties: {
384
+ frameId: {
385
+ type: "string",
386
+ description: "Filter by specific frame ID"
387
+ },
388
+ status: {
389
+ type: "string",
390
+ enum: [
391
+ "pending",
392
+ "in_progress",
393
+ "completed",
394
+ "blocked",
395
+ "cancelled"
396
+ ],
397
+ description: "Filter by status"
398
+ },
399
+ priority: {
400
+ type: "string",
401
+ enum: ["low", "medium", "high", "urgent"],
402
+ description: "Filter by priority"
403
+ },
404
+ search: {
405
+ type: "string",
406
+ description: "Search in task title or description"
407
+ },
408
+ limit: {
409
+ type: "number",
410
+ description: "Max number of tasks to return (default: 20)"
411
+ }
412
+ }
413
+ }
414
+ },
415
+ {
416
+ name: "get_task_metrics",
417
+ description: "Get project task metrics and analytics",
418
+ inputSchema: {
419
+ type: "object",
420
+ properties: {}
421
+ }
422
+ },
423
+ {
424
+ name: "add_task_dependency",
425
+ description: "Add dependency relationship between tasks",
426
+ inputSchema: {
427
+ type: "object",
428
+ properties: {
429
+ taskId: {
430
+ type: "string",
431
+ description: "Task that depends on another"
432
+ },
433
+ dependsOnId: {
434
+ type: "string",
435
+ description: "Task ID that this depends on"
436
+ }
437
+ },
438
+ required: ["taskId", "dependsOnId"]
439
+ }
440
+ },
441
+ {
442
+ name: "linear_sync",
443
+ description: "Sync tasks with Linear",
444
+ inputSchema: {
445
+ type: "object",
446
+ properties: {
447
+ direction: {
448
+ type: "string",
449
+ enum: ["bidirectional", "to_linear", "from_linear"],
450
+ description: "Sync direction"
451
+ }
452
+ }
453
+ }
454
+ },
455
+ {
456
+ name: "linear_update_task",
457
+ description: "Update a Linear task status",
458
+ inputSchema: {
459
+ type: "object",
460
+ properties: {
461
+ issueId: {
462
+ type: "string",
463
+ description: "Linear issue ID or identifier (e.g., STA-34)"
464
+ },
465
+ status: {
466
+ type: "string",
467
+ enum: ["todo", "in-progress", "done", "canceled"],
468
+ description: "New status for the task"
469
+ },
470
+ title: {
471
+ type: "string",
472
+ description: "Update task title (optional)"
473
+ },
474
+ description: {
475
+ type: "string",
476
+ description: "Update task description (optional)"
477
+ },
478
+ priority: {
479
+ type: "number",
480
+ enum: [1, 2, 3, 4],
481
+ description: "Priority (1=urgent, 2=high, 3=medium, 4=low)"
482
+ }
483
+ },
484
+ required: ["issueId"]
485
+ }
486
+ },
487
+ {
488
+ name: "linear_get_tasks",
489
+ description: "Get Linear tasks",
490
+ inputSchema: {
491
+ type: "object",
492
+ properties: {
493
+ status: {
494
+ type: "string",
495
+ enum: ["todo", "in-progress", "done", "all"],
496
+ description: "Filter by status"
497
+ },
498
+ limit: {
499
+ type: "number",
500
+ description: "Maximum number of tasks to return"
501
+ }
502
+ }
503
+ }
504
+ },
505
+ {
506
+ name: "linear_status",
507
+ description: "Get Linear integration status",
508
+ inputSchema: {
509
+ type: "object",
510
+ properties: {}
511
+ }
512
+ },
513
+ {
514
+ name: "get_traces",
515
+ description: "Get detected traces (bundled tool call sequences)",
516
+ inputSchema: {
517
+ type: "object",
518
+ properties: {
519
+ type: {
520
+ type: "string",
521
+ enum: [
522
+ "search_driven",
523
+ "error_recovery",
524
+ "feature_implementation",
525
+ "refactoring",
526
+ "testing",
527
+ "exploration",
528
+ "debugging",
529
+ "documentation",
530
+ "build_deploy",
531
+ "unknown"
532
+ ],
533
+ description: "Filter by trace type"
534
+ },
535
+ minScore: {
536
+ type: "number",
537
+ description: "Minimum importance score (0-1)"
538
+ },
539
+ limit: {
540
+ type: "number",
541
+ description: "Maximum number of traces to return"
542
+ }
543
+ }
544
+ }
545
+ },
546
+ {
547
+ name: "get_trace_statistics",
548
+ description: "Get statistics about detected traces",
549
+ inputSchema: {
550
+ type: "object",
551
+ properties: {}
552
+ }
553
+ },
554
+ {
555
+ name: "flush_traces",
556
+ description: "Flush any pending trace and finalize detection",
557
+ inputSchema: {
558
+ type: "object",
559
+ properties: {}
560
+ }
561
+ },
562
+ {
563
+ name: "compress_old_traces",
564
+ description: "Compress traces older than specified hours",
565
+ inputSchema: {
566
+ type: "object",
567
+ properties: {
568
+ ageHours: {
569
+ type: "number",
570
+ description: "Age threshold in hours (default: 24)"
571
+ }
572
+ }
573
+ }
574
+ },
575
+ {
576
+ name: "smart_context",
577
+ description: "LLM-driven context retrieval - intelligently selects relevant frames based on query",
578
+ inputSchema: {
579
+ type: "object",
580
+ properties: {
581
+ query: {
582
+ type: "string",
583
+ description: "Natural language query describing what context you need"
584
+ },
585
+ tokenBudget: {
586
+ type: "number",
587
+ description: "Maximum tokens to use for context (default: 4000)"
588
+ },
589
+ forceRefresh: {
590
+ type: "boolean",
591
+ description: "Force refresh of cached summaries"
592
+ }
593
+ },
594
+ required: ["query"]
595
+ }
596
+ },
597
+ {
598
+ name: "get_summary",
599
+ description: "Get compressed summary of project memory for analysis",
600
+ inputSchema: {
601
+ type: "object",
602
+ properties: {
603
+ forceRefresh: {
604
+ type: "boolean",
605
+ description: "Force refresh of cached summary"
606
+ }
607
+ }
608
+ }
609
+ }
610
+ ]
611
+ };
612
+ }
613
+ );
614
+ this.server.setRequestHandler(
615
+ z.object({
616
+ method: z.literal("tools/call"),
617
+ params: z.object({
618
+ name: z.string(),
619
+ arguments: z.record(z.unknown())
620
+ })
621
+ }),
622
+ async (request) => {
623
+ const { name, arguments: args } = request.params;
624
+ const callId = uuidv4();
625
+ const startTime = Date.now();
626
+ const currentFrameId = this.frameManager.getCurrentFrameId();
627
+ if (currentFrameId) {
628
+ this.frameManager.addEvent("tool_call", {
629
+ tool_name: name,
630
+ arguments: args,
631
+ timestamp: startTime
632
+ });
633
+ }
634
+ const toolCall = {
635
+ id: callId,
636
+ tool: name,
637
+ arguments: args,
638
+ timestamp: startTime
639
+ };
640
+ let result;
641
+ let error;
642
+ try {
643
+ switch (name) {
644
+ case "get_context":
645
+ result = await this.handleGetContext(args);
646
+ break;
647
+ case "add_decision":
648
+ result = await this.handleAddDecision(args);
649
+ break;
650
+ case "start_frame":
651
+ result = await this.handleStartFrame(args);
652
+ break;
653
+ case "close_frame":
654
+ result = await this.handleCloseFrame(args);
655
+ break;
656
+ case "add_anchor":
657
+ result = await this.handleAddAnchor(args);
658
+ break;
659
+ case "get_hot_stack":
660
+ result = await this.handleGetHotStack(args);
661
+ break;
662
+ case "create_task":
663
+ result = await this.handleCreateTask(args);
664
+ break;
665
+ case "update_task_status":
666
+ result = await this.handleUpdateTaskStatus(args);
667
+ break;
668
+ case "get_active_tasks":
669
+ result = await this.handleGetActiveTasks(args);
670
+ break;
671
+ case "get_task_metrics":
672
+ result = await this.handleGetTaskMetrics(args);
673
+ break;
674
+ case "add_task_dependency":
675
+ result = await this.handleAddTaskDependency(args);
676
+ break;
677
+ case "linear_sync":
678
+ result = await this.handleLinearSync(args);
679
+ break;
680
+ case "linear_update_task":
681
+ result = await this.handleLinearUpdateTask(args);
682
+ break;
683
+ case "linear_get_tasks":
684
+ result = await this.handleLinearGetTasks(args);
685
+ break;
686
+ case "linear_status":
687
+ result = await this.handleLinearStatus(args);
688
+ break;
689
+ case "get_traces":
690
+ result = await this.handleGetTraces(args);
691
+ break;
692
+ case "get_trace_statistics":
693
+ result = await this.handleGetTraceStatistics(args);
694
+ break;
695
+ case "flush_traces":
696
+ result = await this.handleFlushTraces(args);
697
+ break;
698
+ case "compress_old_traces":
699
+ result = await this.handleCompressOldTraces(args);
700
+ break;
701
+ case "smart_context":
702
+ result = await this.handleSmartContext(args);
703
+ break;
704
+ case "get_summary":
705
+ result = await this.handleGetSummary(args);
706
+ break;
707
+ default:
708
+ throw new Error(`Unknown tool: ${name}`);
709
+ }
710
+ } catch (err) {
711
+ error = err instanceof Error ? err : new Error(String(err));
712
+ toolCall.error = error.message;
713
+ throw err;
714
+ } finally {
715
+ const endTime = Date.now();
716
+ if (currentFrameId && name !== "close_frame") {
717
+ try {
718
+ this.frameManager.addEvent("tool_result", {
719
+ tool_name: name,
720
+ success: !error,
721
+ result: error ? { error: error.message } : result,
722
+ timestamp: endTime
723
+ });
724
+ } catch {
725
+ }
726
+ }
727
+ toolCall.result = error ? void 0 : result;
728
+ toolCall.duration = endTime - startTime;
729
+ if (args.file_path || args.path) {
730
+ toolCall.filesAffected = [args.file_path || args.path].filter(
731
+ Boolean
732
+ );
733
+ } else if (result?.files) {
734
+ const files = result.files;
735
+ toolCall.filesAffected = Array.isArray(files) ? files : [files];
736
+ }
737
+ this.traceDetector.addToolCall(toolCall);
738
+ }
739
+ return result;
740
+ }
741
+ );
742
+ }
743
+ async handleGetContext(args) {
744
+ const { query = "", limit = 10 } = args;
745
+ const contexts = Array.from(this.contexts.values()).sort((a, b) => b.importance - a.importance).slice(0, limit);
746
+ contexts.forEach((ctx) => {
747
+ this.db.prepare(
748
+ `
749
+ UPDATE contexts
750
+ SET last_accessed = unixepoch(),
751
+ access_count = access_count + 1
752
+ WHERE id = ?
753
+ `
754
+ ).run(ctx.id);
755
+ });
756
+ const response = contexts.map(
757
+ (ctx) => `[${ctx.type.toUpperCase()}] (importance: ${ctx.importance.toFixed(2)})
758
+ ${ctx.content}`
759
+ ).join("\n\n---\n\n");
760
+ this.logAttention(query, response);
761
+ return {
762
+ content: [
763
+ {
764
+ type: "text",
765
+ text: response || "No context available yet. Start adding decisions and information!"
766
+ }
767
+ ]
768
+ };
769
+ }
770
+ async handleAddDecision(args) {
771
+ const { content, type = "decision" } = args;
772
+ const id = this.addContext(type, content, 0.8);
773
+ return {
774
+ content: [
775
+ {
776
+ type: "text",
777
+ text: `\u2713 Added ${type}: ${content}
778
+ ID: ${id}`
779
+ }
780
+ ]
781
+ };
782
+ }
783
+ async handleStartFrame(args) {
784
+ const { name, type, constraints } = args;
785
+ const inputs = {};
786
+ if (constraints) {
787
+ inputs.constraints = constraints;
788
+ }
789
+ const frameId = this.frameManager.createFrame({
790
+ type,
791
+ name,
792
+ inputs
793
+ });
794
+ this.frameManager.addEvent("user_message", {
795
+ action: "start_frame",
796
+ name,
797
+ type,
798
+ constraints
799
+ });
800
+ this.addContext("active_frame", `Active frame: ${name} (${type})`, 0.9);
801
+ const stackDepth = this.frameManager.getStackDepth();
802
+ return {
803
+ content: [
804
+ {
805
+ type: "text",
806
+ text: `\u{1F680} Started ${type}: ${name}
807
+ Frame ID: ${frameId}
808
+ Stack depth: ${stackDepth}`
809
+ }
810
+ ]
811
+ };
812
+ }
813
+ async handleCloseFrame(args) {
814
+ const { result, outputs } = args;
815
+ const currentFrameId = this.frameManager.getCurrentFrameId();
816
+ if (!currentFrameId) {
817
+ return {
818
+ content: [
819
+ {
820
+ type: "text",
821
+ text: "\u26A0\uFE0F No active frame to close"
822
+ }
823
+ ]
824
+ };
825
+ }
826
+ this.frameManager.addEvent("assistant_message", {
827
+ action: "close_frame",
828
+ result,
829
+ outputs
830
+ });
831
+ this.frameManager.closeFrame(currentFrameId, outputs);
832
+ const newStackDepth = this.frameManager.getStackDepth();
833
+ return {
834
+ content: [
835
+ {
836
+ type: "text",
837
+ text: `\u2705 Closed frame: ${result || "completed"}
838
+ Stack depth: ${newStackDepth}`
839
+ }
840
+ ]
841
+ };
842
+ }
843
+ async handleAddAnchor(args) {
844
+ const { type, text, priority = 5 } = args;
845
+ const anchorId = this.frameManager.addAnchor(type, text, priority);
846
+ this.frameManager.addEvent("decision", {
847
+ anchor_type: type,
848
+ text,
849
+ priority,
850
+ anchor_id: anchorId
851
+ });
852
+ return {
853
+ content: [
854
+ {
855
+ type: "text",
856
+ text: `\u{1F4CC} Added ${type}: ${text}
857
+ Anchor ID: ${anchorId}`
858
+ }
859
+ ]
860
+ };
861
+ }
862
+ async handleGetHotStack(args) {
863
+ const { maxEvents = 20 } = args;
864
+ const hotStack = this.frameManager.getHotStackContext(maxEvents);
865
+ const activePath = this.frameManager.getActiveFramePath();
866
+ if (hotStack.length === 0) {
867
+ return {
868
+ content: [
869
+ {
870
+ type: "text",
871
+ text: "\u{1F4DA} No active frames. Start a frame with start_frame tool."
872
+ }
873
+ ]
874
+ };
875
+ }
876
+ let response = "\u{1F4DA} **Active Call Stack:**\n\n";
877
+ activePath.forEach((frame, index) => {
878
+ const indent = " ".repeat(index);
879
+ const context = hotStack[index];
880
+ response += `${indent}${index + 1}. **${frame.name}** (${frame.type})
881
+ `;
882
+ if (context && context.anchors && context.anchors.length > 0) {
883
+ response += `${indent} \u{1F4CC} ${context.anchors.length} anchors
884
+ `;
885
+ }
886
+ if (context && context.recentEvents && context.recentEvents.length > 0) {
887
+ response += `${indent} \u{1F4DD} ${context.recentEvents.length} recent events
888
+ `;
889
+ }
890
+ response += "\n";
891
+ });
892
+ response += `**Total stack depth:** ${hotStack.length}`;
893
+ this.frameManager.addEvent("observation", {
894
+ action: "get_hot_stack",
895
+ stack_depth: hotStack.length,
896
+ total_anchors: hotStack.reduce(
897
+ (sum, frame) => sum + frame.anchors.length,
898
+ 0
899
+ ),
900
+ total_events: hotStack.reduce(
901
+ (sum, frame) => sum + frame.recentEvents.length,
902
+ 0
903
+ )
904
+ });
905
+ return {
906
+ content: [
907
+ {
908
+ type: "text",
909
+ text: response
910
+ }
911
+ ]
912
+ };
913
+ }
914
+ logAttention(query, response) {
915
+ this.db.prepare(
916
+ `
917
+ INSERT INTO attention_log (query, response)
918
+ VALUES (?, ?)
919
+ `
920
+ ).run(query, response);
921
+ }
922
+ async handleCreateTask(args) {
923
+ const { title, description, priority, estimatedEffort, dependsOn, tags } = args;
924
+ const currentFrameId = this.frameManager.getCurrentFrameId();
925
+ if (!currentFrameId) {
926
+ return {
927
+ content: [
928
+ {
929
+ type: "text",
930
+ text: "\u26A0\uFE0F No active frame. Start a frame first with start_frame tool."
931
+ }
932
+ ]
933
+ };
934
+ }
935
+ const taskId = this.taskStore.createTask({
936
+ title,
937
+ description,
938
+ priority,
939
+ frameId: currentFrameId,
940
+ dependsOn,
941
+ tags,
942
+ estimatedEffort
943
+ });
944
+ this.frameManager.addEvent("decision", {
945
+ action: "create_task",
946
+ task_id: taskId,
947
+ title,
948
+ priority: priority || "medium"
949
+ });
950
+ return {
951
+ content: [
952
+ {
953
+ type: "text",
954
+ text: `\u2705 Created task: ${title}
955
+ ID: ${taskId}
956
+ Frame: ${currentFrameId}
957
+ Stored in: .stackmemory/tasks.jsonl`
958
+ }
959
+ ]
960
+ };
961
+ }
962
+ async handleUpdateTaskStatus(args) {
963
+ const { taskId, status, reason } = args;
964
+ try {
965
+ this.taskStore.updateTaskStatus(taskId, status, reason);
966
+ this.frameManager.addEvent("observation", {
967
+ action: "update_task_status",
968
+ task_id: taskId,
969
+ new_status: status,
970
+ reason
971
+ });
972
+ return {
973
+ content: [
974
+ {
975
+ type: "text",
976
+ text: `\u2705 Updated task ${taskId} to ${status}${reason ? `
977
+ Reason: ${reason}` : ""}`
978
+ }
979
+ ]
980
+ };
981
+ } catch (error) {
982
+ return {
983
+ content: [
984
+ {
985
+ type: "text",
986
+ text: `\u274C Failed to update task: ${error}`
987
+ }
988
+ ]
989
+ };
990
+ }
991
+ }
992
+ async handleGetActiveTasks(args) {
993
+ const { frameId, status, priority, search, limit = 20 } = args;
994
+ let tasks = this.taskStore.getActiveTasks(frameId);
995
+ if (status) {
996
+ tasks = tasks.filter((t) => t.status === status);
997
+ }
998
+ if (priority) {
999
+ tasks = tasks.filter((t) => t.priority === priority);
1000
+ }
1001
+ if (search) {
1002
+ const searchLower = search.toLowerCase();
1003
+ tasks = tasks.filter(
1004
+ (t) => t.title.toLowerCase().includes(searchLower) || t.description && t.description.toLowerCase().includes(searchLower)
1005
+ );
1006
+ }
1007
+ const priorityOrder = { urgent: 0, high: 1, medium: 2, low: 3 };
1008
+ tasks.sort((a, b) => {
1009
+ const pa = priorityOrder[a.priority] ?? 2;
1010
+ const pb = priorityOrder[b.priority] ?? 2;
1011
+ if (pa !== pb) return pa - pb;
1012
+ return b.created_at - a.created_at;
1013
+ });
1014
+ tasks = tasks.slice(0, limit);
1015
+ if (tasks.length === 0) {
1016
+ return {
1017
+ content: [
1018
+ {
1019
+ type: "text",
1020
+ text: search ? `\u{1F4DD} No tasks matching "${search}"` : "\u{1F4DD} No active tasks found"
1021
+ }
1022
+ ]
1023
+ };
1024
+ }
1025
+ let response = `\u{1F4DD} **Tasks** (${tasks.length} found)
1026
+
1027
+ `;
1028
+ tasks.forEach((task) => {
1029
+ const priorityIcon = { urgent: "\u{1F534}", high: "\u{1F7E0}", medium: "\u{1F7E1}", low: "\u{1F7E2}" }[task.priority] || "\u26AA";
1030
+ const statusIcon = {
1031
+ pending: "\u23F3",
1032
+ in_progress: "\u{1F504}",
1033
+ completed: "\u2705",
1034
+ blocked: "\u{1F6AB}",
1035
+ cancelled: "\u274C"
1036
+ }[task.status] || "\u26AA";
1037
+ const effort = task.estimated_effort ? ` (~${task.estimated_effort}m)` : "";
1038
+ const linearMatch = task.title.match(/\[ENG-\d+\]/);
1039
+ const linearId = linearMatch ? linearMatch[0] : "";
1040
+ const title = linearId ? task.title.replace(linearId, "").trim() : task.title;
1041
+ response += `${statusIcon} ${priorityIcon} **${linearId || task.id}** ${title}${effort}
1042
+ `;
1043
+ if (task.description) {
1044
+ const desc = task.description.split("\n")[0].slice(0, 100);
1045
+ response += ` ${desc}${task.description.length > 100 ? "..." : ""}
1046
+ `;
1047
+ }
1048
+ if (task.tags && task.tags.length > 0) {
1049
+ response += ` \u{1F3F7}\uFE0F ${task.tags.join(", ")}
1050
+ `;
1051
+ }
1052
+ response += "\n";
1053
+ });
1054
+ return {
1055
+ content: [
1056
+ {
1057
+ type: "text",
1058
+ text: response
1059
+ }
1060
+ ]
1061
+ };
1062
+ }
1063
+ async handleGetTaskMetrics(_args) {
1064
+ const metrics = this.taskStore.getMetrics();
1065
+ let response = "\u{1F4CA} **Task Metrics**\n\n";
1066
+ response += `**Total Tasks:** ${metrics.total_tasks}
1067
+ `;
1068
+ response += `**Completion Rate:** ${(metrics.completion_rate * 100).toFixed(1)}%
1069
+
1070
+ `;
1071
+ response += "**By Status:**\n";
1072
+ Object.entries(metrics.by_status).forEach(([status, count]) => {
1073
+ response += `- ${status}: ${count}
1074
+ `;
1075
+ });
1076
+ response += "\n**By Priority:**\n";
1077
+ Object.entries(metrics.by_priority).forEach(([priority, count]) => {
1078
+ response += `- ${priority}: ${count}
1079
+ `;
1080
+ });
1081
+ if (metrics.blocked_tasks > 0) {
1082
+ response += `
1083
+ \u26A0\uFE0F **${metrics.blocked_tasks} blocked tasks**`;
1084
+ }
1085
+ if (metrics.avg_effort_accuracy > 0) {
1086
+ response += `
1087
+ \u{1F3AF} **Effort Accuracy:** ${(metrics.avg_effort_accuracy * 100).toFixed(1)}%`;
1088
+ }
1089
+ return {
1090
+ content: [
1091
+ {
1092
+ type: "text",
1093
+ text: response
1094
+ }
1095
+ ]
1096
+ };
1097
+ }
1098
+ async handleAddTaskDependency(args) {
1099
+ const { taskId, dependsOnId } = args;
1100
+ try {
1101
+ this.taskStore.addDependency(taskId, dependsOnId);
1102
+ this.frameManager.addEvent("decision", {
1103
+ action: "add_task_dependency",
1104
+ task_id: taskId,
1105
+ depends_on_id: dependsOnId
1106
+ });
1107
+ return {
1108
+ content: [
1109
+ {
1110
+ type: "text",
1111
+ text: `\u{1F517} Added dependency: ${taskId} depends on ${dependsOnId}`
1112
+ }
1113
+ ]
1114
+ };
1115
+ } catch (error) {
1116
+ return {
1117
+ content: [
1118
+ {
1119
+ type: "text",
1120
+ text: `\u274C Failed to add dependency: ${error}`
1121
+ }
1122
+ ]
1123
+ };
1124
+ }
1125
+ }
1126
+ // Linear Integration Handlers
1127
+ async handleLinearSync(args) {
1128
+ try {
1129
+ const tokens = this.linearAuthManager.loadTokens();
1130
+ if (!tokens) {
1131
+ return {
1132
+ content: [
1133
+ {
1134
+ type: "text",
1135
+ text: "\u274C Linear not authenticated. Run: stackmemory linear setup"
1136
+ }
1137
+ ]
1138
+ };
1139
+ }
1140
+ const syncConfig = { ...DEFAULT_SYNC_CONFIG, enabled: true };
1141
+ if (args.direction) {
1142
+ syncConfig.direction = args.direction;
1143
+ }
1144
+ this.linearSync.updateConfig(syncConfig);
1145
+ const result = await this.linearSync.sync();
1146
+ return {
1147
+ content: [
1148
+ {
1149
+ type: "text",
1150
+ text: `\u2705 Linear sync completed
1151
+ - To Linear: ${result.synced.toLinear} tasks
1152
+ - From Linear: ${result.synced.fromLinear} tasks
1153
+ - Updated: ${result.synced.updated} tasks`
1154
+ }
1155
+ ]
1156
+ };
1157
+ } catch (error) {
1158
+ return {
1159
+ content: [
1160
+ {
1161
+ type: "text",
1162
+ text: `\u274C Linear sync failed: ${error.message}`
1163
+ }
1164
+ ]
1165
+ };
1166
+ }
1167
+ }
1168
+ async handleLinearUpdateTask(args) {
1169
+ try {
1170
+ const { LinearClient } = await import("../linear/client.js");
1171
+ const tokens = this.linearAuthManager.loadTokens();
1172
+ if (!tokens) {
1173
+ return {
1174
+ content: [
1175
+ {
1176
+ type: "text",
1177
+ text: "\u274C Linear not authenticated. Run: stackmemory linear setup"
1178
+ }
1179
+ ]
1180
+ };
1181
+ }
1182
+ const client = new LinearClient({
1183
+ apiKey: tokens.accessToken
1184
+ });
1185
+ let issue = await client.getIssue(args.issueId);
1186
+ if (!issue) {
1187
+ issue = await client.findIssueByIdentifier(args.issueId);
1188
+ }
1189
+ if (!issue) {
1190
+ return {
1191
+ content: [
1192
+ {
1193
+ type: "text",
1194
+ text: `\u274C Linear issue ${args.issueId} not found`
1195
+ }
1196
+ ]
1197
+ };
1198
+ }
1199
+ const updates = {};
1200
+ if (args.status) {
1201
+ const team = await client.getTeam();
1202
+ const states = await client.getWorkflowStates(team.id);
1203
+ const statusMap = {
1204
+ todo: "unstarted",
1205
+ "in-progress": "started",
1206
+ done: "completed",
1207
+ canceled: "cancelled"
1208
+ };
1209
+ const targetType = statusMap[args.status] || args.status;
1210
+ const targetState = states.find((s) => s.type === targetType);
1211
+ if (!targetState) {
1212
+ return {
1213
+ content: [
1214
+ {
1215
+ type: "text",
1216
+ text: `\u274C Invalid status: ${args.status}`
1217
+ }
1218
+ ]
1219
+ };
1220
+ }
1221
+ updates.stateId = targetState.id;
1222
+ }
1223
+ if (args.title) updates.title = args.title;
1224
+ if (args.description) updates.description = args.description;
1225
+ if (args.priority) updates.priority = args.priority;
1226
+ const updatedIssue = await client.updateIssue(issue.id, updates);
1227
+ this.linearSync.updateConfig({
1228
+ ...DEFAULT_SYNC_CONFIG,
1229
+ enabled: true,
1230
+ direction: "from_linear"
1231
+ });
1232
+ const syncResult = await this.linearSync.sync();
1233
+ let response = `\u2705 Updated ${updatedIssue.identifier}: ${updatedIssue.title}
1234
+ `;
1235
+ if (args.status) {
1236
+ response += `Status: ${updatedIssue.state.name}
1237
+ `;
1238
+ }
1239
+ response += `URL: ${updatedIssue.url}
1240
+ `;
1241
+ response += `
1242
+ \u{1F504} Local sync: ${syncResult.synced.fromLinear} new, ${syncResult.synced.updated} updated`;
1243
+ return {
1244
+ content: [
1245
+ {
1246
+ type: "text",
1247
+ text: response
1248
+ }
1249
+ ]
1250
+ };
1251
+ } catch (error) {
1252
+ return {
1253
+ content: [
1254
+ {
1255
+ type: "text",
1256
+ text: `\u274C Failed to update Linear task: ${error.message}`
1257
+ }
1258
+ ]
1259
+ };
1260
+ }
1261
+ }
1262
+ async handleLinearGetTasks(args) {
1263
+ try {
1264
+ const { LinearClient } = await import("../linear/client.js");
1265
+ const tokens = this.linearAuthManager.loadTokens();
1266
+ if (!tokens) {
1267
+ return {
1268
+ content: [
1269
+ {
1270
+ type: "text",
1271
+ text: "\u274C Linear not authenticated. Run: stackmemory linear setup"
1272
+ }
1273
+ ]
1274
+ };
1275
+ }
1276
+ const client = new LinearClient({
1277
+ apiKey: tokens.accessToken
1278
+ });
1279
+ let stateType = void 0;
1280
+ if (args.status && args.status !== "all") {
1281
+ const statusMap = {
1282
+ todo: "unstarted",
1283
+ "in-progress": "started",
1284
+ done: "completed"
1285
+ };
1286
+ stateType = statusMap[args.status] || args.status;
1287
+ }
1288
+ const issues = await client.getIssues({
1289
+ stateType,
1290
+ limit: args.limit || 20
1291
+ });
1292
+ if (!issues || issues.length === 0) {
1293
+ return {
1294
+ content: [
1295
+ {
1296
+ type: "text",
1297
+ text: "No Linear tasks found"
1298
+ }
1299
+ ]
1300
+ };
1301
+ }
1302
+ let response = `\u{1F4CB} **Linear Tasks** (${issues.length} items)
1303
+
1304
+ `;
1305
+ issues.forEach((issue) => {
1306
+ const priority = issue.priority ? `P${issue.priority}` : "-";
1307
+ response += `- **${issue.identifier}**: ${issue.title}
1308
+ `;
1309
+ response += ` Status: ${issue.state.name} | Priority: ${priority}
1310
+ `;
1311
+ if (issue.assignee) {
1312
+ response += ` Assignee: ${issue.assignee.name}
1313
+ `;
1314
+ }
1315
+ response += ` ${issue.url}
1316
+
1317
+ `;
1318
+ });
1319
+ return {
1320
+ content: [
1321
+ {
1322
+ type: "text",
1323
+ text: response
1324
+ }
1325
+ ]
1326
+ };
1327
+ } catch (error) {
1328
+ return {
1329
+ content: [
1330
+ {
1331
+ type: "text",
1332
+ text: `\u274C Failed to get Linear tasks: ${error.message}`
1333
+ }
1334
+ ]
1335
+ };
1336
+ }
1337
+ }
1338
+ async handleLinearStatus(_args) {
1339
+ try {
1340
+ const { LinearClient } = await import("../linear/client.js");
1341
+ const tokens = this.linearAuthManager.loadTokens();
1342
+ if (!tokens) {
1343
+ return {
1344
+ content: [
1345
+ {
1346
+ type: "text",
1347
+ text: "\u274C Linear integration not configured\nRun: stackmemory linear setup"
1348
+ }
1349
+ ]
1350
+ };
1351
+ }
1352
+ try {
1353
+ const client = new LinearClient({
1354
+ apiKey: tokens.accessToken
1355
+ });
1356
+ const viewer = await client.getViewer();
1357
+ const team = await client.getTeam();
1358
+ return {
1359
+ content: [
1360
+ {
1361
+ type: "text",
1362
+ text: `\u2705 **Linear Integration Status**
1363
+
1364
+ Connected as: ${viewer.name} (${viewer.email})
1365
+ Team: ${team.name} (${team.key})
1366
+ Tokens: Valid`
1367
+ }
1368
+ ]
1369
+ };
1370
+ } catch (error) {
1371
+ return {
1372
+ content: [
1373
+ {
1374
+ type: "text",
1375
+ text: `\u26A0\uFE0F Linear configured but connection failed: ${error.message}`
1376
+ }
1377
+ ]
1378
+ };
1379
+ }
1380
+ } catch (error) {
1381
+ return {
1382
+ content: [
1383
+ {
1384
+ type: "text",
1385
+ text: `\u274C Linear status check failed: ${error.message}`
1386
+ }
1387
+ ]
1388
+ };
1389
+ }
1390
+ }
1391
+ async handleGetTraces(args) {
1392
+ const { type, minScore, limit = 20 } = args;
1393
+ this.traceDetector.flush();
1394
+ let traces = this.traceDetector.getTraces();
1395
+ if (type) {
1396
+ traces = traces.filter((t) => t.type === type);
1397
+ }
1398
+ if (minScore !== void 0) {
1399
+ traces = traces.filter((t) => t.score >= minScore);
1400
+ }
1401
+ traces = traces.sort((a, b) => b.score - a.score).slice(0, limit);
1402
+ const formattedTraces = traces.map((trace) => ({
1403
+ id: trace.id,
1404
+ type: trace.type,
1405
+ score: trace.score.toFixed(2),
1406
+ summary: trace.summary,
1407
+ toolCount: trace.tools.length,
1408
+ duration: `${((trace.metadata.endTime - trace.metadata.startTime) / 1e3).toFixed(1)}s`,
1409
+ filesModified: trace.metadata.filesModified.length,
1410
+ hasErrors: trace.metadata.errorsEncountered.length > 0,
1411
+ compressed: !!trace.compressed
1412
+ }));
1413
+ return {
1414
+ content: [
1415
+ {
1416
+ type: "text",
1417
+ text: `Found ${formattedTraces.length} traces:
1418
+
1419
+ ${formattedTraces.map(
1420
+ (t) => `[${t.type}] Score: ${t.score} | Tools: ${t.toolCount} | Duration: ${t.duration}
1421
+ ${t.summary}`
1422
+ ).join("\n\n")}`
1423
+ }
1424
+ ]
1425
+ };
1426
+ }
1427
+ async handleGetTraceStatistics(args) {
1428
+ this.traceDetector.flush();
1429
+ const stats = this.traceDetector.getStatistics();
1430
+ const typeBreakdown = Object.entries(stats.tracesByType).map(([type, count]) => ` ${type}: ${count}`).join("\n");
1431
+ return {
1432
+ content: [
1433
+ {
1434
+ type: "text",
1435
+ text: `**Trace Statistics**
1436
+
1437
+ Total Traces: ${stats.totalTraces}
1438
+ Average Score: ${stats.averageScore.toFixed(2)}
1439
+ Average Length: ${stats.averageLength.toFixed(1)} tools
1440
+ High Importance (>0.7): ${stats.highImportanceCount}
1441
+ Compressed: ${stats.compressedCount}
1442
+
1443
+ **Trace Types:**
1444
+ ${typeBreakdown}`
1445
+ }
1446
+ ]
1447
+ };
1448
+ }
1449
+ async handleFlushTraces(args) {
1450
+ this.traceDetector.flush();
1451
+ return {
1452
+ content: [
1453
+ {
1454
+ type: "text",
1455
+ text: "Pending traces have been flushed and finalized."
1456
+ }
1457
+ ]
1458
+ };
1459
+ }
1460
+ async handleCompressOldTraces(args) {
1461
+ const { ageHours = 24 } = args;
1462
+ const compressedCount = this.traceDetector.compressOldTraces(ageHours);
1463
+ return {
1464
+ content: [
1465
+ {
1466
+ type: "text",
1467
+ text: `Compressed ${compressedCount} traces older than ${ageHours} hours.`
1468
+ }
1469
+ ]
1470
+ };
1471
+ }
1472
+ async handleSmartContext(args) {
1473
+ const { query, tokenBudget = 4e3, forceRefresh = false } = args;
1474
+ try {
1475
+ const result = await this.contextRetrieval.retrieveContext(query, {
1476
+ tokenBudget,
1477
+ forceRefresh
1478
+ });
1479
+ const currentFrameId = this.frameManager.getCurrentFrameId();
1480
+ if (currentFrameId) {
1481
+ this.frameManager.addEvent("observation", {
1482
+ action: "smart_context",
1483
+ query,
1484
+ framesRetrieved: result.frames.length,
1485
+ tokenUsage: result.tokenUsage,
1486
+ confidence: result.analysis.confidenceScore
1487
+ });
1488
+ }
1489
+ let response = result.context;
1490
+ response += `
1491
+
1492
+ ---
1493
+ \u{1F4CA} **Retrieval Stats**
1494
+ `;
1495
+ response += `- Frames included: ${result.frames.length}
1496
+ `;
1497
+ response += `- Tokens used: ${result.tokenUsage.used}/${result.tokenUsage.budget}
1498
+ `;
1499
+ response += `- Confidence: ${(result.analysis.confidenceScore * 100).toFixed(0)}%
1500
+ `;
1501
+ response += `- Time: ${result.metadata.retrievalTimeMs}ms`;
1502
+ return {
1503
+ content: [
1504
+ {
1505
+ type: "text",
1506
+ text: response
1507
+ }
1508
+ ]
1509
+ };
1510
+ } catch (error) {
1511
+ return {
1512
+ content: [
1513
+ {
1514
+ type: "text",
1515
+ text: `\u274C Context retrieval failed: ${error.message}`
1516
+ }
1517
+ ]
1518
+ };
1519
+ }
1520
+ }
1521
+ async handleGetSummary(args) {
1522
+ const { forceRefresh = false } = args;
1523
+ try {
1524
+ const summary = this.contextRetrieval.getSummary(forceRefresh);
1525
+ let response = "\u{1F4CB} **Compressed Memory Summary**\n\n";
1526
+ response += "## Recent Session\n";
1527
+ response += `- Frames: ${summary.recentSession.frames.length}
1528
+ `;
1529
+ response += `- Time range: ${new Date(summary.recentSession.timeRange.start).toLocaleString()} - ${new Date(summary.recentSession.timeRange.end).toLocaleString()}
1530
+ `;
1531
+ if (summary.recentSession.dominantOperations.length > 0) {
1532
+ response += `- Dominant ops: ${summary.recentSession.dominantOperations.slice(0, 5).map((o) => `${o.operation}(${o.count})`).join(", ")}
1533
+ `;
1534
+ }
1535
+ if (summary.recentSession.filesTouched.length > 0) {
1536
+ response += `- Files touched: ${summary.recentSession.filesTouched.slice(0, 5).map((f) => f.path).join(", ")}
1537
+ `;
1538
+ }
1539
+ if (summary.recentSession.errorsEncountered.length > 0) {
1540
+ response += `- Errors: ${summary.recentSession.errorsEncountered.length}
1541
+ `;
1542
+ }
1543
+ response += "\n## Historical Patterns\n";
1544
+ response += `- Topic counts: ${Object.keys(summary.historicalPatterns.topicFrameCounts).length} topics
1545
+ `;
1546
+ if (summary.historicalPatterns.keyDecisions.length > 0) {
1547
+ response += `
1548
+ ### Key Decisions (${summary.historicalPatterns.keyDecisions.length})
1549
+ `;
1550
+ summary.historicalPatterns.keyDecisions.slice(0, 5).forEach((d) => {
1551
+ response += `- ${d.text.substring(0, 80)}${d.text.length > 80 ? "..." : ""}
1552
+ `;
1553
+ });
1554
+ }
1555
+ if (summary.historicalPatterns.recurringIssues.length > 0) {
1556
+ response += `
1557
+ ### Recurring Issues (${summary.historicalPatterns.recurringIssues.length})
1558
+ `;
1559
+ summary.historicalPatterns.recurringIssues.slice(0, 3).forEach((i) => {
1560
+ response += `- ${i.issueType} (${i.occurrenceCount} times)
1561
+ `;
1562
+ });
1563
+ }
1564
+ response += "\n## Available Indices\n";
1565
+ response += `- By time: ${Object.keys(summary.queryableIndices.byTimeframe).length} periods
1566
+ `;
1567
+ response += `- By file: ${Object.keys(summary.queryableIndices.byFile).length} files
1568
+ `;
1569
+ response += `- By topic: ${Object.keys(summary.queryableIndices.byTopic).length} topics
1570
+ `;
1571
+ response += `- By error: ${Object.keys(summary.queryableIndices.byErrorType).length} error types
1572
+ `;
1573
+ response += `
1574
+ ## Stats
1575
+ `;
1576
+ response += `- Total frames: ${summary.stats.totalFrames}
1577
+ `;
1578
+ response += `- Total anchors: ${summary.stats.totalAnchors}
1579
+ `;
1580
+ response += `- Total events: ${summary.stats.totalEvents}
1581
+ `;
1582
+ response += `- Generated: ${new Date(summary.generatedAt).toLocaleString()}`;
1583
+ return {
1584
+ content: [
1585
+ {
1586
+ type: "text",
1587
+ text: response
1588
+ }
1589
+ ]
1590
+ };
1591
+ } catch (error) {
1592
+ return {
1593
+ content: [
1594
+ {
1595
+ type: "text",
1596
+ text: `\u274C Failed to get summary: ${error.message}`
1597
+ }
1598
+ ]
1599
+ };
1600
+ }
1601
+ }
1602
+ async start() {
1603
+ const transport = new StdioServerTransport();
1604
+ await this.server.connect(transport);
1605
+ console.error("StackMemory MCP Server started");
1606
+ }
1607
+ }
1608
+ var server_default = LocalStackMemoryMCP;
1609
+ async function runMCPServer() {
1610
+ const server = new LocalStackMemoryMCP();
1611
+ await server.start();
1612
+ }
1613
+ if (import.meta.url === `file://${process.argv[1]}`) {
1614
+ const server = new LocalStackMemoryMCP();
1615
+ server.start().catch(console.error);
1616
+ }
1617
+ export {
1618
+ server_default as default,
1619
+ runMCPServer
1620
+ };
1621
+ //# sourceMappingURL=server.js.map