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/cli.js CHANGED
@@ -30,6 +30,18 @@ var __copyProps = (to, from, except, desc) => {
30
30
  };
31
31
  var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
32
32
 
33
+ // suppress-idb-warning.ts
34
+ var orig;
35
+ var init_suppress_idb_warning = __esm({
36
+ "suppress-idb-warning.ts"() {
37
+ orig = console.warn.bind(console);
38
+ console.warn = (...args) => {
39
+ if (typeof args[0] === "string" && args[0].includes("IndexedDB is not available")) return;
40
+ orig(...args);
41
+ };
42
+ }
43
+ });
44
+
33
45
  // core/env.ts
34
46
  var DEV;
35
47
  var init_env = __esm({
@@ -64,6 +76,7 @@ function configure(opts) {
64
76
  var g, STORE_PREFIX, INDEX_KEY, journal, journal_default;
65
77
  var init_journal = __esm({
66
78
  "core/memory/journal.ts"() {
79
+ init_suppress_idb_warning();
67
80
  init_env();
68
81
  g = globalThis;
69
82
  __name(namespace, "namespace");
@@ -2989,6 +3002,7 @@ var init_policy_store = __esm({
2989
3002
  if (entry.target !== void 0) built.target = entry.target;
2990
3003
  if (entry.reason !== void 0) built.reason = entry.reason;
2991
3004
  if (entry.detail !== void 0) built.detail = entry.detail;
3005
+ if (entry.mandatory !== void 0) built.mandatory = entry.mandatory;
2992
3006
  return built;
2993
3007
  }, "validatePolicyAuditEntry");
2994
3008
  validatePolicyDocument = /* @__PURE__ */ __name((value) => {
@@ -3066,6 +3080,7 @@ var init_policy_store = __esm({
3066
3080
  if (entry.target !== void 0) built.target = entry.target;
3067
3081
  if (entry.reason !== void 0) built.reason = entry.reason;
3068
3082
  if (entry.detail !== void 0) built.detail = entry.detail;
3083
+ if (entry.mandatory !== void 0) built.mandatory = entry.mandatory;
3069
3084
  return built;
3070
3085
  }, "buildAuditEntry");
3071
3086
  boundedAudit = /* @__PURE__ */ __name((entries2, overrides) => {
@@ -3078,9 +3093,10 @@ var init_policy_store = __esm({
3078
3093
  for (let index = entries2.length - 1; index >= 0; index--) {
3079
3094
  const entry = entries2[index];
3080
3095
  const activeLinked = entry.target !== void 0 && activeOverrideIds.has(entry.target) && (entry.action === "override" || entry.action === "revoke");
3081
- if (activeLinked || budget > 0) {
3096
+ const mandatory = entry.mandatory === true;
3097
+ if (activeLinked || mandatory || budget > 0) {
3082
3098
  kept.unshift(entry);
3083
- if (!activeLinked) budget--;
3099
+ if (!activeLinked && !mandatory) budget--;
3084
3100
  }
3085
3101
  }
3086
3102
  return kept;
@@ -3121,6 +3137,12 @@ var init_policy_store = __esm({
3121
3137
  try {
3122
3138
  await fs5.writeFile(temporary, `${JSON.stringify(document, null, 2)}
3123
3139
  `, "utf8");
3140
+ const handle = await fs5.open(temporary, "r+");
3141
+ try {
3142
+ await handle.sync();
3143
+ } finally {
3144
+ await handle.close();
3145
+ }
3124
3146
  await fs5.rename(temporary, filePath);
3125
3147
  } catch (error) {
3126
3148
  await fs5.rm(temporary, { force: true }).catch(() => void 0);
@@ -5254,7 +5276,7 @@ function encodeMemFile(stateValue, preserved) {
5254
5276
  function decodeMemDocument(value) {
5255
5277
  if (!value || typeof value !== "object" || Array.isArray(value)) throw new Error("Invalid .mem file format");
5256
5278
  const file = value;
5257
- if (file.format !== MEM_FORMAT) throw new Error("Invalid .mem file format");
5279
+ if (file.format !== MEM_FORMAT && file.format !== MEM_FORMAT_LEGACY) throw new Error("Invalid .mem file format");
5258
5280
  if (file.version === MEM_FORMAT_VERSION_V1) {
5259
5281
  if (!file.knowledge) throw new Error("Invalid .mem file format");
5260
5282
  return { state: validateSourceState(file.knowledge) };
@@ -5336,11 +5358,12 @@ function decodeMemDocument(value) {
5336
5358
  preserved: { map: structuredClone(map), data: structuredClone(stateRecord) }
5337
5359
  };
5338
5360
  }
5339
- 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;
5361
+ 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;
5340
5362
  var init_mem_codec = __esm({
5341
5363
  "core/knowledge/mem-codec.ts"() {
5342
5364
  init_state();
5343
5365
  MEM_FORMAT = "dotmem.knowledge";
5366
+ MEM_FORMAT_LEGACY = "memorio.knowledge";
5344
5367
  MEM_FORMAT_VERSION = 2;
5345
5368
  MEM_FORMAT_VERSION_V1 = 1;
5346
5369
  expectedFields = {
@@ -5489,12 +5512,13 @@ async function inspectMem(input) {
5489
5512
  return { status: artifactError.code, representation: "unknown", message: artifactError.message, parts: [] };
5490
5513
  }
5491
5514
  }
5492
- 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;
5515
+ 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;
5493
5516
  var init_mem_package = __esm({
5494
5517
  "core/knowledge/mem-package.ts"() {
5495
5518
  init_browser();
5496
5519
  init_mem_codec();
5497
5520
  MEM_PACKAGE_FORMAT = "dotmem.package";
5521
+ MEM_PACKAGE_FORMAT_LEGACY = "memorio.package";
5498
5522
  MEM_PACKAGE_VERSION = 1;
5499
5523
  MEM_PACKAGE_LIMITS = Object.freeze({
5500
5524
  maximumPackageBytes: 10 * 1024 * 1024,
@@ -5679,10 +5703,10 @@ ${contentId}
5679
5703
  if (!parts[path3]) throw new MemArtifactError("invalid", `Missing MEM package part: ${path3}`);
5680
5704
  }
5681
5705
  const manifest = parseJson(parts[MANIFEST_PATH], MANIFEST_PATH);
5682
- if (manifest.format !== MEM_PACKAGE_FORMAT && manifest.format || manifest.version !== MEM_PACKAGE_VERSION) {
5706
+ if (manifest.format !== MEM_PACKAGE_FORMAT && manifest.format !== MEM_PACKAGE_FORMAT_LEGACY || manifest.version !== MEM_PACKAGE_VERSION) {
5683
5707
  throw new MemArtifactError("unsupported", "Unsupported MEM package format or version");
5684
5708
  }
5685
- 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) {
5709
+ 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) {
5686
5710
  throw new MemArtifactError("invalid", "Invalid MEM package manifest");
5687
5711
  }
5688
5712
  const integrity = parseJson(parts[INTEGRITY_PATH], INTEGRITY_PATH);
@@ -5794,6 +5818,109 @@ ${contentId}
5794
5818
  }
5795
5819
  });
5796
5820
 
5821
+ // core/storage-coordinator/index.ts
5822
+ var nodeFs4, withStorageLock, readStorageGeneration, writeStorageGeneration;
5823
+ var init_storage_coordinator = __esm({
5824
+ "core/storage-coordinator/index.ts"() {
5825
+ nodeFs4 = /* @__PURE__ */ __name(async () => import('fs/promises'), "nodeFs");
5826
+ withStorageLock = /* @__PURE__ */ __name(async (directoryPath, operationOrOptions, operation, _options = {}) => {
5827
+ const opts = typeof operationOrOptions === "function" ? operation ?? {} : operationOrOptions ?? {};
5828
+ const op = typeof operationOrOptions === "function" ? operationOrOptions : operation;
5829
+ const timeoutMs = opts.timeoutMs ?? 3e4;
5830
+ const staleMs = opts.staleMs ?? 6e4;
5831
+ const lockName = opts.lockName ?? ".storage.lock";
5832
+ const lockPath = `${directoryPath}/${lockName}`;
5833
+ const fs5 = await nodeFs4();
5834
+ const started = Date.now();
5835
+ await fs5.mkdir(directoryPath, { recursive: true });
5836
+ while (true) {
5837
+ try {
5838
+ await fs5.mkdir(lockPath);
5839
+ const token2 = `${process.pid}-${Date.now()}-${Math.random().toString(36).slice(2)}`;
5840
+ await fs5.writeFile(`${lockPath}/owner.json`, JSON.stringify({ token: token2, pid: process.pid, createdAt: Date.now() }), { flag: "wx" });
5841
+ break;
5842
+ } catch (error) {
5843
+ const code = error.code;
5844
+ if (code !== "EEXIST" && code !== "ENOENT" && code !== "EPERM" && code !== "ENOTEMPTY") throw error;
5845
+ let stale = false;
5846
+ let processDead = false;
5847
+ try {
5848
+ const raw = await fs5.readFile(`${lockPath}/owner.json`, "utf8");
5849
+ const parsed = JSON.parse(raw);
5850
+ const ageStale = typeof parsed.createdAt === "number" && Date.now() - parsed.createdAt > staleMs;
5851
+ if (typeof parsed.pid === "number") {
5852
+ try {
5853
+ process.kill(parsed.pid, 0);
5854
+ } catch {
5855
+ processDead = true;
5856
+ }
5857
+ } else {
5858
+ processDead = true;
5859
+ }
5860
+ if (ageStale || processDead) stale = true;
5861
+ } catch {
5862
+ stale = true;
5863
+ }
5864
+ if (stale) {
5865
+ if (processDead) {
5866
+ try {
5867
+ await fs5.rm(lockPath, { recursive: true, force: true });
5868
+ continue;
5869
+ } catch {
5870
+ }
5871
+ }
5872
+ try {
5873
+ await fs5.rmdir(lockPath);
5874
+ continue;
5875
+ } catch {
5876
+ }
5877
+ }
5878
+ if (Date.now() - started > timeoutMs) {
5879
+ throw new Error(`Storage lock timeout for ${directoryPath}`);
5880
+ }
5881
+ await new Promise((resolve) => setTimeout(resolve, 25));
5882
+ }
5883
+ }
5884
+ let token = "";
5885
+ try {
5886
+ const raw = await fs5.readFile(`${lockPath}/owner.json`, "utf8");
5887
+ token = JSON.parse(raw).token ?? "";
5888
+ } catch {
5889
+ token = "";
5890
+ }
5891
+ try {
5892
+ return await op();
5893
+ } finally {
5894
+ try {
5895
+ const raw = await fs5.readFile(`${lockPath}/owner.json`, "utf8");
5896
+ const parsed = JSON.parse(raw);
5897
+ if (parsed.token === token && token) {
5898
+ await fs5.rm(lockPath, { recursive: true, force: true });
5899
+ }
5900
+ } catch {
5901
+ }
5902
+ }
5903
+ }, "withStorageLock");
5904
+ readStorageGeneration = /* @__PURE__ */ __name(async (directoryPath) => {
5905
+ const fs5 = await nodeFs4();
5906
+ try {
5907
+ const raw = await fs5.readFile(`${directoryPath}/.storage.generation`, "utf8");
5908
+ const value = Number(raw.trim());
5909
+ return Number.isFinite(value) && value >= 0 ? value : 0;
5910
+ } catch {
5911
+ return 0;
5912
+ }
5913
+ }, "readStorageGeneration");
5914
+ writeStorageGeneration = /* @__PURE__ */ __name(async (directoryPath, value) => {
5915
+ const fs5 = await nodeFs4();
5916
+ await fs5.mkdir(directoryPath, { recursive: true });
5917
+ const temp = `${directoryPath}/.storage.generation.${process.pid}.${Math.random().toString(36).slice(2)}.tmp`;
5918
+ await fs5.writeFile(temp, String(value));
5919
+ await fs5.rename(temp, `${directoryPath}/.storage.generation`);
5920
+ }, "writeStorageGeneration");
5921
+ }
5922
+ });
5923
+
5797
5924
  // core/knowledge/mem-repository.ts
5798
5925
  function resolveDuplicate(existing, existingSource, current, currentSource) {
5799
5926
  const existingRetracts = existing.revision?.kind === "retracts";
@@ -5834,19 +5961,20 @@ async function parseMemFile(value, sourceId) {
5834
5961
  throw new Error(`${message} in ${sourceId}`);
5835
5962
  }
5836
5963
  }
5837
- var DOTMEM_DIRECTORY, DEFAULT_MEM_FILE, directoryLocks, nodeFs4, separator2, normalizePath, isAbsolutePath, resolvePath, joinPath2, parentPath, uniqueSuffix, withDirectoryLock, isMissingDirectory, sourcePriority, memFilePath, MemDirectoryKnowledgeRepository;
5964
+ var DOTMEM_DIRECTORY, DEFAULT_MEM_FILE, nodeFs5, repositoryLoadCaches, separator2, normalizePath, isAbsolutePath, resolvePath, joinPath2, parentPath, uniqueSuffix, isMissingDirectory, sourcePriority, memFilePath, MemDirectoryKnowledgeRepository;
5838
5965
  var init_mem_repository = __esm({
5839
5966
  "core/knowledge/mem-repository.ts"() {
5840
5967
  init_mem_codec();
5841
5968
  init_mem_package();
5842
5969
  init_state();
5843
5970
  init_acquisition_limits();
5971
+ init_storage_coordinator();
5844
5972
  DOTMEM_DIRECTORY = ".dotmem";
5845
5973
  DEFAULT_MEM_FILE = "project.mem";
5846
- directoryLocks = /* @__PURE__ */ new Map();
5847
- nodeFs4 = /* @__PURE__ */ __name(async () => {
5974
+ nodeFs5 = /* @__PURE__ */ __name(async () => {
5848
5975
  return import('fs/promises');
5849
5976
  }, "nodeFs");
5977
+ repositoryLoadCaches = /* @__PURE__ */ new Map();
5850
5978
  separator2 = /* @__PURE__ */ __name(() => process.platform === "win32" ? "\\" : "/", "separator");
5851
5979
  normalizePath = /* @__PURE__ */ __name((value) => value.replace(/[\\/]+/g, separator2()), "normalizePath");
5852
5980
  isAbsolutePath = /* @__PURE__ */ __name((value) => /^(?:[A-Za-z]:[\\/]|[\\/])/.test(value), "isAbsolutePath");
@@ -5858,25 +5986,8 @@ var init_mem_repository = __esm({
5858
5986
  return index <= 0 ? "." : normalized.slice(0, index);
5859
5987
  }, "parentPath");
5860
5988
  uniqueSuffix = /* @__PURE__ */ __name(() => globalThis.crypto?.randomUUID?.() ?? `${Date.now().toString(36)}-${Math.random().toString(36).slice(2)}`, "uniqueSuffix");
5861
- withDirectoryLock = /* @__PURE__ */ __name(async (directoryPath, operation) => {
5862
- const previous = directoryLocks.get(directoryPath) ?? Promise.resolve();
5863
- let release = /* @__PURE__ */ __name(() => void 0, "release");
5864
- const gate = new Promise((resolveGate) => {
5865
- release = resolveGate;
5866
- });
5867
- const queued = previous.then(() => gate);
5868
- directoryLocks.set(directoryPath, queued);
5869
- await previous;
5870
- try {
5871
- return await operation();
5872
- } finally {
5873
- release();
5874
- if (directoryLocks.get(directoryPath) === queued) directoryLocks.delete(directoryPath);
5875
- }
5876
- }, "withDirectoryLock");
5877
5989
  isMissingDirectory = /* @__PURE__ */ __name((error) => error.code === "ENOENT", "isMissingDirectory");
5878
5990
  sourcePriority = /* @__PURE__ */ __name((sourceId, scope) => {
5879
- if (sourceId.endsWith(".mem") && sourceId !== "project.mem" && sourceId !== "user.mem" && sourceId !== "agent.mem") return 0;
5880
5991
  if (scope === "project" || sourceId === "project.mem") return 4;
5881
5992
  if (scope === "user" || sourceId === "user.mem") return 3;
5882
5993
  if (sourceId === "agent.mem" || sourceId === "agent") return 2;
@@ -5904,7 +6015,7 @@ var init_mem_repository = __esm({
5904
6015
  this.loadWritableOnly = loadWritableOnly;
5905
6016
  }
5906
6017
  async discover() {
5907
- const { readdir } = await nodeFs4();
6018
+ const { readdir } = await nodeFs5();
5908
6019
  try {
5909
6020
  const entries2 = await readdir(this.directoryPath, { withFileTypes: true });
5910
6021
  return entries2.filter((entry) => entry.isFile() && entry.name.endsWith(".mem") && entry.name !== "@brain.mem").map((entry) => entry.name).sort((a, b) => a.localeCompare(b));
@@ -5919,7 +6030,7 @@ var init_mem_repository = __esm({
5919
6030
  * receive a clear failure instead of discovering corruption on first use.
5920
6031
  */
5921
6032
  async initialize() {
5922
- const { mkdir } = await nodeFs4();
6033
+ const { mkdir } = await nodeFs5();
5923
6034
  await mkdir(this.directoryPath, { recursive: true });
5924
6035
  await this.load();
5925
6036
  }
@@ -5934,7 +6045,7 @@ var init_mem_repository = __esm({
5934
6045
  * that does not delete is not a delete.
5935
6046
  */
5936
6047
  async clearWritable() {
5937
- const { rm, readdir } = await nodeFs4();
6048
+ const { rm, readdir } = await nodeFs5();
5938
6049
  const filePath = memFilePath(this.directoryPath, this.writableSourceId);
5939
6050
  await rm(filePath, { force: true });
5940
6051
  await rm(`${filePath}.bak`, { force: true });
@@ -5951,15 +6062,28 @@ var init_mem_repository = __esm({
5951
6062
  }
5952
6063
  }
5953
6064
  async load() {
5954
- const loaded = this.loadWritableOnly ? await this.loadSources([this.writableSourceId]) : await this.loadSources();
5955
- return this.combine(loaded);
6065
+ const cacheKey = `${this.directoryPath}:${this.writableSourceId}:${this.loadWritableOnly}`;
6066
+ for (let attempt = 0; attempt < 5; attempt += 1) {
6067
+ const generationBefore = await readStorageGeneration(this.directoryPath);
6068
+ const cached = repositoryLoadCaches.get(cacheKey);
6069
+ if (cached && cached.signature === String(generationBefore)) {
6070
+ return structuredClone(cached.state);
6071
+ }
6072
+ const loaded = this.loadWritableOnly ? await this.loadSources([this.writableSourceId]) : await this.loadSources();
6073
+ const state2 = this.combine(loaded);
6074
+ const generationAfter = await readStorageGeneration(this.directoryPath);
6075
+ if (generationBefore !== generationAfter && attempt < 4) continue;
6076
+ repositoryLoadCaches.set(cacheKey, { signature: String(generationAfter), state: structuredClone(state2) });
6077
+ return state2;
6078
+ }
6079
+ throw new Error("Unable to load stable repository state");
5956
6080
  }
5957
- async save(state2, expectedVersion) {
6081
+ async save(state2, expectedVersion, locked = false) {
5958
6082
  const validated = validateKnowledgeState(state2);
5959
6083
  if (!Number.isInteger(expectedVersion) || expectedVersion < 0 || validated.version !== expectedVersion + 1) {
5960
6084
  throw new Error("Invalid expected persisted version");
5961
6085
  }
5962
- await withDirectoryLock(this.directoryPath, async () => {
6086
+ const doWrite = /* @__PURE__ */ __name(async () => {
5963
6087
  const loaded = await this.loadSources();
5964
6088
  const writable = loaded.find((source) => source.id === this.writableSourceId) ?? {
5965
6089
  id: this.writableSourceId,
@@ -5981,10 +6105,16 @@ var init_mem_repository = __esm({
5981
6105
  claims: [...writable.state.claims, ...newClaims]
5982
6106
  };
5983
6107
  await this.writeSource(writable.filePath, nextWritable, writable.preserved, writable.package);
5984
- });
6108
+ await writeStorageGeneration(this.directoryPath, await readStorageGeneration(this.directoryPath) + 1);
6109
+ }, "doWrite");
6110
+ if (locked) {
6111
+ await doWrite();
6112
+ } else {
6113
+ await withStorageLock(this.directoryPath, doWrite);
6114
+ }
5985
6115
  }
5986
6116
  async loadSources(sourceIds) {
5987
- const { readFile: readFile8 } = await nodeFs4();
6117
+ const { readFile: readFile8 } = await nodeFs5();
5988
6118
  const ids = sourceIds ?? await this.discover();
5989
6119
  const sources = [];
5990
6120
  for (const sourceId of ids) {
@@ -6074,7 +6204,7 @@ var init_mem_repository = __esm({
6074
6204
  * valid package, so the backup is always a version this library can read.
6075
6205
  */
6076
6206
  async keepLastValidVersion(filePath) {
6077
- const { readFile: readFile8, copyFile, rename, rm } = await nodeFs4();
6207
+ const { readFile: readFile8, copyFile, rename, rm } = await nodeFs5();
6078
6208
  let current;
6079
6209
  try {
6080
6210
  current = await readFile8(filePath);
@@ -6098,7 +6228,7 @@ var init_mem_repository = __esm({
6098
6228
  }
6099
6229
  /** Best-effort directory sync: the rename is durable once the directory is. */
6100
6230
  async syncDirectory(directoryPath) {
6101
- const { open } = await nodeFs4();
6231
+ const { open } = await nodeFs5();
6102
6232
  try {
6103
6233
  const handle = await open(directoryPath, "r");
6104
6234
  try {
@@ -6110,7 +6240,7 @@ var init_mem_repository = __esm({
6110
6240
  }
6111
6241
  }
6112
6242
  async writeSource(filePath, state2, preserved, preservedPackage) {
6113
- const { mkdir, rename, rm, open, readFile: readFile8 } = await nodeFs4();
6243
+ const { mkdir, rename, rm, open, readFile: readFile8 } = await nodeFs5();
6114
6244
  if (!Number.isInteger(state2.version) || state2.version < 0) throw new Error("Invalid writable .mem knowledge version");
6115
6245
  for (const claim of state2.claims) validateClaim(claim);
6116
6246
  await mkdir(parentPath(filePath), { recursive: true });
@@ -6980,7 +7110,7 @@ var init_project_identity = __esm({
6980
7110
  });
6981
7111
 
6982
7112
  // core/knowledge/staging.ts
6983
- var DOTMEM_STAGE_FORMAT, DOTMEM_STAGE_VERSION, StageFileError, generateRequestId, nodeCwd, resolveStagingDirectory, stagePathFor, nodeFs5, normalizeClaimIds, revisionFromOptions, writeStageFile, readStageFile, validateStageFile, commitStageFile, cleanupStageFile;
7113
+ var DOTMEM_STAGE_FORMAT, DOTMEM_STAGE_VERSION, StageFileError, generateRequestId, nodeCwd, resolveStagingDirectory, stagePathFor, nodeFs6, normalizeClaimIds, revisionFromOptions, writeStageFile, readStageFile, validateStageFile, commitStageFile, cleanupStageFile;
6984
7114
  var init_staging = __esm({
6985
7115
  "core/knowledge/staging.ts"() {
6986
7116
  init_claim_record();
@@ -7015,7 +7145,7 @@ var init_staging = __esm({
7015
7145
  return `${base}/dotmem`;
7016
7146
  }, "resolveStagingDirectory");
7017
7147
  stagePathFor = /* @__PURE__ */ __name((requestId) => `${resolveStagingDirectory()}/${requestId}.stage`, "stagePathFor");
7018
- nodeFs5 = /* @__PURE__ */ __name(async () => import('fs/promises'), "nodeFs");
7148
+ nodeFs6 = /* @__PURE__ */ __name(async () => import('fs/promises'), "nodeFs");
7019
7149
  normalizeClaimIds = /* @__PURE__ */ __name((value) => {
7020
7150
  if (!value) return [];
7021
7151
  return Array.isArray(value) ? value : [value];
@@ -7040,7 +7170,7 @@ var init_staging = __esm({
7040
7170
  };
7041
7171
  const requestId = generateRequestId();
7042
7172
  const stagePath = stagePathFor(requestId);
7043
- const fs5 = await nodeFs5();
7173
+ const fs5 = await nodeFs6();
7044
7174
  await fs5.mkdir(resolveStagingDirectory(), { recursive: true });
7045
7175
  const stageFile = {
7046
7176
  format: DOTMEM_STAGE_FORMAT,
@@ -7060,7 +7190,7 @@ var init_staging = __esm({
7060
7190
  }, "writeStageFile");
7061
7191
  readStageFile = /* @__PURE__ */ __name(async (requestId) => {
7062
7192
  const stagePath = stagePathFor(requestId);
7063
- const fs5 = await nodeFs5();
7193
+ const fs5 = await nodeFs6();
7064
7194
  try {
7065
7195
  const content = await fs5.readFile(stagePath, "utf8");
7066
7196
  return JSON.parse(content);
@@ -7171,7 +7301,7 @@ var init_staging = __esm({
7171
7301
  }, "commitStageFile");
7172
7302
  cleanupStageFile = /* @__PURE__ */ __name(async (requestId) => {
7173
7303
  const stagePath = stagePathFor(requestId);
7174
- const fs5 = await nodeFs5();
7304
+ const fs5 = await nodeFs6();
7175
7305
  try {
7176
7306
  await fs5.unlink(stagePath);
7177
7307
  } catch (error) {
@@ -8949,6 +9079,7 @@ function _inferConfidence(claim) {
8949
9079
  var LOGIC_MEM_FILE, nodeCwd2, cachedRuntime, LogicEngine, logic, logic_default;
8950
9080
  var init_logic = __esm({
8951
9081
  "core/logic/index.ts"() {
9082
+ init_suppress_idb_warning();
8952
9083
  init_knowledge();
8953
9084
  init_mem_repository();
8954
9085
  init_acquisition_boundary();
@@ -9342,6 +9473,7 @@ async function resetKnowledgeRuntimeCaches() {
9342
9473
  var EmptyLogicRepository, KNOWLEDGE_STATE_KEY, knowledgeSaveQueue, StoreKnowledgeRepository, RuntimeSlot, projectSlot, userSlot, installDotMemReadme;
9343
9474
  var init_knowledge_runtime = __esm({
9344
9475
  "core/memory/knowledge-runtime.ts"() {
9476
+ init_suppress_idb_warning();
9345
9477
  init_knowledge();
9346
9478
  init_project_identity();
9347
9479
  init_user_paths();
@@ -9874,6 +10006,7 @@ async function getEntry(key) {
9874
10006
  var MEMORY_INDEX_KEY, SUPERSEDED_PREFIX, entries;
9875
10007
  var init_entries = __esm({
9876
10008
  "core/memory/entries.ts"() {
10009
+ init_suppress_idb_warning();
9877
10010
  init_env();
9878
10011
  init_journal();
9879
10012
  MEMORY_INDEX_KEY = "__dotmem_memory_index__";
@@ -10226,15 +10359,18 @@ async function findClaimAcrossAllSources(claimId, scope, sourceProject) {
10226
10359
  var acquire;
10227
10360
  var init_acquire = __esm({
10228
10361
  "core/memory/acquire.ts"() {
10362
+ init_suppress_idb_warning();
10229
10363
  init_env();
10230
10364
  init_project_identity();
10231
10365
  init_project_anchor();
10232
10366
  init_acquisition_boundary();
10233
10367
  init_claim_record();
10368
+ init_state();
10234
10369
  init_router();
10235
10370
  init_store_queue();
10236
10371
  init_staging();
10237
10372
  init_user_paths();
10373
+ init_storage_coordinator();
10238
10374
  init_mem_repository();
10239
10375
  init_knowledge_runtime();
10240
10376
  __name(normalizeClaimIds3, "normalizeClaimIds");
@@ -10270,23 +10406,27 @@ var init_acquire = __esm({
10270
10406
  );
10271
10407
  }
10272
10408
  const revision = revisionFromAcquire2(opts);
10409
+ const repository = target.repository;
10273
10410
  await withStoreQueue(acquisitionStoreKey(kind, scope, sourceProject), async () => {
10274
- const state2 = await target.runtime.select([]);
10275
- await target.runtime.update({
10276
- basedOnVersion: state2.context.knowledgeVersion,
10277
- claims: [buildClaimRecord({
10278
- id: opts.id,
10279
- knowledge: boundary.knowledge,
10280
- applicability: opts.applicability,
10281
- evidence: opts.evidence,
10282
- epistemicType: opts.epistemicType,
10283
- provenance: opts.provenance,
10284
- acquiredAt: opts.acquiredAt,
10285
- revision,
10286
- scope,
10287
- sourceProject,
10288
- kind
10289
- })]
10411
+ await withStorageLock(repository.directoryPath, async () => {
10412
+ const state2 = await repository.load();
10413
+ const next = updateKnowledge(state2, {
10414
+ basedOnVersion: state2.version,
10415
+ claims: [buildClaimRecord({
10416
+ id: opts.id,
10417
+ knowledge: boundary.knowledge,
10418
+ applicability: opts.applicability,
10419
+ evidence: opts.evidence,
10420
+ epistemicType: opts.epistemicType,
10421
+ provenance: opts.provenance,
10422
+ acquiredAt: opts.acquiredAt,
10423
+ revision,
10424
+ scope,
10425
+ sourceProject,
10426
+ kind
10427
+ })]
10428
+ });
10429
+ await repository.save(next, state2.version, true);
10290
10430
  });
10291
10431
  });
10292
10432
  const verification = await target.repository.load();
@@ -11818,6 +11958,7 @@ async function bootstrapProject() {
11818
11958
  var pendingDetectionEvents, detectionFlushScheduled, flushDetectionEvents, memory;
11819
11959
  var init_memory = __esm({
11820
11960
  "core/memory/index.ts"() {
11961
+ init_suppress_idb_warning();
11821
11962
  init_journal();
11822
11963
  init_brain();
11823
11964
  init_knowledge_runtime();
@@ -12724,6 +12865,7 @@ var init_policy3 = __esm({
12724
12865
  });
12725
12866
 
12726
12867
  // core/cli/index.ts
12868
+ init_suppress_idb_warning();
12727
12869
  init_memory();
12728
12870
 
12729
12871
  // core/continuity/freshness.ts
@@ -12956,6 +13098,10 @@ var saveContinuityDocument = /* @__PURE__ */ __name(async (path3, document) => {
12956
13098
  }
12957
13099
  }, "saveContinuityDocument");
12958
13100
 
13101
+ // core/continuity-ledger/index.ts
13102
+ init_memory();
13103
+ init_memory();
13104
+
12959
13105
  // core/continuity/index.ts
12960
13106
  var continuity = {
12961
13107
  async context(options) {
@@ -14100,7 +14246,7 @@ Run \`npx dotmem <command> --help\` for command-specific options.
14100
14246
  Memory:
14101
14247
  context "<situation>" [--explain] [--json] [--full] [--claims-only] [--limit <N>] [--format brief]
14102
14248
  project acquired experience for a situation
14103
- init initialize dotmem for the current project (.mem/)
14249
+ init initialize dotmem for the current project (.dotmem/)
14104
14250
  acquire acquire durable experience from a JSON claim on stdin
14105
14251
  learn "<text>" [--scope <user|project>] [--situation "<text>"] [--id "<id>"]
14106
14252
  acquire a claim from plain text (shorthand for acquire)