@stackmemoryai/stackmemory 0.8.0 → 1.0.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 (793) hide show
  1. package/LICENSE +64 -0
  2. package/README.md +54 -4
  3. package/dist/src/agents/core/agent-task-manager.js +0 -1
  4. package/dist/src/agents/verifiers/base-verifier.js +0 -1
  5. package/dist/src/agents/verifiers/formatter-verifier.js +0 -1
  6. package/dist/src/agents/verifiers/llm-judge.js +0 -1
  7. package/dist/src/cli/auto-detect.js +0 -1
  8. package/dist/src/cli/claude-sm-danger.js +0 -1
  9. package/dist/src/cli/claude-sm.js +69 -373
  10. package/dist/src/cli/codex-sm-danger.js +0 -1
  11. package/dist/src/cli/codex-sm.js +28 -1
  12. package/dist/src/cli/commands/api.js +0 -1
  13. package/dist/src/cli/commands/auto-background.js +0 -1
  14. package/dist/src/cli/commands/cleanup-processes.js +0 -1
  15. package/dist/src/cli/commands/clear.js +0 -1
  16. package/dist/src/cli/commands/config.js +0 -1
  17. package/dist/src/cli/commands/context-rehydrate.js +0 -1
  18. package/dist/src/cli/commands/context.js +0 -1
  19. package/dist/src/cli/commands/daemon.js +0 -1
  20. package/dist/src/cli/commands/dashboard.js +4 -5
  21. package/dist/src/cli/commands/db.js +0 -1
  22. package/dist/src/cli/commands/decision.js +0 -1
  23. package/dist/src/cli/commands/discovery.js +0 -1
  24. package/dist/src/cli/commands/handoff.js +0 -1
  25. package/dist/src/cli/commands/hooks.js +0 -1
  26. package/dist/src/cli/commands/linear.js +0 -1
  27. package/dist/src/cli/commands/log.js +0 -1
  28. package/dist/src/cli/commands/login.js +0 -1
  29. package/dist/src/cli/commands/migrate.js +0 -1
  30. package/dist/src/cli/commands/model.js +0 -1
  31. package/dist/src/cli/commands/onboard.js +22 -7
  32. package/dist/src/cli/commands/ping.js +0 -1
  33. package/dist/src/cli/commands/projects.js +0 -1
  34. package/dist/src/cli/commands/ralph.js +0 -1
  35. package/dist/src/cli/commands/retrieval.js +0 -1
  36. package/dist/src/cli/commands/search.js +0 -1
  37. package/dist/src/cli/commands/service.js +0 -1
  38. package/dist/src/cli/commands/session.js +0 -1
  39. package/dist/src/cli/commands/setup.js +1 -6
  40. package/dist/src/cli/commands/shell.js +0 -1
  41. package/dist/src/cli/commands/signup.js +0 -1
  42. package/dist/src/cli/commands/skills.js +4 -3
  43. package/dist/src/cli/commands/storage-tier.js +0 -1
  44. package/dist/src/cli/commands/sweep.js +0 -1
  45. package/dist/src/cli/commands/tasks.js +0 -1
  46. package/dist/src/cli/commands/worktree.js +10 -5
  47. package/dist/src/cli/index.js +9 -76
  48. package/dist/src/cli/opencode-sm.js +28 -1
  49. package/dist/src/cli/utils/viewer.js +0 -1
  50. package/dist/src/core/config/config-manager.js +0 -1
  51. package/dist/src/core/config/feature-flags.js +1 -14
  52. package/dist/src/core/config/storage-config.js +0 -1
  53. package/dist/src/core/config/types.js +0 -1
  54. package/dist/src/core/context/auto-context.js +0 -1
  55. package/dist/src/core/context/dual-stack-manager.js +0 -1
  56. package/dist/src/core/context/enhanced-rehydration.js +0 -2
  57. package/dist/src/core/context/frame-database.js +60 -6
  58. package/dist/src/core/context/frame-digest.js +0 -1
  59. package/dist/src/core/context/frame-handoff-manager.js +0 -1
  60. package/dist/src/core/context/frame-lifecycle-hooks.js +0 -1
  61. package/dist/src/core/context/frame-recovery.js +0 -1
  62. package/dist/src/core/context/frame-stack.js +0 -1
  63. package/dist/src/core/context/frame-types.js +0 -1
  64. package/dist/src/core/context/index.js +0 -1
  65. package/dist/src/core/context/permission-manager.js +0 -1
  66. package/dist/src/core/context/recursive-context-manager.js +3 -2
  67. package/dist/src/core/context/refactored-frame-manager.js +0 -1
  68. package/dist/src/core/context/shared-context-layer.js +0 -1
  69. package/dist/src/core/context/stack-merge-resolver.js +0 -1
  70. package/dist/src/core/context/validation.js +0 -1
  71. package/dist/src/core/database/batch-operations.js +0 -1
  72. package/dist/src/core/database/connection-pool.js +0 -1
  73. package/dist/src/core/database/database-adapter.js +0 -1
  74. package/dist/src/core/database/embedding-provider-factory.js +0 -1
  75. package/dist/src/core/database/embedding-provider.js +0 -1
  76. package/dist/src/core/database/migration-manager.js +0 -1
  77. package/dist/src/core/database/ollama-embedding-provider.js +0 -1
  78. package/dist/src/core/database/openai-embedding-provider.js +0 -1
  79. package/dist/src/core/database/query-cache.js +0 -1
  80. package/dist/src/core/database/query-router.js +0 -1
  81. package/dist/src/core/database/sqlite-adapter.js +18 -108
  82. package/dist/src/core/database/transformers-embedding-provider.js +0 -1
  83. package/dist/src/core/digest/enhanced-hybrid-digest.js +0 -1
  84. package/dist/src/core/digest/frame-digest-integration.js +0 -1
  85. package/dist/src/core/digest/hybrid-digest-generator.js +0 -1
  86. package/dist/src/core/digest/index.js +0 -1
  87. package/dist/src/core/digest/types.js +0 -1
  88. package/dist/src/core/errors/error-utils.js +0 -1
  89. package/dist/src/core/errors/index.js +0 -1
  90. package/dist/src/core/errors/recovery.js +0 -1
  91. package/dist/src/core/execution/parallel-executor.js +0 -1
  92. package/dist/src/core/extensions/custom-tools.js +0 -1
  93. package/dist/src/core/extensions/index.js +0 -1
  94. package/dist/src/core/extensions/loader.js +0 -1
  95. package/dist/src/core/extensions/plugin-system.js +0 -1
  96. package/dist/src/core/extensions/provider-adapter.js +0 -1
  97. package/dist/src/core/extensions/sandbox-runtime.js +0 -1
  98. package/dist/src/core/extensions/types.js +0 -1
  99. package/dist/src/core/frame/workflow-templates.js +0 -1
  100. package/dist/src/core/merge/conflict-detector.js +0 -1
  101. package/dist/src/core/merge/index.js +0 -1
  102. package/dist/src/core/merge/resolution-engine.js +0 -1
  103. package/dist/src/core/merge/stack-diff.js +0 -1
  104. package/dist/src/core/merge/types.js +0 -1
  105. package/dist/src/core/merge/unified-merge-resolver.js +0 -1
  106. package/dist/src/core/models/fallback-monitor.js +0 -1
  107. package/dist/src/core/models/model-router.js +0 -1
  108. package/dist/src/core/monitoring/error-handler.js +0 -1
  109. package/dist/src/core/monitoring/logger.js +0 -1
  110. package/dist/src/core/monitoring/metrics.js +0 -1
  111. package/dist/src/core/monitoring/progress-tracker.js +0 -1
  112. package/dist/src/core/monitoring/session-monitor.js +0 -1
  113. package/dist/src/core/performance/context-cache.js +0 -1
  114. package/dist/src/core/performance/index.js +0 -1
  115. package/dist/src/core/performance/lazy-context-loader.js +3 -8
  116. package/dist/src/core/performance/monitor.js +0 -1
  117. package/dist/src/core/performance/optimized-frame-context.js +0 -1
  118. package/dist/src/core/performance/performance-benchmark.js +0 -1
  119. package/dist/src/core/performance/performance-profiler.js +0 -1
  120. package/dist/src/core/performance/streaming-jsonl-parser.js +0 -1
  121. package/dist/src/core/persistence/postgres-adapter.js +0 -1
  122. package/dist/src/core/projects/project-isolation.js +0 -1
  123. package/dist/src/core/projects/project-manager.js +0 -1
  124. package/dist/src/core/query/query-parser.js +0 -1
  125. package/dist/src/core/query/query-templates.js +0 -1
  126. package/dist/src/core/retrieval/context-retriever.js +0 -1
  127. package/dist/src/core/retrieval/index.js +0 -1
  128. package/dist/src/core/retrieval/llm-context-retrieval.js +0 -1
  129. package/dist/src/core/retrieval/llm-provider.js +0 -1
  130. package/dist/src/core/retrieval/privacy-filter.js +0 -1
  131. package/dist/src/core/retrieval/retrieval-audit.js +0 -1
  132. package/dist/src/core/retrieval/summary-generator.js +15 -6
  133. package/dist/src/core/retrieval/types.js +0 -1
  134. package/dist/src/core/retrieval/unified-context-assembler.js +0 -1
  135. package/dist/src/core/security/index.js +0 -1
  136. package/dist/src/core/security/input-sanitizer.js +0 -1
  137. package/dist/src/core/session/clear-survival.js +0 -1
  138. package/dist/src/core/session/enhanced-handoff.js +0 -1
  139. package/dist/src/core/session/handoff-generator.js +0 -1
  140. package/dist/src/core/session/index.js +0 -1
  141. package/dist/src/core/session/session-manager.js +0 -1
  142. package/dist/src/core/skills/index.js +0 -1
  143. package/dist/src/core/skills/skill-storage.js +0 -1
  144. package/dist/src/core/skills/types.js +0 -1
  145. package/dist/src/core/storage/chromadb-adapter.js +0 -1
  146. package/dist/src/core/storage/infinite-storage.js +0 -1
  147. package/dist/src/core/storage/project-registry.js +0 -1
  148. package/dist/src/core/storage/remote-storage.js +4 -2
  149. package/dist/src/core/storage/storage-tier-manager.js +0 -1
  150. package/dist/src/core/storage/two-tier-storage.js +0 -1
  151. package/dist/src/core/trace/cli-trace-wrapper.js +0 -1
  152. package/dist/src/core/trace/db-trace-wrapper.js +0 -1
  153. package/dist/src/core/trace/debug-trace.js +0 -1
  154. package/dist/src/core/trace/index.js +0 -1
  155. package/dist/src/core/trace/linear-api-wrapper.js +0 -1
  156. package/dist/src/core/trace/trace-detector.js +0 -1
  157. package/dist/src/core/trace/trace-store.js +4 -5
  158. package/dist/src/core/trace/types.js +0 -1
  159. package/dist/src/core/types.js +0 -1
  160. package/dist/src/core/utils/async-mutex.js +0 -1
  161. package/dist/src/core/utils/compression.js +0 -1
  162. package/dist/src/core/utils/update-checker.js +0 -1
  163. package/dist/src/core/worktree/worktree-manager.js +0 -1
  164. package/dist/src/daemon/daemon-config.js +0 -1
  165. package/dist/src/daemon/services/context-service.js +0 -1
  166. package/dist/src/daemon/services/linear-service.js +0 -1
  167. package/dist/src/daemon/services/maintenance-service.js +0 -1
  168. package/dist/src/daemon/services/memory-service.js +0 -1
  169. package/dist/src/daemon/session-daemon.js +0 -1
  170. package/dist/src/daemon/unified-daemon.js +0 -1
  171. package/dist/src/features/analytics/api/analytics-api.js +0 -1
  172. package/dist/src/features/analytics/core/analytics-service.js +1 -2
  173. package/dist/src/features/analytics/index.js +0 -1
  174. package/dist/src/features/analytics/queries/metrics-queries.js +8 -9
  175. package/dist/src/features/analytics/types/metrics.js +0 -1
  176. package/dist/src/features/browser/browser-mcp.js +0 -1
  177. package/dist/src/features/sweep/index.js +0 -1
  178. package/dist/src/features/sweep/prediction-client.js +0 -1
  179. package/dist/src/features/sweep/prompt-builder.js +0 -1
  180. package/dist/src/features/sweep/pty-wrapper.js +11 -2
  181. package/dist/src/features/sweep/state-watcher.js +0 -1
  182. package/dist/src/features/sweep/status-bar.js +0 -1
  183. package/dist/src/features/sweep/sweep-server-manager.js +0 -1
  184. package/dist/src/features/sweep/tab-interceptor.js +0 -1
  185. package/dist/src/features/sweep/types.js +0 -1
  186. package/dist/src/features/tasks/linear-task-manager.js +0 -1
  187. package/dist/src/features/tasks/task-aware-context.js +0 -1
  188. package/dist/src/features/tui/simple-monitor.js +0 -1
  189. package/dist/src/features/tui/swarm-monitor.js +0 -1
  190. package/dist/src/features/web/client/stores/task-store.js +0 -1
  191. package/dist/src/features/web/server/index.js +0 -1
  192. package/dist/src/features/workers/tmux-manager.js +0 -1
  193. package/dist/src/features/workers/worker-registry.js +0 -1
  194. package/dist/src/hooks/auto-background.js +0 -1
  195. package/dist/src/hooks/config.js +0 -1
  196. package/dist/src/hooks/daemon.js +0 -1
  197. package/dist/src/hooks/diffmem-hooks.js +0 -1
  198. package/dist/src/hooks/events.js +0 -1
  199. package/dist/src/hooks/index.js +0 -4
  200. package/dist/src/hooks/linear-task-picker.js +0 -1
  201. package/dist/src/hooks/schemas.js +0 -118
  202. package/dist/src/hooks/secure-fs.js +0 -1
  203. package/dist/src/hooks/security-logger.js +0 -1
  204. package/dist/src/hooks/session-summary.js +0 -1
  205. package/dist/src/index.js +0 -1
  206. package/dist/src/integrations/anthropic/client.js +0 -1
  207. package/dist/src/integrations/claude-code/agent-bridge.js +0 -1
  208. package/dist/src/integrations/claude-code/enhanced-pre-clear-hooks.js +0 -1
  209. package/dist/src/integrations/claude-code/lifecycle-hooks.js +0 -1
  210. package/dist/src/integrations/claude-code/post-task-hooks.js +0 -1
  211. package/dist/src/integrations/claude-code/subagent-client-stub.js +0 -1
  212. package/dist/src/integrations/claude-code/subagent-client.js +0 -1
  213. package/dist/src/integrations/claude-code/task-coordinator.js +0 -1
  214. package/dist/src/integrations/diffmem/client.js +0 -1
  215. package/dist/src/integrations/diffmem/config.js +0 -1
  216. package/dist/src/integrations/diffmem/index.js +0 -1
  217. package/dist/src/integrations/diffmem/types.js +0 -1
  218. package/dist/src/integrations/linear/auth.js +0 -1
  219. package/dist/src/integrations/linear/auto-sync.js +0 -1
  220. package/dist/src/integrations/linear/client.js +0 -1
  221. package/dist/src/integrations/linear/config.js +0 -1
  222. package/dist/src/integrations/linear/migration.js +0 -1
  223. package/dist/src/integrations/linear/oauth-server.js +0 -1
  224. package/dist/src/integrations/linear/rest-client.js +0 -1
  225. package/dist/src/integrations/linear/sync-manager.js +0 -1
  226. package/dist/src/integrations/linear/sync-service.js +0 -1
  227. package/dist/src/integrations/linear/sync.js +0 -1
  228. package/dist/src/integrations/linear/types.js +0 -1
  229. package/dist/src/integrations/linear/unified-sync.js +0 -1
  230. package/dist/src/integrations/linear/webhook-handler.js +0 -1
  231. package/dist/src/integrations/linear/webhook-server.js +0 -1
  232. package/dist/src/integrations/linear/webhook.js +0 -1
  233. package/dist/src/integrations/mcp/handlers/code-execution-handlers.js +0 -1
  234. package/dist/src/integrations/mcp/handlers/context-handlers.js +43 -30
  235. package/dist/src/integrations/mcp/handlers/diffmem-handlers.js +0 -1
  236. package/dist/src/integrations/mcp/handlers/discovery-handlers.js +0 -1
  237. package/dist/src/integrations/mcp/handlers/index.js +1 -3
  238. package/dist/src/integrations/mcp/handlers/linear-handlers.js +24 -61
  239. package/dist/src/integrations/mcp/handlers/skill-handlers.js +0 -1
  240. package/dist/src/integrations/mcp/handlers/task-handlers.js +0 -1
  241. package/dist/src/integrations/mcp/handlers/trace-handlers.js +0 -1
  242. package/dist/src/integrations/mcp/index.js +0 -1
  243. package/dist/src/integrations/mcp/middleware/tool-scoring.js +3 -2
  244. package/dist/src/integrations/mcp/pending-utils.js +0 -1
  245. package/dist/src/integrations/mcp/refactored-server.js +0 -1
  246. package/dist/src/integrations/mcp/remote-server.js +0 -1
  247. package/dist/src/integrations/mcp/schemas.js +0 -1
  248. package/dist/src/integrations/mcp/server.js +20 -24
  249. package/dist/src/integrations/mcp/tool-definitions-code.js +0 -1
  250. package/dist/src/integrations/mcp/tool-definitions.js +0 -1
  251. package/dist/src/integrations/ralph/bridge/ralph-stackmemory-bridge.js +0 -1
  252. package/dist/src/integrations/ralph/context/context-budget-manager.js +0 -1
  253. package/dist/src/integrations/ralph/context/stackmemory-context-loader.js +0 -1
  254. package/dist/src/integrations/ralph/coordination/enhanced-coordination.js +0 -1
  255. package/dist/src/integrations/ralph/index.js +0 -1
  256. package/dist/src/integrations/ralph/learning/pattern-learner.js +0 -1
  257. package/dist/src/integrations/ralph/lifecycle/iteration-lifecycle.js +5 -5
  258. package/dist/src/integrations/ralph/monitoring/swarm-dashboard.js +0 -1
  259. package/dist/src/integrations/ralph/monitoring/swarm-registry.js +0 -1
  260. package/dist/src/integrations/ralph/orchestration/multi-loop-orchestrator.js +0 -1
  261. package/dist/src/integrations/ralph/patterns/compounding-engineering-pattern.js +0 -1
  262. package/dist/src/integrations/ralph/patterns/extended-coherence-sessions.js +0 -1
  263. package/dist/src/integrations/ralph/patterns/oracle-worker-pattern.js +0 -1
  264. package/dist/src/integrations/ralph/performance/performance-optimizer.js +0 -1
  265. package/dist/src/integrations/ralph/recovery/crash-recovery.js +0 -1
  266. package/dist/src/integrations/ralph/state/state-reconciler.js +25 -9
  267. package/dist/src/integrations/ralph/swarm/git-workflow-manager.js +0 -1
  268. package/dist/src/integrations/ralph/swarm/swarm-coordinator.js +0 -1
  269. package/dist/src/integrations/ralph/types.js +0 -1
  270. package/dist/src/integrations/ralph/visualization/ralph-debugger.js +0 -1
  271. package/dist/src/mcp/stackmemory-mcp-server.js +0 -1
  272. package/dist/src/middleware/exponential-rate-limiter.js +0 -1
  273. package/dist/src/models/user.model.js +0 -1
  274. package/dist/src/orchestrators/multimodal/constants.js +0 -1
  275. package/dist/src/orchestrators/multimodal/harness.js +0 -1
  276. package/dist/src/orchestrators/multimodal/providers.js +0 -1
  277. package/dist/src/orchestrators/multimodal/types.js +0 -1
  278. package/dist/src/orchestrators/multimodal/utils.js +0 -1
  279. package/dist/src/servers/production/auth-middleware.js +0 -1
  280. package/dist/src/services/config-service.js +0 -1
  281. package/dist/src/services/context-service.js +0 -1
  282. package/dist/src/skills/api-discovery.js +0 -1
  283. package/dist/src/skills/api-skill.js +0 -1
  284. package/dist/src/skills/claude-skills.js +0 -1
  285. package/dist/src/skills/dashboard-launcher.js +0 -1
  286. package/dist/src/skills/linear-task-runner.js +0 -1
  287. package/dist/src/skills/recursive-agent-orchestrator.js +0 -1
  288. package/dist/src/skills/repo-ingestion-skill.js +0 -1
  289. package/dist/src/skills/spec-generator-skill.js +0 -1
  290. package/dist/src/skills/unified-rlm-orchestrator.js +0 -1
  291. package/dist/src/types/task.js +0 -1
  292. package/dist/src/utils/env.js +0 -1
  293. package/dist/src/utils/formatting.js +0 -1
  294. package/dist/src/utils/process-cleanup.js +0 -1
  295. package/package.json +33 -8
  296. package/scripts/smoke-init-db.sh +77 -0
  297. package/dist/scripts/benchmark-performance.js +0 -48
  298. package/dist/scripts/benchmark-performance.js.map +0 -7
  299. package/dist/scripts/check-redis.js +0 -42
  300. package/dist/scripts/check-redis.js.map +0 -7
  301. package/dist/scripts/initialize.js +0 -183
  302. package/dist/scripts/initialize.js.map +0 -7
  303. package/dist/scripts/list-linear-tasks.js +0 -124
  304. package/dist/scripts/list-linear-tasks.js.map +0 -7
  305. package/dist/scripts/measure-handoff-impact.js +0 -340
  306. package/dist/scripts/measure-handoff-impact.js.map +0 -7
  307. package/dist/scripts/query-chromadb.js +0 -160
  308. package/dist/scripts/query-chromadb.js.map +0 -7
  309. package/dist/scripts/show-linear-summary.js +0 -119
  310. package/dist/scripts/show-linear-summary.js.map +0 -7
  311. package/dist/scripts/simple-swarm-demo.js +0 -90
  312. package/dist/scripts/simple-swarm-demo.js.map +0 -7
  313. package/dist/scripts/status.js +0 -155
  314. package/dist/scripts/status.js.map +0 -7
  315. package/dist/scripts/test-chromadb-sync.js +0 -192
  316. package/dist/scripts/test-chromadb-sync.js.map +0 -7
  317. package/dist/scripts/test-ralph-iteration-fix.js +0 -86
  318. package/dist/scripts/test-ralph-iteration-fix.js.map +0 -7
  319. package/dist/scripts/test-ralph-iterations.js +0 -121
  320. package/dist/scripts/test-ralph-iterations.js.map +0 -7
  321. package/dist/scripts/test-redis-storage.js +0 -389
  322. package/dist/scripts/test-redis-storage.js.map +0 -7
  323. package/dist/scripts/test-simple-ralph-state-sync.js +0 -115
  324. package/dist/scripts/test-simple-ralph-state-sync.js.map +0 -7
  325. package/dist/scripts/test-swarm-fixes.js +0 -125
  326. package/dist/scripts/test-swarm-fixes.js.map +0 -7
  327. package/dist/scripts/test-swarm-tui.js +0 -23
  328. package/dist/scripts/test-swarm-tui.js.map +0 -7
  329. package/dist/scripts/test-tui-shortcuts.js +0 -52
  330. package/dist/scripts/test-tui-shortcuts.js.map +0 -7
  331. package/dist/scripts/validate-tui-shortcuts.js +0 -60
  332. package/dist/scripts/validate-tui-shortcuts.js.map +0 -7
  333. package/dist/src/agents/core/agent-task-manager.js.map +0 -7
  334. package/dist/src/agents/verifiers/base-verifier.js.map +0 -7
  335. package/dist/src/agents/verifiers/formatter-verifier.js.map +0 -7
  336. package/dist/src/agents/verifiers/llm-judge.js.map +0 -7
  337. package/dist/src/cli/auto-detect.js.map +0 -7
  338. package/dist/src/cli/claude-sm-danger.js.map +0 -7
  339. package/dist/src/cli/claude-sm.js.map +0 -7
  340. package/dist/src/cli/codex-sm-danger.js.map +0 -7
  341. package/dist/src/cli/codex-sm.js.map +0 -7
  342. package/dist/src/cli/commands/api.js.map +0 -7
  343. package/dist/src/cli/commands/auto-background.js.map +0 -7
  344. package/dist/src/cli/commands/cleanup-processes.js.map +0 -7
  345. package/dist/src/cli/commands/clear.js.map +0 -7
  346. package/dist/src/cli/commands/config.js.map +0 -7
  347. package/dist/src/cli/commands/context-rehydrate.js.map +0 -7
  348. package/dist/src/cli/commands/context.js.map +0 -7
  349. package/dist/src/cli/commands/daemon.js.map +0 -7
  350. package/dist/src/cli/commands/dashboard.js.map +0 -7
  351. package/dist/src/cli/commands/db.js.map +0 -7
  352. package/dist/src/cli/commands/decision.js.map +0 -7
  353. package/dist/src/cli/commands/discovery.js.map +0 -7
  354. package/dist/src/cli/commands/handoff.js.map +0 -7
  355. package/dist/src/cli/commands/hooks.js.map +0 -7
  356. package/dist/src/cli/commands/linear.js.map +0 -7
  357. package/dist/src/cli/commands/log.js.map +0 -7
  358. package/dist/src/cli/commands/login.js.map +0 -7
  359. package/dist/src/cli/commands/migrate.js.map +0 -7
  360. package/dist/src/cli/commands/model.js.map +0 -7
  361. package/dist/src/cli/commands/onboard.js.map +0 -7
  362. package/dist/src/cli/commands/ping.js.map +0 -7
  363. package/dist/src/cli/commands/projects.js.map +0 -7
  364. package/dist/src/cli/commands/ralph.js.map +0 -7
  365. package/dist/src/cli/commands/retrieval.js.map +0 -7
  366. package/dist/src/cli/commands/search.js.map +0 -7
  367. package/dist/src/cli/commands/service.js.map +0 -7
  368. package/dist/src/cli/commands/session.js.map +0 -7
  369. package/dist/src/cli/commands/settings.js +0 -306
  370. package/dist/src/cli/commands/settings.js.map +0 -7
  371. package/dist/src/cli/commands/setup.js.map +0 -7
  372. package/dist/src/cli/commands/shell.js.map +0 -7
  373. package/dist/src/cli/commands/signup.js.map +0 -7
  374. package/dist/src/cli/commands/skills.js.map +0 -7
  375. package/dist/src/cli/commands/sms-notify.js +0 -795
  376. package/dist/src/cli/commands/sms-notify.js.map +0 -7
  377. package/dist/src/cli/commands/storage-tier.js.map +0 -7
  378. package/dist/src/cli/commands/sweep.js.map +0 -7
  379. package/dist/src/cli/commands/tasks.js.map +0 -7
  380. package/dist/src/cli/commands/worktree.js.map +0 -7
  381. package/dist/src/cli/index.js.map +0 -7
  382. package/dist/src/cli/opencode-sm.js.map +0 -7
  383. package/dist/src/cli/utils/viewer.js.map +0 -7
  384. package/dist/src/core/config/config-manager.js.map +0 -7
  385. package/dist/src/core/config/feature-flags.js.map +0 -7
  386. package/dist/src/core/config/storage-config.js.map +0 -7
  387. package/dist/src/core/config/types.js.map +0 -7
  388. package/dist/src/core/context/auto-context.js.map +0 -7
  389. package/dist/src/core/context/dual-stack-manager.js.map +0 -7
  390. package/dist/src/core/context/enhanced-rehydration.js.map +0 -7
  391. package/dist/src/core/context/frame-database.js.map +0 -7
  392. package/dist/src/core/context/frame-digest.js.map +0 -7
  393. package/dist/src/core/context/frame-handoff-manager.js.map +0 -7
  394. package/dist/src/core/context/frame-lifecycle-hooks.js.map +0 -7
  395. package/dist/src/core/context/frame-recovery.js.map +0 -7
  396. package/dist/src/core/context/frame-stack.js.map +0 -7
  397. package/dist/src/core/context/frame-types.js.map +0 -7
  398. package/dist/src/core/context/index.js.map +0 -7
  399. package/dist/src/core/context/permission-manager.js.map +0 -7
  400. package/dist/src/core/context/recursive-context-manager.js.map +0 -7
  401. package/dist/src/core/context/refactored-frame-manager.js.map +0 -7
  402. package/dist/src/core/context/shared-context-layer.js.map +0 -7
  403. package/dist/src/core/context/stack-merge-resolver.js.map +0 -7
  404. package/dist/src/core/context/validation.js.map +0 -7
  405. package/dist/src/core/database/batch-operations.js.map +0 -7
  406. package/dist/src/core/database/connection-pool.js.map +0 -7
  407. package/dist/src/core/database/database-adapter.js.map +0 -7
  408. package/dist/src/core/database/embedding-provider-factory.js.map +0 -7
  409. package/dist/src/core/database/embedding-provider.js.map +0 -7
  410. package/dist/src/core/database/migration-manager.js.map +0 -7
  411. package/dist/src/core/database/ollama-embedding-provider.js.map +0 -7
  412. package/dist/src/core/database/openai-embedding-provider.js.map +0 -7
  413. package/dist/src/core/database/query-cache.js.map +0 -7
  414. package/dist/src/core/database/query-router.js.map +0 -7
  415. package/dist/src/core/database/sqlite-adapter.js.map +0 -7
  416. package/dist/src/core/database/transformers-embedding-provider.js.map +0 -7
  417. package/dist/src/core/digest/enhanced-hybrid-digest.js.map +0 -7
  418. package/dist/src/core/digest/frame-digest-integration.js.map +0 -7
  419. package/dist/src/core/digest/hybrid-digest-generator.js.map +0 -7
  420. package/dist/src/core/digest/index.js.map +0 -7
  421. package/dist/src/core/digest/types.js.map +0 -7
  422. package/dist/src/core/errors/error-utils.js.map +0 -7
  423. package/dist/src/core/errors/index.js.map +0 -7
  424. package/dist/src/core/errors/recovery.js.map +0 -7
  425. package/dist/src/core/execution/parallel-executor.js.map +0 -7
  426. package/dist/src/core/extensions/custom-tools.js.map +0 -7
  427. package/dist/src/core/extensions/index.js.map +0 -7
  428. package/dist/src/core/extensions/loader.js.map +0 -7
  429. package/dist/src/core/extensions/plugin-system.js.map +0 -7
  430. package/dist/src/core/extensions/provider-adapter.js.map +0 -7
  431. package/dist/src/core/extensions/sandbox-runtime.js.map +0 -7
  432. package/dist/src/core/extensions/types.js.map +0 -7
  433. package/dist/src/core/frame/workflow-templates.js.map +0 -7
  434. package/dist/src/core/merge/conflict-detector.js.map +0 -7
  435. package/dist/src/core/merge/index.js.map +0 -7
  436. package/dist/src/core/merge/resolution-engine.js.map +0 -7
  437. package/dist/src/core/merge/stack-diff.js.map +0 -7
  438. package/dist/src/core/merge/types.js.map +0 -7
  439. package/dist/src/core/merge/unified-merge-resolver.js.map +0 -7
  440. package/dist/src/core/models/fallback-monitor.js.map +0 -7
  441. package/dist/src/core/models/model-router.js.map +0 -7
  442. package/dist/src/core/monitoring/error-handler.js.map +0 -7
  443. package/dist/src/core/monitoring/logger.js.map +0 -7
  444. package/dist/src/core/monitoring/metrics.js.map +0 -7
  445. package/dist/src/core/monitoring/progress-tracker.js.map +0 -7
  446. package/dist/src/core/monitoring/session-monitor.js.map +0 -7
  447. package/dist/src/core/performance/context-cache.js.map +0 -7
  448. package/dist/src/core/performance/index.js.map +0 -7
  449. package/dist/src/core/performance/lazy-context-loader.js.map +0 -7
  450. package/dist/src/core/performance/monitor.js.map +0 -7
  451. package/dist/src/core/performance/optimized-frame-context.js.map +0 -7
  452. package/dist/src/core/performance/performance-benchmark.js.map +0 -7
  453. package/dist/src/core/performance/performance-profiler.js.map +0 -7
  454. package/dist/src/core/performance/streaming-jsonl-parser.js.map +0 -7
  455. package/dist/src/core/persistence/postgres-adapter.js.map +0 -7
  456. package/dist/src/core/projects/project-isolation.js.map +0 -7
  457. package/dist/src/core/projects/project-manager.js.map +0 -7
  458. package/dist/src/core/query/query-parser.js.map +0 -7
  459. package/dist/src/core/query/query-templates.js.map +0 -7
  460. package/dist/src/core/retrieval/context-retriever.js.map +0 -7
  461. package/dist/src/core/retrieval/index.js.map +0 -7
  462. package/dist/src/core/retrieval/llm-context-retrieval.js.map +0 -7
  463. package/dist/src/core/retrieval/llm-provider.js.map +0 -7
  464. package/dist/src/core/retrieval/privacy-filter.js.map +0 -7
  465. package/dist/src/core/retrieval/retrieval-audit.js.map +0 -7
  466. package/dist/src/core/retrieval/summary-generator.js.map +0 -7
  467. package/dist/src/core/retrieval/types.js.map +0 -7
  468. package/dist/src/core/retrieval/unified-context-assembler.js.map +0 -7
  469. package/dist/src/core/security/index.js.map +0 -7
  470. package/dist/src/core/security/input-sanitizer.js.map +0 -7
  471. package/dist/src/core/session/clear-survival.js.map +0 -7
  472. package/dist/src/core/session/enhanced-handoff.js.map +0 -7
  473. package/dist/src/core/session/handoff-generator.js.map +0 -7
  474. package/dist/src/core/session/index.js.map +0 -7
  475. package/dist/src/core/session/session-manager.js.map +0 -7
  476. package/dist/src/core/skills/index.js.map +0 -7
  477. package/dist/src/core/skills/skill-storage.js.map +0 -7
  478. package/dist/src/core/skills/types.js.map +0 -7
  479. package/dist/src/core/storage/chromadb-adapter.js.map +0 -7
  480. package/dist/src/core/storage/infinite-storage.js.map +0 -7
  481. package/dist/src/core/storage/project-registry.js.map +0 -7
  482. package/dist/src/core/storage/remote-storage.js.map +0 -7
  483. package/dist/src/core/storage/storage-tier-manager.js.map +0 -7
  484. package/dist/src/core/storage/two-tier-storage.js.map +0 -7
  485. package/dist/src/core/trace/cli-trace-wrapper.js.map +0 -7
  486. package/dist/src/core/trace/db-trace-wrapper.js.map +0 -7
  487. package/dist/src/core/trace/debug-trace.js.map +0 -7
  488. package/dist/src/core/trace/index.js.map +0 -7
  489. package/dist/src/core/trace/linear-api-wrapper.js.map +0 -7
  490. package/dist/src/core/trace/trace-detector.js.map +0 -7
  491. package/dist/src/core/trace/trace-store.js.map +0 -7
  492. package/dist/src/core/trace/types.js.map +0 -7
  493. package/dist/src/core/types.js.map +0 -7
  494. package/dist/src/core/utils/async-mutex.js.map +0 -7
  495. package/dist/src/core/utils/compression.js.map +0 -7
  496. package/dist/src/core/utils/update-checker.js.map +0 -7
  497. package/dist/src/core/worktree/worktree-manager.js.map +0 -7
  498. package/dist/src/daemon/daemon-config.js.map +0 -7
  499. package/dist/src/daemon/services/context-service.js.map +0 -7
  500. package/dist/src/daemon/services/linear-service.js.map +0 -7
  501. package/dist/src/daemon/services/maintenance-service.js.map +0 -7
  502. package/dist/src/daemon/services/memory-service.js.map +0 -7
  503. package/dist/src/daemon/session-daemon.js.map +0 -7
  504. package/dist/src/daemon/unified-daemon.js.map +0 -7
  505. package/dist/src/features/analytics/api/analytics-api.js.map +0 -7
  506. package/dist/src/features/analytics/core/analytics-service.js.map +0 -7
  507. package/dist/src/features/analytics/index.js.map +0 -7
  508. package/dist/src/features/analytics/queries/metrics-queries.js.map +0 -7
  509. package/dist/src/features/analytics/types/metrics.js.map +0 -7
  510. package/dist/src/features/browser/browser-mcp.js.map +0 -7
  511. package/dist/src/features/sweep/index.js.map +0 -7
  512. package/dist/src/features/sweep/prediction-client.js.map +0 -7
  513. package/dist/src/features/sweep/prompt-builder.js.map +0 -7
  514. package/dist/src/features/sweep/pty-wrapper.js.map +0 -7
  515. package/dist/src/features/sweep/state-watcher.js.map +0 -7
  516. package/dist/src/features/sweep/status-bar.js.map +0 -7
  517. package/dist/src/features/sweep/sweep-server-manager.js.map +0 -7
  518. package/dist/src/features/sweep/tab-interceptor.js.map +0 -7
  519. package/dist/src/features/sweep/types.js.map +0 -7
  520. package/dist/src/features/tasks/linear-task-manager.js.map +0 -7
  521. package/dist/src/features/tasks/task-aware-context.js.map +0 -7
  522. package/dist/src/features/tui/simple-monitor.js.map +0 -7
  523. package/dist/src/features/tui/swarm-monitor.js.map +0 -7
  524. package/dist/src/features/web/client/stores/task-store.js.map +0 -7
  525. package/dist/src/features/web/server/index.js.map +0 -7
  526. package/dist/src/features/workers/tmux-manager.js.map +0 -7
  527. package/dist/src/features/workers/worker-registry.js.map +0 -7
  528. package/dist/src/hooks/auto-background.js.map +0 -7
  529. package/dist/src/hooks/claude-code-whatsapp-hook.js +0 -197
  530. package/dist/src/hooks/claude-code-whatsapp-hook.js.map +0 -7
  531. package/dist/src/hooks/config.js.map +0 -7
  532. package/dist/src/hooks/daemon.js.map +0 -7
  533. package/dist/src/hooks/diffmem-hooks.js.map +0 -7
  534. package/dist/src/hooks/events.js.map +0 -7
  535. package/dist/src/hooks/index.js.map +0 -7
  536. package/dist/src/hooks/linear-task-picker.js.map +0 -7
  537. package/dist/src/hooks/schemas.js.map +0 -7
  538. package/dist/src/hooks/secure-fs.js.map +0 -7
  539. package/dist/src/hooks/security-logger.js.map +0 -7
  540. package/dist/src/hooks/session-summary.js.map +0 -7
  541. package/dist/src/hooks/sms-action-runner.js +0 -371
  542. package/dist/src/hooks/sms-action-runner.js.map +0 -7
  543. package/dist/src/hooks/sms-notify.js +0 -506
  544. package/dist/src/hooks/sms-notify.js.map +0 -7
  545. package/dist/src/hooks/sms-watcher.js +0 -93
  546. package/dist/src/hooks/sms-watcher.js.map +0 -7
  547. package/dist/src/hooks/sms-webhook.js +0 -555
  548. package/dist/src/hooks/sms-webhook.js.map +0 -7
  549. package/dist/src/hooks/whatsapp-commands.js +0 -479
  550. package/dist/src/hooks/whatsapp-commands.js.map +0 -7
  551. package/dist/src/hooks/whatsapp-scheduler.js +0 -317
  552. package/dist/src/hooks/whatsapp-scheduler.js.map +0 -7
  553. package/dist/src/hooks/whatsapp-sync.js +0 -409
  554. package/dist/src/hooks/whatsapp-sync.js.map +0 -7
  555. package/dist/src/index.js.map +0 -7
  556. package/dist/src/integrations/anthropic/client.js.map +0 -7
  557. package/dist/src/integrations/claude-code/agent-bridge.js.map +0 -7
  558. package/dist/src/integrations/claude-code/enhanced-pre-clear-hooks.js.map +0 -7
  559. package/dist/src/integrations/claude-code/lifecycle-hooks.js.map +0 -7
  560. package/dist/src/integrations/claude-code/post-task-hooks.js.map +0 -7
  561. package/dist/src/integrations/claude-code/subagent-client-stub.js.map +0 -7
  562. package/dist/src/integrations/claude-code/subagent-client.js.map +0 -7
  563. package/dist/src/integrations/claude-code/task-coordinator.js.map +0 -7
  564. package/dist/src/integrations/diffmem/client.js.map +0 -7
  565. package/dist/src/integrations/diffmem/config.js.map +0 -7
  566. package/dist/src/integrations/diffmem/index.js.map +0 -7
  567. package/dist/src/integrations/diffmem/types.js.map +0 -7
  568. package/dist/src/integrations/linear/auth.js.map +0 -7
  569. package/dist/src/integrations/linear/auto-sync.js.map +0 -7
  570. package/dist/src/integrations/linear/client.js.map +0 -7
  571. package/dist/src/integrations/linear/config.js.map +0 -7
  572. package/dist/src/integrations/linear/migration.js.map +0 -7
  573. package/dist/src/integrations/linear/oauth-server.js.map +0 -7
  574. package/dist/src/integrations/linear/rest-client.js.map +0 -7
  575. package/dist/src/integrations/linear/sync-manager.js.map +0 -7
  576. package/dist/src/integrations/linear/sync-service.js.map +0 -7
  577. package/dist/src/integrations/linear/sync.js.map +0 -7
  578. package/dist/src/integrations/linear/types.js.map +0 -7
  579. package/dist/src/integrations/linear/unified-sync.js.map +0 -7
  580. package/dist/src/integrations/linear/webhook-handler.js.map +0 -7
  581. package/dist/src/integrations/linear/webhook-server.js.map +0 -7
  582. package/dist/src/integrations/linear/webhook.js.map +0 -7
  583. package/dist/src/integrations/mcp/handlers/code-execution-handlers.js.map +0 -7
  584. package/dist/src/integrations/mcp/handlers/context-handlers.js.map +0 -7
  585. package/dist/src/integrations/mcp/handlers/diffmem-handlers.js.map +0 -7
  586. package/dist/src/integrations/mcp/handlers/discovery-handlers.js.map +0 -7
  587. package/dist/src/integrations/mcp/handlers/index.js.map +0 -7
  588. package/dist/src/integrations/mcp/handlers/linear-handlers.js.map +0 -7
  589. package/dist/src/integrations/mcp/handlers/skill-handlers.js.map +0 -7
  590. package/dist/src/integrations/mcp/handlers/task-handlers.js.map +0 -7
  591. package/dist/src/integrations/mcp/handlers/trace-handlers.js.map +0 -7
  592. package/dist/src/integrations/mcp/index.js.map +0 -7
  593. package/dist/src/integrations/mcp/middleware/tool-scoring.js.map +0 -7
  594. package/dist/src/integrations/mcp/pending-utils.js.map +0 -7
  595. package/dist/src/integrations/mcp/refactored-server.js.map +0 -7
  596. package/dist/src/integrations/mcp/remote-server.js.map +0 -7
  597. package/dist/src/integrations/mcp/schemas.js.map +0 -7
  598. package/dist/src/integrations/mcp/server.js.map +0 -7
  599. package/dist/src/integrations/mcp/tool-definitions-code.js.map +0 -7
  600. package/dist/src/integrations/mcp/tool-definitions.js.map +0 -7
  601. package/dist/src/integrations/ralph/bridge/ralph-stackmemory-bridge.js.map +0 -7
  602. package/dist/src/integrations/ralph/context/context-budget-manager.js.map +0 -7
  603. package/dist/src/integrations/ralph/context/stackmemory-context-loader.js.map +0 -7
  604. package/dist/src/integrations/ralph/coordination/enhanced-coordination.js.map +0 -7
  605. package/dist/src/integrations/ralph/index.js.map +0 -7
  606. package/dist/src/integrations/ralph/learning/pattern-learner.js.map +0 -7
  607. package/dist/src/integrations/ralph/lifecycle/iteration-lifecycle.js.map +0 -7
  608. package/dist/src/integrations/ralph/monitoring/swarm-dashboard.js.map +0 -7
  609. package/dist/src/integrations/ralph/monitoring/swarm-registry.js.map +0 -7
  610. package/dist/src/integrations/ralph/orchestration/multi-loop-orchestrator.js.map +0 -7
  611. package/dist/src/integrations/ralph/patterns/compounding-engineering-pattern.js.map +0 -7
  612. package/dist/src/integrations/ralph/patterns/extended-coherence-sessions.js.map +0 -7
  613. package/dist/src/integrations/ralph/patterns/oracle-worker-pattern.js.map +0 -7
  614. package/dist/src/integrations/ralph/performance/performance-optimizer.js.map +0 -7
  615. package/dist/src/integrations/ralph/recovery/crash-recovery.js.map +0 -7
  616. package/dist/src/integrations/ralph/state/state-reconciler.js.map +0 -7
  617. package/dist/src/integrations/ralph/swarm/git-workflow-manager.js.map +0 -7
  618. package/dist/src/integrations/ralph/swarm/swarm-coordinator.js.map +0 -7
  619. package/dist/src/integrations/ralph/types.js.map +0 -7
  620. package/dist/src/integrations/ralph/visualization/ralph-debugger.js.map +0 -7
  621. package/dist/src/mcp/stackmemory-mcp-server.js.map +0 -7
  622. package/dist/src/middleware/exponential-rate-limiter.js.map +0 -7
  623. package/dist/src/models/user.model.js.map +0 -7
  624. package/dist/src/orchestrators/multimodal/constants.js.map +0 -7
  625. package/dist/src/orchestrators/multimodal/harness.js.map +0 -7
  626. package/dist/src/orchestrators/multimodal/providers.js.map +0 -7
  627. package/dist/src/orchestrators/multimodal/types.js.map +0 -7
  628. package/dist/src/orchestrators/multimodal/utils.js.map +0 -7
  629. package/dist/src/servers/production/auth-middleware.js.map +0 -7
  630. package/dist/src/services/config-service.js.map +0 -7
  631. package/dist/src/services/context-service.js.map +0 -7
  632. package/dist/src/skills/api-discovery.js.map +0 -7
  633. package/dist/src/skills/api-skill.js.map +0 -7
  634. package/dist/src/skills/claude-skills.js.map +0 -7
  635. package/dist/src/skills/dashboard-launcher.js.map +0 -7
  636. package/dist/src/skills/linear-task-runner.js.map +0 -7
  637. package/dist/src/skills/recursive-agent-orchestrator.js.map +0 -7
  638. package/dist/src/skills/repo-ingestion-skill.js.map +0 -7
  639. package/dist/src/skills/spec-generator-skill.js.map +0 -7
  640. package/dist/src/skills/unified-rlm-orchestrator.js.map +0 -7
  641. package/dist/src/types/task.js.map +0 -7
  642. package/dist/src/utils/env.js.map +0 -7
  643. package/dist/src/utils/formatting.js.map +0 -7
  644. package/dist/src/utils/process-cleanup.js.map +0 -7
  645. package/scripts/README-TESTING.md +0 -186
  646. package/scripts/analyze-cli-security.js +0 -288
  647. package/scripts/archive/add-phase-tasks-to-linear.js +0 -163
  648. package/scripts/archive/analyze-linear-duplicates.js +0 -214
  649. package/scripts/archive/analyze-remaining-duplicates.js +0 -230
  650. package/scripts/archive/analyze-sta-duplicates.js +0 -292
  651. package/scripts/archive/analyze-sta-graphql.js +0 -399
  652. package/scripts/archive/cancel-duplicate-tasks.ts +0 -246
  653. package/scripts/archive/check-all-duplicates.ts +0 -419
  654. package/scripts/archive/clean-duplicate-tasks.js +0 -114
  655. package/scripts/archive/cleanup-duplicate-tasks.ts +0 -286
  656. package/scripts/archive/create-phase-tasks.js +0 -387
  657. package/scripts/archive/delete-linear-duplicates.js +0 -182
  658. package/scripts/archive/delete-remaining-duplicates.js +0 -158
  659. package/scripts/archive/delete-sta-duplicates.js +0 -201
  660. package/scripts/archive/delete-sta-oauth.js +0 -201
  661. package/scripts/archive/export-sta-tasks.js +0 -62
  662. package/scripts/archive/install-auto-sync.js +0 -266
  663. package/scripts/archive/install-chromadb-hooks.sh +0 -133
  664. package/scripts/archive/install-enhanced-clear-hooks.sh +0 -431
  665. package/scripts/archive/install-post-task-hooks.sh +0 -289
  666. package/scripts/archive/install-stackmemory-hooks.sh +0 -420
  667. package/scripts/archive/merge-linear-duplicates-safe.ts +0 -362
  668. package/scripts/archive/merge-linear-duplicates.ts +0 -182
  669. package/scripts/archive/remove-sta-tasks.js +0 -70
  670. package/scripts/archive/setup-background-sync.sh +0 -168
  671. package/scripts/archive/setup-claude-auto-triggers.sh +0 -181
  672. package/scripts/archive/setup-claude-autostart.sh +0 -305
  673. package/scripts/archive/setup-git-hooks.sh +0 -25
  674. package/scripts/archive/setup-linear-oauth.sh +0 -46
  675. package/scripts/archive/setup-mcp.sh +0 -113
  676. package/scripts/archive/setup-railway-deployment.sh +0 -81
  677. package/scripts/auto-handoff.sh +0 -262
  678. package/scripts/background-sync-manager.js +0 -478
  679. package/scripts/benchmark-performance.ts +0 -57
  680. package/scripts/check-redis.ts +0 -48
  681. package/scripts/chromadb-auto-loader.sh +0 -128
  682. package/scripts/chromadb-context-loader.js +0 -479
  683. package/scripts/claude-chromadb-hook.js +0 -460
  684. package/scripts/claude-linear-skill.js +0 -455
  685. package/scripts/claude-pre-commit.sh +0 -302
  686. package/scripts/claude-sm-autostart.js +0 -579
  687. package/scripts/claude-with-chromadb.sh +0 -69
  688. package/scripts/clean-linear-backlog.js +0 -273
  689. package/scripts/cleanup-old-sessions.sh +0 -57
  690. package/scripts/create-cleanup-issues.js +0 -302
  691. package/scripts/create-sandbox.sh +0 -269
  692. package/scripts/debug-linear-update.js +0 -174
  693. package/scripts/delete-linear-tasks.js +0 -167
  694. package/scripts/demos/browser-test.ts +0 -39
  695. package/scripts/demos/ralph-integration-demo.ts +0 -245
  696. package/scripts/demos/trace-demo.ts +0 -200
  697. package/scripts/demos/trace-detector.demo.ts +0 -171
  698. package/scripts/demos/trace-test.ts +0 -79
  699. package/scripts/deploy-ralph-swarm.sh +0 -365
  700. package/scripts/deploy.sh +0 -89
  701. package/scripts/deployment/test-deployment.js +0 -194
  702. package/scripts/detect-and-rehydrate.js +0 -162
  703. package/scripts/detect-and-rehydrate.mjs +0 -165
  704. package/scripts/development/create-demo-tasks.js +0 -143
  705. package/scripts/development/debug-frame-test.js +0 -16
  706. package/scripts/development/demo-auto-sync.js +0 -128
  707. package/scripts/development/fix-all-imports.js +0 -213
  708. package/scripts/development/fix-imports.js +0 -229
  709. package/scripts/development/fix-lint-loop.cjs +0 -103
  710. package/scripts/development/fix-project-id.ts +0 -161
  711. package/scripts/development/fix-strict-mode-issues.ts +0 -291
  712. package/scripts/development/reorganize-structure.sh +0 -228
  713. package/scripts/development/test-persistence-direct.js +0 -148
  714. package/scripts/development/test-persistence.js +0 -114
  715. package/scripts/development/test-tasks.js +0 -93
  716. package/scripts/development/update-imports.js +0 -212
  717. package/scripts/fetch-linear-status.js +0 -125
  718. package/scripts/initialize.ts +0 -220
  719. package/scripts/install-notify-hook.sh +0 -84
  720. package/scripts/linear-auto-sync.js +0 -262
  721. package/scripts/linear-auto-sync.sh +0 -161
  722. package/scripts/linear-sync-daemon.js +0 -150
  723. package/scripts/linear-task-review.js +0 -237
  724. package/scripts/list-linear-tasks.ts +0 -178
  725. package/scripts/mcp-proxy.js +0 -66
  726. package/scripts/measure-handoff-impact.mjs +0 -395
  727. package/scripts/measure-handoff-impact.ts +0 -450
  728. package/scripts/publish-local.js +0 -74
  729. package/scripts/query-chromadb.ts +0 -201
  730. package/scripts/ralph-integration-test.js +0 -274
  731. package/scripts/reconcile-local-tasks.js +0 -170
  732. package/scripts/recreate-frames-db.js +0 -89
  733. package/scripts/setup-notify-webhook.sh +0 -103
  734. package/scripts/show-linear-summary.ts +0 -172
  735. package/scripts/simple-swarm-demo.ts +0 -114
  736. package/scripts/stackmemory-auto-handoff.sh +0 -231
  737. package/scripts/start-linear-sync-daemon.sh +0 -141
  738. package/scripts/start-temporal-paradox.sh +0 -214
  739. package/scripts/status.ts +0 -224
  740. package/scripts/stop-notify-webhook.sh +0 -19
  741. package/scripts/swarm-monitor.js +0 -509
  742. package/scripts/sync-and-clean-tasks.js +0 -258
  743. package/scripts/sync-linear-graphql.js +0 -303
  744. package/scripts/sync-linear-tasks.js +0 -186
  745. package/scripts/test-auto-triggers.sh +0 -57
  746. package/scripts/test-browser-mcp.js +0 -74
  747. package/scripts/test-chromadb-full.js +0 -115
  748. package/scripts/test-chromadb-hooks.sh +0 -28
  749. package/scripts/test-chromadb-sync.ts +0 -245
  750. package/scripts/test-claude-config.sh +0 -123
  751. package/scripts/test-cli-security.js +0 -293
  752. package/scripts/test-code-execution.js +0 -143
  753. package/scripts/test-hooks-persistence.sh +0 -220
  754. package/scripts/test-installation-scenarios.sh +0 -359
  755. package/scripts/test-installation.sh +0 -224
  756. package/scripts/test-mcp.js +0 -163
  757. package/scripts/test-parallel-swarms.js +0 -443
  758. package/scripts/test-pre-publish-quick.sh +0 -77
  759. package/scripts/test-quality-gates.sh +0 -263
  760. package/scripts/test-ralph-iteration-fix.ts +0 -118
  761. package/scripts/test-ralph-iterations.ts +0 -164
  762. package/scripts/test-redis-storage.ts +0 -490
  763. package/scripts/test-rlm-basic.sh +0 -122
  764. package/scripts/test-rlm-comprehensive.sh +0 -260
  765. package/scripts/test-rlm-e2e.sh +0 -268
  766. package/scripts/test-rlm-simple.js +0 -90
  767. package/scripts/test-rlm.js +0 -110
  768. package/scripts/test-session-handoff.sh +0 -165
  769. package/scripts/test-setup-e2e.sh +0 -154
  770. package/scripts/test-shell-integration.sh +0 -275
  771. package/scripts/test-simple-ralph-state-sync.ts +0 -178
  772. package/scripts/test-swarm-fixes.ts +0 -161
  773. package/scripts/test-swarm-git-workflow.js +0 -338
  774. package/scripts/test-swarm-tui.ts +0 -34
  775. package/scripts/test-tui-shortcuts.ts +0 -66
  776. package/scripts/testing/ab-test-runner.ts +0 -510
  777. package/scripts/testing/collect-metrics.ts +0 -457
  778. package/scripts/testing/quick-effectiveness-demo.js +0 -187
  779. package/scripts/testing/ralph-cli-test.js +0 -88
  780. package/scripts/testing/ralph-integration-validation.js +0 -727
  781. package/scripts/testing/ralph-swarm-test-scenarios.js +0 -613
  782. package/scripts/testing/real-performance-test.js +0 -422
  783. package/scripts/testing/results/real-performance-results.json +0 -90
  784. package/scripts/testing/run-effectiveness-tests.sh +0 -176
  785. package/scripts/testing/simple-effectiveness-test.js +0 -310
  786. package/scripts/testing/test-tier-migration.js +0 -100
  787. package/scripts/update-linear-status.js +0 -268
  788. package/scripts/update-linear-tasks-fixed.js +0 -284
  789. package/scripts/validate-claude-config.sh +0 -155
  790. package/scripts/validate-swarm-implementation.js +0 -467
  791. package/scripts/validate-tui-shortcuts.ts +0 -83
  792. package/templates/claude-hooks/notify-review-hook.js +0 -360
  793. package/templates/claude-hooks/sms-response-handler.js +0 -174
