@vinaes/succ 1.3.19
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.
- package/LICENSE +87 -0
- package/README.md +588 -0
- package/agents/succ-checkpoint-manager.md +51 -0
- package/agents/succ-code-reviewer.md +181 -0
- package/agents/succ-context-optimizer.md +83 -0
- package/agents/succ-debug.md +224 -0
- package/agents/succ-decision-auditor.md +74 -0
- package/agents/succ-deep-search.md +41 -0
- package/agents/succ-diff-reviewer.md +123 -0
- package/agents/succ-explore.md +83 -0
- package/agents/succ-general.md +109 -0
- package/agents/succ-knowledge-indexer.md +45 -0
- package/agents/succ-knowledge-mapper.md +61 -0
- package/agents/succ-memory-curator.md +43 -0
- package/agents/succ-memory-health-monitor.md +55 -0
- package/agents/succ-pattern-detective.md +62 -0
- package/agents/succ-plan.md +172 -0
- package/agents/succ-quality-improvement-coach.md +63 -0
- package/agents/succ-readiness-improver.md +62 -0
- package/agents/succ-session-handoff-orchestrator.md +54 -0
- package/agents/succ-session-reviewer.md +46 -0
- package/agents/succ-style-tracker.md +73 -0
- package/dist/cli.d.ts +3 -0
- package/dist/cli.d.ts.map +1 -0
- package/dist/cli.js +749 -0
- package/dist/cli.js.map +1 -0
- package/dist/commands/agents-md.d.ts +16 -0
- package/dist/commands/agents-md.d.ts.map +1 -0
- package/dist/commands/agents-md.js +33 -0
- package/dist/commands/agents-md.js.map +1 -0
- package/dist/commands/analyze-agents.d.ts +20 -0
- package/dist/commands/analyze-agents.d.ts.map +1 -0
- package/dist/commands/analyze-agents.js +305 -0
- package/dist/commands/analyze-agents.js.map +1 -0
- package/dist/commands/analyze-helpers.d.ts +22 -0
- package/dist/commands/analyze-helpers.d.ts.map +1 -0
- package/dist/commands/analyze-helpers.js +38 -0
- package/dist/commands/analyze-helpers.js.map +1 -0
- package/dist/commands/analyze-profile.d.ts +53 -0
- package/dist/commands/analyze-profile.d.ts.map +1 -0
- package/dist/commands/analyze-profile.js +638 -0
- package/dist/commands/analyze-profile.js.map +1 -0
- package/dist/commands/analyze-recursive.d.ts +20 -0
- package/dist/commands/analyze-recursive.d.ts.map +1 -0
- package/dist/commands/analyze-recursive.js +326 -0
- package/dist/commands/analyze-recursive.js.map +1 -0
- package/dist/commands/analyze-utils.d.ts +83 -0
- package/dist/commands/analyze-utils.d.ts.map +1 -0
- package/dist/commands/analyze-utils.js +541 -0
- package/dist/commands/analyze-utils.js.map +1 -0
- package/dist/commands/analyze.d.ts +15 -0
- package/dist/commands/analyze.d.ts.map +1 -0
- package/dist/commands/analyze.js +265 -0
- package/dist/commands/analyze.js.map +1 -0
- package/dist/commands/backfill.d.ts +22 -0
- package/dist/commands/backfill.d.ts.map +1 -0
- package/dist/commands/backfill.js +62 -0
- package/dist/commands/backfill.js.map +1 -0
- package/dist/commands/benchmark-quality.d.ts +18 -0
- package/dist/commands/benchmark-quality.d.ts.map +1 -0
- package/dist/commands/benchmark-quality.js +316 -0
- package/dist/commands/benchmark-quality.js.map +1 -0
- package/dist/commands/benchmark-sqlite-vec.d.ts +12 -0
- package/dist/commands/benchmark-sqlite-vec.d.ts.map +1 -0
- package/dist/commands/benchmark-sqlite-vec.js +281 -0
- package/dist/commands/benchmark-sqlite-vec.js.map +1 -0
- package/dist/commands/benchmark.d.ts +57 -0
- package/dist/commands/benchmark.d.ts.map +1 -0
- package/dist/commands/benchmark.js +682 -0
- package/dist/commands/benchmark.js.map +1 -0
- package/dist/commands/chat.d.ts +14 -0
- package/dist/commands/chat.d.ts.map +1 -0
- package/dist/commands/chat.js +84 -0
- package/dist/commands/chat.js.map +1 -0
- package/dist/commands/checkpoint.d.ts +27 -0
- package/dist/commands/checkpoint.d.ts.map +1 -0
- package/dist/commands/checkpoint.js +181 -0
- package/dist/commands/checkpoint.js.map +1 -0
- package/dist/commands/clear.d.ts +9 -0
- package/dist/commands/clear.d.ts.map +1 -0
- package/dist/commands/clear.js +31 -0
- package/dist/commands/clear.js.map +1 -0
- package/dist/commands/config.d.ts +26 -0
- package/dist/commands/config.d.ts.map +1 -0
- package/dist/commands/config.js +247 -0
- package/dist/commands/config.js.map +1 -0
- package/dist/commands/consolidate.d.ts +21 -0
- package/dist/commands/consolidate.d.ts.map +1 -0
- package/dist/commands/consolidate.js +117 -0
- package/dist/commands/consolidate.js.map +1 -0
- package/dist/commands/daemon.d.ts +48 -0
- package/dist/commands/daemon.d.ts.map +1 -0
- package/dist/commands/daemon.js +218 -0
- package/dist/commands/daemon.js.map +1 -0
- package/dist/commands/embedding.d.ts +26 -0
- package/dist/commands/embedding.d.ts.map +1 -0
- package/dist/commands/embedding.js +168 -0
- package/dist/commands/embedding.js.map +1 -0
- package/dist/commands/graph.d.ts +20 -0
- package/dist/commands/graph.d.ts.map +1 -0
- package/dist/commands/graph.js +128 -0
- package/dist/commands/graph.js.map +1 -0
- package/dist/commands/index-code.d.ts +23 -0
- package/dist/commands/index-code.d.ts.map +1 -0
- package/dist/commands/index-code.js +218 -0
- package/dist/commands/index-code.js.map +1 -0
- package/dist/commands/index.d.ts +23 -0
- package/dist/commands/index.d.ts.map +1 -0
- package/dist/commands/index.js +217 -0
- package/dist/commands/index.js.map +1 -0
- package/dist/commands/init-templates.d.ts +21 -0
- package/dist/commands/init-templates.d.ts.map +1 -0
- package/dist/commands/init-templates.js +487 -0
- package/dist/commands/init-templates.js.map +1 -0
- package/dist/commands/init.d.ts +10 -0
- package/dist/commands/init.d.ts.map +1 -0
- package/dist/commands/init.js +865 -0
- package/dist/commands/init.js.map +1 -0
- package/dist/commands/memories.d.ts +47 -0
- package/dist/commands/memories.d.ts.map +1 -0
- package/dist/commands/memories.js +597 -0
- package/dist/commands/memories.js.map +1 -0
- package/dist/commands/migrate.d.ts +19 -0
- package/dist/commands/migrate.d.ts.map +1 -0
- package/dist/commands/migrate.js +154 -0
- package/dist/commands/migrate.js.map +1 -0
- package/dist/commands/prd.d.ts +46 -0
- package/dist/commands/prd.d.ts.map +1 -0
- package/dist/commands/prd.js +378 -0
- package/dist/commands/prd.js.map +1 -0
- package/dist/commands/precompute-context.d.ts +11 -0
- package/dist/commands/precompute-context.d.ts.map +1 -0
- package/dist/commands/precompute-context.js +12 -0
- package/dist/commands/precompute-context.js.map +1 -0
- package/dist/commands/progress.d.ts +16 -0
- package/dist/commands/progress.d.ts.map +1 -0
- package/dist/commands/progress.js +38 -0
- package/dist/commands/progress.js.map +1 -0
- package/dist/commands/reindex.d.ts +17 -0
- package/dist/commands/reindex.d.ts.map +1 -0
- package/dist/commands/reindex.js +83 -0
- package/dist/commands/reindex.js.map +1 -0
- package/dist/commands/retention.d.ts +19 -0
- package/dist/commands/retention.d.ts.map +1 -0
- package/dist/commands/retention.js +162 -0
- package/dist/commands/retention.js.map +1 -0
- package/dist/commands/score.d.ts +10 -0
- package/dist/commands/score.d.ts.map +1 -0
- package/dist/commands/score.js +28 -0
- package/dist/commands/score.js.map +1 -0
- package/dist/commands/search.d.ts +7 -0
- package/dist/commands/search.d.ts.map +1 -0
- package/dist/commands/search.js +89 -0
- package/dist/commands/search.js.map +1 -0
- package/dist/commands/session-summary.d.ts +15 -0
- package/dist/commands/session-summary.d.ts.map +1 -0
- package/dist/commands/session-summary.js +16 -0
- package/dist/commands/session-summary.js.map +1 -0
- package/dist/commands/setup.d.ts +6 -0
- package/dist/commands/setup.d.ts.map +1 -0
- package/dist/commands/setup.js +222 -0
- package/dist/commands/setup.js.map +1 -0
- package/dist/commands/soul.d.ts +9 -0
- package/dist/commands/soul.d.ts.map +1 -0
- package/dist/commands/soul.js +256 -0
- package/dist/commands/soul.js.map +1 -0
- package/dist/commands/stats.d.ts +18 -0
- package/dist/commands/stats.d.ts.map +1 -0
- package/dist/commands/stats.js +138 -0
- package/dist/commands/stats.js.map +1 -0
- package/dist/commands/status.d.ts +2 -0
- package/dist/commands/status.d.ts.map +1 -0
- package/dist/commands/status.js +145 -0
- package/dist/commands/status.js.map +1 -0
- package/dist/commands/train-bpe.d.ts +8 -0
- package/dist/commands/train-bpe.d.ts.map +1 -0
- package/dist/commands/train-bpe.js +35 -0
- package/dist/commands/train-bpe.js.map +1 -0
- package/dist/commands/watch.d.ts +22 -0
- package/dist/commands/watch.d.ts.map +1 -0
- package/dist/commands/watch.js +171 -0
- package/dist/commands/watch.js.map +1 -0
- package/dist/daemon/analyzer.d.ts +54 -0
- package/dist/daemon/analyzer.d.ts.map +1 -0
- package/dist/daemon/analyzer.js +362 -0
- package/dist/daemon/analyzer.js.map +1 -0
- package/dist/daemon/client.d.ts +87 -0
- package/dist/daemon/client.d.ts.map +1 -0
- package/dist/daemon/client.js +356 -0
- package/dist/daemon/client.js.map +1 -0
- package/dist/daemon/index.d.ts +12 -0
- package/dist/daemon/index.d.ts.map +1 -0
- package/dist/daemon/index.js +12 -0
- package/dist/daemon/index.js.map +1 -0
- package/dist/daemon/service.d.ts +51 -0
- package/dist/daemon/service.d.ts.map +1 -0
- package/dist/daemon/service.js +1203 -0
- package/dist/daemon/service.js.map +1 -0
- package/dist/daemon/session-processor.d.ts +85 -0
- package/dist/daemon/session-processor.d.ts.map +1 -0
- package/dist/daemon/session-processor.js +571 -0
- package/dist/daemon/session-processor.js.map +1 -0
- package/dist/daemon/sessions.d.ts +62 -0
- package/dist/daemon/sessions.d.ts.map +1 -0
- package/dist/daemon/sessions.js +192 -0
- package/dist/daemon/sessions.js.map +1 -0
- package/dist/daemon/watcher.d.ts +52 -0
- package/dist/daemon/watcher.d.ts.map +1 -0
- package/dist/daemon/watcher.js +363 -0
- package/dist/daemon/watcher.js.map +1 -0
- package/dist/lib/agents-md-generator.d.ts +33 -0
- package/dist/lib/agents-md-generator.d.ts.map +1 -0
- package/dist/lib/agents-md-generator.js +156 -0
- package/dist/lib/agents-md-generator.js.map +1 -0
- package/dist/lib/ai-readiness.d.ts +132 -0
- package/dist/lib/ai-readiness.d.ts.map +1 -0
- package/dist/lib/ai-readiness.js +702 -0
- package/dist/lib/ai-readiness.js.map +1 -0
- package/dist/lib/analyze-state.d.ts +34 -0
- package/dist/lib/analyze-state.d.ts.map +1 -0
- package/dist/lib/analyze-state.js +106 -0
- package/dist/lib/analyze-state.js.map +1 -0
- package/dist/lib/benchmark.d.ts +250 -0
- package/dist/lib/benchmark.d.ts.map +1 -0
- package/dist/lib/benchmark.js +778 -0
- package/dist/lib/benchmark.js.map +1 -0
- package/dist/lib/bm25.d.ts +114 -0
- package/dist/lib/bm25.d.ts.map +1 -0
- package/dist/lib/bm25.js +727 -0
- package/dist/lib/bm25.js.map +1 -0
- package/dist/lib/bpe.d.ts +70 -0
- package/dist/lib/bpe.d.ts.map +1 -0
- package/dist/lib/bpe.js +270 -0
- package/dist/lib/bpe.js.map +1 -0
- package/dist/lib/checkpoint.d.ts +124 -0
- package/dist/lib/checkpoint.d.ts.map +1 -0
- package/dist/lib/checkpoint.js +321 -0
- package/dist/lib/checkpoint.js.map +1 -0
- package/dist/lib/chunker.d.ts +47 -0
- package/dist/lib/chunker.d.ts.map +1 -0
- package/dist/lib/chunker.js +358 -0
- package/dist/lib/chunker.js.map +1 -0
- package/dist/lib/claude-ws-transport.d.ts +76 -0
- package/dist/lib/claude-ws-transport.d.ts.map +1 -0
- package/dist/lib/claude-ws-transport.js +487 -0
- package/dist/lib/claude-ws-transport.js.map +1 -0
- package/dist/lib/compact-briefing.d.ts +22 -0
- package/dist/lib/compact-briefing.d.ts.map +1 -0
- package/dist/lib/compact-briefing.js +180 -0
- package/dist/lib/compact-briefing.js.map +1 -0
- package/dist/lib/config-defaults.d.ts +41 -0
- package/dist/lib/config-defaults.d.ts.map +1 -0
- package/dist/lib/config-defaults.js +99 -0
- package/dist/lib/config-defaults.js.map +1 -0
- package/dist/lib/config-display.d.ts +16 -0
- package/dist/lib/config-display.d.ts.map +1 -0
- package/dist/lib/config-display.js +408 -0
- package/dist/lib/config-display.js.map +1 -0
- package/dist/lib/config-types.d.ts +601 -0
- package/dist/lib/config-types.d.ts.map +1 -0
- package/dist/lib/config-types.js +7 -0
- package/dist/lib/config-types.js.map +1 -0
- package/dist/lib/config-validation.d.ts +19 -0
- package/dist/lib/config-validation.d.ts.map +1 -0
- package/dist/lib/config-validation.js +136 -0
- package/dist/lib/config-validation.js.map +1 -0
- package/dist/lib/config.d.ts +143 -0
- package/dist/lib/config.d.ts.map +1 -0
- package/dist/lib/config.js +689 -0
- package/dist/lib/config.js.map +1 -0
- package/dist/lib/consolidate.d.ts +115 -0
- package/dist/lib/consolidate.d.ts.map +1 -0
- package/dist/lib/consolidate.js +600 -0
- package/dist/lib/consolidate.js.map +1 -0
- package/dist/lib/db/bm25-indexes.d.ts +58 -0
- package/dist/lib/db/bm25-indexes.d.ts.map +1 -0
- package/dist/lib/db/bm25-indexes.js +333 -0
- package/dist/lib/db/bm25-indexes.js.map +1 -0
- package/dist/lib/db/bpe.d.ts +18 -0
- package/dist/lib/db/bpe.d.ts.map +1 -0
- package/dist/lib/db/bpe.js +44 -0
- package/dist/lib/db/bpe.js.map +1 -0
- package/dist/lib/db/connection.d.ts +47 -0
- package/dist/lib/db/connection.d.ts.map +1 -0
- package/dist/lib/db/connection.js +114 -0
- package/dist/lib/db/connection.js.map +1 -0
- package/dist/lib/db/documents.d.ts +58 -0
- package/dist/lib/db/documents.d.ts.map +1 -0
- package/dist/lib/db/documents.js +374 -0
- package/dist/lib/db/documents.js.map +1 -0
- package/dist/lib/db/file-hash.d.ts +26 -0
- package/dist/lib/db/file-hash.d.ts.map +1 -0
- package/dist/lib/db/file-hash.js +56 -0
- package/dist/lib/db/file-hash.js.map +1 -0
- package/dist/lib/db/global-memories.d.ts +62 -0
- package/dist/lib/db/global-memories.d.ts.map +1 -0
- package/dist/lib/db/global-memories.js +173 -0
- package/dist/lib/db/global-memories.js.map +1 -0
- package/dist/lib/db/graph.d.ts +163 -0
- package/dist/lib/db/graph.d.ts.map +1 -0
- package/dist/lib/db/graph.js +488 -0
- package/dist/lib/db/graph.js.map +1 -0
- package/dist/lib/db/helpers.d.ts +13 -0
- package/dist/lib/db/helpers.d.ts.map +1 -0
- package/dist/lib/db/helpers.js +21 -0
- package/dist/lib/db/helpers.js.map +1 -0
- package/dist/lib/db/hybrid-search.d.ts +64 -0
- package/dist/lib/db/hybrid-search.d.ts.map +1 -0
- package/dist/lib/db/hybrid-search.js +549 -0
- package/dist/lib/db/hybrid-search.js.map +1 -0
- package/dist/lib/db/index.d.ts +23 -0
- package/dist/lib/db/index.d.ts.map +1 -0
- package/dist/lib/db/index.js +23 -0
- package/dist/lib/db/index.js.map +1 -0
- package/dist/lib/db/memories.d.ts +174 -0
- package/dist/lib/db/memories.d.ts.map +1 -0
- package/dist/lib/db/memories.js +866 -0
- package/dist/lib/db/memories.js.map +1 -0
- package/dist/lib/db/retention.d.ts +64 -0
- package/dist/lib/db/retention.d.ts.map +1 -0
- package/dist/lib/db/retention.js +115 -0
- package/dist/lib/db/retention.js.map +1 -0
- package/dist/lib/db/schema.d.ts +29 -0
- package/dist/lib/db/schema.d.ts.map +1 -0
- package/dist/lib/db/schema.js +832 -0
- package/dist/lib/db/schema.js.map +1 -0
- package/dist/lib/db/skills.d.ts +65 -0
- package/dist/lib/db/skills.d.ts.map +1 -0
- package/dist/lib/db/skills.js +119 -0
- package/dist/lib/db/skills.js.map +1 -0
- package/dist/lib/db/token-frequency.d.ts +34 -0
- package/dist/lib/db/token-frequency.d.ts.map +1 -0
- package/dist/lib/db/token-frequency.js +92 -0
- package/dist/lib/db/token-frequency.js.map +1 -0
- package/dist/lib/db/token-stats.d.ts +43 -0
- package/dist/lib/db/token-stats.d.ts.map +1 -0
- package/dist/lib/db/token-stats.js +59 -0
- package/dist/lib/db/token-stats.js.map +1 -0
- package/dist/lib/db/types.d.ts +57 -0
- package/dist/lib/db/types.d.ts.map +1 -0
- package/dist/lib/db/types.js +5 -0
- package/dist/lib/db/types.js.map +1 -0
- package/dist/lib/db/web-search-history.d.ts +22 -0
- package/dist/lib/db/web-search-history.d.ts.map +1 -0
- package/dist/lib/db/web-search-history.js +107 -0
- package/dist/lib/db/web-search-history.js.map +1 -0
- package/dist/lib/debug/state.d.ts +17 -0
- package/dist/lib/debug/state.d.ts.map +1 -0
- package/dist/lib/debug/state.js +131 -0
- package/dist/lib/debug/state.js.map +1 -0
- package/dist/lib/debug/types.d.ts +74 -0
- package/dist/lib/debug/types.d.ts.map +1 -0
- package/dist/lib/debug/types.js +85 -0
- package/dist/lib/debug/types.js.map +1 -0
- package/dist/lib/embedding-pool.d.ts +37 -0
- package/dist/lib/embedding-pool.d.ts.map +1 -0
- package/dist/lib/embedding-pool.js +159 -0
- package/dist/lib/embedding-pool.js.map +1 -0
- package/dist/lib/embedding-worker.d.ts +7 -0
- package/dist/lib/embedding-worker.d.ts.map +1 -0
- package/dist/lib/embedding-worker.js +49 -0
- package/dist/lib/embedding-worker.js.map +1 -0
- package/dist/lib/embeddings.d.ts +54 -0
- package/dist/lib/embeddings.d.ts.map +1 -0
- package/dist/lib/embeddings.js +437 -0
- package/dist/lib/embeddings.js.map +1 -0
- package/dist/lib/errors.d.ts +40 -0
- package/dist/lib/errors.d.ts.map +1 -0
- package/dist/lib/errors.js +66 -0
- package/dist/lib/errors.js.map +1 -0
- package/dist/lib/fault-logger.d.ts +35 -0
- package/dist/lib/fault-logger.d.ts.map +1 -0
- package/dist/lib/fault-logger.js +182 -0
- package/dist/lib/fault-logger.js.map +1 -0
- package/dist/lib/graph/centrality.d.ts +34 -0
- package/dist/lib/graph/centrality.d.ts.map +1 -0
- package/dist/lib/graph/centrality.js +76 -0
- package/dist/lib/graph/centrality.js.map +1 -0
- package/dist/lib/graph/cleanup.d.ts +36 -0
- package/dist/lib/graph/cleanup.d.ts.map +1 -0
- package/dist/lib/graph/cleanup.js +96 -0
- package/dist/lib/graph/cleanup.js.map +1 -0
- package/dist/lib/graph/community-detection.d.ts +61 -0
- package/dist/lib/graph/community-detection.d.ts.map +1 -0
- package/dist/lib/graph/community-detection.js +218 -0
- package/dist/lib/graph/community-detection.js.map +1 -0
- package/dist/lib/graph/contextual-proximity.d.ts +41 -0
- package/dist/lib/graph/contextual-proximity.d.ts.map +1 -0
- package/dist/lib/graph/contextual-proximity.js +125 -0
- package/dist/lib/graph/contextual-proximity.js.map +1 -0
- package/dist/lib/graph/llm-relations.d.ts +54 -0
- package/dist/lib/graph/llm-relations.d.ts.map +1 -0
- package/dist/lib/graph/llm-relations.js +265 -0
- package/dist/lib/graph/llm-relations.js.map +1 -0
- package/dist/lib/graph-export.d.ts +13 -0
- package/dist/lib/graph-export.d.ts.map +1 -0
- package/dist/lib/graph-export.js +637 -0
- package/dist/lib/graph-export.js.map +1 -0
- package/dist/lib/graph-scheduler.d.ts +7 -0
- package/dist/lib/graph-scheduler.d.ts.map +1 -0
- package/dist/lib/graph-scheduler.js +21 -0
- package/dist/lib/graph-scheduler.js.map +1 -0
- package/dist/lib/indexer.d.ts +36 -0
- package/dist/lib/indexer.d.ts.map +1 -0
- package/dist/lib/indexer.js +226 -0
- package/dist/lib/indexer.js.map +1 -0
- package/dist/lib/learning-delta.d.ts +35 -0
- package/dist/lib/learning-delta.d.ts.map +1 -0
- package/dist/lib/learning-delta.js +53 -0
- package/dist/lib/learning-delta.js.map +1 -0
- package/dist/lib/llm.d.ts +118 -0
- package/dist/lib/llm.d.ts.map +1 -0
- package/dist/lib/llm.js +439 -0
- package/dist/lib/llm.js.map +1 -0
- package/dist/lib/lock.d.ts +27 -0
- package/dist/lib/lock.d.ts.map +1 -0
- package/dist/lib/lock.js +143 -0
- package/dist/lib/lock.js.map +1 -0
- package/dist/lib/md-fetch.d.ts +61 -0
- package/dist/lib/md-fetch.d.ts.map +1 -0
- package/dist/lib/md-fetch.js +141 -0
- package/dist/lib/md-fetch.js.map +1 -0
- package/dist/lib/mmr.d.ts +29 -0
- package/dist/lib/mmr.d.ts.map +1 -0
- package/dist/lib/mmr.js +89 -0
- package/dist/lib/mmr.js.map +1 -0
- package/dist/lib/onboarding/ai-chat.d.ts +11 -0
- package/dist/lib/onboarding/ai-chat.d.ts.map +1 -0
- package/dist/lib/onboarding/ai-chat.js +85 -0
- package/dist/lib/onboarding/ai-chat.js.map +1 -0
- package/dist/lib/onboarding/index.d.ts +7 -0
- package/dist/lib/onboarding/index.d.ts.map +1 -0
- package/dist/lib/onboarding/index.js +7 -0
- package/dist/lib/onboarding/index.js.map +1 -0
- package/dist/lib/onboarding/wizard.d.ts +11 -0
- package/dist/lib/onboarding/wizard.d.ts.map +1 -0
- package/dist/lib/onboarding/wizard.js +104 -0
- package/dist/lib/onboarding/wizard.js.map +1 -0
- package/dist/lib/ort-provider.d.ts +27 -0
- package/dist/lib/ort-provider.d.ts.map +1 -0
- package/dist/lib/ort-provider.js +83 -0
- package/dist/lib/ort-provider.js.map +1 -0
- package/dist/lib/ort-session.d.ts +32 -0
- package/dist/lib/ort-session.d.ts.map +1 -0
- package/dist/lib/ort-session.js +227 -0
- package/dist/lib/ort-session.js.map +1 -0
- package/dist/lib/patterns.d.ts +43 -0
- package/dist/lib/patterns.d.ts.map +1 -0
- package/dist/lib/patterns.js +395 -0
- package/dist/lib/patterns.js.map +1 -0
- package/dist/lib/prd/codebase-context.d.ts +27 -0
- package/dist/lib/prd/codebase-context.d.ts.map +1 -0
- package/dist/lib/prd/codebase-context.js +420 -0
- package/dist/lib/prd/codebase-context.js.map +1 -0
- package/dist/lib/prd/context.d.ts +24 -0
- package/dist/lib/prd/context.d.ts.map +1 -0
- package/dist/lib/prd/context.js +68 -0
- package/dist/lib/prd/context.js.map +1 -0
- package/dist/lib/prd/executor.d.ts +52 -0
- package/dist/lib/prd/executor.d.ts.map +1 -0
- package/dist/lib/prd/executor.js +154 -0
- package/dist/lib/prd/executor.js.map +1 -0
- package/dist/lib/prd/export.d.ts +40 -0
- package/dist/lib/prd/export.d.ts.map +1 -0
- package/dist/lib/prd/export.js +511 -0
- package/dist/lib/prd/export.js.map +1 -0
- package/dist/lib/prd/gates.d.ts +30 -0
- package/dist/lib/prd/gates.d.ts.map +1 -0
- package/dist/lib/prd/gates.js +100 -0
- package/dist/lib/prd/gates.js.map +1 -0
- package/dist/lib/prd/generate.d.ts +56 -0
- package/dist/lib/prd/generate.d.ts.map +1 -0
- package/dist/lib/prd/generate.js +357 -0
- package/dist/lib/prd/generate.js.map +1 -0
- package/dist/lib/prd/parse.d.ts +21 -0
- package/dist/lib/prd/parse.d.ts.map +1 -0
- package/dist/lib/prd/parse.js +270 -0
- package/dist/lib/prd/parse.js.map +1 -0
- package/dist/lib/prd/prompt-builder.d.ts +18 -0
- package/dist/lib/prd/prompt-builder.d.ts.map +1 -0
- package/dist/lib/prd/prompt-builder.js +61 -0
- package/dist/lib/prd/prompt-builder.js.map +1 -0
- package/dist/lib/prd/runner.d.ts +54 -0
- package/dist/lib/prd/runner.d.ts.map +1 -0
- package/dist/lib/prd/runner.js +563 -0
- package/dist/lib/prd/runner.js.map +1 -0
- package/dist/lib/prd/scheduler.d.ts +27 -0
- package/dist/lib/prd/scheduler.d.ts.map +1 -0
- package/dist/lib/prd/scheduler.js +113 -0
- package/dist/lib/prd/scheduler.js.map +1 -0
- package/dist/lib/prd/state.d.ts +77 -0
- package/dist/lib/prd/state.d.ts.map +1 -0
- package/dist/lib/prd/state.js +253 -0
- package/dist/lib/prd/state.js.map +1 -0
- package/dist/lib/prd/team-runner.d.ts +48 -0
- package/dist/lib/prd/team-runner.d.ts.map +1 -0
- package/dist/lib/prd/team-runner.js +261 -0
- package/dist/lib/prd/team-runner.js.map +1 -0
- package/dist/lib/prd/types.d.ts +169 -0
- package/dist/lib/prd/types.d.ts.map +1 -0
- package/dist/lib/prd/types.js +143 -0
- package/dist/lib/prd/types.js.map +1 -0
- package/dist/lib/prd/worktree.d.ts +54 -0
- package/dist/lib/prd/worktree.d.ts.map +1 -0
- package/dist/lib/prd/worktree.js +255 -0
- package/dist/lib/prd/worktree.js.map +1 -0
- package/dist/lib/precompute-context.d.ts +48 -0
- package/dist/lib/precompute-context.d.ts.map +1 -0
- package/dist/lib/precompute-context.js +265 -0
- package/dist/lib/precompute-context.js.map +1 -0
- package/dist/lib/pricing.d.ts +60 -0
- package/dist/lib/pricing.d.ts.map +1 -0
- package/dist/lib/pricing.js +258 -0
- package/dist/lib/pricing.js.map +1 -0
- package/dist/lib/process-registry.d.ts +30 -0
- package/dist/lib/process-registry.d.ts.map +1 -0
- package/dist/lib/process-registry.js +92 -0
- package/dist/lib/process-registry.js.map +1 -0
- package/dist/lib/progress-log.d.ts +44 -0
- package/dist/lib/progress-log.d.ts.map +1 -0
- package/dist/lib/progress-log.js +58 -0
- package/dist/lib/progress-log.js.map +1 -0
- package/dist/lib/public-api.d.ts +56 -0
- package/dist/lib/public-api.d.ts.map +1 -0
- package/dist/lib/public-api.js +63 -0
- package/dist/lib/public-api.js.map +1 -0
- package/dist/lib/quality.d.ts +66 -0
- package/dist/lib/quality.d.ts.map +1 -0
- package/dist/lib/quality.js +486 -0
- package/dist/lib/quality.js.map +1 -0
- package/dist/lib/query-expansion.d.ts +16 -0
- package/dist/lib/query-expansion.d.ts.map +1 -0
- package/dist/lib/query-expansion.js +53 -0
- package/dist/lib/query-expansion.js.map +1 -0
- package/dist/lib/readiness.d.ts +35 -0
- package/dist/lib/readiness.d.ts.map +1 -0
- package/dist/lib/readiness.js +142 -0
- package/dist/lib/readiness.js.map +1 -0
- package/dist/lib/reference-embeddings.d.ts +39 -0
- package/dist/lib/reference-embeddings.d.ts.map +1 -0
- package/dist/lib/reference-embeddings.js +95 -0
- package/dist/lib/reference-embeddings.js.map +1 -0
- package/dist/lib/reflection-synthesizer.d.ts +27 -0
- package/dist/lib/reflection-synthesizer.d.ts.map +1 -0
- package/dist/lib/reflection-synthesizer.js +149 -0
- package/dist/lib/reflection-synthesizer.js.map +1 -0
- package/dist/lib/retention.d.ts +105 -0
- package/dist/lib/retention.d.ts.map +1 -0
- package/dist/lib/retention.js +246 -0
- package/dist/lib/retention.js.map +1 -0
- package/dist/lib/sensitive-filter.d.ts +34 -0
- package/dist/lib/sensitive-filter.d.ts.map +1 -0
- package/dist/lib/sensitive-filter.js +344 -0
- package/dist/lib/sensitive-filter.js.map +1 -0
- package/dist/lib/session-observations.d.ts +59 -0
- package/dist/lib/session-observations.d.ts.map +1 -0
- package/dist/lib/session-observations.js +128 -0
- package/dist/lib/session-observations.js.map +1 -0
- package/dist/lib/session-summary.d.ts +65 -0
- package/dist/lib/session-summary.d.ts.map +1 -0
- package/dist/lib/session-summary.js +344 -0
- package/dist/lib/session-summary.js.map +1 -0
- package/dist/lib/similarity-worker.d.ts +7 -0
- package/dist/lib/similarity-worker.d.ts.map +1 -0
- package/dist/lib/similarity-worker.js +36 -0
- package/dist/lib/similarity-worker.js.map +1 -0
- package/dist/lib/skills.d.ts +78 -0
- package/dist/lib/skills.d.ts.map +1 -0
- package/dist/lib/skills.js +439 -0
- package/dist/lib/skills.js.map +1 -0
- package/dist/lib/skyll-client.d.ts +59 -0
- package/dist/lib/skyll-client.d.ts.map +1 -0
- package/dist/lib/skyll-client.js +257 -0
- package/dist/lib/skyll-client.js.map +1 -0
- package/dist/lib/storage/backends/interface.d.ts +383 -0
- package/dist/lib/storage/backends/interface.d.ts.map +1 -0
- package/dist/lib/storage/backends/interface.js +12 -0
- package/dist/lib/storage/backends/interface.js.map +1 -0
- package/dist/lib/storage/backends/postgresql.d.ts +454 -0
- package/dist/lib/storage/backends/postgresql.d.ts.map +1 -0
- package/dist/lib/storage/backends/postgresql.js +2528 -0
- package/dist/lib/storage/backends/postgresql.js.map +1 -0
- package/dist/lib/storage/benchmark.d.ts +16 -0
- package/dist/lib/storage/benchmark.d.ts.map +1 -0
- package/dist/lib/storage/benchmark.js +219 -0
- package/dist/lib/storage/benchmark.js.map +1 -0
- package/dist/lib/storage/dispatcher-export.d.ts +108 -0
- package/dist/lib/storage/dispatcher-export.d.ts.map +1 -0
- package/dist/lib/storage/dispatcher-export.js +593 -0
- package/dist/lib/storage/dispatcher-export.js.map +1 -0
- package/dist/lib/storage/dispatcher.d.ts +468 -0
- package/dist/lib/storage/dispatcher.d.ts.map +1 -0
- package/dist/lib/storage/dispatcher.js +1926 -0
- package/dist/lib/storage/dispatcher.js.map +1 -0
- package/dist/lib/storage/index.d.ts +481 -0
- package/dist/lib/storage/index.d.ts.map +1 -0
- package/dist/lib/storage/index.js +727 -0
- package/dist/lib/storage/index.js.map +1 -0
- package/dist/lib/storage/migration/export-import.d.ts +133 -0
- package/dist/lib/storage/migration/export-import.d.ts.map +1 -0
- package/dist/lib/storage/migration/export-import.js +264 -0
- package/dist/lib/storage/migration/export-import.js.map +1 -0
- package/dist/lib/storage/types.d.ts +313 -0
- package/dist/lib/storage/types.d.ts.map +1 -0
- package/dist/lib/storage/types.js +30 -0
- package/dist/lib/storage/types.js.map +1 -0
- package/dist/lib/storage/vector/interface.d.ts +89 -0
- package/dist/lib/storage/vector/interface.d.ts.map +1 -0
- package/dist/lib/storage/vector/interface.js +10 -0
- package/dist/lib/storage/vector/interface.js.map +1 -0
- package/dist/lib/storage/vector/qdrant.d.ts +221 -0
- package/dist/lib/storage/vector/qdrant.d.ts.map +1 -0
- package/dist/lib/storage/vector/qdrant.js +880 -0
- package/dist/lib/storage/vector/qdrant.js.map +1 -0
- package/dist/lib/supersession.d.ts +26 -0
- package/dist/lib/supersession.d.ts.map +1 -0
- package/dist/lib/supersession.js +97 -0
- package/dist/lib/supersession.js.map +1 -0
- package/dist/lib/temporal.d.ts +140 -0
- package/dist/lib/temporal.d.ts.map +1 -0
- package/dist/lib/temporal.js +303 -0
- package/dist/lib/temporal.js.map +1 -0
- package/dist/lib/token-budget.d.ts +79 -0
- package/dist/lib/token-budget.d.ts.map +1 -0
- package/dist/lib/token-budget.js +146 -0
- package/dist/lib/token-budget.js.map +1 -0
- package/dist/lib/token-counter.d.ts +27 -0
- package/dist/lib/token-counter.d.ts.map +1 -0
- package/dist/lib/token-counter.js +52 -0
- package/dist/lib/token-counter.js.map +1 -0
- package/dist/lib/tree-sitter/chunker-ts.d.ts +24 -0
- package/dist/lib/tree-sitter/chunker-ts.d.ts.map +1 -0
- package/dist/lib/tree-sitter/chunker-ts.js +206 -0
- package/dist/lib/tree-sitter/chunker-ts.js.map +1 -0
- package/dist/lib/tree-sitter/extractor.d.ts +43 -0
- package/dist/lib/tree-sitter/extractor.d.ts.map +1 -0
- package/dist/lib/tree-sitter/extractor.js +297 -0
- package/dist/lib/tree-sitter/extractor.js.map +1 -0
- package/dist/lib/tree-sitter/index.d.ts +13 -0
- package/dist/lib/tree-sitter/index.d.ts.map +1 -0
- package/dist/lib/tree-sitter/index.js +14 -0
- package/dist/lib/tree-sitter/index.js.map +1 -0
- package/dist/lib/tree-sitter/parser.d.ts +70 -0
- package/dist/lib/tree-sitter/parser.d.ts.map +1 -0
- package/dist/lib/tree-sitter/parser.js +354 -0
- package/dist/lib/tree-sitter/parser.js.map +1 -0
- package/dist/lib/tree-sitter/public.d.ts +28 -0
- package/dist/lib/tree-sitter/public.d.ts.map +1 -0
- package/dist/lib/tree-sitter/public.js +50 -0
- package/dist/lib/tree-sitter/public.js.map +1 -0
- package/dist/lib/tree-sitter/queries.d.ts +28 -0
- package/dist/lib/tree-sitter/queries.d.ts.map +1 -0
- package/dist/lib/tree-sitter/queries.js +383 -0
- package/dist/lib/tree-sitter/queries.js.map +1 -0
- package/dist/lib/tree-sitter/types.d.ts +69 -0
- package/dist/lib/tree-sitter/types.d.ts.map +1 -0
- package/dist/lib/tree-sitter/types.js +131 -0
- package/dist/lib/tree-sitter/types.js.map +1 -0
- package/dist/lib/working-memory-pipeline.d.ts +118 -0
- package/dist/lib/working-memory-pipeline.d.ts.map +1 -0
- package/dist/lib/working-memory-pipeline.js +344 -0
- package/dist/lib/working-memory-pipeline.js.map +1 -0
- package/dist/mcp/helpers.d.ts +44 -0
- package/dist/mcp/helpers.d.ts.map +1 -0
- package/dist/mcp/helpers.js +244 -0
- package/dist/mcp/helpers.js.map +1 -0
- package/dist/mcp/index.d.ts +10 -0
- package/dist/mcp/index.d.ts.map +1 -0
- package/dist/mcp/index.js +15 -0
- package/dist/mcp/index.js.map +1 -0
- package/dist/mcp/resources.d.ts +12 -0
- package/dist/mcp/resources.d.ts.map +1 -0
- package/dist/mcp/resources.js +136 -0
- package/dist/mcp/resources.js.map +1 -0
- package/dist/mcp/server.d.ts +22 -0
- package/dist/mcp/server.d.ts.map +1 -0
- package/dist/mcp/server.js +131 -0
- package/dist/mcp/server.js.map +1 -0
- package/dist/mcp/tools/config.d.ts +10 -0
- package/dist/mcp/tools/config.d.ts.map +1 -0
- package/dist/mcp/tools/config.js +236 -0
- package/dist/mcp/tools/config.js.map +1 -0
- package/dist/mcp/tools/dead-end.d.ts +9 -0
- package/dist/mcp/tools/dead-end.d.ts.map +1 -0
- package/dist/mcp/tools/dead-end.js +137 -0
- package/dist/mcp/tools/dead-end.js.map +1 -0
- package/dist/mcp/tools/debug.d.ts +9 -0
- package/dist/mcp/tools/debug.d.ts.map +1 -0
- package/dist/mcp/tools/debug.js +387 -0
- package/dist/mcp/tools/debug.js.map +1 -0
- package/dist/mcp/tools/graph.d.ts +9 -0
- package/dist/mcp/tools/graph.d.ts.map +1 -0
- package/dist/mcp/tools/graph.js +337 -0
- package/dist/mcp/tools/graph.js.map +1 -0
- package/dist/mcp/tools/indexing.d.ts +12 -0
- package/dist/mcp/tools/indexing.d.ts.map +1 -0
- package/dist/mcp/tools/indexing.js +289 -0
- package/dist/mcp/tools/indexing.js.map +1 -0
- package/dist/mcp/tools/memory.d.ts +14 -0
- package/dist/mcp/tools/memory.d.ts.map +1 -0
- package/dist/mcp/tools/memory.js +1170 -0
- package/dist/mcp/tools/memory.js.map +1 -0
- package/dist/mcp/tools/prd.d.ts +12 -0
- package/dist/mcp/tools/prd.d.ts.map +1 -0
- package/dist/mcp/tools/prd.js +276 -0
- package/dist/mcp/tools/prd.js.map +1 -0
- package/dist/mcp/tools/search.d.ts +9 -0
- package/dist/mcp/tools/search.d.ts.map +1 -0
- package/dist/mcp/tools/search.js +279 -0
- package/dist/mcp/tools/search.js.map +1 -0
- package/dist/mcp/tools/status.d.ts +10 -0
- package/dist/mcp/tools/status.d.ts.map +1 -0
- package/dist/mcp/tools/status.js +296 -0
- package/dist/mcp/tools/status.js.map +1 -0
- package/dist/mcp/tools/web-fetch.d.ts +10 -0
- package/dist/mcp/tools/web-fetch.d.ts.map +1 -0
- package/dist/mcp/tools/web-fetch.js +107 -0
- package/dist/mcp/tools/web-fetch.js.map +1 -0
- package/dist/mcp/tools/web-search.d.ts +14 -0
- package/dist/mcp/tools/web-search.d.ts.map +1 -0
- package/dist/mcp/tools/web-search.js +427 -0
- package/dist/mcp/tools/web-search.js.map +1 -0
- package/dist/mcp/types.d.ts +16 -0
- package/dist/mcp/types.d.ts.map +1 -0
- package/dist/mcp/types.js +5 -0
- package/dist/mcp/types.js.map +1 -0
- package/dist/mcp-server.d.ts +9 -0
- package/dist/mcp-server.d.ts.map +1 -0
- package/dist/mcp-server.js +9 -0
- package/dist/mcp-server.js.map +1 -0
- package/dist/prompts/analyze.d.ts +21 -0
- package/dist/prompts/analyze.d.ts.map +1 -0
- package/dist/prompts/analyze.js +27 -0
- package/dist/prompts/analyze.js.map +1 -0
- package/dist/prompts/briefing.d.ts +27 -0
- package/dist/prompts/briefing.d.ts.map +1 -0
- package/dist/prompts/briefing.js +123 -0
- package/dist/prompts/briefing.js.map +1 -0
- package/dist/prompts/chat.d.ts +8 -0
- package/dist/prompts/chat.d.ts.map +1 -0
- package/dist/prompts/chat.js +39 -0
- package/dist/prompts/chat.js.map +1 -0
- package/dist/prompts/daemon.d.ts +16 -0
- package/dist/prompts/daemon.d.ts.map +1 -0
- package/dist/prompts/daemon.js +46 -0
- package/dist/prompts/daemon.js.map +1 -0
- package/dist/prompts/extraction.d.ts +13 -0
- package/dist/prompts/extraction.d.ts.map +1 -0
- package/dist/prompts/extraction.js +93 -0
- package/dist/prompts/extraction.js.map +1 -0
- package/dist/prompts/index.d.ts +17 -0
- package/dist/prompts/index.d.ts.map +1 -0
- package/dist/prompts/index.js +27 -0
- package/dist/prompts/index.js.map +1 -0
- package/dist/prompts/memory.d.ts +11 -0
- package/dist/prompts/memory.d.ts.map +1 -0
- package/dist/prompts/memory.js +23 -0
- package/dist/prompts/memory.js.map +1 -0
- package/dist/prompts/onboarding.d.ts +16 -0
- package/dist/prompts/onboarding.d.ts.map +1 -0
- package/dist/prompts/onboarding.js +183 -0
- package/dist/prompts/onboarding.js.map +1 -0
- package/dist/prompts/prd.d.ts +12 -0
- package/dist/prompts/prd.d.ts.map +1 -0
- package/dist/prompts/prd.js +211 -0
- package/dist/prompts/prd.js.map +1 -0
- package/dist/prompts/quality.d.ts +11 -0
- package/dist/prompts/quality.d.ts.map +1 -0
- package/dist/prompts/quality.js +11 -0
- package/dist/prompts/quality.js.map +1 -0
- package/dist/prompts/skills.d.ts +16 -0
- package/dist/prompts/skills.d.ts.map +1 -0
- package/dist/prompts/skills.js +30 -0
- package/dist/prompts/skills.js.map +1 -0
- package/hooks/succ-post-tool.cjs +227 -0
- package/hooks/succ-pre-tool.cjs +312 -0
- package/hooks/succ-session-end.cjs +85 -0
- package/hooks/succ-session-start.cjs +618 -0
- package/hooks/succ-stop-reflection.cjs +87 -0
- package/hooks/succ-user-prompt.cjs +220 -0
- package/package.json +128 -0
|
@@ -0,0 +1,866 @@
|
|
|
1
|
+
import fs from 'fs';
|
|
2
|
+
import path from 'path';
|
|
3
|
+
import { getDb, cachedPrepare } from './connection.js';
|
|
4
|
+
import { sqliteVecAvailable } from './schema.js';
|
|
5
|
+
import { bufferToFloatArray, floatArrayToBuffer } from './helpers.js';
|
|
6
|
+
import { logWarn } from '../fault-logger.js';
|
|
7
|
+
import { cosineSimilarity } from '../embeddings.js';
|
|
8
|
+
import { triggerAutoExport } from '../graph-scheduler.js';
|
|
9
|
+
import { getSuccDir, getConfig } from '../config.js';
|
|
10
|
+
import { invalidateMemoriesBm25Index } from './bm25-indexes.js';
|
|
11
|
+
import { createMemoryLink } from './graph.js';
|
|
12
|
+
/** Parse JSON tags column, returning empty array on null/invalid. */
|
|
13
|
+
function parseTags(raw) {
|
|
14
|
+
if (!raw)
|
|
15
|
+
return [];
|
|
16
|
+
try {
|
|
17
|
+
return JSON.parse(raw);
|
|
18
|
+
}
|
|
19
|
+
catch {
|
|
20
|
+
return [];
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
/**
|
|
24
|
+
* Log memory deletion events to .succ/memory-audit.log for debugging.
|
|
25
|
+
* Format: [ISO timestamp] [DELETE] caller | count=N | ids=[...] | reason
|
|
26
|
+
*/
|
|
27
|
+
function logDeletion(caller, count, ids, reason) {
|
|
28
|
+
try {
|
|
29
|
+
const succDir = getSuccDir();
|
|
30
|
+
const logFile = path.join(succDir, 'memory-audit.log');
|
|
31
|
+
const timestamp = new Date().toISOString();
|
|
32
|
+
const idStr = ids.length <= 20 ? ids.join(',') : `${ids.slice(0, 20).join(',')}... (${ids.length} total)`;
|
|
33
|
+
const reasonStr = reason ? ` | ${reason}` : '';
|
|
34
|
+
const line = `[${timestamp}] [DELETE] ${caller} | count=${count} | ids=[${idStr}]${reasonStr}\n`;
|
|
35
|
+
fs.promises.appendFile(logFile, line).catch(() => { });
|
|
36
|
+
}
|
|
37
|
+
catch {
|
|
38
|
+
// Never let audit logging break actual operations
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
/**
|
|
42
|
+
* Check if a similar memory already exists (semantic deduplication)
|
|
43
|
+
* Returns the existing memory ID if found, null otherwise
|
|
44
|
+
*/
|
|
45
|
+
export function findSimilarMemory(embedding, threshold = 0.92 // High threshold for near-duplicates
|
|
46
|
+
) {
|
|
47
|
+
const database = getDb();
|
|
48
|
+
// Try sqlite-vec KNN fast path
|
|
49
|
+
if (sqliteVecAvailable) {
|
|
50
|
+
try {
|
|
51
|
+
const queryBuffer = floatArrayToBuffer(embedding);
|
|
52
|
+
const vecResults = database
|
|
53
|
+
.prepare(`
|
|
54
|
+
SELECT m.memory_id, v.distance
|
|
55
|
+
FROM vec_memories v
|
|
56
|
+
JOIN vec_memories_map m ON m.vec_rowid = v.rowid
|
|
57
|
+
WHERE v.embedding MATCH ?
|
|
58
|
+
AND k = 5
|
|
59
|
+
ORDER BY v.distance
|
|
60
|
+
`)
|
|
61
|
+
.all(queryBuffer);
|
|
62
|
+
for (const result of vecResults) {
|
|
63
|
+
const similarity = 1 - result.distance;
|
|
64
|
+
if (similarity >= threshold) {
|
|
65
|
+
const memory = cachedPrepare('SELECT id, content FROM memories WHERE id = ?').get(result.memory_id);
|
|
66
|
+
if (memory) {
|
|
67
|
+
return { id: memory.id, content: memory.content, similarity };
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
return null;
|
|
72
|
+
}
|
|
73
|
+
catch (err) {
|
|
74
|
+
logWarn('memories', 'sqlite-vec KNN failed, using brute-force fallback', {
|
|
75
|
+
error: err instanceof Error ? err.message : String(err),
|
|
76
|
+
});
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
// Brute-force fallback when sqlite-vec unavailable
|
|
80
|
+
const rows = cachedPrepare('SELECT id, content, embedding FROM memories').all();
|
|
81
|
+
for (const row of rows) {
|
|
82
|
+
const existingEmbedding = bufferToFloatArray(row.embedding);
|
|
83
|
+
const similarity = cosineSimilarity(embedding, existingEmbedding);
|
|
84
|
+
if (similarity >= threshold) {
|
|
85
|
+
return { id: row.id, content: row.content, similarity };
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
return null;
|
|
89
|
+
}
|
|
90
|
+
/**
|
|
91
|
+
* Save a new memory with optional deduplication, type, quality score, auto-linking, and validity period
|
|
92
|
+
* Returns { id, isDuplicate, similarity?, linksCreated? }
|
|
93
|
+
*/
|
|
94
|
+
export function saveMemory(content, embedding, tags = [], source, options = {}) {
|
|
95
|
+
const { deduplicate = true, type = 'observation', autoLink = true, linkThreshold = 0.7, qualityScore, validFrom, validUntil, } = options;
|
|
96
|
+
// Check for duplicates if enabled
|
|
97
|
+
if (deduplicate) {
|
|
98
|
+
const existing = findSimilarMemory(embedding);
|
|
99
|
+
if (existing) {
|
|
100
|
+
return { id: existing.id, isDuplicate: true, similarity: existing.similarity };
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
const embeddingBlob = Buffer.from(new Float32Array(embedding).buffer);
|
|
104
|
+
const tagsJson = tags.length > 0 ? JSON.stringify(tags) : null;
|
|
105
|
+
const qualityFactorsJson = qualityScore?.factors ? JSON.stringify(qualityScore.factors) : null;
|
|
106
|
+
// Convert Date objects to ISO strings
|
|
107
|
+
const validFromStr = validFrom
|
|
108
|
+
? validFrom instanceof Date
|
|
109
|
+
? validFrom.toISOString()
|
|
110
|
+
: validFrom
|
|
111
|
+
: null;
|
|
112
|
+
const validUntilStr = validUntil
|
|
113
|
+
? validUntil instanceof Date
|
|
114
|
+
? validUntil.toISOString()
|
|
115
|
+
: validUntil
|
|
116
|
+
: null;
|
|
117
|
+
const result = cachedPrepare(`
|
|
118
|
+
INSERT INTO memories (content, tags, source, type, quality_score, quality_factors, valid_from, valid_until, embedding)
|
|
119
|
+
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)
|
|
120
|
+
`).run(content, tagsJson, source ?? null, type, qualityScore?.score ?? null, qualityFactorsJson, validFromStr, validUntilStr, embeddingBlob);
|
|
121
|
+
const newId = result.lastInsertRowid;
|
|
122
|
+
// Also insert into vec_memories for fast KNN search
|
|
123
|
+
if (sqliteVecAvailable) {
|
|
124
|
+
try {
|
|
125
|
+
const vecResult = cachedPrepare('INSERT INTO vec_memories(embedding) VALUES (?)').run(embeddingBlob);
|
|
126
|
+
cachedPrepare('INSERT INTO vec_memories_map(vec_rowid, memory_id) VALUES (?, ?)').run(vecResult.lastInsertRowid, newId);
|
|
127
|
+
}
|
|
128
|
+
catch (err) {
|
|
129
|
+
logWarn('memories', 'Vector insert failed for memory, semantic recall may not find it', {
|
|
130
|
+
error: err instanceof Error ? err.message : String(err),
|
|
131
|
+
});
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
let linksCreated = 0;
|
|
135
|
+
// Auto-link to similar existing memories
|
|
136
|
+
if (autoLink) {
|
|
137
|
+
linksCreated = autoLinkNewMemory(newId, embedding, linkThreshold);
|
|
138
|
+
}
|
|
139
|
+
// Async LLM enrichment of new links (fire-and-forget)
|
|
140
|
+
if (linksCreated > 0) {
|
|
141
|
+
try {
|
|
142
|
+
const conf = getConfig();
|
|
143
|
+
if (conf.graph_llm_relations?.enabled && conf.graph_llm_relations?.auto_on_save) {
|
|
144
|
+
import('../graph/llm-relations.js')
|
|
145
|
+
.then((m) => m.enrichMemoryLinks(newId))
|
|
146
|
+
.catch((err) => {
|
|
147
|
+
logWarn('memories', `LLM enrichment failed for memory ${newId}`, {
|
|
148
|
+
error: String(err),
|
|
149
|
+
});
|
|
150
|
+
});
|
|
151
|
+
}
|
|
152
|
+
}
|
|
153
|
+
catch {
|
|
154
|
+
// LLM enrichment module not available — skip
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
// Schedule auto-export if enabled (async, non-blocking)
|
|
158
|
+
if (linksCreated > 0) {
|
|
159
|
+
triggerAutoExport().catch((err) => {
|
|
160
|
+
logWarn('memories', err instanceof Error ? err.message : 'Auto-export failed');
|
|
161
|
+
});
|
|
162
|
+
}
|
|
163
|
+
// Async supersession check: detect if new memory replaces an existing one (fire-and-forget)
|
|
164
|
+
import('../supersession.js')
|
|
165
|
+
.then((m) => m.checkSupersession(newId, content, embedding))
|
|
166
|
+
.catch(() => {
|
|
167
|
+
// Supersession module not available or failed — non-critical
|
|
168
|
+
});
|
|
169
|
+
invalidateMemoriesBm25Index();
|
|
170
|
+
return { id: newId, isDuplicate: false, linksCreated };
|
|
171
|
+
}
|
|
172
|
+
/**
|
|
173
|
+
* Auto-link a new memory to existing similar memories
|
|
174
|
+
*/
|
|
175
|
+
function autoLinkNewMemory(memoryId, embedding, threshold = 0.7) {
|
|
176
|
+
const database = getDb();
|
|
177
|
+
// Try sqlite-vec KNN fast path
|
|
178
|
+
if (sqliteVecAvailable) {
|
|
179
|
+
try {
|
|
180
|
+
const queryBuffer = floatArrayToBuffer(embedding);
|
|
181
|
+
const vecResults = database
|
|
182
|
+
.prepare(`
|
|
183
|
+
SELECT m.memory_id, v.distance
|
|
184
|
+
FROM vec_memories v
|
|
185
|
+
JOIN vec_memories_map m ON m.vec_rowid = v.rowid
|
|
186
|
+
WHERE v.embedding MATCH ?
|
|
187
|
+
AND k = 10
|
|
188
|
+
ORDER BY v.distance
|
|
189
|
+
`)
|
|
190
|
+
.all(queryBuffer);
|
|
191
|
+
const similarities = [];
|
|
192
|
+
for (const result of vecResults) {
|
|
193
|
+
if (result.memory_id === memoryId)
|
|
194
|
+
continue; // exclude self
|
|
195
|
+
const similarity = 1 - result.distance;
|
|
196
|
+
if (similarity >= threshold) {
|
|
197
|
+
similarities.push({ id: result.memory_id, similarity });
|
|
198
|
+
}
|
|
199
|
+
}
|
|
200
|
+
const topSimilar = similarities.slice(0, 3);
|
|
201
|
+
let created = 0;
|
|
202
|
+
for (const { id: targetId, similarity } of topSimilar) {
|
|
203
|
+
try {
|
|
204
|
+
const result = createMemoryLink(memoryId, targetId, 'similar_to', similarity);
|
|
205
|
+
if (result.created)
|
|
206
|
+
created++;
|
|
207
|
+
}
|
|
208
|
+
catch (err) {
|
|
209
|
+
logWarn('memories', 'Auto-link creation failed', {
|
|
210
|
+
error: err instanceof Error ? err.message : String(err),
|
|
211
|
+
});
|
|
212
|
+
}
|
|
213
|
+
}
|
|
214
|
+
return created;
|
|
215
|
+
}
|
|
216
|
+
catch {
|
|
217
|
+
// Fall through to brute-force
|
|
218
|
+
}
|
|
219
|
+
}
|
|
220
|
+
// Brute-force fallback
|
|
221
|
+
const memories = cachedPrepare('SELECT id, embedding FROM memories WHERE id != ?').all(memoryId);
|
|
222
|
+
const similarities = [];
|
|
223
|
+
for (const mem of memories) {
|
|
224
|
+
const memEmbedding = bufferToFloatArray(mem.embedding);
|
|
225
|
+
const similarity = cosineSimilarity(embedding, memEmbedding);
|
|
226
|
+
if (similarity >= threshold) {
|
|
227
|
+
similarities.push({ id: mem.id, similarity });
|
|
228
|
+
}
|
|
229
|
+
}
|
|
230
|
+
similarities.sort((a, b) => b.similarity - a.similarity);
|
|
231
|
+
const topSimilar = similarities.slice(0, 3);
|
|
232
|
+
let created = 0;
|
|
233
|
+
for (const { id: targetId, similarity } of topSimilar) {
|
|
234
|
+
try {
|
|
235
|
+
const result = createMemoryLink(memoryId, targetId, 'similar_to', similarity);
|
|
236
|
+
if (result.created)
|
|
237
|
+
created++;
|
|
238
|
+
}
|
|
239
|
+
catch (err) {
|
|
240
|
+
logWarn('memories', 'Auto-link creation failed', {
|
|
241
|
+
error: err instanceof Error ? err.message : String(err),
|
|
242
|
+
});
|
|
243
|
+
}
|
|
244
|
+
}
|
|
245
|
+
return created;
|
|
246
|
+
}
|
|
247
|
+
/**
|
|
248
|
+
* Search memories by semantic similarity with temporal awareness.
|
|
249
|
+
* Uses sqlite-vec for fast KNN search when available, falls back to brute-force.
|
|
250
|
+
*/
|
|
251
|
+
export function searchMemories(queryEmbedding, limit = 5, threshold = 0.3, tags, since, options) {
|
|
252
|
+
const database = getDb();
|
|
253
|
+
const now = options?.asOfDate?.getTime() ?? Date.now();
|
|
254
|
+
const includeExpired = options?.includeExpired ?? false;
|
|
255
|
+
// Try sqlite-vec fast path first
|
|
256
|
+
if (sqliteVecAvailable) {
|
|
257
|
+
try {
|
|
258
|
+
// KNN search via sqlite-vec with mapping table
|
|
259
|
+
const candidateLimit = Math.max(limit * 5, 50); // Get extra for filtering
|
|
260
|
+
const queryBuffer = floatArrayToBuffer(queryEmbedding);
|
|
261
|
+
const vecResults = database
|
|
262
|
+
.prepare(`
|
|
263
|
+
SELECT m.memory_id, v.distance
|
|
264
|
+
FROM vec_memories v
|
|
265
|
+
JOIN vec_memories_map m ON m.vec_rowid = v.rowid
|
|
266
|
+
WHERE v.embedding MATCH ?
|
|
267
|
+
AND k = ?
|
|
268
|
+
ORDER BY v.distance
|
|
269
|
+
`)
|
|
270
|
+
.all(queryBuffer, candidateLimit);
|
|
271
|
+
if (vecResults.length > 0) {
|
|
272
|
+
// Get memory IDs
|
|
273
|
+
const memoryIds = vecResults.map((r) => r.memory_id);
|
|
274
|
+
const distanceMap = new Map(vecResults.map((r) => [r.memory_id, r.distance]));
|
|
275
|
+
// Fetch full memory data for candidates
|
|
276
|
+
const placeholders = memoryIds.map(() => '?').join(',');
|
|
277
|
+
let query = `SELECT * FROM memories WHERE id IN (${placeholders})`;
|
|
278
|
+
const params = [...memoryIds];
|
|
279
|
+
if (since) {
|
|
280
|
+
query += ' AND created_at >= ?';
|
|
281
|
+
params.push(since.toISOString());
|
|
282
|
+
}
|
|
283
|
+
const rows = database.prepare(query).all(...params);
|
|
284
|
+
const results = [];
|
|
285
|
+
for (const row of rows) {
|
|
286
|
+
// Check validity period
|
|
287
|
+
if (!includeExpired) {
|
|
288
|
+
if (row.valid_from) {
|
|
289
|
+
const validFrom = new Date(row.valid_from).getTime();
|
|
290
|
+
if (now < validFrom)
|
|
291
|
+
continue;
|
|
292
|
+
}
|
|
293
|
+
if (row.valid_until) {
|
|
294
|
+
const validUntil = new Date(row.valid_until).getTime();
|
|
295
|
+
if (now > validUntil)
|
|
296
|
+
continue;
|
|
297
|
+
}
|
|
298
|
+
}
|
|
299
|
+
const rowTags = parseTags(row.tags);
|
|
300
|
+
// Filter by tags if specified
|
|
301
|
+
if (tags && tags.length > 0) {
|
|
302
|
+
const hasMatchingTag = tags.some((t) => rowTags.some((rt) => rt.toLowerCase().includes(t.toLowerCase())));
|
|
303
|
+
if (!hasMatchingTag)
|
|
304
|
+
continue;
|
|
305
|
+
}
|
|
306
|
+
// Convert distance to similarity (cosine distance = 1 - similarity)
|
|
307
|
+
const distance = distanceMap.get(row.id) ?? 1;
|
|
308
|
+
const similarity = 1 - distance;
|
|
309
|
+
if (similarity >= threshold) {
|
|
310
|
+
results.push({
|
|
311
|
+
id: row.id,
|
|
312
|
+
content: row.content,
|
|
313
|
+
tags: rowTags,
|
|
314
|
+
source: row.source,
|
|
315
|
+
quality_score: row.quality_score,
|
|
316
|
+
quality_factors: row.quality_factors ? JSON.parse(row.quality_factors) : null,
|
|
317
|
+
access_count: row.access_count ?? 0,
|
|
318
|
+
last_accessed: row.last_accessed,
|
|
319
|
+
valid_from: row.valid_from,
|
|
320
|
+
valid_until: row.valid_until,
|
|
321
|
+
created_at: row.created_at,
|
|
322
|
+
similarity,
|
|
323
|
+
});
|
|
324
|
+
}
|
|
325
|
+
}
|
|
326
|
+
// Sort by similarity (already mostly sorted but need to re-sort after filtering)
|
|
327
|
+
results.sort((a, b) => b.similarity - a.similarity);
|
|
328
|
+
return results.slice(0, limit);
|
|
329
|
+
}
|
|
330
|
+
}
|
|
331
|
+
catch (err) {
|
|
332
|
+
logWarn('memories', 'sqlite-vec KNN failed, using brute-force fallback', {
|
|
333
|
+
error: err instanceof Error ? err.message : String(err),
|
|
334
|
+
});
|
|
335
|
+
}
|
|
336
|
+
}
|
|
337
|
+
// Brute-force fallback
|
|
338
|
+
let query = 'SELECT * FROM memories WHERE 1=1';
|
|
339
|
+
const params = [];
|
|
340
|
+
if (since) {
|
|
341
|
+
query += ' AND created_at >= ?';
|
|
342
|
+
params.push(since.toISOString());
|
|
343
|
+
}
|
|
344
|
+
const rows = database.prepare(query).all(...params);
|
|
345
|
+
const results = [];
|
|
346
|
+
for (const row of rows) {
|
|
347
|
+
if (!includeExpired) {
|
|
348
|
+
if (row.valid_from) {
|
|
349
|
+
const validFrom = new Date(row.valid_from).getTime();
|
|
350
|
+
if (now < validFrom)
|
|
351
|
+
continue;
|
|
352
|
+
}
|
|
353
|
+
if (row.valid_until) {
|
|
354
|
+
const validUntil = new Date(row.valid_until).getTime();
|
|
355
|
+
if (now > validUntil)
|
|
356
|
+
continue;
|
|
357
|
+
}
|
|
358
|
+
}
|
|
359
|
+
const rowTags = parseTags(row.tags);
|
|
360
|
+
if (tags && tags.length > 0) {
|
|
361
|
+
const hasMatchingTag = tags.some((t) => rowTags.some((rt) => rt.toLowerCase().includes(t.toLowerCase())));
|
|
362
|
+
if (!hasMatchingTag)
|
|
363
|
+
continue;
|
|
364
|
+
}
|
|
365
|
+
const embedding = bufferToFloatArray(row.embedding);
|
|
366
|
+
const similarity = cosineSimilarity(queryEmbedding, embedding);
|
|
367
|
+
if (similarity >= threshold) {
|
|
368
|
+
results.push({
|
|
369
|
+
id: row.id,
|
|
370
|
+
content: row.content,
|
|
371
|
+
tags: rowTags,
|
|
372
|
+
source: row.source,
|
|
373
|
+
quality_score: row.quality_score,
|
|
374
|
+
quality_factors: row.quality_factors ? JSON.parse(row.quality_factors) : null,
|
|
375
|
+
access_count: row.access_count ?? 0,
|
|
376
|
+
last_accessed: row.last_accessed,
|
|
377
|
+
valid_from: row.valid_from,
|
|
378
|
+
valid_until: row.valid_until,
|
|
379
|
+
created_at: row.created_at,
|
|
380
|
+
similarity,
|
|
381
|
+
});
|
|
382
|
+
}
|
|
383
|
+
}
|
|
384
|
+
results.sort((a, b) => b.similarity - a.similarity);
|
|
385
|
+
return results.slice(0, limit);
|
|
386
|
+
}
|
|
387
|
+
/**
|
|
388
|
+
* Get recent memories
|
|
389
|
+
*/
|
|
390
|
+
export function getRecentMemories(limit = 10) {
|
|
391
|
+
const rows = cachedPrepare(`
|
|
392
|
+
SELECT id, content, tags, source, type, quality_score, quality_factors, access_count, last_accessed, valid_from, valid_until, correction_count, is_invariant, priority_score, created_at
|
|
393
|
+
FROM memories
|
|
394
|
+
WHERE invalidated_by IS NULL
|
|
395
|
+
ORDER BY created_at DESC
|
|
396
|
+
LIMIT ?
|
|
397
|
+
`).all(limit);
|
|
398
|
+
return rows.map((row) => ({
|
|
399
|
+
id: row.id,
|
|
400
|
+
content: row.content,
|
|
401
|
+
tags: parseTags(row.tags),
|
|
402
|
+
source: row.source,
|
|
403
|
+
type: row.type ?? null,
|
|
404
|
+
quality_score: row.quality_score,
|
|
405
|
+
quality_factors: row.quality_factors ? JSON.parse(row.quality_factors) : null,
|
|
406
|
+
access_count: row.access_count ?? 0,
|
|
407
|
+
last_accessed: row.last_accessed,
|
|
408
|
+
valid_from: row.valid_from,
|
|
409
|
+
valid_until: row.valid_until,
|
|
410
|
+
correction_count: row.correction_count ?? 0,
|
|
411
|
+
is_invariant: !!row.is_invariant,
|
|
412
|
+
priority_score: row.priority_score ?? null,
|
|
413
|
+
created_at: row.created_at,
|
|
414
|
+
}));
|
|
415
|
+
}
|
|
416
|
+
/**
|
|
417
|
+
* Delete a memory by ID
|
|
418
|
+
*/
|
|
419
|
+
export function deleteMemory(id) {
|
|
420
|
+
// Also delete from vec_memories using mapping table
|
|
421
|
+
if (sqliteVecAvailable) {
|
|
422
|
+
try {
|
|
423
|
+
const mapping = cachedPrepare('SELECT vec_rowid FROM vec_memories_map WHERE memory_id = ?').get(id);
|
|
424
|
+
if (mapping) {
|
|
425
|
+
cachedPrepare('DELETE FROM vec_memories WHERE rowid = ?').run(mapping.vec_rowid);
|
|
426
|
+
cachedPrepare('DELETE FROM vec_memories_map WHERE memory_id = ?').run(id);
|
|
427
|
+
}
|
|
428
|
+
}
|
|
429
|
+
catch (err) {
|
|
430
|
+
logWarn('memories', 'Vector cleanup failed during memory deletion', {
|
|
431
|
+
error: err instanceof Error ? err.message : String(err),
|
|
432
|
+
});
|
|
433
|
+
}
|
|
434
|
+
}
|
|
435
|
+
const result = cachedPrepare('DELETE FROM memories WHERE id = ?').run(id);
|
|
436
|
+
if (result.changes > 0) {
|
|
437
|
+
logDeletion('deleteMemory', 1, [id]);
|
|
438
|
+
invalidateMemoriesBm25Index();
|
|
439
|
+
}
|
|
440
|
+
return result.changes > 0;
|
|
441
|
+
}
|
|
442
|
+
/**
|
|
443
|
+
* Soft-invalidate a memory during consolidation.
|
|
444
|
+
* Sets valid_until = now and records which memory superseded it.
|
|
445
|
+
* The memory remains in the database for historical queries and rollback.
|
|
446
|
+
*/
|
|
447
|
+
export function invalidateMemory(memoryId, supersededById) {
|
|
448
|
+
const now = new Date().toISOString();
|
|
449
|
+
const result = cachedPrepare(`
|
|
450
|
+
UPDATE memories
|
|
451
|
+
SET valid_until = ?, invalidated_by = ?
|
|
452
|
+
WHERE id = ? AND invalidated_by IS NULL
|
|
453
|
+
`).run(now, supersededById, memoryId);
|
|
454
|
+
return result.changes > 0;
|
|
455
|
+
}
|
|
456
|
+
/**
|
|
457
|
+
* Restore a soft-invalidated memory by clearing valid_until and invalidated_by.
|
|
458
|
+
* Used by the consolidation rollback (undo) feature.
|
|
459
|
+
*/
|
|
460
|
+
export function restoreInvalidatedMemory(memoryId) {
|
|
461
|
+
const result = cachedPrepare(`
|
|
462
|
+
UPDATE memories
|
|
463
|
+
SET valid_until = NULL, invalidated_by = NULL
|
|
464
|
+
WHERE id = ? AND invalidated_by IS NOT NULL
|
|
465
|
+
`).run(memoryId);
|
|
466
|
+
return result.changes > 0;
|
|
467
|
+
}
|
|
468
|
+
/**
|
|
469
|
+
* Get consolidation history: merged memories and what they superseded.
|
|
470
|
+
* Returns merge operations with their source originals.
|
|
471
|
+
*/
|
|
472
|
+
export function getConsolidationHistory(limit = 20) {
|
|
473
|
+
// Find memories that have supersedes links (these are merge results)
|
|
474
|
+
const rows = cachedPrepare(`
|
|
475
|
+
SELECT DISTINCT ml.source_id as merged_id, ml.created_at as merged_at
|
|
476
|
+
FROM memory_links ml
|
|
477
|
+
WHERE ml.relation = 'supersedes'
|
|
478
|
+
ORDER BY ml.created_at DESC
|
|
479
|
+
LIMIT ?
|
|
480
|
+
`).all(limit);
|
|
481
|
+
return rows.map((row) => {
|
|
482
|
+
const mergedMemory = getMemoryById(row.merged_id);
|
|
483
|
+
const originals = cachedPrepare(`
|
|
484
|
+
SELECT target_id FROM memory_links
|
|
485
|
+
WHERE source_id = ? AND relation = 'supersedes'
|
|
486
|
+
`).all(row.merged_id);
|
|
487
|
+
return {
|
|
488
|
+
mergedMemoryId: row.merged_id,
|
|
489
|
+
mergedContent: mergedMemory?.content ?? '(deleted)',
|
|
490
|
+
originalIds: originals.map((o) => o.target_id),
|
|
491
|
+
mergedAt: row.merged_at,
|
|
492
|
+
};
|
|
493
|
+
});
|
|
494
|
+
}
|
|
495
|
+
/**
|
|
496
|
+
* Get memory stats including type breakdown
|
|
497
|
+
*/
|
|
498
|
+
export function getMemoryStats() {
|
|
499
|
+
const total = cachedPrepare('SELECT COUNT(*) as count FROM memories').get();
|
|
500
|
+
const active = cachedPrepare('SELECT COUNT(*) as count FROM memories WHERE invalidated_by IS NULL').get();
|
|
501
|
+
const oldest = cachedPrepare('SELECT MIN(created_at) as oldest FROM memories WHERE invalidated_by IS NULL').get();
|
|
502
|
+
const newest = cachedPrepare('SELECT MAX(created_at) as newest FROM memories WHERE invalidated_by IS NULL').get();
|
|
503
|
+
// Count by type (active only)
|
|
504
|
+
const typeCounts = cachedPrepare('SELECT COALESCE(type, ?) as type, COUNT(*) as count FROM memories WHERE invalidated_by IS NULL GROUP BY type').all('observation');
|
|
505
|
+
const by_type = {};
|
|
506
|
+
for (const row of typeCounts) {
|
|
507
|
+
by_type[row.type] = row.count;
|
|
508
|
+
}
|
|
509
|
+
// Count stale memories (older than 30 days, active only)
|
|
510
|
+
const thirtyDaysAgo = new Date(Date.now() - 30 * 24 * 60 * 60 * 1000).toISOString();
|
|
511
|
+
const stale = cachedPrepare('SELECT COUNT(*) as count FROM memories WHERE created_at < ? AND invalidated_by IS NULL').get(thirtyDaysAgo);
|
|
512
|
+
return {
|
|
513
|
+
total_memories: total.count,
|
|
514
|
+
active_memories: active.count,
|
|
515
|
+
invalidated_memories: total.count - active.count,
|
|
516
|
+
oldest_memory: oldest.oldest,
|
|
517
|
+
newest_memory: newest.newest,
|
|
518
|
+
by_type,
|
|
519
|
+
stale_count: stale.count,
|
|
520
|
+
};
|
|
521
|
+
}
|
|
522
|
+
/**
|
|
523
|
+
* Delete memories older than a given date
|
|
524
|
+
*/
|
|
525
|
+
export function deleteMemoriesOlderThan(date) {
|
|
526
|
+
const database = getDb();
|
|
527
|
+
// Clean up vec_memories and vec_memories_map for affected memories
|
|
528
|
+
if (sqliteVecAvailable) {
|
|
529
|
+
try {
|
|
530
|
+
const affectedIds = cachedPrepare('SELECT id FROM memories WHERE created_at < ?').all(date.toISOString());
|
|
531
|
+
if (affectedIds.length > 0) {
|
|
532
|
+
const placeholders = affectedIds.map(() => '?').join(',');
|
|
533
|
+
const ids = affectedIds.map((r) => r.id);
|
|
534
|
+
// Get vec rowids to delete
|
|
535
|
+
const vecMappings = database
|
|
536
|
+
.prepare(`SELECT vec_rowid FROM vec_memories_map WHERE memory_id IN (${placeholders})`)
|
|
537
|
+
.all(...ids);
|
|
538
|
+
if (vecMappings.length > 0) {
|
|
539
|
+
const vecPlaceholders = vecMappings.map(() => '?').join(',');
|
|
540
|
+
const vecRowids = vecMappings.map((r) => r.vec_rowid);
|
|
541
|
+
database
|
|
542
|
+
.prepare(`DELETE FROM vec_memories WHERE rowid IN (${vecPlaceholders})`)
|
|
543
|
+
.run(...vecRowids);
|
|
544
|
+
}
|
|
545
|
+
database
|
|
546
|
+
.prepare(`DELETE FROM vec_memories_map WHERE memory_id IN (${placeholders})`)
|
|
547
|
+
.run(...ids);
|
|
548
|
+
}
|
|
549
|
+
}
|
|
550
|
+
catch (err) {
|
|
551
|
+
logWarn('memories', 'Vector cleanup failed during memory deletion', {
|
|
552
|
+
error: err instanceof Error ? err.message : String(err),
|
|
553
|
+
});
|
|
554
|
+
}
|
|
555
|
+
}
|
|
556
|
+
const result = cachedPrepare('DELETE FROM memories WHERE created_at < ?').run(date.toISOString());
|
|
557
|
+
if (result.changes > 0) {
|
|
558
|
+
logDeletion('deleteMemoriesOlderThan', result.changes, [], `older_than=${date.toISOString()}`);
|
|
559
|
+
invalidateMemoriesBm25Index();
|
|
560
|
+
}
|
|
561
|
+
return result.changes;
|
|
562
|
+
}
|
|
563
|
+
/**
|
|
564
|
+
* Delete memories by tag
|
|
565
|
+
*/
|
|
566
|
+
export function deleteMemoriesByTag(tag) {
|
|
567
|
+
const database = getDb();
|
|
568
|
+
// Get all memories with tags
|
|
569
|
+
const memories = cachedPrepare('SELECT id, tags FROM memories WHERE tags IS NOT NULL').all();
|
|
570
|
+
const toDelete = [];
|
|
571
|
+
for (const memory of memories) {
|
|
572
|
+
const tags = parseTags(memory.tags);
|
|
573
|
+
if (tags.some((t) => t.toLowerCase() === tag.toLowerCase())) {
|
|
574
|
+
toDelete.push(memory.id);
|
|
575
|
+
}
|
|
576
|
+
}
|
|
577
|
+
if (toDelete.length === 0)
|
|
578
|
+
return 0;
|
|
579
|
+
const placeholders = toDelete.map(() => '?').join(',');
|
|
580
|
+
// Clean up vec_memories and vec_memories_map for affected memories
|
|
581
|
+
if (sqliteVecAvailable) {
|
|
582
|
+
try {
|
|
583
|
+
const vecMappings = database
|
|
584
|
+
.prepare(`SELECT vec_rowid FROM vec_memories_map WHERE memory_id IN (${placeholders})`)
|
|
585
|
+
.all(...toDelete);
|
|
586
|
+
if (vecMappings.length > 0) {
|
|
587
|
+
const vecPlaceholders = vecMappings.map(() => '?').join(',');
|
|
588
|
+
const vecRowids = vecMappings.map((r) => r.vec_rowid);
|
|
589
|
+
database
|
|
590
|
+
.prepare(`DELETE FROM vec_memories WHERE rowid IN (${vecPlaceholders})`)
|
|
591
|
+
.run(...vecRowids);
|
|
592
|
+
}
|
|
593
|
+
database
|
|
594
|
+
.prepare(`DELETE FROM vec_memories_map WHERE memory_id IN (${placeholders})`)
|
|
595
|
+
.run(...toDelete);
|
|
596
|
+
}
|
|
597
|
+
catch (err) {
|
|
598
|
+
logWarn('memories', 'Vector cleanup failed during memory deletion', {
|
|
599
|
+
error: err instanceof Error ? err.message : String(err),
|
|
600
|
+
});
|
|
601
|
+
}
|
|
602
|
+
}
|
|
603
|
+
const result = database
|
|
604
|
+
.prepare(`DELETE FROM memories WHERE id IN (${placeholders})`)
|
|
605
|
+
.run(...toDelete);
|
|
606
|
+
if (result.changes > 0) {
|
|
607
|
+
logDeletion('deleteMemoriesByTag', result.changes, toDelete, `tag="${tag}"`);
|
|
608
|
+
invalidateMemoriesBm25Index();
|
|
609
|
+
}
|
|
610
|
+
return result.changes;
|
|
611
|
+
}
|
|
612
|
+
/**
|
|
613
|
+
* Get memory by ID
|
|
614
|
+
*/
|
|
615
|
+
export function getMemoryById(id) {
|
|
616
|
+
const row = cachedPrepare('SELECT id, content, tags, source, type, quality_score, quality_factors, access_count, last_accessed, valid_from, valid_until, correction_count, is_invariant, priority_score, created_at FROM memories WHERE id = ?').get(id);
|
|
617
|
+
if (!row)
|
|
618
|
+
return null;
|
|
619
|
+
return {
|
|
620
|
+
id: row.id,
|
|
621
|
+
content: row.content,
|
|
622
|
+
tags: parseTags(row.tags),
|
|
623
|
+
source: row.source,
|
|
624
|
+
type: row.type ?? null,
|
|
625
|
+
quality_score: row.quality_score,
|
|
626
|
+
quality_factors: row.quality_factors ? JSON.parse(row.quality_factors) : null,
|
|
627
|
+
access_count: row.access_count ?? 0,
|
|
628
|
+
last_accessed: row.last_accessed,
|
|
629
|
+
valid_from: row.valid_from,
|
|
630
|
+
valid_until: row.valid_until,
|
|
631
|
+
correction_count: row.correction_count ?? 0,
|
|
632
|
+
is_invariant: !!row.is_invariant,
|
|
633
|
+
priority_score: row.priority_score ?? null,
|
|
634
|
+
created_at: row.created_at,
|
|
635
|
+
};
|
|
636
|
+
}
|
|
637
|
+
/**
|
|
638
|
+
* Delete memories by IDs (batch operation for retention cleanup).
|
|
639
|
+
*/
|
|
640
|
+
export function deleteMemoriesByIds(ids) {
|
|
641
|
+
if (ids.length === 0)
|
|
642
|
+
return 0;
|
|
643
|
+
const database = getDb();
|
|
644
|
+
const placeholders = ids.map(() => '?').join(',');
|
|
645
|
+
// Clean up vec_memories and vec_memories_map for affected memories
|
|
646
|
+
if (sqliteVecAvailable) {
|
|
647
|
+
try {
|
|
648
|
+
const vecMappings = database
|
|
649
|
+
.prepare(`SELECT vec_rowid FROM vec_memories_map WHERE memory_id IN (${placeholders})`)
|
|
650
|
+
.all(...ids);
|
|
651
|
+
if (vecMappings.length > 0) {
|
|
652
|
+
const vecPlaceholders = vecMappings.map(() => '?').join(',');
|
|
653
|
+
const vecRowids = vecMappings.map((r) => r.vec_rowid);
|
|
654
|
+
database
|
|
655
|
+
.prepare(`DELETE FROM vec_memories WHERE rowid IN (${vecPlaceholders})`)
|
|
656
|
+
.run(...vecRowids);
|
|
657
|
+
}
|
|
658
|
+
database
|
|
659
|
+
.prepare(`DELETE FROM vec_memories_map WHERE memory_id IN (${placeholders})`)
|
|
660
|
+
.run(...ids);
|
|
661
|
+
}
|
|
662
|
+
catch {
|
|
663
|
+
// Ignore vec table errors
|
|
664
|
+
}
|
|
665
|
+
}
|
|
666
|
+
const result = database.prepare(`DELETE FROM memories WHERE id IN (${placeholders})`).run(...ids);
|
|
667
|
+
if (result.changes > 0) {
|
|
668
|
+
logDeletion('deleteMemoriesByIds', result.changes, ids, 'batch/retention');
|
|
669
|
+
invalidateMemoriesBm25Index();
|
|
670
|
+
}
|
|
671
|
+
return result.changes;
|
|
672
|
+
}
|
|
673
|
+
/**
|
|
674
|
+
* Search memories as they existed at a specific point in time.
|
|
675
|
+
* Core function for point-in-time queries.
|
|
676
|
+
*/
|
|
677
|
+
export function searchMemoriesAsOf(queryEmbedding, asOfDate, limit = 5, threshold = 0.3) {
|
|
678
|
+
const asOfStr = asOfDate.toISOString();
|
|
679
|
+
const asOfTime = asOfDate.getTime();
|
|
680
|
+
// Get memories that existed at that time
|
|
681
|
+
const rows = cachedPrepare(`
|
|
682
|
+
SELECT * FROM memories
|
|
683
|
+
WHERE created_at <= ?
|
|
684
|
+
`).all(asOfStr);
|
|
685
|
+
const results = [];
|
|
686
|
+
for (const row of rows) {
|
|
687
|
+
// Check validity period at asOfDate
|
|
688
|
+
if (row.valid_from) {
|
|
689
|
+
const validFrom = new Date(row.valid_from).getTime();
|
|
690
|
+
if (asOfTime < validFrom)
|
|
691
|
+
continue;
|
|
692
|
+
}
|
|
693
|
+
if (row.valid_until) {
|
|
694
|
+
const validUntil = new Date(row.valid_until).getTime();
|
|
695
|
+
if (asOfTime > validUntil)
|
|
696
|
+
continue;
|
|
697
|
+
}
|
|
698
|
+
const embedding = bufferToFloatArray(row.embedding);
|
|
699
|
+
const similarity = cosineSimilarity(queryEmbedding, embedding);
|
|
700
|
+
if (similarity >= threshold) {
|
|
701
|
+
results.push({
|
|
702
|
+
id: row.id,
|
|
703
|
+
content: row.content,
|
|
704
|
+
tags: parseTags(row.tags),
|
|
705
|
+
source: row.source,
|
|
706
|
+
quality_score: row.quality_score,
|
|
707
|
+
quality_factors: row.quality_factors ? JSON.parse(row.quality_factors) : null,
|
|
708
|
+
access_count: row.access_count ?? 0,
|
|
709
|
+
last_accessed: row.last_accessed,
|
|
710
|
+
valid_from: row.valid_from,
|
|
711
|
+
valid_until: row.valid_until,
|
|
712
|
+
created_at: row.created_at,
|
|
713
|
+
similarity,
|
|
714
|
+
});
|
|
715
|
+
}
|
|
716
|
+
}
|
|
717
|
+
results.sort((a, b) => b.similarity - a.similarity);
|
|
718
|
+
return results.slice(0, limit);
|
|
719
|
+
}
|
|
720
|
+
/**
|
|
721
|
+
* Save multiple memories in a single transaction with batch duplicate checking.
|
|
722
|
+
* Optimized for session processing to avoid N+1 query problem.
|
|
723
|
+
*
|
|
724
|
+
* Performance: ~95% reduction in DB overhead vs individual saveMemory() calls
|
|
725
|
+
* - Before: N*2 queries (N duplicate checks + N inserts)
|
|
726
|
+
* - After: 1 duplicate check + 1 batch insert
|
|
727
|
+
*
|
|
728
|
+
* @param memories - Array of memories to save
|
|
729
|
+
* @param deduplicateThreshold - Similarity threshold for duplicate detection (default 0.92)
|
|
730
|
+
* @returns Batch save results with per-memory status
|
|
731
|
+
*/
|
|
732
|
+
export function saveMemoriesBatch(memories, deduplicateThreshold = 0.92, options) {
|
|
733
|
+
const database = getDb();
|
|
734
|
+
const results = [];
|
|
735
|
+
let saved = 0;
|
|
736
|
+
let skipped = 0;
|
|
737
|
+
// Early exit if empty
|
|
738
|
+
if (memories.length === 0) {
|
|
739
|
+
return { saved: 0, skipped: 0, results: [] };
|
|
740
|
+
}
|
|
741
|
+
// Batch duplicate check: load all existing memories once
|
|
742
|
+
const existingRows = cachedPrepare('SELECT id, content, embedding FROM memories').all();
|
|
743
|
+
const existingEmbeddings = existingRows.map((row) => ({
|
|
744
|
+
id: row.id,
|
|
745
|
+
content: row.content,
|
|
746
|
+
embedding: bufferToFloatArray(row.embedding),
|
|
747
|
+
}));
|
|
748
|
+
// Check each input memory against existing ones (unless dedup disabled)
|
|
749
|
+
const shouldDedup = options?.deduplicate !== false;
|
|
750
|
+
const toInsert = [];
|
|
751
|
+
if (shouldDedup) {
|
|
752
|
+
for (let i = 0; i < memories.length; i++) {
|
|
753
|
+
const memory = memories[i];
|
|
754
|
+
let isDuplicate = false;
|
|
755
|
+
let duplicateId;
|
|
756
|
+
let maxSimilarity = 0;
|
|
757
|
+
// Check against all existing memories
|
|
758
|
+
for (const existing of existingEmbeddings) {
|
|
759
|
+
const similarity = cosineSimilarity(memory.embedding, existing.embedding);
|
|
760
|
+
if (similarity > maxSimilarity) {
|
|
761
|
+
maxSimilarity = similarity;
|
|
762
|
+
}
|
|
763
|
+
if (similarity >= deduplicateThreshold) {
|
|
764
|
+
isDuplicate = true;
|
|
765
|
+
duplicateId = existing.id;
|
|
766
|
+
break;
|
|
767
|
+
}
|
|
768
|
+
}
|
|
769
|
+
if (isDuplicate) {
|
|
770
|
+
results.push({
|
|
771
|
+
index: i,
|
|
772
|
+
isDuplicate: true,
|
|
773
|
+
id: duplicateId,
|
|
774
|
+
reason: 'duplicate',
|
|
775
|
+
similarity: maxSimilarity,
|
|
776
|
+
});
|
|
777
|
+
skipped++;
|
|
778
|
+
}
|
|
779
|
+
else {
|
|
780
|
+
toInsert.push({ input: memory, index: i });
|
|
781
|
+
}
|
|
782
|
+
}
|
|
783
|
+
}
|
|
784
|
+
else {
|
|
785
|
+
// Skip dedup — insert all
|
|
786
|
+
for (let i = 0; i < memories.length; i++) {
|
|
787
|
+
toInsert.push({ input: memories[i], index: i });
|
|
788
|
+
}
|
|
789
|
+
}
|
|
790
|
+
// Batch insert all non-duplicates in a transaction
|
|
791
|
+
if (toInsert.length > 0) {
|
|
792
|
+
const insertStmt = database.prepare(`
|
|
793
|
+
INSERT INTO memories (content, tags, source, type, quality_score, quality_factors, embedding, valid_from, valid_until)
|
|
794
|
+
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)
|
|
795
|
+
`);
|
|
796
|
+
// Prepare vec_memories statements if available
|
|
797
|
+
let insertVec;
|
|
798
|
+
let insertMap;
|
|
799
|
+
if (sqliteVecAvailable) {
|
|
800
|
+
insertVec = database.prepare('INSERT INTO vec_memories(embedding) VALUES (?)');
|
|
801
|
+
insertMap = database.prepare('INSERT INTO vec_memories_map(vec_rowid, memory_id) VALUES (?, ?)');
|
|
802
|
+
}
|
|
803
|
+
// Transaction for atomic batch insert
|
|
804
|
+
const batchInsert = database.transaction(() => {
|
|
805
|
+
for (const { input, index } of toInsert) {
|
|
806
|
+
const tagsStr = JSON.stringify(input.tags);
|
|
807
|
+
const qualityScore = input.qualityScore?.score ?? null;
|
|
808
|
+
const qualityFactors = input.qualityScore
|
|
809
|
+
? JSON.stringify(input.qualityScore.factors)
|
|
810
|
+
: null;
|
|
811
|
+
const embeddingBlob = floatArrayToBuffer(input.embedding);
|
|
812
|
+
const validFromStr = input.validFrom
|
|
813
|
+
? input.validFrom instanceof Date
|
|
814
|
+
? input.validFrom.toISOString()
|
|
815
|
+
: input.validFrom
|
|
816
|
+
: null;
|
|
817
|
+
const validUntilStr = input.validUntil
|
|
818
|
+
? input.validUntil instanceof Date
|
|
819
|
+
? input.validUntil.toISOString()
|
|
820
|
+
: input.validUntil
|
|
821
|
+
: null;
|
|
822
|
+
const result = insertStmt.run(input.content, tagsStr, input.source ?? null, input.type, qualityScore, qualityFactors, embeddingBlob, validFromStr, validUntilStr);
|
|
823
|
+
const memoryId = Number(result.lastInsertRowid);
|
|
824
|
+
// Insert into vec_memories if available
|
|
825
|
+
if (sqliteVecAvailable && insertVec && insertMap) {
|
|
826
|
+
try {
|
|
827
|
+
const vecResult = insertVec.run(embeddingBlob);
|
|
828
|
+
insertMap.run(vecResult.lastInsertRowid, memoryId);
|
|
829
|
+
}
|
|
830
|
+
catch (err) {
|
|
831
|
+
logWarn('memories', 'Batch vector insert failed for memory', {
|
|
832
|
+
error: err instanceof Error ? err.message : String(err),
|
|
833
|
+
});
|
|
834
|
+
}
|
|
835
|
+
}
|
|
836
|
+
results.push({
|
|
837
|
+
index,
|
|
838
|
+
isDuplicate: false,
|
|
839
|
+
id: memoryId,
|
|
840
|
+
reason: 'saved',
|
|
841
|
+
});
|
|
842
|
+
saved++;
|
|
843
|
+
}
|
|
844
|
+
});
|
|
845
|
+
batchInsert();
|
|
846
|
+
// Auto-link newly saved memories to existing ones
|
|
847
|
+
if (options?.autoLink !== false) {
|
|
848
|
+
const linkThreshold = options?.linkThreshold ?? 0.7;
|
|
849
|
+
for (const { input, index } of toInsert) {
|
|
850
|
+
const savedResult = results.find((r) => r.index === index && !r.isDuplicate);
|
|
851
|
+
if (savedResult?.id) {
|
|
852
|
+
autoLinkNewMemory(savedResult.id, input.embedding, linkThreshold);
|
|
853
|
+
}
|
|
854
|
+
}
|
|
855
|
+
}
|
|
856
|
+
// Trigger graph auto-export once for all memories
|
|
857
|
+
triggerAutoExport();
|
|
858
|
+
}
|
|
859
|
+
// Sort results by original index
|
|
860
|
+
results.sort((a, b) => a.index - b.index);
|
|
861
|
+
if (saved > 0) {
|
|
862
|
+
invalidateMemoriesBm25Index();
|
|
863
|
+
}
|
|
864
|
+
return { saved, skipped, results };
|
|
865
|
+
}
|
|
866
|
+
//# sourceMappingURL=memories.js.map
|