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,285 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Hot Cache - Persistent session context (Karpathy-style)
|
|
3
|
+
*
|
|
4
|
+
* Implements the "hot.md" layer from LLM Wiki pattern:
|
|
5
|
+
* - ~500 words persistent session context
|
|
6
|
+
* - Survives restart (unlike session working set)
|
|
7
|
+
* - Auto-updates on session events
|
|
8
|
+
* - Deduplication and stale detection
|
|
9
|
+
*/
|
|
10
|
+
import { existsSync, mkdirSync, readFileSync, writeFileSync } from 'fs';
|
|
11
|
+
import { join } from 'path';
|
|
12
|
+
import { createHash } from 'crypto';
|
|
13
|
+
import { logger } from '../logger.js';
|
|
14
|
+
import { getProjectPath } from '../projects.js';
|
|
15
|
+
const HOT_CACHE_VERSION = '1.0.0';
|
|
16
|
+
const MAX_HOT_CACHE_SIZE = 500; // ~500 words max
|
|
17
|
+
const STALE_THRESHOLD_DAYS = 7; // Flag as stale after 7 days
|
|
18
|
+
const STALE_REFERENCE_COUNT = 3; // Minimum refs before considering stale
|
|
19
|
+
let hotCacheInstance = null;
|
|
20
|
+
/**
|
|
21
|
+
* Get the hot cache file path for a project
|
|
22
|
+
*/
|
|
23
|
+
function getHotCachePath(projectPath) {
|
|
24
|
+
return join(projectPath, '.squish', 'hot-cache.json');
|
|
25
|
+
}
|
|
26
|
+
/**
|
|
27
|
+
* Ensure .squish directory exists
|
|
28
|
+
*/
|
|
29
|
+
async function ensureSquishDir(projectPath) {
|
|
30
|
+
const squishDir = join(projectPath, '.squish');
|
|
31
|
+
if (!existsSync(squishDir)) {
|
|
32
|
+
mkdirSync(squishDir, { recursive: true });
|
|
33
|
+
}
|
|
34
|
+
return squishDir;
|
|
35
|
+
}
|
|
36
|
+
/**
|
|
37
|
+
* Create content hash for deduplication
|
|
38
|
+
*/
|
|
39
|
+
function hashContent(content) {
|
|
40
|
+
return createHash('sha256').update(content.trim()).digest('hex').slice(0, 12);
|
|
41
|
+
}
|
|
42
|
+
/**
|
|
43
|
+
* Load hot cache from disk (or create new)
|
|
44
|
+
*/
|
|
45
|
+
export async function loadHotCache(projectPath) {
|
|
46
|
+
const path = projectPath || await getProjectPath();
|
|
47
|
+
if (!path) {
|
|
48
|
+
return createEmptyHotCache('');
|
|
49
|
+
}
|
|
50
|
+
const cachePath = getHotCachePath(path);
|
|
51
|
+
try {
|
|
52
|
+
if (existsSync(cachePath)) {
|
|
53
|
+
const content = readFileSync(cachePath, 'utf-8');
|
|
54
|
+
const cache = JSON.parse(content);
|
|
55
|
+
// Clean stale entries on load
|
|
56
|
+
cache.staleEntries = identifyStaleEntries(cache.entries);
|
|
57
|
+
// Remove very stale entries (>14 days)
|
|
58
|
+
cache.entries = cache.entries.filter(entry => {
|
|
59
|
+
const ageDays = (Date.now() - entry.lastReferencedAt) / (24 * 60 * 60 * 1000);
|
|
60
|
+
return ageDays < 14;
|
|
61
|
+
});
|
|
62
|
+
logger.info('[HotCache] Loaded', { entries: cache.entries.length, path });
|
|
63
|
+
return cache;
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
catch (error) {
|
|
67
|
+
logger.warn('[HotCache] Load failed, creating new', { error });
|
|
68
|
+
}
|
|
69
|
+
return createEmptyHotCache(path);
|
|
70
|
+
}
|
|
71
|
+
/**
|
|
72
|
+
* Create empty hot cache
|
|
73
|
+
*/
|
|
74
|
+
function createEmptyHotCache(projectPath) {
|
|
75
|
+
return {
|
|
76
|
+
version: HOT_CACHE_VERSION,
|
|
77
|
+
projectPath,
|
|
78
|
+
entries: [],
|
|
79
|
+
lastUpdated: Date.now(),
|
|
80
|
+
staleEntries: [],
|
|
81
|
+
};
|
|
82
|
+
}
|
|
83
|
+
/**
|
|
84
|
+
* Identify stale entries (>7 days without enough references)
|
|
85
|
+
*/
|
|
86
|
+
function identifyStaleEntries(entries) {
|
|
87
|
+
const stale = [];
|
|
88
|
+
const now = Date.now();
|
|
89
|
+
for (const entry of entries) {
|
|
90
|
+
const daysSinceRef = (now - entry.lastReferencedAt) / (24 * 60 * 60 * 1000);
|
|
91
|
+
if (daysSinceRef > STALE_THRESHOLD_DAYS && entry.referenceCount < STALE_REFERENCE_COUNT) {
|
|
92
|
+
stale.push(entry.id);
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
return stale;
|
|
96
|
+
}
|
|
97
|
+
/**
|
|
98
|
+
* Save hot cache to disk
|
|
99
|
+
*/
|
|
100
|
+
export async function saveHotCache(cache) {
|
|
101
|
+
const cachePath = getHotCachePath(cache.projectPath);
|
|
102
|
+
try {
|
|
103
|
+
await ensureSquishDir(cache.projectPath);
|
|
104
|
+
writeFileSync(cachePath, JSON.stringify(cache, null, 2), 'utf-8');
|
|
105
|
+
cache.lastUpdated = Date.now();
|
|
106
|
+
}
|
|
107
|
+
catch (error) {
|
|
108
|
+
logger.error('[HotCache] Save failed', { error });
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
/**
|
|
112
|
+
* Add an entry to hot cache (with deduplication)
|
|
113
|
+
*/
|
|
114
|
+
export async function addToHotCache(content, options) {
|
|
115
|
+
const path = options?.projectPath || await getProjectPath();
|
|
116
|
+
if (!path) {
|
|
117
|
+
return createEmptyHotCache('');
|
|
118
|
+
}
|
|
119
|
+
const cache = await loadHotCache(path);
|
|
120
|
+
const contentHash = hashContent(content);
|
|
121
|
+
// Check for duplicate by hash
|
|
122
|
+
const existingIndex = cache.entries.findIndex(e => e.hash === contentHash);
|
|
123
|
+
if (existingIndex >= 0) {
|
|
124
|
+
// Update reference info for duplicate
|
|
125
|
+
cache.entries[existingIndex].lastReferencedAt = Date.now();
|
|
126
|
+
cache.entries[existingIndex].referenceCount++;
|
|
127
|
+
await saveHotCache(cache);
|
|
128
|
+
logger.debug('[HotCache] Updated existing entry reference', { hash: contentHash });
|
|
129
|
+
return cache;
|
|
130
|
+
}
|
|
131
|
+
// Add new entry
|
|
132
|
+
const newEntry = {
|
|
133
|
+
id: `hot-${Date.now()}-${Math.random().toString(36).slice(2, 8)}`,
|
|
134
|
+
content: content.slice(0, 500), // Limit individual entry size
|
|
135
|
+
hash: contentHash,
|
|
136
|
+
createdAt: Date.now(),
|
|
137
|
+
lastReferencedAt: Date.now(),
|
|
138
|
+
referenceCount: 1,
|
|
139
|
+
tags: options?.tags,
|
|
140
|
+
};
|
|
141
|
+
cache.entries.push(newEntry);
|
|
142
|
+
// Trim if over max size (remove oldest entries)
|
|
143
|
+
if (cache.entries.length > MAX_HOT_CACHE_SIZE) {
|
|
144
|
+
cache.entries = cache.entries
|
|
145
|
+
.sort((a, b) => b.lastReferencedAt - a.lastReferencedAt)
|
|
146
|
+
.slice(0, MAX_HOT_CACHE_SIZE);
|
|
147
|
+
}
|
|
148
|
+
await saveHotCache(cache);
|
|
149
|
+
logger.info('[HotCache] Added new entry', { entries: cache.entries.length });
|
|
150
|
+
return cache;
|
|
151
|
+
}
|
|
152
|
+
/**
|
|
153
|
+
* Get hot cache summary for context
|
|
154
|
+
* Returns markdown-formatted summary of recent entries
|
|
155
|
+
*/
|
|
156
|
+
export async function getHotCacheSummary(options) {
|
|
157
|
+
const path = options?.projectPath || await getProjectPath();
|
|
158
|
+
if (!path)
|
|
159
|
+
return '';
|
|
160
|
+
const cache = await loadHotCache(path);
|
|
161
|
+
if (cache.entries.length === 0) {
|
|
162
|
+
return '## Hot Cache\n\nNo active hot memories yet.\n';
|
|
163
|
+
}
|
|
164
|
+
const maxEntries = options?.maxEntries || 10;
|
|
165
|
+
const recentEntries = cache.entries
|
|
166
|
+
.sort((a, b) => b.lastReferencedAt - a.lastReferencedAt)
|
|
167
|
+
.slice(0, maxEntries);
|
|
168
|
+
const lines = ['## Hot Cache\n'];
|
|
169
|
+
for (const entry of recentEntries) {
|
|
170
|
+
const date = new Date(entry.lastReferencedAt).toISOString().split('T')[0];
|
|
171
|
+
const stale = cache.staleEntries.includes(entry.id) ? ' [STALE]' : '';
|
|
172
|
+
lines.push(`- ${entry.content.slice(0, 100)}${entry.content.length > 100 ? '...' : ''}${stale} (${date})`);
|
|
173
|
+
}
|
|
174
|
+
if (cache.staleEntries.length > 0) {
|
|
175
|
+
lines.push(`\n* ${cache.staleEntries.length} entries flagged as stale (consider cleaning)*`);
|
|
176
|
+
}
|
|
177
|
+
return lines.join('\n');
|
|
178
|
+
}
|
|
179
|
+
/**
|
|
180
|
+
* Reference an existing hot cache entry (prevents staleness)
|
|
181
|
+
*/
|
|
182
|
+
export async function referenceHotCacheEntry(entryId, projectPath) {
|
|
183
|
+
const path = projectPath || await getProjectPath();
|
|
184
|
+
if (!path)
|
|
185
|
+
return false;
|
|
186
|
+
const cache = await loadHotCache(path);
|
|
187
|
+
const entry = cache.entries.find(e => e.id === entryId);
|
|
188
|
+
if (entry) {
|
|
189
|
+
entry.lastReferencedAt = Date.now();
|
|
190
|
+
entry.referenceCount++;
|
|
191
|
+
await saveHotCache(cache);
|
|
192
|
+
return true;
|
|
193
|
+
}
|
|
194
|
+
return false;
|
|
195
|
+
}
|
|
196
|
+
/**
|
|
197
|
+
* Remove stale entries from hot cache
|
|
198
|
+
*/
|
|
199
|
+
export async function cleanStaleEntries(projectPath) {
|
|
200
|
+
const path = projectPath || await getProjectPath();
|
|
201
|
+
if (!path)
|
|
202
|
+
return 0;
|
|
203
|
+
const cache = await loadHotCache(path);
|
|
204
|
+
const staleIdSet = new Set(cache.staleEntries);
|
|
205
|
+
const originalCount = cache.entries.length;
|
|
206
|
+
cache.entries = cache.entries.filter(e => !staleIdSet.has(e.id));
|
|
207
|
+
cache.staleEntries = [];
|
|
208
|
+
await saveHotCache(cache);
|
|
209
|
+
const removed = originalCount - cache.entries.length;
|
|
210
|
+
logger.info('[HotCache] Cleaned stale entries', { removed });
|
|
211
|
+
return removed;
|
|
212
|
+
}
|
|
213
|
+
/**
|
|
214
|
+
* Add session context to hot cache
|
|
215
|
+
* Called from session hooks with key session information
|
|
216
|
+
*/
|
|
217
|
+
export async function addSessionContextToHotCache(sessionInfo, projectPath) {
|
|
218
|
+
const path = projectPath || await getProjectPath();
|
|
219
|
+
if (!path)
|
|
220
|
+
return createEmptyHotCache('');
|
|
221
|
+
// Build context entries from session info
|
|
222
|
+
const entries = [];
|
|
223
|
+
if (sessionInfo.activeFiles?.length) {
|
|
224
|
+
entries.push(`Active files: ${sessionInfo.activeFiles.join(', ')}`);
|
|
225
|
+
}
|
|
226
|
+
if (sessionInfo.commands?.length) {
|
|
227
|
+
entries.push(`Recent commands: ${sessionInfo.commands.slice(-3).join('; ')}`);
|
|
228
|
+
}
|
|
229
|
+
if (sessionInfo.failures?.length) {
|
|
230
|
+
entries.push(`Recent failures: ${sessionInfo.failures.slice(-2).join('; ')}`);
|
|
231
|
+
}
|
|
232
|
+
if (sessionInfo.decisions?.length) {
|
|
233
|
+
entries.push(`Decisions: ${sessionInfo.decisions.join('; ')}`);
|
|
234
|
+
}
|
|
235
|
+
if (sessionInfo.hypotheses?.length) {
|
|
236
|
+
entries.push(`Hypotheses: ${sessionInfo.hypotheses.slice(-2).join('; ')}`);
|
|
237
|
+
}
|
|
238
|
+
// Add each entry to hot cache
|
|
239
|
+
let cache = await loadHotCache(path);
|
|
240
|
+
for (const entry of entries) {
|
|
241
|
+
cache = await addToHotCache(entry, { projectPath: path });
|
|
242
|
+
}
|
|
243
|
+
return cache;
|
|
244
|
+
}
|
|
245
|
+
/**
|
|
246
|
+
* Get all hot cache entries (for advanced use)
|
|
247
|
+
*/
|
|
248
|
+
export async function getHotCacheEntries(projectPath) {
|
|
249
|
+
const path = projectPath || await getProjectPath();
|
|
250
|
+
if (!path)
|
|
251
|
+
return [];
|
|
252
|
+
const cache = await loadHotCache(path);
|
|
253
|
+
return cache.entries;
|
|
254
|
+
}
|
|
255
|
+
/**
|
|
256
|
+
* Clear hot cache (dangerous - use with caution)
|
|
257
|
+
*/
|
|
258
|
+
export async function clearHotCache(projectPath) {
|
|
259
|
+
const path = projectPath || await getProjectPath();
|
|
260
|
+
if (!path)
|
|
261
|
+
return;
|
|
262
|
+
const cache = createEmptyHotCache(path);
|
|
263
|
+
await saveHotCache(cache);
|
|
264
|
+
logger.info('[HotCache] Cleared');
|
|
265
|
+
}
|
|
266
|
+
/**
|
|
267
|
+
* Get hot cache statistics
|
|
268
|
+
*/
|
|
269
|
+
export async function getHotCacheStats(projectPath) {
|
|
270
|
+
const path = projectPath || await getProjectPath();
|
|
271
|
+
if (!path)
|
|
272
|
+
return { entries: 0, staleEntries: 0, oldestEntry: null, newestEntry: null };
|
|
273
|
+
const cache = await loadHotCache(path);
|
|
274
|
+
if (cache.entries.length === 0) {
|
|
275
|
+
return { entries: 0, staleEntries: 0, oldestEntry: null, newestEntry: null };
|
|
276
|
+
}
|
|
277
|
+
const timestamps = cache.entries.map(e => e.createdAt);
|
|
278
|
+
return {
|
|
279
|
+
entries: cache.entries.length,
|
|
280
|
+
staleEntries: cache.staleEntries.length,
|
|
281
|
+
oldestEntry: Math.min(...timestamps),
|
|
282
|
+
newestEntry: Math.max(...timestamps),
|
|
283
|
+
};
|
|
284
|
+
}
|
|
285
|
+
//# sourceMappingURL=hot-cache.js.map
|
package/dist/core/index.d.ts
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
|
-
export * from './storage/cache
|
|
2
|
-
export * from './context/context
|
|
3
|
-
export * from './storage/database
|
|
4
|
-
export * from './embeddings
|
|
5
|
-
export * from './ingestion/learnings
|
|
6
|
-
export * from './security/privacy
|
|
7
|
-
export * from './projects
|
|
8
|
-
export * from './security/secret-detector
|
|
9
|
-
export * from './worker
|
|
1
|
+
export * from './storage/cache';
|
|
2
|
+
export * from './context/context';
|
|
3
|
+
export * from './storage/database';
|
|
4
|
+
export * from './embeddings';
|
|
5
|
+
export * from './ingestion/learnings';
|
|
6
|
+
export * from './security/privacy';
|
|
7
|
+
export * from './projects';
|
|
8
|
+
export * from './security/secret-detector';
|
|
9
|
+
export * from './worker';
|
|
10
10
|
//# sourceMappingURL=index.d.ts.map
|
package/dist/core/index.js
CHANGED
|
@@ -1,14 +1,11 @@
|
|
|
1
1
|
// Shared services - Core utilities and services
|
|
2
|
-
export * from './storage/cache
|
|
3
|
-
export * from './context/context
|
|
4
|
-
export * from './storage/database
|
|
5
|
-
export * from './embeddings
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
export * from './
|
|
9
|
-
export * from './security/
|
|
10
|
-
export * from './
|
|
11
|
-
// Note: redis exports duplicates of cache, import directly when needed
|
|
12
|
-
export * from './security/secret-detector.js';
|
|
13
|
-
export * from './worker.js';
|
|
2
|
+
export * from './storage/cache';
|
|
3
|
+
export * from './context/context';
|
|
4
|
+
export * from './storage/database';
|
|
5
|
+
export * from './embeddings';
|
|
6
|
+
export * from './ingestion/learnings';
|
|
7
|
+
export * from './security/privacy';
|
|
8
|
+
export * from './projects';
|
|
9
|
+
export * from './security/secret-detector';
|
|
10
|
+
export * from './worker';
|
|
14
11
|
//# sourceMappingURL=index.js.map
|
|
@@ -68,11 +68,11 @@ export declare function getCoreMemoryStats(projectId: string): Promise<{
|
|
|
68
68
|
}>;
|
|
69
69
|
/**
|
|
70
70
|
* Estimate token count from text (rough approximation: 1 token ≈ 4 chars)
|
|
71
|
+
* Import from context-window.ts - single source of truth
|
|
71
72
|
*/
|
|
72
|
-
export
|
|
73
|
+
export { estimateTokens } from '../context/context-window.js';
|
|
73
74
|
/**
|
|
74
75
|
* Get core memory formatted for context injection
|
|
75
76
|
*/
|
|
76
77
|
export declare function formatCoreMemoryForInjection(projectId: string): Promise<string>;
|
|
77
|
-
export {};
|
|
78
78
|
//# sourceMappingURL=core-memory.d.ts.map
|
|
@@ -9,6 +9,7 @@ import { getDb } from '../../db/index.js';
|
|
|
9
9
|
import { getSchema } from '../../db/schema.js';
|
|
10
10
|
import { createDatabaseClient } from '../storage/database.js';
|
|
11
11
|
import config from '../../config.js';
|
|
12
|
+
import { estimateTokens } from '../context/context-window.js';
|
|
12
13
|
// Use configurable limits from environment
|
|
13
14
|
const MAX_TOTAL_SIZE_BYTES = config.coreMemoryTotalBytes;
|
|
14
15
|
const MAX_SECTION_SIZE_BYTES = config.coreMemorySectionBytes;
|
|
@@ -188,10 +189,9 @@ export async function getCoreMemoryStats(projectId) {
|
|
|
188
189
|
}
|
|
189
190
|
/**
|
|
190
191
|
* Estimate token count from text (rough approximation: 1 token ≈ 4 chars)
|
|
192
|
+
* Import from context-window.ts - single source of truth
|
|
191
193
|
*/
|
|
192
|
-
export
|
|
193
|
-
return Math.ceil(text.length / 4);
|
|
194
|
-
}
|
|
194
|
+
export { estimateTokens } from '../context/context-window.js';
|
|
195
195
|
/**
|
|
196
196
|
* Get core memory formatted for context injection
|
|
197
197
|
*/
|
|
@@ -13,6 +13,7 @@ import { logger } from '../logger.js';
|
|
|
13
13
|
import { getDbClient } from '../lib/db-client.js';
|
|
14
14
|
import { createAssociation } from '../associations.js';
|
|
15
15
|
import { search } from '../memory/memories.js';
|
|
16
|
+
import { updateAgentPreference } from '../agent-preferences.js';
|
|
16
17
|
/**
|
|
17
18
|
* Create a learning and optionally auto-link to similar memories/learnings
|
|
18
19
|
*/
|
|
@@ -53,6 +54,8 @@ export async function createLearning(input) {
|
|
|
53
54
|
if (autoLink) {
|
|
54
55
|
await autoLinkLearning(id, input.content, project?.id ?? null);
|
|
55
56
|
}
|
|
57
|
+
// Extract and store agent preferences from this learning
|
|
58
|
+
await updateAgentPreference(project?.id ?? 'default', input.content, id);
|
|
56
59
|
return {
|
|
57
60
|
id,
|
|
58
61
|
projectId: project?.id ?? null,
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
export type SignalClassification = 'discard' | 'session-only' | 'durable-distilled' | 'durable-raw+distilled';
|
|
2
|
+
export interface SignalEventInput {
|
|
3
|
+
toolName: string;
|
|
4
|
+
toolInput?: Record<string, unknown>;
|
|
5
|
+
toolResult?: unknown;
|
|
6
|
+
sessionId?: string | null;
|
|
7
|
+
}
|
|
8
|
+
export interface SignalDecision {
|
|
9
|
+
classification: SignalClassification;
|
|
10
|
+
reasons: string[];
|
|
11
|
+
storeRaw: boolean;
|
|
12
|
+
importance: 'low' | 'medium' | 'high';
|
|
13
|
+
wakeUpPriority: 'low' | 'medium' | 'high';
|
|
14
|
+
placeHint: {
|
|
15
|
+
placeType: 'inbox' | 'ref' | 'wip' | 'sandbox' | 'board' | 'sparks' | 'archive' | null;
|
|
16
|
+
confidence: number;
|
|
17
|
+
};
|
|
18
|
+
graphHint: {
|
|
19
|
+
shouldEnrich: boolean;
|
|
20
|
+
entityTerms: string[];
|
|
21
|
+
reason?: string;
|
|
22
|
+
};
|
|
23
|
+
content: string;
|
|
24
|
+
contentHash: string;
|
|
25
|
+
estimatedSavings: number;
|
|
26
|
+
}
|
|
27
|
+
export interface DistillInput {
|
|
28
|
+
toolName: string;
|
|
29
|
+
command?: string;
|
|
30
|
+
content: string;
|
|
31
|
+
classification: SignalClassification;
|
|
32
|
+
}
|
|
33
|
+
export declare function hashSignalContent(content: string): string;
|
|
34
|
+
export declare function classifySignalEvent(input: SignalEventInput): SignalDecision;
|
|
35
|
+
export declare function distillSignalEvent(input: DistillInput): string;
|
|
36
|
+
export declare function shouldReturnRawFallback(input: {
|
|
37
|
+
query: string;
|
|
38
|
+
hasRawFallback: boolean;
|
|
39
|
+
nuanceSuppressed: boolean;
|
|
40
|
+
}): boolean;
|
|
41
|
+
//# sourceMappingURL=signal-engine.d.ts.map
|
|
@@ -0,0 +1,201 @@
|
|
|
1
|
+
import { createHash } from 'crypto';
|
|
2
|
+
function normalizeContent(toolResult) {
|
|
3
|
+
if (typeof toolResult === 'string')
|
|
4
|
+
return toolResult;
|
|
5
|
+
if (toolResult == null)
|
|
6
|
+
return '';
|
|
7
|
+
if (typeof toolResult === 'object') {
|
|
8
|
+
try {
|
|
9
|
+
return JSON.stringify(toolResult, null, 2);
|
|
10
|
+
}
|
|
11
|
+
catch {
|
|
12
|
+
return String(toolResult);
|
|
13
|
+
}
|
|
14
|
+
}
|
|
15
|
+
return String(toolResult);
|
|
16
|
+
}
|
|
17
|
+
function estimateNoiseSavings(raw, distilled) {
|
|
18
|
+
return Math.max(0, raw.length - distilled.length);
|
|
19
|
+
}
|
|
20
|
+
function extractEntityTerms(content) {
|
|
21
|
+
const matches = content.match(/\b([A-Z][A-Za-z0-9]+|[a-z]+(?:\.[a-z0-9_-]+)+|[A-Za-z0-9_-]+\.ts)\b/g) ?? [];
|
|
22
|
+
return [...new Set(matches.filter((term) => term.length > 2))].slice(0, 6);
|
|
23
|
+
}
|
|
24
|
+
function inferPlaceHint(toolName, normalized) {
|
|
25
|
+
if (['write', 'edit', 'multiedit'].includes(toolName.toLowerCase()) || /\b(fix|bug|implement|refactor|edited|wrote)\b/.test(normalized)) {
|
|
26
|
+
return { placeType: 'wip', confidence: 0.88 };
|
|
27
|
+
}
|
|
28
|
+
if (/\b(test|assertionerror|traceback|exception|experiment|verify)\b/.test(normalized)) {
|
|
29
|
+
return { placeType: 'sandbox', confidence: 0.92 };
|
|
30
|
+
}
|
|
31
|
+
if (/\b(hypothesis|plan|decided|roadmap|task|todo|investigate)\b/.test(normalized)) {
|
|
32
|
+
return { placeType: 'board', confidence: 0.74 };
|
|
33
|
+
}
|
|
34
|
+
if (/\b(research|docs|pattern|reference|api|architecture)\b/.test(normalized)) {
|
|
35
|
+
return { placeType: 'ref', confidence: 0.72 };
|
|
36
|
+
}
|
|
37
|
+
if (/\b(idea|explore|future|concept)\b/.test(normalized)) {
|
|
38
|
+
return { placeType: 'sparks', confidence: 0.68 };
|
|
39
|
+
}
|
|
40
|
+
return { placeType: null, confidence: 0 };
|
|
41
|
+
}
|
|
42
|
+
function inferGraphHint(normalized, content, classification) {
|
|
43
|
+
if (classification === 'discard' || classification === 'session-only') {
|
|
44
|
+
return { shouldEnrich: false, entityTerms: [], reason: 'non-durable signal' };
|
|
45
|
+
}
|
|
46
|
+
const entityTerms = extractEntityTerms(content);
|
|
47
|
+
const hasStructuredSignal = entityTerms.length > 0 || /\b(fix|decision|preference|error|graph|ranking|entity|relationship)\b/.test(normalized);
|
|
48
|
+
if (!hasStructuredSignal) {
|
|
49
|
+
return { shouldEnrich: false, entityTerms: [], reason: 'no graph-worthy entities' };
|
|
50
|
+
}
|
|
51
|
+
return {
|
|
52
|
+
shouldEnrich: true,
|
|
53
|
+
entityTerms,
|
|
54
|
+
reason: 'durable signal with identifiable entities',
|
|
55
|
+
};
|
|
56
|
+
}
|
|
57
|
+
export function hashSignalContent(content) {
|
|
58
|
+
return createHash('sha1').update(content).digest('hex');
|
|
59
|
+
}
|
|
60
|
+
export function classifySignalEvent(input) {
|
|
61
|
+
const toolName = input.toolName;
|
|
62
|
+
const command = String(input.toolInput?.command ?? input.toolInput?.cmd ?? '');
|
|
63
|
+
const content = normalizeContent(input.toolResult);
|
|
64
|
+
const normalized = `${command}\n${content}`.toLowerCase();
|
|
65
|
+
const reasons = [];
|
|
66
|
+
const noisyCommand = /\b(npm|bun|pnpm|yarn)\s+(install|add)\b/.test(normalized) ||
|
|
67
|
+
/\bdownload(ed|ing)?\b|\bfetch(ed|ing)?\b|\bprogress\b|\bresolved\b/.test(normalized);
|
|
68
|
+
if (noisyCommand) {
|
|
69
|
+
const placeHint = inferPlaceHint(toolName, normalized);
|
|
70
|
+
reasons.push('noise filtered from install/build output');
|
|
71
|
+
return {
|
|
72
|
+
classification: 'discard',
|
|
73
|
+
reasons,
|
|
74
|
+
storeRaw: false,
|
|
75
|
+
importance: 'low',
|
|
76
|
+
wakeUpPriority: 'low',
|
|
77
|
+
placeHint,
|
|
78
|
+
graphHint: inferGraphHint(normalized, content, 'discard'),
|
|
79
|
+
content,
|
|
80
|
+
contentHash: hashSignalContent(normalized),
|
|
81
|
+
estimatedSavings: content.length,
|
|
82
|
+
};
|
|
83
|
+
}
|
|
84
|
+
if (/\b(current hypothesis|hypothesis:|investigate|trying next)\b/.test(normalized)) {
|
|
85
|
+
const placeHint = inferPlaceHint(toolName, normalized);
|
|
86
|
+
reasons.push('active session hypothesis');
|
|
87
|
+
return {
|
|
88
|
+
classification: 'session-only',
|
|
89
|
+
reasons,
|
|
90
|
+
storeRaw: false,
|
|
91
|
+
importance: 'medium',
|
|
92
|
+
wakeUpPriority: 'high',
|
|
93
|
+
placeHint,
|
|
94
|
+
graphHint: inferGraphHint(normalized, content, 'session-only'),
|
|
95
|
+
content,
|
|
96
|
+
contentHash: hashSignalContent(normalized),
|
|
97
|
+
estimatedSavings: 0,
|
|
98
|
+
};
|
|
99
|
+
}
|
|
100
|
+
if (/\bcorrection:|actually\b|\binstead of\b|\bprefer(s)?\b/.test(normalized)) {
|
|
101
|
+
const placeHint = inferPlaceHint(toolName, normalized);
|
|
102
|
+
reasons.push('correction or preference worth durable retention');
|
|
103
|
+
return {
|
|
104
|
+
classification: 'durable-distilled',
|
|
105
|
+
reasons,
|
|
106
|
+
storeRaw: false,
|
|
107
|
+
importance: 'high',
|
|
108
|
+
wakeUpPriority: 'high',
|
|
109
|
+
placeHint,
|
|
110
|
+
graphHint: inferGraphHint(normalized, content, 'durable-distilled'),
|
|
111
|
+
content,
|
|
112
|
+
contentHash: hashSignalContent(normalized),
|
|
113
|
+
estimatedSavings: estimateNoiseSavings(content, distillSignalEvent({
|
|
114
|
+
toolName,
|
|
115
|
+
command,
|
|
116
|
+
content,
|
|
117
|
+
classification: 'durable-distilled',
|
|
118
|
+
})),
|
|
119
|
+
};
|
|
120
|
+
}
|
|
121
|
+
if (/\b(fail|failed|failing|assertionerror|stack trace|traceback|exception)\b/.test(normalized) ||
|
|
122
|
+
/\b(test|pytest|vitest|jest|bun test)\b/.test(normalized)) {
|
|
123
|
+
const placeHint = inferPlaceHint(toolName, normalized);
|
|
124
|
+
reasons.push('test or debugging signal with nuance-sensitive output');
|
|
125
|
+
return {
|
|
126
|
+
classification: 'durable-raw+distilled',
|
|
127
|
+
reasons,
|
|
128
|
+
storeRaw: true,
|
|
129
|
+
importance: 'high',
|
|
130
|
+
wakeUpPriority: 'high',
|
|
131
|
+
placeHint,
|
|
132
|
+
graphHint: inferGraphHint(normalized, content, 'durable-raw+distilled'),
|
|
133
|
+
content,
|
|
134
|
+
contentHash: hashSignalContent(normalized),
|
|
135
|
+
estimatedSavings: estimateNoiseSavings(content, distillSignalEvent({
|
|
136
|
+
toolName,
|
|
137
|
+
command,
|
|
138
|
+
content,
|
|
139
|
+
classification: 'durable-raw+distilled',
|
|
140
|
+
})),
|
|
141
|
+
};
|
|
142
|
+
}
|
|
143
|
+
if (['write', 'edit', 'multiedit'].includes(toolName.toLowerCase())) {
|
|
144
|
+
const placeHint = inferPlaceHint(toolName, normalized);
|
|
145
|
+
reasons.push('meaningful file modification');
|
|
146
|
+
return {
|
|
147
|
+
classification: 'durable-distilled',
|
|
148
|
+
reasons,
|
|
149
|
+
storeRaw: false,
|
|
150
|
+
importance: 'medium',
|
|
151
|
+
wakeUpPriority: 'medium',
|
|
152
|
+
placeHint,
|
|
153
|
+
graphHint: inferGraphHint(normalized, content, 'durable-distilled'),
|
|
154
|
+
content,
|
|
155
|
+
contentHash: hashSignalContent(normalized),
|
|
156
|
+
estimatedSavings: estimateNoiseSavings(content, distillSignalEvent({
|
|
157
|
+
toolName,
|
|
158
|
+
command,
|
|
159
|
+
content,
|
|
160
|
+
classification: 'durable-distilled',
|
|
161
|
+
})),
|
|
162
|
+
};
|
|
163
|
+
}
|
|
164
|
+
reasons.push('session-scoped operational context');
|
|
165
|
+
const placeHint = inferPlaceHint(toolName, normalized);
|
|
166
|
+
return {
|
|
167
|
+
classification: 'session-only',
|
|
168
|
+
reasons,
|
|
169
|
+
storeRaw: false,
|
|
170
|
+
importance: 'low',
|
|
171
|
+
wakeUpPriority: 'low',
|
|
172
|
+
placeHint,
|
|
173
|
+
graphHint: inferGraphHint(normalized, content, 'session-only'),
|
|
174
|
+
content,
|
|
175
|
+
contentHash: hashSignalContent(normalized),
|
|
176
|
+
estimatedSavings: 0,
|
|
177
|
+
};
|
|
178
|
+
}
|
|
179
|
+
export function distillSignalEvent(input) {
|
|
180
|
+
const lines = input.content
|
|
181
|
+
.split(/\r?\n/)
|
|
182
|
+
.map((line) => line.trim())
|
|
183
|
+
.filter(Boolean);
|
|
184
|
+
const important = lines.filter((line) => /\b(fail|error|exception|traceback|assert|stack|correction|prefer|decision|fix|edited|wrote)\b/i.test(line));
|
|
185
|
+
const selected = important.length > 0 ? important : lines.slice(0, 4);
|
|
186
|
+
const cleaned = selected.filter((line) => !/\b(pass(ing)?|resolved|download(ed|ing)?|progress|packages? added)\b/i.test(line));
|
|
187
|
+
if (/assertionerror|traceback|exception|stack/i.test(input.content) && !cleaned.some((line) => /assertionerror|traceback|exception|stack/i.test(line))) {
|
|
188
|
+
const extra = lines.find((line) => /assertionerror|traceback|exception|stack/i.test(line));
|
|
189
|
+
if (extra)
|
|
190
|
+
cleaned.push(extra);
|
|
191
|
+
}
|
|
192
|
+
return cleaned.slice(0, 6).join('\n');
|
|
193
|
+
}
|
|
194
|
+
export function shouldReturnRawFallback(input) {
|
|
195
|
+
if (!input.hasRawFallback)
|
|
196
|
+
return false;
|
|
197
|
+
if (input.nuanceSuppressed)
|
|
198
|
+
return true;
|
|
199
|
+
return /\b(raw|original|full|stack trace|traceback|stderr|stdout|rewind)\b/i.test(input.query);
|
|
200
|
+
}
|
|
201
|
+
//# sourceMappingURL=signal-engine.js.map
|
|
@@ -24,7 +24,8 @@ export declare function appendToObsidianVault(memory: ObsidianMemoryInput, vault
|
|
|
24
24
|
*/
|
|
25
25
|
export declare function isObsidianConnected(vaultPath: string): boolean;
|
|
26
26
|
/**
|
|
27
|
-
* Read existing memories from Obsidian vault (for
|
|
27
|
+
* Read existing memories from Obsidian vault (for import feature)
|
|
28
|
+
* Scans vault for .md files and extracts memory blocks
|
|
28
29
|
*/
|
|
29
30
|
export declare function readFromVault(vaultPath: string): Promise<ObsidianMemoryInput[]>;
|
|
30
31
|
//# sourceMappingURL=obsidian-vault.d.ts.map
|