@remnic/plugin-openclaw 1.0.10 → 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.
- package/dist/{calibration-674TDQNV.js → calibration-WCHOK6DX.js} +12 -4
- package/dist/capsule-cli-TFKLAG3S.js +329 -0
- package/dist/capsule-crypto-K3IRTKRH.js +17 -0
- package/dist/capsule-export-CVA3CKUQ.js +265 -0
- package/dist/capsule-import-CFX7BY5W.js +16 -0
- package/dist/capsule-merge-7RVOHJK3.js +189 -0
- package/dist/{causal-chain-OKDZSDEB.js → causal-chain-WYN5QOPS.js} +3 -2
- package/dist/{causal-consolidation-5BEXLQV5.js → causal-consolidation-JD6KJJH6.js} +16 -12
- package/dist/{causal-retrieval-3BKBXVXD.js → causal-retrieval-NZHQOZOE.js} +6 -5
- package/dist/{causal-trajectory-graph-RQIT37DN.js → causal-trajectory-graph-VBPE2WPM.js} +1 -1
- package/dist/chunk-37NKFWSO.js +233 -0
- package/dist/chunk-3G7FAF6S.js +60 -0
- package/dist/{chunk-Z7GRLVK3.js → chunk-3GUF7RQI.js} +235 -19
- package/dist/chunk-3I7RHWYT.js +214 -0
- package/dist/chunk-4G2XCSD2.js +186 -0
- package/dist/chunk-6IWEAUN6.js +148 -0
- package/dist/{chunk-LN5UZQVG.js → chunk-6UFI73TJ.js} +5 -3
- package/dist/chunk-7OQEPGQF.js +529 -0
- package/dist/chunk-B52XADV3.js +244 -0
- package/dist/chunk-BU5KJVWF.js +78 -0
- package/dist/chunk-CXM7EBAO.js +289 -0
- package/dist/chunk-ETJZRIAM.js +227 -0
- package/dist/chunk-FQRSVYY4.js +110 -0
- package/dist/chunk-HRGFO6AW.js +349 -0
- package/dist/chunk-I6B2W2IY.js +47 -0
- package/dist/chunk-JZBOXOUC.js +259 -0
- package/dist/chunk-K7EUBNDD.js +185 -0
- package/dist/chunk-L4PRBB2A.js +1860 -0
- package/dist/chunk-MBIFE6SA.js +250 -0
- package/dist/chunk-N7EOZY6F.js +400 -0
- package/dist/chunk-NKVIN6RD.js +118 -0
- package/dist/chunk-OEI7GLV2.js +17 -0
- package/dist/{chunk-S2ISS4AH.js → chunk-P3DIW2SD.js} +10 -10
- package/dist/{chunk-7TENHBV2.js → chunk-RQCTMECT.js} +10 -48
- package/dist/chunk-SSFTU6LP.js +182 -0
- package/dist/{chunk-BXTMZDRT.js → chunk-SVSQAG6M.js} +7 -5
- package/dist/chunk-TLVIQLB4.js +874 -0
- package/dist/{chunk-JJSNPSCD.js → chunk-TNH24SF6.js} +352 -50
- package/dist/chunk-TVKKIS53.js +720 -0
- package/dist/{chunk-YHH3SXKD.js → chunk-WPINX4MF.js} +1 -59
- package/dist/{chunk-HCFFXBLV.js → chunk-XMSDA5WA.js} +5 -1861
- package/dist/chunk-YGGGUTG3.js +125 -0
- package/dist/chunk-YGXXBRV7.js +10 -0
- package/dist/cipher-VHAFCG7Z.js +27 -0
- package/dist/dreams-ledger-3I52ISYR.js +285 -0
- package/dist/{engine-65C2J63X.js → engine-VMTFKFGO.js} +5 -2
- package/dist/{fallback-llm-LVK5PDIM.js → fallback-llm-WCWNGIQ3.js} +2 -1
- package/dist/first-start-migration-I24M2JEE.js +258 -0
- package/dist/forget-NI4RBDPB.js +68 -0
- package/dist/fs-utils-PZRI2HDZ.js +29 -0
- package/dist/graph-edge-decay-5CVKWBYH.js +203 -0
- package/dist/index.js +9775 -2900
- package/dist/kdf-H5B23ZM2.js +25 -0
- package/dist/memory-governance-DWGFV4FX.js +25 -0
- package/dist/metadata-JAGIWHEA.js +20 -0
- package/dist/migrate-from-identity-anchor-N3354WMP.js +7 -0
- package/dist/path-5LCUBAAZ.js +8 -0
- package/dist/peers-JF2I6RCR.js +43 -0
- package/dist/purge-XN2VSPZ2.js +204 -0
- package/dist/secure-store-FWJ7LBPH.js +149 -0
- package/dist/state-PVISYXRH.js +7 -0
- package/dist/state-store-LP5BO6SF.js +15 -0
- package/dist/{storage-DM4ZGOCN.js → storage-T2OGFUF4.js} +3 -1
- package/dist/tier-stats-IZNW66NC.js +147 -0
- package/dist/trace-NJESSGH7.js +289 -0
- package/dist/tui-MGK2LYJY.js +12 -0
- package/dist/types-H5R5D3WF.js +30 -0
- package/openclaw.plugin.json +519 -4
- package/package.json +1 -1
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
// ../remnic-core/src/runtime/env.ts
|
|
2
|
+
import os from "os";
|
|
3
|
+
var REMNIC_ENGRAM_PREFIX_PAIRS = [
|
|
4
|
+
["REMNIC_", "ENGRAM_"],
|
|
5
|
+
["ENGRAM_", "REMNIC_"]
|
|
6
|
+
];
|
|
7
|
+
function getEnvMap() {
|
|
8
|
+
const runtimeProcess = globalThis.process;
|
|
9
|
+
return runtimeProcess?.["env"];
|
|
10
|
+
}
|
|
11
|
+
function legacyEnvCandidates(name) {
|
|
12
|
+
const candidates = [name];
|
|
13
|
+
for (const [primary, legacy] of REMNIC_ENGRAM_PREFIX_PAIRS) {
|
|
14
|
+
if (name.startsWith(primary)) {
|
|
15
|
+
candidates.push(`${legacy}${name.slice(primary.length)}`);
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
return candidates;
|
|
19
|
+
}
|
|
20
|
+
function readEnvVar(name) {
|
|
21
|
+
const env = getEnvMap();
|
|
22
|
+
for (const candidate of legacyEnvCandidates(name)) {
|
|
23
|
+
const value = env?.[candidate];
|
|
24
|
+
if (typeof value === "string") return value;
|
|
25
|
+
}
|
|
26
|
+
return void 0;
|
|
27
|
+
}
|
|
28
|
+
function resolveHomeDir() {
|
|
29
|
+
return readEnvVar("HOME") || os.homedir();
|
|
30
|
+
}
|
|
31
|
+
function cloneEnv() {
|
|
32
|
+
return { ...getEnvMap() ?? {} };
|
|
33
|
+
}
|
|
34
|
+
function mergeEnv(overrides) {
|
|
35
|
+
const merged = cloneEnv();
|
|
36
|
+
for (const [key, value] of Object.entries(overrides)) {
|
|
37
|
+
if (typeof value === "string") merged[key] = value;
|
|
38
|
+
else delete merged[key];
|
|
39
|
+
}
|
|
40
|
+
return merged;
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
export {
|
|
44
|
+
readEnvVar,
|
|
45
|
+
resolveHomeDir,
|
|
46
|
+
mergeEnv
|
|
47
|
+
};
|
|
@@ -0,0 +1,259 @@
|
|
|
1
|
+
import {
|
|
2
|
+
DEFAULT_ARGON2ID_PARAMS,
|
|
3
|
+
DEFAULT_SCRYPT_PARAMS,
|
|
4
|
+
KDF_SALT_LENGTH
|
|
5
|
+
} from "./chunk-6IWEAUN6.js";
|
|
6
|
+
|
|
7
|
+
// ../remnic-core/src/secure-store/metadata.ts
|
|
8
|
+
var METADATA_FORMAT = "remnic.secure-store.metadata";
|
|
9
|
+
var METADATA_FORMAT_VERSION = 1;
|
|
10
|
+
function bytesToHex(bytes) {
|
|
11
|
+
return Buffer.from(bytes).toString("hex");
|
|
12
|
+
}
|
|
13
|
+
function hexToBytes(hex, expectedLength) {
|
|
14
|
+
if (typeof hex !== "string") {
|
|
15
|
+
throw new Error("hex field must be a string");
|
|
16
|
+
}
|
|
17
|
+
if (!/^[0-9a-f]*$/i.test(hex)) {
|
|
18
|
+
throw new Error("hex field must contain only hexadecimal characters");
|
|
19
|
+
}
|
|
20
|
+
if (hex.length % 2 !== 0) {
|
|
21
|
+
throw new Error("hex field must have even length");
|
|
22
|
+
}
|
|
23
|
+
const buf = Buffer.from(hex, "hex");
|
|
24
|
+
if (buf.length !== expectedLength) {
|
|
25
|
+
throw new Error(
|
|
26
|
+
`hex field decoded to ${buf.length} bytes, expected ${expectedLength}`
|
|
27
|
+
);
|
|
28
|
+
}
|
|
29
|
+
return buf;
|
|
30
|
+
}
|
|
31
|
+
function buildMetadata(options) {
|
|
32
|
+
const { algorithm, salt } = options;
|
|
33
|
+
if (!(salt instanceof Uint8Array) || salt.length !== KDF_SALT_LENGTH) {
|
|
34
|
+
throw new Error(
|
|
35
|
+
`salt must be ${KDF_SALT_LENGTH} bytes, got ${salt?.length ?? "non-buffer"}`
|
|
36
|
+
);
|
|
37
|
+
}
|
|
38
|
+
const createdAt = options.createdAt ?? (/* @__PURE__ */ new Date()).toISOString();
|
|
39
|
+
let kdf;
|
|
40
|
+
if (algorithm === "scrypt") {
|
|
41
|
+
const params = options.params ?? {
|
|
42
|
+
...DEFAULT_SCRYPT_PARAMS
|
|
43
|
+
};
|
|
44
|
+
kdf = { algorithm: "scrypt", params, salt: bytesToHex(salt) };
|
|
45
|
+
} else if (algorithm === "argon2id") {
|
|
46
|
+
const params = options.params ?? {
|
|
47
|
+
...DEFAULT_ARGON2ID_PARAMS
|
|
48
|
+
};
|
|
49
|
+
kdf = { algorithm: "argon2id", params, salt: bytesToHex(salt) };
|
|
50
|
+
} else {
|
|
51
|
+
throw new Error(`unknown KDF algorithm: ${algorithm}`);
|
|
52
|
+
}
|
|
53
|
+
const meta = {
|
|
54
|
+
format: METADATA_FORMAT,
|
|
55
|
+
formatVersion: METADATA_FORMAT_VERSION,
|
|
56
|
+
kdf,
|
|
57
|
+
createdAt
|
|
58
|
+
};
|
|
59
|
+
if (options.note !== void 0) {
|
|
60
|
+
meta.note = options.note;
|
|
61
|
+
}
|
|
62
|
+
return meta;
|
|
63
|
+
}
|
|
64
|
+
function serializeMetadata(meta) {
|
|
65
|
+
validateMetadata(meta);
|
|
66
|
+
const ordered = {
|
|
67
|
+
format: meta.format,
|
|
68
|
+
formatVersion: meta.formatVersion,
|
|
69
|
+
kdf: orderKdf(meta.kdf),
|
|
70
|
+
createdAt: meta.createdAt
|
|
71
|
+
};
|
|
72
|
+
if (meta.note !== void 0) {
|
|
73
|
+
ordered.note = meta.note;
|
|
74
|
+
}
|
|
75
|
+
return JSON.stringify(ordered, null, 2);
|
|
76
|
+
}
|
|
77
|
+
function orderKdf(kdf) {
|
|
78
|
+
if (kdf.algorithm === "scrypt") {
|
|
79
|
+
return {
|
|
80
|
+
algorithm: kdf.algorithm,
|
|
81
|
+
params: {
|
|
82
|
+
N: kdf.params.N,
|
|
83
|
+
r: kdf.params.r,
|
|
84
|
+
p: kdf.params.p,
|
|
85
|
+
keyLength: kdf.params.keyLength,
|
|
86
|
+
maxmem: kdf.params.maxmem
|
|
87
|
+
},
|
|
88
|
+
salt: kdf.salt
|
|
89
|
+
};
|
|
90
|
+
}
|
|
91
|
+
return {
|
|
92
|
+
algorithm: kdf.algorithm,
|
|
93
|
+
params: {
|
|
94
|
+
memoryKiB: kdf.params.memoryKiB,
|
|
95
|
+
iterations: kdf.params.iterations,
|
|
96
|
+
parallelism: kdf.params.parallelism,
|
|
97
|
+
keyLength: kdf.params.keyLength
|
|
98
|
+
},
|
|
99
|
+
salt: kdf.salt
|
|
100
|
+
};
|
|
101
|
+
}
|
|
102
|
+
function parseMetadata(json) {
|
|
103
|
+
if (typeof json !== "string") {
|
|
104
|
+
throw new Error("metadata input must be a string");
|
|
105
|
+
}
|
|
106
|
+
let parsed;
|
|
107
|
+
try {
|
|
108
|
+
parsed = JSON.parse(json);
|
|
109
|
+
} catch (e) {
|
|
110
|
+
const msg = e instanceof Error ? e.message : String(e);
|
|
111
|
+
throw new Error(`metadata is not valid JSON: ${msg}`);
|
|
112
|
+
}
|
|
113
|
+
if (typeof parsed !== "object" || parsed === null || Array.isArray(parsed)) {
|
|
114
|
+
throw new Error("metadata must be a JSON object");
|
|
115
|
+
}
|
|
116
|
+
const obj = parsed;
|
|
117
|
+
if (obj.format !== METADATA_FORMAT) {
|
|
118
|
+
throw new Error(
|
|
119
|
+
`unexpected metadata format: ${String(obj.format)} (expected ${METADATA_FORMAT})`
|
|
120
|
+
);
|
|
121
|
+
}
|
|
122
|
+
if (obj.formatVersion !== METADATA_FORMAT_VERSION) {
|
|
123
|
+
throw new Error(
|
|
124
|
+
`unsupported metadata formatVersion: ${String(obj.formatVersion)} (this build supports ${METADATA_FORMAT_VERSION})`
|
|
125
|
+
);
|
|
126
|
+
}
|
|
127
|
+
if (typeof obj.createdAt !== "string" || obj.createdAt.length === 0) {
|
|
128
|
+
throw new Error("metadata.createdAt must be a non-empty string");
|
|
129
|
+
}
|
|
130
|
+
if (obj.note !== void 0 && typeof obj.note !== "string") {
|
|
131
|
+
throw new Error("metadata.note must be a string when present");
|
|
132
|
+
}
|
|
133
|
+
const kdf = parseKdf(obj.kdf);
|
|
134
|
+
const meta = {
|
|
135
|
+
format: METADATA_FORMAT,
|
|
136
|
+
formatVersion: METADATA_FORMAT_VERSION,
|
|
137
|
+
kdf,
|
|
138
|
+
createdAt: obj.createdAt
|
|
139
|
+
};
|
|
140
|
+
if (typeof obj.note === "string") {
|
|
141
|
+
meta.note = obj.note;
|
|
142
|
+
}
|
|
143
|
+
validateMetadata(meta);
|
|
144
|
+
return meta;
|
|
145
|
+
}
|
|
146
|
+
function parseKdf(value) {
|
|
147
|
+
if (typeof value !== "object" || value === null || Array.isArray(value)) {
|
|
148
|
+
throw new Error("metadata.kdf must be an object");
|
|
149
|
+
}
|
|
150
|
+
const k = value;
|
|
151
|
+
if (k.algorithm !== "scrypt" && k.algorithm !== "argon2id") {
|
|
152
|
+
throw new Error(`metadata.kdf.algorithm must be 'scrypt' or 'argon2id', got ${String(k.algorithm)}`);
|
|
153
|
+
}
|
|
154
|
+
if (typeof k.salt !== "string") {
|
|
155
|
+
throw new Error("metadata.kdf.salt must be a hex string");
|
|
156
|
+
}
|
|
157
|
+
hexToBytes(k.salt, KDF_SALT_LENGTH);
|
|
158
|
+
if (typeof k.params !== "object" || k.params === null || Array.isArray(k.params)) {
|
|
159
|
+
throw new Error("metadata.kdf.params must be an object");
|
|
160
|
+
}
|
|
161
|
+
const params = k.params;
|
|
162
|
+
if (k.algorithm === "scrypt") {
|
|
163
|
+
const required = ["N", "r", "p", "keyLength", "maxmem"];
|
|
164
|
+
for (const key of required) {
|
|
165
|
+
if (typeof params[key] !== "number" || !Number.isFinite(params[key])) {
|
|
166
|
+
throw new Error(`metadata.kdf.params.${key} must be a finite number`);
|
|
167
|
+
}
|
|
168
|
+
}
|
|
169
|
+
return {
|
|
170
|
+
algorithm: "scrypt",
|
|
171
|
+
params: {
|
|
172
|
+
N: params.N,
|
|
173
|
+
r: params.r,
|
|
174
|
+
p: params.p,
|
|
175
|
+
keyLength: params.keyLength,
|
|
176
|
+
maxmem: params.maxmem
|
|
177
|
+
},
|
|
178
|
+
salt: k.salt
|
|
179
|
+
};
|
|
180
|
+
}
|
|
181
|
+
const required2 = [
|
|
182
|
+
"memoryKiB",
|
|
183
|
+
"iterations",
|
|
184
|
+
"parallelism",
|
|
185
|
+
"keyLength"
|
|
186
|
+
];
|
|
187
|
+
for (const key of required2) {
|
|
188
|
+
if (typeof params[key] !== "number" || !Number.isFinite(params[key])) {
|
|
189
|
+
throw new Error(`metadata.kdf.params.${key} must be a finite number`);
|
|
190
|
+
}
|
|
191
|
+
}
|
|
192
|
+
return {
|
|
193
|
+
algorithm: "argon2id",
|
|
194
|
+
params: {
|
|
195
|
+
memoryKiB: params.memoryKiB,
|
|
196
|
+
iterations: params.iterations,
|
|
197
|
+
parallelism: params.parallelism,
|
|
198
|
+
keyLength: params.keyLength
|
|
199
|
+
},
|
|
200
|
+
salt: k.salt
|
|
201
|
+
};
|
|
202
|
+
}
|
|
203
|
+
function validateMetadata(meta) {
|
|
204
|
+
if (meta.format !== METADATA_FORMAT) {
|
|
205
|
+
throw new Error(`metadata.format must be ${METADATA_FORMAT}`);
|
|
206
|
+
}
|
|
207
|
+
if (meta.formatVersion !== METADATA_FORMAT_VERSION) {
|
|
208
|
+
throw new Error(`metadata.formatVersion must be ${METADATA_FORMAT_VERSION}`);
|
|
209
|
+
}
|
|
210
|
+
if (typeof meta.createdAt !== "string" || meta.createdAt.length === 0) {
|
|
211
|
+
throw new Error("metadata.createdAt must be a non-empty ISO-8601 string");
|
|
212
|
+
}
|
|
213
|
+
hexToBytes(meta.kdf.salt, KDF_SALT_LENGTH);
|
|
214
|
+
if (meta.kdf.algorithm === "scrypt") {
|
|
215
|
+
const { N, r, p, keyLength, maxmem } = meta.kdf.params;
|
|
216
|
+
if (!Number.isInteger(N) || N < 2 || N > 2 ** 30 || !Number.isInteger(Math.log2(N))) {
|
|
217
|
+
throw new Error("metadata.kdf.params.N must be a power of 2 in [2, 2^30]");
|
|
218
|
+
}
|
|
219
|
+
if (!Number.isInteger(r) || r < 1) {
|
|
220
|
+
throw new Error("metadata.kdf.params.r must be a positive integer");
|
|
221
|
+
}
|
|
222
|
+
if (!Number.isInteger(p) || p < 1) {
|
|
223
|
+
throw new Error("metadata.kdf.params.p must be a positive integer");
|
|
224
|
+
}
|
|
225
|
+
if (!Number.isInteger(keyLength) || keyLength !== 32) {
|
|
226
|
+
throw new Error("metadata.kdf.params.keyLength must be 32 (AES-256 requires a 32-byte key)");
|
|
227
|
+
}
|
|
228
|
+
if (!Number.isInteger(maxmem) || maxmem < 1024) {
|
|
229
|
+
throw new Error("metadata.kdf.params.maxmem must be a positive integer");
|
|
230
|
+
}
|
|
231
|
+
} else if (meta.kdf.algorithm === "argon2id") {
|
|
232
|
+
const { memoryKiB, iterations, parallelism, keyLength } = meta.kdf.params;
|
|
233
|
+
if (!Number.isInteger(memoryKiB) || memoryKiB < 8) {
|
|
234
|
+
throw new Error("metadata.kdf.params.memoryKiB must be \u2265 8");
|
|
235
|
+
}
|
|
236
|
+
if (!Number.isInteger(iterations) || iterations < 1) {
|
|
237
|
+
throw new Error("metadata.kdf.params.iterations must be a positive integer");
|
|
238
|
+
}
|
|
239
|
+
if (!Number.isInteger(parallelism) || parallelism < 1 || parallelism > 255) {
|
|
240
|
+
throw new Error("metadata.kdf.params.parallelism must be an integer in [1, 255]");
|
|
241
|
+
}
|
|
242
|
+
if (!Number.isInteger(keyLength) || keyLength !== 32) {
|
|
243
|
+
throw new Error("metadata.kdf.params.keyLength must be 32 (AES-256 requires a 32-byte key)");
|
|
244
|
+
}
|
|
245
|
+
}
|
|
246
|
+
}
|
|
247
|
+
function decodeMetadataSalt(meta) {
|
|
248
|
+
return hexToBytes(meta.kdf.salt, KDF_SALT_LENGTH);
|
|
249
|
+
}
|
|
250
|
+
|
|
251
|
+
export {
|
|
252
|
+
METADATA_FORMAT,
|
|
253
|
+
METADATA_FORMAT_VERSION,
|
|
254
|
+
buildMetadata,
|
|
255
|
+
serializeMetadata,
|
|
256
|
+
parseMetadata,
|
|
257
|
+
validateMetadata,
|
|
258
|
+
decodeMetadataSalt
|
|
259
|
+
};
|
|
@@ -0,0 +1,185 @@
|
|
|
1
|
+
import {
|
|
2
|
+
external_exports
|
|
3
|
+
} from "./chunk-XMSDA5WA.js";
|
|
4
|
+
|
|
5
|
+
// ../remnic-core/src/transfer/types.ts
|
|
6
|
+
var ExportManifestV1Schema = external_exports.object({
|
|
7
|
+
format: external_exports.literal("openclaw-engram-export"),
|
|
8
|
+
schemaVersion: external_exports.literal(1),
|
|
9
|
+
createdAt: external_exports.string(),
|
|
10
|
+
pluginVersion: external_exports.string(),
|
|
11
|
+
includesTranscripts: external_exports.boolean(),
|
|
12
|
+
files: external_exports.array(
|
|
13
|
+
external_exports.object({
|
|
14
|
+
path: external_exports.string(),
|
|
15
|
+
sha256: external_exports.string(),
|
|
16
|
+
bytes: external_exports.number().int().nonnegative()
|
|
17
|
+
})
|
|
18
|
+
)
|
|
19
|
+
});
|
|
20
|
+
var ExportMemoryRecordV1Schema = external_exports.object({
|
|
21
|
+
path: external_exports.string(),
|
|
22
|
+
content: external_exports.string()
|
|
23
|
+
});
|
|
24
|
+
var ExportBundleV1Schema = external_exports.object({
|
|
25
|
+
manifest: ExportManifestV1Schema,
|
|
26
|
+
records: external_exports.array(ExportMemoryRecordV1Schema)
|
|
27
|
+
});
|
|
28
|
+
var CAPSULE_ID_PATTERN = /^[A-Za-z0-9](?:[A-Za-z0-9]|-(?!-))*[A-Za-z0-9]$|^[A-Za-z0-9]$/;
|
|
29
|
+
var CapsuleIdSchema = external_exports.string().min(1, "capsule.id must not be empty").max(64, "capsule.id must be 64 characters or fewer").regex(
|
|
30
|
+
CAPSULE_ID_PATTERN,
|
|
31
|
+
"capsule.id must be alphanumeric with single dashes (no spaces, no leading/trailing dashes)"
|
|
32
|
+
);
|
|
33
|
+
var SemverLikeSchema = external_exports.string().min(1, "capsule.version must not be empty").regex(
|
|
34
|
+
/^\d+\.\d+\.\d+(?:-[0-9A-Za-z.-]+)?(?:\+[0-9A-Za-z.-]+)?$/,
|
|
35
|
+
"capsule.version must be a semver-like string (e.g. 1.0.0)"
|
|
36
|
+
);
|
|
37
|
+
var CapsuleRetrievalPolicySchema = external_exports.object({
|
|
38
|
+
/**
|
|
39
|
+
* Per-tier weight overrides applied during recall when the capsule is the
|
|
40
|
+
* active scope. Keys are tier names (e.g. `bm25`, `vector`, `graph`); values
|
|
41
|
+
* are non-negative finite multipliers. The set of valid keys is left open
|
|
42
|
+
* for now so future tiers do not break older manifests.
|
|
43
|
+
*/
|
|
44
|
+
tierWeights: external_exports.record(
|
|
45
|
+
external_exports.string().min(1),
|
|
46
|
+
external_exports.number().finite().nonnegative()
|
|
47
|
+
),
|
|
48
|
+
/**
|
|
49
|
+
* Whether the direct-answer fast path is allowed when this capsule is
|
|
50
|
+
* active. Operators may disable it for capsules whose contents should
|
|
51
|
+
* always flow through the full retrieval pipeline.
|
|
52
|
+
*/
|
|
53
|
+
directAnswerEnabled: external_exports.boolean()
|
|
54
|
+
});
|
|
55
|
+
var CapsuleIncludesSchema = external_exports.object({
|
|
56
|
+
taxonomy: external_exports.boolean(),
|
|
57
|
+
identityAnchors: external_exports.boolean(),
|
|
58
|
+
peerProfiles: external_exports.boolean(),
|
|
59
|
+
procedural: external_exports.boolean()
|
|
60
|
+
});
|
|
61
|
+
var CapsuleParentSchema = external_exports.object({
|
|
62
|
+
capsuleId: CapsuleIdSchema,
|
|
63
|
+
version: SemverLikeSchema,
|
|
64
|
+
/**
|
|
65
|
+
* Posix-relative path prefix under the fork's memory root where the parent
|
|
66
|
+
* capsule's records were placed. Typically `forks/<parent-capsule-id>`.
|
|
67
|
+
* Must be a non-empty string with no leading slash.
|
|
68
|
+
*/
|
|
69
|
+
forkRoot: external_exports.string().min(1, "capsule.parent.forkRoot must not be empty").refine((v) => !v.startsWith("/"), {
|
|
70
|
+
message: "capsule.parent.forkRoot must be a relative path (no leading slash)"
|
|
71
|
+
})
|
|
72
|
+
});
|
|
73
|
+
var CapsuleBlockSchema = external_exports.object({
|
|
74
|
+
id: CapsuleIdSchema,
|
|
75
|
+
version: SemverLikeSchema,
|
|
76
|
+
/**
|
|
77
|
+
* Taxonomy schema version the capsule was authored against. Free-form for
|
|
78
|
+
* now; later PRs may tighten this to a known taxonomy registry.
|
|
79
|
+
*/
|
|
80
|
+
schemaVersion: external_exports.string().min(1, "capsule.schemaVersion must not be empty"),
|
|
81
|
+
/**
|
|
82
|
+
* Optional reference to the parent capsule this one was forked or derived
|
|
83
|
+
* from. `null` (not `undefined`) is the explicit "no parent" sentinel so
|
|
84
|
+
* that round-trips through JSON do not silently drop the field.
|
|
85
|
+
*
|
|
86
|
+
* @deprecated Prefer {@link parent} (structured). This field is preserved
|
|
87
|
+
* for backward compatibility with V2 manifests written before PR 4/6.
|
|
88
|
+
*/
|
|
89
|
+
parentCapsule: external_exports.string().min(1).nullable(),
|
|
90
|
+
/**
|
|
91
|
+
* Structured fork-lineage pointer added in PR 4/6. When present, this
|
|
92
|
+
* capsule is a fork of the described parent. `null` is the explicit
|
|
93
|
+
* "not a fork" sentinel — round-trips through JSON cleanly without
|
|
94
|
+
* silently dropping the field.
|
|
95
|
+
*
|
|
96
|
+
* Defaults to `null` so that V2 manifests written before PR 4/6 (which
|
|
97
|
+
* omit this field) still parse without error. This preserves backward
|
|
98
|
+
* compatibility with the existing `makeV2Manifest()` test fixtures and
|
|
99
|
+
* any in-the-wild V2 archives produced by PR 2/6 and PR 3/6.
|
|
100
|
+
*
|
|
101
|
+
* Invariant: when `parent` is non-null, `parentCapsule` SHOULD equal
|
|
102
|
+
* `parent.capsuleId` for backward compatibility with readers that only
|
|
103
|
+
* understand the legacy field. `forkCapsule()` sets both.
|
|
104
|
+
*/
|
|
105
|
+
parent: CapsuleParentSchema.nullable().default(null),
|
|
106
|
+
description: external_exports.string(),
|
|
107
|
+
retrievalPolicy: CapsuleRetrievalPolicySchema,
|
|
108
|
+
includes: CapsuleIncludesSchema
|
|
109
|
+
});
|
|
110
|
+
var ExportManifestV2Schema = external_exports.object({
|
|
111
|
+
format: external_exports.literal("openclaw-engram-export"),
|
|
112
|
+
schemaVersion: external_exports.literal(2),
|
|
113
|
+
createdAt: external_exports.string(),
|
|
114
|
+
pluginVersion: external_exports.string(),
|
|
115
|
+
includesTranscripts: external_exports.boolean(),
|
|
116
|
+
files: external_exports.array(
|
|
117
|
+
external_exports.object({
|
|
118
|
+
path: external_exports.string(),
|
|
119
|
+
sha256: external_exports.string(),
|
|
120
|
+
bytes: external_exports.number().int().nonnegative()
|
|
121
|
+
})
|
|
122
|
+
),
|
|
123
|
+
capsule: CapsuleBlockSchema
|
|
124
|
+
});
|
|
125
|
+
var ExportBundleV2Schema = external_exports.object({
|
|
126
|
+
manifest: ExportManifestV2Schema,
|
|
127
|
+
records: external_exports.array(ExportMemoryRecordV1Schema)
|
|
128
|
+
});
|
|
129
|
+
function parseExportManifest(input) {
|
|
130
|
+
const version = typeof input === "object" && input !== null ? input.schemaVersion : void 0;
|
|
131
|
+
if (version === 2) {
|
|
132
|
+
const manifest = ExportManifestV2Schema.parse(input);
|
|
133
|
+
return {
|
|
134
|
+
capsuleVersion: 2,
|
|
135
|
+
manifest,
|
|
136
|
+
capsule: manifest.capsule
|
|
137
|
+
};
|
|
138
|
+
}
|
|
139
|
+
if (version === 1) {
|
|
140
|
+
const manifest = ExportManifestV1Schema.parse(input);
|
|
141
|
+
return { capsuleVersion: 1, manifest, capsule: null };
|
|
142
|
+
}
|
|
143
|
+
const v1 = ExportManifestV1Schema.safeParse(input);
|
|
144
|
+
if (v1.success) {
|
|
145
|
+
return { capsuleVersion: 1, manifest: v1.data, capsule: null };
|
|
146
|
+
}
|
|
147
|
+
const v2 = ExportManifestV2Schema.safeParse(input);
|
|
148
|
+
if (v2.success) {
|
|
149
|
+
return {
|
|
150
|
+
capsuleVersion: 2,
|
|
151
|
+
manifest: v2.data,
|
|
152
|
+
capsule: v2.data.capsule
|
|
153
|
+
};
|
|
154
|
+
}
|
|
155
|
+
throw v2.error;
|
|
156
|
+
}
|
|
157
|
+
function parseExportBundle(input) {
|
|
158
|
+
if (typeof input !== "object" || input === null) {
|
|
159
|
+
ExportBundleV1Schema.parse(input);
|
|
160
|
+
throw new Error("unreachable");
|
|
161
|
+
}
|
|
162
|
+
const manifestRaw = input.manifest;
|
|
163
|
+
const normalized = parseExportManifest(manifestRaw);
|
|
164
|
+
if (normalized.capsuleVersion === 2) {
|
|
165
|
+
const bundle2 = ExportBundleV2Schema.parse(input);
|
|
166
|
+
return { capsuleVersion: 2, bundle: bundle2, capsule: bundle2.manifest.capsule };
|
|
167
|
+
}
|
|
168
|
+
const bundle = ExportBundleV1Schema.parse(input);
|
|
169
|
+
return { capsuleVersion: 1, bundle, capsule: null };
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
export {
|
|
173
|
+
ExportManifestV1Schema,
|
|
174
|
+
ExportMemoryRecordV1Schema,
|
|
175
|
+
ExportBundleV1Schema,
|
|
176
|
+
CAPSULE_ID_PATTERN,
|
|
177
|
+
CapsuleRetrievalPolicySchema,
|
|
178
|
+
CapsuleIncludesSchema,
|
|
179
|
+
CapsuleParentSchema,
|
|
180
|
+
CapsuleBlockSchema,
|
|
181
|
+
ExportManifestV2Schema,
|
|
182
|
+
ExportBundleV2Schema,
|
|
183
|
+
parseExportManifest,
|
|
184
|
+
parseExportBundle
|
|
185
|
+
};
|