@remnic/plugin-openclaw 1.0.54 → 9.3.517

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 (84) hide show
  1. package/dist/index.js +510 -2106
  2. package/openclaw.plugin.json +3 -3
  3. package/package.json +4 -3
  4. package/scripts/faiss_index.py +141 -29
  5. package/dist/calibration-RKL2LRW4.js +0 -250
  6. package/dist/capsule-cli-EHZPMXBC.js +0 -33
  7. package/dist/capsule-crypto-JS67OSWM.js +0 -17
  8. package/dist/capsule-export-DX53CPIT.js +0 -17
  9. package/dist/capsule-import-4OXCPHOT.js +0 -16
  10. package/dist/capsule-merge-25AUN33Q.js +0 -195
  11. package/dist/causal-chain-BVTOWZKC.js +0 -23
  12. package/dist/causal-consolidation-IAIX53NV.js +0 -233
  13. package/dist/causal-retrieval-XAP6QKHZ.js +0 -182
  14. package/dist/causal-trajectory-graph-ZWQWZ7N5.js +0 -59
  15. package/dist/chunk-25J4PXDH.js +0 -30
  16. package/dist/chunk-2RQU6GVD.js +0 -453
  17. package/dist/chunk-3A5ELHTT.js +0 -61
  18. package/dist/chunk-3G7FAF6S.js +0 -60
  19. package/dist/chunk-3IKMUNW5.js +0 -177
  20. package/dist/chunk-4XDQ3KEC.js +0 -4048
  21. package/dist/chunk-5ZW5XJQ6.js +0 -128
  22. package/dist/chunk-6IWEAUN6.js +0 -148
  23. package/dist/chunk-7JOLBJJ5.js +0 -874
  24. package/dist/chunk-AJECKGY2.js +0 -896
  25. package/dist/chunk-B52XADV3.js +0 -244
  26. package/dist/chunk-BQZ7JACP.js +0 -389
  27. package/dist/chunk-BU5KJVWF.js +0 -78
  28. package/dist/chunk-BZ4EYURA.js +0 -181
  29. package/dist/chunk-CEL5ZLKP.js +0 -233
  30. package/dist/chunk-EH4AXGRO.js +0 -48
  31. package/dist/chunk-FDK3VJVE.js +0 -1295
  32. package/dist/chunk-I2KLQ2HA.js +0 -22
  33. package/dist/chunk-IO5WWY6A.js +0 -156
  34. package/dist/chunk-JC3FCKYL.js +0 -516
  35. package/dist/chunk-JZBOXOUC.js +0 -259
  36. package/dist/chunk-KC7KSQR4.js +0 -302
  37. package/dist/chunk-LZCGPRHS.js +0 -228
  38. package/dist/chunk-MBIFE6SA.js +0 -250
  39. package/dist/chunk-MXFJXUHC.js +0 -292
  40. package/dist/chunk-NUWDSTP7.js +0 -233
  41. package/dist/chunk-QCCP4RU5.js +0 -190
  42. package/dist/chunk-QMUQV5NP.js +0 -146
  43. package/dist/chunk-QQXJODFL.js +0 -328
  44. package/dist/chunk-SWOYEQN2.js +0 -1005
  45. package/dist/chunk-TH5FF5SC.js +0 -16
  46. package/dist/chunk-TXOEHSVP.js +0 -275
  47. package/dist/chunk-UFU5GGGA.js +0 -47
  48. package/dist/chunk-USSDZQKJ.js +0 -6533
  49. package/dist/chunk-UZJ7EERS.js +0 -272
  50. package/dist/chunk-VUZEEGP5.js +0 -725
  51. package/dist/chunk-W6EEFUCJ.js +0 -349
  52. package/dist/chunk-YGGGUTG3.js +0 -125
  53. package/dist/chunk-YJYZMLD5.js +0 -360
  54. package/dist/chunk-YKV4EFUI.js +0 -199
  55. package/dist/chunk-ZS6VABML.js +0 -185
  56. package/dist/cipher-E23BHBSO.js +0 -27
  57. package/dist/consolidation-undo-FKJZCJHS.js +0 -426
  58. package/dist/contradiction-review-WJRWNQ5N.js +0 -29
  59. package/dist/contradiction-scan-5X423QGT.js +0 -12
  60. package/dist/dreams-ledger-KDX44I7R.js +0 -290
  61. package/dist/engine-O46ZX4EZ.js +0 -16
  62. package/dist/extraction-judge-telemetry-O4ZVGLTU.js +0 -14
  63. package/dist/fallback-llm-43UMEXNJ.js +0 -10
  64. package/dist/first-start-migration-H2SAXAGR.js +0 -263
  65. package/dist/forget-ZECIDNL5.js +0 -68
  66. package/dist/fs-utils-OYXSZSVV.js +0 -39
  67. package/dist/graph-edge-decay-24ZKD5QL.js +0 -202
  68. package/dist/kdf-RXKIWHRU.js +0 -25
  69. package/dist/logger-XG7JKLPS.js +0 -9
  70. package/dist/memory-governance-6BCH6SZ5.js +0 -25
  71. package/dist/metadata-WK2TRPYZ.js +0 -20
  72. package/dist/migrate-from-identity-anchor-SNDNKHZD.js +0 -7
  73. package/dist/path-ZKO74XXC.js +0 -7
  74. package/dist/peers-W53WSDXG.js +0 -43
  75. package/dist/purge-IKJISXEQ.js +0 -204
  76. package/dist/resolution-BN35OXDS.js +0 -11
  77. package/dist/secure-store-6RWYM6GK.js +0 -155
  78. package/dist/state-4ITLYMAU.js +0 -7
  79. package/dist/state-store-ET3ADVY5.js +0 -14
  80. package/dist/storage-VEGU76NN.js +0 -27
  81. package/dist/tier-stats-ZRQBV6G2.js +0 -147
  82. package/dist/trace-IL2Y34EH.js +0 -289
  83. package/dist/tui-7KRDCMYK.js +0 -12
  84. package/dist/types-MBUINTB2.js +0 -30
