@remnic/plugin-openclaw 1.0.9 → 1.0.11

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 (69) hide show
  1. package/dist/{calibration-674TDQNV.js → calibration-WCHOK6DX.js} +12 -4
  2. package/dist/capsule-cli-TFKLAG3S.js +329 -0
  3. package/dist/capsule-crypto-K3IRTKRH.js +17 -0
  4. package/dist/capsule-export-CVA3CKUQ.js +265 -0
  5. package/dist/capsule-import-CFX7BY5W.js +16 -0
  6. package/dist/capsule-merge-7RVOHJK3.js +189 -0
  7. package/dist/{causal-chain-OKDZSDEB.js → causal-chain-WYN5QOPS.js} +3 -2
  8. package/dist/{causal-consolidation-5BEXLQV5.js → causal-consolidation-JD6KJJH6.js} +16 -12
  9. package/dist/{causal-retrieval-3BKBXVXD.js → causal-retrieval-NZHQOZOE.js} +6 -5
  10. package/dist/{causal-trajectory-graph-RQIT37DN.js → causal-trajectory-graph-VBPE2WPM.js} +1 -1
  11. package/dist/chunk-37NKFWSO.js +233 -0
  12. package/dist/chunk-3G7FAF6S.js +60 -0
  13. package/dist/{chunk-Z7GRLVK3.js → chunk-3GUF7RQI.js} +235 -19
  14. package/dist/chunk-3I7RHWYT.js +214 -0
  15. package/dist/chunk-4G2XCSD2.js +186 -0
  16. package/dist/chunk-6IWEAUN6.js +148 -0
  17. package/dist/{chunk-LN5UZQVG.js → chunk-6UFI73TJ.js} +5 -3
  18. package/dist/chunk-7OQEPGQF.js +529 -0
  19. package/dist/chunk-B52XADV3.js +244 -0
  20. package/dist/chunk-BU5KJVWF.js +78 -0
  21. package/dist/chunk-CXM7EBAO.js +289 -0
  22. package/dist/chunk-ETJZRIAM.js +227 -0
  23. package/dist/chunk-FQRSVYY4.js +110 -0
  24. package/dist/chunk-HRGFO6AW.js +349 -0
  25. package/dist/chunk-I6B2W2IY.js +47 -0
  26. package/dist/chunk-JZBOXOUC.js +259 -0
  27. package/dist/chunk-K7EUBNDD.js +185 -0
  28. package/dist/chunk-L4PRBB2A.js +1860 -0
  29. package/dist/chunk-MBIFE6SA.js +250 -0
  30. package/dist/chunk-N7EOZY6F.js +400 -0
  31. package/dist/chunk-NKVIN6RD.js +118 -0
  32. package/dist/chunk-OEI7GLV2.js +17 -0
  33. package/dist/{chunk-S2ISS4AH.js → chunk-P3DIW2SD.js} +10 -10
  34. package/dist/{chunk-7TENHBV2.js → chunk-RQCTMECT.js} +10 -48
  35. package/dist/chunk-SSFTU6LP.js +182 -0
  36. package/dist/{chunk-BXTMZDRT.js → chunk-SVSQAG6M.js} +7 -5
  37. package/dist/chunk-TLVIQLB4.js +874 -0
  38. package/dist/{chunk-JJSNPSCD.js → chunk-TNH24SF6.js} +352 -50
  39. package/dist/chunk-TVKKIS53.js +720 -0
  40. package/dist/{chunk-YHH3SXKD.js → chunk-WPINX4MF.js} +1 -59
  41. package/dist/{chunk-HCFFXBLV.js → chunk-XMSDA5WA.js} +5 -1861
  42. package/dist/chunk-YGGGUTG3.js +125 -0
  43. package/dist/chunk-YGXXBRV7.js +10 -0
  44. package/dist/cipher-VHAFCG7Z.js +27 -0
  45. package/dist/dreams-ledger-3I52ISYR.js +285 -0
  46. package/dist/{engine-65C2J63X.js → engine-VMTFKFGO.js} +5 -2
  47. package/dist/{fallback-llm-LVK5PDIM.js → fallback-llm-WCWNGIQ3.js} +2 -1
  48. package/dist/first-start-migration-I24M2JEE.js +258 -0
  49. package/dist/forget-NI4RBDPB.js +68 -0
  50. package/dist/fs-utils-PZRI2HDZ.js +29 -0
  51. package/dist/graph-edge-decay-5CVKWBYH.js +203 -0
  52. package/dist/index.js +9791 -2902
  53. package/dist/kdf-H5B23ZM2.js +25 -0
  54. package/dist/memory-governance-DWGFV4FX.js +25 -0
  55. package/dist/metadata-JAGIWHEA.js +20 -0
  56. package/dist/migrate-from-identity-anchor-N3354WMP.js +7 -0
  57. package/dist/path-5LCUBAAZ.js +8 -0
  58. package/dist/peers-JF2I6RCR.js +43 -0
  59. package/dist/purge-XN2VSPZ2.js +204 -0
  60. package/dist/secure-store-FWJ7LBPH.js +149 -0
  61. package/dist/state-PVISYXRH.js +7 -0
  62. package/dist/state-store-LP5BO6SF.js +15 -0
  63. package/dist/{storage-DM4ZGOCN.js → storage-T2OGFUF4.js} +3 -1
  64. package/dist/tier-stats-IZNW66NC.js +147 -0
  65. package/dist/trace-NJESSGH7.js +289 -0
  66. package/dist/tui-MGK2LYJY.js +12 -0
  67. package/dist/types-H5R5D3WF.js +30 -0
  68. package/openclaw.plugin.json +519 -4
  69. package/package.json +1 -1
