@seanhogg/builderforce-memory-mcp 2026.10.3 → 2026.10.22

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.
Files changed (72) hide show
  1. package/README.md +22 -5
  2. package/dist/backend.d.ts +26 -0
  3. package/dist/backend.d.ts.map +1 -1
  4. package/dist/backends/memory-store.d.ts +50 -2
  5. package/dist/backends/memory-store.d.ts.map +1 -1
  6. package/dist/backends/memory-store.js +88 -10
  7. package/dist/backends/memory-store.js.map +1 -1
  8. package/dist/bin/http.js +7 -1
  9. package/dist/bin/http.js.map +1 -1
  10. package/dist/bin/install.js +6 -3
  11. package/dist/bin/install.js.map +1 -1
  12. package/dist/bin/stdio.d.ts +9 -4
  13. package/dist/bin/stdio.d.ts.map +1 -1
  14. package/dist/bin/stdio.js +20 -5
  15. package/dist/bin/stdio.js.map +1 -1
  16. package/dist/compaction-tools.d.ts +15 -0
  17. package/dist/compaction-tools.d.ts.map +1 -0
  18. package/dist/compaction-tools.js +192 -0
  19. package/dist/compaction-tools.js.map +1 -0
  20. package/dist/compaction.d.ts +114 -8
  21. package/dist/compaction.d.ts.map +1 -1
  22. package/dist/compaction.js +161 -7
  23. package/dist/compaction.js.map +1 -1
  24. package/dist/index.d.ts +13 -6
  25. package/dist/index.d.ts.map +1 -1
  26. package/dist/index.js +11 -7
  27. package/dist/index.js.map +1 -1
  28. package/dist/install/claude-hooks.d.ts +5 -0
  29. package/dist/install/claude-hooks.d.ts.map +1 -1
  30. package/dist/install/claude-hooks.js +69 -9
  31. package/dist/install/claude-hooks.js.map +1 -1
  32. package/dist/install/server-spec.d.ts +33 -7
  33. package/dist/install/server-spec.d.ts.map +1 -1
  34. package/dist/install/server-spec.js +59 -9
  35. package/dist/install/server-spec.js.map +1 -1
  36. package/dist/model/recall-probe.d.ts +29 -0
  37. package/dist/model/recall-probe.d.ts.map +1 -0
  38. package/dist/model/recall-probe.js +72 -0
  39. package/dist/model/recall-probe.js.map +1 -0
  40. package/dist/persistence/fact-archive.d.ts +47 -0
  41. package/dist/persistence/fact-archive.d.ts.map +1 -0
  42. package/dist/persistence/fact-archive.js +85 -0
  43. package/dist/persistence/fact-archive.js.map +1 -0
  44. package/dist/persistence/shared-json-file.d.ts +24 -1
  45. package/dist/persistence/shared-json-file.d.ts.map +1 -1
  46. package/dist/persistence/shared-json-file.js +46 -1
  47. package/dist/persistence/shared-json-file.js.map +1 -1
  48. package/dist/restore.d.ts +56 -0
  49. package/dist/restore.d.ts.map +1 -0
  50. package/dist/restore.js +118 -0
  51. package/dist/restore.js.map +1 -0
  52. package/dist/tools.d.ts +13 -0
  53. package/dist/tools.d.ts.map +1 -1
  54. package/dist/tools.js +11 -90
  55. package/dist/tools.js.map +1 -1
  56. package/package.json +6 -6
  57. package/server.json +2 -2
  58. package/src/backend.ts +29 -0
  59. package/src/backends/memory-store.ts +141 -11
  60. package/src/bin/http.ts +7 -1
  61. package/src/bin/install.ts +7 -3
  62. package/src/bin/stdio.ts +20 -5
  63. package/src/compaction-tools.ts +206 -0
  64. package/src/compaction.ts +228 -9
  65. package/src/index.ts +55 -10
  66. package/src/install/claude-hooks.ts +72 -9
  67. package/src/install/server-spec.ts +74 -8
  68. package/src/model/recall-probe.ts +81 -0
  69. package/src/persistence/fact-archive.ts +101 -0
  70. package/src/persistence/shared-json-file.ts +54 -1
  71. package/src/restore.ts +144 -0
  72. package/src/tools.ts +24 -93
package/dist/index.d.ts CHANGED
@@ -9,16 +9,23 @@
9
9
  export type { MemoryBackend, RankedRecall, RecallHit, RecallMethod, RememberInput } from "./backend.js";
10
10
  export { createRecallEmbedder, createEvermindEmbedder, CachedTextEmbedder, defaultVectorCacheFile, MODEL_FILE_ENV, TOKENIZER_FILE_ENV, VECTOR_CACHE_ENV } from "./embedding/index.js";
11
11
  export type { EvermindEmbedderOptions, PersistentTextEmbedder, TextEmbedderLike, RecallEmbedderEnv } from "./embedding/index.js";
12
- export { MemoryStoreBackend, createLocalMemoryStoreBackend } from "./backends/memory-store.js";
13
- export type { LocalBackendOptions } from "./backends/memory-store.js";
12
+ export { MemoryStoreBackend, createLocalMemoryStoreBackend, DEFAULT_RECALL_RANKING } from "./backends/memory-store.js";
13
+ export type { LocalBackendOptions, MemoryStoreBackendOptions, RecallRanking } from "./backends/memory-store.js";
14
+ export { FileFactArchive, MemoryFactArchive } from "./persistence/fact-archive.js";
15
+ export type { FactArchive } from "./persistence/fact-archive.js";
16
+ export { SharedJsonFile, DEFAULT_BACKUPS, backupFile } from "./persistence/shared-json-file.js";
17
+ export type { SharedJsonFileOptions } from "./persistence/shared-json-file.js";
14
18
  export { buildMemoryTools } from "./tools.js";
15
19
  export type { MemoryToolsOptions } from "./tools.js";
16
20
  export type { MemoryTool, ToolResult } from "./tool-core.js";
17
21
  export { createExperienceHost, EXPERIENCE_ENV } from "./experience/host.js";
18
22
  export type { ExperienceHost, ExperienceHostOptions, ExperienceEngine } from "./experience/host.js";
19
23
  export { nextExperienceVersion } from "./experience/train.js";
20
- export { STUB_PREFIX, DEFAULT_STUB_CHARS, isStub, firstLine, memoryStub, planCompaction } from "./compaction.js";
21
- export type { CompactionCandidate, CompactionWrite, CompactionSkip, CompactionPlan, CompactionOptions } from "./compaction.js";
24
+ export { STUB_PREFIX, DEFAULT_STUB_CHARS, CONTENT_LOST_LABEL, isStub, isContentLost, firstLine, memoryStub, stubPointer, planCompaction, planLosslessCompaction, probeQuestionFor, probePasses, defaultArchiveFile, parseArchive, mergeArchive, } from "./compaction.js";
25
+ export type { ArchivedFact, ArchiveSnapshot, CompactionCandidate, CompactionWrite, CompactionSkip, CompactionPlan, CompactionOptions, LosslessCompactionOptions, ProbeQuestion, RecallProbe, } from "./compaction.js";
26
+ export { createRecallProbe, lazyRecallProbe, generatorProbe, PROBE_MAX_NEW_TOKENS } from "./model/recall-probe.js";
27
+ export { parseRestoreSource, planRestore, restoredArchive, stubVersion, MIN_POINTER_CHARS } from "./restore.js";
28
+ export type { RestoreRecord, RestoreTarget, RestoreMatch, RestorePlan } from "./restore.js";
22
29
  export { createMemoryMcpServer } from "./transports/sdk.js";
23
30
  export type { SdkServerOptions, SdkMcpServerConfig } from "./transports/sdk.js";
24
31
  export { buildMcpServer } from "./transports/mcp-server.js";
@@ -27,8 +34,8 @@ export { runStdio } from "./transports/stdio.js";
27
34
  export { createMemoryHttpHandler } from "./transports/http.js";
28
35
  export type { HttpHandlerOptions } from "./transports/http.js";
29
36
  export { hashToken, timingSafeEqualStr, buildTenantIndex, bearerToken, RateLimiter } from "./transports/auth.js";
30
- export { buildServerSpec, defaultMemoryFile, resolveMemoryFile, MCP_PACKAGE, MCP_BIN, MEMORY_FILE_ENV, RUNTIME_PEERS } from "./install/server-spec.js";
31
- export type { StdioServerSpec, ServerSpecOptions } from "./install/server-spec.js";
37
+ export { buildServerSpec, defaultMemoryFile, memoryFileCandidates, resolveMemoryFile, CANONICAL_MEMORY_SEGMENTS, LEGACY_MEMORY_SEGMENTS, MCP_PACKAGE, MCP_BIN, MEMORY_FILE_ENV, RUNTIME_PEERS, } from "./install/server-spec.js";
38
+ export type { StdioServerSpec, ServerSpecOptions, MemoryFileProbe, ResolveMemoryFileOptions } from "./install/server-spec.js";
32
39
  export { installMemoryServer } from "./install/install.js";