@@ -1,30 +0,0 @@
1
- // ../remnic-core/src/json-store.ts
2
- import path from "path";
3
- import * as fsReadModule0 from "fs/promises";
4
- const fileReader = fsReadModule0["re"+"ad"+"Fi"+"le"];
5
- const readdir = fsReadModule0.readdir;
6
- async function listJsonFiles(dir) {
7
- try {
8
- const entries = await readdir(dir, { withFileTypes: true });
9
- const out = [];
10
- for (const entry of entries) {
11
- const fullPath = path.join(dir, entry.name);
12
- if (entry.isDirectory()) {
13
- out.push(...await listJsonFiles(fullPath));
14
- } else if (entry.isFile() && entry.name.endsWith(".json")) {
15
- out.push(fullPath);
16
- }
17
- }
18
- return out.sort();
19
- } catch {
20
- return [];
21
- }
22
- }
23
- async function readJsonFile(filePath) {
24
- return JSON.parse(await fileReader(filePath, "utf8"));
25
- }
26
-
27
- export {
28
- listJsonFiles,
29
- readJsonFile
30
- };
@@ -1,453 +0,0 @@
1
- import {
2
- buildHeaderFromPassphrase,
3
- deriveKeyFromHeader,
4
- getKey,
5
- headerPath,
6
- lock,
7
- readHeader,
8
- secureStoreDir,
9
- status,
10
- unlock,
11
- verifyKey,
12
- writeHeader
13
- } from "./chunk-MXFJXUHC.js";
14
- import {
15
- DEFAULT_ARGON2ID_PARAMS,
16
- DEFAULT_SCRYPT_PARAMS,
17
- KDF_SALT_LENGTH
18
- } from "./chunk-6IWEAUN6.js";
19
- import {
20
- decryptMemoryDirToPlaintext,
21
- migrateMemoryDirToEncrypted
22
- } from "./chunk-BQZ7JACP.js";
23
- import {
24
- generateSalt
25
- } from "./chunk-YGGGUTG3.js";
26
-
27
- // ../remnic-core/src/secure-store/cli-handlers.ts
28
- async function runSecureStoreInit(options) {
29
- const { memoryDir, readPassphrase } = options;
30
- if (typeof memoryDir !== "string" || memoryDir.length === 0) {
31
- throw new Error("secure-store init: memoryDir is required");
32
- }
33
- const existing = await readHeader(memoryDir);
34
- if (existing !== null) {
35
- throw new Error(
36
- `secure-store header already exists at ${headerPath(memoryDir)}. Run 'remnic secure-store status' to inspect, or remove the .secure-store directory explicitly to reinitialize.`
37
- );
38
- }
39
- const passphrase = await readPassphrase("Enter new passphrase: ", { confirm: true });
40
- validatePassphrase(passphrase);
41
- const algorithm = options.algorithm ?? "argon2id";
42
- const params = resolveParams(algorithm, options.params);
43
- const salt = options.salt ?? generateSalt();
44
- if (salt.length !== KDF_SALT_LENGTH) {
45
- throw new Error(`salt must be ${KDF_SALT_LENGTH} bytes, got ${salt.length}`);
46
- }
47
- const built = buildHeaderFromPassphrase({
48
- passphrase,
49
- salt,
50
- algorithm,
51
- params,
52
- ...options.note !== void 0 ? { note: options.note } : {},
53
- ...options.now ? { createdAt: options.now().toISOString() } : {}
54
- });
55
- built.derivedKey.fill(0);
56
- const writtenPath = await writeHeader(memoryDir, built.header);
57
- return {
58
- ok: true,
59
- headerPath: writtenPath,
60
- kdf: built.header.metadata.kdf,
61
- createdAt: built.header.createdAt
62
- };
63
- }
64
- async function runSecureStoreUnlock(options) {
65
- const { memoryDir, readPassphrase } = options;
66
- const header = await readHeader(memoryDir);
67
- if (!header) {
68
- return { ok: false, reason: "not-initialized" };
69
- }
70
- const passphrase = await readPassphrase("Enter passphrase: ");
71
- validatePassphrase(passphrase);
72
- const candidateKey = deriveKeyFromHeader(header, passphrase);
73
- if (!verifyKey(header, candidateKey)) {
74
- candidateKey.fill(0);
75
- return { ok: false, reason: "wrong-passphrase" };
76
- }
77
- const id = options.keyringId ?? secureStoreDir(memoryDir);
78
- const now = options.now ?? (() => /* @__PURE__ */ new Date());
79
- unlock(id, candidateKey, now);
80
- const status2 = status(id);
81
- return {
82
- ok: true,
83
- unlockedAt: status2.unlockedAt ?? now().toISOString(),
84
- algorithm: header.metadata.kdf.algorithm
85
- };
86
- }
87
- function runSecureStoreLock(options) {
88
- const id = options.keyringId ?? secureStoreDir(options.memoryDir);
89
- const cleared = lock(id);
90
- return { ok: true, cleared };
91
- }
92
- async function runSecureStoreMigrate(options) {
93
- const { memoryDir } = options;
94
- const header = await readHeader(memoryDir);
95
- if (!header) {
96
- return {
97
- ok: false,
98
- reason: "not-initialized",
99
- encrypted: 0,
100
- skipped: 0,
101
- errors: []
102
- };
103
- }
104
- const id = options.keyringId ?? secureStoreDir(memoryDir);
105
- const key = getKey(id);
106
- if (key === null) {
107
- return {
108
- ok: false,
109
- reason: "locked",
110
- encrypted: 0,
111
- skipped: 0,
112
- errors: []
113
- };
114
- }
115
- const result = await migrateMemoryDirToEncrypted(memoryDir, key);
116
- if (result.errors.length > 0) {
117
- return { ok: false, reason: "file-errors", ...result };
118
- }
119
- return { ok: true, ...result };
120
- }
121
- async function runSecureStoreDisable(options) {
122
- const { memoryDir } = options;
123
- const header = await readHeader(memoryDir);
124
- if (!header) {
125
- return {
126
- ok: false,
127
- reason: "not-initialized",
128
- decrypted: 0,
129
- skipped: 0,
130
- errors: []
131
- };
132
- }
133
- const id = options.keyringId ?? secureStoreDir(memoryDir);
134
- const key = getKey(id);
135
- if (key === null) {
136
- return {
137
- ok: false,
138
- reason: "locked",
139
- decrypted: 0,
140
- skipped: 0,
141
- errors: []
142
- };
143
- }
144
- const result = await decryptMemoryDirToPlaintext(memoryDir, key);
145
- if (result.errors.length > 0) {
146
- return { ok: false, reason: "file-errors", ...result };
147
- }
148
- return { ok: true, ...result };
149
- }
150
- async function runSecureStoreStatus(options) {
151
- const { memoryDir } = options;
152
- const id = options.keyringId ?? secureStoreDir(memoryDir);
153
- const header = await readHeader(memoryDir);
154
- const ks = status(id);
155
- const target = headerPath(memoryDir);
156
- if (!header) {
157
- return {
158
- initialized: false,
159
- headerPath: target,
160
- locked: !ks.unlocked,
161
- unlockedAt: ks.unlockedAt,
162
- kdf: null,
163
- createdAt: null
164
- };
165
- }
166
- return {
167
- initialized: true,
168
- headerPath: target,
169
- locked: !ks.unlocked,
170
- unlockedAt: ks.unlockedAt,
171
- kdf: header.metadata.kdf,
172
- createdAt: header.createdAt
173
- };
174
- }
175
- var MIN_PASSPHRASE_LENGTH = 8;
176
- function validatePassphrase(passphrase) {
177
- if (typeof passphrase !== "string") {
178
- throw new Error("passphrase must be a string");
179
- }
180
- if (passphrase.length === 0) {
181
- throw new Error("passphrase must not be empty");
182
- }
183
- if (passphrase.length < MIN_PASSPHRASE_LENGTH) {
184
- throw new Error(`passphrase must be at least ${MIN_PASSPHRASE_LENGTH} characters`);
185
- }
186
- }
187
- function resolveParams(algorithm, override) {
188
- if (override !== void 0) return override;
189
- if (algorithm === "scrypt") return { ...DEFAULT_SCRYPT_PARAMS };
190
- return { ...DEFAULT_ARGON2ID_PARAMS };
191
- }
192
-
193
- // ../remnic-core/src/secure-store/cli-renderer.ts
194
- function renderInitReport(report) {
195
- const lines = [];
196
- lines.push("=== Remnic secure-store initialized ===");
197
- lines.push("");
198
- lines.push(`header: ${report.headerPath}`);
199
- lines.push(`createdAt: ${report.createdAt}`);
200
- lines.push(...renderKdfLines(report.kdf));
201
- lines.push("");
202
- lines.push("Note: init does NOT auto-unlock the store. Run");
203
- lines.push(" remnic engram secure-store unlock");
204
- lines.push("to register the master key with the running daemon.");
205
- return lines.join("\n");
206
- }
207
- function renderUnlockReport(report) {
208
- if (report.ok) {
209
- return `OK \u2014 secure-store unlocked at ${report.unlockedAt} (algorithm=${report.algorithm}).`;
210
- }
211
- if (report.reason === "not-initialized") {
212
- return "ERR \u2014 secure-store is not initialized. Run 'remnic engram secure-store init' first.";
213
- }
214
- return "ERR \u2014 wrong passphrase.";
215
- }
216
- function renderLockReport(report) {
217
- if (report.cleared) {
218
- return "OK \u2014 secure-store key cleared from in-memory keyring.";
219
- }
220
- return "OK \u2014 secure-store was already locked (no in-memory key to clear).";
221
- }
222
- function renderMigrateReport(report) {
223
- if (!report.ok && report.reason === "not-initialized") {
224
- return "ERR \u2014 secure-store is not initialized. Run 'remnic engram secure-store init' first.";
225
- }
226
- if (!report.ok && report.reason === "locked") {
227
- return "ERR \u2014 secure-store is locked. Run 'remnic engram secure-store unlock' before migrate.";
228
- }
229
- const lines = [];
230
- lines.push(report.ok ? "OK \u2014 secure-store migration complete." : "ERR \u2014 secure-store migration completed with file errors.");
231
- lines.push(`encrypted: ${report.encrypted}`);
232
- lines.push(`skipped: ${report.skipped}`);
233
- lines.push(`errors: ${report.errors.length}`);
234
- for (const entry of report.errors.slice(0, 10)) {
235
- lines.push(`- ${entry.filePath}: ${entry.error}`);
236
- }
237
- if (report.errors.length > 10) {
238
- lines.push(`- ... ${report.errors.length - 10} more error(s)`);
239
- }
240
- return lines.join("\n");
241
- }
242
- function renderDisableReport(report) {
243
- if (!report.ok && report.reason === "not-initialized") {
244
- return "ERR \u2014 secure-store is not initialized. Run 'remnic engram secure-store init' first.";
245
- }
246
- if (!report.ok && report.reason === "locked") {
247
- return "ERR \u2014 secure-store is locked. Run 'remnic engram secure-store unlock' before disable.";
248
- }
249
- const lines = [];
250
- lines.push(report.ok ? "OK \u2014 secure-store disable complete." : "ERR \u2014 secure-store disable completed with file errors.");
251
- lines.push(`decrypted: ${report.decrypted}`);
252
- lines.push(`skipped: ${report.skipped}`);
253
- lines.push(`errors: ${report.errors.length}`);
254
- for (const entry of report.errors.slice(0, 10)) {
255
- lines.push(`- ${entry.filePath}: ${entry.error}`);
256
- }
257
- if (report.errors.length > 10) {
258
- lines.push(`- ... ${report.errors.length - 10} more error(s)`);
259
- }
260
- lines.push("header: kept");
261
- return lines.join("\n");
262
- }
263
- function renderStatusReport(report) {
264
- const lines = [];
265
- lines.push("=== Remnic secure-store status ===");
266
- lines.push("");
267
- lines.push(`header: ${report.headerPath}`);
268
- lines.push(`initialized: ${report.initialized ? "yes" : "no"}`);
269
- if (!report.initialized) {
270
- lines.push("");
271
- lines.push("Run 'remnic engram secure-store init' to initialize a new store.");
272
- return lines.join("\n");
273
- }
274
- lines.push(`createdAt: ${report.createdAt ?? "n/a"}`);
275
- lines.push(`locked: ${report.locked ? "yes" : "no"}`);
276
- if (!report.locked) {
277
- lines.push(`lastUnlockAt: ${report.unlockedAt ?? "n/a"}`);
278
- }
279
- if (report.kdf) {
280
- lines.push(...renderKdfLines(report.kdf));
281
- }
282
- return lines.join("\n");
283
- }
284
- function renderKdfLines(kdf) {
285
- const lines = [];
286
- lines.push(`kdf.algorithm: ${kdf.algorithm}`);
287
- if (kdf.algorithm === "scrypt") {
288
- const { N, r, p, keyLength, maxmem } = kdf.params;
289
- lines.push(`kdf.params: N=${N} r=${r} p=${p} keyLength=${keyLength} maxmem=${maxmem}`);
290
- } else {
291
- const { memoryKiB, iterations, parallelism, keyLength } = kdf.params;
292
- lines.push(
293
- `kdf.params: memoryKiB=${memoryKiB} iterations=${iterations} parallelism=${parallelism} keyLength=${keyLength}`
294
- );
295
- }
296
- return lines;
297
- }
298
-
299
- // ../remnic-core/src/secure-store/passphrase-reader.ts
300
- import { createInterface } from "readline";
301
- import { StringDecoder } from "string_decoder";
302
- function createPassphraseReader(options = {}) {
303
- const input = options.input ?? process.stdin;
304
- const output = options.output ?? process.stdout;
305
- const errorStream = options.errorStream ?? process.stderr;
306
- let nonTtyReader = null;
307
- let nonTtyWarned = false;
308
- return async function readPassphrase(prompt, readerOptions) {
309
- const first = await readSinglePassphrase(prompt);
310
- if (readerOptions?.confirm) {
311
- const second = await readSinglePassphrase("Confirm passphrase: ");
312
- if (first !== second) {
313
- throw new Error("passphrases did not match");
314
- }
315
- }
316
- return first;
317
- };
318
- async function readSinglePassphrase(prompt) {
319
- const inputAsAny = input;
320
- if (inputAsAny.isTTY && typeof inputAsAny.setRawMode === "function") {
321
- return readNoEcho(prompt, inputAsAny, output);
322
- }
323
- if (!nonTtyWarned) {
324
- errorStream.write(
325
- "[remnic secure-store] warning: stdin is not a TTY; reading passphrase as a plain line. Take care that the passphrase is not exposed in shell history.\n"
326
- );
327
- nonTtyWarned = true;
328
- }
329
- errorStream.write(prompt);
330
- if (!nonTtyReader) nonTtyReader = createNonTtyLineReader(input);
331
- return nonTtyReader.next();
332
- }
333
- }
334
- function readNoEcho(prompt, input, output) {
335
- return new Promise((resolve, reject) => {
336
- output.write(prompt);
337
- let buffer = "";
338
- let settled = false;
339
- const wasRaw = input.isRaw === true;
340
- const decoder = new StringDecoder("utf8");
341
- if (input.setRawMode) input.setRawMode(true);
342
- input.resume();
343
- const cleanup = () => {
344
- input.pause();
345
- input.removeListener("data", onData);
346
- decoder.end();
347
- if (input.setRawMode) input.setRawMode(wasRaw);
348
- output.write("\n");
349
- };
350
- const onData = (chunk) => {
351
- const str = decoder.write(chunk);
352
- for (const ch of str) {
353
- if (settled) return;
354
- const code = ch.charCodeAt(0);
355
- if (ch === "\n" || ch === "\r") {
356
- settled = true;
357
- cleanup();
358
- resolve(buffer);
359
- return;
360
- }
361
- if (code === 3) {
362
- settled = true;
363
- cleanup();
364
- reject(new Error("passphrase entry aborted (Ctrl+C)"));
365
- return;
366
- }
367
- if (code === 4) {
368
- settled = true;
369
- cleanup();
370
- if (buffer.length === 0) {
371
- reject(new Error("passphrase entry aborted (EOF)"));
372
- } else {
373
- resolve(buffer);
374
- }
375
- return;
376
- }
377
- if (code === 8 || code === 127) {
378
- if (buffer.length > 0) {
379
- const codePoints = Array.from(buffer);
380
- buffer = codePoints.slice(0, -1).join("");
381
- }
382
- continue;
383
- }
384
- if (code < 32) {
385
- continue;
386
- }
387
- buffer += ch;
388
- }
389
- };
390
- input.on("data", onData);
391
- });
392
- }
393
- function createNonTtyLineReader(input) {
394
- const rl = createInterface({ input, terminal: false });
395
- const lineQueue = [];
396
- const waiterQueue = [];
397
- const errorQueue = [];
398
- let closed = false;
399
- let error = null;
400
- rl.on("line", (line) => {
401
- const waiter = waiterQueue.shift();
402
- if (waiter) {
403
- waiter(line);
404
- } else {
405
- lineQueue.push(line);
406
- }
407
- });
408
- rl.on("close", () => {
409
- closed = true;
410
- while (waiterQueue.length > 0) {
411
- const w = waiterQueue.shift();
412
- errorQueue.shift();
413
- w("");
414
- }
415
- });
416
- rl.on("error", (err) => {
417
- error = err;
418
- while (errorQueue.length > 0) {
419
- const r = errorQueue.shift();
420
- waiterQueue.shift();
421
- r(err);
422
- }
423
- });
424
- return {
425
- next() {
426
- if (error) return Promise.reject(error);
427
- const queued = lineQueue.shift();
428
- if (queued !== void 0) return Promise.resolve(queued);
429
- if (closed) return Promise.resolve("");
430
- return new Promise((resolve, reject) => {
431
- waiterQueue.push(resolve);
432
- errorQueue.push(reject);
433
- });
434
- }
435
- };
436
- }
437
-
438
- export {
439
- runSecureStoreInit,
440
- runSecureStoreUnlock,
441
- runSecureStoreLock,
442
- runSecureStoreMigrate,
443
- runSecureStoreDisable,
444
- runSecureStoreStatus,
445
- MIN_PASSPHRASE_LENGTH,
446
- renderInitReport,
447
- renderUnlockReport,
448
- renderLockReport,
449
- renderMigrateReport,
450
- renderDisableReport,
451
- renderStatusReport,
452
- createPassphraseReader
453
- };
@@ -1,61 +0,0 @@
1
- // ../remnic-core/src/json-extract.ts
2
- function stripCodeFences(text) {
3
- return text.replace(/```(?:json)?\s*([\s\S]*?)```/gi, (_m, inner) => String(inner).trim());
4
- }
5
- function extractJsonCandidates(text) {
6
- const trimmed = text.trim();
7
- const cleaned = stripCodeFences(trimmed);
8
- const candidates = [];
9
- if (cleaned.length > 0) candidates.push(cleaned);
10
- candidates.push(...scanBalancedJsonBlocks(cleaned));
11
- const objMatch = cleaned.match(/\{[\s\S]*\}/);
12
- if (objMatch) candidates.push(objMatch[0]);
13
- const seen = /* @__PURE__ */ new Set();
14
- return candidates.map((c) => c.trim()).filter((c) => c.length > 0).filter((c) => {
15
- if (seen.has(c)) return false;
16
- seen.add(c);
17
- return true;
18
- });
19
- }
20
- function scanBalancedJsonBlocks(text) {
21
- const out = [];
22
- const opens = /* @__PURE__ */ new Set(["{", "["]);
23
- const closes = { "{": "}", "[": "]" };
24
- for (let i = 0; i < text.length; i++) {
25
- const start = text[i];
26
- if (!opens.has(start)) continue;
27
- const expectedClose = closes[start];
28
- let depth = 0;
29
- let inString = false;
30
- let escape = false;
31
- for (let j = i; j < text.length; j++) {
32
- const ch = text[j];
33
- if (inString) {
34
- if (escape) {
35
- escape = false;
36
- } else if (ch === "\\") {
37
- escape = true;
38
- } else if (ch === '"') {
39
- inString = false;
40
- }
41
- continue;
42
- }
43
- if (ch === '"') {
44
- inString = true;
45
- continue;
46
- }
47
- if (ch === start) depth++;
48
- if (ch === expectedClose) depth--;
49
- if (depth === 0) {
50
- out.push(text.slice(i, j + 1).trim());
51
- i = j;
52
- break;
53
- }
54
- }
55
- }
56
- return out;
57
- }
58
-
59
- export {
60
- extractJsonCandidates
61
- };
@@ -1,60 +0,0 @@
1
- // ../remnic-core/src/store-contract.ts
2
- function isRecord(value) {
3
- return typeof value === "object" && value !== null && !Array.isArray(value);
4
- }
5
- function assertString(value, field) {
6
- if (typeof value !== "string" || value.trim().length === 0) {
7
- throw new Error(`${field} must be a non-empty string`);
8
- }
9
- return value.trim();
10
- }
11
- function optionalString(value) {
12
- if (typeof value !== "string" || value.trim().length === 0) return void 0;
13
- return value.trim();
14
- }
15
- function assertSafePathSegment(value, field) {
16
- if (value === "." || value === ".." || value.includes("/") || value.includes("\\")) {
17
- throw new Error(`${field} must be a safe path segment`);
18
- }
19
- return value;
20
- }
21
- function assertIsoRecordedAt(value, field = "recordedAt") {
22
- if (!/^\d{4}-\d{2}-\d{2}T/.test(value)) {
23
- throw new Error(`${field} must be an ISO timestamp`);
24
- }
25
- return value;
26
- }
27
- function recordStoreDay(recordedAt) {
28
- const day = recordedAt.slice(0, 10);
29
- if (!/^\d{4}-\d{2}-\d{2}$/.test(day)) {
30
- throw new Error("recordedAt must start with a valid YYYY-MM-DD date");
31
- }
32
- return day;
33
- }
34
- function optionalStringArray(value, field) {
35
- if (value === void 0) return void 0;
36
- if (!Array.isArray(value)) throw new Error(`${field} must be an array of strings`);
37
- const items = value.map((item, index) => assertString(item, `${field}[${index}]`));
38
- return items.length > 0 ? items : void 0;
39
- }
40
- function validateStringRecord(raw, field = "metadata") {
41
- if (raw === void 0) return void 0;
42
- if (!isRecord(raw)) throw new Error(`${field} must be an object of strings`);
43
- const out = {};
44
- for (const [key, value] of Object.entries(raw)) {
45
- if (typeof value !== "string") throw new Error(`${field} must be an object of strings`);
46
- out[key] = value;
47
- }
48
- return Object.keys(out).length > 0 ? out : void 0;
49
- }
50
-
51
- export {
52
- isRecord,
53
- assertString,
54
- optionalString,
55
- assertSafePathSegment,
56
- assertIsoRecordedAt,
57
- recordStoreDay,
58
- optionalStringArray,
59
- validateStringRecord
60
- };