@remnic/cli 9.54.3 → 9.54.5
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/index.js +56 -41
- package/package.json +31 -31
package/dist/index.js
CHANGED
|
@@ -299,13 +299,14 @@ import {
|
|
|
299
299
|
} from "@remnic/core/reconcile/manifest.js";
|
|
300
300
|
|
|
301
301
|
// src/offline-storage-io.ts
|
|
302
|
-
import {
|
|
302
|
+
import { createDecipheriv, createHash } from "crypto";
|
|
303
303
|
import fs3 from "fs";
|
|
304
|
+
import { lstat, mkdtemp, readdir, rm } from "fs/promises";
|
|
304
305
|
import path from "path";
|
|
305
|
-
import { createHash, createDecipheriv } from "crypto";
|
|
306
306
|
import {
|
|
307
307
|
OFFLINE_SYNC_FILE_CONTENT_TRANSFER_CHUNK_BYTES,
|
|
308
|
-
StorageManager
|
|
308
|
+
StorageManager,
|
|
309
|
+
createSupportPassportPrivateFileExclusion
|
|
309
310
|
} from "@remnic/core";
|
|
310
311
|
import { OFFLINE_DECRYPT_STAGING_DIR_PREFIX } from "@remnic/core/offline-sync-exclude-globs";
|
|
311
312
|
import {
|
|
@@ -326,6 +327,28 @@ import {
|
|
|
326
327
|
readHeader,
|
|
327
328
|
secureStoreDir
|
|
328
329
|
} from "@remnic/core/secure-store";
|
|
330
|
+
var OFFLINE_SYNC_EXCLUSION_CONCURRENCY = 16;
|
|
331
|
+
function resolveOfflineDirectHydrationPath(memoryDir, relPath) {
|
|
332
|
+
const base = path.resolve(memoryDir);
|
|
333
|
+
const target = path.resolve(base, relPath);
|
|
334
|
+
const relative = path.relative(base, target);
|
|
335
|
+
if (relative === "" || relative === ".." || relative.startsWith(`..${path.sep}`) || path.isAbsolute(relative)) {
|
|
336
|
+
throw new Error(`offline sync direct hydration path escapes memory dir: ${relPath}`);
|
|
337
|
+
}
|
|
338
|
+
return target;
|
|
339
|
+
}
|
|
340
|
+
async function filterOfflineSyncBaseFiles(memoryDir, files, excludeFile) {
|
|
341
|
+
const excluded = new Array(files.length);
|
|
342
|
+
for (let offset = 0; offset < files.length; offset += OFFLINE_SYNC_EXCLUSION_CONCURRENCY) {
|
|
343
|
+
await Promise.all(
|
|
344
|
+
files.slice(offset, offset + OFFLINE_SYNC_EXCLUSION_CONCURRENCY).map(async (file, index) => {
|
|
345
|
+
const filePath = resolveOfflineDirectHydrationPath(memoryDir, file.path);
|
|
346
|
+
excluded[offset + index] = await excludeFile({ root: memoryDir, path: file.path, filePath });
|
|
347
|
+
})
|
|
348
|
+
);
|
|
349
|
+
}
|
|
350
|
+
return files.filter((_file, index) => excluded[index] === false);
|
|
351
|
+
}
|
|
329
352
|
async function createConfiguredOfflineStorage(memoryDir, secureStoreEncryptOnWrite = true) {
|
|
330
353
|
const storage = new StorageManager(memoryDir);
|
|
331
354
|
const header = await readHeader(memoryDir);
|
|
@@ -365,6 +388,7 @@ async function createOfflineStorageIo(memoryDir, configuredStorage) {
|
|
|
365
388
|
await cleanupOrphanedOfflineDecryptStaging(memoryDir);
|
|
366
389
|
const { storage, secureStoreKey } = configuredStorage ?? await createConfiguredOfflineStorage(memoryDir);
|
|
367
390
|
return {
|
|
391
|
+
excludeFile: createSupportPassportPrivateFileExclusion(storage),
|
|
368
392
|
readFile: async ({ filePath }) => storage.readOfflineSyncFile(filePath),
|
|
369
393
|
readDeletionRevisions: () => storage.readDeletionRevisions(),
|
|
370
394
|
readFileDigest: async ({ filePath }) => {
|
|
@@ -471,15 +495,9 @@ async function* readEncryptedOfflineFileChunks(options) {
|
|
|
471
495
|
if (envelopeVersion !== ENVELOPE_VERSION) {
|
|
472
496
|
throw new Error(`secure-store envelope has unsupported version ${envelopeVersion}: ${options.filePath}`);
|
|
473
497
|
}
|
|
474
|
-
const salt = envelopeHeader.subarray(
|
|
475
|
-
ENVELOPE_LAYOUT.salt,
|
|
476
|
-
ENVELOPE_LAYOUT.salt + ENVELOPE_SALT_LENGTH
|
|
477
|
-
);
|
|
498
|
+
const salt = envelopeHeader.subarray(ENVELOPE_LAYOUT.salt, ENVELOPE_LAYOUT.salt + ENVELOPE_SALT_LENGTH);
|
|
478
499
|
const iv = envelopeHeader.subarray(ENVELOPE_LAYOUT.iv, ENVELOPE_LAYOUT.iv + IV_LENGTH);
|
|
479
|
-
const authTag = envelopeHeader.subarray(
|
|
480
|
-
ENVELOPE_LAYOUT.authTag,
|
|
481
|
-
ENVELOPE_LAYOUT.authTag + AUTH_TAG_LENGTH
|
|
482
|
-
);
|
|
500
|
+
const authTag = envelopeHeader.subarray(ENVELOPE_LAYOUT.authTag, ENVELOPE_LAYOUT.authTag + AUTH_TAG_LENGTH);
|
|
483
501
|
const aadCandidates = offlineFileAadCandidates(options.filePath, options.memoryDir);
|
|
484
502
|
let lastError;
|
|
485
503
|
for (const aad of aadCandidates) {
|
|
@@ -498,9 +516,7 @@ async function* readEncryptedOfflineFileChunks(options) {
|
|
|
498
516
|
highWaterMark: options.chunkSize
|
|
499
517
|
});
|
|
500
518
|
for await (const encryptedChunk of stream) {
|
|
501
|
-
const plain = decipher.update(
|
|
502
|
-
Buffer.isBuffer(encryptedChunk) ? encryptedChunk : Buffer.from(encryptedChunk)
|
|
503
|
-
);
|
|
519
|
+
const plain = decipher.update(Buffer.isBuffer(encryptedChunk) ? encryptedChunk : Buffer.from(encryptedChunk));
|
|
504
520
|
if (plain.length > 0 && !output.write(plain)) {
|
|
505
521
|
await new Promise((resolve2, reject) => {
|
|
506
522
|
output.once("drain", resolve2);
|
|
@@ -1194,10 +1210,14 @@ async function computeConvergePlan(options = {}) {
|
|
|
1194
1210
|
for (const rootInfo of roots) {
|
|
1195
1211
|
const ns = rootInfo.namespace;
|
|
1196
1212
|
namespacesToPlan.add(ns);
|
|
1213
|
+
const io = await createOfflineStorageIo(rootInfo.rootDir);
|
|
1197
1214
|
const snapshot = await buildOfflineSyncSnapshotFromBase({
|
|
1198
1215
|
root: rootInfo.rootDir,
|
|
1199
1216
|
sourceId: "local",
|
|
1200
|
-
includeContent: false
|
|
1217
|
+
includeContent: false,
|
|
1218
|
+
readFile: io.readFile,
|
|
1219
|
+
readFileDigest: io.readFileDigest,
|
|
1220
|
+
excludeFile: io.excludeFile
|
|
1201
1221
|
});
|
|
1202
1222
|
const files = snapshot.files.filter((record2) => !isInternalRemnicStatePath3(record2.path)).map((record2) => ({
|
|
1203
1223
|
path: record2.path,
|
|
@@ -1207,7 +1227,6 @@ async function computeConvergePlan(options = {}) {
|
|
|
1207
1227
|
}));
|
|
1208
1228
|
localMap.set(ns, files);
|
|
1209
1229
|
const evidence = await readLocalTombstoneEvidence(rootInfo.rootDir);
|
|
1210
|
-
const io = await createOfflineStorageIo(rootInfo.rootDir);
|
|
1211
1230
|
let manifestReadFailed = false;
|
|
1212
1231
|
const manifest = await buildReconcileManifest({
|
|
1213
1232
|
files,
|
|
@@ -11747,15 +11766,6 @@ function offlineDirectPushFiles(options) {
|
|
|
11747
11766
|
return current.sha256 !== base.get(current.path)?.sha256;
|
|
11748
11767
|
}).sort((left, right) => right.bytes - left.bytes || left.path.localeCompare(right.path));
|
|
11749
11768
|
}
|
|
11750
|
-
function resolveOfflineDirectHydrationPath(memoryDir, relPath) {
|
|
11751
|
-
const base = path17.resolve(memoryDir);
|
|
11752
|
-
const target = path17.resolve(base, relPath);
|
|
11753
|
-
const relative = path17.relative(base, target);
|
|
11754
|
-
if (relative === "" || relative === ".." || relative.startsWith(`..${path17.sep}`) || path17.isAbsolute(relative)) {
|
|
11755
|
-
throw new Error(`offline sync direct hydration path escapes memory dir: ${relPath}`);
|
|
11756
|
-
}
|
|
11757
|
-
return target;
|
|
11758
|
-
}
|
|
11759
11769
|
var OFFLINE_SYNC_FILE_CONTENT_UPLOAD_CHUNK_BYTES = OFFLINE_SYNC_FILE_CONTENT_TRANSFER_CHUNK_BYTES4;
|
|
11760
11770
|
async function pushOfflineFileContent(args) {
|
|
11761
11771
|
if (args.readFileChunks) {
|
|
@@ -12355,6 +12365,7 @@ async function runOfflineSyncOnce(options) {
|
|
|
12355
12365
|
options.secureStoreEncryptOnWrite
|
|
12356
12366
|
);
|
|
12357
12367
|
const storageIo = await createOfflineStorageIo(options.memoryDir, offlineStorage);
|
|
12368
|
+
const syncBaseFiles = await filterOfflineSyncBaseFiles(options.memoryDir, baseFiles, storageIo.excludeFile);
|
|
12358
12369
|
const localSourceId = localOfflineSourceId(options.memoryDir);
|
|
12359
12370
|
await drainOfflineSyncImpressions(options.memoryDir, options);
|
|
12360
12371
|
await drainPendingLifecycleForOfflineSync(
|
|
@@ -12369,21 +12380,22 @@ async function runOfflineSyncOnce(options) {
|
|
|
12369
12380
|
const currentSnapshotForPush = await buildOfflineSyncSnapshotFromBase2({
|
|
12370
12381
|
root: options.memoryDir,
|
|
12371
12382
|
sourceId: localSourceId,
|
|
12372
|
-
baseFiles,
|
|
12383
|
+
baseFiles: syncBaseFiles,
|
|
12373
12384
|
baseCapturedAt,
|
|
12374
12385
|
includeContent: false,
|
|
12375
12386
|
includeTranscripts: options.includeTranscripts,
|
|
12376
12387
|
readFile: storageIo.readFile,
|
|
12377
12388
|
readFileDigest: storageIo.readFileDigest,
|
|
12389
|
+
excludeFile: storageIo.excludeFile,
|
|
12378
12390
|
userExcludeRegexps: options.userExcludeRegexps
|
|
12379
12391
|
});
|
|
12380
12392
|
const pendingSummary = summarizeOfflineSyncPendingFiles({
|
|
12381
|
-
baseFiles,
|
|
12393
|
+
baseFiles: syncBaseFiles,
|
|
12382
12394
|
currentFiles: currentSnapshotForPush.files,
|
|
12383
12395
|
includeTranscripts: options.includeTranscripts,
|
|
12384
12396
|
userExcludeRegexps: options.userExcludeRegexps
|
|
12385
12397
|
});
|
|
12386
|
-
const baseByPath = offlineFileStateMap(
|
|
12398
|
+
const baseByPath = offlineFileStateMap(syncBaseFiles);
|
|
12387
12399
|
let directPushAppliedUpserts = 0;
|
|
12388
12400
|
let directPushSkipped = 0;
|
|
12389
12401
|
let directPushNamespace;
|
|
@@ -12393,7 +12405,7 @@ async function runOfflineSyncOnce(options) {
|
|
|
12393
12405
|
const directPushFailures = [];
|
|
12394
12406
|
for (const file of offlineDirectPushFiles({
|
|
12395
12407
|
currentFiles: currentSnapshotForPush.files,
|
|
12396
|
-
baseFiles
|
|
12408
|
+
baseFiles: syncBaseFiles
|
|
12397
12409
|
})) {
|
|
12398
12410
|
if (options.skipLargeFilePaths?.has(file.path)) {
|
|
12399
12411
|
continue;
|
|
@@ -12471,7 +12483,7 @@ async function runOfflineSyncOnce(options) {
|
|
|
12471
12483
|
const resolvedNamespace2 = partial?.resolvedNamespace ?? resolvedOfflineSnapshotNamespace({ namespace: pushed?.namespace ?? "" }, syncNamespace);
|
|
12472
12484
|
const stateWritePaths2 = stateWritePathsFor(resolvedNamespace2);
|
|
12473
12485
|
const nextBaseFiles = advanceOfflineBaseFilesForSuccessfulPush({
|
|
12474
|
-
baseFiles,
|
|
12486
|
+
baseFiles: syncBaseFiles,
|
|
12475
12487
|
currentFiles: currentSnapshotForPush.files,
|
|
12476
12488
|
directPushedPaths: [...directPushedPaths],
|
|
12477
12489
|
hydratedFiles: partial?.hydratedFiles,
|
|
@@ -12518,12 +12530,13 @@ async function runOfflineSyncOnce(options) {
|
|
|
12518
12530
|
let currentSnapshotForChangeset = directPushedPaths.size > 0 ? await buildOfflineSyncSnapshotFromBase2({
|
|
12519
12531
|
root: options.memoryDir,
|
|
12520
12532
|
sourceId: localSourceId,
|
|
12521
|
-
baseFiles,
|
|
12533
|
+
baseFiles: syncBaseFiles,
|
|
12522
12534
|
baseCapturedAt,
|
|
12523
12535
|
includeContent: false,
|
|
12524
12536
|
includeTranscripts: options.includeTranscripts,
|
|
12525
12537
|
readFile: storageIo.readFile,
|
|
12526
12538
|
readFileDigest: storageIo.readFileDigest,
|
|
12539
|
+
excludeFile: storageIo.excludeFile,
|
|
12527
12540
|
userExcludeRegexps: options.userExcludeRegexps
|
|
12528
12541
|
}) : currentSnapshotForPush;
|
|
12529
12542
|
let changesetRetryCount = 0;
|
|
@@ -12533,7 +12546,7 @@ async function runOfflineSyncOnce(options) {
|
|
|
12533
12546
|
root: options.memoryDir,
|
|
12534
12547
|
sourceId: localSourceId,
|
|
12535
12548
|
currentFiles: currentSnapshotForChangeset.files,
|
|
12536
|
-
baseFiles,
|
|
12549
|
+
baseFiles: syncBaseFiles,
|
|
12537
12550
|
// 3-strikes skipped large files must be excluded here too — the
|
|
12538
12551
|
// direct-push loop skips them, but without this line the changeset
|
|
12539
12552
|
// path would still try to upsert them inline (Cursor review, PR
|
|
@@ -12571,12 +12584,13 @@ async function runOfflineSyncOnce(options) {
|
|
|
12571
12584
|
currentSnapshotForChangeset = await buildOfflineSyncSnapshotFromBase2({
|
|
12572
12585
|
root: options.memoryDir,
|
|
12573
12586
|
sourceId: localSourceId,
|
|
12574
|
-
baseFiles,
|
|
12587
|
+
baseFiles: syncBaseFiles,
|
|
12575
12588
|
baseCapturedAt,
|
|
12576
12589
|
includeContent: false,
|
|
12577
12590
|
includeTranscripts: options.includeTranscripts,
|
|
12578
12591
|
readFile: storageIo.readFile,
|
|
12579
12592
|
readFileDigest: storageIo.readFileDigest,
|
|
12593
|
+
excludeFile: storageIo.excludeFile,
|
|
12580
12594
|
userExcludeRegexps: options.userExcludeRegexps
|
|
12581
12595
|
});
|
|
12582
12596
|
}
|
|
@@ -12614,7 +12628,7 @@ async function runOfflineSyncOnce(options) {
|
|
|
12614
12628
|
namespace: syncNamespace,
|
|
12615
12629
|
includeTranscripts: options.includeTranscripts,
|
|
12616
12630
|
includeContent: false,
|
|
12617
|
-
baseFiles,
|
|
12631
|
+
baseFiles: syncBaseFiles,
|
|
12618
12632
|
baseCapturedAt
|
|
12619
12633
|
});
|
|
12620
12634
|
} catch (error) {
|
|
@@ -12626,12 +12640,13 @@ async function runOfflineSyncOnce(options) {
|
|
|
12626
12640
|
currentSnapshot = await buildOfflineSyncSnapshotFromBase2({
|
|
12627
12641
|
root: options.memoryDir,
|
|
12628
12642
|
sourceId: localSourceId,
|
|
12629
|
-
baseFiles,
|
|
12643
|
+
baseFiles: syncBaseFiles,
|
|
12630
12644
|
baseCapturedAt,
|
|
12631
12645
|
includeContent: false,
|
|
12632
12646
|
includeTranscripts: options.includeTranscripts,
|
|
12633
12647
|
readFile: storageIo.readFile,
|
|
12634
|
-
readFileDigest: storageIo.readFileDigest
|
|
12648
|
+
readFileDigest: storageIo.readFileDigest,
|
|
12649
|
+
excludeFile: storageIo.excludeFile
|
|
12635
12650
|
});
|
|
12636
12651
|
} catch (error) {
|
|
12637
12652
|
if (pushed) return writePartialPushState(error);
|
|
@@ -12649,7 +12664,7 @@ async function runOfflineSyncOnce(options) {
|
|
|
12649
12664
|
namespace: syncNamespace,
|
|
12650
12665
|
includeTranscripts: options.includeTranscripts,
|
|
12651
12666
|
snapshot: remoteSnapshotMetadata,
|
|
12652
|
-
baseFiles,
|
|
12667
|
+
baseFiles: syncBaseFiles,
|
|
12653
12668
|
currentFiles: currentSnapshot.files,
|
|
12654
12669
|
memoryDir: options.memoryDir,
|
|
12655
12670
|
readFile: storageIo.readFile,
|
|
@@ -12706,7 +12721,7 @@ async function runOfflineSyncOnce(options) {
|
|
|
12706
12721
|
namespace: syncNamespace,
|
|
12707
12722
|
includeTranscripts: options.includeTranscripts,
|
|
12708
12723
|
snapshot: remoteSnapshotMetadata,
|
|
12709
|
-
baseFiles,
|
|
12724
|
+
baseFiles: syncBaseFiles,
|
|
12710
12725
|
currentFiles: applyCurrentSnapshot.files,
|
|
12711
12726
|
deferredPaths: [...remoteDeferredPaths],
|
|
12712
12727
|
missingContentDeferredPaths: remoteDeferredPaths
|
|
@@ -12724,7 +12739,7 @@ async function runOfflineSyncOnce(options) {
|
|
|
12724
12739
|
pull = await applyOfflineSyncSnapshot({
|
|
12725
12740
|
root: options.memoryDir,
|
|
12726
12741
|
snapshot: remoteSnapshot,
|
|
12727
|
-
baseFiles,
|
|
12742
|
+
baseFiles: syncBaseFiles,
|
|
12728
12743
|
currentFiles: latestApplySnapshot.files,
|
|
12729
12744
|
deferredPaths: [...remoteDeferredPaths],
|
|
12730
12745
|
allowMissingConflictContent: true,
|
|
@@ -12752,7 +12767,7 @@ async function runOfflineSyncOnce(options) {
|
|
|
12752
12767
|
namespace: syncNamespace,
|
|
12753
12768
|
includeTranscripts: options.includeTranscripts,
|
|
12754
12769
|
snapshot: remoteSnapshotMetadata,
|
|
12755
|
-
baseFiles,
|
|
12770
|
+
baseFiles: syncBaseFiles,
|
|
12756
12771
|
currentFiles: applyCurrentSnapshot.files,
|
|
12757
12772
|
deferredPaths: [...remoteDeferredPaths],
|
|
12758
12773
|
missingContentDeferredPaths: remoteDeferredPaths
|
|
@@ -12771,7 +12786,7 @@ async function runOfflineSyncOnce(options) {
|
|
|
12771
12786
|
pull = await applyOfflineSyncSnapshot({
|
|
12772
12787
|
root: options.memoryDir,
|
|
12773
12788
|
snapshot: retrySnapshot,
|
|
12774
|
-
baseFiles,
|
|
12789
|
+
baseFiles: syncBaseFiles,
|
|
12775
12790
|
currentFiles: latestRetryApplySnapshot.files,
|
|
12776
12791
|
deferredPaths: [...remoteDeferredPaths],
|
|
12777
12792
|
allowMissingConflictContent: true,
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@remnic/cli",
|
|
3
|
-
"version": "9.54.
|
|
3
|
+
"version": "9.54.5",
|
|
4
4
|
"description": "CLI for Remnic memory — init, query, doctor, daemon management",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "dist/index.js",
|
|
@@ -26,25 +26,25 @@
|
|
|
26
26
|
},
|
|
27
27
|
"dependencies": {
|
|
28
28
|
"yaml": "^2.4.2",
|
|
29
|
-
"@remnic/
|
|
30
|
-
"@remnic/
|
|
31
|
-
"@remnic/core": "^9.54.
|
|
29
|
+
"@remnic/plugin-pi": "^9.54.5",
|
|
30
|
+
"@remnic/server": "^9.54.5",
|
|
31
|
+
"@remnic/core": "^9.54.5"
|
|
32
32
|
},
|
|
33
33
|
"peerDependencies": {
|
|
34
|
-
"@remnic/bench": "^9.54.
|
|
35
|
-
"@remnic/plugin-openclaw": "^9.54.
|
|
36
|
-
"@remnic/export-weclone": "^9.54.
|
|
37
|
-
"@remnic/import-weclone": "^9.54.
|
|
38
|
-
"@remnic/import-chatgpt": "^9.54.
|
|
39
|
-
"@remnic/import-claude": "^9.54.
|
|
40
|
-
"@remnic/import-gemini": "^9.54.
|
|
41
|
-
"@remnic/import-lossless-claw": "^9.54.
|
|
42
|
-
"@remnic/import-mem0": "^9.54.
|
|
43
|
-
"@remnic/import-supermemory": "^9.54.
|
|
44
|
-
"@remnic/connector-limitless": "^9.54.
|
|
45
|
-
"@remnic/connector-bee": "^9.54.
|
|
46
|
-
"@remnic/connector-omi": "^9.54.
|
|
47
|
-
"@remnic/capture-audio": "^9.54.
|
|
34
|
+
"@remnic/bench": "^9.54.5",
|
|
35
|
+
"@remnic/plugin-openclaw": "^9.54.5",
|
|
36
|
+
"@remnic/export-weclone": "^9.54.5",
|
|
37
|
+
"@remnic/import-weclone": "^9.54.5",
|
|
38
|
+
"@remnic/import-chatgpt": "^9.54.5",
|
|
39
|
+
"@remnic/import-claude": "^9.54.5",
|
|
40
|
+
"@remnic/import-gemini": "^9.54.5",
|
|
41
|
+
"@remnic/import-lossless-claw": "^9.54.5",
|
|
42
|
+
"@remnic/import-mem0": "^9.54.5",
|
|
43
|
+
"@remnic/import-supermemory": "^9.54.5",
|
|
44
|
+
"@remnic/connector-limitless": "^9.54.5",
|
|
45
|
+
"@remnic/connector-bee": "^9.54.5",
|
|
46
|
+
"@remnic/connector-omi": "^9.54.5",
|
|
47
|
+
"@remnic/capture-audio": "^9.54.5"
|
|
48
48
|
},
|
|
49
49
|
"peerDependenciesMeta": {
|
|
50
50
|
"@remnic/bench": {
|
|
@@ -93,19 +93,19 @@
|
|
|
93
93
|
"devDependencies": {
|
|
94
94
|
"tsup": "^8.5.1",
|
|
95
95
|
"typescript": "^5.9.3",
|
|
96
|
-
"@remnic/bench": "9.54.
|
|
97
|
-
"@remnic/plugin-openclaw": "9.54.
|
|
98
|
-
"@remnic/
|
|
99
|
-
"@remnic/
|
|
100
|
-
"@remnic/import-
|
|
101
|
-
"@remnic/import-
|
|
102
|
-
"@remnic/
|
|
103
|
-
"@remnic/
|
|
104
|
-
"@remnic/import-
|
|
105
|
-
"@remnic/
|
|
106
|
-
"@remnic/
|
|
107
|
-
"@remnic/
|
|
108
|
-
"@remnic/
|
|
96
|
+
"@remnic/bench": "9.54.5",
|
|
97
|
+
"@remnic/plugin-openclaw": "9.54.5",
|
|
98
|
+
"@remnic/export-weclone": "9.54.5",
|
|
99
|
+
"@remnic/import-weclone": "9.54.5",
|
|
100
|
+
"@remnic/import-chatgpt": "9.54.5",
|
|
101
|
+
"@remnic/import-gemini": "9.54.5",
|
|
102
|
+
"@remnic/import-lossless-claw": "9.54.5",
|
|
103
|
+
"@remnic/import-mem0": "9.54.5",
|
|
104
|
+
"@remnic/import-claude": "9.54.5",
|
|
105
|
+
"@remnic/import-supermemory": "9.54.5",
|
|
106
|
+
"@remnic/connector-limitless": "9.54.5",
|
|
107
|
+
"@remnic/connector-bee": "9.54.5",
|
|
108
|
+
"@remnic/connector-omi": "9.54.5"
|
|
109
109
|
},
|
|
110
110
|
"license": "MIT",
|
|
111
111
|
"repository": {
|