33
40
  export type { InstallOptions, InstallResult, InstallStatus, HostSelector, FsLike } from "./install/install.js";
34
41
  export { HOSTS, SERVER_KEY, findHost } from "./install/hosts.js";
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAGH,YAAY,EAAE,aAAa,EAAE,YAAY,EAAE,SAAS,EAAE,YAAY,EAAE,aAAa,EAAE,MAAM,cAAc,CAAC;AAMxG,OAAO,EAAE,oBAAoB,EAAE,sBAAsB,EAAE,kBAAkB,EAAE,sBAAsB,EAAE,cAAc,EAAE,kBAAkB,EAAE,gBAAgB,EAAE,MAAM,sBAAsB,CAAC;AACtL,YAAY,EAAE,uBAAuB,EAAE,sBAAsB,EAAE,gBAAgB,EAAE,iBAAiB,EAAE,MAAM,sBAAsB,CAAC;AAGjI,OAAO,EAAE,kBAAkB,EAAE,6BAA6B,EAAE,MAAM,4BAA4B,CAAC;AAC/F,YAAY,EAAE,mBAAmB,EAAE,MAAM,4BAA4B,CAAC;AAGtE,OAAO,EAAE,gBAAgB,EAAE,MAAM,YAAY,CAAC;AAC9C,YAAY,EAAE,kBAAkB,EAAE,MAAM,YAAY,CAAC;AACrD,YAAY,EAAE,UAAU,EAAE,UAAU,EAAE,MAAM,gBAAgB,CAAC;AAI7D,OAAO,EAAE,oBAAoB,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC;AAC5E,YAAY,EAAE,cAAc,EAAE,qBAAqB,EAAE,gBAAgB,EAAE,MAAM,sBAAsB,CAAC;AACpG,OAAO,EAAE,qBAAqB,EAAE,MAAM,uBAAuB,CAAC;AAM9D,OAAO,EAAE,WAAW,EAAE,kBAAkB,EAAE,MAAM,EAAE,SAAS,EAAE,UAAU,EAAE,cAAc,EAAE,MAAM,iBAAiB,CAAC;AACjH,YAAY,EAAE,mBAAmB,EAAE,eAAe,EAAE,cAAc,EAAE,cAAc,EAAE,iBAAiB,EAAE,MAAM,iBAAiB,CAAC;AAG/H,OAAO,EAAE,qBAAqB,EAAE,MAAM,qBAAqB,CAAC;AAC5D,YAAY,EAAE,gBAAgB,EAAE,kBAAkB,EAAE,MAAM,qBAAqB,CAAC;AAEhF,OAAO,EAAE,cAAc,EAAE,MAAM,4BAA4B,CAAC;AAC5D,YAAY,EAAE,gBAAgB,EAAE,MAAM,4BAA4B,CAAC;AAEnE,OAAO,EAAE,QAAQ,EAAE,MAAM,uBAAuB,CAAC;AAEjD,OAAO,EAAE,uBAAuB,EAAE,MAAM,sBAAsB,CAAC;AAC/D,YAAY,EAAE,kBAAkB,EAAE,MAAM,sBAAsB,CAAC;AAC/D,OAAO,EAAE,SAAS,EAAE,kBAAkB,EAAE,gBAAgB,EAAE,WAAW,EAAE,WAAW,EAAE,MAAM,sBAAsB,CAAC;AAGjH,OAAO,EAAE,eAAe,EAAE,iBAAiB,EAAE,iBAAiB,EAAE,WAAW,EAAE,OAAO,EAAE,eAAe,EAAE,aAAa,EAAE,MAAM,0BAA0B,CAAC;AACvJ,YAAY,EAAE,eAAe,EAAE,iBAAiB,EAAE,MAAM,0BAA0B,CAAC;AACnF,OAAO,EAAE,mBAAmB,EAAE,MAAM,sBAAsB,CAAC;AAC3D,YAAY,EAAE,cAAc,EAAE,aAAa,EAAE,aAAa,EAAE,YAAY,EAAE,MAAM,EAAE,MAAM,sBAAsB,CAAC;AAC/G,OAAO,EAAE,KAAK,EAAE,UAAU,EAAE,QAAQ,EAAE,MAAM,oBAAoB,CAAC;AACjE,YAAY,EAAE,WAAW,EAAE,OAAO,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAG7E,OAAO,EAAE,kBAAkB,EAAE,eAAe,EAAE,gBAAgB,EAAE,gBAAgB,EAAE,iBAAiB,EAAE,WAAW,EAAE,MAAM,2BAA2B,CAAC;AACpJ,YAAY,EAAE,gBAAgB,EAAE,UAAU,EAAE,MAAM,2BAA2B,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
package/dist/index.js CHANGED
@@ -12,18 +12,22 @@
12
12
  // host can build the same embedder (and share its persistent vector cache).
13
13
  export { createRecallEmbedder, createEvermindEmbedder, CachedTextEmbedder, defaultVectorCacheFile, MODEL_FILE_ENV, TOKENIZER_FILE_ENV, VECTOR_CACHE_ENV } from "./embedding/index.js";
14
14
  // ── Local backend (IndexedDB via @seanhogg/builderforce-memory) ────────────────────────
15
- export { MemoryStoreBackend, createLocalMemoryStoreBackend } from "./backends/memory-store.js";
15
+ export { MemoryStoreBackend, createLocalMemoryStoreBackend, DEFAULT_RECALL_RANKING } from "./backends/memory-store.js";
16
+ export { FileFactArchive, MemoryFactArchive } from "./persistence/fact-archive.js";
17
+ export { SharedJsonFile, DEFAULT_BACKUPS, backupFile } from "./persistence/shared-json-file.js";
16
18
  // ── Tool core ─────────────────────────────────────────────────────────────────
17
19
  export { buildMemoryTools } from "./tools.js";
18
20
  // ── Experience (demonstrations → Train Once skills → runs → the private model) ─
19
21
  // The domain is the engine's; this is its durable host and its tools.
20
22
  export { createExperienceHost, EXPERIENCE_ENV } from "./experience/host.js";
21
23
  export { nextExperienceVersion } from "./experience/train.js";
22
- // ── Compaction (absorbed fact → one-line pointer stub) ───────────────────────
23
- // Exported so an EXTERNAL compactor (the BuilderForce VS Code extension rewrites
24
- // the snapshot file directly) can produce byte-identical stubs, keeping the two
25
- // paths idempotent with respect to each other.
26
- export { STUB_PREFIX, DEFAULT_STUB_CHARS, isStub, firstLine, memoryStub, planCompaction } from "./compaction.js";
24
+ // ── Compaction (absorbed fact → one-line pointer stub, LOSSLESS) ─────────────
25
+ // Exported so an EXTERNAL compactor (the BuilderForce VS Code extension) produces
26
+ // byte-identical stubs AND follows the same archive + recall-probe rules, keeping
27
+ // the two paths idempotent with respect to each other.
28
+ export { STUB_PREFIX, DEFAULT_STUB_CHARS, CONTENT_LOST_LABEL, isStub, isContentLost, firstLine, memoryStub, stubPointer, planCompaction, planLosslessCompaction, probeQuestionFor, probePasses, defaultArchiveFile, parseArchive, mergeArchive, } from "./compaction.js";
29
+ export { createRecallProbe, lazyRecallProbe, generatorProbe, PROBE_MAX_NEW_TOKENS } from "./model/recall-probe.js";
30
+ export { parseRestoreSource, planRestore, restoredArchive, stubVersion, MIN_POINTER_CHARS } from "./restore.js";
27
31
  // ── Transports ──────────────────────────────────────────────────────────────
28
32
  export { createMemoryMcpServer } from "./transports/sdk.js";
29
33
  export { buildMcpServer } from "./transports/mcp-server.js";
@@ -31,7 +35,7 @@ export { runStdio } from "./transports/stdio.js";
31
35
  export { createMemoryHttpHandler } from "./transports/http.js";
32
36
  export { hashToken, timingSafeEqualStr, buildTenantIndex, bearerToken, RateLimiter } from "./transports/auth.js";
33
37
  // ── Multi-host installer (wire the stdio server into any MCP-capable agent) ───
