@remnic/cli 1.0.24 → 1.0.25
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 +153 -21
- package/package.json +5 -5
package/dist/index.js
CHANGED
|
@@ -5,6 +5,7 @@ import path11 from "path";
|
|
|
5
5
|
import { createDecipheriv, createHash } from "crypto";
|
|
6
6
|
import * as childProcess2 from "child_process";
|
|
7
7
|
import { fileURLToPath as fileURLToPath4 } from "url";
|
|
8
|
+
import { gzipSync } from "zlib";
|
|
8
9
|
import {
|
|
9
10
|
parseConfig,
|
|
10
11
|
isOpenaiApiKeyDisabled,
|
|
@@ -6648,6 +6649,7 @@ function offlineEndpoint(remoteUrl, pathname, params = {}) {
|
|
|
6648
6649
|
return url.toString();
|
|
6649
6650
|
}
|
|
6650
6651
|
var OFFLINE_SYNC_REQUEST_TIMEOUT_DEFAULT_MS = 15 * 6e4;
|
|
6652
|
+
var OFFLINE_SYNC_SNAPSHOT_BASE_POST_PREFERRED_MAX_BODY_BYTES = 16 * 1024 * 1024;
|
|
6651
6653
|
function parseOfflineSyncRequestTimeoutMs(raw, fallback = OFFLINE_SYNC_REQUEST_TIMEOUT_DEFAULT_MS) {
|
|
6652
6654
|
if (raw === void 0 || raw.trim().length === 0) return fallback;
|
|
6653
6655
|
const parsed = Number(raw);
|
|
@@ -6746,29 +6748,130 @@ async function fetchOfflineJson(url, token, init = {}) {
|
|
|
6746
6748
|
}
|
|
6747
6749
|
);
|
|
6748
6750
|
}
|
|
6751
|
+
async function parseOfflineSnapshotStreamResponse(response) {
|
|
6752
|
+
if (!response.body) {
|
|
6753
|
+
throw new Error("offline sync snapshot stream response omitted body");
|
|
6754
|
+
}
|
|
6755
|
+
const reader = response.body.getReader();
|
|
6756
|
+
const decoder = new TextDecoder();
|
|
6757
|
+
let buffered = "";
|
|
6758
|
+
let header = null;
|
|
6759
|
+
const files = [];
|
|
6760
|
+
const handleLine = (line) => {
|
|
6761
|
+
if (line.trim().length === 0) return;
|
|
6762
|
+
const parsed = JSON.parse(line);
|
|
6763
|
+
if (parsed.type === "snapshot") {
|
|
6764
|
+
if (header) throw new Error("offline sync snapshot stream repeated header");
|
|
6765
|
+
header = {
|
|
6766
|
+
...typeof parsed.namespace === "string" && parsed.namespace.length > 0 ? { namespace: parsed.namespace } : {},
|
|
6767
|
+
format: parsed.format,
|
|
6768
|
+
schemaVersion: parsed.schemaVersion,
|
|
6769
|
+
createdAt: parsed.createdAt,
|
|
6770
|
+
sourceId: parsed.sourceId,
|
|
6771
|
+
includeTranscripts: parsed.includeTranscripts
|
|
6772
|
+
};
|
|
6773
|
+
return;
|
|
6774
|
+
}
|
|
6775
|
+
if (parsed.type === "file") {
|
|
6776
|
+
if (!header) throw new Error("offline sync snapshot stream file arrived before header");
|
|
6777
|
+
files.push(parsed.file);
|
|
6778
|
+
return;
|
|
6779
|
+
}
|
|
6780
|
+
throw new Error("offline sync snapshot stream contained unknown event");
|
|
6781
|
+
};
|
|
6782
|
+
for (; ; ) {
|
|
6783
|
+
const { value, done } = await reader.read();
|
|
6784
|
+
if (done) break;
|
|
6785
|
+
buffered += decoder.decode(value, { stream: true });
|
|
6786
|
+
for (; ; ) {
|
|
6787
|
+
const newline = buffered.indexOf("\n");
|
|
6788
|
+
if (newline < 0) break;
|
|
6789
|
+
const line = buffered.slice(0, newline);
|
|
6790
|
+
buffered = buffered.slice(newline + 1);
|
|
6791
|
+
handleLine(line);
|
|
6792
|
+
}
|
|
6793
|
+
}
|
|
6794
|
+
buffered += decoder.decode();
|
|
6795
|
+
handleLine(buffered);
|
|
6796
|
+
const finalHeader = header;
|
|
6797
|
+
if (!finalHeader) throw new Error("offline sync snapshot stream omitted header");
|
|
6798
|
+
const snapshot = normalizeOfflineSyncSnapshot({
|
|
6799
|
+
format: finalHeader.format,
|
|
6800
|
+
schemaVersion: finalHeader.schemaVersion,
|
|
6801
|
+
createdAt: finalHeader.createdAt,
|
|
6802
|
+
sourceId: finalHeader.sourceId,
|
|
6803
|
+
includeTranscripts: finalHeader.includeTranscripts,
|
|
6804
|
+
files
|
|
6805
|
+
});
|
|
6806
|
+
return {
|
|
6807
|
+
...finalHeader.namespace ? { namespace: finalHeader.namespace } : {},
|
|
6808
|
+
...snapshot
|
|
6809
|
+
};
|
|
6810
|
+
}
|
|
6811
|
+
async function fetchOfflineSnapshotStream(args) {
|
|
6812
|
+
const url = offlineEndpoint(args.remoteUrl, "/remnic/v1/offline-sync/snapshot-stream", {
|
|
6813
|
+
namespace: args.namespace,
|
|
6814
|
+
include_transcripts: args.includeTranscripts ? "true" : "false",
|
|
6815
|
+
content: "false"
|
|
6816
|
+
});
|
|
6817
|
+
return fetchOfflineWithResponse(
|
|
6818
|
+
url,
|
|
6819
|
+
args.token,
|
|
6820
|
+
{},
|
|
6821
|
+
{},
|
|
6822
|
+
async (response) => {
|
|
6823
|
+
if (!response.ok) {
|
|
6824
|
+
await throwOfflineResponseError(response, url, {}, "offline sync snapshot-stream request");
|
|
6825
|
+
}
|
|
6826
|
+
return parseOfflineSnapshotStreamResponse(response);
|
|
6827
|
+
}
|
|
6828
|
+
);
|
|
6829
|
+
}
|
|
6749
6830
|
async function fetchOfflineSnapshot(args) {
|
|
6831
|
+
let tryStreamSnapshot = false;
|
|
6750
6832
|
if (args.includeContent === false && args.baseFiles && args.baseFiles.length > 0) {
|
|
6751
|
-
|
|
6752
|
-
|
|
6753
|
-
|
|
6754
|
-
|
|
6755
|
-
|
|
6756
|
-
|
|
6757
|
-
|
|
6758
|
-
|
|
6759
|
-
|
|
6760
|
-
|
|
6761
|
-
|
|
6762
|
-
|
|
6763
|
-
|
|
6764
|
-
|
|
6765
|
-
|
|
6766
|
-
|
|
6767
|
-
|
|
6768
|
-
|
|
6833
|
+
if (args.baseFiles.length > OFFLINE_SYNC_SNAPSHOT_BASE_POST_MAX_FILES) {
|
|
6834
|
+
tryStreamSnapshot = true;
|
|
6835
|
+
} else {
|
|
6836
|
+
const postBody = offlineSnapshotBasePostBody({
|
|
6837
|
+
namespace: args.namespace,
|
|
6838
|
+
includeTranscripts: args.includeTranscripts,
|
|
6839
|
+
baseFiles: args.baseFiles,
|
|
6840
|
+
baseCapturedAt: args.baseCapturedAt
|
|
6841
|
+
});
|
|
6842
|
+
const postRequest = offlineSnapshotBasePostRequest(postBody);
|
|
6843
|
+
if (postRequest) {
|
|
6844
|
+
const postRequestUsesGzip = new Headers(postRequest.headers).get("content-encoding")?.toLowerCase() === "gzip";
|
|
6845
|
+
try {
|
|
6846
|
+
return await fetchOfflineJson(
|
|
6847
|
+
offlineEndpoint(args.remoteUrl, "/remnic/v1/offline-sync/snapshot"),
|
|
6848
|
+
args.token,
|
|
6849
|
+
{
|
|
6850
|
+
method: "POST",
|
|
6851
|
+
...postRequest
|
|
6852
|
+
}
|
|
6853
|
+
);
|
|
6854
|
+
} catch (error) {
|
|
6855
|
+
if (!isOfflineSnapshotPostFallbackError(error, { compressed: postRequestUsesGzip })) throw error;
|
|
6856
|
+
tryStreamSnapshot = true;
|
|
6857
|
+
}
|
|
6858
|
+
} else {
|
|
6859
|
+
tryStreamSnapshot = true;
|
|
6769
6860
|
}
|
|
6770
6861
|
}
|
|
6771
6862
|
}
|
|
6863
|
+
if (tryStreamSnapshot) {
|
|
6864
|
+
try {
|
|
6865
|
+
return await fetchOfflineSnapshotStream({
|
|
6866
|
+
remoteUrl: args.remoteUrl,
|
|
6867
|
+
token: args.token,
|
|
6868
|
+
namespace: args.namespace,
|
|
6869
|
+
includeTranscripts: args.includeTranscripts
|
|
6870
|
+
});
|
|
6871
|
+
} catch (error) {
|
|
6872
|
+
if (!isOfflineSnapshotStreamFallbackError(error)) throw error;
|
|
6873
|
+
}
|
|
6874
|
+
}
|
|
6772
6875
|
return fetchOfflineJson(
|
|
6773
6876
|
offlineEndpoint(args.remoteUrl, "/remnic/v1/offline-sync/snapshot", {
|
|
6774
6877
|
namespace: args.namespace,
|
|
@@ -6788,11 +6891,36 @@ function offlineSnapshotBasePostBody(args) {
|
|
|
6788
6891
|
});
|
|
6789
6892
|
}
|
|
6790
6893
|
function offlineSnapshotBasePostBodyFits(body) {
|
|
6791
|
-
|
|
6894
|
+
const bytes = Buffer.byteLength(body, "utf-8");
|
|
6895
|
+
return bytes <= OFFLINE_SYNC_SNAPSHOT_BASE_MAX_BODY_BYTES && bytes <= OFFLINE_SYNC_SNAPSHOT_BASE_POST_PREFERRED_MAX_BODY_BYTES;
|
|
6896
|
+
}
|
|
6897
|
+
var OFFLINE_SYNC_SNAPSHOT_BASE_POST_MAX_FILES = 5e4;
|
|
6898
|
+
function offlineSnapshotBasePostRequest(body) {
|
|
6899
|
+
const bytes = Buffer.byteLength(body, "utf-8");
|
|
6900
|
+
if (bytes > OFFLINE_SYNC_SNAPSHOT_BASE_MAX_BODY_BYTES) return null;
|
|
6901
|
+
if (bytes <= OFFLINE_SYNC_SNAPSHOT_BASE_POST_PREFERRED_MAX_BODY_BYTES) {
|
|
6902
|
+
return { body };
|
|
6903
|
+
}
|
|
6904
|
+
const compressed = gzipSync(body);
|
|
6905
|
+
if (compressed.byteLength > OFFLINE_SYNC_SNAPSHOT_BASE_POST_PREFERRED_MAX_BODY_BYTES) {
|
|
6906
|
+
return null;
|
|
6907
|
+
}
|
|
6908
|
+
return {
|
|
6909
|
+
body: compressed,
|
|
6910
|
+
headers: {
|
|
6911
|
+
"content-encoding": "gzip"
|
|
6912
|
+
}
|
|
6913
|
+
};
|
|
6914
|
+
}
|
|
6915
|
+
function isOfflineSnapshotPostFallbackError(error, options = {}) {
|
|
6916
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
6917
|
+
if (/offline-sync\/snapshot\b.* returned (404|405|413)\b/.test(message)) return true;
|
|
6918
|
+
if (!options.compressed) return false;
|
|
6919
|
+
return /offline-sync\/snapshot\b.* returned (400|415)\b/.test(message) && /\b(unsupported_content_encoding|invalid_gzip_body|invalid_json)\b/.test(message);
|
|
6792
6920
|
}
|
|
6793
|
-
function
|
|
6921
|
+
function isOfflineSnapshotStreamFallbackError(error) {
|
|
6794
6922
|
const message = error instanceof Error ? error.message : String(error);
|
|
6795
|
-
return /offline-sync\/snapshot\b.* returned (404|405
|
|
6923
|
+
return /offline-sync\/snapshot-stream\b.* returned (404|405)\b/.test(message);
|
|
6796
6924
|
}
|
|
6797
6925
|
async function fetchOfflineFiles(args) {
|
|
6798
6926
|
return fetchOfflineJson(
|
|
@@ -11273,6 +11401,8 @@ export {
|
|
|
11273
11401
|
OFFLINE_SYNC_DIRECT_PUSH_MIN_BYTES,
|
|
11274
11402
|
OFFLINE_SYNC_FILE_CONTENT_UPLOAD_CHUNK_BYTES,
|
|
11275
11403
|
OFFLINE_SYNC_REQUEST_TIMEOUT_DEFAULT_MS,
|
|
11404
|
+
OFFLINE_SYNC_SNAPSHOT_BASE_POST_MAX_FILES,
|
|
11405
|
+
OFFLINE_SYNC_SNAPSHOT_BASE_POST_PREFERRED_MAX_BODY_BYTES,
|
|
11276
11406
|
TAXONOMY_RESOLVE_BOOLEAN_FLAGS,
|
|
11277
11407
|
TAXONOMY_RESOLVE_VALUE_FLAGS,
|
|
11278
11408
|
__benchDatasetTestHooks,
|
|
@@ -11284,6 +11414,7 @@ export {
|
|
|
11284
11414
|
chunkOfflineFileContentBatches,
|
|
11285
11415
|
directHydrateLargeOfflineFiles,
|
|
11286
11416
|
extractXrayRawArgs,
|
|
11417
|
+
fetchOfflineSnapshot,
|
|
11287
11418
|
formatOfflineLargeFilePushFailureMessage,
|
|
11288
11419
|
formatOfflineRequestForError,
|
|
11289
11420
|
getBenchUsageText,
|
|
@@ -11293,6 +11424,7 @@ export {
|
|
|
11293
11424
|
offlinePartialHydrationForPaths,
|
|
11294
11425
|
offlineSnapshotBasePostBody,
|
|
11295
11426
|
offlineSnapshotBasePostBodyFits,
|
|
11427
|
+
offlineSnapshotBasePostRequest,
|
|
11296
11428
|
offlineSnapshotContentFilesForApply,
|
|
11297
11429
|
parseBenchArgs,
|
|
11298
11430
|
parseCapsuleForkArgs,
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@remnic/cli",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.25",
|
|
4
4
|
"description": "CLI for Remnic memory — init, query, doctor, daemon management",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "dist/index.js",
|
|
@@ -26,9 +26,9 @@
|
|
|
26
26
|
},
|
|
27
27
|
"dependencies": {
|
|
28
28
|
"yaml": "^2.4.2",
|
|
29
|
+
"@remnic/plugin-pi": "^1.0.9",
|
|
29
30
|
"@remnic/server": "^1.0.5",
|
|
30
|
-
"@remnic/
|
|
31
|
-
"@remnic/core": "^1.1.30"
|
|
31
|
+
"@remnic/core": "^1.1.31"
|
|
32
32
|
},
|
|
33
33
|
"peerDependencies": {
|
|
34
34
|
"@remnic/bench": "^1.0.0",
|
|
@@ -80,8 +80,8 @@
|
|
|
80
80
|
"@remnic/import-claude": "0.1.0",
|
|
81
81
|
"@remnic/import-gemini": "0.1.0",
|
|
82
82
|
"@remnic/import-lossless-claw": "0.1.1",
|
|
83
|
-
"@remnic/import-
|
|
84
|
-
"@remnic/import-
|
|
83
|
+
"@remnic/import-supermemory": "0.1.2",
|
|
84
|
+
"@remnic/import-mem0": "0.1.0"
|
|
85
85
|
},
|
|
86
86
|
"license": "MIT",
|
|
87
87
|
"repository": {
|