@remnic/cli 9.45.0 → 9.45.2
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 +166 -28
- package/package.json +29 -29
package/dist/index.js
CHANGED
|
@@ -243,9 +243,12 @@ import * as fs3 from "fs";
|
|
|
243
243
|
import { createHash as createHash2 } from "crypto";
|
|
244
244
|
import * as path2 from "path";
|
|
245
245
|
import {
|
|
246
|
+
CONVERGE_CONFLICT_POLICIES,
|
|
247
|
+
DEFAULT_CONVERGE_CONFLICT_POLICY,
|
|
246
248
|
parseConfig as parseConfig2,
|
|
247
249
|
buildOfflineSyncSnapshotFromBase,
|
|
248
250
|
OFFLINE_SYNC_FILE_CONTENT_MAX_CHUNK_BYTES,
|
|
251
|
+
OFFLINE_SYNC_CHANGESET_FORMAT,
|
|
249
252
|
OFFLINE_SYNC_FILE_CONTENT_TRANSFER_CHUNK_BYTES as OFFLINE_SYNC_FILE_CONTENT_TRANSFER_CHUNK_BYTES2,
|
|
250
253
|
applyOfflineSyncFileContentChunk
|
|
251
254
|
} from "@remnic/core";
|
|
@@ -256,6 +259,7 @@ import {
|
|
|
256
259
|
} from "@remnic/core/reconcile/plan.js";
|
|
257
260
|
import {
|
|
258
261
|
defaultConvergeCursorPath,
|
|
262
|
+
deriveConvergeCursorBase,
|
|
259
263
|
readConvergeCursor,
|
|
260
264
|
writeConvergeCursor
|
|
261
265
|
} from "@remnic/core/reconcile/cursor.js";
|
|
@@ -766,13 +770,55 @@ async function postPeerConvergenceComplete(peerUrl, namespaces, token, fetchImpl
|
|
|
766
770
|
}
|
|
767
771
|
return false;
|
|
768
772
|
}
|
|
773
|
+
async function postPeerFileDeletion(peerUrl, namespace, filePath, baseSha256, token, fetchImpl = globalThis.fetch) {
|
|
774
|
+
const base = withoutTrailingSlashes(peerUrl);
|
|
775
|
+
const routes = ["/remnic/v1/offline-sync/apply", "/engram/v1/offline-sync/apply"];
|
|
776
|
+
const headers = {
|
|
777
|
+
"content-type": "application/json",
|
|
778
|
+
...token ? { authorization: `Bearer ${token}` } : {}
|
|
779
|
+
};
|
|
780
|
+
let previousAttemptFailed = false;
|
|
781
|
+
for (const route of routes) {
|
|
782
|
+
try {
|
|
783
|
+
const response = await fetchImpl(`${base}${route}`, {
|
|
784
|
+
method: "POST",
|
|
785
|
+
headers,
|
|
786
|
+
body: JSON.stringify({
|
|
787
|
+
namespace,
|
|
788
|
+
changeset: {
|
|
789
|
+
format: OFFLINE_SYNC_CHANGESET_FORMAT,
|
|
790
|
+
schemaVersion: 1,
|
|
791
|
+
createdAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
792
|
+
sourceId: "remnic-converge",
|
|
793
|
+
includeTranscripts: false,
|
|
794
|
+
changes: [{ type: "delete", path: filePath, baseSha256 }]
|
|
795
|
+
}
|
|
796
|
+
})
|
|
797
|
+
});
|
|
798
|
+
if (!response.ok) throw new Error(`offline apply request failed: ${response.status}`);
|
|
799
|
+
const result = await response.json().catch(() => null);
|
|
800
|
+
if (!result || typeof result !== "object" || !("appliedDeletes" in result) || typeof result.appliedDeletes !== "number" || !("skipped" in result) || typeof result.skipped !== "number" || !("conflicts" in result) || !Array.isArray(result.conflicts) || result.conflicts.length > 0) {
|
|
801
|
+
return false;
|
|
802
|
+
}
|
|
803
|
+
if (result.appliedDeletes === 1) return "applied";
|
|
804
|
+
if (result.skipped === 1) return previousAttemptFailed ? "applied" : "skipped";
|
|
805
|
+
return false;
|
|
806
|
+
} catch {
|
|
807
|
+
previousAttemptFailed = true;
|
|
808
|
+
}
|
|
809
|
+
}
|
|
810
|
+
return false;
|
|
811
|
+
}
|
|
769
812
|
async function computeConvergePlan(options = {}) {
|
|
770
813
|
const baseMap = /* @__PURE__ */ new Map();
|
|
814
|
+
const semanticAgreementMap = /* @__PURE__ */ new Map();
|
|
771
815
|
const namespacesToPlan = /* @__PURE__ */ new Set();
|
|
772
816
|
const localMap = /* @__PURE__ */ new Map();
|
|
773
817
|
const localTombstones = /* @__PURE__ */ new Map();
|
|
774
818
|
const peerMap = /* @__PURE__ */ new Map();
|
|
775
819
|
const peerTombstones = /* @__PURE__ */ new Map();
|
|
820
|
+
const localDeletionMtimeMs = /* @__PURE__ */ new Map();
|
|
821
|
+
const peerDeletionMtimeMs = /* @__PURE__ */ new Map();
|
|
776
822
|
const localManifests = /* @__PURE__ */ new Map();
|
|
777
823
|
const peerManifests = /* @__PURE__ */ new Map();
|
|
778
824
|
if (options.baseFilesByNamespace) {
|
|
@@ -781,6 +827,12 @@ async function computeConvergePlan(options = {}) {
|
|
|
781
827
|
baseMap.set(ns, files);
|
|
782
828
|
}
|
|
783
829
|
}
|
|
830
|
+
if (options.semanticAgreementsByNamespace) {
|
|
831
|
+
for (const [ns, agreements] of options.semanticAgreementsByNamespace) {
|
|
832
|
+
namespacesToPlan.add(ns);
|
|
833
|
+
semanticAgreementMap.set(ns, agreements);
|
|
834
|
+
}
|
|
835
|
+
}
|
|
784
836
|
if (options.localFilesByNamespace) {
|
|
785
837
|
for (const [ns, files] of options.localFilesByNamespace) {
|
|
786
838
|
namespacesToPlan.add(ns);
|
|
@@ -792,6 +844,12 @@ async function computeConvergePlan(options = {}) {
|
|
|
792
844
|
localTombstones.set(ns, new Set(tombstones));
|
|
793
845
|
}
|
|
794
846
|
}
|
|
847
|
+
if (options.localDeletionMtimeMsByNamespace) {
|
|
848
|
+
for (const [ns, mtimes] of options.localDeletionMtimeMsByNamespace) {
|
|
849
|
+
namespacesToPlan.add(ns);
|
|
850
|
+
localDeletionMtimeMs.set(ns, mtimes);
|
|
851
|
+
}
|
|
852
|
+
}
|
|
795
853
|
if (options.peerFilesByNamespace) {
|
|
796
854
|
for (const [ns, files] of options.peerFilesByNamespace) {
|
|
797
855
|
namespacesToPlan.add(ns);
|
|
@@ -803,6 +861,12 @@ async function computeConvergePlan(options = {}) {
|
|
|
803
861
|
peerTombstones.set(ns, new Set(tombstones));
|
|
804
862
|
}
|
|
805
863
|
}
|
|
864
|
+
if (options.peerDeletionMtimeMsByNamespace) {
|
|
865
|
+
for (const [ns, mtimes] of options.peerDeletionMtimeMsByNamespace) {
|
|
866
|
+
namespacesToPlan.add(ns);
|
|
867
|
+
peerDeletionMtimeMs.set(ns, mtimes);
|
|
868
|
+
}
|
|
869
|
+
}
|
|
806
870
|
let config = options.config;
|
|
807
871
|
if (!config) {
|
|
808
872
|
try {
|
|
@@ -893,31 +957,42 @@ async function computeConvergePlan(options = {}) {
|
|
|
893
957
|
}
|
|
894
958
|
}
|
|
895
959
|
const memoryDir = options.cursorDir ?? config?.memoryDir;
|
|
896
|
-
if (
|
|
960
|
+
if (memoryDir && options.peerUrl && (!options.baseFilesByNamespace || !options.semanticAgreementsByNamespace)) {
|
|
897
961
|
for (const ns of namespacesToPlan) {
|
|
898
962
|
const cursorPath = defaultConvergeCursorPath(memoryDir, options.peerUrl, ns);
|
|
899
963
|
const cursor = await readConvergeCursor(cursorPath);
|
|
900
|
-
if (cursor?.baseFiles && cursor.baseFiles.length > 0) {
|
|
964
|
+
if (!options.baseFilesByNamespace && cursor?.baseFiles && cursor.baseFiles.length > 0) {
|
|
901
965
|
baseMap.set(ns, cursor.baseFiles);
|
|
902
966
|
}
|
|
967
|
+
if (!options.semanticAgreementsByNamespace && cursor?.semanticAgreements && cursor.semanticAgreements.length > 0) {
|
|
968
|
+
semanticAgreementMap.set(ns, cursor.semanticAgreements);
|
|
969
|
+
}
|
|
903
970
|
}
|
|
904
971
|
}
|
|
905
972
|
const inputs = [];
|
|
906
973
|
for (const ns of [...namespacesToPlan].sort()) {
|
|
974
|
+
const baseFiles = baseMap.get(ns);
|
|
975
|
+
const localFiles = localMap.get(ns) ?? [];
|
|
976
|
+
const peerFiles = peerMap.get(ns) ?? [];
|
|
977
|
+
const localDeletions = new Map(localDeletionMtimeMs.get(ns) ?? []);
|
|
978
|
+
const peerDeletions = new Map(peerDeletionMtimeMs.get(ns) ?? []);
|
|
907
979
|
inputs.push({
|
|
908
980
|
namespace: ns,
|
|
909
|
-
local:
|
|
910
|
-
peer:
|
|
911
|
-
base:
|
|
981
|
+
local: localFiles,
|
|
982
|
+
peer: peerFiles,
|
|
983
|
+
base: baseFiles,
|
|
984
|
+
localDeletionMtimeMs: localDeletions,
|
|
985
|
+
peerDeletionMtimeMs: peerDeletions,
|
|
912
986
|
tombstonedFileSha256: localTombstones.get(ns) ?? [],
|
|
913
987
|
peerTombstonedFileSha256: peerTombstones.get(ns) ?? []
|
|
914
988
|
});
|
|
915
989
|
}
|
|
916
|
-
const
|
|
917
|
-
|
|
990
|
+
const conflictPolicy = options.conflictPolicy ?? config?.converge.conflictPolicy ?? DEFAULT_CONVERGE_CONFLICT_POLICY;
|
|
991
|
+
const plan = planReconciliation(inputs, { conflictPolicy });
|
|
992
|
+
return collapseActiveFactDuplicates(plan, localManifests, peerManifests, semanticAgreementMap);
|
|
918
993
|
}
|
|
919
994
|
async function executeConvergeApply(options = {}) {
|
|
920
|
-
const conflictPolicy = options.conflictPolicy ??
|
|
995
|
+
const conflictPolicy = options.conflictPolicy ?? options.config?.converge.conflictPolicy ?? DEFAULT_CONVERGE_CONFLICT_POLICY;
|
|
921
996
|
const plan = await computeConvergePlan({ ...options, conflictPolicy });
|
|
922
997
|
if (plan.converged && !options.dryRun) {
|
|
923
998
|
await updateCursorsForPlan(plan, options);
|
|
@@ -930,7 +1005,7 @@ async function executeConvergeApply(options = {}) {
|
|
|
930
1005
|
};
|
|
931
1006
|
}
|
|
932
1007
|
const unresolvedCount = plan.byNamespace.reduce((acc, report) => acc + report.unresolved, 0);
|
|
933
|
-
if (unresolvedCount > 0
|
|
1008
|
+
if (unresolvedCount > 0) {
|
|
934
1009
|
return {
|
|
935
1010
|
converged: false,
|
|
936
1011
|
status: "stopped_unresolved_conflicts",
|
|
@@ -1008,12 +1083,9 @@ async function executeConvergeApply(options = {}) {
|
|
|
1008
1083
|
transferType = "suppress";
|
|
1009
1084
|
} else if (entry.action === "conflict") {
|
|
1010
1085
|
if (entry.resolution === "peer-wins") {
|
|
1011
|
-
transferType = "pull";
|
|
1086
|
+
transferType = entry.peerSha256 ? "pull" : "delete-local";
|
|
1012
1087
|
} else if (entry.resolution === "local-wins") {
|
|
1013
|
-
transferType = "push";
|
|
1014
|
-
} else if (entry.resolution === "supersede-link") {
|
|
1015
|
-
if (entry.newerSide === "peer") transferType = "pull";
|
|
1016
|
-
else if (entry.newerSide === "local") transferType = "push";
|
|
1088
|
+
transferType = entry.localSha256 ? "push" : "delete-peer";
|
|
1017
1089
|
}
|
|
1018
1090
|
}
|
|
1019
1091
|
if (transferType === "pull") {
|
|
@@ -1158,6 +1230,56 @@ async function executeConvergeApply(options = {}) {
|
|
|
1158
1230
|
} else {
|
|
1159
1231
|
actualTransfers.failed += 1;
|
|
1160
1232
|
}
|
|
1233
|
+
} else if (transferType === "delete-local") {
|
|
1234
|
+
let deleted = false;
|
|
1235
|
+
const bufferedFiles = options.localFileBuffers?.get(entry.namespace);
|
|
1236
|
+
if (options.localFileBuffers) {
|
|
1237
|
+
const current = bufferedFiles?.get(entry.path);
|
|
1238
|
+
if (current && entry.localSha256 && createHash2("sha256").update(current).digest("hex") === entry.localSha256) {
|
|
1239
|
+
bufferedFiles.delete(entry.path);
|
|
1240
|
+
deleted = true;
|
|
1241
|
+
}
|
|
1242
|
+
} else {
|
|
1243
|
+
const rootDir = rootMap.get(entry.namespace);
|
|
1244
|
+
if (rootDir && entry.localSha256) {
|
|
1245
|
+
try {
|
|
1246
|
+
const io = await createOfflineStorageIo(rootDir);
|
|
1247
|
+
const filePath = path2.join(rootDir, entry.path);
|
|
1248
|
+
const current = await io.readFileDigest({ root: rootDir, path: entry.path, filePath });
|
|
1249
|
+
if (current.sha256 === entry.localSha256) {
|
|
1250
|
+
await io.deleteFile({ root: rootDir, path: entry.path, filePath });
|
|
1251
|
+
deleted = true;
|
|
1252
|
+
}
|
|
1253
|
+
} catch {
|
|
1254
|
+
deleted = false;
|
|
1255
|
+
}
|
|
1256
|
+
}
|
|
1257
|
+
}
|
|
1258
|
+
if (deleted) actualTransfers.conflictsResolved += 1;
|
|
1259
|
+
else actualTransfers.failed += 1;
|
|
1260
|
+
} else if (transferType === "delete-peer") {
|
|
1261
|
+
let deleted = false;
|
|
1262
|
+
const bufferedFiles = options.peerFileBuffers?.get(entry.namespace);
|
|
1263
|
+
if (options.peerFileBuffers) {
|
|
1264
|
+
const current = bufferedFiles?.get(entry.path);
|
|
1265
|
+
if (current && entry.peerSha256 && createHash2("sha256").update(current).digest("hex") === entry.peerSha256) {
|
|
1266
|
+
bufferedFiles.delete(entry.path);
|
|
1267
|
+
deleted = true;
|
|
1268
|
+
}
|
|
1269
|
+
} else if (options.peerUrl && entry.peerSha256) {
|
|
1270
|
+
const deletionResult = await postPeerFileDeletion(
|
|
1271
|
+
options.peerUrl,
|
|
1272
|
+
entry.namespace,
|
|
1273
|
+
entry.path,
|
|
1274
|
+
entry.peerSha256,
|
|
1275
|
+
resolvedToken,
|
|
1276
|
+
fetchFn
|
|
1277
|
+
);
|
|
1278
|
+
deleted = Boolean(deletionResult);
|
|
1279
|
+
if (deletionResult === "applied") peerMutatedNamespaces.add(entry.namespace);
|
|
1280
|
+
}
|
|
1281
|
+
if (deleted) actualTransfers.conflictsResolved += 1;
|
|
1282
|
+
else actualTransfers.failed += 1;
|
|
1161
1283
|
} else if (transferType === "suppress") {
|
|
1162
1284
|
actualTransfers.suppressed += 1;
|
|
1163
1285
|
}
|
|
@@ -1198,16 +1320,19 @@ async function updateCursorsForPlan(plan, options) {
|
|
|
1198
1320
|
const namespaces = new Set(plan.byNamespace.map((n) => n.namespace));
|
|
1199
1321
|
for (const ns of namespaces) {
|
|
1200
1322
|
const cursorPath = defaultConvergeCursorPath(memoryDir, peerUrl, ns);
|
|
1201
|
-
const
|
|
1202
|
-
|
|
1203
|
-
|
|
1204
|
-
|
|
1323
|
+
const priorSemanticAgreements = options.semanticAgreementsByNamespace?.get(ns) ?? (await readConvergeCursor(cursorPath))?.semanticAgreements ?? [];
|
|
1324
|
+
const { baseFiles, semanticAgreements } = deriveConvergeCursorBase(
|
|
1325
|
+
plan.entries,
|
|
1326
|
+
ns,
|
|
1327
|
+
priorSemanticAgreements
|
|
1328
|
+
);
|
|
1205
1329
|
const cursorState = {
|
|
1206
1330
|
version: 1,
|
|
1207
1331
|
peerUrl,
|
|
1208
1332
|
namespace: ns,
|
|
1209
1333
|
lastConvergedAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
1210
|
-
baseFiles
|
|
1334
|
+
baseFiles,
|
|
1335
|
+
semanticAgreements
|
|
1211
1336
|
};
|
|
1212
1337
|
try {
|
|
1213
1338
|
await writeConvergeCursor(cursorPath, cursorState);
|
|
@@ -1250,7 +1375,7 @@ function formatConvergeApplyReport(result) {
|
|
|
1250
1375
|
lines.push(formatConvergeReport(result.plan));
|
|
1251
1376
|
return lines.join("\n");
|
|
1252
1377
|
}
|
|
1253
|
-
async function cmdConverge(action, rest, json) {
|
|
1378
|
+
async function cmdConverge(action, rest, json, config = parseConfig2({})) {
|
|
1254
1379
|
if (action === "help" || action === "--help" || action === "-h" || rest.includes("--help") || rest.includes("-h")) {
|
|
1255
1380
|
console.log(`Usage: remnic converge <plan|apply> [options]
|
|
1256
1381
|
|
|
@@ -1262,7 +1387,8 @@ Options:
|
|
|
1262
1387
|
--peer <url> Peer server URL (or --remote-url / --remote)
|
|
1263
1388
|
--token <token> Bearer token or SecretRef for peer authentication
|
|
1264
1389
|
--conflict-policy <policy>
|
|
1265
|
-
|
|
1390
|
+
Policy override (newest-wins|manual)
|
|
1391
|
+
Default: converge.conflictPolicy (newest-wins)
|
|
1266
1392
|
--dry-run Simulate transfers without mutating disk or remote peer
|
|
1267
1393
|
--json Output detailed JSON plan report
|
|
1268
1394
|
`);
|
|
@@ -1288,16 +1414,19 @@ Options:
|
|
|
1288
1414
|
i += 1;
|
|
1289
1415
|
} else if (arg === "--dry-run") {
|
|
1290
1416
|
dryRun = true;
|
|
1291
|
-
} else if (arg === "--conflict-policy"
|
|
1292
|
-
const
|
|
1293
|
-
if (
|
|
1294
|
-
|
|
1417
|
+
} else if (arg === "--conflict-policy") {
|
|
1418
|
+
const policy = rest[i + 1];
|
|
1419
|
+
if (typeof policy !== "string" || !CONVERGE_CONFLICT_POLICIES.includes(policy)) {
|
|
1420
|
+
throw new Error(
|
|
1421
|
+
`converge: --conflict-policy must be one of ${CONVERGE_CONFLICT_POLICIES.join(", ")}`
|
|
1422
|
+
);
|
|
1295
1423
|
}
|
|
1424
|
+
conflictPolicy = policy;
|
|
1296
1425
|
i += 1;
|
|
1297
1426
|
}
|
|
1298
1427
|
}
|
|
1299
1428
|
if (action === "plan") {
|
|
1300
|
-
const plan = await computeConvergePlan({ peerUrl, peerToken, conflictPolicy });
|
|
1429
|
+
const plan = await computeConvergePlan({ config, peerUrl, peerToken, conflictPolicy });
|
|
1301
1430
|
if (json) {
|
|
1302
1431
|
console.log(JSON.stringify(plan, null, 2));
|
|
1303
1432
|
} else {
|
|
@@ -1309,7 +1438,8 @@ Options:
|
|
|
1309
1438
|
peerUrl,
|
|
1310
1439
|
peerToken,
|
|
1311
1440
|
dryRun,
|
|
1312
|
-
conflictPolicy
|
|
1441
|
+
conflictPolicy,
|
|
1442
|
+
config
|
|
1313
1443
|
});
|
|
1314
1444
|
if (json) {
|
|
1315
1445
|
console.log(JSON.stringify(result, null, 2));
|
|
@@ -14426,7 +14556,15 @@ Options:
|
|
|
14426
14556
|
case "converge": {
|
|
14427
14557
|
const action = rest[0] ?? "plan";
|
|
14428
14558
|
const json = rest.includes("--json");
|
|
14429
|
-
|
|
14559
|
+
const args = rest.slice(1);
|
|
14560
|
+
if (action === "help" || action === "--help" || action === "-h" || args.includes("--help") || args.includes("-h")) {
|
|
14561
|
+
await cmdConverge(action, args, json);
|
|
14562
|
+
break;
|
|
14563
|
+
}
|
|
14564
|
+
const configPath = resolveConfigPath();
|
|
14565
|
+
const raw = fs12.existsSync(configPath) ? JSON.parse(fs12.readFileSync(configPath, "utf8")) : {};
|
|
14566
|
+
const config = parseConfig5(resolveRemnicConfigRecord4(raw));
|
|
14567
|
+
await cmdConverge(action, args, json, config);
|
|
14430
14568
|
break;
|
|
14431
14569
|
}
|
|
14432
14570
|
case "oauth": {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@remnic/cli",
|
|
3
|
-
"version": "9.45.
|
|
3
|
+
"version": "9.45.2",
|
|
4
4
|
"description": "CLI for Remnic memory — init, query, doctor, daemon management",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "dist/index.js",
|
|
@@ -26,24 +26,24 @@
|
|
|
26
26
|
},
|
|
27
27
|
"dependencies": {
|
|
28
28
|
"yaml": "^2.4.2",
|
|
29
|
-
"@remnic/
|
|
30
|
-
"@remnic/core": "^9.45.
|
|
31
|
-
"@remnic/
|
|
29
|
+
"@remnic/server": "^9.45.2",
|
|
30
|
+
"@remnic/core": "^9.45.2",
|
|
31
|
+
"@remnic/plugin-pi": "^9.45.2"
|
|
32
32
|
},
|
|
33
33
|
"peerDependencies": {
|
|
34
|
-
"@remnic/bench": "^9.45.
|
|
35
|
-
"@remnic/export-weclone": "^9.45.
|
|
36
|
-
"@remnic/import-weclone": "^9.45.
|
|
37
|
-
"@remnic/import-chatgpt": "^9.45.
|
|
38
|
-
"@remnic/import-claude": "^9.45.
|
|
39
|
-
"@remnic/import-gemini": "^9.45.
|
|
40
|
-
"@remnic/import-lossless-claw": "^9.45.
|
|
41
|
-
"@remnic/import-mem0": "^9.45.
|
|
42
|
-
"@remnic/import-supermemory": "^9.45.
|
|
43
|
-
"@remnic/connector-limitless": "^9.45.
|
|
44
|
-
"@remnic/connector-bee": "^9.45.
|
|
45
|
-
"@remnic/connector-omi": "^9.45.
|
|
46
|
-
"@remnic/capture-audio": "^9.45.
|
|
34
|
+
"@remnic/bench": "^9.45.2",
|
|
35
|
+
"@remnic/export-weclone": "^9.45.2",
|
|
36
|
+
"@remnic/import-weclone": "^9.45.2",
|
|
37
|
+
"@remnic/import-chatgpt": "^9.45.2",
|
|
38
|
+
"@remnic/import-claude": "^9.45.2",
|
|
39
|
+
"@remnic/import-gemini": "^9.45.2",
|
|
40
|
+
"@remnic/import-lossless-claw": "^9.45.2",
|
|
41
|
+
"@remnic/import-mem0": "^9.45.2",
|
|
42
|
+
"@remnic/import-supermemory": "^9.45.2",
|
|
43
|
+
"@remnic/connector-limitless": "^9.45.2",
|
|
44
|
+
"@remnic/connector-bee": "^9.45.2",
|
|
45
|
+
"@remnic/connector-omi": "^9.45.2",
|
|
46
|
+
"@remnic/capture-audio": "^9.45.2"
|
|
47
47
|
},
|
|
48
48
|
"peerDependenciesMeta": {
|
|
49
49
|
"@remnic/bench": {
|
|
@@ -89,18 +89,18 @@
|
|
|
89
89
|
"devDependencies": {
|
|
90
90
|
"tsup": "^8.5.1",
|
|
91
91
|
"typescript": "^5.9.3",
|
|
92
|
-
"@remnic/bench": "9.45.
|
|
93
|
-
"@remnic/export-weclone": "9.45.
|
|
94
|
-
"@remnic/import-
|
|
95
|
-
"@remnic/import-
|
|
96
|
-
"@remnic/import-
|
|
97
|
-
"@remnic/import-
|
|
98
|
-
"@remnic/import-
|
|
99
|
-
"@remnic/
|
|
100
|
-
"@remnic/
|
|
101
|
-
"@remnic/import-
|
|
102
|
-
"@remnic/connector-omi": "9.45.
|
|
103
|
-
"@remnic/connector-bee": "9.45.
|
|
92
|
+
"@remnic/bench": "9.45.2",
|
|
93
|
+
"@remnic/export-weclone": "9.45.2",
|
|
94
|
+
"@remnic/import-claude": "9.45.2",
|
|
95
|
+
"@remnic/import-gemini": "9.45.2",
|
|
96
|
+
"@remnic/import-weclone": "9.45.2",
|
|
97
|
+
"@remnic/import-lossless-claw": "9.45.2",
|
|
98
|
+
"@remnic/import-supermemory": "9.45.2",
|
|
99
|
+
"@remnic/connector-limitless": "9.45.2",
|
|
100
|
+
"@remnic/import-mem0": "9.45.2",
|
|
101
|
+
"@remnic/import-chatgpt": "9.45.2",
|
|
102
|
+
"@remnic/connector-omi": "9.45.2",
|
|
103
|
+
"@remnic/connector-bee": "9.45.2"
|
|
104
104
|
},
|
|
105
105
|
"license": "MIT",
|
|
106
106
|
"repository": {
|