squish-memory 1.0.2 → 1.1.5
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 +130 -0
- package/CHANGELOG.md +55 -0
- package/README.md +150 -287
- package/config/hooks/claude-code-hooks.json +39 -0
- package/config/hooks/cursor-hooks.json +30 -0
- package/config/hooks/opencode-hooks.json +30 -0
- package/config/hooks/windsurf-hooks.json +30 -0
- package/config/mcp-mode-semantics.json +23 -21
- package/config/plugin-manifest.json +101 -152
- package/{plugin.json → config/plugin.json} +2 -2
- package/config/settings.json +52 -51
- package/{commands → core/commands}/init.md +39 -39
- package/dist/config.d.ts +28 -4
- package/dist/config.js +97 -29
- package/dist/core/adapters/config/claude-code.d.ts +45 -0
- package/dist/core/adapters/config/claude-code.js +113 -0
- package/dist/core/adapters/config/cursor.d.ts +26 -0
- package/dist/core/adapters/config/cursor.js +74 -0
- package/dist/core/adapters/config/opencode.d.ts +23 -0
- package/dist/core/adapters/config/opencode.js +73 -0
- package/dist/core/adapters/config/windsurf.d.ts +26 -0
- package/dist/core/adapters/config/windsurf.js +74 -0
- package/dist/core/adapters/index.d.ts +45 -0
- package/dist/core/adapters/index.js +84 -0
- package/dist/core/adapters/scripts/install-adapter.d.ts +19 -0
- package/dist/core/adapters/scripts/install-adapter.js +149 -0
- package/dist/core/adapters/timeline.d.ts +23 -0
- package/dist/core/adapters/timeline.js +88 -0
- package/dist/core/adapters/types.d.ts +157 -0
- package/dist/core/adapters/types.js +50 -0
- package/dist/{algorithms → core/algorithms}/analytics/token-estimator.d.ts +1 -1
- package/dist/{algorithms → core/algorithms}/analytics/token-estimator.js +3 -3
- package/dist/{algorithms → core/algorithms}/detection/semantic-ranker.d.ts +1 -1
- package/dist/{algorithms → core/algorithms}/detection/semantic-ranker.js +1 -1
- package/dist/{algorithms → core/algorithms}/detection/two-stage-detector.d.ts +1 -1
- package/dist/{algorithms → core/algorithms}/detection/two-stage-detector.js +7 -10
- package/dist/{algorithms → core/algorithms}/handlers/approve-merge.js +4 -4
- package/dist/{algorithms → core/algorithms}/handlers/detect-duplicates.js +3 -3
- package/dist/{algorithms → core/algorithms}/handlers/get-stats.js +3 -3
- package/dist/{algorithms → core/algorithms}/handlers/list-proposals.js +3 -3
- package/dist/{algorithms → core/algorithms}/handlers/preview-merge.js +3 -3
- package/dist/{algorithms → core/algorithms}/handlers/reject-merge.js +3 -3
- package/dist/{algorithms → core/algorithms}/handlers/reverse-merge.js +3 -3
- package/dist/core/algorithms/index.d.ts +21 -0
- package/dist/core/algorithms/index.js +26 -0
- package/dist/core/algorithms/operations/cache-maintenance.d.ts +12 -0
- package/dist/core/algorithms/operations/cache-maintenance.js +157 -0
- package/dist/{algorithms → core/algorithms}/safety/safety-checks.d.ts +1 -1
- package/dist/{algorithms → core/algorithms}/strategies/merge-strategies.d.ts +19 -1
- package/dist/{algorithms → core/algorithms}/strategies/merge-strategies.js +74 -123
- package/dist/core/algorithms/types.d.ts +133 -0
- package/dist/core/algorithms/types.js +5 -0
- package/dist/core/associations.d.ts +1 -2
- package/dist/core/associations.js +1 -2
- package/dist/core/autosave.d.ts +19 -0
- package/dist/core/autosave.js +16 -0
- package/dist/{commands → core/commands}/managed-sync.js +5 -5
- package/dist/core/commands/mcp-server.js +739 -0
- package/dist/core/context/agent-context.d.ts +106 -0
- package/dist/core/context/agent-context.js +274 -0
- package/dist/core/{context-paging.d.ts → context/context-paging.d.ts} +2 -12
- package/dist/core/{context-paging.js → context/context-paging.js} +19 -39
- package/dist/core/context/context-window.d.ts +40 -0
- package/dist/core/context/context-window.js +177 -0
- package/dist/core/context/context.js +22 -0
- package/dist/core/embeddings.d.ts +1 -1
- package/dist/core/embeddings.js +54 -2
- package/dist/core/error-handling.d.ts +63 -0
- package/dist/core/error-handling.js +173 -0
- package/dist/core/external-folder/index.d.ts +102 -0
- package/dist/core/external-folder/index.js +294 -0
- package/dist/core/hooks/agent-hooks.d.ts +74 -0
- package/dist/core/hooks/agent-hooks.js +244 -0
- package/dist/core/hooks/auto-tagger.d.ts +19 -0
- package/dist/core/hooks/auto-tagger.js +155 -0
- package/dist/core/hooks/capture-filter.d.ts +41 -0
- package/dist/core/hooks/capture-filter.js +128 -0
- package/dist/core/index.d.ts +6 -6
- package/dist/core/index.js +6 -6
- package/dist/core/{agent-memory.js → ingestion/agent-memory.js} +5 -7
- package/dist/core/{core-memory.js → ingestion/core-memory.js} +4 -4
- package/dist/core/ingestion/learnings.d.ts +57 -0
- package/dist/core/ingestion/learnings.js +202 -0
- package/dist/core/lib/db-client.d.ts +114 -0
- package/dist/core/lib/db-client.js +130 -0
- package/dist/core/lib/schemas.d.ts +129 -0
- package/dist/core/lib/schemas.js +87 -0
- package/dist/core/{utils.d.ts → lib/utils.d.ts} +1 -0
- package/dist/core/{utils.js → lib/utils.js} +31 -15
- package/dist/core/lib/validation.d.ts +38 -0
- package/dist/core/lib/validation.js +151 -0
- package/dist/core/lifecycle.d.ts +7 -0
- package/dist/core/lifecycle.js +140 -20
- package/dist/core/local-embeddings.d.ts +6 -1
- package/dist/core/local-embeddings.js +6 -15
- package/dist/core/logger.js +7 -1
- package/dist/core/mcp/tools.js +35 -3
- package/dist/core/memory/categorizer.js +1 -0
- package/dist/core/memory/conflict-detector.js +1 -1
- package/dist/core/memory/consolidation.d.ts +1 -10
- package/dist/core/memory/consolidation.js +2 -11
- package/dist/core/memory/context-collector.js +1 -1
- package/dist/core/memory/edit-workflow.js +1 -1
- package/dist/core/memory/entity-resolver.js +7 -7
- package/dist/core/memory/fact-extractor.js +12 -12
- package/dist/core/memory/feedback-tracker.js +1 -1
- package/dist/core/memory/hooks.d.ts +88 -0
- package/dist/core/memory/hooks.js +174 -0
- package/dist/core/memory/hybrid-retrieval.js +2 -2
- package/dist/core/memory/hybrid-search.d.ts +1 -6
- package/dist/core/memory/hybrid-search.js +70 -84
- package/dist/core/memory/importance.d.ts +8 -13
- package/dist/core/memory/importance.js +47 -74
- package/dist/core/memory/loader.d.ts +31 -0
- package/dist/core/memory/loader.js +141 -0
- package/dist/core/memory/markdown/markdown-storage.d.ts +72 -0
- package/dist/core/memory/markdown/markdown-storage.js +243 -0
- package/dist/core/memory/memories.d.ts +12 -4
- package/dist/core/memory/memories.js +192 -180
- package/dist/core/memory/memory-lifecycle.d.ts +8 -0
- package/dist/core/memory/memory-lifecycle.js +55 -0
- package/dist/core/memory/migrate.d.ts +21 -0
- package/dist/core/memory/migrate.js +134 -0
- package/dist/core/memory/normalization.d.ts +22 -0
- package/dist/core/memory/normalization.js +26 -0
- package/dist/core/memory/progressive-disclosure.js +1 -1
- package/dist/core/memory/query-rewriter.js +9 -9
- package/dist/core/memory/serialization.d.ts +4 -0
- package/dist/core/memory/serialization.js +49 -0
- package/dist/core/memory/stats.d.ts +5 -0
- package/dist/core/memory/stats.js +63 -12
- package/dist/core/memory/temporal-facts.js +21 -0
- package/dist/core/memory/write-gate.js +1 -1
- package/dist/core/obsidian-vault.d.ts +30 -0
- package/dist/core/obsidian-vault.js +94 -0
- package/dist/core/places/index.d.ts +14 -0
- package/dist/core/places/index.js +14 -0
- package/dist/core/places/memory-places.d.ts +68 -0
- package/dist/core/places/memory-places.js +261 -0
- package/dist/core/places/places.d.ts +88 -0
- package/dist/core/places/places.js +314 -0
- package/dist/core/places/rules.d.ts +74 -0
- package/dist/core/places/rules.js +240 -0
- package/dist/core/places/walking.d.ts +56 -0
- package/dist/core/places/walking.js +121 -0
- package/dist/core/projects.d.ts +5 -0
- package/dist/core/projects.js +39 -18
- package/dist/core/responses.d.ts +96 -0
- package/dist/core/responses.js +122 -0
- package/dist/core/scheduler/cron-scheduler.js +29 -7
- package/dist/core/scheduler/index.d.ts +1 -1
- package/dist/core/scheduler/index.js +1 -1
- package/dist/core/scheduler/job-runner.js +1 -1
- package/dist/core/search/conversations.js +40 -42
- package/dist/core/search/entities.js +6 -9
- package/dist/core/search/graph-boost.d.ts +7 -0
- package/dist/core/search/graph-boost.js +23 -0
- package/dist/core/search/qmd-search.js +4 -4
- package/dist/core/security/encrypt.d.ts +6 -0
- package/dist/core/security/encrypt.js +47 -0
- package/dist/core/{governance.d.ts → security/governance.d.ts} +6 -1
- package/dist/core/security/governance.js +79 -0
- package/dist/core/session/auto-load.js +6 -6
- package/dist/core/session/index.d.ts +1 -1
- package/dist/core/session/index.js +1 -1
- package/dist/core/session/self-iteration-job.d.ts +20 -0
- package/dist/core/session/self-iteration-job.js +282 -0
- package/dist/core/session/session-hooks.d.ts +18 -0
- package/dist/core/session/session-hooks.js +58 -0
- package/dist/core/session-hooks/self-iteration-job.js +35 -35
- package/dist/core/{cache.js → storage/cache.js} +2 -2
- package/dist/core/sync/qmd-sync.d.ts +1 -13
- package/dist/core/sync/qmd-sync.js +1 -13
- package/dist/core/toon.d.ts +43 -0
- package/dist/core/toon.js +160 -0
- package/dist/core/utils/memory-operations.js +1 -1
- package/dist/core/utils/vector-operations.d.ts +71 -0
- package/dist/core/utils/vector-operations.js +129 -0
- package/dist/db/adapter.d.ts +3 -3
- package/dist/db/adapter.js +99 -88
- package/dist/db/bootstrap.js +820 -522
- package/dist/{drizzle → db/drizzle}/schema-sqlite.d.ts +74 -25
- package/dist/{drizzle → db/drizzle}/schema-sqlite.js +91 -24
- package/dist/{drizzle → db/drizzle}/schema.d.ts +79 -32
- package/dist/{drizzle → db/drizzle}/schema.js +106 -35
- package/dist/db/drizzle.config.d.ts +3 -0
- package/dist/db/drizzle.config.js +12 -0
- package/dist/db/index.d.ts +1 -5
- package/dist/db/index.js +51 -8
- package/dist/db/neon.d.ts +8 -0
- package/dist/db/neon.js +20 -0
- package/dist/db/schema/index.d.ts +40 -0
- package/dist/db/schema/index.js +105 -0
- package/dist/db/schema/tables/context-sessions.d.ts +9 -0
- package/dist/db/schema/tables/context-sessions.js +37 -0
- package/dist/db/schema/tables/conversations.d.ts +9 -0
- package/dist/db/schema/tables/conversations.js +47 -0
- package/dist/db/schema/tables/core-memory.d.ts +9 -0
- package/dist/db/schema/tables/core-memory.js +41 -0
- package/dist/db/schema/tables/entities.d.ts +9 -0
- package/dist/db/schema/tables/entities.js +39 -0
- package/dist/db/schema/tables/entity-relations.d.ts +9 -0
- package/dist/db/schema/tables/entity-relations.js +31 -0
- package/dist/db/schema/tables/learnings.d.ts +9 -0
- package/dist/db/schema/tables/learnings.js +66 -0
- package/dist/db/schema/tables/memories.d.ts +9 -0
- package/dist/db/schema/tables/memories.js +161 -0
- package/dist/db/schema/tables/memory-associations.d.ts +9 -0
- package/dist/db/schema/tables/memory-associations.js +39 -0
- package/dist/db/schema/tables/memory-hash-cache.d.ts +9 -0
- package/dist/db/schema/tables/memory-hash-cache.js +29 -0
- package/dist/db/schema/tables/memory-merge-history.d.ts +9 -0
- package/dist/db/schema/tables/memory-merge-history.js +33 -0
- package/dist/db/schema/tables/memory-merge-proposals.d.ts +9 -0
- package/dist/db/schema/tables/memory-merge-proposals.js +39 -0
- package/dist/db/schema/tables/messages.d.ts +9 -0
- package/dist/db/schema/tables/messages.js +41 -0
- package/dist/db/schema/tables/namespaces.d.ts +9 -0
- package/dist/db/schema/tables/namespaces.js +37 -0
- package/dist/db/schema/tables/projects.d.ts +9 -0
- package/dist/db/schema/tables/projects.js +31 -0
- package/dist/db/schema/tables/users.d.ts +9 -0
- package/dist/db/schema/tables/users.js +27 -0
- package/dist/db/schema.d.ts +1 -1
- package/dist/db/schema.js +2 -2
- package/dist/db/supabase.d.ts +9 -0
- package/dist/db/supabase.js +24 -0
- package/dist/index.d.ts +2 -14
- package/dist/index.js +1320 -640
- package/dist/vendor/sql.js/sql-wasm.wasm +0 -0
- package/dist/webui/server.d.ts +5 -0
- package/dist/{api/web/web.js → webui/server.js} +511 -508
- package/generated/mcp/manifest.json +1 -1
- package/{.mcp.json → mcp.json.example} +1 -1
- package/package.json +159 -181
- package/scripts/README.md +60 -0
- package/scripts/copy-runtime-assets.mjs +26 -0
- package/scripts/generate-mcp.mjs +264 -264
- package/scripts/github-release.sh +4 -4
- package/scripts/install-claude-code.sh +85 -0
- package/scripts/install-cursor.sh +56 -0
- package/scripts/install-hooks.sh +73 -0
- package/scripts/install-interactive.mjs +357 -677
- package/scripts/install-opencode.sh +75 -0
- package/scripts/install-windsurf.sh +67 -0
- package/skills/squish-memory/SKILL.md +104 -114
- package/skills/squish-memory/{install.mjs → scripts/install.mjs} +2 -2
- package/skills/squish-memory/{install.sh → scripts/install.sh} +2 -2
- package/skills/squish-memory/write_skill.js +2 -0
- package/.claude-plugin/marketplace.json +0 -20
- package/.claude-plugin/plugin.json +0 -32
- package/.env.mcp.example +0 -60
- package/QUICK-START.md +0 -71
- package/bin/squish-add.mjs +0 -32
- package/bin/squish-rm.mjs +0 -21
- package/commands/observe.md +0 -5
- package/dist/api/web/index.d.ts +0 -3
- package/dist/api/web/index.js +0 -4
- package/dist/api/web/web-server.d.ts +0 -3
- package/dist/api/web/web-server.js +0 -6
- package/dist/api/web/web.d.ts +0 -4
- package/dist/commands/mcp-server.js +0 -393
- package/dist/core/context.js +0 -24
- package/dist/core/governance.js +0 -64
- package/dist/core/observations.d.ts +0 -26
- package/dist/core/observations.js +0 -110
- package/dist/core/requirements.d.ts +0 -20
- package/dist/core/requirements.js +0 -35
- package/hooks/hooks.json +0 -52
- package/hooks/post-tool-use.js +0 -26
- package/hooks/session-end.js +0 -28
- package/hooks/session-start.js +0 -33
- package/hooks/user-prompt-submit.js +0 -26
- package/hooks/utils.js +0 -153
- package/npx-installer.js +0 -208
- package/packages/plugin-claude-code/README.md +0 -73
- package/packages/plugin-claude-code/dist/plugin-wrapper.d.ts +0 -35
- package/packages/plugin-claude-code/dist/plugin-wrapper.js +0 -191
- package/packages/plugin-claude-code/package.json +0 -31
- package/packages/plugin-openclaw/README.md +0 -70
- package/packages/plugin-openclaw/dist/index.d.ts +0 -49
- package/packages/plugin-openclaw/dist/index.js +0 -262
- package/packages/plugin-openclaw/openclaw.plugin.json +0 -94
- package/packages/plugin-openclaw/package.json +0 -31
- package/packages/plugin-opencode/install.mjs +0 -217
- package/packages/plugin-opencode/package.json +0 -21
- package/scripts/db/check-db.mjs +0 -88
- package/scripts/db/fix-all-columns.mjs +0 -52
- package/scripts/db/fix-schema-all.mjs +0 -55
- package/scripts/db/fix-schema-full.mjs +0 -46
- package/scripts/db/fix-schema.mjs +0 -38
- package/scripts/db/init-db.mjs +0 -13
- package/scripts/db/recreate-db.mjs +0 -14
- package/scripts/install-mcp.mjs +0 -116
- package/scripts/install-web.sh +0 -120
- package/scripts/install.mjs +0 -340
- package/scripts/openclaw-bootstrap.mjs +0 -127
- package/scripts/package-release.sh +0 -71
- package/scripts/test/test-all-systems.mjs +0 -139
- package/scripts/test/test-memory-system.mjs +0 -139
- package/scripts/test/test-v0.5.0.mjs +0 -210
- package/skills/memory-guide/SKILL.md +0 -332
- package/skills/squish-cli/SKILL.md +0 -240
- package/skills/squish-mcp/SKILL.md +0 -355
- package/skills/squish-memory/claude-desktop.json +0 -12
- package/skills/squish-memory/openclaw.json +0 -13
- package/skills/squish-memory/opencode.json +0 -14
- package/skills/squish-memory/skill.json +0 -32
- /package/{commands → core/commands}/context-paging.md +0 -0
- /package/{commands → core/commands}/context-status.md +0 -0
- /package/{commands → core/commands}/context.md +0 -0
- /package/{commands → core/commands}/core-memory.md +0 -0
- /package/{commands → core/commands}/health.md +0 -0
- /package/{commands → core/commands}/merge.md +0 -0
- /package/{commands → core/commands}/recall.md +0 -0
- /package/{commands → core/commands}/remember.md +0 -0
- /package/{commands → core/commands}/search.md +0 -0
- /package/dist/{algorithms → core/algorithms}/detection/hash-filters.d.ts +0 -0
- /package/dist/{algorithms → core/algorithms}/detection/hash-filters.js +0 -0
- /package/dist/{algorithms → core/algorithms}/handlers/approve-merge.d.ts +0 -0
- /package/dist/{algorithms → core/algorithms}/handlers/detect-duplicates.d.ts +0 -0
- /package/dist/{algorithms → core/algorithms}/handlers/get-stats.d.ts +0 -0
- /package/dist/{algorithms → core/algorithms}/handlers/list-proposals.d.ts +0 -0
- /package/dist/{algorithms → core/algorithms}/handlers/preview-merge.d.ts +0 -0
- /package/dist/{algorithms → core/algorithms}/handlers/reject-merge.d.ts +0 -0
- /package/dist/{algorithms → core/algorithms}/handlers/reverse-merge.d.ts +0 -0
- /package/dist/{algorithms → core/algorithms}/safety/safety-checks.js +0 -0
- /package/dist/{algorithms → core/algorithms}/utils/response-builder.d.ts +0 -0
- /package/dist/{algorithms → core/algorithms}/utils/response-builder.js +0 -0
- /package/dist/{commands → core/commands}/managed-sync.d.ts +0 -0
- /package/dist/{commands → core/commands}/mcp-server.d.ts +0 -0
- /package/dist/core/{context.d.ts → context/context.d.ts} +0 -0
- /package/dist/core/{agent-memory.d.ts → ingestion/agent-memory.d.ts} +0 -0
- /package/dist/core/{core-memory.d.ts → ingestion/core-memory.d.ts} +0 -0
- /package/dist/core/{privacy.d.ts → security/privacy.d.ts} +0 -0
- /package/dist/core/{privacy.js → security/privacy.js} +0 -0
- /package/dist/core/{secret-detector.d.ts → security/secret-detector.d.ts} +0 -0
- /package/dist/core/{secret-detector.js → security/secret-detector.js} +0 -0
- /package/dist/core/{cache.d.ts → storage/cache.d.ts} +0 -0
- /package/dist/core/{database.d.ts → storage/database.d.ts} +0 -0
- /package/dist/core/{database.js → storage/database.js} +0 -0
|
@@ -3,28 +3,62 @@
|
|
|
3
3
|
* Each type has different merge semantics to preserve meaning and prevent data loss.
|
|
4
4
|
*/
|
|
5
5
|
/**
|
|
6
|
-
*
|
|
7
|
-
*
|
|
6
|
+
* Base implementation of MergeStrategy with common functionality.
|
|
7
|
+
* Reduces code duplication across specific merge strategies.
|
|
8
8
|
*/
|
|
9
|
-
class
|
|
10
|
-
type = 'fact';
|
|
9
|
+
export class BaseMergeStrategy {
|
|
11
10
|
canMerge(sources) {
|
|
12
|
-
// Facts can almost always be merged
|
|
13
11
|
if (sources.length < 2) {
|
|
14
12
|
return { ok: false, reason: 'Need at least 2 memories to merge' };
|
|
15
13
|
}
|
|
16
14
|
return { ok: true };
|
|
17
15
|
}
|
|
16
|
+
validateSources(sources) {
|
|
17
|
+
return sources.length >= 2;
|
|
18
|
+
}
|
|
19
|
+
handleEmptySources() {
|
|
20
|
+
return {
|
|
21
|
+
content: '',
|
|
22
|
+
summary: null,
|
|
23
|
+
tags: [],
|
|
24
|
+
metadata: {},
|
|
25
|
+
mergeReason: 'Empty source set',
|
|
26
|
+
conflictWarnings: [],
|
|
27
|
+
};
|
|
28
|
+
}
|
|
29
|
+
mergeTags(sources) {
|
|
30
|
+
const tagSet = new Set();
|
|
31
|
+
for (const source of sources) {
|
|
32
|
+
for (const tag of source.tags || []) {
|
|
33
|
+
tagSet.add(tag);
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
return Array.from(tagSet);
|
|
37
|
+
}
|
|
38
|
+
buildBaseMetadata(sources, extra) {
|
|
39
|
+
return {
|
|
40
|
+
mergedFrom: sources.map((m) => m.id),
|
|
41
|
+
mergeCount: sources.length,
|
|
42
|
+
...extra,
|
|
43
|
+
};
|
|
44
|
+
}
|
|
45
|
+
sortByDate(sources, order = 'desc') {
|
|
46
|
+
const sorted = [...sources].sort((a, b) => new Date(b.createdAt).getTime() - new Date(a.createdAt).getTime());
|
|
47
|
+
return order === 'asc' ? [...sorted].reverse() : sorted;
|
|
48
|
+
}
|
|
49
|
+
sortChronologically(sources) {
|
|
50
|
+
return [...sources].sort((a, b) => new Date(a.createdAt).getTime() - new Date(b.createdAt).getTime());
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
/**
|
|
54
|
+
* FACT strategy: Union of information, remove exact duplicates.
|
|
55
|
+
* Combines all unique facts into a unified statement with provenance tracking.
|
|
56
|
+
*/
|
|
57
|
+
class FactMergeStrategy extends BaseMergeStrategy {
|
|
58
|
+
type = 'fact';
|
|
18
59
|
merge(sources) {
|
|
19
60
|
if (sources.length === 0) {
|
|
20
|
-
return
|
|
21
|
-
content: '',
|
|
22
|
-
summary: null,
|
|
23
|
-
tags: [],
|
|
24
|
-
metadata: {},
|
|
25
|
-
mergeReason: 'Empty source set',
|
|
26
|
-
conflictWarnings: [],
|
|
27
|
-
};
|
|
61
|
+
return this.handleEmptySources();
|
|
28
62
|
}
|
|
29
63
|
// Split content into sentences and deduplicate
|
|
30
64
|
const sentenceSet = new Set();
|
|
@@ -45,27 +79,14 @@ class FactMergeStrategy {
|
|
|
45
79
|
// Sort sentences for consistency
|
|
46
80
|
const mergedSentences = Array.from(sentenceSet).sort();
|
|
47
81
|
const content = mergedSentences.join('. ') + (mergedSentences.length > 0 ? '.' : '');
|
|
48
|
-
//
|
|
49
|
-
const
|
|
50
|
-
for (const source of sources) {
|
|
51
|
-
for (const tag of source.tags || []) {
|
|
52
|
-
tagSet.add(tag);
|
|
53
|
-
}
|
|
54
|
-
}
|
|
55
|
-
// Create merged metadata with provenance
|
|
56
|
-
const metadata = {
|
|
57
|
-
mergedFrom: sources.map((m) => ({
|
|
58
|
-
id: m.id,
|
|
59
|
-
createdAt: m.createdAt,
|
|
60
|
-
source: m.source,
|
|
61
|
-
})),
|
|
62
|
-
mergeCount: sources.length,
|
|
82
|
+
// Build merged metadata with provenance
|
|
83
|
+
const metadata = this.buildBaseMetadata(sources, {
|
|
63
84
|
timestamps: timestamps.sort(),
|
|
64
|
-
};
|
|
85
|
+
});
|
|
65
86
|
return {
|
|
66
87
|
content,
|
|
67
88
|
summary: null,
|
|
68
|
-
tags:
|
|
89
|
+
tags: this.mergeTags(sources),
|
|
69
90
|
metadata,
|
|
70
91
|
mergeReason: `Merged ${sources.length} facts by combining all unique statements`,
|
|
71
92
|
conflictWarnings: [],
|
|
@@ -76,27 +97,14 @@ class FactMergeStrategy {
|
|
|
76
97
|
* PREFERENCE strategy: Keep latest by timestamp, track evolution history.
|
|
77
98
|
* Warns if preferences conflict, indicating user changed their mind.
|
|
78
99
|
*/
|
|
79
|
-
class PreferenceMergeStrategy {
|
|
100
|
+
class PreferenceMergeStrategy extends BaseMergeStrategy {
|
|
80
101
|
type = 'preference';
|
|
81
|
-
canMerge(sources) {
|
|
82
|
-
if (sources.length < 2) {
|
|
83
|
-
return { ok: false, reason: 'Need at least 2 memories to merge' };
|
|
84
|
-
}
|
|
85
|
-
return { ok: true };
|
|
86
|
-
}
|
|
87
102
|
merge(sources) {
|
|
88
103
|
if (sources.length === 0) {
|
|
89
|
-
return
|
|
90
|
-
content: '',
|
|
91
|
-
summary: null,
|
|
92
|
-
tags: [],
|
|
93
|
-
metadata: {},
|
|
94
|
-
mergeReason: 'Empty source set',
|
|
95
|
-
conflictWarnings: [],
|
|
96
|
-
};
|
|
104
|
+
return this.handleEmptySources();
|
|
97
105
|
}
|
|
98
106
|
// Sort by creation date (newest first)
|
|
99
|
-
const sorted =
|
|
107
|
+
const sorted = this.sortByDate(sources);
|
|
100
108
|
const latest = sorted[0];
|
|
101
109
|
const warnings = [];
|
|
102
110
|
// Check for conflicting preferences
|
|
@@ -112,12 +120,10 @@ class PreferenceMergeStrategy {
|
|
|
112
120
|
confidence: m.confidence || 100,
|
|
113
121
|
source: m.source,
|
|
114
122
|
}));
|
|
115
|
-
const metadata = {
|
|
116
|
-
mergedFrom: sources.map((m) => m.id),
|
|
123
|
+
const metadata = this.buildBaseMetadata(sources, {
|
|
117
124
|
preferenceHistory: history,
|
|
118
|
-
mergeCount: sources.length,
|
|
119
125
|
latestAt: latest.createdAt,
|
|
120
|
-
};
|
|
126
|
+
});
|
|
121
127
|
const summary = sources.length > 1
|
|
122
128
|
? `Prefers: ${latest.content} (evolved from ${sources.length} preferences)`
|
|
123
129
|
: null;
|
|
@@ -135,27 +141,14 @@ class PreferenceMergeStrategy {
|
|
|
135
141
|
* DECISION strategy: Keep latest decision, link to previous ones in timeline.
|
|
136
142
|
* Warns if decisions contradict, preserving rationale history.
|
|
137
143
|
*/
|
|
138
|
-
class DecisionMergeStrategy {
|
|
144
|
+
class DecisionMergeStrategy extends BaseMergeStrategy {
|
|
139
145
|
type = 'decision';
|
|
140
|
-
canMerge(sources) {
|
|
141
|
-
if (sources.length < 2) {
|
|
142
|
-
return { ok: false, reason: 'Need at least 2 memories to merge' };
|
|
143
|
-
}
|
|
144
|
-
return { ok: true };
|
|
145
|
-
}
|
|
146
146
|
merge(sources) {
|
|
147
147
|
if (sources.length === 0) {
|
|
148
|
-
return
|
|
149
|
-
content: '',
|
|
150
|
-
summary: null,
|
|
151
|
-
tags: [],
|
|
152
|
-
metadata: {},
|
|
153
|
-
mergeReason: 'Empty source set',
|
|
154
|
-
conflictWarnings: [],
|
|
155
|
-
};
|
|
148
|
+
return this.handleEmptySources();
|
|
156
149
|
}
|
|
157
150
|
// Sort by creation date (newest first)
|
|
158
|
-
const sorted =
|
|
151
|
+
const sorted = this.sortByDate(sources);
|
|
159
152
|
const latest = sorted[0];
|
|
160
153
|
const warnings = [];
|
|
161
154
|
// Check for conflicting decisions
|
|
@@ -170,13 +163,11 @@ class DecisionMergeStrategy {
|
|
|
170
163
|
confidence: m.confidence || 100,
|
|
171
164
|
rationale: m.summary || 'No rationale recorded',
|
|
172
165
|
}));
|
|
173
|
-
const metadata = {
|
|
174
|
-
mergedFrom: sources.map((m) => m.id),
|
|
166
|
+
const metadata = this.buildBaseMetadata(sources, {
|
|
175
167
|
decisionTimeline: timeline,
|
|
176
|
-
mergeCount: sources.length,
|
|
177
168
|
currentDecisionAt: latest.createdAt,
|
|
178
169
|
supersedes: sorted.slice(1).map((m) => m.id),
|
|
179
|
-
};
|
|
170
|
+
});
|
|
180
171
|
const summary = sources.length > 1 ? `Decided: ${latest.content} (${sources.length} decisions)` : null;
|
|
181
172
|
return {
|
|
182
173
|
content: latest.content,
|
|
@@ -192,31 +183,17 @@ class DecisionMergeStrategy {
|
|
|
192
183
|
* OBSERVATION strategy: Aggregate observations in chronological order.
|
|
193
184
|
* Preserves temporal patterns and frequency information.
|
|
194
185
|
*/
|
|
195
|
-
class ObservationMergeStrategy {
|
|
186
|
+
class ObservationMergeStrategy extends BaseMergeStrategy {
|
|
196
187
|
type = 'observation';
|
|
197
|
-
canMerge(sources) {
|
|
198
|
-
if (sources.length < 2) {
|
|
199
|
-
return { ok: false, reason: 'Need at least 2 memories to merge' };
|
|
200
|
-
}
|
|
201
|
-
return { ok: true };
|
|
202
|
-
}
|
|
203
188
|
merge(sources) {
|
|
204
189
|
if (sources.length === 0) {
|
|
205
|
-
return
|
|
206
|
-
content: '',
|
|
207
|
-
summary: null,
|
|
208
|
-
tags: [],
|
|
209
|
-
metadata: {},
|
|
210
|
-
mergeReason: 'Empty source set',
|
|
211
|
-
conflictWarnings: [],
|
|
212
|
-
};
|
|
190
|
+
return this.handleEmptySources();
|
|
213
191
|
}
|
|
214
192
|
// Sort chronologically
|
|
215
|
-
const sorted =
|
|
193
|
+
const sorted = this.sortChronologically(sources);
|
|
216
194
|
// Create observation summary
|
|
217
195
|
const observations = sorted.map((m) => `• ${m.content}`).join('\n');
|
|
218
|
-
const metadata = {
|
|
219
|
-
mergedFrom: sources.map((m) => m.id),
|
|
196
|
+
const metadata = this.buildBaseMetadata(sources, {
|
|
220
197
|
observationCount: sources.length,
|
|
221
198
|
timeSpan: {
|
|
222
199
|
start: sorted[0].createdAt,
|
|
@@ -227,18 +204,11 @@ class ObservationMergeStrategy {
|
|
|
227
204
|
content: m.content,
|
|
228
205
|
createdAt: m.createdAt,
|
|
229
206
|
})),
|
|
230
|
-
};
|
|
231
|
-
// Merge tags
|
|
232
|
-
const tagSet = new Set();
|
|
233
|
-
for (const source of sources) {
|
|
234
|
-
for (const tag of source.tags || []) {
|
|
235
|
-
tagSet.add(tag);
|
|
236
|
-
}
|
|
237
|
-
}
|
|
207
|
+
});
|
|
238
208
|
return {
|
|
239
209
|
content: `Observations (${sources.length} total):\n${observations}`,
|
|
240
210
|
summary: `${sources.length} observations over time period`,
|
|
241
|
-
tags:
|
|
211
|
+
tags: this.mergeTags(sources),
|
|
242
212
|
metadata,
|
|
243
213
|
mergeReason: `Merged ${sources.length} observations chronologically`,
|
|
244
214
|
conflictWarnings: [],
|
|
@@ -249,24 +219,11 @@ class ObservationMergeStrategy {
|
|
|
249
219
|
* CONTEXT strategy: Union of unique context, remove exact duplicates.
|
|
250
220
|
* Preserves all distinct context items.
|
|
251
221
|
*/
|
|
252
|
-
class ContextMergeStrategy {
|
|
222
|
+
class ContextMergeStrategy extends BaseMergeStrategy {
|
|
253
223
|
type = 'context';
|
|
254
|
-
canMerge(sources) {
|
|
255
|
-
if (sources.length < 2) {
|
|
256
|
-
return { ok: false, reason: 'Need at least 2 memories to merge' };
|
|
257
|
-
}
|
|
258
|
-
return { ok: true };
|
|
259
|
-
}
|
|
260
224
|
merge(sources) {
|
|
261
225
|
if (sources.length === 0) {
|
|
262
|
-
return
|
|
263
|
-
content: '',
|
|
264
|
-
summary: null,
|
|
265
|
-
tags: [],
|
|
266
|
-
metadata: {},
|
|
267
|
-
mergeReason: 'Empty source set',
|
|
268
|
-
conflictWarnings: [],
|
|
269
|
-
};
|
|
226
|
+
return this.handleEmptySources();
|
|
270
227
|
}
|
|
271
228
|
// Deduplicate by content (exact matches)
|
|
272
229
|
const uniqueContexts = new Map();
|
|
@@ -280,23 +237,15 @@ class ContextMergeStrategy {
|
|
|
280
237
|
.sort()
|
|
281
238
|
.map((content) => `• ${content}`)
|
|
282
239
|
.join('\n');
|
|
283
|
-
const metadata = {
|
|
284
|
-
mergedFrom: sources.map((m) => m.id),
|
|
240
|
+
const metadata = this.buildBaseMetadata(sources, {
|
|
285
241
|
uniqueContextCount: uniqueContexts.size,
|
|
286
242
|
totalContextCount: sources.length,
|
|
287
243
|
deduplicatedEntries: sources.length - uniqueContexts.size,
|
|
288
|
-
};
|
|
289
|
-
// Merge tags
|
|
290
|
-
const tagSet = new Set();
|
|
291
|
-
for (const source of sources) {
|
|
292
|
-
for (const tag of source.tags || []) {
|
|
293
|
-
tagSet.add(tag);
|
|
294
|
-
}
|
|
295
|
-
}
|
|
244
|
+
});
|
|
296
245
|
return {
|
|
297
246
|
content: contextList,
|
|
298
247
|
summary: `${uniqueContexts.size} context items (${sources.length} total)`,
|
|
299
|
-
tags:
|
|
248
|
+
tags: this.mergeTags(sources),
|
|
300
249
|
metadata,
|
|
301
250
|
mergeReason: `Merged ${sources.length} context records into ${uniqueContexts.size} unique items`,
|
|
302
251
|
conflictWarnings: [],
|
|
@@ -309,6 +258,8 @@ export const MERGE_STRATEGIES = {
|
|
|
309
258
|
decision: new DecisionMergeStrategy(),
|
|
310
259
|
observation: new ObservationMergeStrategy(),
|
|
311
260
|
context: new ContextMergeStrategy(),
|
|
261
|
+
reflection: new ObservationMergeStrategy(),
|
|
262
|
+
note: new ObservationMergeStrategy(), // jot uses observation strategy
|
|
312
263
|
};
|
|
313
264
|
export function getMergeStrategy(type) {
|
|
314
265
|
const strategy = MERGE_STRATEGIES[type];
|
|
@@ -0,0 +1,133 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* TypeScript types and interfaces for memory merging
|
|
3
|
+
*/
|
|
4
|
+
import type { Memory, MemoryMergeProposal } from '../../db/drizzle/schema.js';
|
|
5
|
+
/**
|
|
6
|
+
* Merge proposal status
|
|
7
|
+
*/
|
|
8
|
+
export type MergeProposalStatus = 'pending' | 'approved' | 'rejected' | 'expired';
|
|
9
|
+
/**
|
|
10
|
+
* Confidence level for merge suggestions
|
|
11
|
+
*/
|
|
12
|
+
export type ConfidenceLevel = 'high' | 'medium' | 'low';
|
|
13
|
+
/**
|
|
14
|
+
* Detection method used to find duplicates
|
|
15
|
+
*/
|
|
16
|
+
export type DetectionMethod = 'simhash' | 'minhash' | 'embedding';
|
|
17
|
+
/**
|
|
18
|
+
* Merge strategy type per memory type
|
|
19
|
+
*/
|
|
20
|
+
export type MergeStrategyType = 'union' | 'latest' | 'voting' | 'custom';
|
|
21
|
+
/**
|
|
22
|
+
* Memory pair candidate for merging
|
|
23
|
+
*/
|
|
24
|
+
export interface MemoryMergePair {
|
|
25
|
+
memory1: Memory;
|
|
26
|
+
memory2: Memory;
|
|
27
|
+
similarityScore: number;
|
|
28
|
+
detectionMethod: DetectionMethod;
|
|
29
|
+
confidenceLevel: ConfidenceLevel;
|
|
30
|
+
mergeReason: string;
|
|
31
|
+
}
|
|
32
|
+
/**
|
|
33
|
+
* Merge proposal with all details
|
|
34
|
+
*/
|
|
35
|
+
export interface MergeProposalDetails {
|
|
36
|
+
proposal: MemoryMergeProposal;
|
|
37
|
+
sourceMemories: Memory[];
|
|
38
|
+
previewMerged: {
|
|
39
|
+
content: string;
|
|
40
|
+
summary: string | null;
|
|
41
|
+
tags: string[];
|
|
42
|
+
metadata: Record<string, unknown>;
|
|
43
|
+
};
|
|
44
|
+
analysis: {
|
|
45
|
+
savedTokens: number;
|
|
46
|
+
savedPercentage: number;
|
|
47
|
+
conflictWarnings: string[];
|
|
48
|
+
};
|
|
49
|
+
}
|
|
50
|
+
/**
|
|
51
|
+
* Merge result after approval
|
|
52
|
+
*/
|
|
53
|
+
export interface MergeResult {
|
|
54
|
+
proposalId: string;
|
|
55
|
+
canonicalMemoryId: string;
|
|
56
|
+
mergedMemoryIds: string[];
|
|
57
|
+
tokensSaved: number;
|
|
58
|
+
mergedAt: Date;
|
|
59
|
+
mergeHistoryId?: string;
|
|
60
|
+
}
|
|
61
|
+
/**
|
|
62
|
+
* Merge reversal result
|
|
63
|
+
*/
|
|
64
|
+
export interface MergeReversal {
|
|
65
|
+
mergeHistoryId: string;
|
|
66
|
+
canonicalMemoryId: string;
|
|
67
|
+
restoredMemoryIds: string[];
|
|
68
|
+
reversedAt: Date;
|
|
69
|
+
}
|
|
70
|
+
/**
|
|
71
|
+
* Detection statistics
|
|
72
|
+
*/
|
|
73
|
+
export interface DetectionStatistics {
|
|
74
|
+
totalMemories: number;
|
|
75
|
+
scannedMemories: number;
|
|
76
|
+
candidatesFound: number;
|
|
77
|
+
candidatesRanked: number;
|
|
78
|
+
estimatedTokensSaved: number;
|
|
79
|
+
timeMs: {
|
|
80
|
+
stage1: number;
|
|
81
|
+
stage2: number;
|
|
82
|
+
total: number;
|
|
83
|
+
};
|
|
84
|
+
}
|
|
85
|
+
/**
|
|
86
|
+
* Project merge statistics
|
|
87
|
+
*/
|
|
88
|
+
export interface ProjectMergeStatistics {
|
|
89
|
+
projectId: string;
|
|
90
|
+
totalMemories: number;
|
|
91
|
+
mergeableMemories: number;
|
|
92
|
+
mergedMemories: number;
|
|
93
|
+
canonicalMemories: number;
|
|
94
|
+
pendingProposals: number;
|
|
95
|
+
approvedMerges: number;
|
|
96
|
+
rejectedProposals: number;
|
|
97
|
+
reversedMerges: number;
|
|
98
|
+
tokensSaved: {
|
|
99
|
+
total: number;
|
|
100
|
+
formatted: string;
|
|
101
|
+
percentage: number;
|
|
102
|
+
};
|
|
103
|
+
averageMergeSize: number;
|
|
104
|
+
}
|
|
105
|
+
/**
|
|
106
|
+
* Merge safety check result
|
|
107
|
+
*/
|
|
108
|
+
export interface SafetyCheckResult {
|
|
109
|
+
passed: boolean;
|
|
110
|
+
warnings: string[];
|
|
111
|
+
blockers: string[];
|
|
112
|
+
}
|
|
113
|
+
/**
|
|
114
|
+
* Hash cache entry for fast duplicate detection
|
|
115
|
+
*/
|
|
116
|
+
export interface HashCacheEntry {
|
|
117
|
+
memoryId: string;
|
|
118
|
+
simhash: string;
|
|
119
|
+
minhash: number[];
|
|
120
|
+
contentHash: string;
|
|
121
|
+
lastUpdated: Date;
|
|
122
|
+
}
|
|
123
|
+
/**
|
|
124
|
+
* Stage 1 candidate pair with hash distances
|
|
125
|
+
*/
|
|
126
|
+
export interface Stage1CandidatePair {
|
|
127
|
+
memoryId1: string;
|
|
128
|
+
memoryId2: string;
|
|
129
|
+
simhashDistance: number;
|
|
130
|
+
minhashSimilarity: number;
|
|
131
|
+
matched: 'simhash' | 'minhash' | 'both';
|
|
132
|
+
}
|
|
133
|
+
//# sourceMappingURL=types.d.ts.map
|
|
@@ -8,8 +8,7 @@ export type AssociationType = 'co_occurred' | 'supersedes' | 'contradicts' | 'su
|
|
|
8
8
|
*/
|
|
9
9
|
export declare function createAssociation(fromMemoryId: string, toMemoryId: string, type: AssociationType, weight?: number): Promise<void>;
|
|
10
10
|
/**
|
|
11
|
-
* Track co-activation of multiple memories (
|
|
12
|
-
* OPTIMIZED: Uses bulk upsert instead of N² individual database operations
|
|
11
|
+
* Track co-activation of multiple memories (used together)
|
|
13
12
|
*/
|
|
14
13
|
export declare function trackCoactivation(memoryIds: string[]): Promise<void>;
|
|
15
14
|
/**
|
|
@@ -47,8 +47,7 @@ export async function createAssociation(fromMemoryId, toMemoryId, type, weight =
|
|
|
47
47
|
}
|
|
48
48
|
}
|
|
49
49
|
/**
|
|
50
|
-
* Track co-activation of multiple memories (
|
|
51
|
-
* OPTIMIZED: Uses bulk upsert instead of N² individual database operations
|
|
50
|
+
* Track co-activation of multiple memories (used together)
|
|
52
51
|
*/
|
|
53
52
|
export async function trackCoactivation(memoryIds) {
|
|
54
53
|
if (memoryIds.length < 2)
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
export declare function getDefaultAutosaveHook(): {
|
|
2
|
+
getMessageCount: () => number;
|
|
3
|
+
updateConfig: (opts?: {
|
|
4
|
+
enabled?: boolean;
|
|
5
|
+
messageCount?: number;
|
|
6
|
+
hooks?: string[];
|
|
7
|
+
}) => void;
|
|
8
|
+
getConfig: () => {
|
|
9
|
+
enabled: boolean;
|
|
10
|
+
messageCount: number;
|
|
11
|
+
hooks: string[];
|
|
12
|
+
};
|
|
13
|
+
};
|
|
14
|
+
export declare function createAutosaveConfig(): {
|
|
15
|
+
enabled: boolean;
|
|
16
|
+
messageCount: number;
|
|
17
|
+
hooks: string[];
|
|
18
|
+
};
|
|
19
|
+
//# sourceMappingURL=autosave.d.ts.map
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
// Autosave functionality placeholder
|
|
2
|
+
export function getDefaultAutosaveHook() {
|
|
3
|
+
let config = { enabled: false, messageCount: 10, hooks: [] };
|
|
4
|
+
return {
|
|
5
|
+
getMessageCount: () => 0,
|
|
6
|
+
updateConfig: (opts) => {
|
|
7
|
+
if (opts)
|
|
8
|
+
Object.assign(config, opts);
|
|
9
|
+
},
|
|
10
|
+
getConfig: () => ({ ...config })
|
|
11
|
+
};
|
|
12
|
+
}
|
|
13
|
+
export function createAutosaveConfig() {
|
|
14
|
+
return { enabled: false, messageCount: 10, hooks: [] };
|
|
15
|
+
}
|
|
16
|
+
//# sourceMappingURL=autosave.js.map
|
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import { MCPClient } from '
|
|
2
|
-
import { config } from '
|
|
3
|
-
import { logger } from '
|
|
4
|
-
import {
|
|
1
|
+
import { MCPClient } from '../../core/mcp/client.js';
|
|
2
|
+
import { config } from '../../config.js';
|
|
3
|
+
import { logger } from '../../core/logger.js';
|
|
4
|
+
import { search, rememberMemory } from '../../core/memory/memories.js';
|
|
5
5
|
export class ManagedSync {
|
|
6
6
|
client;
|
|
7
7
|
syncEnabled;
|
|
@@ -26,7 +26,7 @@ export class ManagedSync {
|
|
|
26
26
|
if (!this.syncEnabled)
|
|
27
27
|
return;
|
|
28
28
|
try {
|
|
29
|
-
const memory = await
|
|
29
|
+
const memory = await search({ query: memoryId, limit: 1 });
|
|
30
30
|
if (memory.length > 0) {
|
|
31
31
|
await this.client.callTool('managed_memory_store', {
|
|
32
32
|
memory: memory[0],
|