@@ -1,7 +0,0 @@
1
- {
2
- "version": 3,
3
- "sources": ["../../../../src/core/skills/skill-storage.ts"],
4
- "sourcesContent": ["/**\n * Skill Storage Service\n * Redis-backed persistent storage for agent learnings and skills\n * All skills are namespaced by userId for multi-user support\n */\n\nimport 'dotenv/config';\nimport Redis from 'ioredis';\nimport { v4 as uuidv4 } from 'uuid';\nimport { logger } from '../monitoring/logger.js';\n\n// Type-safe environment variable access\nfunction getEnv(key: string, defaultValue?: string): string {\n const value = process.env[key];\n if (value === undefined) {\n if (defaultValue !== undefined) return defaultValue;\n throw new Error(`Environment variable ${key} is required`);\n }\n return value;\n}\n\nfunction getOptionalEnv(key: string): string | undefined {\n return process.env[key];\n}\n\nimport {\n Skill,\n CreateSkillInput,\n UpdateSkillInput,\n SkillQuery,\n JournalEntry,\n JournalEntryType,\n SessionSummary,\n SkillCategory,\n SkillPriority,\n REDIS_KEYS,\n CACHE_TTL,\n calculateSkillTTL,\n SkillSchema,\n JournalEntrySchema,\n} from './types.js';\n\nexport interface SkillStorageConfig {\n redisUrl: string;\n userId: string; // Required: user namespace for skills\n keyPrefix?: string;\n enableMetrics?: boolean;\n}\n\nexport interface SkillStorageMetrics {\n userId: string;\n skillsTotal: number;\n skillsByCategory: Record<SkillCategory, number>;\n journalEntriesTotal: number;\n sessionsTracked: number;\n cacheHits: number;\n cacheMisses: number;\n}\n\nexport class SkillStorageService {\n private redis: Redis;\n private userId: string;\n private keyPrefix: string;\n private enableMetrics: boolean;\n\n // Metrics tracking\n private metrics = {\n cacheHits: 0,\n cacheMisses: 0,\n };\n\n constructor(config: SkillStorageConfig) {\n this.redis = new Redis(config.redisUrl);\n this.userId = config.userId;\n this.keyPrefix = config.keyPrefix || 'sm:skills';\n this.enableMetrics = config.enableMetrics ?? true;\n\n this.redis.on('error', (err) => {\n logger.error('Redis connection error in SkillStorage', err);\n });\n\n this.redis.on('connect', () => {\n logger.info('SkillStorage connected to Redis');\n });\n\n logger.info('SkillStorageService initialized', {\n userId: this.userId,\n keyPrefix: this.keyPrefix,\n enableMetrics: this.enableMetrics,\n });\n }\n\n private key(pattern: string): string {\n return `${this.keyPrefix}:${pattern}`;\n }\n\n /**\n * Get the current user ID\n */\n getUserId(): string {\n return this.userId;\n }\n\n // ============================================================\n // SKILL CRUD OPERATIONS\n // ============================================================\n\n /**\n * Create a new skill\n */\n async createSkill(input: CreateSkillInput): Promise<Skill> {\n const now = new Date().toISOString();\n const skill: Skill = {\n ...input,\n id: uuidv4(),\n createdAt: now,\n updatedAt: now,\n validatedCount: 0,\n };\n\n // Validate\n SkillSchema.parse(skill);\n\n const pipeline = this.redis.pipeline();\n const skillKey = this.key(REDIS_KEYS.skill(this.userId, skill.id));\n\n // Store skill\n pipeline.setex(\n skillKey,\n calculateSkillTTL(skill.validatedCount),\n JSON.stringify(skill)\n );\n\n // Index by tool\n if (skill.tool) {\n pipeline.zadd(\n this.key(REDIS_KEYS.skillsByTool(this.userId, skill.tool)),\n Date.now(),\n skill.id\n );\n }\n\n // Index by category\n pipeline.zadd(\n this.key(REDIS_KEYS.skillsByCategory(this.userId, skill.category)),\n this.priorityScore(skill.priority),\n skill.id\n );\n\n // Index by tags\n for (const tag of skill.tags) {\n pipeline.zadd(\n this.key(REDIS_KEYS.skillsByTag(this.userId, tag)),\n Date.now(),\n skill.id\n );\n }\n\n // Add to recent skills\n pipeline.zadd(\n this.key(REDIS_KEYS.skillsRecent(this.userId)),\n Date.now(),\n skill.id\n );\n pipeline.zremrangebyrank(\n this.key(REDIS_KEYS.skillsRecent(this.userId)),\n 0,\n -1001\n ); // Keep last 1000\n\n await pipeline.exec();\n\n logger.info('Created skill', {\n userId: this.userId,\n id: skill.id,\n category: skill.category,\n tool: skill.tool,\n });\n\n return skill;\n }\n\n /**\n * Get skill by ID\n */\n async getSkill(id: string): Promise<Skill | null> {\n const skillKey = this.key(REDIS_KEYS.skill(this.userId, id));\n const data = await this.redis.get(skillKey);\n\n if (!data) {\n this.metrics.cacheMisses++;\n return null;\n }\n\n this.metrics.cacheHits++;\n return JSON.parse(data) as Skill;\n }\n\n /**\n * Update an existing skill\n */\n async updateSkill(input: UpdateSkillInput): Promise<Skill | null> {\n const existing = await this.getSkill(input.id);\n if (!existing) {\n return null;\n }\n\n const updated: Skill = {\n ...existing,\n ...input,\n updatedAt: new Date().toISOString(),\n };\n\n // Validate\n SkillSchema.parse(updated);\n\n const skillKey = this.key(REDIS_KEYS.skill(this.userId, updated.id));\n await this.redis.setex(\n skillKey,\n calculateSkillTTL(updated.validatedCount),\n JSON.stringify(updated)\n );\n\n logger.info('Updated skill', { userId: this.userId, id: updated.id });\n\n return updated;\n }\n\n /**\n * Validate a skill (increment validation count)\n */\n async validateSkill(id: string): Promise<Skill | null> {\n const skill = await this.getSkill(id);\n if (!skill) {\n return null;\n }\n\n skill.validatedCount++;\n skill.lastValidated = new Date().toISOString();\n skill.updatedAt = new Date().toISOString();\n\n const skillKey = this.key(REDIS_KEYS.skill(this.userId, id));\n // TTL increases with validation count: 7 days base + 7 days per validation, max 90 days\n await this.redis.setex(\n skillKey,\n calculateSkillTTL(skill.validatedCount),\n JSON.stringify(skill)\n );\n\n // Update validated index\n await this.redis.zadd(\n this.key(REDIS_KEYS.skillsValidated(this.userId)),\n skill.validatedCount,\n id\n );\n\n // Check for promotion eligibility\n if (skill.validatedCount >= 3 && skill.priority !== 'critical') {\n await this.redis.sadd(\n this.key(REDIS_KEYS.promotionCandidates(this.userId)),\n id\n );\n }\n\n logger.info('Validated skill', {\n userId: this.userId,\n id,\n validatedCount: skill.validatedCount,\n });\n\n return skill;\n }\n\n /**\n * Delete a skill\n */\n async deleteSkill(id: string): Promise<boolean> {\n const skill = await this.getSkill(id);\n if (!skill) {\n return false;\n }\n\n const pipeline = this.redis.pipeline();\n const skillKey = this.key(REDIS_KEYS.skill(this.userId, id));\n\n // Remove skill\n pipeline.del(skillKey);\n\n // Remove from indexes\n if (skill.tool) {\n pipeline.zrem(\n this.key(REDIS_KEYS.skillsByTool(this.userId, skill.tool)),\n id\n );\n }\n\n pipeline.zrem(\n this.key(REDIS_KEYS.skillsByCategory(this.userId, skill.category)),\n id\n );\n\n for (const tag of skill.tags) {\n pipeline.zrem(this.key(REDIS_KEYS.skillsByTag(this.userId, tag)), id);\n }\n\n pipeline.zrem(this.key(REDIS_KEYS.skillsRecent(this.userId)), id);\n pipeline.zrem(this.key(REDIS_KEYS.skillsValidated(this.userId)), id);\n pipeline.srem(this.key(REDIS_KEYS.promotionCandidates(this.userId)), id);\n\n await pipeline.exec();\n\n logger.info('Deleted skill', { userId: this.userId, id });\n\n return true;\n }\n\n // ============================================================\n // SKILL QUERIES\n // ============================================================\n\n /**\n * Query skills with filters\n */\n async querySkills(query: SkillQuery): Promise<Skill[]> {\n let skillIds: string[] = [];\n\n // Determine which index to use\n if (query.tool) {\n skillIds = await this.redis.zrevrange(\n this.key(REDIS_KEYS.skillsByTool(this.userId, query.tool)),\n 0,\n -1\n );\n } else if (query.categories && query.categories.length === 1) {\n skillIds = await this.redis.zrevrange(\n this.key(REDIS_KEYS.skillsByCategory(this.userId, query.categories[0])),\n 0,\n -1\n );\n } else if (query.tags && query.tags.length === 1) {\n skillIds = await this.redis.zrevrange(\n this.key(REDIS_KEYS.skillsByTag(this.userId, query.tags[0])),\n 0,\n -1\n );\n } else {\n // Default to recent skills\n skillIds = await this.redis.zrevrange(\n this.key(REDIS_KEYS.skillsRecent(this.userId)),\n 0,\n query.limit + query.offset\n );\n }\n\n if (skillIds.length === 0) {\n return [];\n }\n\n // Fetch skills\n const pipeline = this.redis.pipeline();\n for (const id of skillIds) {\n pipeline.get(this.key(REDIS_KEYS.skill(this.userId, id)));\n }\n\n const results = await pipeline.exec();\n if (!results) {\n return [];\n }\n\n let skills: Skill[] = results\n .map(([err, data]) => {\n if (err || !data) return null;\n try {\n return JSON.parse(data as string) as Skill;\n } catch {\n return null;\n }\n })\n .filter((s): s is Skill => s !== null);\n\n // Apply additional filters\n if (query.categories && query.categories.length > 0) {\n skills = skills.filter((s) => query.categories!.includes(s.category));\n }\n\n if (query.priorities && query.priorities.length > 0) {\n skills = skills.filter((s) => query.priorities!.includes(s.priority));\n }\n\n if (query.minValidatedCount !== undefined) {\n skills = skills.filter(\n (s) => s.validatedCount >= query.minValidatedCount!\n );\n }\n\n if (query.language) {\n skills = skills.filter((s) => s.language === query.language);\n }\n\n if (query.framework) {\n skills = skills.filter((s) => s.framework === query.framework);\n }\n\n // Sort\n skills.sort((a, b) => {\n let aVal: number, bVal: number;\n\n switch (query.sortBy) {\n case 'priority':\n aVal = this.priorityScore(a.priority);\n bVal = this.priorityScore(b.priority);\n break;\n case 'validatedCount':\n aVal = a.validatedCount;\n bVal = b.validatedCount;\n break;\n case 'createdAt':\n aVal = new Date(a.createdAt).getTime();\n bVal = new Date(b.createdAt).getTime();\n break;\n case 'updatedAt':\n aVal = new Date(a.updatedAt).getTime();\n bVal = new Date(b.updatedAt).getTime();\n break;\n default:\n aVal = this.priorityScore(a.priority);\n bVal = this.priorityScore(b.priority);\n }\n\n return query.sortOrder === 'desc' ? bVal - aVal : aVal - bVal;\n });\n\n // Apply pagination\n return skills.slice(query.offset, query.offset + query.limit);\n }\n\n /**\n * Get skills relevant to current context\n */\n async getRelevantSkills(context: {\n tool?: string;\n language?: string;\n framework?: string;\n tags?: string[];\n }): Promise<Skill[]> {\n const skills: Skill[] = [];\n const seenIds = new Set<string>();\n\n // Always include critical skills\n const criticalIds = await this.redis.zrevrange(\n this.key(REDIS_KEYS.skillsByCategory(this.userId, 'correction')),\n 0,\n -1\n );\n\n for (const id of criticalIds) {\n const skill = await this.getSkill(id);\n if (skill && skill.priority === 'critical' && !seenIds.has(id)) {\n skills.push(skill);\n seenIds.add(id);\n }\n }\n\n // Get tool-specific skills\n if (context.tool) {\n const toolSkills = await this.querySkills({\n tool: context.tool,\n limit: 20,\n offset: 0,\n sortBy: 'priority',\n sortOrder: 'desc',\n });\n\n for (const skill of toolSkills) {\n if (!seenIds.has(skill.id)) {\n skills.push(skill);\n seenIds.add(skill.id);\n }\n }\n }\n\n // Get highly validated skills\n const validatedIds = await this.redis.zrevrange(\n this.key(REDIS_KEYS.skillsValidated(this.userId)),\n 0,\n 10\n );\n\n for (const id of validatedIds) {\n if (!seenIds.has(id)) {\n const skill = await this.getSkill(id);\n if (skill) {\n skills.push(skill);\n seenIds.add(id);\n }\n }\n }\n\n return skills.slice(0, 50); // Cap at 50 skills\n }\n\n // ============================================================\n // SESSION JOURNAL\n // ============================================================\n\n /**\n * Create a journal entry\n */\n async createJournalEntry(\n sessionId: string,\n type: JournalEntryType,\n title: string,\n content: string,\n context?: JournalEntry['context']\n ): Promise<JournalEntry> {\n const entry: JournalEntry = {\n id: uuidv4(),\n sessionId,\n type,\n title,\n content,\n context,\n createdAt: new Date().toISOString(),\n };\n\n // Validate\n JournalEntrySchema.parse(entry);\n\n const pipeline = this.redis.pipeline();\n\n // Store entry\n pipeline.setex(\n this.key(REDIS_KEYS.journalEntry(this.userId, entry.id)),\n CACHE_TTL.journal,\n JSON.stringify(entry)\n );\n\n // Index by session\n pipeline.zadd(\n this.key(REDIS_KEYS.journalSession(this.userId, sessionId)),\n Date.now(),\n entry.id\n );\n\n // Add to recent journal\n pipeline.zadd(\n this.key(REDIS_KEYS.journalRecent(this.userId)),\n Date.now(),\n entry.id\n );\n pipeline.zremrangebyrank(\n this.key(REDIS_KEYS.journalRecent(this.userId)),\n 0,\n -501\n ); // Keep last 500\n\n await pipeline.exec();\n\n logger.info('Created journal entry', {\n userId: this.userId,\n id: entry.id,\n sessionId,\n type,\n title,\n });\n\n return entry;\n }\n\n /**\n * Get journal entries for a session\n */\n async getSessionJournal(sessionId: string): Promise<JournalEntry[]> {\n const entryIds = await this.redis.zrevrange(\n this.key(REDIS_KEYS.journalSession(this.userId, sessionId)),\n 0,\n -1\n );\n\n if (entryIds.length === 0) {\n return [];\n }\n\n const pipeline = this.redis.pipeline();\n for (const id of entryIds) {\n pipeline.get(this.key(REDIS_KEYS.journalEntry(this.userId, id)));\n }\n\n const results = await pipeline.exec();\n if (!results) {\n return [];\n }\n\n return results\n .map(([err, data]) => {\n if (err || !data) return null;\n try {\n return JSON.parse(data as string) as JournalEntry;\n } catch {\n return null;\n }\n })\n .filter((e): e is JournalEntry => e !== null);\n }\n\n /**\n * Promote a journal entry to a skill\n */\n async promoteToSkill(\n entryId: string,\n category: SkillCategory,\n priority: SkillPriority = 'medium'\n ): Promise<Skill | null> {\n const entryData = await this.redis.get(\n this.key(REDIS_KEYS.journalEntry(this.userId, entryId))\n );\n\n if (!entryData) {\n return null;\n }\n\n const entry = JSON.parse(entryData) as JournalEntry;\n\n const skill = await this.createSkill({\n content: entry.content,\n summary: entry.title,\n category,\n priority,\n tags: [],\n tool: entry.context?.tool,\n source: 'observation',\n sessionId: entry.sessionId,\n });\n\n // Update entry with promotion reference\n entry.promotedToSkillId = skill.id;\n await this.redis.setex(\n this.key(REDIS_KEYS.journalEntry(this.userId, entryId)),\n CACHE_TTL.journal,\n JSON.stringify(entry)\n );\n\n logger.info('Promoted journal entry to skill', {\n userId: this.userId,\n entryId,\n skillId: skill.id,\n });\n\n return skill;\n }\n\n // ============================================================\n // SESSION MANAGEMENT\n // ============================================================\n\n /**\n * Start tracking a new session\n */\n async startSession(sessionId: string): Promise<void> {\n const summary: SessionSummary = {\n sessionId,\n startedAt: new Date().toISOString(),\n entriesCount: 0,\n correctionsCount: 0,\n decisionsCount: 0,\n keyLearnings: [],\n promotedSkillIds: [],\n };\n\n await this.redis.setex(\n this.key(REDIS_KEYS.sessionSummary(this.userId, sessionId)),\n CACHE_TTL.session,\n JSON.stringify(summary)\n );\n\n await this.redis.sadd(\n this.key(REDIS_KEYS.sessionsActive(this.userId)),\n sessionId\n );\n\n logger.info('Started session tracking', { userId: this.userId, sessionId });\n }\n\n /**\n * End a session and generate summary\n */\n async endSession(sessionId: string): Promise<SessionSummary | null> {\n const summaryData = await this.redis.get(\n this.key(REDIS_KEYS.sessionSummary(this.userId, sessionId))\n );\n\n if (!summaryData) {\n return null;\n }\n\n const summary = JSON.parse(summaryData) as SessionSummary;\n summary.endedAt = new Date().toISOString();\n\n // Count entries by type\n const entries = await this.getSessionJournal(sessionId);\n summary.entriesCount = entries.length;\n summary.correctionsCount = entries.filter(\n (e) => e.type === 'correction'\n ).length;\n summary.decisionsCount = entries.filter(\n (e) => e.type === 'decision'\n ).length;\n\n // Extract key learnings\n summary.keyLearnings = entries\n .filter((e) => e.type === 'correction' || e.type === 'resolution')\n .slice(0, 5)\n .map((e) => e.title);\n\n // Get promoted skills\n summary.promotedSkillIds = entries\n .filter((e) => e.promotedToSkillId)\n .map((e) => e.promotedToSkillId!);\n\n await this.redis.setex(\n this.key(REDIS_KEYS.sessionSummary(this.userId, sessionId)),\n CACHE_TTL.session,\n JSON.stringify(summary)\n );\n\n await this.redis.srem(\n this.key(REDIS_KEYS.sessionsActive(this.userId)),\n sessionId\n );\n\n logger.info('Ended session', {\n userId: this.userId,\n sessionId,\n entriesCount: summary.entriesCount,\n keyLearnings: summary.keyLearnings.length,\n });\n\n return summary;\n }\n\n /**\n * Get session summary\n */\n async getSessionSummary(sessionId: string): Promise<SessionSummary | null> {\n const data = await this.redis.get(\n this.key(REDIS_KEYS.sessionSummary(this.userId, sessionId))\n );\n\n if (!data) {\n return null;\n }\n\n return JSON.parse(data) as SessionSummary;\n }\n\n // ============================================================\n // KNOWLEDGE HYGIENE\n // ============================================================\n\n /**\n * Get skills eligible for promotion\n */\n async getPromotionCandidates(): Promise<Skill[]> {\n const ids = await this.redis.smembers(\n this.key(REDIS_KEYS.promotionCandidates(this.userId))\n );\n\n const skills: Skill[] = [];\n for (const id of ids) {\n const skill = await this.getSkill(id);\n if (skill && skill.validatedCount >= 3) {\n skills.push(skill);\n }\n }\n\n return skills;\n }\n\n /**\n * Promote a skill (increase priority)\n */\n async promoteSkill(id: string): Promise<Skill | null> {\n const skill = await this.getSkill(id);\n if (!skill) {\n return null;\n }\n\n const priorityOrder: SkillPriority[] = [\n 'low',\n 'medium',\n 'high',\n 'critical',\n ];\n const currentIndex = priorityOrder.indexOf(skill.priority);\n\n if (currentIndex < priorityOrder.length - 1) {\n skill.priority = priorityOrder[currentIndex + 1];\n skill.updatedAt = new Date().toISOString();\n\n await this.redis.setex(\n this.key(REDIS_KEYS.skill(this.userId, id)),\n calculateSkillTTL(skill.validatedCount),\n JSON.stringify(skill)\n );\n\n // Update category index with new score\n await this.redis.zadd(\n this.key(REDIS_KEYS.skillsByCategory(this.userId, skill.category)),\n this.priorityScore(skill.priority),\n id\n );\n\n // Remove from promotion candidates if now critical\n if (skill.priority === 'critical') {\n await this.redis.srem(\n this.key(REDIS_KEYS.promotionCandidates(this.userId)),\n id\n );\n }\n\n logger.info('Promoted skill', {\n userId: this.userId,\n id,\n newPriority: skill.priority,\n });\n }\n\n return skill;\n }\n\n /**\n * Archive stale skills (not validated in 90 days)\n */\n async archiveStaleSkills(daysThreshold: number = 90): Promise<number> {\n const cutoff = Date.now() - daysThreshold * 24 * 60 * 60 * 1000;\n let archivedCount = 0;\n\n // Get all recent skills\n const skillIds = await this.redis.zrangebyscore(\n this.key(REDIS_KEYS.skillsRecent(this.userId)),\n 0,\n cutoff\n );\n\n for (const id of skillIds) {\n const skill = await this.getSkill(id);\n if (skill && skill.priority !== 'critical') {\n // Check if it was validated recently\n if (\n !skill.lastValidated ||\n new Date(skill.lastValidated).getTime() < cutoff\n ) {\n // Downgrade to low priority instead of deleting\n if (skill.priority !== 'low') {\n skill.priority = 'low';\n skill.updatedAt = new Date().toISOString();\n await this.redis.setex(\n this.key(REDIS_KEYS.skill(this.userId, id)),\n calculateSkillTTL(skill.validatedCount),\n JSON.stringify(skill)\n );\n archivedCount++;\n }\n }\n }\n }\n\n logger.info('Archived stale skills', {\n userId: this.userId,\n archivedCount,\n daysThreshold,\n });\n\n return archivedCount;\n }\n\n // ============================================================\n // METRICS & UTILITIES\n // ============================================================\n\n /**\n * Get storage metrics\n */\n async getMetrics(): Promise<SkillStorageMetrics> {\n const [\n skillsTotal,\n toolSkills,\n workflowSkills,\n correctionSkills,\n patternSkills,\n preferenceSkills,\n pitfallSkills,\n optimizationSkills,\n journalTotal,\n sessionsActive,\n ] = await Promise.all([\n this.redis.zcard(this.key(REDIS_KEYS.skillsRecent(this.userId))),\n this.redis.zcard(\n this.key(REDIS_KEYS.skillsByCategory(this.userId, 'tool'))\n ),\n this.redis.zcard(\n this.key(REDIS_KEYS.skillsByCategory(this.userId, 'workflow'))\n ),\n this.redis.zcard(\n this.key(REDIS_KEYS.skillsByCategory(this.userId, 'correction'))\n ),\n this.redis.zcard(\n this.key(REDIS_KEYS.skillsByCategory(this.userId, 'pattern'))\n ),\n this.redis.zcard(\n this.key(REDIS_KEYS.skillsByCategory(this.userId, 'preference'))\n ),\n this.redis.zcard(\n this.key(REDIS_KEYS.skillsByCategory(this.userId, 'pitfall'))\n ),\n this.redis.zcard(\n this.key(REDIS_KEYS.skillsByCategory(this.userId, 'optimization'))\n ),\n this.redis.zcard(this.key(REDIS_KEYS.journalRecent(this.userId))),\n this.redis.scard(this.key(REDIS_KEYS.sessionsActive(this.userId))),\n ]);\n\n return {\n userId: this.userId,\n skillsTotal,\n skillsByCategory: {\n tool: toolSkills,\n workflow: workflowSkills,\n correction: correctionSkills,\n pattern: patternSkills,\n preference: preferenceSkills,\n pitfall: pitfallSkills,\n optimization: optimizationSkills,\n },\n journalEntriesTotal: journalTotal,\n sessionsTracked: sessionsActive,\n cacheHits: this.metrics.cacheHits,\n cacheMisses: this.metrics.cacheMisses,\n };\n }\n\n /**\n * Priority to numeric score for sorting\n */\n private priorityScore(priority: SkillPriority): number {\n const scores: Record<SkillPriority, number> = {\n critical: 1000,\n high: 100,\n medium: 10,\n low: 1,\n };\n return scores[priority];\n }\n\n /**\n * Close Redis connection\n */\n async close(): Promise<void> {\n await this.redis.quit();\n logger.info('SkillStorageService closed');\n }\n}\n\n// ============================================================\n// SINGLETON INSTANCES (per user)\n// ============================================================\n\nconst userStorageInstances = new Map<string, SkillStorageService>();\n\n/**\n * Get or create skill storage instance for a user\n */\nexport function getSkillStorage(\n config: SkillStorageConfig\n): SkillStorageService {\n const existing = userStorageInstances.get(config.userId);\n if (existing) {\n return existing;\n }\n\n const instance = new SkillStorageService(config);\n userStorageInstances.set(config.userId, instance);\n return instance;\n}\n\n/**\n * Initialize skill storage with Redis URL from environment\n */\nexport function initializeSkillStorage(\n userId: string,\n redisUrl?: string\n): SkillStorageService {\n const url = redisUrl || process.env['REDIS_URL'];\n\n if (!url) {\n throw new Error('REDIS_URL environment variable not set');\n }\n\n return getSkillStorage({ redisUrl: url, userId });\n}\n\n/**\n * Get default user ID from environment or generate one\n */\nexport function getDefaultUserId(): string {\n return (\n process.env['STACKMEMORY_USER_ID'] ||\n process.env['USER'] ||\n process.env['USERNAME'] ||\n 'default'\n );\n}\n"],
5
- "mappings": "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",
6
- "names": []
7
- }
@@ -1,7 +0,0 @@
1
- {
2
- "version": 3,
3
- "sources": ["../../../../src/core/skills/types.ts"],
4
- "sourcesContent": ["/**\n * Skill Storage Types\n * Types for persistent agent learning and skill memory\n */\n\nimport { z } from 'zod';\n\n// ============================================================\n// SKILL SCHEMAS\n// ============================================================\n\n/**\n * Skill category for organization\n */\nexport const SkillCategorySchema = z.enum([\n 'tool', // Tool-specific patterns\n 'workflow', // Process/workflow improvements\n 'correction', // User corrections to remember\n 'pattern', // Code/architecture patterns\n 'preference', // User preferences\n 'pitfall', // Things to avoid\n 'optimization', // Performance/efficiency tips\n]);\n\nexport type SkillCategory = z.infer<typeof SkillCategorySchema>;\n\n/**\n * Skill priority for retrieval ordering\n */\nexport const SkillPrioritySchema = z.enum([\n 'critical', // Always include in context\n 'high', // Include when relevant\n 'medium', // Include if space permits\n 'low', // Archive/reference only\n]);\n\nexport type SkillPriority = z.infer<typeof SkillPrioritySchema>;\n\n/**\n * Individual skill/learning entry\n */\nexport const SkillSchema = z.object({\n id: z.string().uuid(),\n\n // Content\n content: z.string().min(1).max(5000),\n summary: z.string().max(500).optional(),\n\n // Classification\n category: SkillCategorySchema,\n priority: SkillPrioritySchema.default('medium'),\n tags: z.array(z.string()).default([]),\n\n // Context\n tool: z.string().optional(), // Related tool name\n project: z.string().optional(), // Project context\n language: z.string().optional(), // Programming language\n framework: z.string().optional(), // Framework context\n\n // Validation tracking\n validatedCount: z.number().int().min(0).default(0),\n lastValidated: z.string().datetime().optional(),\n\n // Lifecycle\n createdAt: z.string().datetime(),\n updatedAt: z.string().datetime(),\n expiresAt: z.string().datetime().optional(),\n\n // Source tracking\n source: z.enum(['correction', 'observation', 'explicit', 'inferred']),\n sessionId: z.string().optional(),\n});\n\nexport type Skill = z.infer<typeof SkillSchema>;\n\n/**\n * Skill creation input\n */\nexport const CreateSkillSchema = SkillSchema.omit({\n id: true,\n createdAt: true,\n updatedAt: true,\n validatedCount: true,\n});\n\nexport type CreateSkillInput = z.infer<typeof CreateSkillSchema>;\n\n/**\n * Skill update input\n */\nexport const UpdateSkillSchema = SkillSchema.partial().extend({\n id: z.string().uuid(),\n});\n\nexport type UpdateSkillInput = z.infer<typeof UpdateSkillSchema>;\n\n// ============================================================\n// SESSION JOURNAL SCHEMAS\n// ============================================================\n\n/**\n * Session journal entry type\n */\nexport const JournalEntryTypeSchema = z.enum([\n 'decision', // Architectural/design decision\n 'correction', // User corrected agent behavior\n 'blocker', // Issue encountered\n 'resolution', // How an issue was resolved\n 'observation', // Noticed pattern or behavior\n 'outcome', // Result of an action\n]);\n\nexport type JournalEntryType = z.infer<typeof JournalEntryTypeSchema>;\n\n/**\n * Session journal entry\n */\nexport const JournalEntrySchema = z.object({\n id: z.string().uuid(),\n sessionId: z.string(),\n type: JournalEntryTypeSchema,\n\n // Content\n title: z.string().max(200),\n content: z.string().max(5000),\n\n // Context\n context: z\n .object({\n file: z.string().optional(),\n tool: z.string().optional(),\n command: z.string().optional(),\n })\n .optional(),\n\n // Outcome tracking\n outcome: z.enum(['success', 'failure', 'partial', 'pending']).optional(),\n\n // Timestamps\n createdAt: z.string().datetime(),\n\n // Link to promoted skill\n promotedToSkillId: z.string().uuid().optional(),\n});\n\nexport type JournalEntry = z.infer<typeof JournalEntrySchema>;\n\n/**\n * Session summary\n */\nexport const SessionSummarySchema = z.object({\n sessionId: z.string(),\n startedAt: z.string().datetime(),\n endedAt: z.string().datetime().optional(),\n\n // Stats\n entriesCount: z.number().int().min(0),\n correctionsCount: z.number().int().min(0),\n decisionsCount: z.number().int().min(0),\n\n // Key learnings from this session\n keyLearnings: z.array(z.string()).default([]),\n\n // Skills promoted from this session\n promotedSkillIds: z.array(z.string().uuid()).default([]),\n});\n\nexport type SessionSummary = z.infer<typeof SessionSummarySchema>;\n\n// ============================================================\n// QUERY SCHEMAS\n// ============================================================\n\n/**\n * Skill query filters\n */\nexport const SkillQuerySchema = z.object({\n // Filter by classification\n categories: z.array(SkillCategorySchema).optional(),\n priorities: z.array(SkillPrioritySchema).optional(),\n tags: z.array(z.string()).optional(),\n\n // Filter by context\n tool: z.string().optional(),\n project: z.string().optional(),\n language: z.string().optional(),\n framework: z.string().optional(),\n\n // Filter by validation\n minValidatedCount: z.number().int().min(0).optional(),\n\n // Pagination\n limit: z.number().int().min(1).max(100).default(50),\n offset: z.number().int().min(0).default(0),\n\n // Sorting\n sortBy: z\n .enum(['priority', 'validatedCount', 'createdAt', 'updatedAt'])\n .default('priority'),\n sortOrder: z.enum(['asc', 'desc']).default('desc'),\n});\n\nexport type SkillQuery = z.infer<typeof SkillQuerySchema>;\n\n// ============================================================\n// REDIS KEY PATTERNS\n// ============================================================\n\n/**\n * Redis key generators - all keys are namespaced by userId\n * Use 'global' as userId for shared/team skills\n */\nexport const REDIS_KEYS = {\n // Skills (namespaced by user)\n skill: (userId: string, id: string) => `user:${userId}:skill:${id}`,\n skillsByTool: (userId: string, tool: string) =>\n `user:${userId}:skills:tool:${tool}`,\n skillsByCategory: (userId: string, category: SkillCategory) =>\n `user:${userId}:skills:category:${category}`,\n skillsByTag: (userId: string, tag: string) =>\n `user:${userId}:skills:tag:${tag}`,\n skillsRecent: (userId: string) => `user:${userId}:skills:recent`,\n skillsValidated: (userId: string) => `user:${userId}:skills:validated`,\n\n // Session journal (namespaced by user)\n journalEntry: (userId: string, id: string) =>\n `user:${userId}:journal:entry:${id}`,\n journalSession: (userId: string, sessionId: string) =>\n `user:${userId}:journal:session:${sessionId}`,\n journalRecent: (userId: string) => `user:${userId}:journal:recent`,\n\n // Session tracking (namespaced by user)\n sessionSummary: (userId: string, sessionId: string) =>\n `user:${userId}:session:summary:${sessionId}`,\n sessionsActive: (userId: string) => `user:${userId}:sessions:active`,\n\n // Promotion tracking (namespaced by user)\n promotionCandidates: (userId: string) =>\n `user:${userId}:skills:promotion:candidates`,\n\n // Locks (global)\n syncLock: (resource: string) => `lock:skill:${resource}`,\n} as const;\n\n// ============================================================\n// CACHE TTL CONSTANTS (in seconds)\n// ============================================================\n\nexport const CACHE_TTL = {\n // Base skill TTL: 7 days minimum\n skillBase: 604800, // 7 days\n // Max skill TTL: 90 days for frequently used skills\n skillMax: 7776000, // 90 days\n // TTL increment per validation/use: +7 days\n skillIncrement: 604800, // 7 days\n\n skillIndex: 86400, // 1 day (was 1 hour)\n session: 604800, // 7 days\n journal: 2592000, // 30 days\n lock: 30, // 30 seconds\n} as const;\n\n/**\n * Calculate TTL for a skill based on usage\n * Base: 7 days, +7 days per validation, max 90 days\n */\nexport function calculateSkillTTL(validatedCount: number): number {\n const ttl = CACHE_TTL.skillBase + validatedCount * CACHE_TTL.skillIncrement;\n return Math.min(ttl, CACHE_TTL.skillMax);\n}\n"],
5
- "mappings": "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",
6
- "names": []
7
- }
@@ -1,7 +0,0 @@
1
- {
2
- "version": 3,
3
- "sources": ["../../../../src/core/storage/chromadb-adapter.ts"],
4
- "sourcesContent": ["/**\n * ChromaDB Storage Adapter for StackMemory\n *\n * Provides vector storage and semantic search capabilities for context data\n * using ChromaDB cloud service with user and team segmentation.\n *\n * NOTE: chromadb is an optional dependency. This adapter gracefully handles\n * the case when chromadb is not installed.\n */\n\nimport { v4 as uuidv4 } from 'uuid';\n\n// Dynamic import types for optional chromadb dependency\ntype CloudClient = import('chromadb').CloudClient;\ntype Collection = import('chromadb').Collection;\nimport { Frame } from '../context/index.js';\nimport { Logger } from '../monitoring/logger.js';\n\ninterface ChromaDocument {\n id: string;\n document: string;\n metadata: {\n user_id: string;\n team_id?: string;\n frame_id: string;\n session_id: string;\n project_name: string;\n timestamp: number;\n type: 'frame' | 'decision' | 'observation' | 'context';\n score?: number;\n tags?: string[];\n };\n}\n\ninterface ChromaConfig {\n apiKey: string;\n tenant: string;\n database: string;\n collectionName?: string;\n}\n\n// Check if chromadb is available\nlet chromadbModule: typeof import('chromadb') | null = null;\n\nasync function getChromaDB(): Promise<typeof import('chromadb')> {\n if (!chromadbModule) {\n try {\n chromadbModule = await import('chromadb');\n } catch {\n throw new Error(\n 'chromadb is not installed. Install it with: npm install chromadb'\n );\n }\n }\n return chromadbModule;\n}\n\nexport class ChromaDBAdapter {\n private client: CloudClient | null = null;\n private collection: Collection | null = null;\n private logger: Logger;\n private config: ChromaConfig;\n private userId: string;\n private teamId?: string;\n\n constructor(config: ChromaConfig, userId: string, teamId?: string) {\n this.config = config;\n this.userId = userId;\n this.teamId = teamId;\n this.logger = new Logger('ChromaDBAdapter');\n }\n\n /**\n * Factory method to create and initialize the adapter\n */\n static async create(\n config: ChromaConfig,\n userId: string,\n teamId?: string\n ): Promise<ChromaDBAdapter> {\n const adapter = new ChromaDBAdapter(config, userId, teamId);\n await adapter.initClient();\n return adapter;\n }\n\n private async initClient(): Promise<void> {\n const chromadb = await getChromaDB();\n this.client = new chromadb.CloudClient({\n apiKey: this.config.apiKey,\n tenant: this.config.tenant,\n database: this.config.database,\n });\n }\n\n async initialize(): Promise<void> {\n try {\n if (!this.client) {\n await this.initClient();\n }\n\n const collectionName =\n this.config.collectionName || 'stackmemory_contexts';\n\n // Get or create collection with metadata for filtering\n this.collection = await this.client!.getOrCreateCollection({\n name: collectionName,\n metadata: {\n description: 'StackMemory context storage',\n version: '1.0.0',\n created_at: new Date().toISOString(),\n },\n });\n\n this.logger.info(`ChromaDB collection '${collectionName}' initialized`);\n } catch (error: unknown) {\n this.logger.error('Failed to initialize ChromaDB collection', error);\n throw error;\n }\n }\n\n /**\n * Store a frame in ChromaDB\n */\n async storeFrame(frame: Frame): Promise<void> {\n if (!this.collection) {\n throw new Error('ChromaDB not initialized');\n }\n\n try {\n // Prepare document from frame\n const frameMetadata: any = {\n user_id: this.userId,\n frame_id: frame.frameId,\n session_id: frame.sessionId || 'unknown',\n project_name: frame.projectName || 'default',\n timestamp: frame.timestamp,\n type: 'frame',\n score: frame.score,\n tags: frame.tags || [],\n };\n\n // Only add team_id if it exists\n if (this.teamId) {\n frameMetadata.team_id = this.teamId;\n }\n\n const document: ChromaDocument = {\n id: `frame_${frame.frameId}_${this.userId}`,\n document: this.frameToDocument(frame),\n metadata: frameMetadata,\n };\n\n // Add to ChromaDB\n await this.collection.add({\n ids: [document.id],\n documents: [document.document],\n metadatas: [document.metadata],\n });\n\n this.logger.debug(\n `Stored frame ${frame.frameId} for user ${this.userId}`\n );\n } catch (error: unknown) {\n this.logger.error(`Failed to store frame ${frame.frameId}`, error);\n throw error;\n }\n }\n\n /**\n * Store a decision or observation\n */\n async storeContext(\n type: 'decision' | 'observation',\n content: string,\n metadata?: Record<string, any>\n ): Promise<void> {\n if (!this.collection) {\n throw new Error('ChromaDB not initialized');\n }\n\n try {\n const contextId = `${type}_${uuidv4()}_${this.userId}`;\n\n const documentMetadata: any = {\n user_id: this.userId,\n frame_id: metadata?.frame_id || 'none',\n session_id: metadata?.session_id || 'unknown',\n project_name: metadata?.project_name || 'default',\n timestamp: Date.now(),\n type,\n ...metadata,\n };\n\n // Only add team_id if it exists (ChromaDB doesn't accept undefined values)\n if (this.teamId) {\n documentMetadata.team_id = this.teamId;\n }\n\n const document: ChromaDocument = {\n id: contextId,\n document: content,\n metadata: documentMetadata,\n };\n\n await this.collection.add({\n ids: [document.id],\n documents: [document.document],\n metadatas: [document.metadata],\n });\n\n this.logger.debug(`Stored ${type} for user ${this.userId}`);\n } catch (error: unknown) {\n this.logger.error(`Failed to store ${type}`, error);\n throw error;\n }\n }\n\n /**\n * Query contexts by semantic similarity\n */\n async queryContexts(\n query: string,\n limit: number = 10,\n filters?: {\n type?: string[];\n projectName?: string;\n sessionId?: string;\n startTime?: number;\n endTime?: number;\n }\n ): Promise<Array<{ content: string; metadata: any; distance: number }>> {\n if (!this.collection) {\n throw new Error('ChromaDB not initialized');\n }\n\n try {\n // Build where clause for filtering\n const whereClause: any = {\n user_id: this.userId,\n };\n\n // Add team filter if applicable\n if (this.teamId) {\n whereClause['$or'] = [\n { team_id: this.teamId },\n { user_id: this.userId },\n ];\n }\n\n // Add additional filters\n if (filters?.type && filters.type.length > 0) {\n whereClause.type = { $in: filters.type };\n }\n\n if (filters?.projectName) {\n whereClause.project_name = filters.projectName;\n }\n\n if (filters?.sessionId) {\n whereClause.session_id = filters.sessionId;\n }\n\n if (filters?.startTime || filters?.endTime) {\n whereClause.timestamp = {};\n if (filters.startTime) {\n whereClause.timestamp.$gte = filters.startTime;\n }\n if (filters.endTime) {\n whereClause.timestamp.$lte = filters.endTime;\n }\n }\n\n // Query ChromaDB\n const results = await this.collection.query({\n queryTexts: [query],\n nResults: limit,\n where: whereClause,\n include: ['documents', 'metadatas', 'distances'],\n });\n\n // Format results\n const contexts: Array<{\n content: string;\n metadata: any;\n distance: number;\n }> = [];\n\n if (results.documents && results.documents[0]) {\n for (let i = 0; i < results.documents[0].length; i++) {\n contexts.push({\n content: results.documents[0][i] || '',\n metadata: results.metadatas?.[0]?.[i] || {},\n distance: results.distances?.[0]?.[i] || 0,\n });\n }\n }\n\n this.logger.debug(`Found ${contexts.length} contexts for query`);\n return contexts;\n } catch (error: unknown) {\n this.logger.error('Failed to query contexts', error);\n throw error;\n }\n }\n\n /**\n * Get user's recent contexts\n */\n async getRecentContexts(\n limit: number = 20,\n type?: string\n ): Promise<Array<{ content: string; metadata: any }>> {\n if (!this.collection) {\n throw new Error('ChromaDB not initialized');\n }\n\n try {\n const whereClause: any = {\n user_id: this.userId,\n };\n\n if (type) {\n whereClause.type = type;\n }\n\n // Get all documents for the user (ChromaDB doesn't support direct ordering)\n const results = await this.collection.get({\n where: whereClause,\n include: ['documents', 'metadatas'],\n });\n\n // Sort by timestamp and limit\n const contexts: Array<{ content: string; metadata: any }> = [];\n\n if (results.documents) {\n const indexed = results.documents.map((doc, i) => ({\n content: doc || '',\n metadata: results.metadatas?.[i] || {},\n }));\n\n // Sort by timestamp descending\n indexed.sort(\n (a, b) => (b.metadata.timestamp || 0) - (a.metadata.timestamp || 0)\n );\n\n // Take limit\n contexts.push(...indexed.slice(0, limit));\n }\n\n return contexts;\n } catch (error: unknown) {\n this.logger.error('Failed to get recent contexts', error);\n throw error;\n }\n }\n\n /**\n * Delete old contexts (retention policy)\n */\n async deleteOldContexts(olderThanDays: number = 30): Promise<number> {\n if (!this.collection) {\n throw new Error('ChromaDB not initialized');\n }\n\n try {\n const cutoffTime = Date.now() - olderThanDays * 24 * 60 * 60 * 1000;\n\n // Get old documents\n const results = await this.collection.get({\n where: {\n user_id: this.userId,\n timestamp: { $lt: cutoffTime },\n },\n include: ['ids'],\n });\n\n if (!results.ids || results.ids.length === 0) {\n return 0;\n }\n\n // Delete old documents\n await this.collection.delete({\n ids: results.ids,\n });\n\n this.logger.info(`Deleted ${results.ids.length} old contexts`);\n return results.ids.length;\n } catch (error: unknown) {\n this.logger.error('Failed to delete old contexts', error);\n throw error;\n }\n }\n\n /**\n * Get team contexts (if user is part of a team)\n */\n async getTeamContexts(\n limit: number = 20\n ): Promise<Array<{ content: string; metadata: any }>> {\n if (!this.collection || !this.teamId) {\n return [];\n }\n\n try {\n const results = await this.collection.get({\n where: {\n team_id: this.teamId,\n },\n include: ['documents', 'metadatas'],\n limit,\n });\n\n const contexts: Array<{ content: string; metadata: any }> = [];\n\n if (results.documents) {\n for (let i = 0; i < results.documents.length; i++) {\n contexts.push({\n content: results.documents[i] || '',\n metadata: results.metadatas?.[i] || {},\n });\n }\n }\n\n return contexts;\n } catch (error: unknown) {\n this.logger.error('Failed to get team contexts', error);\n return [];\n }\n }\n\n /**\n * Convert frame to searchable document\n */\n private frameToDocument(frame: Frame): string {\n const parts = [\n `Frame: ${frame.title}`,\n `Type: ${frame.type}`,\n `Status: ${frame.status}`,\n ];\n\n if (frame.description) {\n parts.push(`Description: ${frame.description}`);\n }\n\n if (frame.inputs && frame.inputs.length > 0) {\n parts.push(`Inputs: ${frame.inputs.join(', ')}`);\n }\n\n if (frame.outputs && frame.outputs.length > 0) {\n parts.push(`Outputs: ${frame.outputs.join(', ')}`);\n }\n\n if (frame.tags && frame.tags.length > 0) {\n parts.push(`Tags: ${frame.tags.join(', ')}`);\n }\n\n if (frame.digest_json) {\n try {\n const digest = JSON.parse(frame.digest_json);\n if (digest.summary) {\n parts.push(`Summary: ${digest.summary}`);\n }\n if (digest.keyDecisions) {\n parts.push(`Decisions: ${digest.keyDecisions.join('. ')}`);\n }\n } catch {\n // Ignore parse errors\n }\n }\n\n return parts.join('\\n');\n }\n\n /**\n * Update team ID for a user\n */\n async updateTeamId(newTeamId: string): Promise<void> {\n this.teamId = newTeamId;\n this.logger.info(`Updated team ID to ${newTeamId} for user ${this.userId}`);\n }\n\n /**\n * Get storage statistics\n */\n async getStats(): Promise<{\n totalDocuments: number;\n userDocuments: number;\n teamDocuments?: number;\n documentsByType: Record<string, number>;\n }> {\n if (!this.collection) {\n throw new Error('ChromaDB not initialized');\n }\n\n try {\n // Get user documents\n const userResults = await this.collection.get({\n where: { user_id: this.userId },\n include: ['metadatas'],\n });\n\n const stats: any = {\n totalDocuments: 0,\n userDocuments: userResults.ids?.length || 0,\n documentsByType: {},\n };\n\n // Count by type\n if (userResults.metadatas) {\n for (const metadata of userResults.metadatas) {\n const type = metadata?.type || 'unknown';\n stats.documentsByType[type] = (stats.documentsByType[type] || 0) + 1;\n }\n }\n\n // Get team documents if applicable\n if (this.teamId) {\n const teamResults = await this.collection.get({\n where: { team_id: this.teamId },\n include: ['ids'],\n });\n stats.teamDocuments = teamResults.ids?.length || 0;\n }\n\n stats.totalDocuments = stats.userDocuments + (stats.teamDocuments || 0);\n\n return stats;\n } catch (error: unknown) {\n this.logger.error('Failed to get stats', error);\n throw error;\n }\n }\n}\n"],
5
- "mappings": "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",
6
- "names": []
7
- }
@@ -1,7 +0,0 @@
1
- {
2
- "version": 3,
3
- "sources": ["../../../../src/core/storage/infinite-storage.ts"],
4
- "sourcesContent": ["/**\n * Infinite Storage System for StackMemory\n * Implements STA-287: Remote storage with TimeSeries DB + S3 + Redis\n *\n * Storage Tiers:\n * - Hot: Redis (< 1 hour, frequently accessed)\n * - Warm: TimeSeries DB (1 hour - 7 days)\n * - Cold: S3 Standard (7 days - 30 days)\n * - Archive: S3 Glacier (> 30 days)\n */\n\nimport {\n S3Client,\n PutObjectCommand,\n GetObjectCommand,\n ListObjectsV2Command,\n} from '@aws-sdk/client-s3';\nimport { createClient as createRedisClient } from 'redis';\nimport { Pool } from 'pg';\nimport { Logger } from '../monitoring/logger.js';\nimport { Frame } from '../context/index.js';\nimport { v4 as uuidv4 } from 'uuid';\nimport { compress, decompress } from '../utils/compression.js';\n\nexport interface StorageTier {\n name: 'hot' | 'warm' | 'cold' | 'archive';\n ageThresholdHours: number;\n storageClass: string;\n accessLatencyMs: number;\n}\n\nexport interface StorageConfig {\n redis: {\n url: string;\n ttlSeconds: number;\n maxMemoryMB: number;\n };\n timeseries: {\n connectionString: string;\n retentionDays: number;\n };\n s3: {\n bucket: string;\n region: string;\n accessKeyId?: string;\n secretAccessKey?: string;\n };\n tiers: StorageTier[];\n}\n\nexport interface StorageMetrics {\n totalObjects: number;\n tierDistribution: Record<string, number>;\n storageBytes: number;\n avgLatencyMs: number;\n p50LatencyMs: number;\n p99LatencyMs: number;\n}\n\nexport class InfiniteStorageSystem {\n private redisClient: any;\n private timeseriesPool: Pool;\n private s3Client: S3Client;\n private logger: Logger;\n private config: StorageConfig;\n private latencies: number[] = [];\n private migrationWorker: NodeJS.Timeout | null = null;\n\n constructor(config: StorageConfig) {\n this.config = config;\n this.logger = new Logger('InfiniteStorage');\n\n // Default storage tiers\n if (!config.tiers || config.tiers.length === 0) {\n this.config.tiers = [\n {\n name: 'hot',\n ageThresholdHours: 1,\n storageClass: 'MEMORY',\n accessLatencyMs: 5,\n },\n {\n name: 'warm',\n ageThresholdHours: 168,\n storageClass: 'TIMESERIES',\n accessLatencyMs: 50,\n },\n {\n name: 'cold',\n ageThresholdHours: 720,\n storageClass: 'S3_STANDARD',\n accessLatencyMs: 100,\n },\n {\n name: 'archive',\n ageThresholdHours: Infinity,\n storageClass: 'S3_GLACIER',\n accessLatencyMs: 3600000,\n },\n ];\n }\n }\n\n async initialize(): Promise<void> {\n try {\n // Initialize Redis (hot tier)\n if (this.config.redis?.url) {\n this.redisClient = createRedisClient({\n url: this.config.redis.url,\n });\n\n await this.redisClient.connect();\n\n // Configure Redis memory policy\n await this.redisClient.configSet('maxmemory-policy', 'allkeys-lru');\n if (this.config.redis.maxMemoryMB) {\n await this.redisClient.configSet(\n 'maxmemory',\n `${this.config.redis.maxMemoryMB}mb`\n );\n }\n\n this.logger.info('Redis client initialized for hot tier');\n }\n\n // Initialize TimeSeries DB (warm tier)\n if (this.config.timeseries?.connectionString) {\n this.timeseriesPool = new Pool({\n connectionString: this.config.timeseries.connectionString,\n max: 10,\n idleTimeoutMillis: 30000,\n });\n\n // Create TimeSeries tables if not exists\n await this.createTimeSeriesTables();\n this.logger.info('TimeSeries DB initialized for warm tier');\n }\n\n // Initialize S3 (cold/archive tiers)\n if (this.config.s3?.bucket) {\n this.s3Client = new S3Client({\n region: this.config.s3.region || 'us-east-1',\n credentials: this.config.s3.accessKeyId\n ? {\n accessKeyId: this.config.s3.accessKeyId,\n secretAccessKey: this.config.s3.secretAccessKey!,\n }\n : undefined,\n });\n\n this.logger.info('S3 client initialized for cold/archive tiers');\n }\n\n // Start background migration worker\n this.startMigrationWorker();\n\n this.logger.info('Infinite Storage System initialized');\n } catch (error: unknown) {\n this.logger.error('Failed to initialize storage system', error);\n throw error;\n }\n }\n\n /**\n * Create TimeSeries tables for warm tier storage\n */\n private async createTimeSeriesTables(): Promise<void> {\n const client = await this.timeseriesPool.connect();\n\n try {\n // Create hypertable for time-series data\n await client.query(`\n CREATE TABLE IF NOT EXISTS frame_timeseries (\n time TIMESTAMPTZ NOT NULL,\n frame_id TEXT NOT NULL,\n user_id TEXT NOT NULL,\n project_name TEXT,\n type TEXT,\n data JSONB,\n compressed_data BYTEA,\n storage_tier TEXT DEFAULT 'warm',\n access_count INTEGER DEFAULT 0,\n last_accessed TIMESTAMPTZ DEFAULT NOW(),\n PRIMARY KEY (time, frame_id)\n )\n `);\n\n // Create hypertable if using TimescaleDB\n await client\n .query(\n `\n SELECT create_hypertable('frame_timeseries', 'time', \n chunk_time_interval => INTERVAL '1 day',\n if_not_exists => TRUE)\n `\n )\n .catch(() => {\n // Fallback to regular partitioning if not TimescaleDB\n this.logger.info('Using standard PostgreSQL partitioning');\n });\n\n // Create indexes\n await client.query(`\n CREATE INDEX IF NOT EXISTS idx_frame_user ON frame_timeseries (user_id, time DESC);\n CREATE INDEX IF NOT EXISTS idx_frame_project ON frame_timeseries (project_name, time DESC);\n CREATE INDEX IF NOT EXISTS idx_frame_tier ON frame_timeseries (storage_tier);\n `);\n\n // Create compression policy (TimescaleDB specific)\n await client\n .query(\n `\n SELECT add_compression_policy('frame_timeseries', INTERVAL '7 days', if_not_exists => TRUE)\n `\n )\n .catch(() => {\n this.logger.info('Compression policy not available');\n });\n } finally {\n client.release();\n }\n }\n\n /**\n * Store a frame with automatic tier selection\n */\n async storeFrame(frame: Frame, userId: string): Promise<void> {\n const startTime = Date.now();\n\n try {\n const frameData = JSON.stringify(frame);\n const compressedData = await compress(frameData);\n const frameKey = `frame:${userId}:${frame.frameId}`;\n\n // Always store in hot tier first (Redis)\n if (this.redisClient) {\n await this.redisClient.setEx(\n frameKey,\n this.config.redis.ttlSeconds || 3600,\n compressedData\n );\n\n // Store metadata for quick lookups\n await this.redisClient.hSet(`meta:${frameKey}`, {\n userId,\n projectName: frame.projectName || 'default',\n type: frame.type,\n timestamp: frame.timestamp,\n tier: 'hot',\n });\n }\n\n // Also store in warm tier for durability\n if (this.timeseriesPool) {\n const client = await this.timeseriesPool.connect();\n\n try {\n await client.query(\n `\n INSERT INTO frame_timeseries (time, frame_id, user_id, project_name, type, data, compressed_data, storage_tier)\n VALUES ($1, $2, $3, $4, $5, $6, $7, $8)\n ON CONFLICT (time, frame_id) DO UPDATE\n SET data = EXCLUDED.data,\n compressed_data = EXCLUDED.compressed_data,\n last_accessed = NOW(),\n access_count = frame_timeseries.access_count + 1\n `,\n [\n new Date(frame.timestamp),\n frame.frameId,\n userId,\n frame.projectName || 'default',\n frame.type,\n frame,\n compressedData,\n 'warm',\n ]\n );\n } finally {\n client.release();\n }\n }\n\n // Track latency\n const latency = Date.now() - startTime;\n this.trackLatency(latency);\n\n this.logger.debug(`Stored frame ${frame.frameId} in ${latency}ms`);\n } catch (error: unknown) {\n this.logger.error(`Failed to store frame ${frame.frameId}`, error);\n throw error;\n }\n }\n\n /**\n * Retrieve a frame with intelligent caching\n */\n async retrieveFrame(frameId: string, userId: string): Promise<Frame | null> {\n const startTime = Date.now();\n const frameKey = `frame:${userId}:${frameId}`;\n\n try {\n // Try hot tier first (Redis)\n if (this.redisClient) {\n const cached = await this.redisClient.get(frameKey);\n if (cached) {\n const decompressed = await decompress(cached);\n const frame = JSON.parse(decompressed);\n\n // Refresh TTL on access\n await this.redisClient.expire(\n frameKey,\n this.config.redis.ttlSeconds || 3600\n );\n\n const latency = Date.now() - startTime;\n this.trackLatency(latency);\n this.logger.debug(\n `Retrieved frame ${frameId} from hot tier in ${latency}ms`\n );\n\n return frame;\n }\n }\n\n // Try warm tier (TimeSeries DB)\n if (this.timeseriesPool) {\n const client = await this.timeseriesPool.connect();\n\n try {\n const result = await client.query(\n `\n SELECT data, compressed_data, storage_tier \n FROM frame_timeseries \n WHERE frame_id = $1 AND user_id = $2\n ORDER BY time DESC\n LIMIT 1\n `,\n [frameId, userId]\n );\n\n if (result.rows.length > 0) {\n const row = result.rows[0];\n let frame: Frame;\n\n if (row.compressed_data) {\n const decompressed = await decompress(row.compressed_data);\n frame = JSON.parse(decompressed);\n } else {\n frame = row.data;\n }\n\n // Update access stats\n await client.query(\n `\n UPDATE frame_timeseries \n SET last_accessed = NOW(), access_count = access_count + 1\n WHERE frame_id = $1 AND user_id = $2\n `,\n [frameId, userId]\n );\n\n // Promote to hot tier if frequently accessed\n if (this.redisClient) {\n await this.promoteToHotTier(frame, userId);\n }\n\n const latency = Date.now() - startTime;\n this.trackLatency(latency);\n this.logger.debug(\n `Retrieved frame ${frameId} from warm tier in ${latency}ms`\n );\n\n return frame;\n }\n } finally {\n client.release();\n }\n }\n\n // Try cold/archive tiers (S3)\n if (this.s3Client && this.config.s3.bucket) {\n const key = `frames/${userId}/${frameId}.json.gz`;\n\n try {\n const command = new GetObjectCommand({\n Bucket: this.config.s3.bucket,\n Key: key,\n });\n\n const response = await this.s3Client.send(command);\n const compressedData = await response.Body!.transformToByteArray();\n const decompressed = await decompress(Buffer.from(compressedData));\n const frame = JSON.parse(decompressed);\n\n // Promote to warmer tiers for future access\n await this.promoteFrame(frame, userId);\n\n const latency = Date.now() - startTime;\n this.trackLatency(latency);\n this.logger.debug(\n `Retrieved frame ${frameId} from cold tier in ${latency}ms`\n );\n\n return frame;\n } catch (error: any) {\n if (error.Code !== 'NoSuchKey') {\n throw error;\n }\n }\n }\n\n this.logger.debug(`Frame ${frameId} not found in any tier`);\n return null;\n } catch (error: unknown) {\n this.logger.error(`Failed to retrieve frame ${frameId}`, error);\n throw error;\n }\n }\n\n /**\n * Promote frame to hot tier for fast access\n */\n private async promoteToHotTier(frame: Frame, userId: string): Promise<void> {\n if (!this.redisClient) return;\n\n try {\n const frameKey = `frame:${userId}:${frame.frameId}`;\n const frameData = JSON.stringify(frame);\n const compressedData = await compress(frameData);\n\n await this.redisClient.setEx(\n frameKey,\n this.config.redis.ttlSeconds || 3600,\n compressedData\n );\n\n this.logger.debug(`Promoted frame ${frame.frameId} to hot tier`);\n } catch (error: unknown) {\n this.logger.error(`Failed to promote frame ${frame.frameId}`, error);\n }\n }\n\n /**\n * Promote frame through storage tiers\n */\n private async promoteFrame(frame: Frame, userId: string): Promise<void> {\n // Promote to warm tier\n if (this.timeseriesPool) {\n const client = await this.timeseriesPool.connect();\n\n try {\n const compressedData = await compress(JSON.stringify(frame));\n\n await client.query(\n `\n INSERT INTO frame_timeseries (time, frame_id, user_id, data, compressed_data, storage_tier)\n VALUES ($1, $2, $3, $4, $5, $6)\n ON CONFLICT (time, frame_id) DO UPDATE\n SET storage_tier = 'warm',\n last_accessed = NOW(),\n access_count = frame_timeseries.access_count + 1\n `,\n [\n new Date(frame.timestamp),\n frame.frameId,\n userId,\n frame,\n compressedData,\n 'warm',\n ]\n );\n } finally {\n client.release();\n }\n }\n\n // Also promote to hot tier\n await this.promoteToHotTier(frame, userId);\n }\n\n /**\n * Start background worker for tier migration\n */\n private startMigrationWorker(): void {\n // Run migration every hour\n this.migrationWorker = setInterval(\n async () => {\n await this.migrateAgedData();\n },\n 60 * 60 * 1000\n );\n\n this.logger.info('Migration worker started');\n }\n\n /**\n * Migrate aged data to appropriate storage tiers\n */\n private async migrateAgedData(): Promise<void> {\n this.logger.info('Starting tier migration...');\n\n if (!this.timeseriesPool) return;\n\n const client = await this.timeseriesPool.connect();\n\n try {\n // Find data eligible for cold storage (> 7 days old)\n const coldEligible = await client.query(`\n SELECT frame_id, user_id, data, compressed_data\n FROM frame_timeseries\n WHERE storage_tier = 'warm'\n AND time < NOW() - INTERVAL '7 days'\n AND last_accessed < NOW() - INTERVAL '7 days'\n LIMIT 1000\n `);\n\n // Migrate to S3 cold storage\n for (const row of coldEligible.rows) {\n await this.migrateToS3(row, 'STANDARD');\n\n // Update tier in database\n await client.query(\n `\n UPDATE frame_timeseries\n SET storage_tier = 'cold'\n WHERE frame_id = $1 AND user_id = $2\n `,\n [row.frame_id, row.user_id]\n );\n }\n\n // Find data eligible for archive (> 30 days old)\n const archiveEligible = await client.query(`\n SELECT frame_id, user_id, data, compressed_data\n FROM frame_timeseries\n WHERE storage_tier = 'cold'\n AND time < NOW() - INTERVAL '30 days'\n AND last_accessed < NOW() - INTERVAL '30 days'\n LIMIT 1000\n `);\n\n // Migrate to S3 Glacier\n for (const row of archiveEligible.rows) {\n await this.migrateToS3(row, 'GLACIER');\n\n // Update tier in database\n await client.query(\n `\n UPDATE frame_timeseries\n SET storage_tier = 'archive'\n WHERE frame_id = $1 AND user_id = $2\n `,\n [row.frame_id, row.user_id]\n );\n }\n\n this.logger.info(\n `Migration completed: ${coldEligible.rows.length} to cold, ${archiveEligible.rows.length} to archive`\n );\n } finally {\n client.release();\n }\n }\n\n /**\n * Migrate data to S3 storage\n */\n private async migrateToS3(row: any, storageClass: string): Promise<void> {\n if (!this.s3Client || !this.config.s3.bucket) return;\n\n try {\n const key = `frames/${row.user_id}/${row.frame_id}.json.gz`;\n const data =\n row.compressed_data || (await compress(JSON.stringify(row.data)));\n\n const command = new PutObjectCommand({\n Bucket: this.config.s3.bucket,\n Key: key,\n Body: data,\n StorageClass: storageClass,\n Metadata: {\n userId: row.user_id,\n frameId: row.frame_id,\n migratedAt: new Date().toISOString(),\n },\n });\n\n await this.s3Client.send(command);\n\n this.logger.debug(`Migrated frame ${row.frame_id} to S3 ${storageClass}`);\n } catch (error: unknown) {\n this.logger.error(`Failed to migrate frame ${row.frame_id} to S3`, error);\n throw error;\n }\n }\n\n /**\n * Track latency for performance monitoring\n */\n private trackLatency(latencyMs: number): void {\n this.latencies.push(latencyMs);\n\n // Keep only last 1000 measurements\n if (this.latencies.length > 1000) {\n this.latencies.shift();\n }\n }\n\n /**\n * Get storage metrics\n */\n async getMetrics(): Promise<StorageMetrics> {\n const metrics: StorageMetrics = {\n totalObjects: 0,\n tierDistribution: {},\n storageBytes: 0,\n avgLatencyMs: 0,\n p50LatencyMs: 0,\n p99LatencyMs: 0,\n };\n\n // Calculate latency percentiles\n if (this.latencies.length > 0) {\n const sorted = [...this.latencies].sort((a, b) => a - b);\n metrics.avgLatencyMs = sorted.reduce((a, b) => a + b, 0) / sorted.length;\n metrics.p50LatencyMs = sorted[Math.floor(sorted.length * 0.5)];\n metrics.p99LatencyMs = sorted[Math.floor(sorted.length * 0.99)];\n }\n\n // Get tier distribution from TimeSeries DB\n if (this.timeseriesPool) {\n const client = await this.timeseriesPool.connect();\n\n try {\n const result = await client.query(`\n SELECT \n storage_tier,\n COUNT(*) as count,\n SUM(pg_column_size(compressed_data)) as bytes\n FROM frame_timeseries\n GROUP BY storage_tier\n `);\n\n for (const row of result.rows) {\n metrics.tierDistribution[row.storage_tier] = parseInt(row.count);\n metrics.storageBytes += parseInt(row.bytes || 0);\n metrics.totalObjects += parseInt(row.count);\n }\n } finally {\n client.release();\n }\n }\n\n return metrics;\n }\n\n /**\n * Cleanup and shutdown\n */\n async shutdown(): Promise<void> {\n if (this.migrationWorker) {\n clearInterval(this.migrationWorker);\n }\n\n if (this.redisClient) {\n await this.redisClient.quit();\n }\n\n if (this.timeseriesPool) {\n await this.timeseriesPool.end();\n }\n\n this.logger.info('Infinite Storage System shut down');\n }\n}\n"],
5
- "mappings": "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",
6
- "names": []
7
- }
@@ -1,7 +0,0 @@
1
- {
2
- "version": 3,
3
- "sources": ["../../../../src/core/storage/project-registry.ts"],
4
- "sourcesContent": ["/**\n * Project Registry Manager\n * Manages multi-repository support with a central project registry.\n * Projects are registered with their paths and DB locations, and one\n * project can be marked as active at a time.\n */\n\nimport * as path from 'path';\nimport type { DatabaseAdapter } from '../database/database-adapter.js';\n\nexport interface ProjectInfo {\n projectId: string;\n repoPath: string;\n displayName: string | null;\n dbPath: string;\n isActive: boolean;\n createdAt: number;\n lastAccessed: number;\n}\n\nexport class ProjectRegistryManager {\n constructor(private adapter: DatabaseAdapter) {}\n\n /** Register a new project */\n async register(\n projectId: string,\n repoPath: string,\n displayName?: string\n ): Promise<void> {\n const dbPath = this.computeDbPath(repoPath);\n await this.adapter.registerProject({\n projectId,\n repoPath,\n displayName,\n dbPath,\n });\n }\n\n /** List all registered projects */\n async list(): Promise<ProjectInfo[]> {\n return this.adapter.getRegisteredProjects();\n }\n\n /** Switch active project */\n async switchTo(projectId: string): Promise<boolean> {\n const projects = await this.list();\n if (!projects.find((p) => p.projectId === projectId)) return false;\n await this.adapter.setActiveProject(projectId);\n return true;\n }\n\n /** Remove a project from registry (doesn't delete data) */\n async remove(projectId: string): Promise<boolean> {\n return this.adapter.removeProject(projectId);\n }\n\n /** Get current active project */\n async getActive(): Promise<ProjectInfo | null> {\n const activeId = await this.adapter.getActiveProject();\n if (!activeId) return null;\n const projects = await this.list();\n return projects.find((p) => p.projectId === activeId) || null;\n }\n\n /** Auto-detect project from cwd */\n async detectAndRegister(cwd: string): Promise<string> {\n const projectId = path.basename(cwd);\n const existing = await this.list();\n const found = existing.find((p) => p.repoPath === cwd);\n if (found) {\n await this.adapter.touchProject(found.projectId);\n return found.projectId;\n }\n await this.register(projectId, cwd);\n return projectId;\n }\n\n private computeDbPath(repoPath: string): string {\n return path.join(repoPath, '.stackmemory', 'memory.db');\n }\n}\n"],
5
- "mappings": ";;;;AAOA,YAAY,UAAU;AAaf,MAAM,uBAAuB;AAAA,EAClC,YAAoB,SAA0B;AAA1B;AAAA,EAA2B;AAAA;AAAA,EAG/C,MAAM,SACJ,WACA,UACA,aACe;AACf,UAAM,SAAS,KAAK,cAAc,QAAQ;AAC1C,UAAM,KAAK,QAAQ,gBAAgB;AAAA,MACjC;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IACF,CAAC;AAAA,EACH;AAAA;AAAA,EAGA,MAAM,OAA+B;AACnC,WAAO,KAAK,QAAQ,sBAAsB;AAAA,EAC5C;AAAA;AAAA,EAGA,MAAM,SAAS,WAAqC;AAClD,UAAM,WAAW,MAAM,KAAK,KAAK;AACjC,QAAI,CAAC,SAAS,KAAK,CAAC,MAAM,EAAE,cAAc,SAAS,EAAG,QAAO;AAC7D,UAAM,KAAK,QAAQ,iBAAiB,SAAS;AAC7C,WAAO;AAAA,EACT;AAAA;AAAA,EAGA,MAAM,OAAO,WAAqC;AAChD,WAAO,KAAK,QAAQ,cAAc,SAAS;AAAA,EAC7C;AAAA;AAAA,EAGA,MAAM,YAAyC;AAC7C,UAAM,WAAW,MAAM,KAAK,QAAQ,iBAAiB;AACrD,QAAI,CAAC,SAAU,QAAO;AACtB,UAAM,WAAW,MAAM,KAAK,KAAK;AACjC,WAAO,SAAS,KAAK,CAAC,MAAM,EAAE,cAAc,QAAQ,KAAK;AAAA,EAC3D;AAAA;AAAA,EAGA,MAAM,kBAAkB,KAA8B;AACpD,UAAM,YAAY,KAAK,SAAS,GAAG;AACnC,UAAM,WAAW,MAAM,KAAK,KAAK;AACjC,UAAM,QAAQ,SAAS,KAAK,CAAC,MAAM,EAAE,aAAa,GAAG;AACrD,QAAI,OAAO;AACT,YAAM,KAAK,QAAQ,aAAa,MAAM,SAAS;AAC/C,aAAO,MAAM;AAAA,IACf;AACA,UAAM,KAAK,SAAS,WAAW,GAAG;AAClC,WAAO;AAAA,EACT;AAAA,EAEQ,cAAc,UAA0B;AAC9C,WAAO,KAAK,KAAK,UAAU,gBAAgB,WAAW;AAAA,EACxD;AACF;",
6
- "names": []
7
- }
@@ -1,7 +0,0 @@
1
- {
2
- "version": 3,
3
- "sources": ["../../../../src/core/storage/remote-storage.ts"],
4
- "sourcesContent": ["/**\n * Remote Storage Interface for Two-Tier Storage System\n * Implements infinite retention with TimeSeries DB + S3\n */\n\nimport {\n S3Client,\n PutObjectCommand,\n GetObjectCommand,\n DeleteObjectCommand,\n} from '@aws-sdk/client-s3';\nimport { Storage } from '@google-cloud/storage';\nimport { logger } from '../monitoring/logger.js';\nimport { Trace, CompressedTrace } from '../trace/types.js';\nimport Database from 'better-sqlite3';\n// Type-safe environment variable access\nfunction getEnv(key: string, defaultValue?: string): string {\n const value = process.env[key];\n if (value === undefined) {\n if (defaultValue !== undefined) return defaultValue;\n throw new Error(`Environment variable ${key} is required`);\n }\n return value;\n}\n\nfunction getOptionalEnv(key: string): string | undefined {\n return process.env[key];\n}\n\nexport enum StorageTier {\n HOT = 'hot', // < 7 days - Railway Buckets or GCS Standard\n NEARLINE = 'nearline', // 7-30 days - GCS Nearline ($0.01/GB)\n COLDLINE = 'coldline', // 30-90 days - GCS Coldline ($0.004/GB)\n ARCHIVE = 'archive', // > 90 days - GCS Archive ($0.0012/GB)\n}\n\nexport interface RemoteStorageConfig {\n provider: 'gcs' | 's3' | 'railway';\n gcs?: {\n bucketName: string;\n projectId: string;\n keyFilename?: string; // Path to service account key\n };\n s3?: {\n bucket: string;\n region: string;\n accessKeyId?: string;\n secretAccessKey?: string;\n endpoint?: string; // For Railway buckets or MinIO\n };\n timeseries: {\n type: 'clickhouse' | 'timescale' | 'influxdb' | 'sqlite'; // SQLite for dev\n host: string;\n port: number;\n database: string;\n username?: string;\n password?: string;\n };\n migration: {\n batchSize: number;\n hotAgeHours: number; // < 7 days\n nearlineAgeHours: number; // 7-30 days\n coldlineAgeHours: number; // 30-90 days\n archiveAgeHours: number; // > 90 days\n scoreThreshold: number; // Score threshold for early migration\n };\n}\n\nexport const DEFAULT_REMOTE_CONFIG: RemoteStorageConfig = {\n provider: 'gcs', // Default to GCS for better pricing\n gcs: {\n bucketName: 'stackmemory-traces',\n projectId: process.env['GCP_PROJECT_ID'] || 'stackmemory',\n },\n timeseries: {\n type: 'sqlite', // Use SQLite for development\n host: 'localhost',\n port: 0,\n database: 'stackmemory_timeseries',\n },\n migration: {\n batchSize: 100,\n hotAgeHours: 168, // 7 days\n nearlineAgeHours: 720, // 30 days\n coldlineAgeHours: 2160, // 90 days\n archiveAgeHours: 8760, // 365 days\n scoreThreshold: 0.4,\n },\n};\n\nexport interface MigrationCandidate {\n traceId: string;\n age: number;\n score: number;\n size: number;\n tier: StorageTier;\n shouldMigrate: boolean;\n compressionLevel: 'none' | 'light' | 'medium' | 'heavy';\n}\n\n/**\n * Remote storage manager for infinite trace retention\n */\nexport class RemoteStorageManager {\n private storageClient?: S3Client | Storage;\n private config: RemoteStorageConfig;\n private localDb: Database.Database;\n private migrationInProgress = false;\n\n constructor(\n localDb: Database.Database,\n config?: Partial<RemoteStorageConfig>\n ) {\n this.localDb = localDb;\n this.config = { ...DEFAULT_REMOTE_CONFIG, ...config };\n\n this.initializeStorageClient();\n this.initializeSchema();\n }\n\n /**\n * Initialize storage client based on provider\n */\n private initializeStorageClient(): void {\n switch (this.config.provider) {\n case 'gcs':\n if (this.config.gcs) {\n this.storageClient = new Storage({\n projectId: this.config.gcs.projectId,\n keyFilename: this.config.gcs.keyFilename,\n });\n }\n break;\n\n case 's3':\n case 'railway':\n if (this.config.s3?.accessKeyId && this.config.s3?.secretAccessKey) {\n this.storageClient = new S3Client({\n region: this.config.s3.region,\n credentials: {\n accessKeyId: this.config.s3.accessKeyId,\n secretAccessKey: this.config.s3.secretAccessKey,\n },\n endpoint: this.config.s3.endpoint, // Railway buckets endpoint\n });\n }\n break;\n }\n }\n\n /**\n * Initialize migration tracking schema\n */\n private initializeSchema(): void {\n this.localDb.exec(`\n CREATE TABLE IF NOT EXISTS remote_migrations (\n trace_id TEXT PRIMARY KEY,\n migrated_at INTEGER NOT NULL,\n storage_tier TEXT NOT NULL,\n s3_key TEXT,\n timeseries_id TEXT,\n compression_level TEXT,\n original_size INTEGER,\n compressed_size INTEGER,\n retrieval_count INTEGER DEFAULT 0,\n last_retrieved INTEGER,\n FOREIGN KEY (trace_id) REFERENCES traces(id) ON DELETE CASCADE\n )\n `);\n\n this.localDb.exec(`\n CREATE INDEX IF NOT EXISTS idx_migrations_tier ON remote_migrations(storage_tier);\n CREATE INDEX IF NOT EXISTS idx_migrations_migrated ON remote_migrations(migrated_at);\n `);\n }\n\n /**\n * Identify traces for migration based on age and importance\n */\n async identifyMigrationCandidates(): Promise<MigrationCandidate[]> {\n const now = Date.now();\n\n // Query all traces with their metadata\n const traces = this.localDb\n .prepare(\n `\n SELECT \n t.id,\n t.score,\n t.start_time,\n LENGTH(t.compressed_data) + \n COALESCE((SELECT SUM(LENGTH(tc.arguments) + LENGTH(tc.result)) \n FROM tool_calls tc WHERE tc.trace_id = t.id), 0) as size,\n rm.trace_id as already_migrated\n FROM traces t\n LEFT JOIN remote_migrations rm ON t.id = rm.trace_id\n WHERE rm.trace_id IS NULL -- Not already migrated\n ORDER BY t.start_time ASC\n `\n )\n .all() as any[];\n\n const candidates: MigrationCandidate[] = [];\n\n for (const trace of traces) {\n const ageHours = (now - trace.start_time) / (1000 * 60 * 60);\n const candidate = this.evaluateTrace(\n trace.id,\n ageHours,\n trace.score,\n trace.size || 0\n );\n\n candidates.push(candidate);\n }\n\n return candidates;\n }\n\n /**\n * Evaluate a trace for migration based on GCS storage classes\n */\n private evaluateTrace(\n traceId: string,\n ageHours: number,\n score: number,\n size: number\n ): MigrationCandidate {\n let tier = StorageTier.HOT;\n let shouldMigrate = false;\n let compressionLevel: 'none' | 'light' | 'medium' | 'heavy' = 'none';\n\n // Determine storage tier based on age and GCS storage classes\n if (ageHours > this.config.migration.archiveAgeHours) {\n // GCS Archive: $0.0012/GB - accessed < once per year\n tier = StorageTier.ARCHIVE;\n shouldMigrate = true;\n compressionLevel = 'heavy';\n } else if (ageHours > this.config.migration.coldlineAgeHours) {\n // GCS Coldline: $0.004/GB - accessed < once per quarter\n tier = StorageTier.COLDLINE;\n shouldMigrate = true;\n compressionLevel = 'heavy';\n } else if (ageHours > this.config.migration.nearlineAgeHours) {\n // GCS Nearline: $0.01/GB - accessed < once per month\n tier = StorageTier.NEARLINE;\n shouldMigrate = true;\n compressionLevel = 'medium';\n } else if (ageHours > this.config.migration.hotAgeHours) {\n // Still hot but consider migration if low importance\n tier = StorageTier.HOT;\n if (score < this.config.migration.scoreThreshold) {\n shouldMigrate = true;\n compressionLevel = 'light';\n }\n }\n\n // Force migration for size pressure\n const localSizeLimit = 2 * 1024 * 1024 * 1024; // 2GB\n const currentLocalSize = this.getLocalStorageSize();\n\n if (currentLocalSize > localSizeLimit * 0.75) {\n // Start migrating when 75% full\n shouldMigrate = true;\n if (compressionLevel === 'none') {\n compressionLevel = 'light';\n }\n }\n\n return {\n traceId,\n age: ageHours,\n score,\n size,\n tier,\n shouldMigrate,\n compressionLevel,\n };\n }\n\n /**\n * Migrate traces to remote storage\n */\n async migrateTraces(\n candidates: MigrationCandidate[],\n dryRun: boolean = false\n ): Promise<{\n migrated: number;\n failed: number;\n totalSize: number;\n errors: string[];\n }> {\n if (this.migrationInProgress) {\n return {\n migrated: 0,\n failed: 0,\n totalSize: 0,\n errors: ['Migration already in progress'],\n };\n }\n\n this.migrationInProgress = true;\n const results = {\n migrated: 0,\n failed: 0,\n totalSize: 0,\n errors: [] as string[],\n };\n\n try {\n // Process in batches\n const toMigrate = candidates.filter((c: any) => c.shouldMigrate);\n const batches = this.createBatches(\n toMigrate,\n this.config.migration.batchSize\n );\n\n for (const batch of batches) {\n if (dryRun) {\n logger.info('Dry run - would migrate batch', {\n count: batch.length,\n totalSize: batch.reduce((sum, c) => sum + c.size, 0),\n });\n results.migrated += batch.length;\n continue;\n }\n\n const batchResults = await this.migrateBatch(batch);\n results.migrated += batchResults.success;\n results.failed += batchResults.failed;\n results.totalSize += batchResults.totalSize;\n results.errors.push(...batchResults.errors);\n\n // Small delay between batches\n await new Promise((resolve) => setTimeout(resolve, 100));\n }\n } finally {\n this.migrationInProgress = false;\n }\n\n logger.info('Migration completed', results);\n return results;\n }\n\n /**\n * Migrate a batch of traces\n */\n private async migrateBatch(batch: MigrationCandidate[]): Promise<{\n success: number;\n failed: number;\n totalSize: number;\n errors: string[];\n }> {\n const results = {\n success: 0,\n failed: 0,\n totalSize: 0,\n errors: [] as string[],\n };\n\n for (const candidate of batch) {\n try {\n // Get full trace data\n const trace = this.getTraceData(candidate.traceId);\n if (!trace) {\n throw new Error(`Trace ${candidate.traceId} not found`);\n }\n\n // Compress based on level\n const compressed = this.compressTrace(\n trace,\n candidate.compressionLevel\n );\n\n // Upload to S3\n if (this.s3Client) {\n const s3Key = this.generateS3Key(candidate);\n await this.uploadToS3(s3Key, compressed);\n\n // Record migration\n this.recordMigration(candidate, s3Key, trace, compressed);\n } else {\n // Local simulation for testing\n this.recordMigration(candidate, 'simulated', trace, compressed);\n }\n\n // Optionally remove from local after successful migration\n if (\n candidate.tier === StorageTier.COLD ||\n candidate.tier === StorageTier.ARCHIVE\n ) {\n this.removeLocalTrace(candidate.traceId);\n }\n\n results.success++;\n results.totalSize += candidate.size;\n } catch (error: unknown) {\n results.failed++;\n results.errors.push(`Failed to migrate ${candidate.traceId}: ${error}`);\n logger.error('Migration failed for trace', {\n traceId: candidate.traceId,\n error,\n });\n }\n }\n\n return results;\n }\n\n /**\n * Get full trace data for migration\n */\n private getTraceData(traceId: string): any {\n const traceRow = this.localDb\n .prepare('SELECT * FROM traces WHERE id = ?')\n .get(traceId);\n\n if (!traceRow) return null;\n\n const toolCalls = this.localDb\n .prepare(\n 'SELECT * FROM tool_calls WHERE trace_id = ? ORDER BY sequence_number'\n )\n .all(traceId);\n\n return {\n trace: traceRow,\n toolCalls,\n };\n }\n\n /**\n * Compress trace based on compression level\n */\n private compressTrace(\n data: any,\n level: 'none' | 'light' | 'medium' | 'heavy'\n ): Buffer {\n const jsonData = JSON.stringify(data);\n\n // Apply different compression based on level\n switch (level) {\n case 'none':\n return Buffer.from(jsonData);\n\n case 'light':\n // Remove formatting, keep all data\n return Buffer.from(JSON.stringify(JSON.parse(jsonData)));\n\n case 'medium':\n // Remove null fields and compress\n const cleaned = JSON.parse(jsonData, (key, value) =>\n value === null || value === undefined ? undefined : value\n );\n return Buffer.from(JSON.stringify(cleaned));\n\n case 'heavy':\n // Remove tool results and arguments, keep only essential\n const minimal = {\n id: data.trace.id,\n type: data.trace.type,\n score: data.trace.score,\n summary: data.trace.summary,\n timestamps: {\n start: data.trace.start_time,\n end: data.trace.end_time,\n },\n toolCount: data.toolCalls.length,\n toolTypes: [...new Set(data.toolCalls.map((t: any) => t.tool))],\n };\n return Buffer.from(JSON.stringify(minimal));\n\n default:\n return Buffer.from(jsonData);\n }\n }\n\n /**\n * Generate S3 key for trace\n */\n private generateS3Key(candidate: MigrationCandidate): string {\n const date = new Date(Date.now() - candidate.age * 60 * 60 * 1000);\n const year = date.getFullYear();\n const month = String(date.getMonth() + 1).padStart(2, '0');\n const day = String(date.getDate()).padStart(2, '0');\n\n return `traces/${year}/${month}/${day}/${candidate.tier}/${candidate.traceId}.json`;\n }\n\n /**\n * Upload to S3\n */\n private async uploadToS3(key: string, data: Buffer): Promise<void> {\n if (!this.s3Client) {\n throw new Error('S3 client not configured');\n }\n\n const command = new PutObjectCommand({\n Bucket: this.config.s3.bucket,\n Key: key,\n Body: data,\n ContentType: 'application/json',\n Metadata: {\n 'trace-version': '1.0',\n compression: 'true',\n },\n });\n\n await this.s3Client.send(command);\n }\n\n /**\n * Record migration in local database\n */\n private recordMigration(\n candidate: MigrationCandidate,\n s3Key: string,\n originalData: any,\n compressedData: Buffer\n ): void {\n const stmt = this.localDb.prepare(`\n INSERT INTO remote_migrations (\n trace_id, migrated_at, storage_tier, s3_key,\n compression_level, original_size, compressed_size\n ) VALUES (?, ?, ?, ?, ?, ?, ?)\n `);\n\n stmt.run(\n candidate.traceId,\n Date.now(),\n candidate.tier,\n s3Key,\n candidate.compressionLevel,\n JSON.stringify(originalData).length,\n compressedData.length\n );\n }\n\n /**\n * Remove local trace after migration\n */\n private removeLocalTrace(traceId: string): void {\n this.localDb\n .prepare('DELETE FROM tool_calls WHERE trace_id = ?')\n .run(traceId);\n this.localDb.prepare('DELETE FROM traces WHERE id = ?').run(traceId);\n }\n\n /**\n * Get current local storage size\n */\n private getLocalStorageSize(): number {\n const result = this.localDb\n .prepare(\n `\n SELECT \n SUM(LENGTH(compressed_data)) +\n COALESCE((SELECT SUM(LENGTH(arguments) + LENGTH(result)) \n FROM tool_calls), 0) as total_size\n FROM traces\n `\n )\n .get() as any;\n\n return result?.total_size || 0;\n }\n\n /**\n * Create batches from candidates\n */\n private createBatches<T>(items: T[], batchSize: number): T[][] {\n const batches: T[][] = [];\n for (let i = 0; i < items.length; i += batchSize) {\n batches.push(items.slice(i, i + batchSize));\n }\n return batches;\n }\n\n /**\n * Retrieve trace from remote storage\n */\n async retrieveTrace(traceId: string): Promise<any> {\n const migration = this.localDb\n .prepare(\n `\n SELECT * FROM remote_migrations WHERE trace_id = ?\n `\n )\n .get(traceId) as any;\n\n if (!migration) {\n throw new Error(`Trace ${traceId} not found in remote storage`);\n }\n\n // Update retrieval count\n this.localDb\n .prepare(\n `\n UPDATE remote_migrations \n SET retrieval_count = retrieval_count + 1, last_retrieved = ?\n WHERE trace_id = ?\n `\n )\n .run(Date.now(), traceId);\n\n if (!this.s3Client) {\n throw new Error('S3 client not configured');\n }\n\n // Retrieve from S3\n const command = new GetObjectCommand({\n Bucket: this.config.s3.bucket,\n Key: migration.s3_key,\n });\n\n const response = await this.s3Client.send(command);\n const data = await response.Body?.transformToString();\n\n if (!data) {\n throw new Error('No data retrieved from S3');\n }\n\n return JSON.parse(data);\n }\n\n /**\n * Get migration statistics\n */\n getMigrationStats(): any {\n const stats = this.localDb\n .prepare(\n `\n SELECT \n storage_tier,\n COUNT(*) as count,\n SUM(original_size) as original_size,\n SUM(compressed_size) as compressed_size,\n AVG(retrieval_count) as avg_retrievals\n FROM remote_migrations\n GROUP BY storage_tier\n `\n )\n .all();\n\n const total = this.localDb\n .prepare(\n `\n SELECT \n COUNT(*) as total_migrated,\n SUM(original_size) as total_original,\n SUM(compressed_size) as total_compressed\n FROM remote_migrations\n `\n )\n .get();\n\n return {\n byTier: stats,\n total,\n compressionRatio: total\n ? (\n 1 -\n (total as any).total_compressed / (total as any).total_original\n ).toFixed(2)\n : 0,\n localSize: this.getLocalStorageSize(),\n };\n }\n}\n"],
5
- "mappings": "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",
6
- "names": ["StorageTier"]
7
- }
@@ -1,7 +0,0 @@
1
- {
2
- "version": 3,
3
- "sources": ["../../../../src/core/storage/storage-tier-manager.ts"],
4
- "sourcesContent": ["/**\n * StorageTierManager - Cold-tier frame archival to S3/GCS\n * Archives old frames to cloud storage before GC deletion,\n * with rehydration cache for on-demand retrieval.\n */\n\nimport type { Frame } from '../context/index.js';\n\nexport interface ColdStorageProvider {\n upload(key: string, data: Buffer): Promise<void>;\n download(key: string): Promise<Buffer | null>;\n exists(key: string): Promise<boolean>;\n delete(key: string): Promise<void>;\n list(prefix: string): Promise<string[]>;\n}\n\nexport interface StorageTierConfig {\n coldTierProvider?: 'none' | 's3' | 'gcs';\n coldTierBucket?: string;\n coldTierPrefix?: string; // default: 'stackmemory/frames/'\n migrationAgeDays?: number; // frames older than this get migrated (default: 60)\n rehydrateCacheMinutes?: number; // cache rehydrated frames for N minutes (default: 30)\n}\n\n/**\n * In-memory implementation of ColdStorageProvider for testing.\n */\nexport class InMemoryColdStorageProvider implements ColdStorageProvider {\n private store = new Map<string, Buffer>();\n\n async upload(key: string, data: Buffer): Promise<void> {\n this.store.set(key, Buffer.from(data));\n }\n\n async download(key: string): Promise<Buffer | null> {\n const data = this.store.get(key);\n return data ? Buffer.from(data) : null;\n }\n\n async exists(key: string): Promise<boolean> {\n return this.store.has(key);\n }\n\n async delete(key: string): Promise<void> {\n this.store.delete(key);\n }\n\n async list(prefix: string): Promise<string[]> {\n const keys: string[] = [];\n for (const key of this.store.keys()) {\n if (key.startsWith(prefix)) {\n keys.push(key);\n }\n }\n return keys;\n }\n\n /** Test helper: get current store size */\n get size(): number {\n return this.store.size;\n }\n\n /** Test helper: clear all stored data */\n clear(): void {\n this.store.clear();\n }\n}\n\nexport class StorageTierManager {\n private provider: ColdStorageProvider | null = null;\n private config: StorageTierConfig;\n private rehydrateCache = new Map<\n string,\n { frame: Frame; cachedAt: number }\n >();\n\n constructor(config: StorageTierConfig) {\n this.config = config;\n }\n\n async initialize(): Promise<void> {\n switch (this.config.coldTierProvider) {\n case 's3':\n this.provider = await this.createS3Provider();\n break;\n case 'gcs':\n this.provider = await this.createGCSProvider();\n break;\n default:\n this.provider = null;\n }\n }\n\n /**\n * Initialize with an externally-provided ColdStorageProvider.\n * Useful for testing or custom backends.\n */\n initializeWithProvider(provider: ColdStorageProvider): void {\n this.provider = provider;\n }\n\n get isEnabled(): boolean {\n return this.provider !== null;\n }\n\n /** Archive a frame to cold storage */\n async archiveFrame(frame: Frame): Promise<boolean> {\n if (!this.provider) return false;\n const key = this.frameKey(frame.frame_id);\n const data = Buffer.from(JSON.stringify(frame));\n await this.provider.upload(key, data);\n return true;\n }\n\n /** Archive multiple frames (batch) */\n async archiveFrames(frames: Frame[]): Promise<number> {\n let archived = 0;\n for (const frame of frames) {\n if (await this.archiveFrame(frame)) archived++;\n }\n return archived;\n }\n\n /** Rehydrate a frame from cold storage (with local cache) */\n async rehydrateFrame(frameId: string): Promise<Frame | null> {\n // Check cache first\n const cached = this.rehydrateCache.get(frameId);\n const cacheMs = (this.config.rehydrateCacheMinutes ?? 30) * 60 * 1000;\n if (cached && Date.now() - cached.cachedAt < cacheMs) {\n return cached.frame;\n }\n\n if (!this.provider) return null;\n const key = this.frameKey(frameId);\n const data = await this.provider.download(key);\n if (!data) return null;\n\n const frame = JSON.parse(data.toString()) as Frame;\n this.rehydrateCache.set(frameId, { frame, cachedAt: Date.now() });\n return frame;\n }\n\n /** Delete an archived frame from cold storage */\n async deleteArchived(frameId: string): Promise<boolean> {\n if (!this.provider) return false;\n const key = this.frameKey(frameId);\n const found = await this.provider.exists(key);\n if (!found) return false;\n await this.provider.delete(key);\n this.rehydrateCache.delete(frameId);\n return true;\n }\n\n /** Get storage stats */\n async getStats(): Promise<{\n provider: string;\n archivedFrames: number;\n bucket: string;\n }> {\n if (!this.provider) {\n return { provider: 'none', archivedFrames: 0, bucket: '' };\n }\n const prefix = this.config.coldTierPrefix ?? 'stackmemory/frames/';\n const keys = await this.provider.list(prefix);\n return {\n provider: this.config.coldTierProvider ?? 'none',\n archivedFrames: keys.length,\n bucket: this.config.coldTierBucket ?? '',\n };\n }\n\n /** Clear the rehydration cache */\n clearCache(): void {\n this.rehydrateCache.clear();\n }\n\n private frameKey(frameId: string): string {\n const prefix = this.config.coldTierPrefix ?? 'stackmemory/frames/';\n return `${prefix}${frameId}.json`;\n }\n\n private async createS3Provider(): Promise<ColdStorageProvider> {\n const {\n S3Client,\n PutObjectCommand,\n GetObjectCommand,\n HeadObjectCommand,\n DeleteObjectCommand,\n ListObjectsV2Command,\n } = await import('@aws-sdk/client-s3');\n const client = new S3Client({});\n const bucket = this.config.coldTierBucket!;\n\n return {\n async upload(key: string, data: Buffer) {\n await client.send(\n new PutObjectCommand({ Bucket: bucket, Key: key, Body: data })\n );\n },\n async download(key: string) {\n try {\n const res = await client.send(\n new GetObjectCommand({ Bucket: bucket, Key: key })\n );\n const bytes = await res.Body?.transformToByteArray();\n return bytes ? Buffer.from(bytes) : null;\n } catch {\n return null;\n }\n },\n async exists(key: string) {\n try {\n await client.send(\n new HeadObjectCommand({ Bucket: bucket, Key: key })\n );\n return true;\n } catch {\n return false;\n }\n },\n async delete(key: string) {\n await client.send(\n new DeleteObjectCommand({ Bucket: bucket, Key: key })\n );\n },\n async list(prefix: string) {\n const res = await client.send(\n new ListObjectsV2Command({ Bucket: bucket, Prefix: prefix })\n );\n return (res.Contents ?? []).map((c) => c.Key!).filter(Boolean);\n },\n };\n }\n\n private async createGCSProvider(): Promise<ColdStorageProvider> {\n const { Storage } = await import('@google-cloud/storage');\n const storage = new Storage();\n const bucket = storage.bucket(this.config.coldTierBucket!);\n\n return {\n async upload(key: string, data: Buffer) {\n await bucket.file(key).save(data);\n },\n async download(key: string) {\n try {\n const [data] = await bucket.file(key).download();\n return data;\n } catch {\n return null;\n }\n },\n async exists(key: string) {\n const [fileExists] = await bucket.file(key).exists();\n return fileExists;\n },\n async delete(key: string) {\n await bucket.file(key).delete();\n },\n async list(prefix: string) {\n const [files] = await bucket.getFiles({ prefix });\n return files.map((f) => f.name);\n },\n };\n }\n}\n"],
5
- "mappings": "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",
6
- "names": []
7
- }
@@ -1,7 +0,0 @@
1
- {
2
- "version": 3,
3
- "sources": ["../../../../src/core/storage/two-tier-storage.ts"],
4
- "sourcesContent": ["/**\n * Two-Tier Storage System for StackMemory\n * Implements STA-414: Local and Remote Storage with Migration\n *\n * Local Tiers:\n * - Young: < 1 day (complete retention in RAM)\n * - Mature: 1-7 days (selective retention with LZ4)\n * - Old: 7-30 days (critical only with ZSTD)\n *\n * Remote Tier:\n * - Infinite retention with TimeSeries DB + S3\n * - Monthly partitioning\n * - Cost-aware migration\n */\n\nimport Database from 'better-sqlite3';\nimport {\n S3Client,\n PutObjectCommand,\n GetObjectCommand,\n} from '@aws-sdk/client-s3';\nimport type { RedisClientType } from 'redis';\nimport { createClient as createRedisClient } from 'redis';\nimport { Pool } from 'pg';\nimport * as zlib from 'zlib';\nimport { promisify } from 'util';\nimport { v4 as uuidv4 } from 'uuid';\nimport { Logger } from '../monitoring/logger.js';\nimport type { Frame, Event, Anchor } from '../context/index.js';\n\n// LZ4 would be installed separately: npm install lz4\n// For now we'll use a placeholder\nconst lz4 = {\n encode: (data: Buffer) => data, // Placeholder\n decode: (data: Buffer) => data, // Placeholder\n};\n\nconst gzip = promisify(zlib.gzip);\nconst gunzip = promisify(zlib.gunzip);\n\nexport enum StorageTier {\n YOUNG = 'young', // < 1 day, in RAM\n MATURE = 'mature', // 1-7 days, LZ4\n OLD = 'old', // 7-30 days, ZSTD\n REMOTE = 'remote', // > 30 days, S3\n}\n\nexport interface TierConfig {\n name: StorageTier;\n maxAgeHours: number;\n compressionType: 'none' | 'lz4' | 'zstd' | 'gzip';\n retentionPolicy: 'complete' | 'selective' | 'critical';\n maxSizeMB: number;\n}\n\nexport interface MigrationTrigger {\n type: 'age' | 'size' | 'importance';\n threshold: number;\n action: 'migrate' | 'compress' | 'delete';\n}\n\nexport interface OfflineQueueItem {\n id: string;\n data: any;\n priority: 'high' | 'normal';\n timestamp: number;\n}\n\nexport interface TwoTierConfig {\n local: {\n dbPath: string;\n maxSizeGB: number;\n tiers: TierConfig[];\n };\n remote: {\n redis?: {\n url: string;\n ttlSeconds: number;\n };\n timeseries?: {\n connectionString: string;\n };\n s3: {\n bucket: string;\n region: string;\n accessKeyId?: string;\n secretAccessKey?: string;\n };\n };\n migration: {\n triggers: MigrationTrigger[];\n batchSize: number;\n intervalMs: number;\n offlineQueuePath?: string;\n };\n}\n\nexport interface StorageStats {\n localUsageMB: number;\n remoteUsageMB: number;\n tierDistribution: Record<StorageTier, number>;\n compressionRatio: number;\n migrationsPending: number;\n lastMigration: Date | null;\n}\n\nexport class TwoTierStorageSystem {\n private db: Database.Database;\n private redisClient?: RedisClientType;\n private timeseriesPool?: Pool;\n private s3Client: S3Client;\n private logger: Logger;\n private config: TwoTierConfig;\n private migrationTimer?: NodeJS.Timeout;\n private offlineQueue: OfflineQueueItem[] = [];\n private stats: StorageStats;\n\n constructor(config: TwoTierConfig) {\n this.config = config;\n this.logger = new Logger('TwoTierStorage');\n\n // Initialize local SQLite\n this.db = new Database(config.local.dbPath);\n this.initializeLocalStorage();\n\n // Initialize S3 client\n this.s3Client = new S3Client({\n region: config.remote.s3.region,\n credentials:\n config.remote.s3.accessKeyId && config.remote.s3.secretAccessKey\n ? {\n accessKeyId: config.remote.s3.accessKeyId,\n secretAccessKey: config.remote.s3.secretAccessKey,\n }\n : undefined,\n });\n\n // Initialize stats\n this.stats = {\n localUsageMB: 0,\n remoteUsageMB: 0,\n tierDistribution: {\n [StorageTier.YOUNG]: 0,\n [StorageTier.MATURE]: 0,\n [StorageTier.OLD]: 0,\n [StorageTier.REMOTE]: 0,\n },\n compressionRatio: 1.0,\n migrationsPending: 0,\n lastMigration: null,\n };\n }\n\n private initializeLocalStorage(): void {\n // Enable WAL mode for better concurrency\n this.db.pragma('journal_mode = WAL');\n this.db.pragma('synchronous = NORMAL');\n\n // Create storage tables with tier information\n this.db.exec(`\n CREATE TABLE IF NOT EXISTS storage_items (\n id TEXT PRIMARY KEY,\n frame_id TEXT NOT NULL,\n tier TEXT NOT NULL,\n data BLOB NOT NULL,\n metadata TEXT,\n size_bytes INTEGER,\n importance_score REAL DEFAULT 0.5,\n access_count INTEGER DEFAULT 0,\n last_accessed DATETIME DEFAULT CURRENT_TIMESTAMP,\n created_at DATETIME DEFAULT CURRENT_TIMESTAMP,\n compressed BOOLEAN DEFAULT FALSE,\n compression_type TEXT\n );\n \n CREATE INDEX IF NOT EXISTS idx_tier_age ON storage_items (tier, created_at);\n CREATE INDEX IF NOT EXISTS idx_frame ON storage_items (frame_id);\n CREATE INDEX IF NOT EXISTS idx_importance ON storage_items (importance_score DESC);\n \n CREATE TABLE IF NOT EXISTS migration_queue (\n id TEXT PRIMARY KEY,\n item_id TEXT NOT NULL,\n source_tier TEXT NOT NULL,\n target_tier TEXT NOT NULL,\n priority INTEGER DEFAULT 5,\n attempts INTEGER DEFAULT 0,\n status TEXT DEFAULT 'pending',\n created_at DATETIME DEFAULT CURRENT_TIMESTAMP\n );\n \n CREATE INDEX IF NOT EXISTS idx_status_priority ON migration_queue (status, priority DESC);\n \n CREATE TABLE IF NOT EXISTS storage_metrics (\n id INTEGER PRIMARY KEY AUTOINCREMENT,\n tier TEXT NOT NULL,\n item_count INTEGER,\n total_size_mb REAL,\n avg_compression_ratio REAL,\n measured_at DATETIME DEFAULT CURRENT_TIMESTAMP\n );\n `);\n }\n\n async initialize(): Promise<void> {\n try {\n // Initialize Redis for hot cache\n if (this.config.remote.redis?.url) {\n this.redisClient = createRedisClient({\n url: this.config.remote.redis.url,\n });\n await this.redisClient.connect();\n this.logger.info('Redis connected for hot cache');\n }\n\n // Initialize TimeSeries DB\n if (this.config.remote.timeseries?.connectionString) {\n this.timeseriesPool = new Pool({\n connectionString: this.config.remote.timeseries.connectionString,\n max: 5,\n });\n await this.initializeTimeseriesSchema();\n this.logger.info('TimeSeries DB connected');\n }\n\n // Start migration worker\n this.startMigrationWorker();\n\n // Load offline queue if exists\n await this.loadOfflineQueue();\n\n // Calculate initial stats\n await this.updateStats();\n\n this.logger.info('Two-tier storage system initialized');\n } catch (error) {\n this.logger.error('Failed to initialize storage', { error });\n throw error;\n }\n }\n\n private async initializeTimeseriesSchema(): Promise<void> {\n if (!this.timeseriesPool) return;\n\n const client = await this.timeseriesPool.connect();\n try {\n await client.query(`\n CREATE TABLE IF NOT EXISTS frame_timeseries (\n time TIMESTAMPTZ NOT NULL,\n frame_id TEXT NOT NULL,\n project_id TEXT NOT NULL,\n data JSONB,\n metrics JSONB,\n importance_score REAL\n );\n \n SELECT create_hypertable('frame_timeseries', 'time', \n chunk_time_interval => INTERVAL '1 month',\n if_not_exists => TRUE\n );\n \n CREATE INDEX IF NOT EXISTS idx_frame_time \n ON frame_timeseries (frame_id, time DESC);\n `);\n } finally {\n client.release();\n }\n }\n\n /**\n * Store a frame with automatic tier selection\n */\n async storeFrame(\n frame: Frame,\n events: Event[],\n anchors: Anchor[]\n ): Promise<string> {\n const storageId = uuidv4();\n const data = { frame, events, anchors };\n const tier = this.selectTier(frame);\n\n // Calculate importance score\n const importanceScore = this.calculateImportance(frame, events, anchors);\n\n // Compress based on tier\n const compressed = await this.compressData(data, tier);\n\n // Store locally first\n const stmt = this.db.prepare(`\n INSERT INTO storage_items (\n id, frame_id, tier, data, metadata, size_bytes, \n importance_score, compressed, compression_type\n ) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)\n `);\n\n stmt.run(\n storageId,\n frame.frame_id,\n tier,\n compressed.data,\n JSON.stringify({\n originalSize: compressed.originalSize,\n compressedSize: compressed.compressedSize,\n }),\n compressed.compressedSize,\n importanceScore,\n compressed.compressed ? 1 : 0,\n compressed.compressionType\n );\n\n // Also store in Redis if young and available\n if (tier === StorageTier.YOUNG && this.redisClient) {\n await this.redisClient.setex(\n `frame:${frame.frame_id}`,\n this.config.remote.redis?.ttlSeconds || 300,\n JSON.stringify(data)\n );\n }\n\n // Queue for remote upload if important\n if (importanceScore > 0.7) {\n await this.queueRemoteUpload(storageId, data, 'high');\n }\n\n return storageId;\n }\n\n /**\n * Retrieve a frame from any tier\n */\n async retrieveFrame(frameId: string): Promise<any> {\n // Check Redis first\n if (this.redisClient) {\n try {\n const cached = await this.redisClient.get(`frame:${frameId}`);\n if (cached) {\n this.updateAccessCount(frameId);\n return JSON.parse(cached);\n }\n } catch (error) {\n this.logger.warn('Redis retrieval failed', { frameId, error });\n }\n }\n\n // Check local storage\n const local = this.db\n .prepare(\n `\n SELECT data, compressed, compression_type \n FROM storage_items \n WHERE frame_id = ?\n ORDER BY created_at DESC\n LIMIT 1\n `\n )\n .get(frameId);\n\n if (local) {\n this.updateAccessCount(frameId);\n const data = local.compressed\n ? await this.decompressData(local.data, local.compression_type)\n : JSON.parse(local.data);\n\n // Promote to Redis if frequently accessed\n if (this.redisClient) {\n await this.redisClient.setex(\n `frame:${frameId}`,\n 300, // 5 minute cache\n JSON.stringify(data)\n );\n }\n\n return data;\n }\n\n // Check remote storage\n return this.retrieveFromRemote(frameId);\n }\n\n /**\n * Select appropriate tier based on frame age and characteristics\n */\n private selectTier(frame: Frame): StorageTier {\n if (!frame.created_at || isNaN(frame.created_at)) {\n this.logger.warn('Invalid frame timestamp, defaulting to YOUNG tier');\n return StorageTier.YOUNG;\n }\n\n const ageHours = (Date.now() - frame.created_at) / (1000 * 60 * 60);\n\n if (ageHours < 24) return StorageTier.YOUNG;\n if (ageHours < 168) return StorageTier.MATURE; // 7 days\n if (ageHours < 720) return StorageTier.OLD; // 30 days\n return StorageTier.REMOTE;\n }\n\n /**\n * Calculate importance score for migration decisions\n */\n private calculateImportance(\n frame: Frame,\n events: Event[],\n anchors: Anchor[]\n ): number {\n let score = 0.5; // Base score\n\n // Increase for frames with decisions\n const decisions = anchors.filter((a) => a.type === 'DECISION');\n score += decisions.length * 0.1;\n\n // Increase for frames with many events\n score += Math.min(events.length * 0.01, 0.2);\n\n // Increase for recent frames\n const ageHours = (Date.now() - frame.created_at) / (1000 * 60 * 60);\n if (ageHours < 24) score += 0.2;\n else if (ageHours < 168) score += 0.1;\n\n // Increase for frames with errors\n const errors = events.filter((e) => e.event_type === 'error');\n if (errors.length > 0) score += 0.2;\n\n return Math.min(score, 1.0);\n }\n\n /**\n * Compress data based on tier configuration\n */\n private async compressData(data: any, tier: StorageTier): Promise<any> {\n const json = JSON.stringify(data);\n const originalSize = Buffer.byteLength(json);\n\n const tierConfig = this.config.local.tiers.find((t) => t.name === tier);\n if (!tierConfig || tierConfig.compressionType === 'none') {\n return {\n data: Buffer.from(json),\n originalSize,\n compressedSize: originalSize,\n compressed: false,\n compressionType: 'none',\n };\n }\n\n let compressed: Buffer;\n switch (tierConfig.compressionType) {\n case 'lz4':\n compressed = lz4.encode(Buffer.from(json));\n break;\n case 'zstd':\n // For ZSTD, we'll use gzip as a placeholder (install zstd-codec for real impl)\n compressed = await gzip(json, { level: 9 });\n break;\n case 'gzip':\n compressed = await gzip(json);\n break;\n default:\n compressed = Buffer.from(json);\n }\n\n return {\n data: compressed,\n originalSize,\n compressedSize: compressed.length,\n compressed: true,\n compressionType: tierConfig.compressionType,\n };\n }\n\n /**\n * Decompress data\n */\n private async decompressData(\n data: Buffer,\n compressionType: string\n ): Promise<any> {\n let decompressed: Buffer;\n\n switch (compressionType) {\n case 'lz4':\n decompressed = lz4.decode(data);\n break;\n case 'zstd':\n case 'gzip':\n decompressed = await gunzip(data);\n break;\n default:\n decompressed = data;\n }\n\n return JSON.parse(decompressed.toString());\n }\n\n /**\n * Start background migration worker\n */\n private startMigrationWorker(): void {\n this.migrationTimer = setInterval(async () => {\n try {\n await this.processMigrations();\n await this.checkMigrationTriggers();\n await this.processOfflineQueue();\n } catch (error) {\n this.logger.error('Migration worker error', { error });\n }\n }, this.config.migration.intervalMs);\n\n this.logger.info('Migration worker started');\n }\n\n /**\n * Process pending migrations\n */\n private async processMigrations(): Promise<void> {\n const pending = this.db\n .prepare(\n `\n SELECT * FROM migration_queue \n WHERE status = 'pending' \n ORDER BY priority DESC, created_at ASC \n LIMIT ?\n `\n )\n .all(this.config.migration.batchSize);\n\n for (const migration of pending) {\n try {\n await this.executeMigration(migration);\n\n // Mark as completed\n this.db\n .prepare(\n `\n UPDATE migration_queue \n SET status = 'completed' \n WHERE id = ?\n `\n )\n .run(migration.id);\n } catch (error) {\n this.logger.error('Migration failed', { migration, error });\n\n // Update attempts\n this.db\n .prepare(\n `\n UPDATE migration_queue \n SET attempts = attempts + 1,\n status = CASE WHEN attempts >= 3 THEN 'failed' ELSE 'pending' END\n WHERE id = ?\n `\n )\n .run(migration.id);\n }\n }\n\n this.stats.lastMigration = new Date();\n }\n\n /**\n * Check and trigger migrations based on rules\n */\n private async checkMigrationTriggers(): Promise<void> {\n // Check age-based triggers\n for (const trigger of this.config.migration.triggers) {\n if (trigger.type === 'age') {\n const items = this.db\n .prepare(\n `\n SELECT id, frame_id, tier \n FROM storage_items \n WHERE julianday('now') - julianday(created_at) > ?\n AND tier != ?\n LIMIT 100\n `\n )\n .all(trigger.threshold / 24, StorageTier.REMOTE);\n\n for (const item of items) {\n this.queueMigration(item.id, item.tier, StorageTier.REMOTE);\n }\n }\n\n // Check size-based triggers\n if (trigger.type === 'size') {\n const stats = this.db\n .prepare(\n `\n SELECT SUM(size_bytes) as total_size \n FROM storage_items \n WHERE tier IN ('young', 'mature')\n `\n )\n .get();\n\n if (stats.total_size > trigger.threshold * 1024 * 1024) {\n // Migrate oldest items\n const items = this.db\n .prepare(\n `\n SELECT id, tier FROM storage_items \n WHERE tier IN ('young', 'mature')\n ORDER BY created_at ASC \n LIMIT 50\n `\n )\n .all();\n\n for (const item of items) {\n const targetTier =\n item.tier === StorageTier.YOUNG\n ? StorageTier.MATURE\n : StorageTier.OLD;\n this.queueMigration(item.id, item.tier, targetTier);\n }\n }\n }\n }\n }\n\n /**\n * Queue a migration\n */\n private queueMigration(\n itemId: string,\n sourceTier: string,\n targetTier: string,\n priority: number = 5\n ): void {\n const id = uuidv4();\n this.db\n .prepare(\n `\n INSERT INTO migration_queue (id, item_id, source_tier, target_tier, priority)\n VALUES (?, ?, ?, ?, ?)\n `\n )\n .run(id, itemId, sourceTier, targetTier, priority);\n\n this.stats.migrationsPending++;\n }\n\n /**\n * Execute a single migration\n */\n private async executeMigration(migration: any): Promise<void> {\n // Get item data\n const item = this.db\n .prepare(\n `\n SELECT * FROM storage_items WHERE id = ?\n `\n )\n .get(migration.item_id);\n\n if (!item) {\n throw new Error(`Item not found: ${migration.item_id}`);\n }\n\n // Decompress if needed\n const data = item.compressed\n ? await this.decompressData(item.data, item.compression_type)\n : JSON.parse(item.data);\n\n // Upload to remote\n if (migration.target_tier === StorageTier.REMOTE) {\n await this.uploadToS3(item.frame_id, data);\n\n // Delete from local after successful upload\n this.db\n .prepare(\n `\n DELETE FROM storage_items WHERE id = ?\n `\n )\n .run(migration.item_id);\n } else {\n // Re-compress for new tier\n const compressed = await this.compressData(data, migration.target_tier);\n\n // Update local storage\n this.db\n .prepare(\n `\n UPDATE storage_items \n SET tier = ?, data = ?, size_bytes = ?, \n compressed = ?, compression_type = ?\n WHERE id = ?\n `\n )\n .run(\n migration.target_tier,\n compressed.data,\n compressed.compressedSize,\n compressed.compressed ? 1 : 0,\n compressed.compressionType,\n migration.item_id\n );\n }\n\n this.logger.info('Migration completed', {\n itemId: migration.item_id,\n from: migration.source_tier,\n to: migration.target_tier,\n });\n }\n\n /**\n * Upload data to S3\n */\n private async uploadToS3(frameId: string, data: any): Promise<void> {\n const date = new Date();\n const partition = `${date.getFullYear()}/${String(date.getMonth() + 1).padStart(2, '0')}`;\n const key = `frames/${partition}/${frameId}.json.gz`;\n\n const compressed = await gzip(JSON.stringify(data));\n\n const command = new PutObjectCommand({\n Bucket: this.config.remote.s3.bucket,\n Key: key,\n Body: compressed,\n ContentType: 'application/json',\n ContentEncoding: 'gzip',\n Metadata: {\n frameId,\n uploadedAt: date.toISOString(),\n },\n });\n\n await this.s3Client.send(command);\n }\n\n /**\n * Retrieve from remote storage\n */\n private async retrieveFromRemote(frameId: string): Promise<any> {\n // Try TimeSeries DB first\n if (this.timeseriesPool) {\n const client = await this.timeseriesPool.connect();\n try {\n const result = await client.query(\n `\n SELECT data FROM frame_timeseries \n WHERE frame_id = $1 \n ORDER BY time DESC \n LIMIT 1\n `,\n [frameId]\n );\n\n if (result.rows.length > 0) {\n return result.rows[0].data;\n }\n } finally {\n client.release();\n }\n }\n\n // Try S3\n // Would need to search multiple partitions - simplified for now\n const date = new Date();\n for (let i = 0; i < 3; i++) {\n const checkDate = new Date(date);\n checkDate.setMonth(checkDate.getMonth() - i);\n const partition = `${checkDate.getFullYear()}/${String(checkDate.getMonth() + 1).padStart(2, '0')}`;\n const key = `frames/${partition}/${frameId}.json.gz`;\n\n try {\n const command = new GetObjectCommand({\n Bucket: this.config.remote.s3.bucket,\n Key: key,\n });\n\n const response = await this.s3Client.send(command);\n if (!response.Body) continue;\n const body = await response.Body.transformToByteArray();\n const decompressed = await gunzip(Buffer.from(body));\n return JSON.parse(decompressed.toString());\n } catch {\n // Continue searching - frame not in this partition\n }\n }\n\n return null;\n }\n\n /**\n * Queue for offline upload\n */\n private async queueRemoteUpload(\n id: string,\n data: any,\n priority: 'high' | 'normal'\n ): Promise<void> {\n this.offlineQueue.push({ \n id, \n data, \n priority, \n timestamp: Date.now() \n });\n\n // Persist queue if configured\n if (this.config.migration.offlineQueuePath) {\n await this.saveOfflineQueue();\n }\n }\n\n /**\n * Process offline upload queue\n */\n private async processOfflineQueue(): Promise<void> {\n if (this.offlineQueue.length === 0) return;\n\n // Check if online\n const isOnline = await this.checkConnectivity();\n if (!isOnline) return;\n\n // Process high priority first\n this.offlineQueue.sort((a, b) => {\n if (a.priority !== b.priority) {\n return a.priority === 'high' ? -1 : 1;\n }\n return a.timestamp - b.timestamp;\n });\n\n const batch = this.offlineQueue.splice(0, 10);\n for (const item of batch) {\n try {\n await this.uploadToS3(item.id, item.data);\n } catch {\n // Re-queue on failure\n this.offlineQueue.push(item);\n }\n }\n\n await this.saveOfflineQueue();\n }\n\n /**\n * Check connectivity to remote services\n */\n private async checkConnectivity(): Promise<boolean> {\n try {\n // Simple S3 head bucket check\n const response = await fetch('https://s3.amazonaws.com');\n return response.ok;\n } catch {\n return false;\n }\n }\n\n /**\n * Update access count for cache promotion\n */\n private updateAccessCount(frameId: string): void {\n this.db\n .prepare(\n `\n UPDATE storage_items \n SET access_count = access_count + 1,\n last_accessed = CURRENT_TIMESTAMP\n WHERE frame_id = ?\n `\n )\n .run(frameId);\n }\n\n /**\n * Save offline queue to disk\n */\n private async saveOfflineQueue(): Promise<void> {\n if (!this.config.migration.offlineQueuePath) return;\n\n const fs = await import('fs/promises');\n await fs.writeFile(\n this.config.migration.offlineQueuePath,\n JSON.stringify(this.offlineQueue),\n 'utf-8'\n );\n }\n\n /**\n * Load offline queue from disk\n */\n private async loadOfflineQueue(): Promise<void> {\n if (!this.config.migration.offlineQueuePath) return;\n\n const fs = await import('fs/promises');\n try {\n const data = await fs.readFile(\n this.config.migration.offlineQueuePath,\n 'utf-8'\n );\n this.offlineQueue = JSON.parse(data);\n this.logger.info(\n `Loaded ${this.offlineQueue.length} items from offline queue`\n );\n } catch {\n // Queue file doesn't exist yet - this is normal on first run\n }\n }\n\n /**\n * Update storage statistics\n */\n private async updateStats(): Promise<void> {\n // Calculate local usage\n const localStats = this.db\n .prepare(\n `\n SELECT \n tier,\n COUNT(*) as count,\n SUM(size_bytes) / 1048576.0 as size_mb\n FROM storage_items\n GROUP BY tier\n `\n )\n .all();\n\n this.stats.localUsageMB = 0;\n for (const stat of localStats) {\n this.stats.tierDistribution[stat.tier as StorageTier] = stat.count;\n this.stats.localUsageMB += stat.size_mb;\n }\n\n // Calculate compression ratio\n const compressionStats = this.db\n .prepare(\n `\n SELECT \n AVG(CAST(json_extract(metadata, '$.originalSize') AS REAL) / \n CAST(json_extract(metadata, '$.compressedSize') AS REAL)) as ratio\n FROM storage_items\n WHERE compressed = 1\n `\n )\n .get();\n\n this.stats.compressionRatio = compressionStats?.ratio || 1.0;\n\n // Count pending migrations\n const pending = this.db\n .prepare(\n `\n SELECT COUNT(*) as count \n FROM migration_queue \n WHERE status = 'pending'\n `\n )\n .get();\n\n this.stats.migrationsPending = pending.count;\n\n // Save metrics\n this.db\n .prepare(\n `\n INSERT INTO storage_metrics (tier, item_count, total_size_mb, avg_compression_ratio)\n VALUES ('all', ?, ?, ?)\n `\n )\n .run(\n Object.values(this.stats.tierDistribution).reduce((a, b) => a + b, 0),\n this.stats.localUsageMB,\n this.stats.compressionRatio\n );\n }\n\n /**\n * Get current storage statistics\n */\n async getStats(): Promise<StorageStats> {\n await this.updateStats();\n return { ...this.stats };\n }\n\n /**\n * Cleanup and shutdown\n */\n async shutdown(): Promise<void> {\n if (this.migrationTimer) {\n clearInterval(this.migrationTimer);\n }\n\n await this.saveOfflineQueue();\n\n if (this.redisClient) {\n await this.redisClient.quit();\n }\n\n if (this.timeseriesPool) {\n await this.timeseriesPool.end();\n }\n\n this.db.close();\n\n this.logger.info('Two-tier storage system shut down');\n }\n}\n\n// Export default configuration\nexport const defaultTwoTierConfig: TwoTierConfig = {\n local: {\n dbPath: '~/.stackmemory/two-tier.db',\n maxSizeGB: 2,\n tiers: [\n {\n name: StorageTier.YOUNG,\n maxAgeHours: 24,\n compressionType: 'none',\n retentionPolicy: 'complete',\n maxSizeMB: 500,\n },\n {\n name: StorageTier.MATURE,\n maxAgeHours: 168,\n compressionType: 'lz4',\n retentionPolicy: 'selective',\n maxSizeMB: 1000,\n },\n {\n name: StorageTier.OLD,\n maxAgeHours: 720,\n compressionType: 'zstd',\n retentionPolicy: 'critical',\n maxSizeMB: 500,\n },\n ],\n },\n remote: {\n s3: {\n bucket: process.env.S3_BUCKET || 'stackmemory-storage',\n region: process.env.AWS_REGION || 'us-east-1',\n },\n },\n migration: {\n triggers: [\n { type: 'age', threshold: 720, action: 'migrate' }, // 30 days\n { type: 'size', threshold: 1500, action: 'migrate' }, // 1.5GB\n { type: 'importance', threshold: 0.3, action: 'delete' }, // Low importance\n ],\n batchSize: 50,\n intervalMs: 60000, // 1 minute\n offlineQueuePath: '~/.stackmemory/offline-queue.json',\n },\n};\n"],
5
- "mappings": "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",
6
- "names": ["StorageTier"]
7
- }
@@ -1,7 +0,0 @@
1
- {
2
- "version": 3,
3
- "sources": ["../../../../src/core/trace/cli-trace-wrapper.ts"],
4
- "sourcesContent": ["/**\n * CLI Command Trace Wrapper\n * Automatically wraps Commander.js commands with comprehensive tracing\n */\n\nimport { Command } from 'commander';\nimport { trace } from './debug-trace.js';\nimport { logger } from '../monitoring/logger.js';\n// Type-safe environment variable access\nfunction getEnv(key: string, defaultValue?: string): string {\n const value = process.env[key];\n if (value === undefined) {\n if (defaultValue !== undefined) return defaultValue;\n throw new Error(`Environment variable ${key} is required`);\n }\n return value;\n}\n\nfunction getOptionalEnv(key: string): string | undefined {\n return process.env[key];\n}\n\nexport function wrapCommand(command: Command): Command {\n const originalAction = command.action.bind(command);\n\n command.action(async function (...args: any[]): Promise<void> {\n // Extract command path and options\n const commandPath = getCommandPath(command);\n const options = args[args.length - 1];\n const commandArgs = args.slice(0, -1);\n\n // Build comprehensive context\n const context = {\n command: commandPath,\n args: commandArgs,\n options: typeof options === 'object' ? options : {},\n cwd: process.cwd(),\n env: {\n NODE_ENV: process.env['NODE_ENV'],\n DEBUG_TRACE: process.env['DEBUG_TRACE'],\n LINEAR_API_KEY: process.env['LINEAR_API_KEY'] ? '[SET]' : '[NOT SET]',\n },\n timestamp: new Date().toISOString(),\n };\n\n // Log command start\n logger.info(`CLI Command: ${commandPath}`, context);\n\n // Wrap the actual action with tracing\n await trace.command(commandPath, context, async () => {\n try {\n // Call the original action with wrapped handler\n const result = await originalAction.apply(null, args as any);\n\n // Log successful completion\n logger.info(`CLI Command Completed: ${commandPath}`, {\n duration: trace\n .exportTraces()\n .find((t: any) => t.name === commandPath)?.duration,\n });\n\n // Show execution summary if verbose\n if (process.env['DEBUG_TRACE'] === 'true') {\n console.log(trace.getExecutionSummary());\n }\n } catch (error: unknown) {\n // Enhanced error logging for CLI commands\n logger.error(\n `CLI Command Failed: ${commandPath}`,\n error as Error,\n context\n );\n\n // Get the last error trace for debugging\n const lastError = trace.getLastError();\n if (lastError) {\n console.error('\\n\uD83D\uDCCD Error occurred at:');\n console.error(` ${lastError.name}`);\n if (lastError.params) {\n console.error(\n ' With params:',\n JSON.stringify(lastError.params, null, 2)\n );\n }\n console.error(' Error details:', lastError.error);\n }\n\n // Re-throw to maintain original error handling\n throw error;\n }\n });\n });\n\n // Recursively wrap subcommands\n command.commands.forEach((subcommand) => {\n wrapCommand(subcommand);\n });\n\n return command;\n}\n\nfunction getCommandPath(command: Command): string {\n const parts: string[] = [];\n let current: Command | null = command;\n\n while (current) {\n if (current.name()) {\n parts.unshift(current.name());\n }\n current = current.parent as Command | null;\n }\n\n return parts.join(' ');\n}\n\n/**\n * Wrap the main program with comprehensive tracing\n */\nexport function wrapProgram(program: Command): Command {\n // Add global error handler with tracing\n program.exitOverride((err) => {\n if (err.code === 'commander.help' || err.code === 'commander.version') {\n // Normal help/version display, not an error\n process.exit(0);\n }\n\n // Log the error with full context\n logger.error('CLI Error', err, {\n code: err.code,\n exitCode: err.exitCode,\n command: process.argv.slice(2).join(' '),\n });\n\n // Show trace summary on error\n if (process.env['DEBUG_TRACE'] === 'true') {\n console.error('\\n' + trace.getExecutionSummary());\n }\n\n process.exit(err.exitCode || 1);\n });\n\n // Add pre-action hook for setup\n program.hook('preAction', (thisCommand) => {\n // Initialize trace context for this command\n trace.reset();\n\n // Log command invocation\n const commandPath = getCommandPath(thisCommand);\n logger.debug(`Preparing to execute: ${commandPath}`, {\n args: thisCommand.args,\n opts: thisCommand.opts(),\n });\n });\n\n // Add post-action hook for cleanup\n program.hook('postAction', (thisCommand) => {\n // Log completion\n const commandPath = getCommandPath(thisCommand);\n logger.debug(`Completed execution: ${commandPath}`);\n });\n\n // Wrap all existing commands\n program.commands.forEach((command) => {\n wrapCommand(command);\n });\n\n return program;\n}\n\n/**\n * Helper to wrap async functions with step tracing\n */\nexport function traceStep<T>(name: string, fn: () => Promise<T>): Promise<T> {\n return trace.step(name, fn);\n}\n\n/**\n * Helper to wrap database queries\n */\nexport function traceQuery<T>(sql: string, params: any, fn: () => T): T {\n return trace.traceSync('query', sql.substring(0, 100), params, fn);\n}\n\n/**\n * Helper to wrap API calls\n */\nexport function traceAPI<T>(\n method: string,\n url: string,\n body: any,\n fn: () => Promise<T>\n): Promise<T> {\n return trace.api(method, url, body, fn);\n}\n"],
5
- "mappings": "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",
6
- "names": []
7
- }
@@ -1,7 +0,0 @@
1
- {
2
- "version": 3,
3
- "sources": ["../../../../src/core/trace/db-trace-wrapper.ts"],
4
- "sourcesContent": ["/**\n * Database Operations Trace Wrapper\n * Wraps SQLite operations with comprehensive tracing for debugging\n */\n\nimport Database from 'better-sqlite3';\nimport { trace } from './debug-trace.js';\nimport { logger } from '../monitoring/logger.js';\n\nexport interface TracedDatabaseOptions extends Database.Options {\n traceEnabled?: boolean;\n slowQueryThreshold?: number;\n}\n\n/**\n * Create a traced database instance\n */\nexport function createTracedDatabase(\n filename: string,\n options?: TracedDatabaseOptions\n): Database.Database {\n const db = new Database(filename, options);\n\n if (options?.traceEnabled !== false) {\n return wrapDatabase(db, options?.slowQueryThreshold);\n }\n\n return db;\n}\n\n/**\n * Wrap an existing database with tracing\n */\nexport function wrapDatabase(\n db: Database.Database,\n slowQueryThreshold = 100\n): Database.Database {\n // Wrap prepare method to trace all queries\n const originalPrepare = db.prepare.bind(db);\n\n db.prepare = function (source: string) {\n const statement = originalPrepare(source);\n return wrapStatement(statement, source, slowQueryThreshold);\n } as typeof db.prepare;\n\n // Wrap exec for direct SQL execution\n const originalExec = db.exec.bind(db);\n\n db.exec = function (source: string): Database.Database {\n return trace.traceSync(\n 'query',\n `EXEC: ${source.substring(0, 50)}...`,\n {},\n () => {\n const startTime = performance.now();\n const result = originalExec(source);\n const duration = performance.now() - startTime;\n\n if (duration > slowQueryThreshold) {\n logger.warn(`Slow query detected: ${duration.toFixed(0)}ms`, {\n query: source.substring(0, 200),\n duration,\n });\n }\n\n return result;\n }\n );\n };\n\n // Wrap transaction for transaction tracking\n const originalTransaction = db.transaction.bind(db);\n\n db.transaction = function (fn: any) {\n return originalTransaction(function (this: any, ...args: any[]) {\n return trace.traceSync(\n 'query',\n 'TRANSACTION',\n { args: args.length },\n () => {\n return fn.apply(this, args);\n }\n );\n });\n } as typeof db.transaction;\n\n // Add query statistics tracking\n (db as any).__queryStats = {\n totalQueries: 0,\n slowQueries: 0,\n totalDuration: 0,\n queryTypes: {} as Record<string, number>,\n };\n\n return db;\n}\n\n/**\n * Wrap a statement with tracing\n */\nfunction wrapStatement<T extends any[] = any[]>(\n statement: Database.Statement<T>,\n source: string,\n slowQueryThreshold: number\n): Database.Statement<T> {\n const queryType = source.trim().split(/\\s+/)[0].toUpperCase();\n const shortQuery = source.substring(0, 100).replace(/\\s+/g, ' ');\n\n // Wrap run method\n const originalRun = statement.run.bind(statement);\n statement.run = function (...params: T): Database.RunResult {\n return trace.traceSync(\n 'query',\n `${queryType}: ${shortQuery}`,\n params,\n () => {\n const startTime = performance.now();\n const result = originalRun(...params);\n const duration = performance.now() - startTime;\n\n // Track statistics\n updateQueryStats(statement, queryType, duration, slowQueryThreshold);\n\n // Log slow queries\n if (duration > slowQueryThreshold) {\n logger.warn(`Slow ${queryType} query: ${duration.toFixed(0)}ms`, {\n query: shortQuery,\n params,\n duration,\n changes: result.changes,\n });\n }\n\n return result;\n }\n );\n };\n\n // Wrap get method\n const originalGet = statement.get.bind(statement);\n statement.get = function (...params: T): any {\n return trace.traceSync(\n 'query',\n `${queryType} (get): ${shortQuery}`,\n params,\n () => {\n const startTime = performance.now();\n const result = originalGet(...params);\n const duration = performance.now() - startTime;\n\n updateQueryStats(statement, queryType, duration, slowQueryThreshold);\n\n if (duration > slowQueryThreshold) {\n logger.warn(`Slow ${queryType} query: ${duration.toFixed(0)}ms`, {\n query: shortQuery,\n params,\n duration,\n found: result != null,\n });\n }\n\n return result;\n }\n );\n };\n\n // Wrap all method\n const originalAll = statement.all.bind(statement);\n statement.all = function (...params: T): any[] {\n return trace.traceSync(\n 'query',\n `${queryType} (all): ${shortQuery}`,\n params,\n () => {\n const startTime = performance.now();\n const result = originalAll(...params);\n const duration = performance.now() - startTime;\n\n updateQueryStats(statement, queryType, duration, slowQueryThreshold);\n\n if (duration > slowQueryThreshold) {\n logger.warn(`Slow ${queryType} query: ${duration.toFixed(0)}ms`, {\n query: shortQuery,\n params,\n duration,\n rows: result.length,\n });\n }\n\n // Warn about potential N+1 queries\n if (result.length > 100 && queryType === 'SELECT') {\n logger.warn(`Large result set: ${result.length} rows`, {\n query: shortQuery,\n suggestion: 'Consider pagination or more specific queries',\n });\n }\n\n return result;\n }\n );\n };\n\n // Wrap iterate method for cursor operations\n const originalIterate = statement.iterate.bind(statement);\n statement.iterate = function (...params: T): IterableIterator<any> {\n const startTime = performance.now();\n let rowCount = 0;\n\n const iterator = originalIterate(...params);\n const wrappedIterator: IterableIterator<any> = {\n [Symbol.iterator]() {\n return this;\n },\n next() {\n const result = iterator.next();\n if (!result.done) {\n rowCount++;\n } else {\n const duration = performance.now() - startTime;\n updateQueryStats(statement, queryType, duration, slowQueryThreshold);\n\n if (duration > slowQueryThreshold) {\n logger.warn(\n `Slow ${queryType} iteration: ${duration.toFixed(0)}ms`,\n {\n query: shortQuery,\n params,\n duration,\n rows: rowCount,\n }\n );\n }\n }\n return result;\n },\n };\n\n return wrappedIterator;\n };\n\n return statement;\n}\n\n/**\n * Update query statistics\n */\nfunction updateQueryStats(\n statement: Database.Statement,\n queryType: string,\n duration: number,\n slowQueryThreshold: number\n): void {\n const db = statement.database as any;\n if (db.__queryStats) {\n db.__queryStats.totalQueries++;\n db.__queryStats.totalDuration += duration;\n\n if (duration > slowQueryThreshold) {\n db.__queryStats.slowQueries++;\n }\n\n if (!db.__queryStats.queryTypes[queryType]) {\n db.__queryStats.queryTypes[queryType] = 0;\n }\n db.__queryStats.queryTypes[queryType]++;\n }\n}\n\n/**\n * Get query statistics from a traced database\n */\nexport function getQueryStatistics(db: Database.Database): {\n totalQueries: number;\n slowQueries: number;\n averageDuration: number;\n totalDuration: number;\n queryTypes: Record<string, number>;\n} | null {\n const stats = (db as any).__queryStats;\n if (!stats) return null;\n\n return {\n ...stats,\n averageDuration:\n stats.totalQueries > 0 ? stats.totalDuration / stats.totalQueries : 0,\n };\n}\n\n/**\n * Helper to trace a specific query with context\n */\nexport async function traceQuery<T>(\n db: Database.Database,\n queryName: string,\n query: string,\n params: any[],\n fn: () => T\n): Promise<T> {\n return trace.traceAsync('query', queryName, { query, params }, async () => {\n try {\n const result = fn();\n\n // Log successful complex queries for debugging\n if (query.includes('JOIN') || query.includes('GROUP BY')) {\n logger.debug(`Complex query executed: ${queryName}`, {\n query: query.substring(0, 200),\n params,\n });\n }\n\n return result;\n } catch (error: unknown) {\n // Enhanced error logging for database errors\n logger.error(`Database query failed: ${queryName}`, error as Error, {\n query,\n params,\n errorCode: (error as any).code,\n });\n throw error;\n }\n });\n}\n\n/**\n * Create a traced transaction with automatic rollback on error\n */\nexport function createTracedTransaction<T>(\n db: Database.Database,\n name: string,\n fn: (tx: Database.Transaction<(args: any) => T>) => T\n): T {\n return trace.traceSync('query', `TRANSACTION: ${name}`, {}, () => {\n const startTime = performance.now();\n\n try {\n const tx = db.transaction(fn);\n const result = (tx as any).deferred();\n\n const duration = performance.now() - startTime;\n logger.info(`Transaction completed: ${name}`, {\n duration,\n success: true,\n });\n\n return result;\n } catch (error: unknown) {\n const duration = performance.now() - startTime;\n logger.error(`Transaction failed: ${name}`, error as Error, {\n duration,\n success: false,\n });\n throw error;\n }\n });\n}\n"],
5
- "mappings": "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",
6
- "names": []
7
- }