@seanhogg/builderforce-memory-mcp 2026.10.3 → 2026.10.23

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 +99 -13
  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 +102 -13
  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,CAqPjE;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
  );
@@ -145,26 +194,52 @@ if (mode === "--capture") {
145
194
  const msgs = [];
146
195
  for (const ln of raw.split("\\n")) { if (ln.trim()) { try { msgs.push(JSON.parse(ln)); } catch { /* partial */ } } }
147
196
 
197
+ // The harness also writes user-role entries the person never typed. A subagent
198
+ // hand-back or a background-task notification is a whole entry of harness text, so
199
+ // when the newest one is that, there is no human instruction to capture. Reminders
200
+ // and IDE/slash-command echoes ride inside a real message, so they are cut out of it.
201
+ const HARNESS_ENTRY_TAGS = ["agent-message", "task-notification"];
202
+ const INJECTED_BLOCK_TAGS = [
203
+ "system-reminder", "ide_opened_file", "ide_selection", "local-command-caveat",
204
+ "local-command-stdout", "command-name", "command-message", "command-args",
205
+ ];
206
+ const stripBlocks = (txt) => {
207
+ let out = txt;
208
+ for (const tag of INJECTED_BLOCK_TAGS) {
209
+ for (;;) {
210
+ const start = out.indexOf("<" + tag);
211
+ if (start < 0) break;
212
+ const close = out.indexOf("</" + tag + ">", start);
213
+ out = out.slice(0, start) + (close < 0 ? "" : out.slice(close + tag.length + 3));
214
+ }
215
+ }
216
+ return out.trim();
217
+ };
218
+
148
219
  let lastUserText = "";
220
+ let sawUser = false;
149
221
  let rememberedThisTurn = false;
150
- for (let i = msgs.length - 1; i >= 0; i--) {
222
+ for (let i = msgs.length - 1; i >= 0 && !sawUser; i--) {
151
223
  const m = msgs[i] || {};
152
224
  const inner = m.message || m;
153
225
  const role = inner.role;
154
226
  const content = inner.content;
155
- if (role === "assistant" && !lastUserText) {
227
+ if (role === "assistant") {
156
228
  if (Array.isArray(content)) for (const c of content) {
157
229
  if (c && c.type === "tool_use" && typeof c.name === "string" && c.name.includes("memory_remember")) rememberedThisTurn = true;
158
230
  }
159
231
  }
160
- if (role === "user" && !lastUserText) {
232
+ if (role === "user") {
161
233
  let txt = "";
162
234
  if (typeof content === "string") txt = content;
163
235
  else if (Array.isArray(content)) for (const c of content) {
164
236
  if (typeof c === "string") txt += c + " ";
165
237
  else if (c && c.type === "text" && typeof c.text === "string") txt += c.text + " ";
166
238
  }
167
- if (txt.trim()) lastUserText = txt;
239
+ if (!txt.trim()) continue; // a tool result, not a turn
240
+ sawUser = true;
241
+ if (m.isMeta || HARNESS_ENTRY_TAGS.some((tag) => txt.includes("<" + tag))) break;
242
+ lastUserText = stripBlocks(txt);
168
243
  }
169
244
  }
170
245
  if (!lastUserText || rememberedThisTurn) process.exit(0);
@@ -207,7 +282,11 @@ if (entries.length === 0) {
207
282
  process.exit(0);
208
283
  }
209
284
  const ranked = entries
210
- .map((e) => ({ key: e.key, content: String(e.content ?? ""), importance: typeof e.importance === "number" ? e.importance : 0.5 }))
285
+ .map((e) => {
286
+ const importance = typeof e.importance === "number" ? e.importance : 0.5;
287
+ // Lost content is importance-demoted so intact memories lead the digest.
288
+ return { key: e.key, content: String(e.content ?? ""), importance: isLost(e) ? importance * LOST_DEMOTION : importance };
289
+ })
211
290
  .sort((a, b) => b.importance - a.importance)
212
291
  .slice(0, 6);
213
292
 
@@ -218,7 +297,7 @@ for (const e of ranked) led.add(e.key);
218
297
  saveLedger(sessionId, led);
219
298
 
220
299
  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");
300
+ const top = ranked.map((e) => render(e, 180)).join("\\n");
222
301
  process.stdout.write(
223
302
  "[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
303
  );
@@ -245,6 +324,13 @@ capture that won't let a durable correction go unrecorded.
245
324
  - \`memory_recall_by_tag(tag)\` — everything under a tag.
246
325
  - \`memory_remember(key, content, [tags], [importance])\` — store ONE durable fact.
247
326
  - \`memory_forget(key)\` — drop a superseded fact.
327
+ - \`memory_compact(keys)\` — stub facts the local Evermind has absorbed (proven by a
328
+ recall probe; the original is archived, so recall still returns it).
329
+ - \`memory_restore(file|json)\` — bring back the text of memories marked
330
+ "${CONTENT_LOST_LABEL}" from an export.
331
+
332
+ A memory labelled "${CONTENT_LOST_LABEL}" is a one-line pointer whose full
333
+ text is gone: treat it as a lead, verify it before acting on it.
248
334
 
249
335
  ## Discipline
250
336
  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"}