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
|
@@ -0,0 +1,309 @@
|
|
|
1
|
+
import { getDbClient } from '../lib/db-client.js';
|
|
2
|
+
import { getRecent } from '../memory/memories.js';
|
|
3
|
+
import { getMemoryStats } from '../memory/stats.js';
|
|
4
|
+
import { explainMemory } from '../memory/explain.js';
|
|
5
|
+
import { getLatestProjectWorkingSetSummary, getProjectSignalStats } from '../session/working-set.js';
|
|
6
|
+
import { getGraphStats } from '../graph/index.js';
|
|
7
|
+
import { getAllProjects, getProjectByPath, ensureProject } from '../projects.js';
|
|
8
|
+
import { getProjectPlaces } from '../places/places.js';
|
|
9
|
+
import { getMemoryPlace } from '../places/memory-places.js';
|
|
10
|
+
import { getPlace } from '../places/places.js';
|
|
11
|
+
import { config } from '../../config.js';
|
|
12
|
+
import { getBeliefsForMemory } from '../beliefs/store.js';
|
|
13
|
+
function isLegacyPlaceholderProject(project, currentWorkspacePath) {
|
|
14
|
+
const normalizedPath = project.path.trim();
|
|
15
|
+
if (normalizedPath === '.')
|
|
16
|
+
return true;
|
|
17
|
+
if (!currentWorkspacePath)
|
|
18
|
+
return false;
|
|
19
|
+
return normalizedPath === currentWorkspacePath && String(project.metadata?.source ?? '') === 'mcp';
|
|
20
|
+
}
|
|
21
|
+
function filterNormalOtherProjects(projects, currentProjectId, currentWorkspacePath) {
|
|
22
|
+
return projects.filter((candidate) => {
|
|
23
|
+
if (candidate.id === currentProjectId)
|
|
24
|
+
return false;
|
|
25
|
+
return !isLegacyPlaceholderProject(candidate, currentWorkspacePath);
|
|
26
|
+
});
|
|
27
|
+
}
|
|
28
|
+
function inferResolution(project, mode) {
|
|
29
|
+
if (mode !== 'inferred')
|
|
30
|
+
return mode;
|
|
31
|
+
const source = String(project.metadata?.source ?? '');
|
|
32
|
+
return source === 'mcp' ? 'auto-created' : 'inferred';
|
|
33
|
+
}
|
|
34
|
+
function toProjectSummary(project, mode) {
|
|
35
|
+
return {
|
|
36
|
+
id: project.id,
|
|
37
|
+
name: project.name,
|
|
38
|
+
path: project.path,
|
|
39
|
+
resolution: inferResolution(project, mode),
|
|
40
|
+
};
|
|
41
|
+
}
|
|
42
|
+
export async function resolveProjectScope(projectPath) {
|
|
43
|
+
const projects = await getAllProjects();
|
|
44
|
+
const explicitPath = projectPath?.trim();
|
|
45
|
+
if (explicitPath) {
|
|
46
|
+
let project = await getProjectByPath(explicitPath);
|
|
47
|
+
let resolution = 'explicit';
|
|
48
|
+
if (!project) {
|
|
49
|
+
project = await ensureProject(explicitPath);
|
|
50
|
+
resolution = 'auto-created';
|
|
51
|
+
}
|
|
52
|
+
if (!project) {
|
|
53
|
+
throw new Error(`Unable to resolve project: ${explicitPath}`);
|
|
54
|
+
}
|
|
55
|
+
return {
|
|
56
|
+
currentProject: toProjectSummary(project, resolution),
|
|
57
|
+
otherProjects: filterNormalOtherProjects(projects, project.id, explicitPath)
|
|
58
|
+
.map((candidate) => toProjectSummary(candidate, 'inferred')),
|
|
59
|
+
nextStep: null,
|
|
60
|
+
};
|
|
61
|
+
}
|
|
62
|
+
const cwd = process.cwd();
|
|
63
|
+
const cwdProject = await getProjectByPath(cwd);
|
|
64
|
+
if (cwdProject) {
|
|
65
|
+
return {
|
|
66
|
+
currentProject: toProjectSummary(cwdProject, 'inferred'),
|
|
67
|
+
otherProjects: filterNormalOtherProjects(projects, cwdProject.id, cwd)
|
|
68
|
+
.map((candidate) => toProjectSummary(candidate, 'inferred')),
|
|
69
|
+
nextStep: null,
|
|
70
|
+
};
|
|
71
|
+
}
|
|
72
|
+
if (projects.length === 1) {
|
|
73
|
+
return {
|
|
74
|
+
currentProject: toProjectSummary(projects[0], 'inferred'),
|
|
75
|
+
otherProjects: [],
|
|
76
|
+
nextStep: null,
|
|
77
|
+
};
|
|
78
|
+
}
|
|
79
|
+
const autoProject = await ensureProject(cwd);
|
|
80
|
+
if (!autoProject) {
|
|
81
|
+
throw new Error(`Unable to create project for current workspace: ${cwd}`);
|
|
82
|
+
}
|
|
83
|
+
const otherProjects = projects
|
|
84
|
+
.filter((candidate) => candidate.id !== autoProject.id)
|
|
85
|
+
.filter((candidate) => !isLegacyPlaceholderProject(candidate, cwd))
|
|
86
|
+
.map((candidate) => toProjectSummary(candidate, 'inferred'));
|
|
87
|
+
return {
|
|
88
|
+
currentProject: toProjectSummary(autoProject, 'auto-created'),
|
|
89
|
+
otherProjects,
|
|
90
|
+
nextStep: otherProjects.length > 0
|
|
91
|
+
? 'Pass --project with the intended workspace path if this is not the project you meant.'
|
|
92
|
+
: null,
|
|
93
|
+
};
|
|
94
|
+
}
|
|
95
|
+
async function getMemoryPlaceName(memoryId) {
|
|
96
|
+
const placeId = await getMemoryPlace(memoryId);
|
|
97
|
+
if (!placeId)
|
|
98
|
+
return null;
|
|
99
|
+
const place = await getPlace(placeId);
|
|
100
|
+
return place?.name ?? null;
|
|
101
|
+
}
|
|
102
|
+
export async function buildContextState(projectPath, limit = 10) {
|
|
103
|
+
const scope = await resolveProjectScope(projectPath);
|
|
104
|
+
const projectPathResolved = scope.currentProject.path;
|
|
105
|
+
const [sessionSummary, signalSummary, graphStats, memories] = await Promise.all([
|
|
106
|
+
getLatestProjectWorkingSetSummary(projectPathResolved),
|
|
107
|
+
getProjectSignalStats(projectPathResolved),
|
|
108
|
+
getGraphStats(projectPathResolved),
|
|
109
|
+
getRecent(projectPathResolved, limit),
|
|
110
|
+
]);
|
|
111
|
+
const project = await getProjectByPath(projectPathResolved);
|
|
112
|
+
const places = project ? await getProjectPlaces(project.id) : [];
|
|
113
|
+
const activePlaces = places.filter((place) => place.memoryCount > 0).map((place) => place.name);
|
|
114
|
+
const durableMemories = await Promise.all(memories.map(async (memory) => ({
|
|
115
|
+
id: memory.id,
|
|
116
|
+
type: memory.type,
|
|
117
|
+
content: memory.content,
|
|
118
|
+
place: await getMemoryPlaceName(memory.id),
|
|
119
|
+
})));
|
|
120
|
+
const beliefRows = await Promise.all(memories.map((memory) => getBeliefsForMemory(memory.id)));
|
|
121
|
+
const beliefs = beliefRows.flat().slice(0, 6).map((belief) => ({
|
|
122
|
+
type: belief.type,
|
|
123
|
+
statement: belief.statement,
|
|
124
|
+
status: belief.status,
|
|
125
|
+
}));
|
|
126
|
+
return {
|
|
127
|
+
currentProject: scope.currentProject,
|
|
128
|
+
otherProjects: scope.otherProjects,
|
|
129
|
+
runtime: {
|
|
130
|
+
sessionSummary,
|
|
131
|
+
activePlaces,
|
|
132
|
+
signalSummary: {
|
|
133
|
+
captured: signalSummary.captured,
|
|
134
|
+
suppressed: signalSummary.suppressed,
|
|
135
|
+
sessionOnly: signalSummary.sessionOnly,
|
|
136
|
+
durable: signalSummary.durable,
|
|
137
|
+
durableWithRaw: signalSummary.durableWithRaw,
|
|
138
|
+
},
|
|
139
|
+
graphSummary: graphStats.entityCount > 0 || graphStats.relationCount > 0
|
|
140
|
+
? `enabled; ${graphStats.entityCount} entities, ${graphStats.relationCount} relations`
|
|
141
|
+
: 'enabled; no graph enrichments yet',
|
|
142
|
+
},
|
|
143
|
+
durableMemories,
|
|
144
|
+
beliefs,
|
|
145
|
+
nextStep: scope.nextStep,
|
|
146
|
+
};
|
|
147
|
+
}
|
|
148
|
+
export async function buildStatsState(projectPath) {
|
|
149
|
+
const scope = await resolveProjectScope(projectPath);
|
|
150
|
+
const projectPathResolved = scope.currentProject.path;
|
|
151
|
+
const [stats, graphStats, sessionSummary] = await Promise.all([
|
|
152
|
+
getMemoryStats(projectPathResolved),
|
|
153
|
+
getGraphStats(projectPathResolved),
|
|
154
|
+
getLatestProjectWorkingSetSummary(projectPathResolved),
|
|
155
|
+
]);
|
|
156
|
+
const project = await getProjectByPath(projectPathResolved);
|
|
157
|
+
const places = project ? await getProjectPlaces(project.id) : [];
|
|
158
|
+
return {
|
|
159
|
+
currentProject: `${scope.currentProject.name} (${scope.currentProject.path})`,
|
|
160
|
+
totals: {
|
|
161
|
+
memories: stats.totalMemories,
|
|
162
|
+
durable: Math.max(stats.totalMemories, (stats.signal?.durable ?? 0) + (stats.signal?.durableWithRaw ?? 0)),
|
|
163
|
+
sessionLocal: stats.signal?.sessionOnly ?? 0,
|
|
164
|
+
},
|
|
165
|
+
signal: {
|
|
166
|
+
captured: stats.signal?.captured ?? 0,
|
|
167
|
+
suppressed: stats.signal?.suppressed ?? 0,
|
|
168
|
+
sessionOnly: stats.signal?.sessionOnly ?? 0,
|
|
169
|
+
durable: stats.signal?.durable ?? 0,
|
|
170
|
+
durableWithRaw: stats.signal?.durableWithRaw ?? 0,
|
|
171
|
+
tokensSaved: stats.signal?.tokensSaved ?? 0,
|
|
172
|
+
placeRouted: stats.signal?.placeRouted ?? 0,
|
|
173
|
+
graphEnriched: stats.signal?.graphEnriched ?? 0,
|
|
174
|
+
},
|
|
175
|
+
places: {
|
|
176
|
+
active: places.filter((place) => place.memoryCount > 0).length,
|
|
177
|
+
named: places.filter((place) => place.memoryCount > 0).map((place) => place.name),
|
|
178
|
+
},
|
|
179
|
+
graph: {
|
|
180
|
+
status: graphStats.entityCount > 0 || graphStats.relationCount > 0 ? 'enabled' : 'enabled (idle)',
|
|
181
|
+
enrichments: stats.signal?.graphEnriched ?? 0,
|
|
182
|
+
},
|
|
183
|
+
wakeUp: sessionSummary || 'No working set yet',
|
|
184
|
+
signalNote: stats.totalMemories > 0 && (stats.signal?.captured ?? 0) === 0
|
|
185
|
+
? 'Signal counts cover capture-era writes only. Legacy durable memories may exist without signal telemetry.'
|
|
186
|
+
: 'Signal counts cover capture-era writes only.',
|
|
187
|
+
};
|
|
188
|
+
}
|
|
189
|
+
export async function buildHealthState(projectPath) {
|
|
190
|
+
const scope = await resolveProjectScope(projectPath);
|
|
191
|
+
const checks = [];
|
|
192
|
+
let severity = 'ok';
|
|
193
|
+
let nextStep = scope.nextStep;
|
|
194
|
+
try {
|
|
195
|
+
await getDbClient();
|
|
196
|
+
checks.push({ name: 'database', status: 'ok', detail: 'Database connection succeeded.' });
|
|
197
|
+
}
|
|
198
|
+
catch (error) {
|
|
199
|
+
severity = 'broken';
|
|
200
|
+
nextStep = 'Fix database initialization before relying on memory reads or writes.';
|
|
201
|
+
checks.push({
|
|
202
|
+
name: 'database',
|
|
203
|
+
status: 'broken',
|
|
204
|
+
detail: error?.message ?? 'Database initialization failed.',
|
|
205
|
+
});
|
|
206
|
+
}
|
|
207
|
+
checks.push({
|
|
208
|
+
name: 'project resolution',
|
|
209
|
+
status: 'ok',
|
|
210
|
+
detail: `${scope.currentProject.name} at ${scope.currentProject.path} (${scope.currentProject.resolution})`,
|
|
211
|
+
});
|
|
212
|
+
try {
|
|
213
|
+
await getRecent(scope.currentProject.path, 1);
|
|
214
|
+
checks.push({ name: 'memory write path', status: 'ok', detail: 'Memory store is readable for this project.' });
|
|
215
|
+
}
|
|
216
|
+
catch (error) {
|
|
217
|
+
severity = severity === 'broken' ? 'broken' : 'degraded';
|
|
218
|
+
nextStep = nextStep ?? 'Run `squish doctor` to repair local storage before writing memories.';
|
|
219
|
+
checks.push({
|
|
220
|
+
name: 'memory write path',
|
|
221
|
+
status: 'degraded',
|
|
222
|
+
detail: error?.message ?? 'Memory store could not be read.',
|
|
223
|
+
});
|
|
224
|
+
}
|
|
225
|
+
try {
|
|
226
|
+
const sessionSummary = await getLatestProjectWorkingSetSummary(scope.currentProject.path);
|
|
227
|
+
checks.push({
|
|
228
|
+
name: 'session working set',
|
|
229
|
+
status: sessionSummary ? 'ok' : 'degraded',
|
|
230
|
+
detail: sessionSummary || 'No compact working set has been captured yet.',
|
|
231
|
+
});
|
|
232
|
+
if (!sessionSummary && severity === 'ok') {
|
|
233
|
+
severity = 'degraded';
|
|
234
|
+
nextStep = nextStep ?? 'Run a normal session or memory write so Squish can build a working-set wake-up summary.';
|
|
235
|
+
}
|
|
236
|
+
}
|
|
237
|
+
catch (error) {
|
|
238
|
+
severity = severity === 'broken' ? 'broken' : 'degraded';
|
|
239
|
+
checks.push({
|
|
240
|
+
name: 'session working set',
|
|
241
|
+
status: 'degraded',
|
|
242
|
+
detail: error?.message ?? 'Working-set state could not be loaded.',
|
|
243
|
+
});
|
|
244
|
+
}
|
|
245
|
+
const project = await getProjectByPath(scope.currentProject.path);
|
|
246
|
+
const places = project ? await getProjectPlaces(project.id) : [];
|
|
247
|
+
const activePlaces = places.filter((place) => place.memoryCount > 0);
|
|
248
|
+
checks.push({
|
|
249
|
+
name: 'places',
|
|
250
|
+
status: activePlaces.length > 0 ? 'ok' : 'degraded',
|
|
251
|
+
detail: activePlaces.length > 0
|
|
252
|
+
? `${activePlaces.length} active places: ${activePlaces.map((place) => place.name).join(', ')}`
|
|
253
|
+
: 'No populated places yet.',
|
|
254
|
+
});
|
|
255
|
+
if (activePlaces.length === 0 && severity === 'ok') {
|
|
256
|
+
severity = 'degraded';
|
|
257
|
+
nextStep = nextStep ?? 'Store or recall project memories to populate place routing.';
|
|
258
|
+
}
|
|
259
|
+
const graphStats = await getGraphStats(scope.currentProject.path);
|
|
260
|
+
checks.push({
|
|
261
|
+
name: 'graph',
|
|
262
|
+
status: graphStats.entityCount > 0 || graphStats.relationCount > 0 ? 'ok' : 'degraded',
|
|
263
|
+
detail: graphStats.entityCount > 0 || graphStats.relationCount > 0
|
|
264
|
+
? `${graphStats.entityCount} entities and ${graphStats.relationCount} relations available.`
|
|
265
|
+
: 'Graph is enabled but has no extracted entities yet.',
|
|
266
|
+
});
|
|
267
|
+
if (graphStats.entityCount === 0 && graphStats.relationCount === 0 && severity === 'ok') {
|
|
268
|
+
severity = 'degraded';
|
|
269
|
+
nextStep = nextStep ?? 'Write or recall durable memories so graph enrichment has material to process.';
|
|
270
|
+
}
|
|
271
|
+
checks.push({
|
|
272
|
+
name: 'mode',
|
|
273
|
+
status: 'ok',
|
|
274
|
+
detail: `${config.isManagedMode ? 'managed' : 'local'} mode; embeddings ${config.embeddingsProvider}`,
|
|
275
|
+
});
|
|
276
|
+
return {
|
|
277
|
+
severity,
|
|
278
|
+
currentProject: `${scope.currentProject.name} (${scope.currentProject.path})`,
|
|
279
|
+
checks,
|
|
280
|
+
nextStep,
|
|
281
|
+
};
|
|
282
|
+
}
|
|
283
|
+
export async function buildInspectState(id) {
|
|
284
|
+
const inspection = await explainMemory(id);
|
|
285
|
+
if (!inspection)
|
|
286
|
+
return null;
|
|
287
|
+
return {
|
|
288
|
+
id: inspection.id,
|
|
289
|
+
classification: inspection.classification,
|
|
290
|
+
storageReason: inspection.reasons.join('; ') || 'Stored as durable memory.',
|
|
291
|
+
durability: inspection.classification === 'session-only' ? 'session-only' : 'durable',
|
|
292
|
+
place: inspection.place ?? null,
|
|
293
|
+
placeType: inspection.placeType ?? null,
|
|
294
|
+
graphStatus: inspection.graphStatus ?? null,
|
|
295
|
+
rawFallback: inspection.rawFallbackSnapshotId ?? null,
|
|
296
|
+
wakeUpPriority: inspection.nuanceSuppressed ? 'high' : 'normal',
|
|
297
|
+
metadataAvailability: inspection.legacyMetadata
|
|
298
|
+
? 'Legacy durable record; signal-era metadata is unavailable.'
|
|
299
|
+
: 'Signal metadata available.',
|
|
300
|
+
beliefs: (inspection.beliefs ?? []).map((belief) => ({
|
|
301
|
+
id: belief.id,
|
|
302
|
+
type: belief.type,
|
|
303
|
+
statement: belief.statement,
|
|
304
|
+
status: belief.status,
|
|
305
|
+
confidence: belief.confidence,
|
|
306
|
+
})),
|
|
307
|
+
};
|
|
308
|
+
}
|
|
309
|
+
//# sourceMappingURL=trust-state.js.map
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/** Cron Scheduler - Persistent cron-based job scheduling with fallback support */
|
|
2
|
-
export type JobType = 'nightly' | 'weekly' | 'hourly';
|
|
2
|
+
export type JobType = 'nightly' | 'weekly' | 'hourly' | 'daily';
|
|
3
3
|
export type JobStatus = 'success' | 'failed' | 'skipped';
|
|
4
4
|
export interface ScheduledJob {
|
|
5
5
|
id: string;
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
/** Cron Scheduler - Persistent cron-based job scheduling with fallback support */
|
|
2
2
|
import cron from 'node-cron';
|
|
3
|
-
import { selfIterationHandler } from '../session
|
|
3
|
+
import { selfIterationHandler } from '../session/self-iteration-job.js';
|
|
4
4
|
import { runLifecycleMaintenance } from '../lifecycle.js';
|
|
5
5
|
import { logger } from '../logger.js';
|
|
6
6
|
import { config } from '../../config.js';
|
|
@@ -8,7 +8,14 @@ import { getDb } from '../../db/index.js';
|
|
|
8
8
|
import { maintenanceJobs, maintenanceJobHistory } from '../../db/drizzle/schema-sqlite.js';
|
|
9
9
|
import { eq } from 'drizzle-orm';
|
|
10
10
|
const jobHandlers = new Map();
|
|
11
|
-
const activeTasks = new Map();
|
|
11
|
+
const activeTasks = new Map(); // node-cron ScheduledTask type
|
|
12
|
+
// Job interval by type (in ms) - used for catch-up detection
|
|
13
|
+
const JOB_INTERVALS = {
|
|
14
|
+
hourly: 60 * 60 * 1000, // 1 hour
|
|
15
|
+
daily: 24 * 60 * 60 * 1000, // 24 hours
|
|
16
|
+
nightly: 24 * 60 * 60 * 1000, // 24 hours (same as daily)
|
|
17
|
+
weekly: 7 * 24 * 60 * 60 * 1000, // 7 days
|
|
18
|
+
};
|
|
12
19
|
export function registerJobHandler(jobName, handler) {
|
|
13
20
|
jobHandlers.set(jobName, handler);
|
|
14
21
|
logger.info(`[Scheduler] Registered handler for job: ${jobName}`);
|
|
@@ -29,6 +36,67 @@ const decayHandler = async (context) => {
|
|
|
29
36
|
};
|
|
30
37
|
};
|
|
31
38
|
registerJobHandler('decay_maintenance', decayHandler);
|
|
39
|
+
// Belief decay handler - applies confidence decay to beliefs
|
|
40
|
+
const beliefDecayHandler = async (context) => {
|
|
41
|
+
const { applyBeliefDecay } = await import('../beliefs/decay.js');
|
|
42
|
+
const stats = await applyBeliefDecay();
|
|
43
|
+
return {
|
|
44
|
+
recordsProcessed: stats.decayed + stats.sourceCountUpdated,
|
|
45
|
+
summary: {
|
|
46
|
+
beliefDecayed: stats.decayed,
|
|
47
|
+
sourceCountUpdated: stats.sourceCountUpdated,
|
|
48
|
+
errors: stats.errors,
|
|
49
|
+
},
|
|
50
|
+
};
|
|
51
|
+
};
|
|
52
|
+
registerJobHandler('belief_decay', beliefDecayHandler);
|
|
53
|
+
// Auto-clean handler - deletes stale memories automatically
|
|
54
|
+
const autoCleanHandler = async (context) => {
|
|
55
|
+
const { getStaleMemories, deleteMemoryPermanently } = await import('../memory/stale-cleaner.js');
|
|
56
|
+
const { getAllProjects } = await import('../projects.js');
|
|
57
|
+
const jobConfig = context.config;
|
|
58
|
+
if (jobConfig.enabled === false) {
|
|
59
|
+
return { recordsProcessed: 0, summary: { skipped: true, reason: 'auto-clean disabled' } };
|
|
60
|
+
}
|
|
61
|
+
const olderThanDays = jobConfig.olderThanDays || 30;
|
|
62
|
+
const confidenceLevels = jobConfig.confidenceLevel || ['outdated', 'speculative'];
|
|
63
|
+
const minImportance = jobConfig.minImportance || 40;
|
|
64
|
+
const dryRun = jobConfig.dryRun !== undefined ? jobConfig.dryRun : false; // Default to actual delete for safety
|
|
65
|
+
const projects = await getAllProjects();
|
|
66
|
+
let totalStale = 0;
|
|
67
|
+
let totalDeleted = 0;
|
|
68
|
+
for (const project of projects) {
|
|
69
|
+
const stale = await getStaleMemories({
|
|
70
|
+
olderThanDays,
|
|
71
|
+
confidenceLevels,
|
|
72
|
+
minImportance,
|
|
73
|
+
projectId: project.id,
|
|
74
|
+
});
|
|
75
|
+
totalStale += stale.length;
|
|
76
|
+
if (dryRun) {
|
|
77
|
+
logger.info(`[AutoClean] Would delete ${stale.length} stale memories in ${project.path}`);
|
|
78
|
+
}
|
|
79
|
+
else {
|
|
80
|
+
for (const memory of stale) {
|
|
81
|
+
if (!memory.isPinned) {
|
|
82
|
+
await deleteMemoryPermanently(memory.id);
|
|
83
|
+
totalDeleted++;
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
logger.info(`[AutoClean] Deleted ${stale.length} stale memories in ${project.path}`);
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
return {
|
|
90
|
+
recordsProcessed: dryRun ? totalStale : totalDeleted,
|
|
91
|
+
summary: {
|
|
92
|
+
mode: dryRun ? 'dry-run' : 'deleted',
|
|
93
|
+
projectsScanned: projects.length,
|
|
94
|
+
memoriesAffected: dryRun ? totalStale : totalDeleted,
|
|
95
|
+
criteria: { olderThanDays, confidenceLevels, minImportance },
|
|
96
|
+
},
|
|
97
|
+
};
|
|
98
|
+
};
|
|
99
|
+
registerJobHandler('auto_clean', autoCleanHandler);
|
|
32
100
|
export async function initializeScheduler() {
|
|
33
101
|
if (!config.cronEnabled) {
|
|
34
102
|
logger.info('[Scheduler] Cron scheduling disabled, using heartbeat fallback');
|
|
@@ -41,6 +109,8 @@ export async function initializeScheduler() {
|
|
|
41
109
|
}
|
|
42
110
|
try {
|
|
43
111
|
await ensureDefaultJobs(db);
|
|
112
|
+
// Check for missed jobs (catch-up after machine wake from sleep)
|
|
113
|
+
await checkMissedJobs();
|
|
44
114
|
const sqliteDb = db;
|
|
45
115
|
const jobs = await sqliteDb
|
|
46
116
|
.select()
|
|
@@ -55,6 +125,78 @@ export async function initializeScheduler() {
|
|
|
55
125
|
logger.error('[Scheduler] Failed to initialize:', error);
|
|
56
126
|
}
|
|
57
127
|
}
|
|
128
|
+
/**
|
|
129
|
+
* Check for missed jobs and execute catch-up if needed
|
|
130
|
+
* Called on scheduler initialization (including after machine wake from sleep)
|
|
131
|
+
*/
|
|
132
|
+
async function checkMissedJobs() {
|
|
133
|
+
try {
|
|
134
|
+
const db = await getDb();
|
|
135
|
+
if (!db)
|
|
136
|
+
return;
|
|
137
|
+
const sqliteDb = db;
|
|
138
|
+
const jobs = await sqliteDb
|
|
139
|
+
.select()
|
|
140
|
+
.from(maintenanceJobs)
|
|
141
|
+
.where(eq(maintenanceJobs.enabled, true));
|
|
142
|
+
const now = Date.now();
|
|
143
|
+
for (const job of jobs) {
|
|
144
|
+
const intervalMs = JOB_INTERVALS[job.jobType];
|
|
145
|
+
if (!intervalMs)
|
|
146
|
+
continue;
|
|
147
|
+
const lastRun = job.lastRunAt ? new Date(job.lastRunAt).getTime() : 0;
|
|
148
|
+
const elapsed = lastRun > 0 ? now - lastRun : intervalMs * 2; // If never run, treat as overdue
|
|
149
|
+
const gracePeriod = intervalMs * 1.5; // 1.5x interval grace
|
|
150
|
+
if (elapsed > gracePeriod) {
|
|
151
|
+
logger.info(`[Scheduler] Catch-up needed for ${job.jobName}, elapsed ${Math.round(elapsed / (60 * 60 * 1000))}h (grace: ${Math.round(gracePeriod / (60 * 60 * 1000))}h)`);
|
|
152
|
+
// Execute catch-up
|
|
153
|
+
const handler = jobHandlers.get(job.jobName);
|
|
154
|
+
if (handler) {
|
|
155
|
+
try {
|
|
156
|
+
const startedAt = new Date();
|
|
157
|
+
const context = {
|
|
158
|
+
jobId: job.id,
|
|
159
|
+
jobName: job.jobName,
|
|
160
|
+
jobType: job.jobType,
|
|
161
|
+
config: typeof job.jobConfig === 'string'
|
|
162
|
+
? JSON.parse(job.jobConfig)
|
|
163
|
+
: job.jobConfig ?? {},
|
|
164
|
+
startedAt,
|
|
165
|
+
};
|
|
166
|
+
await handler(context);
|
|
167
|
+
// Record successful catch-up run
|
|
168
|
+
const completedAt = new Date();
|
|
169
|
+
await sqliteDb
|
|
170
|
+
.update(maintenanceJobs)
|
|
171
|
+
.set({
|
|
172
|
+
lastRunAt: completedAt,
|
|
173
|
+
lastRunStatus: 'success',
|
|
174
|
+
lastRunDuration: completedAt.getTime() - startedAt.getTime(),
|
|
175
|
+
})
|
|
176
|
+
.where(eq(maintenanceJobs.id, job.id));
|
|
177
|
+
logger.info(`[Scheduler] Catch-up completed for ${job.jobName}`);
|
|
178
|
+
}
|
|
179
|
+
catch (catchError) {
|
|
180
|
+
const msg = catchError instanceof Error ? catchError.message : String(catchError);
|
|
181
|
+
logger.error(`[Scheduler] Catch-up failed for ${job.jobName}:`, msg);
|
|
182
|
+
await sqliteDb
|
|
183
|
+
.update(maintenanceJobs)
|
|
184
|
+
.set({
|
|
185
|
+
lastRunAt: new Date(),
|
|
186
|
+
lastRunStatus: 'failed',
|
|
187
|
+
lastRunError: msg,
|
|
188
|
+
})
|
|
189
|
+
.where(eq(maintenanceJobs.id, job.id));
|
|
190
|
+
}
|
|
191
|
+
}
|
|
192
|
+
}
|
|
193
|
+
}
|
|
194
|
+
}
|
|
195
|
+
catch (error) {
|
|
196
|
+
const msg = error instanceof Error ? error.message : String(error);
|
|
197
|
+
logger.error('[Scheduler] Error checking missed jobs:', msg);
|
|
198
|
+
}
|
|
199
|
+
}
|
|
58
200
|
async function ensureDefaultJobs(db) {
|
|
59
201
|
const defaultJobs = [
|
|
60
202
|
{
|
|
@@ -64,6 +206,13 @@ async function ensureDefaultJobs(db) {
|
|
|
64
206
|
enabled: true,
|
|
65
207
|
jobConfig: { applyDecay: true, updateTiers: true, evictOld: true },
|
|
66
208
|
},
|
|
209
|
+
{
|
|
210
|
+
jobName: 'belief_decay',
|
|
211
|
+
jobType: 'daily',
|
|
212
|
+
cronExpression: '0 4 * * *', // Run daily at 4 AM
|
|
213
|
+
enabled: true,
|
|
214
|
+
jobConfig: { applyBeliefDecay: true },
|
|
215
|
+
},
|
|
67
216
|
{
|
|
68
217
|
jobName: 'nightly_maintenance',
|
|
69
218
|
jobType: 'nightly',
|
|
@@ -85,6 +234,19 @@ async function ensureDefaultJobs(db) {
|
|
|
85
234
|
enabled: true,
|
|
86
235
|
jobConfig: { minMessageCount: 5, maxMessagesToProcess: 50 },
|
|
87
236
|
},
|
|
237
|
+
{
|
|
238
|
+
jobName: 'auto_clean',
|
|
239
|
+
jobType: 'daily',
|
|
240
|
+
cronExpression: '0 3 * * *', // Run daily at 3 AM
|
|
241
|
+
enabled: true,
|
|
242
|
+
jobConfig: {
|
|
243
|
+
enabled: true,
|
|
244
|
+
olderThanDays: 30,
|
|
245
|
+
confidenceLevel: ['outdated', 'speculative'],
|
|
246
|
+
minImportance: 40,
|
|
247
|
+
dryRun: true, // Start with dry-run for safety
|
|
248
|
+
},
|
|
249
|
+
},
|
|
88
250
|
];
|
|
89
251
|
for (const job of defaultJobs) {
|
|
90
252
|
let existing;
|
|
@@ -167,7 +329,6 @@ export async function scheduleJob(job) {
|
|
|
167
329
|
const task = cron.schedule(job.cronExpression, async () => {
|
|
168
330
|
await executeJob(job);
|
|
169
331
|
}, {
|
|
170
|
-
scheduled: true,
|
|
171
332
|
timezone: 'UTC',
|
|
172
333
|
});
|
|
173
334
|
activeTasks.set(job.jobName, task);
|
|
@@ -15,8 +15,8 @@ export async function runNightlyJob(context) {
|
|
|
15
15
|
try {
|
|
16
16
|
const lifecycleResult = await runLifecycleMaintenance();
|
|
17
17
|
summary.decayApplied = lifecycleResult?.decayed || 0;
|
|
18
|
+
// Simplified: hot/cold only (warm removed)
|
|
18
19
|
summary.tiersUpdated = (lifecycleResult?.tierChanges?.hot || 0) +
|
|
19
|
-
(lifecycleResult?.tierChanges?.warm || 0) +
|
|
20
20
|
(lifecycleResult?.tierChanges?.cold || 0);
|
|
21
21
|
recordsProcessed += summary.decayApplied;
|
|
22
22
|
recordsProcessed += summary.tiersUpdated;
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import { type QMDSearchResult } from '../embeddings/qmd-client.js';
|
|
2
|
+
export type { QMDSearchResult };
|
|
3
|
+
export interface QMDStatus {
|
|
4
|
+
indexHealth: string;
|
|
5
|
+
documentCount: number;
|
|
6
|
+
collections?: Array<{
|
|
7
|
+
name: string;
|
|
8
|
+
path: string;
|
|
9
|
+
documentCount: number;
|
|
10
|
+
}>;
|
|
11
|
+
}
|
|
12
|
+
export declare function isAvailable(): Promise<boolean>;
|
|
13
|
+
export declare function search(query: string, options?: {
|
|
14
|
+
collection?: string;
|
|
15
|
+
limit?: number;
|
|
16
|
+
minScore?: number;
|
|
17
|
+
}): Promise<QMDSearchResult[]>;
|
|
18
|
+
export declare function vsearch(query: string, options?: {
|
|
19
|
+
collection?: string;
|
|
20
|
+
limit?: number;
|
|
21
|
+
minScore?: number;
|
|
22
|
+
}): Promise<QMDSearchResult[]>;
|
|
23
|
+
export declare function query(queryText: string, options?: {
|
|
24
|
+
collection?: string;
|
|
25
|
+
limit?: number;
|
|
26
|
+
minScore?: number;
|
|
27
|
+
}): Promise<QMDSearchResult[]>;
|
|
28
|
+
export declare function get(pathOrDocid: string, options?: {
|
|
29
|
+
full?: boolean;
|
|
30
|
+
maxBytes?: number;
|
|
31
|
+
}): Promise<string>;
|
|
32
|
+
export declare function status(): Promise<QMDStatus | null>;
|
|
33
|
+
export declare function embed(): Promise<number[] | null>;
|
|
34
|
+
export declare function ensureWikiDir(projectPath: string): Promise<string>;
|
|
35
|
+
export declare function close(): Promise<void>;
|
|
36
|
+
//# sourceMappingURL=qmd-wrapper.d.ts.map
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
import { getQMDClient } from '../embeddings/qmd-client.js';
|
|
2
|
+
export async function isAvailable() {
|
|
3
|
+
const client = await getQMDClient();
|
|
4
|
+
return client.isAvailable();
|
|
5
|
+
}
|
|
6
|
+
export async function search(query, options = {}) {
|
|
7
|
+
const client = await getQMDClient();
|
|
8
|
+
if (!(await client.isAvailable()))
|
|
9
|
+
return [];
|
|
10
|
+
return client.search({ query, ...options });
|
|
11
|
+
}
|
|
12
|
+
export async function vsearch(query, options = {}) {
|
|
13
|
+
const client = await getQMDClient();
|
|
14
|
+
if (!(await client.isAvailable()))
|
|
15
|
+
return [];
|
|
16
|
+
return client.vsearch({ query, ...options });
|
|
17
|
+
}
|
|
18
|
+
export async function query(queryText, options = {}) {
|
|
19
|
+
const client = await getQMDClient();
|
|
20
|
+
if (!(await client.isAvailable()))
|
|
21
|
+
return [];
|
|
22
|
+
return client.query({ query: queryText, ...options });
|
|
23
|
+
}
|
|
24
|
+
export async function get(pathOrDocid, options = {}) {
|
|
25
|
+
const client = await getQMDClient();
|
|
26
|
+
if (!(await client.isAvailable()))
|
|
27
|
+
return '';
|
|
28
|
+
return client.get({ pathOrDocid, ...options });
|
|
29
|
+
}
|
|
30
|
+
export async function status() {
|
|
31
|
+
const client = await getQMDClient();
|
|
32
|
+
if (!(await client.isAvailable()))
|
|
33
|
+
return null;
|
|
34
|
+
const result = await client.status();
|
|
35
|
+
if (!result)
|
|
36
|
+
return null;
|
|
37
|
+
return {
|
|
38
|
+
indexHealth: result.indexHealth,
|
|
39
|
+
documentCount: result.collections.reduce((sum, collection) => sum + collection.documentCount, 0),
|
|
40
|
+
collections: result.collections,
|
|
41
|
+
};
|
|
42
|
+
}
|
|
43
|
+
export async function embed() {
|
|
44
|
+
return null;
|
|
45
|
+
}
|
|
46
|
+
export async function ensureWikiDir(projectPath) {
|
|
47
|
+
const { join } = await import('path');
|
|
48
|
+
const { mkdirSync, existsSync } = await import('fs');
|
|
49
|
+
const wikiDir = join(projectPath, '.squish', 'wiki');
|
|
50
|
+
if (!existsSync(wikiDir))
|
|
51
|
+
mkdirSync(wikiDir, { recursive: true });
|
|
52
|
+
return wikiDir;
|
|
53
|
+
}
|
|
54
|
+
export async function close() {
|
|
55
|
+
const client = await getQMDClient();
|
|
56
|
+
await client.disconnect();
|
|
57
|
+
}
|
|
58
|
+
//# sourceMappingURL=qmd-wrapper.js.map
|
|
@@ -6,9 +6,9 @@ import { search } from '../memory/memories.js';
|
|
|
6
6
|
import { getProjectContext } from '../context/context.js';
|
|
7
7
|
import { getOrCreateProject } from '../projects.js';
|
|
8
8
|
import { DEFAULT_AUTO_LOAD_CONFIG } from './types.js';
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
}
|
|
9
|
+
import { estimateTokens } from '../context/context-window.js';
|
|
10
|
+
import { getLatestProjectWorkingSetSummary } from './working-set.js';
|
|
11
|
+
import { getHotCacheSummary } from '../hot-cache.js';
|
|
12
12
|
export async function performAutoLoad(projectPath, customConfig) {
|
|
13
13
|
const startTime = Date.now();
|
|
14
14
|
const cfg = { ...DEFAULT_AUTO_LOAD_CONFIG, ...customConfig };
|
|
@@ -33,6 +33,31 @@ export async function performAutoLoad(projectPath, customConfig) {
|
|
|
33
33
|
return result;
|
|
34
34
|
}
|
|
35
35
|
const projectId = project.id;
|
|
36
|
+
try {
|
|
37
|
+
const workingSetSummary = await getLatestProjectWorkingSetSummary(projectPath);
|
|
38
|
+
if (workingSetSummary) {
|
|
39
|
+
result.tokensUsed += estimateTokens(workingSetSummary);
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
catch (error) {
|
|
43
|
+
const msg = error instanceof Error ? error.message : String(error);
|
|
44
|
+
result.warnings.push(`Failed to load session working set: ${msg}`);
|
|
45
|
+
}
|
|
46
|
+
// NEW: Load persistent hot cache (Karpathy-style, survives restart)
|
|
47
|
+
if (cfg.includeCoreMemory) {
|
|
48
|
+
try {
|
|
49
|
+
const hotCacheSummary = await getHotCacheSummary({ projectPath, maxEntries: 5 });
|
|
50
|
+
if (hotCacheSummary) {
|
|
51
|
+
result.tokensUsed += estimateTokens(hotCacheSummary);
|
|
52
|
+
logger.info('[AutoLoad] Hot cache loaded from persistent storage');
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
catch (error) {
|
|
56
|
+
const msg = error instanceof Error ? error.message : String(error);
|
|
57
|
+
result.warnings.push(`Failed to load hot cache: ${msg}`);
|
|
58
|
+
logger.warn(`[AutoLoad] Failed to load hot cache: ${msg}`);
|
|
59
|
+
}
|
|
60
|
+
}
|
|
36
61
|
if (cfg.includeCoreMemory) {
|
|
37
62
|
try {
|
|
38
63
|
await initializeCoreMemory(projectId);
|