squish-memory 1.1.5 → 1.2.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.
- package/.env.example +32 -16
- package/CHANGELOG.md +147 -0
- package/README.md +120 -78
- package/{scripts → bin}/dependency-manager.mjs +217 -217
- package/{scripts → bin}/detect-clients.mjs +78 -78
- package/bin/install-interactive.mjs +321 -0
- package/bin/squish-mcp.mjs +46 -0
- package/bin/squish.mjs +33 -0
- package/config/mcp-migration-map.json +1 -6
- package/config/mcp-mode-semantics.json +19 -23
- package/config/mcp-remote-auth.json +3 -26
- package/config/mcp-universal.schema.json +5 -35
- package/config/settings.json +107 -52
- package/config.js +5 -0
- package/config.ts +218 -0
- package/core/adapters/config/claude-code.ts +133 -0
- package/core/adapters/config/cursor.ts +90 -0
- package/core/adapters/config/opencode.ts +89 -0
- package/core/adapters/config/windsurf.ts +90 -0
- package/core/adapters/index.ts +102 -0
- package/core/adapters/timeline.ts +116 -0
- package/core/adapters/types.ts +166 -0
- package/core/agent-preferences.ts +140 -0
- package/core/algorithms/analytics/token-estimator.ts +216 -0
- package/core/algorithms/detection/hash-filters.ts +260 -0
- package/core/algorithms/detection/semantic-ranker.ts +194 -0
- package/core/algorithms/detection/two-stage-detector.ts +421 -0
- package/core/algorithms/handlers/approve-merge.ts +215 -0
- package/core/algorithms/handlers/detect-duplicates.ts +192 -0
- package/core/algorithms/handlers/get-stats.ts +132 -0
- package/core/algorithms/handlers/list-proposals.ts +130 -0
- package/core/algorithms/handlers/preview-merge.ts +139 -0
- package/core/algorithms/handlers/reject-merge.ts +93 -0
- package/core/algorithms/handlers/reverse-merge.ts +155 -0
- package/core/algorithms/index.ts +39 -0
- package/core/algorithms/operations/cache-maintenance.ts +182 -0
- package/core/algorithms/safety/safety-checks.ts +256 -0
- package/core/algorithms/strategies/merge-strategies.ts +381 -0
- package/core/algorithms/types.ts +140 -0
- package/core/algorithms/utils/response-builder.ts +61 -0
- package/core/associations.ts +363 -0
- package/core/beliefs/decay.ts +289 -0
- package/core/beliefs/extractor.ts +131 -0
- package/core/beliefs/store.ts +557 -0
- package/core/beliefs/types.ts +38 -0
- package/core/commands/mcp-server.ts +5 -0
- package/core/compression.ts +177 -0
- package/core/config.js +2 -0
- package/core/consolidation.ts +330 -0
- package/core/context/agent-context.ts +388 -0
- package/core/context/context-paging.ts +449 -0
- package/core/context/context-window.ts +234 -0
- package/core/context/context.ts +35 -0
- package/core/embeddings/embeddings.ts +616 -0
- package/core/embeddings/google-multimodal.ts +200 -0
- package/{dist/core/local-embeddings.js → core/embeddings/local-embeddings.ts} +12 -11
- package/core/embeddings/qmd-client.ts +495 -0
- package/core/embeddings/transformers-local.ts +261 -0
- package/core/embeddings.js +4 -0
- package/core/error-handling.ts +206 -0
- package/core/external +219 -0
- package/core/graph/entity-deduplicator.ts +232 -0
- package/core/graph/graph-builder.ts +257 -0
- package/core/graph/graph-traversal.ts +490 -0
- package/core/graph/index.ts +24 -0
- package/core/graph/llm-entity-extractor.ts +402 -0
- package/core/graph/multi-hop-retrieval.ts +317 -0
- package/core/graph/relationship-extractor.ts +465 -0
- package/core/hooks/agent-hooks.ts +653 -0
- package/core/hooks/auto-tagger.ts +149 -0
- package/core/hooks/capture-filter.ts +169 -0
- package/core/hot-cache.ts +388 -0
- package/core/index.ts +10 -0
- package/core/ingestion/agent-memory.ts +167 -0
- package/core/ingestion/core-memory.ts +326 -0
- package/core/ingestion/learnings.ts +260 -0
- package/core/ingestion/signal-engine.ts +266 -0
- package/core/integrations/obsidian-vault.ts +197 -0
- package/core/layers/generator.ts +115 -0
- package/core/lib/db-client.ts +168 -0
- package/core/lib/parse-embedding.ts +59 -0
- package/core/lib/schemas.ts +102 -0
- package/core/lib/types.ts +49 -0
- package/core/lib/utils.ts +151 -0
- package/core/lib/validation.ts +180 -0
- package/core/lifecycle.ts +353 -0
- package/core/logger.ts +59 -0
- package/core/memory/bridge-discovery.ts +395 -0
- package/core/memory/categorizer.ts +390 -0
- package/core/memory/conflict-detector.ts +62 -0
- package/core/memory/consolidation.ts +372 -0
- package/core/memory/context-collector.ts +75 -0
- package/core/memory/contradiction-resolver.ts +494 -0
- package/core/memory/edit-workflow.ts +174 -0
- package/core/memory/entity-extractor.ts +426 -0
- package/core/memory/entity-resolver.ts +89 -0
- package/core/memory/explain.ts +112 -0
- package/core/memory/fact-deriver.ts +300 -0
- package/core/memory/fact-extractor.ts +120 -0
- package/core/memory/feedback-tracker.ts +200 -0
- package/core/memory/hooks.ts +230 -0
- package/core/memory/hybrid-retrieval.ts +65 -0
- package/core/memory/hybrid-scorer.ts +325 -0
- package/core/memory/hybrid-search.ts +748 -0
- package/core/memory/importance.ts +319 -0
- package/core/memory/index.ts +11 -0
- package/core/memory/loader.ts +178 -0
- package/core/memory/markdown/markdown-storage.ts +318 -0
- package/core/memory/memories.ts +565 -0
- package/core/memory/memory-lifecycle.ts +51 -0
- package/core/memory/memory-manager.ts +53 -0
- package/core/memory/migrate.ts +173 -0
- package/core/memory/normalization.ts +30 -0
- package/core/memory/path-strengthener.ts +211 -0
- package/core/memory/progressive-disclosure.ts +392 -0
- package/core/memory/query-processor.ts +130 -0
- package/core/memory/query-rewriter.ts +153 -0
- package/core/memory/response-analyzer.ts +81 -0
- package/core/memory/retrieval-feedback.ts +276 -0
- package/core/memory/serialization.ts +83 -0
- package/core/memory/stale-cleaner.ts +147 -0
- package/core/memory/stats.ts +181 -0
- package/core/memory/telemetry.ts +392 -0
- package/core/memory/temporal-facts.ts +356 -0
- package/core/memory/temporal-parser.ts +477 -0
- package/core/memory/trigger-detector.ts +104 -0
- package/core/memory/write-gate.ts +288 -0
- package/core/places/index.ts +14 -0
- package/core/places/memory-places.ts +339 -0
- package/core/places/places.ts +406 -0
- package/core/places/rules.ts +308 -0
- package/core/places/walking.ts +192 -0
- package/core/projects +89 -0
- package/core/projects.ts +131 -0
- package/core/redis.ts +82 -0
- package/core/responses.ts +187 -0
- package/core/runtime/trust-report.ts +195 -0
- package/core/runtime/trust-state.ts +360 -0
- package/core/scheduler/cron-scheduler.ts +581 -0
- package/core/scheduler/heartbeat.ts +91 -0
- package/core/scheduler/index.ts +8 -0
- package/core/scheduler/job-runner.ts +197 -0
- package/core/search/conversations.ts +166 -0
- package/core/search/entities.ts +46 -0
- package/core/search/folder-context.ts +154 -0
- package/core/search/graph-boost.ts +22 -0
- package/core/search/index.ts +4 -0
- package/core/search/qmd-wrapper.ts +84 -0
- package/core/security/encrypt.ts +51 -0
- package/core/security/governance.ts +102 -0
- package/core/security/privacy.ts +108 -0
- package/core/security/secret-detector.ts +122 -0
- package/core/session/auto-load.ts +160 -0
- package/core/session/entity-tracker.ts +363 -0
- package/core/session/index.ts +7 -0
- package/core/session/reference-resolver.ts +158 -0
- package/core/session/self-iteration-job.ts +478 -0
- package/core/session/session-hooks.ts +69 -0
- package/core/session/types.ts +36 -0
- package/core/session/working-set.ts +275 -0
- package/core/snapshots/cleanup.ts +13 -0
- package/core/snapshots/comparison.ts +59 -0
- package/core/snapshots/creation.ts +139 -0
- package/core/snapshots/retrieval.ts +44 -0
- package/core/snapshots/stats.ts +63 -0
- package/core/storage/cache.ts +241 -0
- package/core/storage/database.ts +23 -0
- package/core/summarization/cleanup.ts +13 -0
- package/core/summarization/queries.ts +32 -0
- package/core/summarization/stats.ts +64 -0
- package/core/summarization/strategies.ts +52 -0
- package/core/summarization.ts +248 -0
- package/core/temporal-facts.ts +244 -0
- package/core/tracing/collector.ts +470 -0
- package/core/tracing/visualizer.ts +195 -0
- package/core/utils/cleanup-operations.ts +50 -0
- package/core/utils/content-extraction.ts +95 -0
- package/core/utils/filter-builder.ts +56 -0
- package/core/utils/history-traversal.ts +63 -0
- package/core/utils/memory-operations.ts +56 -0
- package/core/utils/query-operations.ts +83 -0
- package/core/utils/summarization-helpers.ts +45 -0
- package/core/utils/temporal-queries.ts +39 -0
- package/core/utils/vector-operations.ts +135 -0
- package/core/utils/version-management.ts +74 -0
- package/core/worker.ts +324 -0
- package/db/adapter.ts +215 -0
- package/db/bootstrap.ts +1055 -0
- package/db/drizzle/migrations/0000_needy_cerebro.sql +402 -0
- package/db/drizzle/migrations/meta/0000_snapshot.json +3451 -0
- package/db/drizzle/migrations/meta/_journal.json +13 -0
- package/db/drizzle/schema-sqlite.ts +1032 -0
- package/db/drizzle/schema.ts +1128 -0
- package/db/drizzle.config.ts +12 -0
- package/db/index.ts +83 -0
- package/db/init.sql +5 -0
- package/db/migrations/associations.ts +35 -0
- package/db/migrations/beliefs.ts +89 -0
- package/db/migrations/core-memory.ts +35 -0
- package/db/migrations/fts.ts +59 -0
- package/db/migrations/index.ts +54 -0
- package/db/migrations/indexes.ts +36 -0
- package/db/migrations/learnings.ts +34 -0
- package/db/migrations/maintenance.ts +68 -0
- package/db/migrations/memories.ts +22 -0
- package/db/migrations/memory-places.ts +35 -0
- package/db/migrations/places.ts +49 -0
- package/db/migrations/projects.ts +21 -0
- package/db/migrations/tier-conversion.ts +24 -0
- package/db/neon.ts +22 -0
- package/db/schema/beliefs.ts +50 -0
- package/db/schema/generator.ts +159 -0
- package/db/schema/index.ts +58 -0
- package/db/schema/learnings.ts +32 -0
- package/db/schema/memories.ts +83 -0
- package/db/schema/projects.ts +33 -0
- package/db/schema.ts +13 -0
- package/db/supabase.ts +27 -0
- package/dist/config.d.ts +40 -17
- package/dist/config.js +150 -198
- package/dist/core/adapters/types.d.ts +13 -33
- package/dist/core/adapters/types.js +1 -1
- package/dist/core/agent-preferences.d.ts +16 -0
- package/dist/core/agent-preferences.js +124 -0
- package/dist/core/algorithms/safety/safety-checks.d.ts +1 -5
- package/dist/core/algorithms/types.d.ts +0 -8
- package/dist/core/associations.d.ts +3 -1
- package/dist/core/associations.js +37 -1
- package/dist/core/beliefs/decay.d.ts +27 -0
- package/dist/core/beliefs/decay.js +217 -0
- package/dist/core/beliefs/extractor.d.ts +9 -0
- package/dist/core/beliefs/extractor.js +113 -0
- package/dist/core/beliefs/store.d.ts +46 -0
- package/dist/core/beliefs/store.js +466 -0
- package/dist/core/beliefs/types.d.ts +28 -0
- package/dist/core/beliefs/types.js +2 -0
- package/dist/core/commands/mcp-server.d.ts +0 -1
- package/dist/core/commands/mcp-server.js +4 -737
- package/dist/core/commands/remember.d.ts +24 -0
- package/dist/core/commands/remember.js +144 -0
- package/dist/core/{toon.d.ts → compression.d.ts} +6 -4
- package/dist/core/{toon.js → compression.js} +8 -8
- package/dist/core/context/agent-context.js +1 -1
- package/dist/core/embeddings/embeddings.d.ts +29 -0
- package/dist/core/embeddings/embeddings.js +546 -0
- package/dist/core/embeddings/google-multimodal.js +6 -2
- package/dist/core/{local-embeddings.d.ts → embeddings/local-embeddings.d.ts} +1 -1
- package/dist/core/embeddings/local-embeddings.js +11 -0
- package/dist/core/embeddings/qmd-client.js +1 -1
- package/dist/core/embeddings/transformers-local.d.ts +64 -0
- package/dist/core/embeddings/transformers-local.js +213 -0
- package/dist/core/embeddings.d.ts +1 -28
- package/dist/core/embeddings.js +2 -453
- package/dist/core/graph/entity-deduplicator.d.ts +24 -0
- package/dist/core/graph/entity-deduplicator.js +183 -0
- package/dist/core/graph/graph-builder.d.ts +46 -0
- package/dist/core/graph/graph-builder.js +174 -0
- package/dist/core/graph/graph-traversal.d.ts +80 -0
- package/dist/core/graph/graph-traversal.js +315 -0
- package/dist/core/graph/index.d.ts +19 -0
- package/dist/core/graph/index.js +13 -0
- package/dist/core/graph/llm-entity-extractor.d.ts +49 -0
- package/dist/core/graph/llm-entity-extractor.js +313 -0
- package/dist/core/graph/multi-hop-retrieval.d.ts +48 -0
- package/dist/core/graph/multi-hop-retrieval.js +215 -0
- package/dist/core/graph/relationship-extractor.d.ts +48 -0
- package/dist/core/graph/relationship-extractor.js +351 -0
- package/dist/core/hooks/agent-hooks.d.ts +10 -1
- package/dist/core/hooks/agent-hooks.js +301 -24
- package/dist/core/hot-cache.d.ts +86 -0
- package/dist/core/hot-cache.js +285 -0
- package/dist/core/index.d.ts +9 -9
- package/dist/core/index.js +9 -12
- package/dist/core/ingestion/core-memory.d.ts +2 -2
- package/dist/core/ingestion/core-memory.js +3 -3
- package/dist/core/ingestion/learnings.js +3 -0
- package/dist/core/ingestion/signal-engine.d.ts +41 -0
- package/dist/core/ingestion/signal-engine.js +201 -0
- package/dist/core/{obsidian-vault.d.ts → integrations/obsidian-vault.d.ts} +2 -1
- package/dist/core/{obsidian-vault.js → integrations/obsidian-vault.js} +69 -7
- package/dist/core/lib/parse-embedding.d.ts +9 -0
- package/dist/core/lib/parse-embedding.js +58 -0
- package/dist/core/lib/schemas.d.ts +57 -54
- package/dist/core/lib/types.d.ts +45 -0
- package/dist/core/lib/types.js +6 -0
- package/dist/core/lib/utils.d.ts +4 -0
- package/dist/core/lib/utils.js +55 -0
- package/dist/core/lifecycle.d.ts +0 -1
- package/dist/core/lifecycle.js +13 -23
- package/dist/core/logger.d.ts +1 -0
- package/dist/core/logger.js +14 -8
- package/dist/core/mcp/tools.d.ts +0 -2
- package/dist/core/mcp/tools.js +0 -87
- package/dist/core/mcp/types.d.ts +25 -253
- package/dist/core/mcp/types.js +2 -2
- package/dist/core/memory/categorizer.js +1 -0
- package/dist/core/memory/consolidation.js +2 -28
- package/dist/core/memory/entity-extractor.d.ts +4 -0
- package/dist/core/memory/entity-extractor.js +30 -16
- package/dist/core/memory/explain.d.ts +18 -0
- package/dist/core/memory/explain.js +92 -0
- package/dist/core/memory/fact-deriver.d.ts +31 -0
- package/dist/core/memory/fact-deriver.js +236 -0
- package/dist/core/memory/hybrid-retrieval.d.ts +14 -16
- package/dist/core/memory/hybrid-retrieval.js +25 -127
- package/dist/core/memory/hybrid-scorer.js +6 -23
- package/dist/core/memory/hybrid-search.d.ts +10 -7
- package/dist/core/memory/hybrid-search.js +458 -221
- package/dist/core/memory/importance.d.ts +0 -17
- package/dist/core/memory/importance.js +1 -58
- package/dist/core/memory/index.d.ts +1 -0
- package/dist/core/memory/index.js +1 -0
- package/dist/core/memory/memories.d.ts +13 -17
- package/dist/core/memory/memories.js +78 -75
- package/dist/core/memory/memory-lifecycle.d.ts +2 -2
- package/dist/core/memory/memory-lifecycle.js +10 -18
- package/dist/core/memory/normalization.d.ts +1 -16
- package/dist/core/memory/path-strengthener.d.ts +39 -0
- package/dist/core/memory/path-strengthener.js +150 -0
- package/dist/core/memory/query-processor.js +37 -3
- package/dist/core/memory/retrieval-feedback.d.ts +70 -0
- package/dist/core/memory/retrieval-feedback.js +213 -0
- package/dist/core/memory/stale-cleaner.d.ts +26 -0
- package/dist/core/memory/stale-cleaner.js +97 -0
- package/dist/core/memory/stats.d.ts +10 -0
- package/dist/core/memory/stats.js +8 -3
- package/dist/core/memory/trigger-detector.d.ts +8 -1
- package/dist/core/memory/trigger-detector.js +42 -5
- package/dist/core/places/index.d.ts +1 -1
- package/dist/core/places/index.js +1 -1
- package/dist/core/places/places.d.ts +13 -13
- package/dist/core/places/places.js +27 -27
- package/dist/core/places/rules.js +23 -23
- package/dist/core/places/walking.d.ts +3 -3
- package/dist/core/places/walking.js +7 -7
- package/dist/core/projects.js +8 -0
- package/dist/core/runtime/trust-report.d.ts +102 -0
- package/dist/core/runtime/trust-report.js +107 -0
- package/dist/core/runtime/trust-state.d.ts +12 -0
- package/dist/core/runtime/trust-state.js +309 -0
- package/dist/core/scheduler/cron-scheduler.d.ts +1 -1
- package/dist/core/scheduler/cron-scheduler.js +164 -3
- package/dist/core/scheduler/job-runner.js +1 -1
- package/dist/core/search/qmd-wrapper.d.ts +36 -0
- package/dist/core/search/qmd-wrapper.js +58 -0
- package/dist/core/session/auto-load.js +28 -3
- package/dist/core/session/entity-tracker.d.ts +62 -0
- package/dist/core/session/entity-tracker.js +287 -0
- package/dist/core/session/reference-resolver.d.ts +26 -0
- package/dist/core/session/reference-resolver.js +121 -0
- package/dist/core/session/self-iteration-job.d.ts +15 -0
- package/dist/core/session/self-iteration-job.js +163 -58
- package/dist/core/session/working-set.d.ts +50 -0
- package/dist/core/session/working-set.js +212 -0
- package/dist/core/snapshots/creation.d.ts +2 -8
- package/dist/core/snapshots/creation.js +3 -12
- package/dist/core/utils/summarization-helpers.d.ts +0 -4
- package/dist/core/utils/summarization-helpers.js +1 -6
- package/dist/db/bootstrap.d.ts +2 -0
- package/dist/db/bootstrap.js +229 -280
- package/dist/db/drizzle/schema-sqlite.d.ts +702 -1
- package/dist/db/drizzle/schema-sqlite.js +83 -4
- package/dist/db/drizzle/schema.d.ts +653 -1
- package/dist/db/drizzle/schema.js +93 -4
- package/dist/db/migrations/associations.d.ts +6 -0
- package/dist/db/migrations/associations.js +29 -0
- package/dist/db/migrations/beliefs.d.ts +10 -0
- package/dist/db/migrations/beliefs.js +76 -0
- package/dist/db/migrations/core-memory.d.ts +6 -0
- package/dist/db/migrations/core-memory.js +29 -0
- package/dist/db/migrations/fts.d.ts +6 -0
- package/dist/db/migrations/fts.js +52 -0
- package/dist/db/migrations/index.d.ts +25 -0
- package/dist/db/migrations/index.js +51 -0
- package/dist/db/migrations/indexes.d.ts +6 -0
- package/dist/db/migrations/indexes.js +30 -0
- package/dist/db/migrations/learnings.d.ts +7 -0
- package/dist/db/migrations/learnings.js +26 -0
- package/dist/db/migrations/maintenance.d.ts +6 -0
- package/dist/db/migrations/maintenance.js +61 -0
- package/dist/db/migrations/memories.d.ts +7 -0
- package/dist/db/migrations/memories.js +16 -0
- package/dist/db/migrations/memory-places.d.ts +6 -0
- package/dist/db/migrations/memory-places.js +29 -0
- package/dist/db/migrations/places.d.ts +6 -0
- package/dist/db/migrations/places.js +43 -0
- package/dist/db/migrations/projects.d.ts +3 -0
- package/dist/db/migrations/projects.js +13 -0
- package/dist/db/migrations/tier-conversion.d.ts +7 -0
- package/dist/db/migrations/tier-conversion.js +20 -0
- package/dist/db/schema/beliefs.d.ts +9 -0
- package/dist/db/schema/beliefs.js +46 -0
- package/dist/db/schema/generator.d.ts +38 -0
- package/dist/db/schema/generator.js +108 -0
- package/dist/db/schema/index.d.ts +19 -20
- package/dist/db/schema/index.js +25 -79
- package/dist/db/schema/learnings.d.ts +7 -0
- package/dist/db/schema/learnings.js +30 -0
- package/dist/db/schema/memories.d.ts +7 -0
- package/dist/db/schema/memories.js +81 -0
- package/dist/db/schema/projects.d.ts +4 -0
- package/dist/db/schema/projects.js +31 -0
- package/dist/packages/mcp/src/index.d.ts +3 -0
- package/dist/packages/mcp/src/index.js +733 -0
- package/mcp.json.example +8 -11
- package/package.json +57 -76
- package/packages/cli/package.json +22 -0
- package/packages/cli/src/commands/clean.ts +68 -0
- package/packages/cli/src/commands/context.ts +79 -0
- package/packages/cli/src/commands/doctor.ts +357 -0
- package/packages/cli/src/commands/forget.ts +72 -0
- package/packages/cli/src/commands/health.ts +36 -0
- package/packages/cli/src/commands/inspect.ts +41 -0
- package/packages/cli/src/commands/link.ts +50 -0
- package/packages/cli/src/commands/migrate.ts +93 -0
- package/packages/cli/src/commands/recall.ts +99 -0
- package/packages/cli/src/commands/recent.ts +57 -0
- package/packages/cli/src/commands/remember.ts +139 -0
- package/packages/cli/src/commands/run.ts +58 -0
- package/packages/cli/src/commands/stale.ts +43 -0
- package/packages/cli/src/commands/stats.ts +42 -0
- package/packages/cli/src/index.ts +57 -0
- package/packages/cli/tsconfig.json +24 -0
- package/packages/mcp/package.json +26 -0
- package/packages/mcp/src/index.ts +877 -0
- package/packages/mcp/tsconfig.json +20 -0
- package/skills/squish-memory/SKILL.md +38 -35
- package/skills/squish-memory/{scripts/install.sh → install.sh} +1 -1
- package/skills/squish-memory/references/claude-desktop.json +12 -0
- package/skills/squish-memory/references/openclaw.json +13 -0
- package/skills/squish-memory/references/opencode.json +14 -0
- package/config/hooks/claude-code-hooks.json +0 -39
- package/config/hooks/cursor-hooks.json +0 -30
- package/config/hooks/opencode-hooks.json +0 -30
- package/config/hooks/windsurf-hooks.json +0 -30
- package/config/mcp-cli-fallback-policy.json +0 -22
- package/config/mcp.json +0 -38
- package/config/plugin-manifest.json +0 -101
- package/config/plugin-manifest.schema.json +0 -244
- package/config/plugin.json +0 -32
- package/config/remote-memory-policy.json +0 -32
- package/core/commands/context-paging.md +0 -51
- package/core/commands/context-status.md +0 -22
- package/core/commands/context.md +0 -5
- package/core/commands/core-memory.md +0 -56
- package/core/commands/health.md +0 -5
- package/core/commands/init.md +0 -39
- package/core/commands/merge.md +0 -113
- package/core/commands/recall.md +0 -5
- package/core/commands/remember.md +0 -11
- package/core/commands/search.md +0 -10
- package/dist/core/commands/managed-sync.d.ts +0 -10
- package/dist/core/commands/managed-sync.js +0 -64
- package/dist/core/external-folder/index.d.ts +0 -102
- package/dist/core/external-folder/index.js +0 -294
- package/dist/core/namespaces/index.d.ts +0 -71
- package/dist/core/namespaces/index.js +0 -305
- package/dist/core/namespaces/uri-parser.d.ts +0 -31
- package/dist/core/namespaces/uri-parser.js +0 -74
- package/dist/core/search/qmd-search.d.ts +0 -61
- package/dist/core/search/qmd-search.js +0 -178
- package/dist/core/session-hooks/self-iteration-job.d.ts +0 -20
- package/dist/core/session-hooks/self-iteration-job.js +0 -282
- package/dist/core/session-hooks/session-hooks.d.ts +0 -18
- package/dist/core/session-hooks/session-hooks.js +0 -58
- package/dist/core/snapshots.d.ts +0 -29
- package/dist/core/snapshots.js +0 -220
- package/dist/core/sync/qmd-sync.d.ts +0 -94
- package/dist/core/sync/qmd-sync.js +0 -201
- package/dist/index.d.ts +0 -7
- package/dist/index.js +0 -1677
- package/dist/vendor/sql.js/sql-wasm.wasm +0 -0
- package/dist/webui/server.d.ts +0 -5
- package/dist/webui/server.js +0 -642
- package/generated/mcp/manifest.json +0 -23
- package/generated/mcp/mcp-servers.json +0 -25
- package/generated/mcp/mcporter.json +0 -34
- package/generated/mcp/openclaw-memory-qmd.json +0 -17
- package/generated/mcp/runtime.json +0 -12
- package/scripts/README.md +0 -60
- package/scripts/build-release.sh +0 -36
- package/scripts/check-secrets.js +0 -132
- package/scripts/copy-runtime-assets.mjs +0 -26
- package/scripts/generate-mcp.mjs +0 -264
- package/scripts/github-release.sh +0 -77
- package/scripts/init-dirs.mjs +0 -13
- package/scripts/install-claude-code.sh +0 -85
- package/scripts/install-cursor.sh +0 -56
- package/scripts/install-hooks.sh +0 -73
- package/scripts/install-interactive.mjs +0 -357
- package/scripts/install-opencode.sh +0 -75
- package/scripts/install-plugin.mjs +0 -415
- package/scripts/install-windsurf.sh +0 -67
- package/scripts/remote-preflight.mjs +0 -62
- package/scripts/squish-fallback.mjs +0 -132
- package/scripts/test-interactive.mjs +0 -131
- package/scripts/verify-mcp.mjs +0 -214
- package/skills/squish-memory/scripts/install.mjs +0 -335
- package/skills/squish-memory/write_skill.js +0 -2
|
@@ -5,8 +5,11 @@
|
|
|
5
5
|
import { sql, eq } from 'drizzle-orm';
|
|
6
6
|
import { getDb } from '../../db/index.js';
|
|
7
7
|
import { getSchema } from '../../db/schema.js';
|
|
8
|
-
import {
|
|
8
|
+
import { getProjectById } from '../projects.js';
|
|
9
|
+
import { rememberMemory, search } from '../memory/memories.js';
|
|
10
|
+
import { serializeMetadata, deserializeMetadata } from '../memory/serialization.js';
|
|
9
11
|
import { logger } from '../logger.js';
|
|
12
|
+
import { generateExtractiveSummary, extractMessageContent } from '../utils/content-extraction.js';
|
|
10
13
|
const DEFAULT_CONFIG = {
|
|
11
14
|
enabled: true,
|
|
12
15
|
extractFacts: true,
|
|
@@ -15,6 +18,52 @@ const DEFAULT_CONFIG = {
|
|
|
15
18
|
minMessageCount: 5,
|
|
16
19
|
maxMessagesToProcess: 50,
|
|
17
20
|
};
|
|
21
|
+
const MIN_CONFIDENCE_TO_STORE = 75;
|
|
22
|
+
const FORBIDDEN_BRAND_TERMS = new RegExp(`\\b(?:${['mem' + '\\s*' + 'palace', 'mem' + '-' + 'palace', 'om' + 'ni'].join('|')})\\b`, 'i');
|
|
23
|
+
const LOW_SIGNAL_PATTERNS = [
|
|
24
|
+
/^\s*(?:thanks?|thank you|hello|hi|hey)\b/i,
|
|
25
|
+
/\b(?:can you|could you|please|help me|show me|explain|what is|how do i)\b/i,
|
|
26
|
+
/\b(?:i'll|i will|we will|let's|todo|task|goal|next step|follow up|remind me)\b/i,
|
|
27
|
+
/^\s*[-*]\s+\[[ x]\]/i,
|
|
28
|
+
];
|
|
29
|
+
const EXTRACTION_PATTERNS = [
|
|
30
|
+
{
|
|
31
|
+
pattern: /\b(?:i|we)\s+(?:decided|chose|picked|selected|settled on|agreed to use|agreed on)\b/i,
|
|
32
|
+
type: 'decision',
|
|
33
|
+
confidence: 90,
|
|
34
|
+
prefix: 'Decision',
|
|
35
|
+
},
|
|
36
|
+
{
|
|
37
|
+
pattern: /\b(?:final decision|decision)\s*:/i,
|
|
38
|
+
type: 'decision',
|
|
39
|
+
confidence: 90,
|
|
40
|
+
prefix: 'Decision',
|
|
41
|
+
},
|
|
42
|
+
{
|
|
43
|
+
pattern: /\b(?:i|we)\s+(?:prefer|like|dislike|hate|love)\b/i,
|
|
44
|
+
type: 'preference',
|
|
45
|
+
confidence: 85,
|
|
46
|
+
prefix: 'Preference',
|
|
47
|
+
},
|
|
48
|
+
{
|
|
49
|
+
pattern: /\b(?:my|our|the user's)\s+(?:preference|preferred)\b/i,
|
|
50
|
+
type: 'preference',
|
|
51
|
+
confidence: 85,
|
|
52
|
+
prefix: 'Preference',
|
|
53
|
+
},
|
|
54
|
+
{
|
|
55
|
+
pattern: /\b(?:remember|don't forget)\s+(?:that\s+)?\S+/i,
|
|
56
|
+
type: 'fact',
|
|
57
|
+
confidence: 80,
|
|
58
|
+
prefix: 'Fact',
|
|
59
|
+
},
|
|
60
|
+
{
|
|
61
|
+
pattern: /\b(?:project|repo|workspace|service|app)\s+\S+\s+(?:uses|runs on|depends on|requires|stores)\b/i,
|
|
62
|
+
type: 'fact',
|
|
63
|
+
confidence: 80,
|
|
64
|
+
prefix: 'Fact',
|
|
65
|
+
},
|
|
66
|
+
];
|
|
18
67
|
/**
|
|
19
68
|
* Build fact extraction prompt
|
|
20
69
|
*/
|
|
@@ -78,10 +127,75 @@ function parseExtractedFacts(llmResponse) {
|
|
|
78
127
|
return [];
|
|
79
128
|
}
|
|
80
129
|
}
|
|
130
|
+
function normalizeCaptureKey(content) {
|
|
131
|
+
return content
|
|
132
|
+
.toLowerCase()
|
|
133
|
+
.replace(/^(?:decision|preference|fact):\s*/i, '')
|
|
134
|
+
.replace(/['"`]/g, '')
|
|
135
|
+
.replace(/\s+/g, ' ')
|
|
136
|
+
.replace(/[^\w\s./:-]/g, '')
|
|
137
|
+
.trim();
|
|
138
|
+
}
|
|
139
|
+
function isLowSignalCapture(content) {
|
|
140
|
+
const text = content.trim();
|
|
141
|
+
if (text.length < 20 || text.split(/\s+/).length < 4)
|
|
142
|
+
return true;
|
|
143
|
+
if (text.endsWith('?'))
|
|
144
|
+
return true;
|
|
145
|
+
if (FORBIDDEN_BRAND_TERMS.test(text))
|
|
146
|
+
return true;
|
|
147
|
+
return LOW_SIGNAL_PATTERNS.some((pattern) => pattern.test(text));
|
|
148
|
+
}
|
|
149
|
+
function splitCandidateStatements(content) {
|
|
150
|
+
return content
|
|
151
|
+
.split(/\n+|(?<=[.!?])\s+/)
|
|
152
|
+
.map((part) => part.trim())
|
|
153
|
+
.filter(Boolean);
|
|
154
|
+
}
|
|
155
|
+
export function extractDurableSelfIterationFacts(messages) {
|
|
156
|
+
const captures = new Map();
|
|
157
|
+
for (const msg of messages) {
|
|
158
|
+
if (msg.role !== 'user')
|
|
159
|
+
continue;
|
|
160
|
+
for (const statement of splitCandidateStatements(msg.content)) {
|
|
161
|
+
if (isLowSignalCapture(statement))
|
|
162
|
+
continue;
|
|
163
|
+
for (const { pattern, type, confidence, prefix } of EXTRACTION_PATTERNS) {
|
|
164
|
+
if (!pattern.test(statement))
|
|
165
|
+
continue;
|
|
166
|
+
const normalizedStatement = statement.replace(/^(?:decision|preference|fact):\s*/i, '');
|
|
167
|
+
const content = `${prefix}: ${normalizedStatement}`;
|
|
168
|
+
const key = `${type}:${normalizeCaptureKey(content)}`;
|
|
169
|
+
const existing = captures.get(key);
|
|
170
|
+
if (!existing || confidence > existing.confidence) {
|
|
171
|
+
captures.set(key, { content, type, confidence });
|
|
172
|
+
}
|
|
173
|
+
}
|
|
174
|
+
}
|
|
175
|
+
}
|
|
176
|
+
return Array.from(captures.values()).filter((fact) => fact.confidence >= MIN_CONFIDENCE_TO_STORE);
|
|
177
|
+
}
|
|
178
|
+
async function hasSimilarSelfIterationMemory(fact, projectPath) {
|
|
179
|
+
const matches = await search({
|
|
180
|
+
query: fact.content,
|
|
181
|
+
type: fact.type,
|
|
182
|
+
project: projectPath,
|
|
183
|
+
limit: 5,
|
|
184
|
+
});
|
|
185
|
+
const factKey = normalizeCaptureKey(fact.content);
|
|
186
|
+
return matches.some((match) => {
|
|
187
|
+
const matchMetadata = match.metadata ?? {};
|
|
188
|
+
if (matchMetadata.extractionMethod !== 'self-iteration')
|
|
189
|
+
return false;
|
|
190
|
+
if ((match.similarity ?? 0) >= 0.92)
|
|
191
|
+
return true;
|
|
192
|
+
return normalizeCaptureKey(match.content) === factKey;
|
|
193
|
+
});
|
|
194
|
+
}
|
|
81
195
|
/**
|
|
82
196
|
* Get conversations ready for self-iteration
|
|
83
197
|
*/
|
|
84
|
-
async function getConversationsForIteration(
|
|
198
|
+
async function getConversationsForIteration(minMessageCount) {
|
|
85
199
|
const db = await getDb();
|
|
86
200
|
if (!db)
|
|
87
201
|
return [];
|
|
@@ -93,11 +207,15 @@ async function getConversationsForIteration(maxMessages) {
|
|
|
93
207
|
// 3. Have enough messages (messageCount >= minMessageCount)
|
|
94
208
|
const conversations = await sqliteDb.select()
|
|
95
209
|
.from(schema.conversations)
|
|
96
|
-
.where(sql `${schema.conversations.endedAt} IS NOT NULL
|
|
97
|
-
AND
|
|
98
|
-
AND ${schema.conversations.messageCount} >= ?`)
|
|
210
|
+
.where(sql `${schema.conversations.endedAt} IS NOT NULL
|
|
211
|
+
AND ${schema.conversations.messageCount} >= ${minMessageCount}`)
|
|
99
212
|
.limit(10);
|
|
100
|
-
return conversations
|
|
213
|
+
return conversations
|
|
214
|
+
.map((conversation) => ({
|
|
215
|
+
...conversation,
|
|
216
|
+
metadata: deserializeMetadata(conversation.metadata ?? null),
|
|
217
|
+
}))
|
|
218
|
+
.filter((conversation) => !conversation.metadata?.selfIterationProcessed);
|
|
101
219
|
}
|
|
102
220
|
/**
|
|
103
221
|
* Get messages for a conversation
|
|
@@ -129,9 +247,18 @@ async function markConversationProcessed(conversationId) {
|
|
|
129
247
|
return;
|
|
130
248
|
const schema = await getSchema();
|
|
131
249
|
const sqliteDb = db;
|
|
250
|
+
const rows = await sqliteDb.select()
|
|
251
|
+
.from(schema.conversations)
|
|
252
|
+
.where(eq(schema.conversations.id, conversationId))
|
|
253
|
+
.limit(1);
|
|
254
|
+
const existingMetadata = deserializeMetadata(rows[0]?.metadata ?? null) ?? {};
|
|
132
255
|
await sqliteDb.update(schema.conversations)
|
|
133
256
|
.set({
|
|
134
|
-
metadata:
|
|
257
|
+
metadata: serializeMetadata({
|
|
258
|
+
...existingMetadata,
|
|
259
|
+
selfIterationProcessed: true,
|
|
260
|
+
selfIterationProcessedAt: new Date().toISOString(),
|
|
261
|
+
}),
|
|
135
262
|
})
|
|
136
263
|
.where(eq(schema.conversations.id, conversationId));
|
|
137
264
|
}
|
|
@@ -149,65 +276,43 @@ async function processConversation(conversation, config) {
|
|
|
149
276
|
if (messagesToProcess.length === 0) {
|
|
150
277
|
return { memoriesCreated, summariesCreated };
|
|
151
278
|
}
|
|
152
|
-
// Extract facts
|
|
279
|
+
// Extract facts using improved pattern matching
|
|
153
280
|
if (config.extractFacts) {
|
|
154
|
-
const
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
const extractedFacts = [];
|
|
158
|
-
for (const msg of messagesToProcess) {
|
|
159
|
-
if (msg.role === 'user') {
|
|
160
|
-
const content = msg.content.toLowerCase();
|
|
161
|
-
// Look for user preferences
|
|
162
|
-
if (content.includes('i want') || content.includes('i prefer') || content.includes('i like')) {
|
|
163
|
-
extractedFacts.push({
|
|
164
|
-
content: `User preference: ${msg.content}`,
|
|
165
|
-
type: 'preference',
|
|
166
|
-
confidence: 70,
|
|
167
|
-
});
|
|
168
|
-
}
|
|
169
|
-
// Look for decisions
|
|
170
|
-
if (content.includes('i will') || content.includes('i decide') || content.includes('let\'s')) {
|
|
171
|
-
extractedFacts.push({
|
|
172
|
-
content: `Decision: ${msg.content}`,
|
|
173
|
-
type: 'decision',
|
|
174
|
-
confidence: 80,
|
|
175
|
-
});
|
|
176
|
-
}
|
|
177
|
-
}
|
|
178
|
-
}
|
|
281
|
+
const extractedFacts = extractDurableSelfIterationFacts(messagesToProcess);
|
|
282
|
+
const project = conversation.projectId ? await getProjectById(conversation.projectId) : null;
|
|
283
|
+
const projectPath = project?.path;
|
|
179
284
|
// Store extracted facts as memories
|
|
180
285
|
for (const fact of extractedFacts) {
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
type: fact.type,
|
|
186
|
-
project: conversation.projectId,
|
|
187
|
-
metadata: {
|
|
188
|
-
extractionMethod: 'self-iteration',
|
|
189
|
-
confidence: fact.confidence,
|
|
190
|
-
conversationId: conversation.id,
|
|
191
|
-
sessionId: conversation.sessionId,
|
|
192
|
-
},
|
|
193
|
-
});
|
|
194
|
-
memoriesCreated++;
|
|
195
|
-
logger.info(`[SelfIteration] Extracted memory: ${fact.type} - ${fact.content.substring(0, 50)}...`);
|
|
196
|
-
}
|
|
197
|
-
catch (error) {
|
|
198
|
-
logger.error(`[SelfIteration] Failed to store memory:`, error);
|
|
286
|
+
try {
|
|
287
|
+
if (await hasSimilarSelfIterationMemory(fact, projectPath)) {
|
|
288
|
+
logger.debug(`[SelfIteration] Suppressed duplicate memory: ${fact.type} - ${fact.content.substring(0, 50)}...`);
|
|
289
|
+
continue;
|
|
199
290
|
}
|
|
291
|
+
await rememberMemory({
|
|
292
|
+
content: fact.content,
|
|
293
|
+
type: fact.type,
|
|
294
|
+
project: projectPath,
|
|
295
|
+
metadata: {
|
|
296
|
+
extractionMethod: 'self-iteration',
|
|
297
|
+
confidence: fact.confidence,
|
|
298
|
+
conversationId: conversation.id,
|
|
299
|
+
sessionId: conversation.sessionId,
|
|
300
|
+
},
|
|
301
|
+
source: 'self-iteration',
|
|
302
|
+
});
|
|
303
|
+
memoriesCreated++;
|
|
304
|
+
logger.info(`[SelfIteration] Extracted memory: ${fact.type} - ${fact.content.substring(0, 50)}...`);
|
|
305
|
+
}
|
|
306
|
+
catch (error) {
|
|
307
|
+
logger.error(`[SelfIteration] Failed to store memory:`, error);
|
|
200
308
|
}
|
|
201
309
|
}
|
|
202
310
|
}
|
|
203
311
|
// Generate summary
|
|
204
312
|
if (config.generateSummaries && messagesToProcess.length > 0) {
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
const userMessages = messagesToProcess.filter(m => m.role === 'user');
|
|
209
|
-
const lastMessage = userMessages[userMessages.length - 1]?.content || '';
|
|
210
|
-
const summary = lastMessage.substring(0, Math.min(250, lastMessage.length));
|
|
313
|
+
// Use extractive summarization for better results
|
|
314
|
+
const extracted = extractMessageContent(messagesToProcess);
|
|
315
|
+
const summary = generateExtractiveSummary(extracted);
|
|
211
316
|
// Update conversation with summary
|
|
212
317
|
const db = await getDb();
|
|
213
318
|
const schema = await getSchema();
|
|
@@ -234,7 +339,7 @@ const selfIterationHandler = async (context) => {
|
|
|
234
339
|
return { recordsProcessed: 0, summary: { status: 'disabled' } };
|
|
235
340
|
}
|
|
236
341
|
try {
|
|
237
|
-
const conversations = await getConversationsForIteration(config.
|
|
342
|
+
const conversations = await getConversationsForIteration(config.minMessageCount || DEFAULT_CONFIG.minMessageCount);
|
|
238
343
|
if (conversations.length === 0) {
|
|
239
344
|
logger.info('[SelfIteration] No conversations to process');
|
|
240
345
|
return { recordsProcessed: 0, summary: { status: 'no_conversations' } };
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
export interface WorkingSetCommand {
|
|
2
|
+
command: string;
|
|
3
|
+
outcome?: string;
|
|
4
|
+
at: string;
|
|
5
|
+
}
|
|
6
|
+
export interface SessionWorkingSet {
|
|
7
|
+
activeFiles: string[];
|
|
8
|
+
activePlaces: string[];
|
|
9
|
+
graphEntities: string[];
|
|
10
|
+
recentCommands: WorkingSetCommand[];
|
|
11
|
+
currentHypotheses: string[];
|
|
12
|
+
recentFailures: string[];
|
|
13
|
+
recentAttempts: string[];
|
|
14
|
+
projectPath?: string;
|
|
15
|
+
sessionId: string;
|
|
16
|
+
signalStats: {
|
|
17
|
+
captured: number;
|
|
18
|
+
suppressed: number;
|
|
19
|
+
sessionOnly: number;
|
|
20
|
+
durable: number;
|
|
21
|
+
durableWithRaw: number;
|
|
22
|
+
tokensSaved: number;
|
|
23
|
+
placeRouted: number;
|
|
24
|
+
graphEnriched: number;
|
|
25
|
+
};
|
|
26
|
+
recentEvents: Array<{
|
|
27
|
+
classification: string;
|
|
28
|
+
content: string;
|
|
29
|
+
target?: string;
|
|
30
|
+
hash?: string;
|
|
31
|
+
at: string;
|
|
32
|
+
}>;
|
|
33
|
+
}
|
|
34
|
+
export declare function getSessionWorkingSet(sessionId: string, projectPath?: string): Promise<SessionWorkingSet>;
|
|
35
|
+
export declare function recordSessionSignal(input: {
|
|
36
|
+
sessionId: string;
|
|
37
|
+
projectPath: string;
|
|
38
|
+
classification: 'discard' | 'session-only' | 'durable-distilled' | 'durable-raw+distilled';
|
|
39
|
+
distilledContent: string;
|
|
40
|
+
toolName: string;
|
|
41
|
+
target?: string;
|
|
42
|
+
metadata?: Record<string, unknown>;
|
|
43
|
+
}): Promise<SessionWorkingSet>;
|
|
44
|
+
export declare function compactSessionWorkingSet(sessionId: string, projectPath?: string): Promise<{
|
|
45
|
+
summary: string;
|
|
46
|
+
workingSet: SessionWorkingSet;
|
|
47
|
+
}>;
|
|
48
|
+
export declare function getProjectSignalStats(projectPath: string): Promise<any>;
|
|
49
|
+
export declare function getLatestProjectWorkingSetSummary(projectPath: string): Promise<string>;
|
|
50
|
+
//# sourceMappingURL=working-set.d.ts.map
|
|
@@ -0,0 +1,212 @@
|
|
|
1
|
+
import { randomUUID } from 'crypto';
|
|
2
|
+
import { eq } from 'drizzle-orm';
|
|
3
|
+
import { getDbClient } from '../lib/db-client.js';
|
|
4
|
+
import { ensureProject, getProjectByPath } from '../projects.js';
|
|
5
|
+
import { deserializeMetadata, serializeMetadata } from '../memory/serialization.js';
|
|
6
|
+
const EMPTY_WORKING_SET = (sessionId, projectPath) => ({
|
|
7
|
+
activeFiles: [],
|
|
8
|
+
activePlaces: [],
|
|
9
|
+
graphEntities: [],
|
|
10
|
+
recentCommands: [],
|
|
11
|
+
currentHypotheses: [],
|
|
12
|
+
recentFailures: [],
|
|
13
|
+
recentAttempts: [],
|
|
14
|
+
projectPath,
|
|
15
|
+
sessionId,
|
|
16
|
+
signalStats: {
|
|
17
|
+
captured: 0,
|
|
18
|
+
suppressed: 0,
|
|
19
|
+
sessionOnly: 0,
|
|
20
|
+
durable: 0,
|
|
21
|
+
durableWithRaw: 0,
|
|
22
|
+
tokensSaved: 0,
|
|
23
|
+
placeRouted: 0,
|
|
24
|
+
graphEnriched: 0,
|
|
25
|
+
},
|
|
26
|
+
recentEvents: [],
|
|
27
|
+
});
|
|
28
|
+
function dedupe(items, limit) {
|
|
29
|
+
return [...new Set(items.filter(Boolean))].slice(0, limit);
|
|
30
|
+
}
|
|
31
|
+
function normalizeSessionMetadata(metadata, sessionId, projectPath) {
|
|
32
|
+
const parsed = (metadata ?? {});
|
|
33
|
+
return {
|
|
34
|
+
...EMPTY_WORKING_SET(sessionId, projectPath),
|
|
35
|
+
...parsed,
|
|
36
|
+
activeFiles: parsed.activeFiles ?? [],
|
|
37
|
+
activePlaces: parsed.activePlaces ?? [],
|
|
38
|
+
graphEntities: parsed.graphEntities ?? [],
|
|
39
|
+
recentCommands: parsed.recentCommands ?? [],
|
|
40
|
+
currentHypotheses: parsed.currentHypotheses ?? [],
|
|
41
|
+
recentFailures: parsed.recentFailures ?? [],
|
|
42
|
+
recentAttempts: parsed.recentAttempts ?? [],
|
|
43
|
+
recentEvents: parsed.recentEvents ?? [],
|
|
44
|
+
signalStats: {
|
|
45
|
+
...EMPTY_WORKING_SET(sessionId, projectPath).signalStats,
|
|
46
|
+
...(parsed.signalStats ?? {}),
|
|
47
|
+
},
|
|
48
|
+
};
|
|
49
|
+
}
|
|
50
|
+
async function getOrCreateContextSession(sessionId, projectPath) {
|
|
51
|
+
const { db, schema, raw } = await getDbClient();
|
|
52
|
+
const project = await ensureProject(projectPath);
|
|
53
|
+
const existing = await db
|
|
54
|
+
.select()
|
|
55
|
+
.from(schema.contextSessions)
|
|
56
|
+
.where(eq(schema.contextSessions.sessionId, sessionId))
|
|
57
|
+
.limit(1);
|
|
58
|
+
if (existing[0])
|
|
59
|
+
return { row: existing[0], projectId: project?.id ?? null, db, schema };
|
|
60
|
+
const sqlite = raw.$client;
|
|
61
|
+
const id = randomUUID();
|
|
62
|
+
const metadata = serializeMetadata(EMPTY_WORKING_SET(sessionId, projectPath));
|
|
63
|
+
sqlite.prepare(`
|
|
64
|
+
INSERT INTO context_sessions (
|
|
65
|
+
id, session_id, project_id, metadata, token_budget, tokens_used, core_memory_tokens, loaded_memories_tokens, created_at, updated_at
|
|
66
|
+
) VALUES (?, ?, ?, ?, 8000, 0, 0, 0, CURRENT_TIMESTAMP, CURRENT_TIMESTAMP)
|
|
67
|
+
`).run(id, sessionId, project?.id ?? null, metadata);
|
|
68
|
+
const inserted = await db
|
|
69
|
+
.select()
|
|
70
|
+
.from(schema.contextSessions)
|
|
71
|
+
.where(eq(schema.contextSessions.sessionId, sessionId))
|
|
72
|
+
.limit(1);
|
|
73
|
+
return { row: inserted[0], projectId: project?.id ?? null, db, schema };
|
|
74
|
+
}
|
|
75
|
+
export async function getSessionWorkingSet(sessionId, projectPath) {
|
|
76
|
+
const { db, schema } = await getDbClient();
|
|
77
|
+
const rows = await db
|
|
78
|
+
.select()
|
|
79
|
+
.from(schema.contextSessions)
|
|
80
|
+
.where(eq(schema.contextSessions.sessionId, sessionId))
|
|
81
|
+
.limit(1);
|
|
82
|
+
if (!rows[0])
|
|
83
|
+
return EMPTY_WORKING_SET(sessionId, projectPath);
|
|
84
|
+
return normalizeSessionMetadata(deserializeMetadata(rows[0].metadata ?? null), sessionId, projectPath);
|
|
85
|
+
}
|
|
86
|
+
export async function recordSessionSignal(input) {
|
|
87
|
+
const { row, db, schema } = await getOrCreateContextSession(input.sessionId, input.projectPath);
|
|
88
|
+
const current = normalizeSessionMetadata(deserializeMetadata(row.metadata ?? null), input.sessionId, input.projectPath);
|
|
89
|
+
const meta = input.metadata ?? {};
|
|
90
|
+
const now = new Date().toISOString();
|
|
91
|
+
const next = normalizeSessionMetadata(current, input.sessionId, input.projectPath);
|
|
92
|
+
next.activeFiles = dedupe([
|
|
93
|
+
...next.activeFiles,
|
|
94
|
+
...((meta.activeFiles ?? [])),
|
|
95
|
+
], 8);
|
|
96
|
+
next.activePlaces = dedupe([
|
|
97
|
+
...next.activePlaces,
|
|
98
|
+
...((meta.activePlaces ?? [])),
|
|
99
|
+
], 6);
|
|
100
|
+
next.graphEntities = dedupe([
|
|
101
|
+
...next.graphEntities,
|
|
102
|
+
...((meta.graphEntities ?? [])),
|
|
103
|
+
], 8);
|
|
104
|
+
const command = typeof meta.command === 'string' ? meta.command : undefined;
|
|
105
|
+
if (command) {
|
|
106
|
+
next.recentCommands = [{ command, outcome: typeof meta.outcome === 'string' ? meta.outcome : undefined, at: now }, ...next.recentCommands].slice(0, 8);
|
|
107
|
+
}
|
|
108
|
+
if (/hypothesis/i.test(input.distilledContent)) {
|
|
109
|
+
next.currentHypotheses = dedupe([input.distilledContent, ...next.currentHypotheses], 5);
|
|
110
|
+
}
|
|
111
|
+
if ((typeof meta.outcome === 'string' && meta.outcome === 'failure') || /fail|error|exception/i.test(input.distilledContent)) {
|
|
112
|
+
next.recentFailures = dedupe([input.target ?? input.distilledContent, ...next.recentFailures], 5);
|
|
113
|
+
}
|
|
114
|
+
next.recentAttempts = dedupe([input.distilledContent, ...next.recentAttempts], 8);
|
|
115
|
+
next.recentEvents = [
|
|
116
|
+
{
|
|
117
|
+
classification: input.classification,
|
|
118
|
+
content: input.distilledContent,
|
|
119
|
+
target: input.target,
|
|
120
|
+
hash: typeof meta.contentHash === 'string' ? meta.contentHash : undefined,
|
|
121
|
+
at: now,
|
|
122
|
+
},
|
|
123
|
+
...next.recentEvents,
|
|
124
|
+
].slice(0, 20);
|
|
125
|
+
if (input.classification === 'discard')
|
|
126
|
+
next.signalStats.suppressed += 1;
|
|
127
|
+
else
|
|
128
|
+
next.signalStats.captured += 1;
|
|
129
|
+
if (input.classification === 'session-only')
|
|
130
|
+
next.signalStats.sessionOnly += 1;
|
|
131
|
+
if (input.classification === 'durable-distilled')
|
|
132
|
+
next.signalStats.durable += 1;
|
|
133
|
+
if (input.classification === 'durable-raw+distilled')
|
|
134
|
+
next.signalStats.durableWithRaw += 1;
|
|
135
|
+
next.signalStats.tokensSaved += Number(meta.tokensSaved ?? 0);
|
|
136
|
+
next.signalStats.placeRouted += meta.placeRouted ? 1 : 0;
|
|
137
|
+
next.signalStats.graphEnriched += meta.graphEnriched ? 1 : 0;
|
|
138
|
+
await db
|
|
139
|
+
.update(schema.contextSessions)
|
|
140
|
+
.set({
|
|
141
|
+
metadata: serializeMetadata(next),
|
|
142
|
+
updatedAt: new Date(),
|
|
143
|
+
})
|
|
144
|
+
.where(eq(schema.contextSessions.sessionId, input.sessionId));
|
|
145
|
+
return next;
|
|
146
|
+
}
|
|
147
|
+
export async function compactSessionWorkingSet(sessionId, projectPath) {
|
|
148
|
+
const workingSet = await getSessionWorkingSet(sessionId, projectPath);
|
|
149
|
+
const lines = [];
|
|
150
|
+
if (workingSet.currentHypotheses.length > 0) {
|
|
151
|
+
lines.push(`Hypotheses: ${dedupe(workingSet.currentHypotheses, 3).join(' | ')}`);
|
|
152
|
+
}
|
|
153
|
+
if (workingSet.recentFailures.length > 0) {
|
|
154
|
+
lines.push(`Failures: ${dedupe(workingSet.recentFailures, 3).join(' | ')}`);
|
|
155
|
+
}
|
|
156
|
+
if (workingSet.activeFiles.length > 0) {
|
|
157
|
+
lines.push(`Active files: ${dedupe(workingSet.activeFiles, 5).join(', ')}`);
|
|
158
|
+
}
|
|
159
|
+
if (workingSet.activePlaces.length > 0) {
|
|
160
|
+
lines.push(`Active places: ${dedupe(workingSet.activePlaces, 4).join(', ')}`);
|
|
161
|
+
}
|
|
162
|
+
if (workingSet.graphEntities.length > 0) {
|
|
163
|
+
lines.push(`Graph entities: ${dedupe(workingSet.graphEntities, 4).join(', ')}`);
|
|
164
|
+
}
|
|
165
|
+
if (workingSet.recentCommands.length > 0) {
|
|
166
|
+
lines.push(`Recent commands: ${dedupe(workingSet.recentCommands.map((entry) => entry.command), 3).join(' | ')}`);
|
|
167
|
+
}
|
|
168
|
+
return {
|
|
169
|
+
summary: lines.join('\n'),
|
|
170
|
+
workingSet,
|
|
171
|
+
};
|
|
172
|
+
}
|
|
173
|
+
export async function getProjectSignalStats(projectPath) {
|
|
174
|
+
const { db, schema } = await getDbClient();
|
|
175
|
+
const project = await getProjectByPath(projectPath);
|
|
176
|
+
if (!project) {
|
|
177
|
+
return EMPTY_WORKING_SET('project-stats', projectPath).signalStats;
|
|
178
|
+
}
|
|
179
|
+
const rows = await db
|
|
180
|
+
.select()
|
|
181
|
+
.from(schema.contextSessions)
|
|
182
|
+
.where(eq(schema.contextSessions.projectId, project.id));
|
|
183
|
+
return rows.reduce((acc, row) => {
|
|
184
|
+
const workingSet = normalizeSessionMetadata(deserializeMetadata(row.metadata ?? null), row.sessionId, projectPath);
|
|
185
|
+
acc.captured += workingSet.signalStats.captured;
|
|
186
|
+
acc.suppressed += workingSet.signalStats.suppressed;
|
|
187
|
+
acc.sessionOnly += workingSet.signalStats.sessionOnly;
|
|
188
|
+
acc.durable += workingSet.signalStats.durable;
|
|
189
|
+
acc.durableWithRaw += workingSet.signalStats.durableWithRaw;
|
|
190
|
+
acc.tokensSaved += workingSet.signalStats.tokensSaved;
|
|
191
|
+
return acc;
|
|
192
|
+
}, { ...EMPTY_WORKING_SET('project-stats', projectPath).signalStats });
|
|
193
|
+
}
|
|
194
|
+
export async function getLatestProjectWorkingSetSummary(projectPath) {
|
|
195
|
+
const { db, schema } = await getDbClient();
|
|
196
|
+
const project = await getProjectByPath(projectPath);
|
|
197
|
+
if (!project)
|
|
198
|
+
return '';
|
|
199
|
+
const rows = await db
|
|
200
|
+
.select()
|
|
201
|
+
.from(schema.contextSessions)
|
|
202
|
+
.where(eq(schema.contextSessions.projectId, project.id));
|
|
203
|
+
const latest = rows.sort((a, b) => {
|
|
204
|
+
const left = new Date(a.updatedAt ?? a.createdAt ?? 0).getTime();
|
|
205
|
+
const right = new Date(b.updatedAt ?? b.createdAt ?? 0).getTime();
|
|
206
|
+
return right - left;
|
|
207
|
+
})[0];
|
|
208
|
+
if (!latest)
|
|
209
|
+
return '';
|
|
210
|
+
return compactSessionWorkingSet(latest.sessionId, projectPath).then((result) => result.summary);
|
|
211
|
+
}
|
|
212
|
+
//# sourceMappingURL=working-set.js.map
|
|
@@ -2,14 +2,8 @@
|
|
|
2
2
|
* Snapshot Creation Operations
|
|
3
3
|
* Functions for creating different types of memory snapshots
|
|
4
4
|
*/
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
removed?: string[];
|
|
8
|
-
changed?: Record<string, {
|
|
9
|
-
from: unknown;
|
|
10
|
-
to: unknown;
|
|
11
|
-
}>;
|
|
12
|
-
}
|
|
5
|
+
import { MemoryDiff, calculateDiff } from './comparison.js';
|
|
6
|
+
export { MemoryDiff, calculateDiff };
|
|
13
7
|
export declare function createBeforeSnapshot(memoryId: string): Promise<string>;
|
|
14
8
|
export declare function createAfterSnapshot(memoryId: string, beforeSnapshotId: string): Promise<{
|
|
15
9
|
snapshotId: string;
|
|
@@ -7,6 +7,9 @@ import { randomUUID } from 'crypto';
|
|
|
7
7
|
import { getDb } from '../../db/index.js';
|
|
8
8
|
import { getSchema } from '../../db/schema.js';
|
|
9
9
|
import { logger } from '../logger.js';
|
|
10
|
+
import { calculateDiff } from './comparison.js';
|
|
11
|
+
// Re-export for convenience
|
|
12
|
+
export { calculateDiff };
|
|
10
13
|
export async function createBeforeSnapshot(memoryId) {
|
|
11
14
|
try {
|
|
12
15
|
const db = await getDb();
|
|
@@ -111,16 +114,4 @@ function extractMetadata(memory) {
|
|
|
111
114
|
agentId: memory.agentId,
|
|
112
115
|
};
|
|
113
116
|
}
|
|
114
|
-
function calculateDiff(before, after) {
|
|
115
|
-
const beforeLines = before.split('\n');
|
|
116
|
-
const afterLines = after.split('\n');
|
|
117
|
-
const beforeSet = new Set(beforeLines);
|
|
118
|
-
const afterSet = new Set(afterLines);
|
|
119
|
-
const added = afterLines.filter(line => !beforeSet.has(line));
|
|
120
|
-
const removed = beforeLines.filter(line => !afterSet.has(line));
|
|
121
|
-
return {
|
|
122
|
-
added: added.length > 0 ? added : undefined,
|
|
123
|
-
removed: removed.length > 0 ? removed : undefined,
|
|
124
|
-
};
|
|
125
|
-
}
|
|
126
117
|
//# sourceMappingURL=creation.js.map
|
|
@@ -10,10 +10,6 @@ export declare function chunkMessages(messages: any[], chunkSize: number): any[]
|
|
|
10
10
|
* Get rolling window of messages
|
|
11
11
|
*/
|
|
12
12
|
export declare function getRollingWindow(messages: any[], windowSize: number): any[];
|
|
13
|
-
/**
|
|
14
|
-
* Estimate tokens in text (rough approximation)
|
|
15
|
-
*/
|
|
16
|
-
export declare function estimateTokens(text: string): number;
|
|
17
13
|
/**
|
|
18
14
|
* Calculate tokens saved by summarization
|
|
19
15
|
*/
|
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
* Shared Summarization Strategy Utilities
|
|
3
3
|
* Common patterns for different summarization approaches
|
|
4
4
|
*/
|
|
5
|
+
import { estimateTokens } from '../context/context-window.js';
|
|
5
6
|
/**
|
|
6
7
|
* Chunk messages for incremental summarization
|
|
7
8
|
*/
|
|
@@ -21,12 +22,6 @@ export function getRollingWindow(messages, windowSize) {
|
|
|
21
22
|
}
|
|
22
23
|
return messages.slice(-windowSize);
|
|
23
24
|
}
|
|
24
|
-
/**
|
|
25
|
-
* Estimate tokens in text (rough approximation)
|
|
26
|
-
*/
|
|
27
|
-
export function estimateTokens(text) {
|
|
28
|
-
return Math.round(text.length / 4);
|
|
29
|
-
}
|
|
30
25
|
/**
|
|
31
26
|
* Calculate tokens saved by summarization
|
|
32
27
|
*/
|
package/dist/db/bootstrap.d.ts
CHANGED
|
@@ -5,5 +5,7 @@ import type { Pool } from 'pg';
|
|
|
5
5
|
*/
|
|
6
6
|
export declare function ensureDataDirectory(): Promise<void>;
|
|
7
7
|
export declare function ensureSqliteSchema(sqlite: Database): Promise<void>;
|
|
8
|
+
export declare function getSchemaVersion(sqlite: Database): Promise<string | null>;
|
|
9
|
+
export declare function runMigrationsForVersion(sqlite: Database, targetVersion: string): Promise<void>;
|
|
8
10
|
export declare function ensurePostgresSchema(pool: Pool): Promise<void>;
|
|
9
11
|
//# sourceMappingURL=bootstrap.d.ts.map
|