34
- export { buildServerSpec, defaultMemoryFile, resolveMemoryFile, MCP_PACKAGE, MCP_BIN, MEMORY_FILE_ENV, RUNTIME_PEERS } from "./install/server-spec.js";
38
+ export { buildServerSpec, defaultMemoryFile, memoryFileCandidates, resolveMemoryFile, CANONICAL_MEMORY_SEGMENTS, LEGACY_MEMORY_SEGMENTS, MCP_PACKAGE, MCP_BIN, MEMORY_FILE_ENV, RUNTIME_PEERS, } from "./install/server-spec.js";
35
39
  export { installMemoryServer } from "./install/install.js";
36
40
  export { HOSTS, SERVER_KEY, findHost } from "./install/hosts.js";
37
41
  // Claude Code "memory combo" — hooks (SessionStart/PreCompact/UserPromptSubmit/Stop)
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAKH,8EAA8E;AAC9E,iFAAiF;AACjF,gFAAgF;AAChF,4EAA4E;AAC5E,OAAO,EAAE,oBAAoB,EAAE,sBAAsB,EAAE,kBAAkB,EAAE,sBAAsB,EAAE,cAAc,EAAE,kBAAkB,EAAE,gBAAgB,EAAE,MAAM,sBAAsB,CAAC;AAGtL,0FAA0F;AAC1F,OAAO,EAAE,kBAAkB,EAAE,6BAA6B,EAAE,MAAM,4BAA4B,CAAC;AAG/F,iFAAiF;AACjF,OAAO,EAAE,gBAAgB,EAAE,MAAM,YAAY,CAAC;AAI9C,kFAAkF;AAClF,sEAAsE;AACtE,OAAO,EAAE,oBAAoB,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC;AAE5E,OAAO,EAAE,qBAAqB,EAAE,MAAM,uBAAuB,CAAC;AAE9D,gFAAgF;AAChF,iFAAiF;AACjF,gFAAgF;AAChF,+CAA+C;AAC/C,OAAO,EAAE,WAAW,EAAE,kBAAkB,EAAE,MAAM,EAAE,SAAS,EAAE,UAAU,EAAE,cAAc,EAAE,MAAM,iBAAiB,CAAC;AAGjH,+EAA+E;AAC/E,OAAO,EAAE,qBAAqB,EAAE,MAAM,qBAAqB,CAAC;AAG5D,OAAO,EAAE,cAAc,EAAE,MAAM,4BAA4B,CAAC;AAG5D,OAAO,EAAE,QAAQ,EAAE,MAAM,uBAAuB,CAAC;AAEjD,OAAO,EAAE,uBAAuB,EAAE,MAAM,sBAAsB,CAAC;AAE/D,OAAO,EAAE,SAAS,EAAE,kBAAkB,EAAE,gBAAgB,EAAE,WAAW,EAAE,WAAW,EAAE,MAAM,sBAAsB,CAAC;AAEjH,iFAAiF;AACjF,OAAO,EAAE,eAAe,EAAE,iBAAiB,EAAE,iBAAiB,EAAE,WAAW,EAAE,OAAO,EAAE,eAAe,EAAE,aAAa,EAAE,MAAM,0BAA0B,CAAC;AAEvJ,OAAO,EAAE,mBAAmB,EAAE,MAAM,sBAAsB,CAAC;AAE3D,OAAO,EAAE,KAAK,EAAE,UAAU,EAAE,QAAQ,EAAE,MAAM,oBAAoB,CAAC;AAEjE,qFAAqF;AACrF,4FAA4F;AAC5F,OAAO,EAAE,kBAAkB,EAAE,eAAe,EAAE,gBAAgB,EAAE,gBAAgB,EAAE,iBAAiB,EAAE,WAAW,EAAE,MAAM,2BAA2B,CAAC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAKH,8EAA8E;AAC9E,iFAAiF;AACjF,gFAAgF;AAChF,4EAA4E;AAC5E,OAAO,EAAE,oBAAoB,EAAE,sBAAsB,EAAE,kBAAkB,EAAE,sBAAsB,EAAE,cAAc,EAAE,kBAAkB,EAAE,gBAAgB,EAAE,MAAM,sBAAsB,CAAC;AAGtL,0FAA0F;AAC1F,OAAO,EAAE,kBAAkB,EAAE,6BAA6B,EAAE,sBAAsB,EAAE,MAAM,4BAA4B,CAAC;AAEvH,OAAO,EAAE,eAAe,EAAE,iBAAiB,EAAE,MAAM,+BAA+B,CAAC;AAEnF,OAAO,EAAE,cAAc,EAAE,eAAe,EAAE,UAAU,EAAE,MAAM,mCAAmC,CAAC;AAGhG,iFAAiF;AACjF,OAAO,EAAE,gBAAgB,EAAE,MAAM,YAAY,CAAC;AAI9C,kFAAkF;AAClF,sEAAsE;AACtE,OAAO,EAAE,oBAAoB,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC;AAE5E,OAAO,EAAE,qBAAqB,EAAE,MAAM,uBAAuB,CAAC;AAE9D,gFAAgF;AAChF,kFAAkF;AAClF,kFAAkF;AAClF,uDAAuD;AACvD,OAAO,EACH,WAAW,EACX,kBAAkB,EAClB,kBAAkB,EAClB,MAAM,EACN,aAAa,EACb,SAAS,EACT,UAAU,EACV,WAAW,EACX,cAAc,EACd,sBAAsB,EACtB,gBAAgB,EAChB,WAAW,EACX,kBAAkB,EAClB,YAAY,EACZ,YAAY,GACf,MAAM,iBAAiB,CAAC;AAazB,OAAO,EAAE,iBAAiB,EAAE,eAAe,EAAE,cAAc,EAAE,oBAAoB,EAAE,MAAM,yBAAyB,CAAC;AACnH,OAAO,EAAE,kBAAkB,EAAE,WAAW,EAAE,eAAe,EAAE,WAAW,EAAE,iBAAiB,EAAE,MAAM,cAAc,CAAC;AAGhH,+EAA+E;AAC/E,OAAO,EAAE,qBAAqB,EAAE,MAAM,qBAAqB,CAAC;AAG5D,OAAO,EAAE,cAAc,EAAE,MAAM,4BAA4B,CAAC;AAG5D,OAAO,EAAE,QAAQ,EAAE,MAAM,uBAAuB,CAAC;AAEjD,OAAO,EAAE,uBAAuB,EAAE,MAAM,sBAAsB,CAAC;AAE/D,OAAO,EAAE,SAAS,EAAE,kBAAkB,EAAE,gBAAgB,EAAE,WAAW,EAAE,WAAW,EAAE,MAAM,sBAAsB,CAAC;AAEjH,iFAAiF;AACjF,OAAO,EACH,eAAe,EACf,iBAAiB,EACjB,oBAAoB,EACpB,iBAAiB,EACjB,yBAAyB,EACzB,sBAAsB,EACtB,WAAW,EACX,OAAO,EACP,eAAe,EACf,aAAa,GAChB,MAAM,0BAA0B,CAAC;AAElC,OAAO,EAAE,mBAAmB,EAAE,MAAM,sBAAsB,CAAC;AAE3D,OAAO,EAAE,KAAK,EAAE,UAAU,EAAE,QAAQ,EAAE,MAAM,oBAAoB,CAAC;AAEjE,qFAAqF;AACrF,4FAA4F;AAC5F,OAAO,EAAE,kBAAkB,EAAE,eAAe,EAAE,gBAAgB,EAAE,gBAAgB,EAAE,iBAAiB,EAAE,WAAW,EAAE,MAAM,2BAA2B,CAAC"}
@@ -28,6 +28,11 @@ import type { FsLike } from "./install.js";
28
28
  * Code plugin, whose files are static and machine-independent. The runtime
29
29
  * branch must stay in lockstep with `resolveMemoryFile`; `install.test.mjs`
30
30
  * asserts it does.
31
+ *
32
+ * Compaction stubs whose original was never archived (`contentLost`) are still
33
+ * injected — the pointer is a real lead — but labelled
34
+ * {@link CONTENT_LOST_LABEL} and importance-demoted, so they rank below intact
35
+ * memories and are never presented as verified fact.
31
36
  */
32
37
  export declare function bfmemHookSource(memoryFile: string | null): string;
33
38
  /** The companion skill doc that teaches the recall/remember discipline. */
