dotmem 0.0.8 → 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/agent.cjs CHANGED
@@ -18,6 +18,18 @@ var __export = (target, all) => {
18
18
  __defProp(target, name, { get: all[name], enumerable: true });
19
19
  };
20
20
 
21
+ // suppress-idb-warning.ts
22
+ var orig;
23
+ var init_suppress_idb_warning = __esm({
24
+ "suppress-idb-warning.ts"() {
25
+ orig = console.warn.bind(console);
26
+ console.warn = (...args) => {
27
+ if (typeof args[0] === "string" && args[0].includes("IndexedDB is not available")) return;
28
+ orig(...args);
29
+ };
30
+ }
31
+ });
32
+
21
33
  // core/idb.ts
22
34
  var idb;
23
35
  var init_idb = __esm({
@@ -46,6 +58,7 @@ __export(global_exports, {
46
58
  var getPlatform;
47
59
  var init_global = __esm({
48
60
  "core/global.ts"() {
61
+ init_suppress_idb_warning();
49
62
  init_idb();
50
63
  getPlatform = /* @__PURE__ */ __name(() => {
51
64
  const proc = globalThis.process;
package/agent.js CHANGED
@@ -16,6 +16,18 @@ var __export = (target, all) => {
16
16
  __defProp(target, name, { get: all[name], enumerable: true });
17
17
  };
18
18
 
19
+ // suppress-idb-warning.ts
20
+ var orig;
21
+ var init_suppress_idb_warning = __esm({
22
+ "suppress-idb-warning.ts"() {
23
+ orig = console.warn.bind(console);
24
+ console.warn = (...args) => {
25
+ if (typeof args[0] === "string" && args[0].includes("IndexedDB is not available")) return;
26
+ orig(...args);
27
+ };
28
+ }
29
+ });
30
+
19
31
  // core/idb.ts
20
32
  var idb;
21
33
  var init_idb = __esm({
@@ -44,6 +56,7 @@ __export(global_exports, {
44
56
  var getPlatform;
45
57
  var init_global = __esm({
46
58
  "core/global.ts"() {
59
+ init_suppress_idb_warning();
47
60
  init_idb();
48
61
  getPlatform = /* @__PURE__ */ __name(() => {
49
62
  const proc = globalThis.process;
package/bin/cli.cjs CHANGED
@@ -9,6 +9,11 @@ function _interopDefault (e) { return e && e.__esModule ? e : { default: e }; }
9
9
 
10
10
  var process__default = /*#__PURE__*/_interopDefault(process);
11
11
 
12
+ var __origWarn = console.warn.bind(console);
13
+ console.warn = (...args2) => {
14
+ if (typeof args2[0] === "string" && args2[0].includes("IndexedDB is not available")) return;
15
+ __origWarn(...args2);
16
+ };
12
17
  var rawArgs = process__default.default.argv.slice(2);
13
18
  var storageRootFlagIndex = rawArgs.indexOf("--storage-root");
14
19
  var hasStorageRootFlag = storageRootFlagIndex !== -1;
package/bin/cli.js CHANGED
@@ -2,6 +2,11 @@
2
2
  import process from 'process';
3
3
  import { fileURLToPath } from 'url';
4
4
 
5
+ var __origWarn = console.warn.bind(console);
6
+ console.warn = (...args2) => {
7
+ if (typeof args2[0] === "string" && args2[0].includes("IndexedDB is not available")) return;
8
+ __origWarn(...args2);
9
+ };
5
10
  var rawArgs = process.argv.slice(2);
6
11
  var storageRootFlagIndex = rawArgs.indexOf("--storage-root");
7
12
  var hasStorageRootFlag = storageRootFlagIndex !== -1;
package/bin/mcp.cjs CHANGED
@@ -7,6 +7,11 @@ function _interopDefault (e) { return e && e.__esModule ? e : { default: e }; }
7
7
 
8
8
  var process__default = /*#__PURE__*/_interopDefault(process);
9
9
 
10
+ var __origWarn = console.warn.bind(console);
11
+ console.warn = (...args) => {
12
+ if (typeof args[0] === "string" && args[0].includes("IndexedDB is not available")) return;
13
+ __origWarn(...args);
14
+ };
10
15
  var nodeMajorVersion = Number.parseInt(process__default.default.versions.node.split(".")[0] ?? "", 10);
11
16
  if (!Number.isInteger(nodeMajorVersion) || nodeMajorVersion < 20) {
12
17
  console.error("dotmem-mcp requires Node.js >=20; the normal dotmem runtime remains compatible with its declared Node.js version.");
package/bin/mcp.js CHANGED
@@ -1,6 +1,11 @@
1
1
  #!/usr/bin/env node
2
2
  import process from 'process';
3
3
 
4
+ var __origWarn = console.warn.bind(console);
5
+ console.warn = (...args) => {
6
+ if (typeof args[0] === "string" && args[0].includes("IndexedDB is not available")) return;
7
+ __origWarn(...args);
8
+ };
4
9
  var nodeMajorVersion = Number.parseInt(process.versions.node.split(".")[0] ?? "", 10);
5
10
  if (!Number.isInteger(nodeMajorVersion) || nodeMajorVersion < 20) {
6
11
  console.error("dotmem-mcp requires Node.js >=20; the normal dotmem runtime remains compatible with its declared Node.js version.");
package/cli.cjs CHANGED
@@ -39,6 +39,18 @@ var __copyProps = (to, from, except, desc) => {
39
39
  };
40
40
  var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
41
41
 
42
+ // suppress-idb-warning.ts
43
+ var orig;
44
+ var init_suppress_idb_warning = __esm({
45
+ "suppress-idb-warning.ts"() {
46
+ orig = console.warn.bind(console);
47
+ console.warn = (...args) => {
48
+ if (typeof args[0] === "string" && args[0].includes("IndexedDB is not available")) return;
49
+ orig(...args);
50
+ };
51
+ }
52
+ });
53
+
42
54
  // core/env.ts
43
55
  var DEV;
44
56
  var init_env = __esm({
@@ -73,6 +85,7 @@ function configure(opts) {
73
85
  var g, STORE_PREFIX, INDEX_KEY, journal, journal_default;
74
86
  var init_journal = __esm({
75
87
  "core/memory/journal.ts"() {
88
+ init_suppress_idb_warning();
76
89
  init_env();
77
90
  g = globalThis;
78
91
  __name(namespace, "namespace");
@@ -2998,6 +3011,7 @@ var init_policy_store = __esm({
2998
3011
  if (entry.target !== void 0) built.target = entry.target;
2999
3012
  if (entry.reason !== void 0) built.reason = entry.reason;
3000
3013
  if (entry.detail !== void 0) built.detail = entry.detail;
3014
+ if (entry.mandatory !== void 0) built.mandatory = entry.mandatory;
3001
3015
  return built;
3002
3016
  }, "validatePolicyAuditEntry");
3003
3017
  validatePolicyDocument = /* @__PURE__ */ __name((value) => {
@@ -3075,6 +3089,7 @@ var init_policy_store = __esm({
3075
3089
  if (entry.target !== void 0) built.target = entry.target;
3076
3090
  if (entry.reason !== void 0) built.reason = entry.reason;
3077
3091
  if (entry.detail !== void 0) built.detail = entry.detail;
3092
+ if (entry.mandatory !== void 0) built.mandatory = entry.mandatory;
3078
3093
  return built;
3079
3094
  }, "buildAuditEntry");
3080
3095
  boundedAudit = /* @__PURE__ */ __name((entries2, overrides) => {
@@ -3087,9 +3102,10 @@ var init_policy_store = __esm({
3087
3102
  for (let index = entries2.length - 1; index >= 0; index--) {
3088
3103
  const entry = entries2[index];
3089
3104
  const activeLinked = entry.target !== void 0 && activeOverrideIds.has(entry.target) && (entry.action === "override" || entry.action === "revoke");
3090
- if (activeLinked || budget > 0) {
3105
+ const mandatory = entry.mandatory === true;
3106
+ if (activeLinked || mandatory || budget > 0) {
3091
3107
  kept.unshift(entry);
3092
- if (!activeLinked) budget--;
3108
+ if (!activeLinked && !mandatory) budget--;
3093
3109
  }
3094
3110
  }
3095
3111
  return kept;
@@ -3130,6 +3146,12 @@ var init_policy_store = __esm({
3130
3146
  try {
3131
3147
  await fs5.writeFile(temporary, `${JSON.stringify(document, null, 2)}
3132
3148
  `, "utf8");
3149
+ const handle = await fs5.open(temporary, "r+");
3150
+ try {
3151
+ await handle.sync();
3152
+ } finally {
3153
+ await handle.close();
3154
+ }
3133
3155
  await fs5.rename(temporary, filePath);
3134
3156
  } catch (error) {
3135
3157
  await fs5.rm(temporary, { force: true }).catch(() => void 0);
@@ -5263,7 +5285,7 @@ function encodeMemFile(stateValue, preserved) {
5263
5285
  function decodeMemDocument(value) {
5264
5286
  if (!value || typeof value !== "object" || Array.isArray(value)) throw new Error("Invalid .mem file format");
5265
5287
  const file = value;
5266
- if (file.format !== MEM_FORMAT) throw new Error("Invalid .mem file format");
5288
+ if (file.format !== MEM_FORMAT && file.format !== MEM_FORMAT_LEGACY) throw new Error("Invalid .mem file format");
5267
5289
  if (file.version === MEM_FORMAT_VERSION_V1) {
5268
5290
  if (!file.knowledge) throw new Error("Invalid .mem file format");
5269
5291
  return { state: validateSourceState(file.knowledge) };
@@ -5345,11 +5367,12 @@ function decodeMemDocument(value) {
5345
5367
  preserved: { map: structuredClone(map), data: structuredClone(stateRecord) }
5346
5368
  };
5347
5369
  }
5348
- var MEM_FORMAT, MEM_FORMAT_VERSION, MEM_FORMAT_VERSION_V1, expectedFields, epistemicTypes, revisionKinds, claimKinds, isJsonValue2, createMemInterpretationMap, validateSourceState, trimRecord, fieldIndexes, validateVocabulary, put, get, optionalGet, requireRecord, putOptional;
5370
+ var MEM_FORMAT, MEM_FORMAT_LEGACY, MEM_FORMAT_VERSION, MEM_FORMAT_VERSION_V1, expectedFields, epistemicTypes, revisionKinds, claimKinds, isJsonValue2, createMemInterpretationMap, validateSourceState, trimRecord, fieldIndexes, validateVocabulary, put, get, optionalGet, requireRecord, putOptional;
5349
5371
  var init_mem_codec = __esm({
5350
5372
  "core/knowledge/mem-codec.ts"() {
5351
5373
  init_state();
5352
5374
  MEM_FORMAT = "dotmem.knowledge";
5375
+ MEM_FORMAT_LEGACY = "memorio.knowledge";
5353
5376
  MEM_FORMAT_VERSION = 2;
5354
5377
  MEM_FORMAT_VERSION_V1 = 1;
5355
5378
  expectedFields = {
@@ -5498,12 +5521,13 @@ async function inspectMem(input) {
5498
5521
  return { status: artifactError.code, representation: "unknown", message: artifactError.message, parts: [] };
5499
5522
  }
5500
5523
  }
5501
- var MEM_PACKAGE_FORMAT, MEM_PACKAGE_VERSION, MEM_PACKAGE_LIMITS, MEM_PACKAGE_WRITE_MARGIN_BYTES, MEM_PACKAGE_WRITE_LIMITS, MANIFEST_PATH, MAP_PATH, DATA_PATH, INTEGRITY_PATH, requiredParts, encoder2, decoder, MemArtifactError, stableValue, jsonBytes, sha256, parseJson, validEntryPath, concatenate, readZipParts, createManifest, digestTableIdentity, signaturePayload, base64UrlDecode, keyIdentity, signaturePath, encodePackage, isZip, decodePackage, verifySignature;
5524
+ var MEM_PACKAGE_FORMAT, MEM_PACKAGE_FORMAT_LEGACY, MEM_PACKAGE_VERSION, MEM_PACKAGE_LIMITS, MEM_PACKAGE_WRITE_MARGIN_BYTES, MEM_PACKAGE_WRITE_LIMITS, MANIFEST_PATH, MAP_PATH, DATA_PATH, INTEGRITY_PATH, requiredParts, encoder2, decoder, MemArtifactError, stableValue, jsonBytes, sha256, parseJson, validEntryPath, concatenate, readZipParts, createManifest, digestTableIdentity, signaturePayload, base64UrlDecode, keyIdentity, signaturePath, encodePackage, isZip, decodePackage, verifySignature;
5502
5525
  var init_mem_package = __esm({
5503
5526
  "core/knowledge/mem-package.ts"() {
5504
5527
  init_browser();
5505
5528
  init_mem_codec();
5506
5529
  MEM_PACKAGE_FORMAT = "dotmem.package";
5530
+ MEM_PACKAGE_FORMAT_LEGACY = "memorio.package";
5507
5531
  MEM_PACKAGE_VERSION = 1;
5508
5532
  MEM_PACKAGE_LIMITS = Object.freeze({
5509
5533
  maximumPackageBytes: 10 * 1024 * 1024,
@@ -5688,10 +5712,10 @@ ${contentId}
5688
5712
  if (!parts[path3]) throw new MemArtifactError("invalid", `Missing MEM package part: ${path3}`);
5689
5713
  }
5690
5714
  const manifest = parseJson(parts[MANIFEST_PATH], MANIFEST_PATH);
5691
- if (manifest.format !== MEM_PACKAGE_FORMAT && manifest.format || manifest.version !== MEM_PACKAGE_VERSION) {
5715
+ if (manifest.format !== MEM_PACKAGE_FORMAT && manifest.format !== MEM_PACKAGE_FORMAT_LEGACY || manifest.version !== MEM_PACKAGE_VERSION) {
5692
5716
  throw new MemArtifactError("unsupported", "Unsupported MEM package format or version");
5693
5717
  }
5694
- if (manifest.memory?.format !== MEM_FORMAT && manifest.memory?.format || manifest.memory.version !== MEM_FORMAT_VERSION || manifest.parts?.map !== MAP_PATH || manifest.parts?.data !== DATA_PATH || manifest.parts?.integrity !== INTEGRITY_PATH) {
5718
+ if (manifest.memory?.format !== MEM_FORMAT && manifest.memory?.format !== MEM_FORMAT_LEGACY || manifest.memory.version !== MEM_FORMAT_VERSION || manifest.parts?.map !== MAP_PATH || manifest.parts?.data !== DATA_PATH || manifest.parts?.integrity !== INTEGRITY_PATH) {
5695
5719
  throw new MemArtifactError("invalid", "Invalid MEM package manifest");
5696
5720
  }
5697
5721
  const integrity = parseJson(parts[INTEGRITY_PATH], INTEGRITY_PATH);
@@ -5803,6 +5827,109 @@ ${contentId}
5803
5827
  }
5804
5828
  });
5805
5829
 
5830
+ // core/storage-coordinator/index.ts
5831
+ var nodeFs4, withStorageLock, readStorageGeneration, writeStorageGeneration;
5832
+ var init_storage_coordinator = __esm({
5833
+ "core/storage-coordinator/index.ts"() {
5834
+ nodeFs4 = /* @__PURE__ */ __name(async () => import('fs/promises'), "nodeFs");
5835
+ withStorageLock = /* @__PURE__ */ __name(async (directoryPath, operationOrOptions, operation, _options = {}) => {
5836
+ const opts = typeof operationOrOptions === "function" ? operation ?? {} : operationOrOptions ?? {};
5837
+ const op = typeof operationOrOptions === "function" ? operationOrOptions : operation;
5838
+ const timeoutMs = opts.timeoutMs ?? 3e4;
5839
+ const staleMs = opts.staleMs ?? 6e4;
5840
+ const lockName = opts.lockName ?? ".storage.lock";
5841
+ const lockPath = `${directoryPath}/${lockName}`;
5842
+ const fs5 = await nodeFs4();
5843
+ const started = Date.now();
5844
+ await fs5.mkdir(directoryPath, { recursive: true });
5845
+ while (true) {
5846
+ try {
5847
+ await fs5.mkdir(lockPath);
5848
+ const token2 = `${process.pid}-${Date.now()}-${Math.random().toString(36).slice(2)}`;
5849
+ await fs5.writeFile(`${lockPath}/owner.json`, JSON.stringify({ token: token2, pid: process.pid, createdAt: Date.now() }), { flag: "wx" });
5850
+ break;
5851
+ } catch (error) {
5852
+ const code = error.code;
5853
+ if (code !== "EEXIST" && code !== "ENOENT" && code !== "EPERM" && code !== "ENOTEMPTY") throw error;
5854
+ let stale = false;
5855
+ let processDead = false;
5856
+ try {
5857
+ const raw = await fs5.readFile(`${lockPath}/owner.json`, "utf8");
5858
+ const parsed = JSON.parse(raw);
5859
+ const ageStale = typeof parsed.createdAt === "number" && Date.now() - parsed.createdAt > staleMs;
5860
+ if (typeof parsed.pid === "number") {
5861
+ try {
5862
+ process.kill(parsed.pid, 0);
5863
+ } catch {
5864
+ processDead = true;
5865
+ }
5866
+ } else {
5867
+ processDead = true;
5868
+ }
5869
+ if (ageStale || processDead) stale = true;
5870
+ } catch {
5871
+ stale = true;
5872
+ }
5873
+ if (stale) {
5874
+ if (processDead) {
5875
+ try {
5876
+ await fs5.rm(lockPath, { recursive: true, force: true });
5877
+ continue;
5878
+ } catch {
5879
+ }
5880
+ }
5881
+ try {
5882
+ await fs5.rmdir(lockPath);
5883
+ continue;
5884
+ } catch {
5885
+ }
5886
+ }
5887
+ if (Date.now() - started > timeoutMs) {
5888
+ throw new Error(`Storage lock timeout for ${directoryPath}`);
5889
+ }
5890
+ await new Promise((resolve) => setTimeout(resolve, 25));
5891
+ }
5892
+ }
5893
+ let token = "";
5894
+ try {
5895
+ const raw = await fs5.readFile(`${lockPath}/owner.json`, "utf8");
5896
+ token = JSON.parse(raw).token ?? "";
5897
+ } catch {
5898
+ token = "";
5899
+ }
5900
+ try {
5901
+ return await op();
5902
+ } finally {
5903
+ try {
5904
+ const raw = await fs5.readFile(`${lockPath}/owner.json`, "utf8");
5905
+ const parsed = JSON.parse(raw);
5906
+ if (parsed.token === token && token) {
5907
+ await fs5.rm(lockPath, { recursive: true, force: true });
5908
+ }
5909
+ } catch {
5910
+ }
5911
+ }
5912
+ }, "withStorageLock");
5913
+ readStorageGeneration = /* @__PURE__ */ __name(async (directoryPath) => {
5914
+ const fs5 = await nodeFs4();
5915
+ try {
5916
+ const raw = await fs5.readFile(`${directoryPath}/.storage.generation`, "utf8");
5917
+ const value = Number(raw.trim());
5918
+ return Number.isFinite(value) && value >= 0 ? value : 0;
5919
+ } catch {
5920
+ return 0;
5921
+ }
5922
+ }, "readStorageGeneration");
5923
+ writeStorageGeneration = /* @__PURE__ */ __name(async (directoryPath, value) => {
5924
+ const fs5 = await nodeFs4();
5925
+ await fs5.mkdir(directoryPath, { recursive: true });
5926
+ const temp = `${directoryPath}/.storage.generation.${process.pid}.${Math.random().toString(36).slice(2)}.tmp`;
5927
+ await fs5.writeFile(temp, String(value));
5928
+ await fs5.rename(temp, `${directoryPath}/.storage.generation`);
5929
+ }, "writeStorageGeneration");
5930
+ }
5931
+ });
5932
+
5806
5933
  // core/knowledge/mem-repository.ts
5807
5934
  function resolveDuplicate(existing, existingSource, current, currentSource) {
5808
5935
  const existingRetracts = existing.revision?.kind === "retracts";
@@ -5843,19 +5970,20 @@ async function parseMemFile(value, sourceId) {
5843
5970
  throw new Error(`${message} in ${sourceId}`);
5844
5971
  }
5845
5972
  }
5846
- var DOTMEM_DIRECTORY, DEFAULT_MEM_FILE, directoryLocks, nodeFs4, separator2, normalizePath, isAbsolutePath, resolvePath, joinPath2, parentPath, uniqueSuffix, withDirectoryLock, isMissingDirectory, sourcePriority, memFilePath, MemDirectoryKnowledgeRepository;
5973
+ var DOTMEM_DIRECTORY, DEFAULT_MEM_FILE, nodeFs5, repositoryLoadCaches, separator2, normalizePath, isAbsolutePath, resolvePath, joinPath2, parentPath, uniqueSuffix, isMissingDirectory, sourcePriority, memFilePath, MemDirectoryKnowledgeRepository;
5847
5974
  var init_mem_repository = __esm({
5848
5975
  "core/knowledge/mem-repository.ts"() {
5849
5976
  init_mem_codec();
5850
5977
  init_mem_package();
5851
5978
  init_state();
5852
5979
  init_acquisition_limits();
5980
+ init_storage_coordinator();
5853
5981
  DOTMEM_DIRECTORY = ".dotmem";
5854
5982
  DEFAULT_MEM_FILE = "project.mem";
5855
- directoryLocks = /* @__PURE__ */ new Map();
5856
- nodeFs4 = /* @__PURE__ */ __name(async () => {
5983
+ nodeFs5 = /* @__PURE__ */ __name(async () => {
5857
5984
  return import('fs/promises');
5858
5985
  }, "nodeFs");
5986
+ repositoryLoadCaches = /* @__PURE__ */ new Map();
5859
5987
  separator2 = /* @__PURE__ */ __name(() => process.platform === "win32" ? "\\" : "/", "separator");
5860
5988
  normalizePath = /* @__PURE__ */ __name((value) => value.replace(/[\\/]+/g, separator2()), "normalizePath");
5861
5989
  isAbsolutePath = /* @__PURE__ */ __name((value) => /^(?:[A-Za-z]:[\\/]|[\\/])/.test(value), "isAbsolutePath");
@@ -5867,25 +5995,8 @@ var init_mem_repository = __esm({
5867
5995
  return index <= 0 ? "." : normalized.slice(0, index);
5868
5996
  }, "parentPath");
5869
5997
  uniqueSuffix = /* @__PURE__ */ __name(() => globalThis.crypto?.randomUUID?.() ?? `${Date.now().toString(36)}-${Math.random().toString(36).slice(2)}`, "uniqueSuffix");
5870
- withDirectoryLock = /* @__PURE__ */ __name(async (directoryPath, operation) => {
5871
- const previous = directoryLocks.get(directoryPath) ?? Promise.resolve();
5872
- let release = /* @__PURE__ */ __name(() => void 0, "release");
5873
- const gate = new Promise((resolveGate) => {
5874
- release = resolveGate;
5875
- });
5876
- const queued = previous.then(() => gate);
5877
- directoryLocks.set(directoryPath, queued);
5878
- await previous;
5879
- try {
5880
- return await operation();
5881
- } finally {
5882
- release();
5883
- if (directoryLocks.get(directoryPath) === queued) directoryLocks.delete(directoryPath);
5884
- }
5885
- }, "withDirectoryLock");
5886
5998
  isMissingDirectory = /* @__PURE__ */ __name((error) => error.code === "ENOENT", "isMissingDirectory");
5887
5999
  sourcePriority = /* @__PURE__ */ __name((sourceId, scope) => {
5888
- if (sourceId.endsWith(".mem") && sourceId !== "project.mem" && sourceId !== "user.mem" && sourceId !== "agent.mem") return 0;
5889
6000
  if (scope === "project" || sourceId === "project.mem") return 4;
5890
6001
  if (scope === "user" || sourceId === "user.mem") return 3;
5891
6002
  if (sourceId === "agent.mem" || sourceId === "agent") return 2;
@@ -5913,7 +6024,7 @@ var init_mem_repository = __esm({
5913
6024
  this.loadWritableOnly = loadWritableOnly;
5914
6025
  }
5915
6026
  async discover() {
5916
- const { readdir } = await nodeFs4();
6027
+ const { readdir } = await nodeFs5();
5917
6028
  try {
5918
6029
  const entries2 = await readdir(this.directoryPath, { withFileTypes: true });
5919
6030
  return entries2.filter((entry) => entry.isFile() && entry.name.endsWith(".mem") && entry.name !== "@brain.mem").map((entry) => entry.name).sort((a, b) => a.localeCompare(b));
@@ -5928,7 +6039,7 @@ var init_mem_repository = __esm({
5928
6039
  * receive a clear failure instead of discovering corruption on first use.
5929
6040
  */
5930
6041
  async initialize() {
5931
- const { mkdir } = await nodeFs4();
6042
+ const { mkdir } = await nodeFs5();
5932
6043
  await mkdir(this.directoryPath, { recursive: true });
5933
6044
  await this.load();
5934
6045
  }
@@ -5943,7 +6054,7 @@ var init_mem_repository = __esm({
5943
6054
  * that does not delete is not a delete.
5944
6055
  */
5945
6056
  async clearWritable() {
5946
- const { rm, readdir } = await nodeFs4();
6057
+ const { rm, readdir } = await nodeFs5();
5947
6058
  const filePath = memFilePath(this.directoryPath, this.writableSourceId);
5948
6059
  await rm(filePath, { force: true });
5949
6060
  await rm(`${filePath}.bak`, { force: true });
@@ -5960,15 +6071,28 @@ var init_mem_repository = __esm({
5960
6071
  }
5961
6072
  }
5962
6073
  async load() {
5963
- const loaded = this.loadWritableOnly ? await this.loadSources([this.writableSourceId]) : await this.loadSources();
5964
- return this.combine(loaded);
6074
+ const cacheKey = `${this.directoryPath}:${this.writableSourceId}:${this.loadWritableOnly}`;
6075
+ for (let attempt = 0; attempt < 5; attempt += 1) {
6076
+ const generationBefore = await readStorageGeneration(this.directoryPath);
6077
+ const cached = repositoryLoadCaches.get(cacheKey);
6078
+ if (cached && cached.signature === String(generationBefore)) {
6079
+ return structuredClone(cached.state);
6080
+ }
6081
+ const loaded = this.loadWritableOnly ? await this.loadSources([this.writableSourceId]) : await this.loadSources();
6082
+ const state2 = this.combine(loaded);
6083
+ const generationAfter = await readStorageGeneration(this.directoryPath);
6084
+ if (generationBefore !== generationAfter && attempt < 4) continue;
6085
+ repositoryLoadCaches.set(cacheKey, { signature: String(generationAfter), state: structuredClone(state2) });
6086
+ return state2;
6087
+ }
6088
+ throw new Error("Unable to load stable repository state");
5965
6089
  }
5966
- async save(state2, expectedVersion) {
6090
+ async save(state2, expectedVersion, locked = false) {
5967
6091
  const validated = validateKnowledgeState(state2);
5968
6092
  if (!Number.isInteger(expectedVersion) || expectedVersion < 0 || validated.version !== expectedVersion + 1) {
5969
6093
  throw new Error("Invalid expected persisted version");
5970
6094
  }
5971
- await withDirectoryLock(this.directoryPath, async () => {
6095
+ const doWrite = /* @__PURE__ */ __name(async () => {
5972
6096
  const loaded = await this.loadSources();
5973
6097
  const writable = loaded.find((source) => source.id === this.writableSourceId) ?? {
5974
6098
  id: this.writableSourceId,
@@ -5990,10 +6114,16 @@ var init_mem_repository = __esm({
5990
6114
  claims: [...writable.state.claims, ...newClaims]
5991
6115
  };
5992
6116
  await this.writeSource(writable.filePath, nextWritable, writable.preserved, writable.package);
5993
- });
6117
+ await writeStorageGeneration(this.directoryPath, await readStorageGeneration(this.directoryPath) + 1);
6118
+ }, "doWrite");
6119
+ if (locked) {
6120
+ await doWrite();
6121
+ } else {
6122
+ await withStorageLock(this.directoryPath, doWrite);
6123
+ }
5994
6124
  }
5995
6125
  async loadSources(sourceIds) {
5996
- const { readFile: readFile8 } = await nodeFs4();
6126
+ const { readFile: readFile8 } = await nodeFs5();
5997
6127
  const ids = sourceIds ?? await this.discover();
5998
6128
  const sources = [];
5999
6129
  for (const sourceId of ids) {
@@ -6083,7 +6213,7 @@ var init_mem_repository = __esm({
6083
6213
  * valid package, so the backup is always a version this library can read.
6084
6214
  */
6085
6215
  async keepLastValidVersion(filePath) {
6086
- const { readFile: readFile8, copyFile, rename, rm } = await nodeFs4();
6216
+ const { readFile: readFile8, copyFile, rename, rm } = await nodeFs5();
6087
6217
  let current;
6088
6218
  try {
6089
6219
  current = await readFile8(filePath);
@@ -6107,7 +6237,7 @@ var init_mem_repository = __esm({
6107
6237
  }
6108
6238
  /** Best-effort directory sync: the rename is durable once the directory is. */
6109
6239
  async syncDirectory(directoryPath) {
6110
- const { open } = await nodeFs4();
6240
+ const { open } = await nodeFs5();
6111
6241
  try {
6112
6242
  const handle = await open(directoryPath, "r");
6113
6243
  try {
@@ -6119,7 +6249,7 @@ var init_mem_repository = __esm({
6119
6249
  }
6120
6250
  }
6121
6251
  async writeSource(filePath, state2, preserved, preservedPackage) {
6122
- const { mkdir, rename, rm, open, readFile: readFile8 } = await nodeFs4();
6252
+ const { mkdir, rename, rm, open, readFile: readFile8 } = await nodeFs5();
6123
6253
  if (!Number.isInteger(state2.version) || state2.version < 0) throw new Error("Invalid writable .mem knowledge version");
6124
6254
  for (const claim of state2.claims) validateClaim(claim);
6125
6255
  await mkdir(parentPath(filePath), { recursive: true });
@@ -6989,7 +7119,7 @@ var init_project_identity = __esm({
6989
7119
  });
6990
7120
 
6991
7121
  // core/knowledge/staging.ts
6992
- var DOTMEM_STAGE_FORMAT, DOTMEM_STAGE_VERSION, StageFileError, generateRequestId, nodeCwd, resolveStagingDirectory, stagePathFor, nodeFs5, normalizeClaimIds, revisionFromOptions, writeStageFile, readStageFile, validateStageFile, commitStageFile, cleanupStageFile;
7122
+ var DOTMEM_STAGE_FORMAT, DOTMEM_STAGE_VERSION, StageFileError, generateRequestId, nodeCwd, resolveStagingDirectory, stagePathFor, nodeFs6, normalizeClaimIds, revisionFromOptions, writeStageFile, readStageFile, validateStageFile, commitStageFile, cleanupStageFile;
6993
7123
  var init_staging = __esm({
6994
7124
  "core/knowledge/staging.ts"() {
6995
7125
  init_claim_record();
@@ -7024,7 +7154,7 @@ var init_staging = __esm({
7024
7154
  return `${base}/dotmem`;
7025
7155
  }, "resolveStagingDirectory");
7026
7156
  stagePathFor = /* @__PURE__ */ __name((requestId) => `${resolveStagingDirectory()}/${requestId}.stage`, "stagePathFor");
7027
- nodeFs5 = /* @__PURE__ */ __name(async () => import('fs/promises'), "nodeFs");
7157
+ nodeFs6 = /* @__PURE__ */ __name(async () => import('fs/promises'), "nodeFs");
7028
7158
  normalizeClaimIds = /* @__PURE__ */ __name((value) => {
7029
7159
  if (!value) return [];
7030
7160
  return Array.isArray(value) ? value : [value];
@@ -7049,7 +7179,7 @@ var init_staging = __esm({
7049
7179
  };
7050
7180
  const requestId = generateRequestId();
7051
7181
  const stagePath = stagePathFor(requestId);
7052
- const fs5 = await nodeFs5();
7182
+ const fs5 = await nodeFs6();
7053
7183
  await fs5.mkdir(resolveStagingDirectory(), { recursive: true });
7054
7184
  const stageFile = {
7055
7185
  format: DOTMEM_STAGE_FORMAT,
@@ -7069,7 +7199,7 @@ var init_staging = __esm({
7069
7199
  }, "writeStageFile");
7070
7200
  readStageFile = /* @__PURE__ */ __name(async (requestId) => {
7071
7201
  const stagePath = stagePathFor(requestId);
7072
- const fs5 = await nodeFs5();
7202
+ const fs5 = await nodeFs6();
7073
7203
  try {
7074
7204
  const content = await fs5.readFile(stagePath, "utf8");
7075
7205
  return JSON.parse(content);
@@ -7180,7 +7310,7 @@ var init_staging = __esm({
7180
7310
  }, "commitStageFile");
7181
7311
  cleanupStageFile = /* @__PURE__ */ __name(async (requestId) => {
7182
7312
  const stagePath = stagePathFor(requestId);
7183
- const fs5 = await nodeFs5();
7313
+ const fs5 = await nodeFs6();
7184
7314
  try {
7185
7315
  await fs5.unlink(stagePath);
7186
7316
  } catch (error) {
@@ -8958,6 +9088,7 @@ function _inferConfidence(claim) {
8958
9088
  var LOGIC_MEM_FILE, nodeCwd2, cachedRuntime, LogicEngine, logic, logic_default;
8959
9089
  var init_logic = __esm({
8960
9090
  "core/logic/index.ts"() {
9091
+ init_suppress_idb_warning();
8961
9092
  init_knowledge();
8962
9093
  init_mem_repository();
8963
9094
  init_acquisition_boundary();
@@ -9351,6 +9482,7 @@ async function resetKnowledgeRuntimeCaches() {
9351
9482
  var EmptyLogicRepository, KNOWLEDGE_STATE_KEY, knowledgeSaveQueue, StoreKnowledgeRepository, RuntimeSlot, projectSlot, userSlot, installDotMemReadme;
9352
9483
  var init_knowledge_runtime = __esm({
9353
9484
  "core/memory/knowledge-runtime.ts"() {
9485
+ init_suppress_idb_warning();
9354
9486
  init_knowledge();
9355
9487
  init_project_identity();
9356
9488
  init_user_paths();
@@ -9883,6 +10015,7 @@ async function getEntry(key) {
9883
10015
  var MEMORY_INDEX_KEY, SUPERSEDED_PREFIX, entries;
9884
10016
  var init_entries = __esm({
9885
10017
  "core/memory/entries.ts"() {
10018
+ init_suppress_idb_warning();
9886
10019
  init_env();
9887
10020
  init_journal();
9888
10021
  MEMORY_INDEX_KEY = "__dotmem_memory_index__";
@@ -10235,15 +10368,18 @@ async function findClaimAcrossAllSources(claimId, scope, sourceProject) {
10235
10368
  var acquire;
10236
10369
  var init_acquire = __esm({
10237
10370
  "core/memory/acquire.ts"() {
10371
+ init_suppress_idb_warning();
10238
10372
  init_env();
10239
10373
  init_project_identity();
10240
10374
  init_project_anchor();
10241
10375
  init_acquisition_boundary();
10242
10376
  init_claim_record();
10377
+ init_state();
10243
10378
  init_router();
10244
10379
  init_store_queue();
10245
10380
  init_staging();
10246
10381
  init_user_paths();
10382
+ init_storage_coordinator();
10247
10383
  init_mem_repository();
10248
10384
  init_knowledge_runtime();
10249
10385
  __name(normalizeClaimIds3, "normalizeClaimIds");
@@ -10279,23 +10415,27 @@ var init_acquire = __esm({
10279
10415
  );
10280
10416
  }
10281
10417
  const revision = revisionFromAcquire2(opts);
10418
+ const repository = target.repository;
10282
10419
  await withStoreQueue(acquisitionStoreKey(kind, scope, sourceProject), async () => {
10283
- const state2 = await target.runtime.select([]);
10284
- await target.runtime.update({
10285
- basedOnVersion: state2.context.knowledgeVersion,
10286
- claims: [buildClaimRecord({
10287
- id: opts.id,
10288
- knowledge: boundary.knowledge,
10289
- applicability: opts.applicability,
10290
- evidence: opts.evidence,
10291
- epistemicType: opts.epistemicType,
10292
- provenance: opts.provenance,
10293
- acquiredAt: opts.acquiredAt,
10294
- revision,
10295
- scope,
10296
- sourceProject,
10297
- kind
10298
- })]
10420
+ await withStorageLock(repository.directoryPath, async () => {
10421
+ const state2 = await repository.load();
10422
+ const next = updateKnowledge(state2, {
10423
+ basedOnVersion: state2.version,
10424
+ claims: [buildClaimRecord({
10425
+ id: opts.id,
10426
+ knowledge: boundary.knowledge,
10427
+ applicability: opts.applicability,
10428
+ evidence: opts.evidence,
10429
+ epistemicType: opts.epistemicType,
10430
+ provenance: opts.provenance,
10431
+ acquiredAt: opts.acquiredAt,
10432
+ revision,
10433
+ scope,
10434
+ sourceProject,
10435
+ kind
10436
+ })]
10437
+ });
10438
+ await repository.save(next, state2.version, true);
10299
10439
  });
10300
10440
  });
10301
10441
  const verification = await target.repository.load();
@@ -11827,6 +11967,7 @@ async function bootstrapProject() {
11827
11967
  var pendingDetectionEvents, detectionFlushScheduled, flushDetectionEvents; exports.memory = void 0;
11828
11968
  var init_memory = __esm({
11829
11969
  "core/memory/index.ts"() {
11970
+ init_suppress_idb_warning();
11830
11971
  init_journal();
11831
11972
  init_brain();
11832
11973
  init_knowledge_runtime();
@@ -12733,6 +12874,7 @@ var init_policy3 = __esm({
12733
12874
  });
12734
12875
 
12735
12876
  // core/cli/index.ts
12877
+ init_suppress_idb_warning();
12736
12878
  init_memory();
12737
12879
 
12738
12880
  // core/continuity/freshness.ts
@@ -12965,6 +13107,10 @@ var saveContinuityDocument = /* @__PURE__ */ __name(async (path3, document) => {
12965
13107
  }
12966
13108
  }, "saveContinuityDocument");
12967
13109
 
13110
+ // core/continuity-ledger/index.ts
13111
+ init_memory();
13112
+ init_memory();
13113
+
12968
13114
  // core/continuity/index.ts
12969
13115
  var continuity = {
12970
13116
  async context(options) {
@@ -14109,7 +14255,7 @@ Run \`npx dotmem <command> --help\` for command-specific options.
14109
14255
  Memory:
14110
14256
  context "<situation>" [--explain] [--json] [--full] [--claims-only] [--limit <N>] [--format brief]
14111
14257
  project acquired experience for a situation
14112
- init initialize dotmem for the current project (.mem/)
14258
+ init initialize dotmem for the current project (.dotmem/)
14113
14259
  acquire acquire durable experience from a JSON claim on stdin
14114
14260
  learn "<text>" [--scope <user|project>] [--situation "<text>"] [--id "<id>"]
14115
14261
  acquire a claim from plain text (shorthand for acquire)