@remnic/cli 1.0.13 → 1.0.14
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 +22 -17
- package/package.json +5 -5
package/dist/index.js
CHANGED
|
@@ -6670,6 +6670,7 @@ async function fetchOfflineFiles(args) {
|
|
|
6670
6670
|
);
|
|
6671
6671
|
}
|
|
6672
6672
|
var OFFLINE_SYNC_DIRECT_HYDRATE_MIN_BYTES = 16 * 1024 * 1024;
|
|
6673
|
+
var OFFLINE_SYNC_FILES_CONTENT_MAX_BATCH_BYTES = 8 * 1024 * 1024;
|
|
6673
6674
|
function parseOfflineHeaderNumber(headers, name) {
|
|
6674
6675
|
const raw = headers.get(name);
|
|
6675
6676
|
if (raw === null) throw new Error(`offline file content response omitted ${name}`);
|
|
@@ -6761,16 +6762,16 @@ async function readFirstOfflineSyncState(paths) {
|
|
|
6761
6762
|
function offlineFileStateMap(files) {
|
|
6762
6763
|
return new Map(files.map((file) => [file.path, file]));
|
|
6763
6764
|
}
|
|
6764
|
-
function
|
|
6765
|
+
function offlineSnapshotContentFilesForApply(options) {
|
|
6765
6766
|
const base = offlineFileStateMap(options.baseFiles);
|
|
6766
6767
|
const current = options.currentFiles ? offlineFileStateMap(options.currentFiles) : null;
|
|
6767
|
-
const
|
|
6768
|
+
const files = [];
|
|
6768
6769
|
for (const incoming of options.snapshot.files) {
|
|
6769
6770
|
if (current?.get(incoming.path)?.sha256 === incoming.sha256) continue;
|
|
6770
6771
|
if (base.get(incoming.path)?.sha256 === incoming.sha256) continue;
|
|
6771
|
-
|
|
6772
|
+
files.push(incoming);
|
|
6772
6773
|
}
|
|
6773
|
-
return
|
|
6774
|
+
return files.sort((left, right) => left.path.localeCompare(right.path));
|
|
6774
6775
|
}
|
|
6775
6776
|
function shouldDirectHydrateOfflineFile(options) {
|
|
6776
6777
|
if (options.incoming.bytes < OFFLINE_SYNC_DIRECT_HYDRATE_MIN_BYTES) return false;
|
|
@@ -6852,19 +6853,22 @@ async function directHydrateLargeOfflineFiles(args) {
|
|
|
6852
6853
|
}
|
|
6853
6854
|
return hydrated;
|
|
6854
6855
|
}
|
|
6855
|
-
function
|
|
6856
|
+
function chunkOfflineFileContentBatches(files) {
|
|
6856
6857
|
const chunks = [];
|
|
6857
6858
|
let current = [];
|
|
6858
|
-
let
|
|
6859
|
-
|
|
6860
|
-
|
|
6861
|
-
|
|
6859
|
+
let currentPathBytes = 256;
|
|
6860
|
+
let currentContentBytes = 0;
|
|
6861
|
+
for (const file of files) {
|
|
6862
|
+
const pathCost = Buffer.byteLength(JSON.stringify(file.path), "utf-8") + 1;
|
|
6863
|
+
if (current.length > 0 && (current.length >= 1e3 || currentPathBytes + pathCost > 96e3 || currentContentBytes + file.bytes > OFFLINE_SYNC_FILES_CONTENT_MAX_BATCH_BYTES)) {
|
|
6862
6864
|
chunks.push(current);
|
|
6863
6865
|
current = [];
|
|
6864
|
-
|
|
6866
|
+
currentPathBytes = 256;
|
|
6867
|
+
currentContentBytes = 0;
|
|
6865
6868
|
}
|
|
6866
|
-
current.push(
|
|
6867
|
-
|
|
6869
|
+
current.push(file);
|
|
6870
|
+
currentPathBytes += pathCost;
|
|
6871
|
+
currentContentBytes += file.bytes;
|
|
6868
6872
|
}
|
|
6869
6873
|
if (current.length > 0) chunks.push(current);
|
|
6870
6874
|
return chunks;
|
|
@@ -6878,22 +6882,22 @@ function isMissingOfflineContentError(error) {
|
|
|
6878
6882
|
return /^missing decoded content for /.test(message);
|
|
6879
6883
|
}
|
|
6880
6884
|
async function hydrateOfflineSnapshotContent(args) {
|
|
6881
|
-
const
|
|
6885
|
+
const neededFiles = offlineSnapshotContentFilesForApply({
|
|
6882
6886
|
snapshot: args.snapshot,
|
|
6883
6887
|
baseFiles: args.baseFiles,
|
|
6884
6888
|
currentFiles: args.currentFiles
|
|
6885
6889
|
});
|
|
6886
|
-
if (
|
|
6890
|
+
if (neededFiles.length === 0) return args.snapshot;
|
|
6887
6891
|
const expectedByPath = new Map(args.snapshot.files.map((file) => [file.path, file]));
|
|
6888
6892
|
const contentByPath = /* @__PURE__ */ new Map();
|
|
6889
6893
|
try {
|
|
6890
|
-
for (const batch of
|
|
6894
|
+
for (const batch of chunkOfflineFileContentBatches(neededFiles)) {
|
|
6891
6895
|
const partial = await fetchOfflineFiles({
|
|
6892
6896
|
remoteUrl: args.remoteUrl,
|
|
6893
6897
|
token: args.token,
|
|
6894
6898
|
namespace: args.namespace,
|
|
6895
6899
|
includeTranscripts: args.includeTranscripts,
|
|
6896
|
-
paths: batch
|
|
6900
|
+
paths: batch.map((file) => file.path)
|
|
6897
6901
|
});
|
|
6898
6902
|
for (const file of partial.files) {
|
|
6899
6903
|
const expected = expectedByPath.get(file.path);
|
|
@@ -6917,7 +6921,7 @@ async function hydrateOfflineSnapshotContent(args) {
|
|
|
6917
6921
|
includeContent: true
|
|
6918
6922
|
});
|
|
6919
6923
|
}
|
|
6920
|
-
const missing =
|
|
6924
|
+
const missing = neededFiles.map((file) => file.path).filter((relPath) => !contentByPath.has(relPath));
|
|
6921
6925
|
if (missing.length > 0) {
|
|
6922
6926
|
throw new Error(
|
|
6923
6927
|
`remote offline content response omitted ${missing.length} changed file${missing.length === 1 ? "" : "s"}; retry sync`
|
|
@@ -10228,6 +10232,7 @@ export {
|
|
|
10228
10232
|
buildBenchRuntimeProfileRequest,
|
|
10229
10233
|
buildPackageBenchExecutionPlans,
|
|
10230
10234
|
buildQueryRecallRequest,
|
|
10235
|
+
chunkOfflineFileContentBatches,
|
|
10231
10236
|
extractXrayRawArgs,
|
|
10232
10237
|
getBenchUsageText,
|
|
10233
10238
|
hasFlag,
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@remnic/cli",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.14",
|
|
4
4
|
"description": "CLI for Remnic memory — init, query, doctor, daemon management",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "dist/index.js",
|
|
@@ -27,8 +27,8 @@
|
|
|
27
27
|
"dependencies": {
|
|
28
28
|
"yaml": "^2.4.2",
|
|
29
29
|
"@remnic/plugin-pi": "^1.0.0",
|
|
30
|
-
"@remnic/
|
|
31
|
-
"@remnic/
|
|
30
|
+
"@remnic/server": "^1.0.5",
|
|
31
|
+
"@remnic/core": "^1.1.20"
|
|
32
32
|
},
|
|
33
33
|
"peerDependencies": {
|
|
34
34
|
"@remnic/bench": "^1.0.0",
|
|
@@ -78,10 +78,10 @@
|
|
|
78
78
|
"@remnic/import-weclone": "1.0.1",
|
|
79
79
|
"@remnic/import-chatgpt": "0.1.0",
|
|
80
80
|
"@remnic/import-claude": "0.1.0",
|
|
81
|
+
"@remnic/import-gemini": "0.1.0",
|
|
81
82
|
"@remnic/import-lossless-claw": "0.1.1",
|
|
82
|
-
"@remnic/import-supermemory": "0.1.2",
|
|
83
83
|
"@remnic/import-mem0": "0.1.0",
|
|
84
|
-
"@remnic/import-
|
|
84
|
+
"@remnic/import-supermemory": "0.1.2"
|
|
85
85
|
},
|
|
86
86
|
"license": "MIT",
|
|
87
87
|
"repository": {
|