@remnic/cli 1.0.17 → 1.0.18
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 +78 -4
- package/package.json +5 -5
package/dist/index.js
CHANGED
|
@@ -88,7 +88,9 @@ import {
|
|
|
88
88
|
formatProcedureStatsText,
|
|
89
89
|
parseXrayCliOptions,
|
|
90
90
|
renderXray,
|
|
91
|
+
OFFLINE_SYNC_APPLY_MAX_BODY_BYTES,
|
|
91
92
|
OFFLINE_SYNC_FILE_CONTENT_MAX_CHUNK_BYTES,
|
|
93
|
+
OFFLINE_SYNC_FILE_CONTENT_TRANSFER_CHUNK_BYTES,
|
|
92
94
|
applyOfflineSyncSnapshot,
|
|
93
95
|
buildOfflineSyncChangeset,
|
|
94
96
|
buildOfflineSyncSnapshot,
|
|
@@ -6689,6 +6691,16 @@ async function fetchOfflineFiles(args) {
|
|
|
6689
6691
|
}
|
|
6690
6692
|
var OFFLINE_SYNC_DIRECT_HYDRATE_MIN_BYTES = 16 * 1024 * 1024;
|
|
6691
6693
|
var OFFLINE_SYNC_FILES_CONTENT_MAX_BATCH_BYTES = 8 * 1024 * 1024;
|
|
6694
|
+
var OFFLINE_SYNC_APPLY_MAX_REQUEST_BYTES = Math.floor(OFFLINE_SYNC_APPLY_MAX_BODY_BYTES / 2);
|
|
6695
|
+
var OFFLINE_SYNC_DIRECT_PUSH_INLINE_MARGIN_BYTES = 256 * 1024;
|
|
6696
|
+
var OFFLINE_SYNC_INLINE_CONTENT_MAX_BYTES = Math.max(
|
|
6697
|
+
1,
|
|
6698
|
+
Math.floor((OFFLINE_SYNC_APPLY_MAX_REQUEST_BYTES - OFFLINE_SYNC_DIRECT_PUSH_INLINE_MARGIN_BYTES) * 3 / 4)
|
|
6699
|
+
);
|
|
6700
|
+
var OFFLINE_SYNC_DIRECT_PUSH_MIN_BYTES = Math.min(
|
|
6701
|
+
OFFLINE_SYNC_DIRECT_HYDRATE_MIN_BYTES,
|
|
6702
|
+
OFFLINE_SYNC_INLINE_CONTENT_MAX_BYTES
|
|
6703
|
+
);
|
|
6692
6704
|
function parseOfflineHeaderNumber(headers, name) {
|
|
6693
6705
|
const raw = headers.get(name);
|
|
6694
6706
|
if (raw === null) throw new Error(`offline file content response omitted ${name}`);
|
|
@@ -6837,7 +6849,7 @@ function shouldDirectHydrateOfflineFile(options) {
|
|
|
6837
6849
|
function offlineDirectPushFiles(options) {
|
|
6838
6850
|
const base = offlineFileStateMap(options.baseFiles);
|
|
6839
6851
|
return options.currentFiles.filter((current) => {
|
|
6840
|
-
if (current.bytes <
|
|
6852
|
+
if (current.bytes < OFFLINE_SYNC_DIRECT_PUSH_MIN_BYTES) return false;
|
|
6841
6853
|
return current.sha256 !== base.get(current.path)?.sha256;
|
|
6842
6854
|
}).sort((left, right) => right.bytes - left.bytes || left.path.localeCompare(right.path));
|
|
6843
6855
|
}
|
|
@@ -6850,6 +6862,7 @@ function resolveOfflineDirectHydrationPath(memoryDir, relPath) {
|
|
|
6850
6862
|
}
|
|
6851
6863
|
return target;
|
|
6852
6864
|
}
|
|
6865
|
+
var OFFLINE_SYNC_FILE_CONTENT_UPLOAD_CHUNK_BYTES = OFFLINE_SYNC_FILE_CONTENT_TRANSFER_CHUNK_BYTES;
|
|
6853
6866
|
async function pushOfflineFileContent(args) {
|
|
6854
6867
|
if (args.readFileChunks) {
|
|
6855
6868
|
return pushOfflineFileContentFromChunkReader(args);
|
|
@@ -6862,7 +6875,7 @@ async function pushOfflineFileContent(args) {
|
|
|
6862
6875
|
path: args.file.path,
|
|
6863
6876
|
offset,
|
|
6864
6877
|
length: Math.min(
|
|
6865
|
-
|
|
6878
|
+
OFFLINE_SYNC_FILE_CONTENT_UPLOAD_CHUNK_BYTES,
|
|
6866
6879
|
Math.max(1, args.file.bytes - offset)
|
|
6867
6880
|
),
|
|
6868
6881
|
includeTranscripts: args.includeTranscripts,
|
|
@@ -6907,7 +6920,7 @@ async function pushOfflineFileContentFromChunkReader(args) {
|
|
|
6907
6920
|
root: path11.resolve(args.memoryDir),
|
|
6908
6921
|
path: args.file.path,
|
|
6909
6922
|
filePath,
|
|
6910
|
-
chunkSize:
|
|
6923
|
+
chunkSize: OFFLINE_SYNC_FILE_CONTENT_UPLOAD_CHUNK_BYTES
|
|
6911
6924
|
});
|
|
6912
6925
|
let offset = 0;
|
|
6913
6926
|
let pending = null;
|
|
@@ -7126,7 +7139,39 @@ async function hydrateOfflineSnapshotContent(args) {
|
|
|
7126
7139
|
})
|
|
7127
7140
|
};
|
|
7128
7141
|
}
|
|
7129
|
-
|
|
7142
|
+
function chunkOfflineChangesetApplyBatches(changeset, namespace, maxRequestBytes = OFFLINE_SYNC_APPLY_MAX_REQUEST_BYTES) {
|
|
7143
|
+
if (!Number.isInteger(maxRequestBytes) || maxRequestBytes < 1) {
|
|
7144
|
+
throw new Error("offline sync apply max request bytes must be a positive integer");
|
|
7145
|
+
}
|
|
7146
|
+
const chunks = [];
|
|
7147
|
+
let current = [];
|
|
7148
|
+
const requestBytesFor = (changes) => Buffer.byteLength(JSON.stringify({
|
|
7149
|
+
namespace,
|
|
7150
|
+
changeset: {
|
|
7151
|
+
...changeset,
|
|
7152
|
+
changes
|
|
7153
|
+
}
|
|
7154
|
+
}), "utf-8");
|
|
7155
|
+
for (const change of changeset.changes) {
|
|
7156
|
+
const withChange = [...current, change];
|
|
7157
|
+
if (current.length > 0 && requestBytesFor(withChange) > maxRequestBytes) {
|
|
7158
|
+
chunks.push({ ...changeset, changes: current });
|
|
7159
|
+
current = [];
|
|
7160
|
+
}
|
|
7161
|
+
const singleBytes = requestBytesFor([...current, change]);
|
|
7162
|
+
if (singleBytes > maxRequestBytes) {
|
|
7163
|
+
throw new Error(
|
|
7164
|
+
`offline sync change for ${change.path} exceeds the apply request size budget; retry after direct-push threshold is lowered`
|
|
7165
|
+
);
|
|
7166
|
+
}
|
|
7167
|
+
current.push(change);
|
|
7168
|
+
}
|
|
7169
|
+
if (current.length > 0) {
|
|
7170
|
+
chunks.push({ ...changeset, changes: current });
|
|
7171
|
+
}
|
|
7172
|
+
return chunks;
|
|
7173
|
+
}
|
|
7174
|
+
async function postOfflineChangesBatch(args) {
|
|
7130
7175
|
return fetchOfflineJson(
|
|
7131
7176
|
offlineEndpoint(args.remoteUrl, "/remnic/v1/offline-sync/apply"),
|
|
7132
7177
|
args.token,
|
|
@@ -7139,6 +7184,31 @@ async function pushOfflineChanges(args) {
|
|
|
7139
7184
|
}
|
|
7140
7185
|
);
|
|
7141
7186
|
}
|
|
7187
|
+
async function pushOfflineChanges(args) {
|
|
7188
|
+
let namespace = args.namespace ?? "";
|
|
7189
|
+
let appliedUpserts = 0;
|
|
7190
|
+
let appliedDeletes = 0;
|
|
7191
|
+
let skipped = 0;
|
|
7192
|
+
const conflicts = [];
|
|
7193
|
+
for (const changeset of chunkOfflineChangesetApplyBatches(args.changeset, args.namespace)) {
|
|
7194
|
+
const result = await postOfflineChangesBatch({
|
|
7195
|
+
...args,
|
|
7196
|
+
changeset
|
|
7197
|
+
});
|
|
7198
|
+
namespace = result.namespace || namespace;
|
|
7199
|
+
appliedUpserts += result.appliedUpserts;
|
|
7200
|
+
appliedDeletes += result.appliedDeletes;
|
|
7201
|
+
skipped += result.skipped;
|
|
7202
|
+
conflicts.push(...result.conflicts);
|
|
7203
|
+
}
|
|
7204
|
+
return {
|
|
7205
|
+
namespace,
|
|
7206
|
+
appliedUpserts,
|
|
7207
|
+
appliedDeletes,
|
|
7208
|
+
skipped,
|
|
7209
|
+
conflicts
|
|
7210
|
+
};
|
|
7211
|
+
}
|
|
7142
7212
|
function parseOfflineIntervalMs(args) {
|
|
7143
7213
|
const raw = resolveRequiredValueFlag(args, "--interval-ms");
|
|
7144
7214
|
if (raw === void 0) return 6e4;
|
|
@@ -10604,12 +10674,16 @@ if (argv1Base.endsWith("remnic.ts") || argv1Base.endsWith("remnic.js") || argv1B
|
|
|
10604
10674
|
}
|
|
10605
10675
|
export {
|
|
10606
10676
|
BENCHMARK_CATALOG,
|
|
10677
|
+
OFFLINE_SYNC_APPLY_MAX_REQUEST_BYTES,
|
|
10678
|
+
OFFLINE_SYNC_DIRECT_PUSH_MIN_BYTES,
|
|
10679
|
+
OFFLINE_SYNC_FILE_CONTENT_UPLOAD_CHUNK_BYTES,
|
|
10607
10680
|
TAXONOMY_RESOLVE_BOOLEAN_FLAGS,
|
|
10608
10681
|
TAXONOMY_RESOLVE_VALUE_FLAGS,
|
|
10609
10682
|
__benchDatasetTestHooks,
|
|
10610
10683
|
buildBenchRuntimeProfileRequest,
|
|
10611
10684
|
buildPackageBenchExecutionPlans,
|
|
10612
10685
|
buildQueryRecallRequest,
|
|
10686
|
+
chunkOfflineChangesetApplyBatches,
|
|
10613
10687
|
chunkOfflineFileContentBatches,
|
|
10614
10688
|
extractXrayRawArgs,
|
|
10615
10689
|
formatOfflineLargeFilePushFailureMessage,
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@remnic/cli",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.18",
|
|
4
4
|
"description": "CLI for Remnic memory — init, query, doctor, daemon management",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "dist/index.js",
|
|
@@ -26,8 +26,8 @@
|
|
|
26
26
|
},
|
|
27
27
|
"dependencies": {
|
|
28
28
|
"yaml": "^2.4.2",
|
|
29
|
-
"@remnic/plugin-pi": "^1.0.
|
|
30
|
-
"@remnic/core": "^1.1.
|
|
29
|
+
"@remnic/plugin-pi": "^1.0.4",
|
|
30
|
+
"@remnic/core": "^1.1.24",
|
|
31
31
|
"@remnic/server": "^1.0.5"
|
|
32
32
|
},
|
|
33
33
|
"peerDependencies": {
|
|
@@ -76,11 +76,11 @@
|
|
|
76
76
|
"@remnic/bench": "1.0.1",
|
|
77
77
|
"@remnic/export-weclone": "1.0.1",
|
|
78
78
|
"@remnic/import-weclone": "1.0.1",
|
|
79
|
+
"@remnic/import-claude": "0.1.0",
|
|
79
80
|
"@remnic/import-chatgpt": "0.1.0",
|
|
80
81
|
"@remnic/import-gemini": "0.1.0",
|
|
81
|
-
"@remnic/import-claude": "0.1.0",
|
|
82
|
-
"@remnic/import-lossless-claw": "0.1.1",
|
|
83
82
|
"@remnic/import-mem0": "0.1.0",
|
|
83
|
+
"@remnic/import-lossless-claw": "0.1.1",
|
|
84
84
|
"@remnic/import-supermemory": "0.1.2"
|
|
85
85
|
},
|
|
86
86
|
"license": "MIT",
|