@@ -0,0 +1,118 @@
1
+ // ../remnic-core/src/transfer/fs-utils.ts
2
+ import { createHash } from "crypto";
3
+ import {
4
+ lstat,
5
+ mkdir,
6
+ readdir,
7
+ readFile,
8
+ realpath,
9
+ stat,
10
+ writeFile
11
+ } from "fs/promises";
12
+ import path from "path";
13
+ async function sha256File(filePath) {
14
+ const buf = await readFile(filePath);
15
+ const sha256 = createHash("sha256").update(buf).digest("hex");
16
+ return { sha256, bytes: buf.byteLength };
17
+ }
18
+ function sha256String(content) {
19
+ const buf = Buffer.from(content, "utf-8");
20
+ const sha256 = createHash("sha256").update(buf).digest("hex");
21
+ return { sha256, bytes: buf.byteLength };
22
+ }
23
+ async function writeJsonFile(filePath, value) {
24
+ await mkdir(path.dirname(filePath), { recursive: true });
25
+ await writeFile(filePath, JSON.stringify(value, null, 2) + "\n", "utf-8");
26
+ }
27
+ async function readJsonFile(filePath) {
28
+ const raw = await readFile(filePath, "utf-8");
29
+ return JSON.parse(raw);
30
+ }
31
+ async function listFilesRecursive(rootDir) {
32
+ const out = [];
33
+ async function walk(dir) {
34
+ const entries = await readdir(dir, { withFileTypes: true });
35
+ for (const ent of entries) {
36
+ const fp = path.join(dir, ent.name);
37
+ if (ent.isDirectory()) {
38
+ await walk(fp);
39
+ } else if (ent.isFile()) {
40
+ out.push(fp);
41
+ }
42
+ }
43
+ }
44
+ await walk(rootDir);
45
+ return out.sort();
46
+ }
47
+ async function ensureDirExists(dirPath) {
48
+ await mkdir(dirPath, { recursive: true });
49
+ }
50
+ async function fileExists(filePath) {
51
+ try {
52
+ await stat(filePath);
53
+ return true;
54
+ } catch {
55
+ return false;
56
+ }
57
+ }
58
+ function toPosixRelPath(absPath, rootDir) {
59
+ const rel = path.relative(rootDir, absPath);
60
+ return rel.split(path.sep).join("/");
61
+ }
62
+ function fromPosixRelPath(relPath) {
63
+ return relPath.split("/").join(path.sep);
64
+ }
65
+ function isPathInsideRoot(rootReal, absPath) {
66
+ const rel = path.relative(rootReal, absPath);
67
+ if (rel === "") return true;
68
+ if (rel === "..") return false;
69
+ if (rel.startsWith(`..${path.sep}`)) return false;
70
+ if (path.isAbsolute(rel)) return false;
71
+ return true;
72
+ }
73
+ async function assertIsDirectoryNotSymlink(absPath, errorPrefix, argName) {
74
+ const st = await stat(absPath).catch(() => null);
75
+ if (!st || !st.isDirectory()) {
76
+ throw new Error(
77
+ `${errorPrefix}: '${argName}' must be an existing directory: ${absPath}`
78
+ );
79
+ }
80
+ const lst = await lstat(absPath).catch(() => null);
81
+ if (lst && lst.isSymbolicLink()) {
82
+ throw new Error(
83
+ `${errorPrefix}: '${argName}' must not be a symlink \u2014 resolve it to its real path first: ${absPath}`
84
+ );
85
+ }
86
+ }
87
+ async function assertRealpathInsideRoot(rootReal, targetAbs, sourcePath, errorPrefix) {
88
+ let existing = targetAbs;
89
+ const suffix = [];
90
+ while (existing !== path.dirname(existing)) {
91
+ const st = await lstat(existing).catch(() => null);
92
+ if (st !== null) break;
93
+ suffix.unshift(path.basename(existing));
94
+ existing = path.dirname(existing);
95
+ }
96
+ const existingReal = await realpath(existing).catch(() => existing);
97
+ const targetReal = suffix.length > 0 ? path.join(existingReal, ...suffix) : existingReal;
98
+ if (!isPathInsideRoot(rootReal, targetReal)) {
99
+ throw new Error(
100
+ `${errorPrefix}: record path escapes target root via symlink: ${sourcePath}`
101
+ );
102
+ }
103
+ }
104
+
105
+ export {
106
+ sha256File,
107
+ sha256String,
108
+ writeJsonFile,
109
+ readJsonFile,
110
+ listFilesRecursive,
111
+ ensureDirExists,
112
+ fileExists,
113
+ toPosixRelPath,
114
+ fromPosixRelPath,
115
+ isPathInsideRoot,
116
+ assertIsDirectoryNotSymlink,
117
+ assertRealpathInsideRoot
118
+ };
@@ -0,0 +1,17 @@
1
+ import {
2
+ resolveHomeDir
3
+ } from "./chunk-I6B2W2IY.js";
4
+
5
+ // ../remnic-core/src/utils/path.ts
6
+ import path from "path";
7
+ function expandTildePath(p) {
8
+ if (p === "~") return resolveHomeDir();
9
+ if (p.startsWith("~/") || p.startsWith("~\\")) {
10
+ return path.join(resolveHomeDir(), p.slice(2));
11
+ }
12
+ return p;
13
+ }
14
+
15
+ export {
16
+ expandTildePath
17
+ };
@@ -1,18 +1,18 @@
1
- import {
2
- readEnvVar,
3
- resolveHomeDir
4
- } from "./chunk-7TENHBV2.js";
5
- import {
6
- StorageManager,
7
- isConsolidationOperator
8
- } from "./chunk-JJSNPSCD.js";
9
1
  import {
10
2
  countRecallTokenOverlap,
11
3
  normalizeRecallTokens
12
- } from "./chunk-YHH3SXKD.js";
4
+ } from "./chunk-WPINX4MF.js";
5
+ import {
6
+ StorageManager,
7
+ isSemanticConsolidationLlmOperator
8
+ } from "./chunk-TNH24SF6.js";
13
9
  import {
14
10
  log
15
11
  } from "./chunk-UFU5GGGA.js";