@@ -1 +1 @@
1
- {"version":3,"file":"claude-hooks.d.ts","sourceRoot":"","sources":["../../src/install/claude-hooks.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;GAoBG;AAGH,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,cAAc,CAAC;AAG3C;;;;;;;;GAQG;AACH,wBAAgB,eAAe,CAAC,UAAU,EAAE,MAAM,GAAG,IAAI,GAAG,MAAM,CAiMjE;AAED,2EAA2E;AAC3E,wBAAgB,gBAAgB,IAAI,MAAM,CA0BzC;AAED,qFAAqF;AACrF,MAAM,WAAW,gBAAgB;IAC7B,SAAS,EAAE,MAAM,CAAC;IAClB,YAAY,EAAE,MAAM,CAAC;IACrB,UAAU,EAAE,MAAM,CAAC;IACnB,cAAc,EAAE,MAAM,CAAC;CAC1B;AAED,wBAAgB,gBAAgB,CAAC,SAAS,EAAE,MAAM,GAAG,gBAAgB,CAOpE;AAED;;;;;GAKG;AACH,eAAO,MAAM,WAAW;;;;;;;;;;;;EAKd,CAAC;AAEX,qFAAqF;AACrF,MAAM,MAAM,UAAU,GAAG,MAAM,CAAC,MAAM,EAAE,KAAK,CAAC;IAAE,KAAK,EAAE,KAAK,CAAC;QAAE,IAAI,EAAE,SAAS,CAAC;QAAC,OAAO,EAAE,MAAM,CAAA;KAAE,CAAC,CAAA;CAAE,CAAC,CAAC,CAAC;AAEvG;;;;GAIG;AACH,wBAAgB,iBAAiB,CAAC,aAAa,SAAyB,GAAG,UAAU,CAQpF;AAED;;;;GAIG;AACH,wBAAgB,kBAAkB,CAAC,IAAI,EAAE;IACrC,EAAE,EAAE,MAAM,CAAC;IACX,SAAS,EAAE,MAAM,CAAC;IAClB,UAAU,EAAE,MAAM,CAAC;CACtB,GAAG;IAAE,UAAU,EAAE,MAAM,CAAC;IAAC,UAAU,EAAE,MAAM,EAAE,CAAC;IAAC,YAAY,EAAE,MAAM,CAAA;CAAE,CAmDrE"}
1
+ {"version":3,"file":"claude-hooks.d.ts","sourceRoot":"","sources":["../../src/install/claude-hooks.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;GAoBG;AAIH,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,cAAc,CAAC;AA2B3C;;;;;;;;;;;;;GAaG;AACH,wBAAgB,eAAe,CAAC,UAAU,EAAE,MAAM,GAAG,IAAI,GAAG,MAAM,CA2NjE;AAED,2EAA2E;AAC3E,wBAAgB,gBAAgB,IAAI,MAAM,CAiCzC;AAED,qFAAqF;AACrF,MAAM,WAAW,gBAAgB;IAC7B,SAAS,EAAE,MAAM,CAAC;IAClB,YAAY,EAAE,MAAM,CAAC;IACrB,UAAU,EAAE,MAAM,CAAC;IACnB,cAAc,EAAE,MAAM,CAAC;CAC1B;AAED,wBAAgB,gBAAgB,CAAC,SAAS,EAAE,MAAM,GAAG,gBAAgB,CAOpE;AAED;;;;;GAKG;AACH,eAAO,MAAM,WAAW;;;;;;;;;;;;EAKd,CAAC;AAEX,qFAAqF;AACrF,MAAM,MAAM,UAAU,GAAG,MAAM,CAAC,MAAM,EAAE,KAAK,CAAC;IAAE,KAAK,EAAE,KAAK,CAAC;QAAE,IAAI,EAAE,SAAS,CAAC;QAAC,OAAO,EAAE,MAAM,CAAA;KAAE,CAAC,CAAA;CAAE,CAAC,CAAC,CAAC;AAEvG;;;;GAIG;AACH,wBAAgB,iBAAiB,CAAC,aAAa,SAAyB,GAAG,UAAU,CAQpF;AAED;;;;GAIG;AACH,wBAAgB,kBAAkB,CAAC,IAAI,EAAE;IACrC,EAAE,EAAE,MAAM,CAAC;IACX,SAAS,EAAE,MAAM,CAAC;IAClB,UAAU,EAAE,MAAM,CAAC;CACtB,GAAG;IAAE,UAAU,EAAE,MAAM,CAAC;IAAC,UAAU,EAAE,MAAM,EAAE,CAAC;IAAC,YAAY,EAAE,MAAM,CAAA;CAAE,CAmDrE"}
@@ -20,7 +20,29 @@
20
20
  * is idempotent and backup-safe, matching install.ts.
21
21
  */
22
22
  import nodePath from "node:path";
23
- import { MEMORY_FILE_ENV } from "./server-spec.js";
23
+ import { CONTENT_LOST_LABEL, STUB_PREFIX } from "../compaction.js";
24
+ import { CANONICAL_MEMORY_SEGMENTS, LEGACY_MEMORY_SEGMENTS, MEMORY_FILE_ENV } from "./server-spec.js";
25
+ /** `path.join(os.homedir(), "<seg>", …)` as hook-script source. */
26
+ const homeJoin = (segments) => `path.join(os.homedir(), ${segments.map((s) => JSON.stringify(s)).join(", ")})`;
27
+ /**
28
+ * The run-time twin of `resolveMemoryFile`, as hook-script source: the env
29
+ * override, else whichever candidate holds a memory.json (the most recently
30
+ * written when both do), else the canonical default. Built from the SAME segment
31
+ * constants, so the two cannot name different files.
32
+ */
33
+ function runtimeMemoryFileExpr() {
34
+ return `(() => {
35
+ const explicit = process.env[${JSON.stringify(MEMORY_FILE_ENV)}];
36
+ if (explicit) return explicit;
37
+ const candidates = [${homeJoin(CANONICAL_MEMORY_SEGMENTS)}, ${homeJoin(LEGACY_MEMORY_SEGMENTS)}];
38
+ let best = null, bestMtime = -Infinity;
39
+ for (const c of candidates) {
40
+ try { const st = fs.statSync(c); if (st.isFile() && st.mtimeMs > bestMtime) { best = c; bestMtime = st.mtimeMs; } }
41
+ catch { /* absent */ }
42
+ }
43
+ return best || candidates[0];
44
+ })()`;
45
+ }
24
46
  /**
25
47
  * The single hook script, four modes.
26
48
  *
@@ -29,11 +51,14 @@ import { MEMORY_FILE_ENV } from "./server-spec.js";
29
51
  * Code plugin, whose files are static and machine-independent. The runtime
30
52
  * branch must stay in lockstep with `resolveMemoryFile`; `install.test.mjs`
31
53
  * asserts it does.
54
+ *
55
+ * Compaction stubs whose original was never archived (`contentLost`) are still
56
+ * injected — the pointer is a real lead — but labelled
57
+ * {@link CONTENT_LOST_LABEL} and importance-demoted, so they rank below intact
58
+ * memories and are never presented as verified fact.
32
59
  */
33
60
  export function bfmemHookSource(memoryFile) {
34
- const fileExpr = memoryFile === null
35
- ? `process.env[${JSON.stringify(MEMORY_FILE_ENV)}] || path.join(os.homedir(), ".builderforce-memory", "memory.json")`
36
- : JSON.stringify(memoryFile);
61
+ const fileExpr = memoryFile === null ? runtimeMemoryFileExpr() : JSON.stringify(memoryFile);
37
62
  return `#!/usr/bin/env node
38
63
  /**
39
64
  * builderforce-memory hook — generated by builderforce-memory-install. Dependency-free:
@@ -58,6 +83,29 @@ function loadEntries() {
58
83
  try { const p = JSON.parse(fs.readFileSync(FILE, "utf8")); return Array.isArray(p) ? p : []; }
59
84
  catch { return []; }
60
85
  }
86
+
87
+ // ── Compaction stubs ─────────────────────────────────────────────────────────
88
+ // A compacted memory's full original lives in the archive beside the snapshot
89
+ // (memory.json → memory.archive.json). A stub with NO archived original is lost
90
+ // content: still injected (the pointer is a real lead) but labelled and demoted.
91
+ const ARCHIVE = FILE.replace(/\\.json$/i, "") + ".archive.json";
92
+ const STUB_PREFIX = ${JSON.stringify(STUB_PREFIX)};
93
+ const LOST_LABEL = ${JSON.stringify(CONTENT_LOST_LABEL)};
94
+ const LOST_DEMOTION = 0.5;
95
+ let archivedKeys = null;
96
+ function archived() {
97
+ if (archivedKeys) return archivedKeys;
98
+ try { const a = JSON.parse(fs.readFileSync(ARCHIVE, "utf8")); archivedKeys = new Set(Object.keys((a && a.facts) || {})); }
99
+ catch { archivedKeys = new Set(); }
100
+ return archivedKeys;
101
+ }
102
+ function isLost(e) {
103
+ // The archive decides (a snapshot's contentLost flag can trail a restore).
104
+ return String(e.content || "").trimStart().startsWith(STUB_PREFIX) && !archived().has(e.key);
105
+ }
106
+ function render(e, max) {
107
+ return "• " + e.key + ": " + String(e.content || "").slice(0, max) + (isLost(e) ? " " + LOST_LABEL : "");
108
+ }
61
109
  function tokens(s) {
62
110
  return String(s || "").toLowerCase().split(/[^a-z0-9]+/).filter((t) => t.length >= 3);
63
111
  }
@@ -108,16 +156,17 @@ if (mode === "--recall") {
108
156
  const hay = new Set(tokens([e.key, e.content, (e.tags || []).join(" ")].join(" ")));
109
157
  let score = 0;
110
158
  for (const t of q) if (hay.has(t)) score++;
111
- return { e, score };
159
+ // Lost content still qualifies on overlap, but ranks below intact memories.
160
+ return { e, score, rank: isLost(e) ? score * LOST_DEMOTION : score };
112
161
  })
113
162
  .filter((x) => x.score >= 2)
114
163
  .filter((x) => !led.has(x.e.key)) // already surfaced this session → don't re-inject
115
- .sort((a, b) => b.score - a.score)
164
+ .sort((a, b) => b.rank - a.rank)
116
165
  .slice(0, 3);
117
166
  if (scored.length === 0) process.exit(0);
118
167
  for (const x of scored) led.add(x.e.key);
119
168
  saveLedger(sid, led);
120
- const lines = scored.map((x) => "• " + x.e.key + ": " + String(x.e.content || "").slice(0, 200)).join("\\n");
169
+ const lines = scored.map((x) => render(x.e, 200)).join("\\n");
121
170
  process.stdout.write(
122
171
  "[builderforce-memory] Relevant stored memories for this request — use these instead of re-deriving or re-reading:\\n" + lines,
123
172
  );
@@ -207,7 +256,11 @@ if (entries.length === 0) {
207
256
  process.exit(0);
208
257
  }
209
258
  const ranked = entries
210
- .map((e) => ({ key: e.key, content: String(e.content ?? ""), importance: typeof e.importance === "number" ? e.importance : 0.5 }))
259
+ .map((e) => {
260
+ const importance = typeof e.importance === "number" ? e.importance : 0.5;
261
+ // Lost content is importance-demoted so intact memories lead the digest.
262
+ return { key: e.key, content: String(e.content ?? ""), importance: isLost(e) ? importance * LOST_DEMOTION : importance };
263
+ })
211
264
  .sort((a, b) => b.importance - a.importance)
212
265
  .slice(0, 6);
213
266
 
@@ -218,7 +271,7 @@ for (const e of ranked) led.add(e.key);
218
271
  saveLedger(sessionId, led);
219
272
 
220
273
  if (src === "resume") process.exit(0); // context retained across resume — nothing to re-inject
221
- const top = ranked.map((e) => "• " + e.key + ": " + e.content.slice(0, 180)).join("\\n");
274
+ const top = ranked.map((e) => render(e, 180)).join("\\n");
222
275
  process.stdout.write(
223
276
  "[builderforce-memory] Active — token-saving memory loaded. Before re-reading files or history, call memory_recall. Store durable facts with memory_remember.\\nTop memories:\\n" + top,
224
277
  );
@@ -245,6 +298,13 @@ capture that won't let a durable correction go unrecorded.
245
298
  - \`memory_recall_by_tag(tag)\` — everything under a tag.
246
299
  - \`memory_remember(key, content, [tags], [importance])\` — store ONE durable fact.
247
300
  - \`memory_forget(key)\` — drop a superseded fact.
301
+ - \`memory_compact(keys)\` — stub facts the local Evermind has absorbed (proven by a
302
+ recall probe; the original is archived, so recall still returns it).
303
+ - \`memory_restore(file|json)\` — bring back the text of memories marked
304
+ "${CONTENT_LOST_LABEL}" from an export.
305
+
306
+ A memory labelled "${CONTENT_LOST_LABEL}" is a one-line pointer whose full
307
+ text is gone: treat it as a lead, verify it before acting on it.
248
308
 
249
309
  ## Discipline
250
310
  Reuse a stable key to REPLACE a fact (write-through), don't append duplicates.
@@ -1 +1 @@
1
- {"version":3,"file":"claude-hooks.js","sourceRoot":"","sources":["../../src/install/claude-hooks.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"claude-hooks.js","sourceRoot":"","sources":["../../src/install/claude-hooks.ts"],"names":[],"mappings":"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"}
@@ -12,17 +12,43 @@ export interface StdioServerSpec {
12
12
  env?: Record<string, string>;
13
13
  }
14
14
  /**
15
- * The default JSON snapshot path: ONE store per machine, so every MCP host
16
- * (Claude Code, Cursor, Claude Desktop, …) shares the same memory.
15
+ * The snapshot path override every reader and writer honours first.
17
16
  *
18
- * Single source of truth for the installer, the stdio bin's fallback, and the
19
- * Claude Code plugin's hook script — a memory file the writer and the reader
20
- * disagree about is memory that silently disappears.
17
+ * ONE resolver ({@link resolveMemoryFile}) serves the installer, both server bins
18
+ * and the Claude Code hook script (which inlines the same rules — see
19
+ * `bfmemHookSource`) — a memory file the writer and the reader disagree about is
20
+ * memory that silently disappears.
21
21
  */
22
22
  export declare const MEMORY_FILE_ENV = "BUILDERFORCE_MEMORY_FILE";
23
+ /** The canonical per-machine store, relative to the home directory. */
24
+ export declare const CANONICAL_MEMORY_SEGMENTS: readonly [".builderforce-memory", "memory.json"];
25
+ /**
26
+ * Where earlier installers put the store (`~/.claude/builderforce-memory/memory.json`).
27
+ * Still honoured: a machine whose live memory sits here keeps using it.
28
+ */
29
+ export declare const LEGACY_MEMORY_SEGMENTS: readonly [".claude", "builderforce-memory", "memory.json"];
30
+ /** The default JSON snapshot path: ONE store per machine, shared by every MCP host. */
23
31
  export declare function defaultMemoryFile(homedir?: string): string;
24
- /** The snapshot path in effect: explicit env wins, else the shared default. */
25
- export declare function resolveMemoryFile(env?: Record<string, string | undefined>, homedir?: string): string;
32
+ /** Every location a store may live in, canonical first. */
33
+ export declare function memoryFileCandidates(homedir?: string): string[];
34
+ /** File probe the resolver uses — injectable for tests. */
35
+ export interface MemoryFileProbe {
36
+ /** Unix-ms modification time of `path` when it is a file, else null. */
37
+ fileMtime(path: string): number | null;
38
+ }
39
+ export interface ResolveMemoryFileOptions {
40
+ probe?: MemoryFileProbe;
41
+ /** Told which store won when more than one location is in play. Default: silent. */
42
+ log?: (line: string) => void;
43
+ }
44
+ /**
45
+ * The snapshot path in effect:
46
+ * 1. `BUILDERFORCE_MEMORY_FILE`, when set;
47
+ * 2. else whichever candidate location actually holds a `memory.json` — the
48
+ * most recently written one if both do (logged; neither is ever deleted);
49
+ * 3. else the canonical default.
50
+ */
51
+ export declare function resolveMemoryFile(env?: Record<string, string | undefined>, homedir?: string, opts?: ResolveMemoryFileOptions): string;
26
52
  export interface ServerSpecOptions {
27
53
  /** Absolute path to the JSON snapshot that makes memory survive restarts. */
28
54
  memoryFile?: string;
@@ -1 +1 @@
1
- {"version":3,"file":"server-spec.d.ts","sourceRoot":"","sources":["../../src/install/server-spec.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAKH,MAAM,WAAW,eAAe;IAC5B,OAAO,EAAE,MAAM,CAAC;IAChB,IAAI,EAAE,MAAM,EAAE,CAAC;IACf,GAAG,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CAChC;AAED;;;;;;;GAOG;AACH,eAAO,MAAM,eAAe,6BAA6B,CAAC;AAE1D,wBAAgB,iBAAiB,CAAC,OAAO,GAAE,MAAyB,GAAG,MAAM,CAE5E;AAED,+EAA+E;AAC/E,wBAAgB,iBAAiB,CAC7B,GAAG,GAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,SAAS,CAAe,EACrD,OAAO,CAAC,EAAE,MAAM,GACjB,MAAM,CAER;AAED,MAAM,WAAW,iBAAiB;IAC9B,6EAA6E;IAC7E,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,+DAA+D;IAC/D,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,6EAA6E;IAC7E,QAAQ,CAAC,EAAE,MAAM,CAAC,QAAQ,CAAC;IAC3B;;;OAGG;IACH,QAAQ,CAAC,EAAE,MAAM,CAAC;CACrB;AAED,+EAA+E;AAC/E,eAAO,MAAM,WAAW,sCAAsC,CAAC;AAC/D,eAAO,MAAM,OAAO,4BAA4B,CAAC;AAEjD;;;;;;GAMG;AACH,eAAO,MAAM,aAAa,UAIzB,CAAC;AASF;;;GAGG;AACH,wBAAgB,eAAe,CAAC,IAAI,GAAE,iBAAsB,GAAG,eAAe,CAc7E"}
1
+ {"version":3,"file":"server-spec.d.ts","sourceRoot":"","sources":["../../src/install/server-spec.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAMH,MAAM,WAAW,eAAe;IAC5B,OAAO,EAAE,MAAM,CAAC;IAChB,IAAI,EAAE,MAAM,EAAE,CAAC;IACf,GAAG,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CAChC;AAED;;;;;;;GAOG;AACH,eAAO,MAAM,eAAe,6BAA6B,CAAC;AAE1D,uEAAuE;AACvE,eAAO,MAAM,yBAAyB,kDAAmD,CAAC;AAE1F;;;GAGG;AACH,eAAO,MAAM,sBAAsB,4DAA6D,CAAC;AAEjG,uFAAuF;AACvF,wBAAgB,iBAAiB,CAAC,OAAO,GAAE,MAAyB,GAAG,MAAM,CAE5E;AAED,2DAA2D;AAC3D,wBAAgB,oBAAoB,CAAC,OAAO,GAAE,MAAyB,GAAG,MAAM,EAAE,CAEjF;AAED,2DAA2D;AAC3D,MAAM,WAAW,eAAe;IAC5B,wEAAwE;IACxE,SAAS,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAAC;CAC1C;AAaD,MAAM,WAAW,wBAAwB;IACrC,KAAK,CAAC,EAAE,eAAe,CAAC;IACxB,oFAAoF;IACpF,GAAG,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,CAAC;CAChC;AAED;;;;;;GAMG;AACH,wBAAgB,iBAAiB,CAC7B,GAAG,GAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,SAAS,CAAe,EACrD,OAAO,CAAC,EAAE,MAAM,EAChB,IAAI,GAAE,wBAA6B,GACpC,MAAM,CAsBR;AAED,MAAM,WAAW,iBAAiB;IAC9B,6EAA6E;IAC7E,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,+DAA+D;IAC/D,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,6EAA6E;IAC7E,QAAQ,CAAC,EAAE,MAAM,CAAC,QAAQ,CAAC;IAC3B;;;OAGG;IACH,QAAQ,CAAC,EAAE,MAAM,CAAC;CACrB;AAED,+EAA+E;AAC/E,eAAO,MAAM,WAAW,sCAAsC,CAAC;AAC/D,eAAO,MAAM,OAAO,4BAA4B,CAAC;AAEjD;;;;;;GAMG;AACH,eAAO,MAAM,aAAa,UAIzB,CAAC;AASF;;;GAGG;AACH,wBAAgB,eAAe,CAAC,IAAI,GAAE,iBAAsB,GAAG,eAAe,CAc7E"}
@@ -6,23 +6,73 @@
6
6
  * file/shape differs. This module is the single source of truth for HOW the
7
7
  * server is launched, so the per-host adapters never re-derive the command.
8
8
  */
9
+ import nodeFs from "node:fs";
9
10
  import nodeOs from "node:os";
10
11
  import nodePath from "node:path";
11
12
  /**
12
- * The default JSON snapshot path: ONE store per machine, so every MCP host
13
- * (Claude Code, Cursor, Claude Desktop, …) shares the same memory.
13
+ * The snapshot path override every reader and writer honours first.
14
14
  *
15
- * Single source of truth for the installer, the stdio bin's fallback, and the
16
- * Claude Code plugin's hook script — a memory file the writer and the reader
17
- * disagree about is memory that silently disappears.
15
+ * ONE resolver ({@link resolveMemoryFile}) serves the installer, both server bins
16
+ * and the Claude Code hook script (which inlines the same rules — see
17
+ * `bfmemHookSource`) — a memory file the writer and the reader disagree about is
18
+ * memory that silently disappears.
18
19
  */
19
20
  export const MEMORY_FILE_ENV = "BUILDERFORCE_MEMORY_FILE";
21
+ /** The canonical per-machine store, relative to the home directory. */
22
+ export const CANONICAL_MEMORY_SEGMENTS = [".builderforce-memory", "memory.json"];
23
+ /**
24
+ * Where earlier installers put the store (`~/.claude/builderforce-memory/memory.json`).
25
+ * Still honoured: a machine whose live memory sits here keeps using it.
26
+ */
27
+ export const LEGACY_MEMORY_SEGMENTS = [".claude", "builderforce-memory", "memory.json"];
28
+ /** The default JSON snapshot path: ONE store per machine, shared by every MCP host. */
20
29
  export function defaultMemoryFile(homedir = nodeOs.homedir()) {
21
- return nodePath.join(homedir, ".builderforce-memory", "memory.json");
30
+ return nodePath.join(homedir, ...CANONICAL_MEMORY_SEGMENTS);
31
+ }
32
+ /** Every location a store may live in, canonical first. */
33
+ export function memoryFileCandidates(homedir = nodeOs.homedir()) {
34
+ return [defaultMemoryFile(homedir), nodePath.join(homedir, ...LEGACY_MEMORY_SEGMENTS)];
22
35
  }
23
- /** The snapshot path in effect: explicit env wins, else the shared default. */
24
- export function resolveMemoryFile(env = process.env, homedir) {
25
- return env[MEMORY_FILE_ENV] || defaultMemoryFile(homedir);
36
+ const nodeProbe = {
37
+ fileMtime(path) {
38
+ try {
39
+ const st = nodeFs.statSync(path);
40
+ return st.isFile() ? st.mtimeMs : null;
41
+ }
42
+ catch {
43
+ return null;
44
+ }
45
+ },
46
+ };
47
+ /**
48
+ * The snapshot path in effect:
49
+ * 1. `BUILDERFORCE_MEMORY_FILE`, when set;
50
+ * 2. else whichever candidate location actually holds a `memory.json` — the
51
+ * most recently written one if both do (logged; neither is ever deleted);
52
+ * 3. else the canonical default.
53
+ */
54
+ export function resolveMemoryFile(env = process.env, homedir, opts = {}) {
55
+ const explicit = env[MEMORY_FILE_ENV];
56
+ if (explicit)
57
+ return explicit;
58
+ const probe = opts.probe ?? nodeProbe;
59
+ const candidates = memoryFileCandidates(homedir);
60
+ const present = candidates
61
+ .map((path) => ({ path, mtime: probe.fileMtime(path) }))
62
+ .filter((c) => c.mtime !== null);
63
+ if (present.length === 0)
64
+ return candidates[0];
65
+ if (present.length === 1) {
66
+ if (present[0].path !== candidates[0]) {
67
+ opts.log?.(`[builderforce-memory] using the store at ${present[0].path} (no memory.json at ${candidates[0]}).`);
68
+ }
69
+ return present[0].path;
70
+ }
71
+ const winner = present.reduce((a, b) => (b.mtime > a.mtime ? b : a));
72
+ const others = present.filter((c) => c !== winner).map((c) => c.path);
73
+ opts.log?.(`[builderforce-memory] memory.json exists in ${present.length} locations; using ${winner.path} ` +
74
+ `(most recently written). Left untouched: ${others.join(", ")}.`);
75
+ return winner.path;
26
76
  }
27
77
  /** Published package + bin. The bin name matches the unscoped package name. */
28
78
  export const MCP_PACKAGE = "@seanhogg/builderforce-memory-mcp";
@@ -1 +1 @@
1
- {"version":3,"file":"server-spec.js","sourceRoot":"","sources":["../../src/install/server-spec.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,MAAM,MAAM,SAAS,CAAC;AAC7B,OAAO,QAAQ,MAAM,WAAW,CAAC;AAQjC;;;;;;;GAOG;AACH,MAAM,CAAC,MAAM,eAAe,GAAG,0BAA0B,CAAC;AAE1D,MAAM,UAAU,iBAAiB,CAAC,UAAkB,MAAM,CAAC,OAAO,EAAE;IAChE,OAAO,QAAQ,CAAC,IAAI,CAAC,OAAO,EAAE,sBAAsB,EAAE,aAAa,CAAC,CAAC;AACzE,CAAC;AAED,+EAA+E;AAC/E,MAAM,UAAU,iBAAiB,CAC7B,MAA0C,OAAO,CAAC,GAAG,EACrD,OAAgB;IAEhB,OAAO,GAAG,CAAC,eAAe,CAAC,IAAI,iBAAiB,CAAC,OAAO,CAAC,CAAC;AAC9D,CAAC;AAgBD,+EAA+E;AAC/E,MAAM,CAAC,MAAM,WAAW,GAAG,mCAAmC,CAAC;AAC/D,MAAM,CAAC,MAAM,OAAO,GAAG,yBAAyB,CAAC;AAEjD;;;;;;GAMG;AACH,MAAM,CAAC,MAAM,aAAa,GAAG;IACzB,+BAA+B;IAC/B,sCAAsC;IACtC,gBAAgB;CACnB,CAAC;AAEF,SAAS,OAAO,CAAC,IAAuB;IACpC,MAAM,GAAG,GAA2B,EAAE,CAAC;IACvC,IAAI,IAAI,CAAC,UAAU;QAAE,GAAG,CAAC,0BAA0B,CAAC,GAAG,IAAI,CAAC,UAAU,CAAC;IACvE,IAAI,IAAI,CAAC,QAAQ;QAAE,GAAG,CAAC,8BAA8B,CAAC,GAAG,GAAG,CAAC;IAC7D,OAAO,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,SAAS,CAAC;AACzD,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,eAAe,CAAC,OAA0B,EAAE;IACxD,MAAM,QAAQ,GAAG,IAAI,CAAC,QAAQ,IAAI,OAAO,CAAC,QAAQ,CAAC;IACnD,MAAM,GAAG,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAE1B,IAAI,IAAI,CAAC,QAAQ,EAAE,CAAC;QAChB,OAAO,EAAE,OAAO,EAAE,MAAM,EAAE,IAAI,EAAE,CAAC,IAAI,CAAC,QAAQ,CAAC,EAAE,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,GAAG,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC;IAC/E,CAAC;IAED,MAAM,OAAO,GAAG,CAAC,IAAI,EAAE,IAAI,EAAE,WAAW,EAAE,GAAG,aAAa,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,EAAE,OAAO,CAAC,CAAC;IAE/F,IAAI,QAAQ,KAAK,OAAO,EAAE,CAAC;QACvB,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC,IAAI,EAAE,KAAK,EAAE,GAAG,OAAO,CAAC,EAAE,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,GAAG,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC;IACxF,CAAC;IACD,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,IAAI,EAAE,OAAO,EAAE,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,GAAG,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC;AACtE,CAAC"}
1
+ {"version":3,"file":"server-spec.js","sourceRoot":"","sources":["../../src/install/server-spec.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,29 @@
1
+ /**
2
+ * The recall probe compaction runs before it stubs a fact: the person's local
3
+ * Evermind model — the same `.evermind` package recall embeds with and experience
4
+ * training adapts (`BUILDERFORCE_MEMORY_MODEL`) — is asked the question generated
5
+ * from the fact (`probeQuestionFor`), and the fact is stubbed only when the answer
6
+ * carries it. No model configured, or one that cannot generate, means no probe —
7
+ * and no probe means nothing is compacted.
8
+ */
9
+ import type { RecallProbe } from "../compaction.js";
10
+ /** Tokens the model may spend answering one probe — a cloze answer is a word or two. */
11
+ export declare const PROBE_MAX_NEW_TOKENS = 16;
12
+ /** Wrap any text generator as a probe. Greedy, short, never throws. */
13
+ export declare function generatorProbe(generate: (prompt: string) => string | Promise<string>): RecallProbe;
14
+ export interface RecallProbeEnv {
15
+ env?: Record<string, string | undefined>;
16
+ }
17
+ /**
18
+ * The probe for this server, or null when no model is configured, the package is
19
+ * not a text LM, or its tokenizer cannot decode (no answer text to check).
20
+ */
21
+ export declare function createRecallProbe(opts?: RecallProbeEnv): Promise<RecallProbe | null>;
22
+ /**
23
+ * {@link createRecallProbe}, deferred to the first compaction — a server should not
24
+ * load a checkpoint at boot for a tool most sessions never call. Null when no model
25
+ * is configured; a model that then fails to load answers nothing (every probe fails,
26
+ * so nothing is stubbed).
27
+ */
28
+ export declare function lazyRecallProbe(opts?: RecallProbeEnv): RecallProbe | null;
29
+ //# sourceMappingURL=recall-probe.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"recall-probe.d.ts","sourceRoot":"","sources":["../../src/model/recall-probe.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAC;AASpD,wFAAwF;AACxF,eAAO,MAAM,oBAAoB,KAAK,CAAC;AAEvC,uEAAuE;AACvE,wBAAgB,cAAc,CAAC,QAAQ,EAAE,CAAC,MAAM,EAAE,MAAM,KAAK,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,GAAG,WAAW,CAWlG;AAED,MAAM,WAAW,cAAc;IAC3B,GAAG,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,SAAS,CAAC,CAAC;CAC5C;AAED;;;GAGG;AACH,wBAAsB,iBAAiB,CAAC,IAAI,GAAE,cAAmB,GAAG,OAAO,CAAC,WAAW,GAAG,IAAI,CAAC,CAkB9F;AAED;;;;;GAKG;AACH,wBAAgB,eAAe,CAAC,IAAI,GAAE,cAAmB,GAAG,WAAW,GAAG,IAAI,CAW7E"}
@@ -0,0 +1,72 @@
1
+ /**
2
+ * The recall probe compaction runs before it stubs a fact: the person's local
3
+ * Evermind model — the same `.evermind` package recall embeds with and experience
4
+ * training adapts (`BUILDERFORCE_MEMORY_MODEL`) — is asked the question generated
5
+ * from the fact (`probeQuestionFor`), and the fact is stubbed only when the answer
6
+ * carries it. No model configured, or one that cannot generate, means no probe —
7
+ * and no probe means nothing is compacted.
8
+ */
9
+ import { MODEL_FILE_ENV, TOKENIZER_FILE_ENV } from "../embedding/index.js";
10
+ import { loadEvermindPackage } from "./evermind-package.js";
11
+ /** Tokens the model may spend answering one probe — a cloze answer is a word or two. */
12
+ export const PROBE_MAX_NEW_TOKENS = 16;
13
+ /** Wrap any text generator as a probe. Greedy, short, never throws. */
14
+ export function generatorProbe(generate) {
15
+ return {
16
+ async answer(question) {
17
+ try {
18
+ const out = await generate(question);
19
+ return typeof out === "string" ? out : null;
20
+ }
21
+ catch {
22
+ return null;
23
+ }
24
+ },
25
+ };
26
+ }
27
+ /**
28
+ * The probe for this server, or null when no model is configured, the package is
29
+ * not a text LM, or its tokenizer cannot decode (no answer text to check).
30
+ */
31
+ export async function createRecallProbe(opts = {}) {
32
+ const env = opts.env ?? process.env;
33
+ const modelFile = env[MODEL_FILE_ENV];
34
+ if (!modelFile)
35
+ return null;
36
+ const loaded = await loadEvermindPackage(modelFile, env[TOKENIZER_FILE_ENV] || undefined);
37
+ if (!loaded)
38
+ return null;
39
+ const codec = loaded.codec;
40
+ if (typeof codec.decode !== "function")
41
+ return null;
42
+ let lm;
43
+ try {
44
+ lm = loaded.pkg.loadLM();
45
+ }
46
+ catch {
47
+ return null;
48
+ }
49
+ if (typeof lm?.generateText !== "function")
50
+ return null;
51
+ return generatorProbe((prompt) => lm.generateText(prompt, loaded.codec, { maxNewTokens: PROBE_MAX_NEW_TOKENS, temperature: 0 }));
52
+ }
53
+ /**
54
+ * {@link createRecallProbe}, deferred to the first compaction — a server should not
55
+ * load a checkpoint at boot for a tool most sessions never call. Null when no model
56
+ * is configured; a model that then fails to load answers nothing (every probe fails,
57
+ * so nothing is stubbed).
58
+ */
59
+ export function lazyRecallProbe(opts = {}) {
60
+ const env = opts.env ?? process.env;
61
+ if (!env[MODEL_FILE_ENV])
62
+ return null;
63
+ let probe = null;
64
+ return {
65
+ async answer(question) {
66
+ probe ??= createRecallProbe({ env });
67
+ const p = await probe;
68
+ return p ? p.answer(question) : null;
69
+ },
70
+ };
71
+ }
72
+ //# sourceMappingURL=recall-probe.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"recall-probe.js","sourceRoot":"","sources":["../../src/model/recall-probe.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAGH,OAAO,EAAE,cAAc,EAAE,kBAAkB,EAAE,MAAM,uBAAuB,CAAC;AAC3E,OAAO,EAAE,mBAAmB,EAAE,MAAM,uBAAuB,CAAC;AAO5D,wFAAwF;AACxF,MAAM,CAAC,MAAM,oBAAoB,GAAG,EAAE,CAAC;AAEvC,uEAAuE;AACvE,MAAM,UAAU,cAAc,CAAC,QAAsD;IACjF,OAAO;QACH,KAAK,CAAC,MAAM,CAAC,QAAgB;YACzB,IAAI,CAAC;gBACD,MAAM,GAAG,GAAG,MAAM,QAAQ,CAAC,QAAQ,CAAC,CAAC;gBACrC,OAAO,OAAO,GAAG,KAAK,QAAQ,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC;YAChD,CAAC;YAAC,MAAM,CAAC;gBACL,OAAO,IAAI,CAAC;YAChB,CAAC;QACL,CAAC;KACJ,CAAC;AACN,CAAC;AAMD;;;GAGG;AACH,MAAM,CAAC,KAAK,UAAU,iBAAiB,CAAC,OAAuB,EAAE;IAC7D,MAAM,GAAG,GAAG,IAAI,CAAC,GAAG,IAAI,OAAO,CAAC,GAAG,CAAC;IACpC,MAAM,SAAS,GAAG,GAAG,CAAC,cAAc,CAAC,CAAC;IACtC,IAAI,CAAC,SAAS;QAAE,OAAO,IAAI,CAAC;IAC5B,MAAM,MAAM,GAAG,MAAM,mBAAmB,CAAC,SAAS,EAAE,GAAG,CAAC,kBAAkB,CAAC,IAAI,SAAS,CAAC,CAAC;IAC1F,IAAI,CAAC,MAAM;QAAE,OAAO,IAAI,CAAC;IACzB,MAAM,KAAK,GAAG,MAAM,CAAC,KAAwC,CAAC;IAC9D,IAAI,OAAO,KAAK,CAAC,MAAM,KAAK,UAAU;QAAE,OAAO,IAAI,CAAC;IACpD,IAAI,EAAgB,CAAC;IACrB,IAAI,CAAC;QACD,EAAE,GAAG,MAAM,CAAC,GAAG,CAAC,MAAM,EAAkB,CAAC;IAC7C,CAAC;IAAC,MAAM,CAAC;QACL,OAAO,IAAI,CAAC;IAChB,CAAC;IACD,IAAI,OAAO,EAAE,EAAE,YAAY,KAAK,UAAU;QAAE,OAAO,IAAI,CAAC;IACxD,OAAO,cAAc,CAAC,CAAC,MAAM,EAAE,EAAE,CAC7B,EAAE,CAAC,YAAY,CAAC,MAAM,EAAE,MAAM,CAAC,KAAK,EAAE,EAAE,YAAY,EAAE,oBAAoB,EAAE,WAAW,EAAE,CAAC,EAAE,CAAC,CAChG,CAAC;AACN,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,eAAe,CAAC,OAAuB,EAAE;IACrD,MAAM,GAAG,GAAG,IAAI,CAAC,GAAG,IAAI,OAAO,CAAC,GAAG,CAAC;IACpC,IAAI,CAAC,GAAG,CAAC,cAAc,CAAC;QAAE,OAAO,IAAI,CAAC;IACtC,IAAI,KAAK,GAAuC,IAAI,CAAC;IACrD,OAAO;QACH,KAAK,CAAC,MAAM,CAAC,QAAgB;YACzB,KAAK,KAAK,iBAAiB,CAAC,EAAE,GAAG,EAAE,CAAC,CAAC;YACrC,MAAM,CAAC,GAAG,MAAM,KAAK,CAAC;YACtB,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC;QACzC,CAAC;KACJ,CAAC;AACN,CAAC"}
@@ -0,0 +1,47 @@
1
+ /**
2
+ * FactArchive — where a compacted fact's full original lives once its body is a stub.
3
+ *
4
+ * The archive is deliberately NOT a field on the stored entry: the store snapshot is
5
+ * rebuilt from the store on every write, rewritten in place by other processes, and
6
+ * capped/evicted at {@link DEFAULT_MAX_ENTRIES}; an archived original riding inside
7
+ * it would be lost to any one of those. A separate sidecar (`memory.archive.json`,
8
+ * see `defaultArchiveFile`) is only ever merged into, never pruned, so an evicted or
9
+ * forgotten stub still has its original.
10
+ *
11
+ * Two implementations, one contract: in-memory (a backend with no disk mirror) and
12
+ * file-backed (shared across processes through {@link SharedJsonFile}, with its
13
+ * rotating backups and freshness check).
14
+ */
15
+ import { type ArchivedFact } from "../compaction.js";
16
+ import { type SharedFileFs } from "./shared-json-file.js";
17
+ export interface FactArchive {
18
+ /** The archived original for `key`, if one exists. */
19
+ get(key: string): ArchivedFact | undefined;
20
+ /** Every row, read once — for callers resolving many keys in one pass. */
21
+ all(): Readonly<Record<string, ArchivedFact>>;
22
+ /** Add or replace archive rows. Durable before it returns. */
23
+ putMany(facts: ArchivedFact[]): void;
24
+ }
25
+ /** Process-local archive — the default for a backend with no disk mirror. */
26
+ export declare class MemoryFactArchive implements FactArchive {
27
+ private readonly rows;
28
+ get(key: string): ArchivedFact | undefined;
29
+ all(): Readonly<Record<string, ArchivedFact>>;
30
+ putMany(facts: ArchivedFact[]): void;
31
+ }
32
+ /**
33
+ * Archive mirrored to a JSON file several processes share. Re-reads the file when it
34
+ * changed underneath this process; every write merges into the latest on-disk text,
35
+ * so two writers add to one archive rather than overwriting each other's rows.
36
+ */
37
+ export declare class FileFactArchive implements FactArchive {
38
+ private rows;
39
+ private text;
40
+ private readonly file;
41
+ constructor(path: string, fs: SharedFileFs);
42
+ get(key: string): ArchivedFact | undefined;
43
+ all(): Readonly<Record<string, ArchivedFact>>;
44
+ putMany(facts: ArchivedFact[]): void;
45
+ private refresh;
46
+ }
47
+ //# sourceMappingURL=fact-archive.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"fact-archive.d.ts","sourceRoot":"","sources":["../../src/persistence/fact-archive.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAEH,OAAO,EAA8B,KAAK,YAAY,EAAE,MAAM,kBAAkB,CAAC;AACjF,OAAO,EAAkB,KAAK,YAAY,EAAE,MAAM,uBAAuB,CAAC;AAW1E,MAAM,WAAW,WAAW;IACxB,sDAAsD;IACtD,GAAG,CAAC,GAAG,EAAE,MAAM,GAAG,YAAY,GAAG,SAAS,CAAC;IAC3C,0EAA0E;IAC1E,GAAG,IAAI,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,YAAY,CAAC,CAAC,CAAC;IAC9C,8DAA8D;IAC9D,OAAO,CAAC,KAAK,EAAE,YAAY,EAAE,GAAG,IAAI,CAAC;CACxC;AAED,6EAA6E;AAC7E,qBAAa,iBAAkB,YAAW,WAAW;IACjD,OAAO,CAAC,QAAQ,CAAC,IAAI,CAAqF;IAE1G,GAAG,CAAC,GAAG,EAAE,MAAM,GAAG,YAAY,GAAG,SAAS;IAI1C,GAAG,IAAI,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,YAAY,CAAC,CAAC;IAI7C,OAAO,CAAC,KAAK,EAAE,YAAY,EAAE,GAAG,IAAI;CAGvC;AAED;;;;GAIG;AACH,qBAAa,eAAgB,YAAW,WAAW;IAC/C,OAAO,CAAC,IAAI,CAAoC;IAChD,OAAO,CAAC,IAAI,CAAuB;IACnC,OAAO,CAAC,QAAQ,CAAC,IAAI,CAAiB;gBAE1B,IAAI,EAAE,MAAM,EAAE,EAAE,EAAE,YAAY;IAK1C,GAAG,CAAC,GAAG,EAAE,MAAM,GAAG,YAAY,GAAG,SAAS;IAK1C,GAAG,IAAI,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,YAAY,CAAC,CAAC;IAK7C,OAAO,CAAC,KAAK,EAAE,YAAY,EAAE,GAAG,IAAI;IAepC,OAAO,CAAC,OAAO;CAOlB"}