@remnic/cli 9.44.0 → 9.45.1
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 +191 -26
- 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";
|
|
@@ -259,6 +262,10 @@ import {
|
|
|
259
262
|
readConvergeCursor,
|
|
260
263
|
writeConvergeCursor
|
|
261
264
|
} from "@remnic/core/reconcile/cursor.js";
|
|
265
|
+
import {
|
|
266
|
+
buildReconcileManifest,
|
|
267
|
+
collapseActiveFactDuplicates
|
|
268
|
+
} from "@remnic/core/reconcile/manifest.js";
|
|
262
269
|
|
|
263
270
|
// src/offline-storage-io.ts
|
|
264
271
|
import { mkdtemp, readdir, lstat, rm } from "fs/promises";
|
|
@@ -762,6 +769,45 @@ async function postPeerConvergenceComplete(peerUrl, namespaces, token, fetchImpl
|
|
|
762
769
|
}
|
|
763
770
|
return false;
|
|
764
771
|
}
|
|
772
|
+
async function postPeerFileDeletion(peerUrl, namespace, filePath, baseSha256, token, fetchImpl = globalThis.fetch) {
|
|
773
|
+
const base = withoutTrailingSlashes(peerUrl);
|
|
774
|
+
const routes = ["/remnic/v1/offline-sync/apply", "/engram/v1/offline-sync/apply"];
|
|
775
|
+
const headers = {
|
|
776
|
+
"content-type": "application/json",
|
|
777
|
+
...token ? { authorization: `Bearer ${token}` } : {}
|
|
778
|
+
};
|
|
779
|
+
let previousAttemptFailed = false;
|
|
780
|
+
for (const route of routes) {
|
|
781
|
+
try {
|
|
782
|
+
const response = await fetchImpl(`${base}${route}`, {
|
|
783
|
+
method: "POST",
|
|
784
|
+
headers,
|
|
785
|
+
body: JSON.stringify({
|
|
786
|
+
namespace,
|
|
787
|
+
changeset: {
|
|
788
|
+
format: OFFLINE_SYNC_CHANGESET_FORMAT,
|
|
789
|
+
schemaVersion: 1,
|
|
790
|
+
createdAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
791
|
+
sourceId: "remnic-converge",
|
|
792
|
+
includeTranscripts: false,
|
|
793
|
+
changes: [{ type: "delete", path: filePath, baseSha256 }]
|
|
794
|
+
}
|
|
795
|
+
})
|
|
796
|
+
});
|
|
797
|
+
if (!response.ok) throw new Error(`offline apply request failed: ${response.status}`);
|
|
798
|
+
const result = await response.json().catch(() => null);
|
|
799
|
+
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) {
|
|
800
|
+
return false;
|
|
801
|
+
}
|
|
802
|
+
if (result.appliedDeletes === 1) return "applied";
|
|
803
|
+
if (result.skipped === 1) return previousAttemptFailed ? "applied" : "skipped";
|
|
804
|
+
return false;
|
|
805
|
+
} catch {
|
|
806
|
+
previousAttemptFailed = true;
|
|
807
|
+
}
|
|
808
|
+
}
|
|
809
|
+
return false;
|
|
810
|
+
}
|
|
765
811
|
async function computeConvergePlan(options = {}) {
|
|
766
812
|
const baseMap = /* @__PURE__ */ new Map();
|
|
767
813
|
const namespacesToPlan = /* @__PURE__ */ new Set();
|
|
@@ -769,6 +815,10 @@ async function computeConvergePlan(options = {}) {
|
|
|
769
815
|
const localTombstones = /* @__PURE__ */ new Map();
|
|
770
816
|
const peerMap = /* @__PURE__ */ new Map();
|
|
771
817
|
const peerTombstones = /* @__PURE__ */ new Map();
|
|
818
|
+
const localDeletionMtimeMs = /* @__PURE__ */ new Map();
|
|
819
|
+
const peerDeletionMtimeMs = /* @__PURE__ */ new Map();
|
|
820
|
+
const localManifests = /* @__PURE__ */ new Map();
|
|
821
|
+
const peerManifests = /* @__PURE__ */ new Map();
|
|
772
822
|
if (options.baseFilesByNamespace) {
|
|
773
823
|
for (const [ns, files] of options.baseFilesByNamespace) {
|
|
774
824
|
namespacesToPlan.add(ns);
|
|
@@ -786,6 +836,12 @@ async function computeConvergePlan(options = {}) {
|
|
|
786
836
|
localTombstones.set(ns, new Set(tombstones));
|
|
787
837
|
}
|
|
788
838
|
}
|
|
839
|
+
if (options.localDeletionMtimeMsByNamespace) {
|
|
840
|
+
for (const [ns, mtimes] of options.localDeletionMtimeMsByNamespace) {
|
|
841
|
+
namespacesToPlan.add(ns);
|
|
842
|
+
localDeletionMtimeMs.set(ns, mtimes);
|
|
843
|
+
}
|
|
844
|
+
}
|
|
789
845
|
if (options.peerFilesByNamespace) {
|
|
790
846
|
for (const [ns, files] of options.peerFilesByNamespace) {
|
|
791
847
|
namespacesToPlan.add(ns);
|
|
@@ -797,6 +853,12 @@ async function computeConvergePlan(options = {}) {
|
|
|
797
853
|
peerTombstones.set(ns, new Set(tombstones));
|
|
798
854
|
}
|
|
799
855
|
}
|
|
856
|
+
if (options.peerDeletionMtimeMsByNamespace) {
|
|
857
|
+
for (const [ns, mtimes] of options.peerDeletionMtimeMsByNamespace) {
|
|
858
|
+
namespacesToPlan.add(ns);
|
|
859
|
+
peerDeletionMtimeMs.set(ns, mtimes);
|
|
860
|
+
}
|
|
861
|
+
}
|
|
800
862
|
let config = options.config;
|
|
801
863
|
if (!config) {
|
|
802
864
|
try {
|
|
@@ -826,6 +888,26 @@ async function computeConvergePlan(options = {}) {
|
|
|
826
888
|
bytes: record.bytes
|
|
827
889
|
}));
|
|
828
890
|
localMap.set(ns, files);
|
|
891
|
+
try {
|
|
892
|
+
const io = await createOfflineStorageIo(rootInfo.rootDir);
|
|
893
|
+
localManifests.set(
|
|
894
|
+
ns,
|
|
895
|
+
await buildReconcileManifest({
|
|
896
|
+
files,
|
|
897
|
+
readFile: async (file) => {
|
|
898
|
+
const readFile2 = io.readFile;
|
|
899
|
+
if (!readFile2) throw new Error("offline storage cannot read reconciliation manifest files");
|
|
900
|
+
return await readFile2({
|
|
901
|
+
root: rootInfo.rootDir,
|
|
902
|
+
path: file.path,
|
|
903
|
+
filePath: path2.join(rootInfo.rootDir, file.path)
|
|
904
|
+
});
|
|
905
|
+
}
|
|
906
|
+
})
|
|
907
|
+
);
|
|
908
|
+
} catch {
|
|
909
|
+
localManifests.delete(ns);
|
|
910
|
+
}
|
|
829
911
|
const tombstones = await readLocalTombstones(rootInfo.rootDir);
|
|
830
912
|
localTombstones.set(ns, tombstones);
|
|
831
913
|
} catch {
|
|
@@ -833,7 +915,8 @@ async function computeConvergePlan(options = {}) {
|
|
|
833
915
|
}
|
|
834
916
|
}
|
|
835
917
|
}
|
|
836
|
-
|
|
918
|
+
const peerUrl = options.peerUrl;
|
|
919
|
+
if (!options.peerFilesByNamespace && peerUrl) {
|
|
837
920
|
let resolvedToken;
|
|
838
921
|
if (options.peerToken) {
|
|
839
922
|
try {
|
|
@@ -846,9 +929,23 @@ async function computeConvergePlan(options = {}) {
|
|
|
846
929
|
}
|
|
847
930
|
const fetchFn = options.fetchImpl ?? globalThis.fetch;
|
|
848
931
|
for (const ns of namespacesToPlan) {
|
|
849
|
-
const peerData = await fetchPeerSnapshot(
|
|
932
|
+
const peerData = await fetchPeerSnapshot(peerUrl, ns, resolvedToken, fetchFn);
|
|
850
933
|
peerMap.set(ns, peerData.files);
|
|
851
934
|
peerTombstones.set(ns, peerData.tombstones);
|
|
935
|
+
peerManifests.set(
|
|
936
|
+
ns,
|
|
937
|
+
await buildReconcileManifest({
|
|
938
|
+
files: peerData.files,
|
|
939
|
+
cachedFiles: localManifests.get(ns)?.files,
|
|
940
|
+
readFile: async (file) => {
|
|
941
|
+
const remote = await fetchPeerFileContent(peerUrl, ns, file.path, resolvedToken, fetchFn);
|
|
942
|
+
if (!remote || remote.sha256 !== file.sha256) {
|
|
943
|
+
throw new Error(`failed to read peer reconciliation manifest file: ${file.path}`);
|
|
944
|
+
}
|
|
945
|
+
return remote.content;
|
|
946
|
+
}
|
|
947
|
+
})
|
|
948
|
+
);
|
|
852
949
|
}
|
|
853
950
|
}
|
|
854
951
|
const memoryDir = options.cursorDir ?? config?.memoryDir;
|
|
@@ -863,19 +960,28 @@ async function computeConvergePlan(options = {}) {
|
|
|
863
960
|
}
|
|
864
961
|
const inputs = [];
|
|
865
962
|
for (const ns of [...namespacesToPlan].sort()) {
|
|
963
|
+
const baseFiles = baseMap.get(ns);
|
|
964
|
+
const localFiles = localMap.get(ns) ?? [];
|
|
965
|
+
const peerFiles = peerMap.get(ns) ?? [];
|
|
966
|
+
const localDeletions = new Map(localDeletionMtimeMs.get(ns) ?? []);
|
|
967
|
+
const peerDeletions = new Map(peerDeletionMtimeMs.get(ns) ?? []);
|
|
866
968
|
inputs.push({
|
|
867
969
|
namespace: ns,
|
|
868
|
-
local:
|
|
869
|
-
peer:
|
|
870
|
-
base:
|
|
970
|
+
local: localFiles,
|
|
971
|
+
peer: peerFiles,
|
|
972
|
+
base: baseFiles,
|
|
973
|
+
localDeletionMtimeMs: localDeletions,
|
|
974
|
+
peerDeletionMtimeMs: peerDeletions,
|
|
871
975
|
tombstonedFileSha256: localTombstones.get(ns) ?? [],
|
|
872
976
|
peerTombstonedFileSha256: peerTombstones.get(ns) ?? []
|
|
873
977
|
});
|
|
874
978
|
}
|
|
875
|
-
|
|
979
|
+
const conflictPolicy = options.conflictPolicy ?? config?.converge.conflictPolicy ?? DEFAULT_CONVERGE_CONFLICT_POLICY;
|
|
980
|
+
const plan = planReconciliation(inputs, { conflictPolicy });
|
|
981
|
+
return collapseActiveFactDuplicates(plan, localManifests, peerManifests);
|
|
876
982
|
}
|
|
877
983
|
async function executeConvergeApply(options = {}) {
|
|
878
|
-
const conflictPolicy = options.conflictPolicy ??
|
|
984
|
+
const conflictPolicy = options.conflictPolicy ?? options.config?.converge.conflictPolicy ?? DEFAULT_CONVERGE_CONFLICT_POLICY;
|
|
879
985
|
const plan = await computeConvergePlan({ ...options, conflictPolicy });
|
|
880
986
|
if (plan.converged && !options.dryRun) {
|
|
881
987
|
await updateCursorsForPlan(plan, options);
|
|
@@ -888,7 +994,7 @@ async function executeConvergeApply(options = {}) {
|
|
|
888
994
|
};
|
|
889
995
|
}
|
|
890
996
|
const unresolvedCount = plan.byNamespace.reduce((acc, report) => acc + report.unresolved, 0);
|
|
891
|
-
if (unresolvedCount > 0
|
|
997
|
+
if (unresolvedCount > 0) {
|
|
892
998
|
return {
|
|
893
999
|
converged: false,
|
|
894
1000
|
status: "stopped_unresolved_conflicts",
|
|
@@ -966,12 +1072,9 @@ async function executeConvergeApply(options = {}) {
|
|
|
966
1072
|
transferType = "suppress";
|
|
967
1073
|
} else if (entry.action === "conflict") {
|
|
968
1074
|
if (entry.resolution === "peer-wins") {
|
|
969
|
-
transferType = "pull";
|
|
1075
|
+
transferType = entry.peerSha256 ? "pull" : "delete-local";
|
|
970
1076
|
} else if (entry.resolution === "local-wins") {
|
|
971
|
-
transferType = "push";
|
|
972
|
-
} else if (entry.resolution === "supersede-link") {
|
|
973
|
-
if (entry.newerSide === "peer") transferType = "pull";
|
|
974
|
-
else if (entry.newerSide === "local") transferType = "push";
|
|
1077
|
+
transferType = entry.localSha256 ? "push" : "delete-peer";
|
|
975
1078
|
}
|
|
976
1079
|
}
|
|
977
1080
|
if (transferType === "pull") {
|
|
@@ -1116,6 +1219,56 @@ async function executeConvergeApply(options = {}) {
|
|
|
1116
1219
|
} else {
|
|
1117
1220
|
actualTransfers.failed += 1;
|
|
1118
1221
|
}
|
|
1222
|
+
} else if (transferType === "delete-local") {
|
|
1223
|
+
let deleted = false;
|
|
1224
|
+
const bufferedFiles = options.localFileBuffers?.get(entry.namespace);
|
|
1225
|
+
if (options.localFileBuffers) {
|
|
1226
|
+
const current = bufferedFiles?.get(entry.path);
|
|
1227
|
+
if (current && entry.localSha256 && createHash2("sha256").update(current).digest("hex") === entry.localSha256) {
|
|
1228
|
+
bufferedFiles.delete(entry.path);
|
|
1229
|
+
deleted = true;
|
|
1230
|
+
}
|
|
1231
|
+
} else {
|
|
1232
|
+
const rootDir = rootMap.get(entry.namespace);
|
|
1233
|
+
if (rootDir && entry.localSha256) {
|
|
1234
|
+
try {
|
|
1235
|
+
const io = await createOfflineStorageIo(rootDir);
|
|
1236
|
+
const filePath = path2.join(rootDir, entry.path);
|
|
1237
|
+
const current = await io.readFileDigest({ root: rootDir, path: entry.path, filePath });
|
|
1238
|
+
if (current.sha256 === entry.localSha256) {
|
|
1239
|
+
await io.deleteFile({ root: rootDir, path: entry.path, filePath });
|
|
1240
|
+
deleted = true;
|
|
1241
|
+
}
|
|
1242
|
+
} catch {
|
|
1243
|
+
deleted = false;
|
|
1244
|
+
}
|
|
1245
|
+
}
|
|
1246
|
+
}
|
|
1247
|
+
if (deleted) actualTransfers.conflictsResolved += 1;
|
|
1248
|
+
else actualTransfers.failed += 1;
|
|
1249
|
+
} else if (transferType === "delete-peer") {
|
|
1250
|
+
let deleted = false;
|
|
1251
|
+
const bufferedFiles = options.peerFileBuffers?.get(entry.namespace);
|
|
1252
|
+
if (options.peerFileBuffers) {
|
|
1253
|
+
const current = bufferedFiles?.get(entry.path);
|
|
1254
|
+
if (current && entry.peerSha256 && createHash2("sha256").update(current).digest("hex") === entry.peerSha256) {
|
|
1255
|
+
bufferedFiles.delete(entry.path);
|
|
1256
|
+
deleted = true;
|
|
1257
|
+
}
|
|
1258
|
+
} else if (options.peerUrl && entry.peerSha256) {
|
|
1259
|
+
const deletionResult = await postPeerFileDeletion(
|
|
1260
|
+
options.peerUrl,
|
|
1261
|
+
entry.namespace,
|
|
1262
|
+
entry.path,
|
|
1263
|
+
entry.peerSha256,
|
|
1264
|
+
resolvedToken,
|
|
1265
|
+
fetchFn
|
|
1266
|
+
);
|
|
1267
|
+
deleted = Boolean(deletionResult);
|
|
1268
|
+
if (deletionResult === "applied") peerMutatedNamespaces.add(entry.namespace);
|
|
1269
|
+
}
|
|
1270
|
+
if (deleted) actualTransfers.conflictsResolved += 1;
|
|
1271
|
+
else actualTransfers.failed += 1;
|
|
1119
1272
|
} else if (transferType === "suppress") {
|
|
1120
1273
|
actualTransfers.suppressed += 1;
|
|
1121
1274
|
}
|
|
@@ -1156,10 +1309,9 @@ async function updateCursorsForPlan(plan, options) {
|
|
|
1156
1309
|
const namespaces = new Set(plan.byNamespace.map((n) => n.namespace));
|
|
1157
1310
|
for (const ns of namespaces) {
|
|
1158
1311
|
const cursorPath = defaultConvergeCursorPath(memoryDir, peerUrl, ns);
|
|
1159
|
-
const
|
|
1160
|
-
|
|
1161
|
-
|
|
1162
|
-
sha256: e.localSha256 ?? e.peerSha256 ?? "unknown"
|
|
1312
|
+
const baseFiles = plan.entries.filter((entry) => entry.namespace === ns && entry.reason !== "semantic_duplicate" && !(entry.reason === "local_modified_peer_deleted" && entry.resolution === "peer-wins") && !(entry.reason === "local_deleted_peer_modified" && entry.resolution === "local-wins")).map((entry) => ({
|
|
1313
|
+
path: entry.path,
|
|
1314
|
+
sha256: entry.localSha256 ?? entry.peerSha256 ?? "unknown"
|
|
1163
1315
|
}));
|
|
1164
1316
|
const cursorState = {
|
|
1165
1317
|
version: 1,
|
|
@@ -1209,7 +1361,7 @@ function formatConvergeApplyReport(result) {
|
|
|
1209
1361
|
lines.push(formatConvergeReport(result.plan));
|
|
1210
1362
|
return lines.join("\n");
|
|
1211
1363
|
}
|
|
1212
|
-
async function cmdConverge(action, rest, json) {
|
|
1364
|
+
async function cmdConverge(action, rest, json, config = parseConfig2({})) {
|
|
1213
1365
|
if (action === "help" || action === "--help" || action === "-h" || rest.includes("--help") || rest.includes("-h")) {
|
|
1214
1366
|
console.log(`Usage: remnic converge <plan|apply> [options]
|
|
1215
1367
|
|
|
@@ -1221,7 +1373,8 @@ Options:
|
|
|
1221
1373
|
--peer <url> Peer server URL (or --remote-url / --remote)
|
|
1222
1374
|
--token <token> Bearer token or SecretRef for peer authentication
|
|
1223
1375
|
--conflict-policy <policy>
|
|
1224
|
-
|
|
1376
|
+
Policy override (newest-wins|manual)
|
|
1377
|
+
Default: converge.conflictPolicy (newest-wins)
|
|
1225
1378
|
--dry-run Simulate transfers without mutating disk or remote peer
|
|
1226
1379
|
--json Output detailed JSON plan report
|
|
1227
1380
|
`);
|
|
@@ -1247,16 +1400,19 @@ Options:
|
|
|
1247
1400
|
i += 1;
|
|
1248
1401
|
} else if (arg === "--dry-run") {
|
|
1249
1402
|
dryRun = true;
|
|
1250
|
-
} else if (arg === "--conflict-policy"
|
|
1251
|
-
const
|
|
1252
|
-
if (
|
|
1253
|
-
|
|
1403
|
+
} else if (arg === "--conflict-policy") {
|
|
1404
|
+
const policy = rest[i + 1];
|
|
1405
|
+
if (typeof policy !== "string" || !CONVERGE_CONFLICT_POLICIES.includes(policy)) {
|
|
1406
|
+
throw new Error(
|
|
1407
|
+
`converge: --conflict-policy must be one of ${CONVERGE_CONFLICT_POLICIES.join(", ")}`
|
|
1408
|
+
);
|
|
1254
1409
|
}
|
|
1410
|
+
conflictPolicy = policy;
|
|
1255
1411
|
i += 1;
|
|
1256
1412
|
}
|
|
1257
1413
|
}
|
|
1258
1414
|
if (action === "plan") {
|
|
1259
|
-
const plan = await computeConvergePlan({ peerUrl, peerToken, conflictPolicy });
|
|
1415
|
+
const plan = await computeConvergePlan({ config, peerUrl, peerToken, conflictPolicy });
|
|
1260
1416
|
if (json) {
|
|
1261
1417
|
console.log(JSON.stringify(plan, null, 2));
|
|
1262
1418
|
} else {
|
|
@@ -1268,7 +1424,8 @@ Options:
|
|
|
1268
1424
|
peerUrl,
|
|
1269
1425
|
peerToken,
|
|
1270
1426
|
dryRun,
|
|
1271
|
-
conflictPolicy
|
|
1427
|
+
conflictPolicy,
|
|
1428
|
+
config
|
|
1272
1429
|
});
|
|
1273
1430
|
if (json) {
|
|
1274
1431
|
console.log(JSON.stringify(result, null, 2));
|
|
@@ -14385,7 +14542,15 @@ Options:
|
|
|
14385
14542
|
case "converge": {
|
|
14386
14543
|
const action = rest[0] ?? "plan";
|
|
14387
14544
|
const json = rest.includes("--json");
|
|
14388
|
-
|
|
14545
|
+
const args = rest.slice(1);
|
|
14546
|
+
if (action === "help" || action === "--help" || action === "-h" || args.includes("--help") || args.includes("-h")) {
|
|
14547
|
+
await cmdConverge(action, args, json);
|
|
14548
|
+
break;
|
|
14549
|
+
}
|
|
14550
|
+
const configPath = resolveConfigPath();
|
|
14551
|
+
const raw = fs12.existsSync(configPath) ? JSON.parse(fs12.readFileSync(configPath, "utf8")) : {};
|
|
14552
|
+
const config = parseConfig5(resolveRemnicConfigRecord4(raw));
|
|
14553
|
+
await cmdConverge(action, args, json, config);
|
|
14389
14554
|
break;
|
|
14390
14555
|
}
|
|
14391
14556
|
case "oauth": {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@remnic/cli",
|
|
3
|
-
"version": "9.
|
|
3
|
+
"version": "9.45.1",
|
|
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/
|
|
31
|
-
"@remnic/
|
|
29
|
+
"@remnic/server": "^9.45.1",
|
|
30
|
+
"@remnic/plugin-pi": "^9.45.1",
|
|
31
|
+
"@remnic/core": "^9.45.1"
|
|
32
32
|
},
|
|
33
33
|
"peerDependencies": {
|
|
34
|
-
"@remnic/bench": "^9.
|
|
35
|
-
"@remnic/export-weclone": "^9.
|
|
36
|
-
"@remnic/import-weclone": "^9.
|
|
37
|
-
"@remnic/import-chatgpt": "^9.
|
|
38
|
-
"@remnic/import-claude": "^9.
|
|
39
|
-
"@remnic/import-gemini": "^9.
|
|
40
|
-
"@remnic/import-lossless-claw": "^9.
|
|
41
|
-
"@remnic/import-mem0": "^9.
|
|
42
|
-
"@remnic/import-supermemory": "^9.
|
|
43
|
-
"@remnic/connector-limitless": "^9.
|
|
44
|
-
"@remnic/connector-bee": "^9.
|
|
45
|
-
"@remnic/connector-omi": "^9.
|
|
46
|
-
"@remnic/capture-audio": "^9.
|
|
34
|
+
"@remnic/bench": "^9.45.1",
|
|
35
|
+
"@remnic/export-weclone": "^9.45.1",
|
|
36
|
+
"@remnic/import-weclone": "^9.45.1",
|
|
37
|
+
"@remnic/import-chatgpt": "^9.45.1",
|
|
38
|
+
"@remnic/import-claude": "^9.45.1",
|
|
39
|
+
"@remnic/import-gemini": "^9.45.1",
|
|
40
|
+
"@remnic/import-lossless-claw": "^9.45.1",
|
|
41
|
+
"@remnic/import-mem0": "^9.45.1",
|
|
42
|
+
"@remnic/import-supermemory": "^9.45.1",
|
|
43
|
+
"@remnic/connector-limitless": "^9.45.1",
|
|
44
|
+
"@remnic/connector-bee": "^9.45.1",
|
|
45
|
+
"@remnic/connector-omi": "^9.45.1",
|
|
46
|
+
"@remnic/capture-audio": "^9.45.1"
|
|
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.
|
|
93
|
-
"@remnic/export-weclone": "9.
|
|
94
|
-
"@remnic/import-weclone": "9.
|
|
95
|
-
"@remnic/import-chatgpt": "9.
|
|
96
|
-
"@remnic/import-
|
|
97
|
-
"@remnic/import-mem0": "9.
|
|
98
|
-
"@remnic/import-
|
|
99
|
-
"@remnic/import-lossless-claw": "9.
|
|
100
|
-
"@remnic/
|
|
101
|
-
"@remnic/connector-bee": "9.
|
|
102
|
-
"@remnic/
|
|
103
|
-
"@remnic/connector-omi": "9.
|
|
92
|
+
"@remnic/bench": "9.45.1",
|
|
93
|
+
"@remnic/export-weclone": "9.45.1",
|
|
94
|
+
"@remnic/import-weclone": "9.45.1",
|
|
95
|
+
"@remnic/import-chatgpt": "9.45.1",
|
|
96
|
+
"@remnic/import-claude": "9.45.1",
|
|
97
|
+
"@remnic/import-mem0": "9.45.1",
|
|
98
|
+
"@remnic/import-gemini": "9.45.1",
|
|
99
|
+
"@remnic/import-lossless-claw": "9.45.1",
|
|
100
|
+
"@remnic/import-supermemory": "9.45.1",
|
|
101
|
+
"@remnic/connector-bee": "9.45.1",
|
|
102
|
+
"@remnic/connector-limitless": "9.45.1",
|
|
103
|
+
"@remnic/connector-omi": "9.45.1"
|
|
104
104
|
},
|
|
105
105
|
"license": "MIT",
|
|
106
106
|
"repository": {
|