12
+ import {
13
+ readEnvVar,
14
+ resolveHomeDir
15
+ } from "./chunk-I6B2W2IY.js";
16
16
 
17
17
  // ../remnic-core/src/connectors/codex-materialize-runner.ts
18
18
  import path2 from "path";
@@ -990,7 +990,7 @@ function parseOperatorAwareConsolidationResponse(response, cluster) {
990
990
  const obj = parsed;
991
991
  const rawOperator = typeof obj.operator === "string" ? obj.operator.trim().toLowerCase() : "";
992
992
  const rawOutput = typeof obj.output === "string" ? obj.output : "";
993
- const operator = isConsolidationOperator(rawOperator) ? rawOperator : chooseConsolidationOperator(cluster);
993
+ const operator = isSemanticConsolidationLlmOperator(rawOperator) ? rawOperator : chooseConsolidationOperator(cluster);
994
994
  const output = rawOutput.trim().length > 0 ? rawOutput.trim() : response.trim();
995
995
  return { operator, output };
996
996
  }
@@ -4,6 +4,9 @@ import {
4
4
  import {
5
5
  log
6
6
  } from "./chunk-UFU5GGGA.js";
7
+ import {
8
+ readEnvVar
9
+ } from "./chunk-I6B2W2IY.js";
7
10
 
8
11
  // ../remnic-core/src/openai-chat-compat.ts
9
12
  function normalizedModel(model) {
@@ -38,51 +41,9 @@ function buildChatCompletionTokenLimit(model, maxTokens, options) {
38
41
  return { max_tokens: safeMaxTokens };
39
42
  }
40
43
 
41
- // ../remnic-core/src/runtime/env.ts
42
- import os from "os";
43
- var REMNIC_ENGRAM_PREFIX_PAIRS = [
44
- ["REMNIC_", "ENGRAM_"],
45
- ["ENGRAM_", "REMNIC_"]
46
- ];
47
- function getEnvMap() {
48
- const runtimeProcess = globalThis.process;
49
- return runtimeProcess?.["env"];
50
- }
51
- function legacyEnvCandidates(name) {
52
- const candidates = [name];
53
- for (const [primary, legacy] of REMNIC_ENGRAM_PREFIX_PAIRS) {
54
- if (name.startsWith(primary)) {
55
- candidates.push(`${legacy}${name.slice(primary.length)}`);
56
- }
57
- }
58
- return candidates;
59
- }
60
- function readEnvVar(name) {
61
- const env = getEnvMap();
62
- for (const candidate of legacyEnvCandidates(name)) {
63
- const value = env?.[candidate];
64
- if (typeof value === "string") return value;
65
- }
66
- return void 0;
67
- }
68
- function resolveHomeDir() {
69
- return readEnvVar("HOME") || os.homedir();
70
- }
71
- function cloneEnv() {
72
- return { ...getEnvMap() ?? {} };
73
- }
74
- function mergeEnv(overrides) {
75
- const merged = cloneEnv();
76
- for (const [key, value] of Object.entries(overrides)) {
77
- if (typeof value === "string") merged[key] = value;
78
- else delete merged[key];
79
- }
80
- return merged;
81
- }
82
-
83
44
  // ../remnic-core/src/resolve-provider-secret.ts
84
45
  import path from "path";
85
- import os2 from "os";
46
+ import os from "os";
86
47
  var _resolveApiKeyForProvider = null;
87
48
  var _getRuntimeAuthForModel = null;
88
49
  var _resolverLoaded = false;
@@ -126,6 +87,9 @@ async function getGatewayResolver() {
126
87
  return null;
127
88
  }
128
89
  async function findRuntimeModules() {
90
+ return findGatewayRuntimeModules("runtime-model-auth.runtime-");
91
+ }
92
+ async function findGatewayRuntimeModules(filePrefix) {
129
93
  const { accessSync, constants, readdirSync, realpathSync, statSync } = await import("fs");
130
94
  const { createRequire } = await import("module");
131
95
  const candidates = [];
@@ -169,7 +133,7 @@ async function findRuntimeModules() {
169
133
  try {
170
134
  const files = readdirSync(dir);
171
135
  for (const f of files) {
172
- if (f.startsWith("runtime-model-auth.runtime-") && f.endsWith(".js")) {
136
+ if (f.startsWith(filePrefix) && f.endsWith(".js")) {
173
137
  candidates.push(path.join(dir, f));
174
138
  }
175
139
  }
@@ -200,7 +164,7 @@ function findExecutableOnPath(executableName, access, stat, executableMode) {
200
164
  }
201
165
  async function resolveProviderApiKey(providerId, apiKeyValue, gatewayConfig, agentDir) {
202
166
  const resolvedAgentDir = path.resolve(
203
- agentDir ?? path.join(os2.homedir(), ".openclaw", "agents", "main", "agent")
167
+ agentDir ?? path.join(os.homedir(), ".openclaw", "agents", "main", "agent")
204
168
  );
205
169
  const cacheKey = `provider:${providerId}:agentDir:${resolvedAgentDir}`;
206
170
  if (resolvedCache.has(cacheKey)) {
@@ -730,10 +694,8 @@ function extractResponsesOutputText(data) {
730
694
  }
731
695
 
732
696
  export {
733
- readEnvVar,
734
- resolveHomeDir,
735
- mergeEnv,
736
697
  shouldAssumeOpenAiChatCompletions,
737
698
  buildChatCompletionTokenLimit,
699
+ findGatewayRuntimeModules,
738
700
  FallbackLlmClient
739
701
  };
@@ -0,0 +1,182 @@
1
+ import {
2
+ getKey,
3
+ readHeader,
4
+ secureStoreDir
5
+ } from "./chunk-CXM7EBAO.js";
6
+ import {
7
+ open,
8
+ seal
9
+ } from "./chunk-YGGGUTG3.js";
10
+
11
+ // ../remnic-core/src/transfer/capsule-crypto.ts
12
+ import { open as openFileHandle, readFile, writeFile } from "fs/promises";
13
+ import path from "path";
14
+ var MAGIC = Buffer.from("REMNIC-ENC\0", "ascii");
15
+ var FORMAT_VERSION = 2;
16
+ var MIN_ENC_SIZE_V1 = MAGIC.length + 1 + 45;
17
+ var MIN_ENC_SIZE = MAGIC.length + 1 + 2;
18
+ async function isEncryptedCapsuleFile(filePath) {
19
+ if (!filePath.endsWith(".enc")) return false;
20
+ let fh = null;
21
+ try {
22
+ fh = await openFileHandle(filePath, "r");
23
+ const buf = Buffer.allocUnsafe(MAGIC.length);
24
+ const { bytesRead } = await fh.read(buf, 0, MAGIC.length, 0);
25
+ if (bytesRead < MAGIC.length) return false;
26
+ return buf.equals(MAGIC);
27
+ } catch {
28
+ return false;
29
+ } finally {
30
+ if (fh !== null) {
31
+ await fh.close().catch(() => void 0);
32
+ }
33
+ }
34
+ }
35
+ async function encryptCapsuleFile(opts) {
36
+ const encPath = opts.outPath ?? `${opts.sourceGzPath}.enc`;
37
+ const key = getKeyOrThrow(opts.memoryDir, "encrypt capsule");
38
+ const plaintext = await readFile(opts.sourceGzPath);
39
+ const basename = path.basename(encPath);
40
+ const aad = Buffer.from(basename, "utf-8");
41
+ const kdfSection = await loadKdfSection(opts.memoryDir);
42
+ const envelope = seal(key, kdfSection.salt, plaintext, { aad });
43
+ const versionBuf = Buffer.alloc(1);
44
+ versionBuf.writeUInt8(FORMAT_VERSION, 0);
45
+ const kdfJsonBuf = Buffer.from(kdfSection.json, "utf-8");
46
+ const kdfLenBuf = Buffer.alloc(2);
47
+ kdfLenBuf.writeUInt16LE(kdfJsonBuf.length, 0);
48
+ const output = Buffer.concat([MAGIC, versionBuf, kdfLenBuf, kdfJsonBuf, envelope]);
49
+ await writeFile(encPath, output);
50
+ return { encPath };
51
+ }
52
+ async function decryptCapsuleFile(opts) {
53
+ const gzPath = opts.outPath ?? opts.encPath.replace(/\.enc$/, "");
54
+ const buf = await readFile(opts.encPath);
55
+ if (buf.length < MIN_ENC_SIZE_V1) {
56
+ throw new Error(
57
+ `decryptCapsuleFile: file too short to be an encrypted capsule: ${opts.encPath}`
58
+ );
59
+ }
60
+ if (!buf.subarray(0, MAGIC.length).equals(MAGIC)) {
61
+ throw new Error(
62
+ `decryptCapsuleFile: file does not start with REMNIC-ENC magic: ${opts.encPath}`
63
+ );
64
+ }
65
+ const version = buf.readUInt8(MAGIC.length);
66
+ if (version !== 1 && version !== 2) {
67
+ throw new Error(
68
+ `decryptCapsuleFile: unsupported encrypted-capsule format version ${version} (this build supports versions 1 and 2): ${opts.encPath}`
69
+ );
70
+ }
71
+ const { key, envelopeOffset } = resolveKeyAndOffset(buf, version, opts.memoryDir, "decryptCapsuleFile", opts.encPath);
72
+ const envelope = buf.subarray(envelopeOffset);
73
+ const basename = path.basename(opts.encPath);
74
+ const aad = Buffer.from(basename, "utf-8");
75
+ let plaintext;
76
+ try {
77
+ plaintext = open(key, envelope, { aad });
78
+ } catch (cause) {
79
+ throw new Error(
80
+ `decryptCapsuleFile: authentication failed \u2014 wrong passphrase, tampered archive, or key mismatch. Ensure the secure-store is unlocked with the correct passphrase and the archive has not been modified: ${opts.encPath}`,
81
+ { cause }
82
+ );
83
+ }
84
+ await writeFile(gzPath, plaintext);
85
+ return { gzPath };
86
+ }
87
+ async function decryptCapsuleFileInMemory(encPath, memoryDir) {
88
+ const buf = await readFile(encPath);
89
+ if (buf.length < MIN_ENC_SIZE_V1) {
90
+ throw new Error(
91
+ `decryptCapsuleFileInMemory: file too short to be an encrypted capsule: ${encPath}`
92
+ );
93
+ }
94
+ if (!buf.subarray(0, MAGIC.length).equals(MAGIC)) {
95
+ throw new Error(
96
+ `decryptCapsuleFileInMemory: file does not start with REMNIC-ENC magic: ${encPath}`
97
+ );
98
+ }
99
+ const version = buf.readUInt8(MAGIC.length);
100
+ if (version !== 1 && version !== 2) {
101
+ throw new Error(
102
+ `decryptCapsuleFileInMemory: unsupported encrypted-capsule format version ${version} (this build supports versions 1 and 2): ${encPath}`
103
+ );
104
+ }
105
+ const { key, envelopeOffset } = resolveKeyAndOffset(buf, version, memoryDir, "decryptCapsuleFileInMemory", encPath);
106
+ const envelope = buf.subarray(envelopeOffset);
107
+ const basename = path.basename(encPath);
108
+ const aad = Buffer.from(basename, "utf-8");
109
+ try {
110
+ return open(key, envelope, { aad });
111
+ } catch (cause) {
112
+ throw new Error(
113
+ `decryptCapsuleFileInMemory: authentication failed \u2014 wrong passphrase, tampered archive, or key mismatch. Ensure the secure-store is unlocked with the correct passphrase and the archive has not been modified: ${encPath}`,
114
+ { cause }
115
+ );
116
+ }
117
+ }
118
+ async function loadKdfSection(memoryDir) {
119
+ try {
120
+ const header = await readHeader(memoryDir);
121
+ if (header !== null) {
122
+ const { decodeMetadataSalt } = await import("./metadata-JAGIWHEA.js");
123
+ const salt2 = decodeMetadataSalt(header.metadata);
124
+ const kdf = header.metadata.kdf;
125
+ const json2 = JSON.stringify({
126
+ algorithm: kdf.algorithm,
127
+ params: kdf.params,
128
+ salt: salt2.toString("hex")
129
+ });
130
+ return { json: json2, salt: salt2 };
131
+ }
132
+ } catch {
133
+ }
134
+ const { generateSalt } = await import("./cipher-VHAFCG7Z.js");
135
+ const salt = generateSalt();
136
+ const { DEFAULT_ARGON2ID_PARAMS } = await import("./kdf-H5B23ZM2.js");
137
+ const json = JSON.stringify({
138
+ algorithm: "argon2id",
139
+ params: DEFAULT_ARGON2ID_PARAMS,
140
+ salt: salt.toString("hex")
141
+ });
142
+ return { json, salt };
143
+ }
144
+ function getKeyOrThrow(memoryDir, action) {
145
+ const storeId = secureStoreDir(memoryDir);
146
+ const key = getKey(storeId);
147
+ if (key === null) {
148
+ throw new Error(
149
+ `Secure-store is locked or not initialized \u2014 cannot ${action}. Run \`remnic secure-store unlock\` first, or \`remnic secure-store init\` if the store has never been initialized.`
150
+ );
151
+ }
152
+ return key;
153
+ }
154
+ function resolveKeyAndOffset(buf, version, memoryDir, caller, encPath) {
155
+ if (version === 1) {
156
+ const key2 = getKeyOrThrow(memoryDir, "decrypt capsule");
157
+ return { key: key2, envelopeOffset: MAGIC.length + 1 };
158
+ }
159
+ const kdfLenOffset = MAGIC.length + 1;
160
+ if (buf.length < kdfLenOffset + 2) {
161
+ throw new Error(
162
+ `${caller}: file too short for format v2 KDF length field: ${encPath}`
163
+ );
164
+ }
165
+ const kdfLen = buf.readUInt16LE(kdfLenOffset);
166
+ const kdfJsonOffset = kdfLenOffset + 2;
167
+ if (buf.length < kdfJsonOffset + kdfLen) {
168
+ throw new Error(
169
+ `${caller}: file too short for format v2 KDF params section (expected ${kdfLen} bytes): ${encPath}`
170
+ );
171
+ }
172
+ const envelopeOffset = kdfJsonOffset + kdfLen;
173
+ const key = getKeyOrThrow(memoryDir, "decrypt capsule");
174
+ return { key, envelopeOffset };
175
+ }
176
+
177
+ export {
178
+ isEncryptedCapsuleFile,
179
+ encryptCapsuleFile,
180
+ decryptCapsuleFile,
181
+ decryptCapsuleFileInMemory
182
+ };
@@ -1,12 +1,14 @@
1
1
  import {
2
- assertIsoRecordedAt,
3
- assertString,
4
2
  countRecallTokenOverlap,
5
- isRecord,
6
3
  normalizeRecallTokens,
7
- recordStoreDay,
8
4
  topicOverlapScore
9
- } from "./chunk-YHH3SXKD.js";
5
+ } from "./chunk-WPINX4MF.js";
6
+ import {
7
+ assertIsoRecordedAt,
8
+ assertString,
9
+ isRecord,
10
+ recordStoreDay
11
+ } from "./chunk-3G7FAF6S.js";
10
12
  import {
11
13
  listJsonFiles,
12
14
  readJsonFile