@remnic/cli 1.0.24 → 9.3.515
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 +406 -133
- package/package.json +22 -22
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,
|
|
@@ -850,7 +851,12 @@ function validateBenchFlags(action, args) {
|
|
|
850
851
|
if (!arg.startsWith("-")) {
|
|
851
852
|
continue;
|
|
852
853
|
}
|
|
853
|
-
|
|
854
|
+
const legacyEqualsPrefix = allowed.legacyEqualsPrefixes?.find((prefix) => arg.startsWith(prefix));
|
|
855
|
+
if (legacyEqualsPrefix) {
|
|
856
|
+
const value = arg.slice(legacyEqualsPrefix.length);
|
|
857
|
+
if (value.trim().length === 0) {
|
|
858
|
+
throw new Error(`ERROR: ${legacyEqualsPrefix.slice(0, -1)} requires a value.`);
|
|
859
|
+
}
|
|
854
860
|
continue;
|
|
855
861
|
}
|
|
856
862
|
if (isBenchValueFlag(arg)) {
|
|
@@ -1973,6 +1979,66 @@ function isCandidateReady(candidate, existsSync3) {
|
|
|
1973
1979
|
function resolveServerBin(options = {}) {
|
|
1974
1980
|
return resolveServerBinDetails(options).path;
|
|
1975
1981
|
}
|
|
1982
|
+
function readVerifiedDaemonPid(options) {
|
|
1983
|
+
const readFileSync3 = options.readFileSync ?? fs4.readFileSync;
|
|
1984
|
+
const unlinkSync = options.unlinkSync ?? fs4.unlinkSync;
|
|
1985
|
+
const processKill = options.processKill ?? process.kill;
|
|
1986
|
+
const execFileSync3 = options.execFileSync ?? ((command, args, execOptions) => childProcess.execFileSync(command, args, execOptions));
|
|
1987
|
+
for (const file of options.pidFiles) {
|
|
1988
|
+
let pid;
|
|
1989
|
+
try {
|
|
1990
|
+
pid = parseDaemonPid(readFileSync3(file, "utf8"));
|
|
1991
|
+
} catch {
|
|
1992
|
+
continue;
|
|
1993
|
+
}
|
|
1994
|
+
if (pid === void 0) {
|
|
1995
|
+
removePidFileBestEffort(file, unlinkSync);
|
|
1996
|
+
continue;
|
|
1997
|
+
}
|
|
1998
|
+
try {
|
|
1999
|
+
processKill(pid, 0);
|
|
2000
|
+
} catch {
|
|
2001
|
+
removePidFileBestEffort(file, unlinkSync);
|
|
2002
|
+
continue;
|
|
2003
|
+
}
|
|
2004
|
+
const command = readProcessCommand(pid, execFileSync3);
|
|
2005
|
+
if (command === void 0) {
|
|
2006
|
+
return pid;
|
|
2007
|
+
}
|
|
2008
|
+
if (doesProcessCommandLookLikeRemnicDaemon(command, options.expectedServerBin)) {
|
|
2009
|
+
return pid;
|
|
2010
|
+
}
|
|
2011
|
+
removePidFileBestEffort(file, unlinkSync);
|
|
2012
|
+
}
|
|
2013
|
+
return void 0;
|
|
2014
|
+
}
|
|
2015
|
+
function doesProcessCommandLookLikeRemnicDaemon(command, expectedServerBin) {
|
|
2016
|
+
const normalizedCommand = command.trim();
|
|
2017
|
+
const normalizedExpected = path8.resolve(expandTilde(expectedServerBin));
|
|
2018
|
+
return normalizedCommand.includes(normalizedExpected) || /(?:^|\s|[/\\])(?:remnic-server|engram-server)(?:\.js)?(?:\s|$)/.test(normalizedCommand) || /@remnic[/\\]server[/\\]/.test(normalizedCommand) || /packages[/\\]remnic-server[/\\](?:bin[/\\]remnic-server\.js|dist[/\\]index\.js|src[/\\]index\.ts)/.test(normalizedCommand);
|
|
2019
|
+
}
|
|
2020
|
+
function parseDaemonPid(raw) {
|
|
2021
|
+
const trimmed = raw.trim();
|
|
2022
|
+
if (!/^\d+$/.test(trimmed)) return void 0;
|
|
2023
|
+
const pid = Number(trimmed);
|
|
2024
|
+
return Number.isSafeInteger(pid) && pid > 0 ? pid : void 0;
|
|
2025
|
+
}
|
|
2026
|
+
function readProcessCommand(pid, execFileSync3) {
|
|
2027
|
+
try {
|
|
2028
|
+
return execFileSync3("ps", ["-p", String(pid), "-o", "command="], {
|
|
2029
|
+
encoding: "utf8",
|
|
2030
|
+
stdio: "pipe"
|
|
2031
|
+
});
|
|
2032
|
+
} catch {
|
|
2033
|
+
return void 0;
|
|
2034
|
+
}
|
|
2035
|
+
}
|
|
2036
|
+
function removePidFileBestEffort(file, unlinkSync) {
|
|
2037
|
+
try {
|
|
2038
|
+
unlinkSync(file);
|
|
2039
|
+
} catch {
|
|
2040
|
+
}
|
|
2041
|
+
}
|
|
1976
2042
|
function inspectLaunchdPlist(plistPath, options = {}) {
|
|
1977
2043
|
const existsSync3 = options.existsSync ?? fs4.existsSync;
|
|
1978
2044
|
const readFileSync3 = options.readFileSync ?? fs4.readFileSync;
|
|
@@ -2431,7 +2497,8 @@ Usage:
|
|
|
2431
2497
|
|
|
2432
2498
|
Required:
|
|
2433
2499
|
--adapter <name> One of: ${SUPPORTED_IMPORTERS.join(" | ")}
|
|
2434
|
-
--file <path> Path to
|
|
2500
|
+
--file <path> Path to a text/JSON source export. ZIP archives
|
|
2501
|
+
are not accepted by this single-file path yet. May be
|
|
2435
2502
|
omitted for API-only adapters (mem0).
|
|
2436
2503
|
|
|
2437
2504
|
Options:
|
|
@@ -2522,6 +2589,11 @@ function rejectLeftoverImportArgs(args, command) {
|
|
|
2522
2589
|
}
|
|
2523
2590
|
}
|
|
2524
2591
|
async function runImportCommand(args, io) {
|
|
2592
|
+
if (args.file && isZipFilePath(args.file)) {
|
|
2593
|
+
throw new Error(
|
|
2594
|
+
`ZIP imports are not supported by --file yet: '${args.file}'. Extract the archive first or use --all-from-bundle for supported bundle layouts.`
|
|
2595
|
+
);
|
|
2596
|
+
}
|
|
2525
2597
|
const adapter = await io.loadAdapter(args.adapter);
|
|
2526
2598
|
let input;
|
|
2527
2599
|
if (args.file) {
|
|
@@ -2574,6 +2646,16 @@ async function runImportCommand(args, io) {
|
|
|
2574
2646
|
}
|
|
2575
2647
|
return result;
|
|
2576
2648
|
}
|
|
2649
|
+
function isZipFilePath(filePath) {
|
|
2650
|
+
return pathExtension(filePath) === ".zip";
|
|
2651
|
+
}
|
|
2652
|
+
function pathExtension(filePath) {
|
|
2653
|
+
const normalized = filePath.trim().toLowerCase();
|
|
2654
|
+
const lastSlash = Math.max(normalized.lastIndexOf("/"), normalized.lastIndexOf("\\"));
|
|
2655
|
+
const base = normalized.slice(lastSlash + 1);
|
|
2656
|
+
const dot = base.lastIndexOf(".");
|
|
2657
|
+
return dot >= 0 ? base.slice(dot) : "";
|
|
2658
|
+
}
|
|
2577
2659
|
function parseImportBundleArgs(rest) {
|
|
2578
2660
|
const args = [...rest];
|
|
2579
2661
|
if (!args.includes("--all-from-bundle")) return void 0;
|
|
@@ -3836,7 +3918,8 @@ var __benchDatasetTestHooks = {
|
|
|
3836
3918
|
seed,
|
|
3837
3919
|
benchmarkOptions
|
|
3838
3920
|
);
|
|
3839
|
-
}
|
|
3921
|
+
},
|
|
3922
|
+
printBenchStatusLineForTest: printBenchStatusLine
|
|
3840
3923
|
};
|
|
3841
3924
|
function printBenchPackageSummary(result, outputPath, outputLabel = "Results saved") {
|
|
3842
3925
|
console.log(`Benchmark: ${result.meta.benchmark}`);
|
|
@@ -3851,6 +3934,13 @@ function printBenchPackageSummary(result, outputPath, outputLabel = "Results sav
|
|
|
3851
3934
|
}
|
|
3852
3935
|
console.log(`${outputLabel}: ${outputPath}`);
|
|
3853
3936
|
}
|
|
3937
|
+
function printBenchStatusLine(jsonMode, message) {
|
|
3938
|
+
if (jsonMode) {
|
|
3939
|
+
console.error(message);
|
|
3940
|
+
} else {
|
|
3941
|
+
console.log(message);
|
|
3942
|
+
}
|
|
3943
|
+
}
|
|
3854
3944
|
function printStoredBenchResultSummary(result, summary) {
|
|
3855
3945
|
printBenchPackageSummary(result, summary.path, "Stored result");
|
|
3856
3946
|
console.log(`Run id: ${summary.id}`);
|
|
@@ -4671,7 +4761,8 @@ async function runBenchViaPackage(parsed, benchmarkId, runtimeProfile, benchStat
|
|
|
4671
4761
|
if (completed % 50 === 0 || completed === total) {
|
|
4672
4762
|
const elapsed = Math.round((Date.now() - benchStartTime) / 1e3);
|
|
4673
4763
|
const remaining = total && elapsed > 0 ? Math.round((total - completed) / (completed / elapsed)) : "?";
|
|
4674
|
-
|
|
4764
|
+
printBenchStatusLine(
|
|
4765
|
+
parsed.json,
|
|
4675
4766
|
` [${benchmarkId}] ${completed}/${total ?? "?"} tasks (${elapsed}s elapsed, ~${remaining}s remaining)`
|
|
4676
4767
|
);
|
|
4677
4768
|
}
|
|
@@ -6648,6 +6739,7 @@ function offlineEndpoint(remoteUrl, pathname, params = {}) {
|
|
|
6648
6739
|
return url.toString();
|
|
6649
6740
|
}
|
|
6650
6741
|
var OFFLINE_SYNC_REQUEST_TIMEOUT_DEFAULT_MS = 15 * 6e4;
|
|
6742
|
+
var OFFLINE_SYNC_SNAPSHOT_BASE_POST_PREFERRED_MAX_BODY_BYTES = 16 * 1024 * 1024;
|
|
6651
6743
|
function parseOfflineSyncRequestTimeoutMs(raw, fallback = OFFLINE_SYNC_REQUEST_TIMEOUT_DEFAULT_MS) {
|
|
6652
6744
|
if (raw === void 0 || raw.trim().length === 0) return fallback;
|
|
6653
6745
|
const parsed = Number(raw);
|
|
@@ -6746,29 +6838,130 @@ async function fetchOfflineJson(url, token, init = {}) {
|
|
|
6746
6838
|
}
|
|
6747
6839
|
);
|
|
6748
6840
|
}
|
|
6841
|
+
async function parseOfflineSnapshotStreamResponse(response) {
|
|
6842
|
+
if (!response.body) {
|
|
6843
|
+
throw new Error("offline sync snapshot stream response omitted body");
|
|
6844
|
+
}
|
|
6845
|
+
const reader = response.body.getReader();
|
|
6846
|
+
const decoder = new TextDecoder();
|
|
6847
|
+
let buffered = "";
|
|
6848
|
+
let header = null;
|
|
6849
|
+
const files = [];
|
|
6850
|
+
const handleLine = (line) => {
|
|
6851
|
+
if (line.trim().length === 0) return;
|
|
6852
|
+
const parsed = JSON.parse(line);
|
|
6853
|
+
if (parsed.type === "snapshot") {
|
|
6854
|
+
if (header) throw new Error("offline sync snapshot stream repeated header");
|
|
6855
|
+
header = {
|
|
6856
|
+
...typeof parsed.namespace === "string" && parsed.namespace.length > 0 ? { namespace: parsed.namespace } : {},
|
|
6857
|
+
format: parsed.format,
|
|
6858
|
+
schemaVersion: parsed.schemaVersion,
|
|
6859
|
+
createdAt: parsed.createdAt,
|
|
6860
|
+
sourceId: parsed.sourceId,
|
|
6861
|
+
includeTranscripts: parsed.includeTranscripts
|
|
6862
|
+
};
|
|
6863
|
+
return;
|
|
6864
|
+
}
|
|
6865
|
+
if (parsed.type === "file") {
|
|
6866
|
+
if (!header) throw new Error("offline sync snapshot stream file arrived before header");
|
|
6867
|
+
files.push(parsed.file);
|
|
6868
|
+
return;
|
|
6869
|
+
}
|
|
6870
|
+
throw new Error("offline sync snapshot stream contained unknown event");
|
|
6871
|
+
};
|
|
6872
|
+
for (; ; ) {
|
|
6873
|
+
const { value, done } = await reader.read();
|
|
6874
|
+
if (done) break;
|
|
6875
|
+
buffered += decoder.decode(value, { stream: true });
|
|
6876
|
+
for (; ; ) {
|
|
6877
|
+
const newline = buffered.indexOf("\n");
|
|
6878
|
+
if (newline < 0) break;
|
|
6879
|
+
const line = buffered.slice(0, newline);
|
|
6880
|
+
buffered = buffered.slice(newline + 1);
|
|
6881
|
+
handleLine(line);
|
|
6882
|
+
}
|
|
6883
|
+
}
|
|
6884
|
+
buffered += decoder.decode();
|
|
6885
|
+
handleLine(buffered);
|
|
6886
|
+
const finalHeader = header;
|
|
6887
|
+
if (!finalHeader) throw new Error("offline sync snapshot stream omitted header");
|
|
6888
|
+
const snapshot = normalizeOfflineSyncSnapshot({
|
|
6889
|
+
format: finalHeader.format,
|
|
6890
|
+
schemaVersion: finalHeader.schemaVersion,
|
|
6891
|
+
createdAt: finalHeader.createdAt,
|
|
6892
|
+
sourceId: finalHeader.sourceId,
|
|
6893
|
+
includeTranscripts: finalHeader.includeTranscripts,
|
|
6894
|
+
files
|
|
6895
|
+
});
|
|
6896
|
+
return {
|
|
6897
|
+
...finalHeader.namespace ? { namespace: finalHeader.namespace } : {},
|
|
6898
|
+
...snapshot
|
|
6899
|
+
};
|
|
6900
|
+
}
|
|
6901
|
+
async function fetchOfflineSnapshotStream(args) {
|
|
6902
|
+
const url = offlineEndpoint(args.remoteUrl, "/remnic/v1/offline-sync/snapshot-stream", {
|
|
6903
|
+
namespace: args.namespace,
|
|
6904
|
+
include_transcripts: args.includeTranscripts ? "true" : "false",
|
|
6905
|
+
content: "false"
|
|
6906
|
+
});
|
|
6907
|
+
return fetchOfflineWithResponse(
|
|
6908
|
+
url,
|
|
6909
|
+
args.token,
|
|
6910
|
+
{},
|
|
6911
|
+
{},
|
|
6912
|
+
async (response) => {
|
|
6913
|
+
if (!response.ok) {
|
|
6914
|
+
await throwOfflineResponseError(response, url, {}, "offline sync snapshot-stream request");
|
|
6915
|
+
}
|
|
6916
|
+
return parseOfflineSnapshotStreamResponse(response);
|
|
6917
|
+
}
|
|
6918
|
+
);
|
|
6919
|
+
}
|
|
6749
6920
|
async function fetchOfflineSnapshot(args) {
|
|
6921
|
+
let tryStreamSnapshot = false;
|
|
6750
6922
|
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
|
-
|
|
6923
|
+
if (args.baseFiles.length > OFFLINE_SYNC_SNAPSHOT_BASE_POST_MAX_FILES) {
|
|
6924
|
+
tryStreamSnapshot = true;
|
|
6925
|
+
} else {
|
|
6926
|
+
const postBody = offlineSnapshotBasePostBody({
|
|
6927
|
+
namespace: args.namespace,
|
|
6928
|
+
includeTranscripts: args.includeTranscripts,
|
|
6929
|
+
baseFiles: args.baseFiles,
|
|
6930
|
+
baseCapturedAt: args.baseCapturedAt
|
|
6931
|
+
});
|
|
6932
|
+
const postRequest = offlineSnapshotBasePostRequest(postBody);
|
|
6933
|
+
if (postRequest) {
|
|
6934
|
+
const postRequestUsesGzip = new Headers(postRequest.headers).get("content-encoding")?.toLowerCase() === "gzip";
|
|
6935
|
+
try {
|
|
6936
|
+
return await fetchOfflineJson(
|
|
6937
|
+
offlineEndpoint(args.remoteUrl, "/remnic/v1/offline-sync/snapshot"),
|
|
6938
|
+
args.token,
|
|
6939
|
+
{
|
|
6940
|
+
method: "POST",
|
|
6941
|
+
...postRequest
|
|
6942
|
+
}
|
|
6943
|
+
);
|
|
6944
|
+
} catch (error) {
|
|
6945
|
+
if (!isOfflineSnapshotPostFallbackError(error, { compressed: postRequestUsesGzip })) throw error;
|
|
6946
|
+
tryStreamSnapshot = true;
|
|
6947
|
+
}
|
|
6948
|
+
} else {
|
|
6949
|
+
tryStreamSnapshot = true;
|
|
6769
6950
|
}
|
|
6770
6951
|
}
|
|
6771
6952
|
}
|
|
6953
|
+
if (tryStreamSnapshot) {
|
|
6954
|
+
try {
|
|
6955
|
+
return await fetchOfflineSnapshotStream({
|
|
6956
|
+
remoteUrl: args.remoteUrl,
|
|
6957
|
+
token: args.token,
|
|
6958
|
+
namespace: args.namespace,
|
|
6959
|
+
includeTranscripts: args.includeTranscripts
|
|
6960
|
+
});
|
|
6961
|
+
} catch (error) {
|
|
6962
|
+
if (!isOfflineSnapshotStreamFallbackError(error)) throw error;
|
|
6963
|
+
}
|
|
6964
|
+
}
|
|
6772
6965
|
return fetchOfflineJson(
|
|
6773
6966
|
offlineEndpoint(args.remoteUrl, "/remnic/v1/offline-sync/snapshot", {
|
|
6774
6967
|
namespace: args.namespace,
|
|
@@ -6788,11 +6981,36 @@ function offlineSnapshotBasePostBody(args) {
|
|
|
6788
6981
|
});
|
|
6789
6982
|
}
|
|
6790
6983
|
function offlineSnapshotBasePostBodyFits(body) {
|
|
6791
|
-
|
|
6984
|
+
const bytes = Buffer.byteLength(body, "utf-8");
|
|
6985
|
+
return bytes <= OFFLINE_SYNC_SNAPSHOT_BASE_MAX_BODY_BYTES && bytes <= OFFLINE_SYNC_SNAPSHOT_BASE_POST_PREFERRED_MAX_BODY_BYTES;
|
|
6986
|
+
}
|
|
6987
|
+
var OFFLINE_SYNC_SNAPSHOT_BASE_POST_MAX_FILES = 5e4;
|
|
6988
|
+
function offlineSnapshotBasePostRequest(body) {
|
|
6989
|
+
const bytes = Buffer.byteLength(body, "utf-8");
|
|
6990
|
+
if (bytes > OFFLINE_SYNC_SNAPSHOT_BASE_MAX_BODY_BYTES) return null;
|
|
6991
|
+
if (bytes <= OFFLINE_SYNC_SNAPSHOT_BASE_POST_PREFERRED_MAX_BODY_BYTES) {
|
|
6992
|
+
return { body };
|
|
6993
|
+
}
|
|
6994
|
+
const compressed = gzipSync(body);
|
|
6995
|
+
if (compressed.byteLength > OFFLINE_SYNC_SNAPSHOT_BASE_POST_PREFERRED_MAX_BODY_BYTES) {
|
|
6996
|
+
return null;
|
|
6997
|
+
}
|
|
6998
|
+
return {
|
|
6999
|
+
body: compressed,
|
|
7000
|
+
headers: {
|
|
7001
|
+
"content-encoding": "gzip"
|
|
7002
|
+
}
|
|
7003
|
+
};
|
|
7004
|
+
}
|
|
7005
|
+
function isOfflineSnapshotPostFallbackError(error, options = {}) {
|
|
7006
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
7007
|
+
if (/offline-sync\/snapshot\b.* returned (404|405|413)\b/.test(message)) return true;
|
|
7008
|
+
if (!options.compressed) return false;
|
|
7009
|
+
return /offline-sync\/snapshot\b.* returned (400|415)\b/.test(message) && /\b(unsupported_content_encoding|invalid_gzip_body|invalid_json)\b/.test(message);
|
|
6792
7010
|
}
|
|
6793
|
-
function
|
|
7011
|
+
function isOfflineSnapshotStreamFallbackError(error) {
|
|
6794
7012
|
const message = error instanceof Error ? error.message : String(error);
|
|
6795
|
-
return /offline-sync\/snapshot\b.* returned (404|405
|
|
7013
|
+
return /offline-sync\/snapshot-stream\b.* returned (404|405)\b/.test(message);
|
|
6796
7014
|
}
|
|
6797
7015
|
async function fetchOfflineFiles(args) {
|
|
6798
7016
|
return fetchOfflineJson(
|
|
@@ -8681,109 +8899,113 @@ async function cmdConnectors(action, rest, json) {
|
|
|
8681
8899
|
const remnicCfg = raw.remnic ?? raw.engram ?? raw;
|
|
8682
8900
|
const config = parseConfig(remnicCfg);
|
|
8683
8901
|
const orchestrator = new Orchestrator(config);
|
|
8684
|
-
|
|
8685
|
-
|
|
8686
|
-
|
|
8687
|
-
|
|
8688
|
-
const
|
|
8689
|
-
|
|
8690
|
-
|
|
8691
|
-
|
|
8902
|
+
try {
|
|
8903
|
+
await orchestrator.initialize();
|
|
8904
|
+
await orchestrator.deferredReady;
|
|
8905
|
+
const cfg = config.connectors;
|
|
8906
|
+
const sharedIngestFn = async (docs) => {
|
|
8907
|
+
const fetchedAt = (/* @__PURE__ */ new Date()).toISOString();
|
|
8908
|
+
const turns = docs.map((doc) => ({
|
|
8909
|
+
role: "assistant",
|
|
8910
|
+
content: doc.title ? `# ${doc.title}
|
|
8692
8911
|
|
|
8693
8912
|
${doc.content}` : doc.content,
|
|
8694
|
-
|
|
8695
|
-
|
|
8696
|
-
|
|
8697
|
-
|
|
8698
|
-
|
|
8699
|
-
|
|
8700
|
-
|
|
8701
|
-
|
|
8702
|
-
|
|
8703
|
-
|
|
8704
|
-
|
|
8705
|
-
|
|
8706
|
-
|
|
8707
|
-
|
|
8708
|
-
|
|
8709
|
-
|
|
8710
|
-
|
|
8711
|
-
|
|
8712
|
-
|
|
8913
|
+
timestamp: fetchedAt
|
|
8914
|
+
}));
|
|
8915
|
+
await orchestrator.ingestBulkImportBatch(turns);
|
|
8916
|
+
};
|
|
8917
|
+
const makeWriteCursorFn = (id) => async (state) => {
|
|
8918
|
+
await writeLiveConnectorState(config.memoryDir, id, {
|
|
8919
|
+
id,
|
|
8920
|
+
cursor: state.cursor,
|
|
8921
|
+
lastSyncAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
8922
|
+
lastSyncStatus: state.lastSyncStatus,
|
|
8923
|
+
...state.lastSyncError !== void 0 ? { lastSyncError: state.lastSyncError } : {},
|
|
8924
|
+
totalDocsImported: state.totalDocsImported
|
|
8925
|
+
});
|
|
8926
|
+
};
|
|
8927
|
+
let runResult;
|
|
8928
|
+
if (connectorName === GDRIVE_ID) {
|
|
8929
|
+
if (!cfg?.googleDrive?.enabled) {
|
|
8930
|
+
process.stderr.write(
|
|
8931
|
+
`connectors run: connector "${connectorName}" is disabled. Set connectors.googleDrive.enabled=true in config.
|
|
8713
8932
|
`
|
|
8714
|
-
|
|
8715
|
-
|
|
8716
|
-
|
|
8717
|
-
|
|
8718
|
-
|
|
8719
|
-
|
|
8720
|
-
|
|
8721
|
-
|
|
8722
|
-
|
|
8723
|
-
|
|
8933
|
+
);
|
|
8934
|
+
process.exitCode = 1;
|
|
8935
|
+
return;
|
|
8936
|
+
}
|
|
8937
|
+
let validatedCfg;
|
|
8938
|
+
try {
|
|
8939
|
+
validatedCfg = validateGDriveCfg(cfg.googleDrive);
|
|
8940
|
+
} catch (err) {
|
|
8941
|
+
process.stderr.write(
|
|
8942
|
+
`connectors run: invalid config for "${connectorName}": ${err instanceof Error ? err.message : String(err)}
|
|
8724
8943
|
`
|
|
8725
|
-
|
|
8726
|
-
|
|
8727
|
-
|
|
8728
|
-
|
|
8729
|
-
|
|
8730
|
-
|
|
8731
|
-
|
|
8732
|
-
|
|
8733
|
-
|
|
8734
|
-
|
|
8735
|
-
|
|
8736
|
-
|
|
8737
|
-
|
|
8738
|
-
|
|
8739
|
-
|
|
8740
|
-
|
|
8741
|
-
|
|
8742
|
-
|
|
8944
|
+
);
|
|
8945
|
+
process.exitCode = 1;
|
|
8946
|
+
return;
|
|
8947
|
+
}
|
|
8948
|
+
const connector = makeGDriveConnector();
|
|
8949
|
+
const state = await readLiveConnectorState(config.memoryDir, connectorName);
|
|
8950
|
+
runResult = await pollOnce({
|
|
8951
|
+
connectorId: connectorName,
|
|
8952
|
+
priorState: state,
|
|
8953
|
+
syncFn: (cursor) => connector.syncIncremental({
|
|
8954
|
+
cursor,
|
|
8955
|
+
config: validatedCfg
|
|
8956
|
+
}),
|
|
8957
|
+
ingestFn: sharedIngestFn,
|
|
8958
|
+
writeCursorFn: makeWriteCursorFn(connectorName)
|
|
8959
|
+
});
|
|
8960
|
+
} else if (connectorName === NOTION_ID) {
|
|
8961
|
+
if (!cfg?.notion?.enabled) {
|
|
8962
|
+
process.stderr.write(
|
|
8963
|
+
`connectors run: connector "${connectorName}" is disabled. Set connectors.notion.enabled=true in config.
|
|
8964
|
+
`
|
|
8965
|
+
);
|
|
8966
|
+
process.exitCode = 1;
|
|
8967
|
+
return;
|
|
8968
|
+
}
|
|
8969
|
+
let validatedCfg;
|
|
8970
|
+
try {
|
|
8971
|
+
validatedCfg = validateNotionCfg(cfg.notion);
|
|
8972
|
+
} catch (err) {
|
|
8973
|
+
process.stderr.write(
|
|
8974
|
+
`connectors run: invalid config for "${connectorName}": ${err instanceof Error ? err.message : String(err)}
|
|
8975
|
+
`
|
|
8976
|
+
);
|
|
8977
|
+
process.exitCode = 1;
|
|
8978
|
+
return;
|
|
8979
|
+
}
|
|
8980
|
+
const connector = makeNotionConnector();
|
|
8981
|
+
const state = await readLiveConnectorState(config.memoryDir, connectorName);
|
|
8982
|
+
runResult = await pollOnce({
|
|
8983
|
+
connectorId: connectorName,
|
|
8984
|
+
priorState: state,
|
|
8985
|
+
syncFn: (cursor) => connector.syncIncremental({
|
|
8986
|
+
cursor,
|
|
8987
|
+
config: validatedCfg
|
|
8988
|
+
}),
|
|
8989
|
+
ingestFn: sharedIngestFn,
|
|
8990
|
+
writeCursorFn: makeWriteCursorFn(connectorName)
|
|
8991
|
+
});
|
|
8992
|
+
} else {
|
|
8743
8993
|
process.stderr.write(
|
|
8744
|
-
`connectors run: connector "${connectorName}"
|
|
8994
|
+
`connectors run: unknown connector "${connectorName}". Known connectors: ${GDRIVE_ID}, ${NOTION_ID}.
|
|
8745
8995
|
`
|
|
8746
8996
|
);
|
|
8747
8997
|
process.exitCode = 1;
|
|
8748
8998
|
return;
|
|
8749
8999
|
}
|
|
8750
|
-
|
|
8751
|
-
|
|
8752
|
-
|
|
8753
|
-
} catch (err) {
|
|
8754
|
-
process.stderr.write(
|
|
8755
|
-
`connectors run: invalid config for "${connectorName}": ${err instanceof Error ? err.message : String(err)}
|
|
8756
|
-
`
|
|
8757
|
-
);
|
|
9000
|
+
const output = renderRunResult(connectorName, runResult, format);
|
|
9001
|
+
if (runResult.error !== void 0 || runResult.stateWriteError !== void 0) {
|
|
9002
|
+
process.stderr.write(output + "\n");
|
|
8758
9003
|
process.exitCode = 1;
|
|
8759
|
-
|
|
9004
|
+
} else {
|
|
9005
|
+
console.log(output);
|
|
8760
9006
|
}
|
|
8761
|
-
|
|
8762
|
-
|
|
8763
|
-
runResult = await pollOnce({
|
|
8764
|
-
connectorId: connectorName,
|
|
8765
|
-
priorState: state,
|
|
8766
|
-
syncFn: (cursor) => connector.syncIncremental({
|
|
8767
|
-
cursor,
|
|
8768
|
-
config: validatedCfg
|
|
8769
|
-
}),
|
|
8770
|
-
ingestFn: sharedIngestFn,
|
|
8771
|
-
writeCursorFn: makeWriteCursorFn(connectorName)
|
|
8772
|
-
});
|
|
8773
|
-
} else {
|
|
8774
|
-
process.stderr.write(
|
|
8775
|
-
`connectors run: unknown connector "${connectorName}". Known connectors: ${GDRIVE_ID}, ${NOTION_ID}.
|
|
8776
|
-
`
|
|
8777
|
-
);
|
|
8778
|
-
process.exitCode = 1;
|
|
8779
|
-
return;
|
|
8780
|
-
}
|
|
8781
|
-
const output = renderRunResult(connectorName, runResult, format);
|
|
8782
|
-
if (runResult.error !== void 0 || runResult.stateWriteError !== void 0) {
|
|
8783
|
-
process.stderr.write(output + "\n");
|
|
8784
|
-
process.exitCode = 1;
|
|
8785
|
-
} else {
|
|
8786
|
-
console.log(output);
|
|
9007
|
+
} finally {
|
|
9008
|
+
await orchestrator.destroy();
|
|
8787
9009
|
}
|
|
8788
9010
|
} else {
|
|
8789
9011
|
console.log("Usage: remnic connectors <list|install|remove|doctor|marketplace|status|run> [id]");
|
|
@@ -9091,7 +9313,7 @@ async function cmdLegacyBenchmark(action, rest, json) {
|
|
|
9091
9313
|
} else if (action === "report") {
|
|
9092
9314
|
const reportPath = benchConfig.reportPath;
|
|
9093
9315
|
const suite = await runBenchSuite(service, { ...benchConfig, reportPath });
|
|
9094
|
-
|
|
9316
|
+
printBenchStatusLine(json, `Report saved to ${reportPath ?? "benchmarks/report.json"}`);
|
|
9095
9317
|
if (json) {
|
|
9096
9318
|
console.log(JSON.stringify(suite.report, null, 2));
|
|
9097
9319
|
}
|
|
@@ -9218,9 +9440,9 @@ async function cmdBench(rest) {
|
|
|
9218
9440
|
}
|
|
9219
9441
|
const completeCount = prevStatus.benchmarks.filter((b) => b.status === "complete").length;
|
|
9220
9442
|
const failedCount = prevStatus.benchmarks.filter((b) => b.status === "failed").length;
|
|
9221
|
-
|
|
9222
|
-
|
|
9223
|
-
|
|
9443
|
+
printBenchStatusLine(parsed.json, `Resuming from: ${path11.basename(latestStatusPath)}`);
|
|
9444
|
+
printBenchStatusLine(parsed.json, ` Previous run: ${prevStatus.startedAt}`);
|
|
9445
|
+
printBenchStatusLine(parsed.json, ` Benchmarks: ${prevStatus.benchmarks.length} total, ${completeCount} complete, ${failedCount} failed`);
|
|
9224
9446
|
const before = selectedBenchmarks.length;
|
|
9225
9447
|
if (parsed.resume) {
|
|
9226
9448
|
selectedWorkItems = filterBenchWorkItemsForPreviousStatus(
|
|
@@ -9229,7 +9451,7 @@ async function cmdBench(rest) {
|
|
|
9229
9451
|
"resume"
|
|
9230
9452
|
);
|
|
9231
9453
|
selectedBenchmarks = [...new Set(selectedWorkItems.map((item) => item.benchmarkId))];
|
|
9232
|
-
|
|
9454
|
+
printBenchStatusLine(parsed.json, ` Resuming: ${selectedBenchmarks.length} of ${before} benchmarks to re-run`);
|
|
9233
9455
|
} else {
|
|
9234
9456
|
selectedWorkItems = filterBenchWorkItemsForPreviousStatus(
|
|
9235
9457
|
selectedWorkItems,
|
|
@@ -9237,13 +9459,14 @@ async function cmdBench(rest) {
|
|
|
9237
9459
|
"retry-failed"
|
|
9238
9460
|
);
|
|
9239
9461
|
selectedBenchmarks = [...new Set(selectedWorkItems.map((item) => item.benchmarkId))];
|
|
9240
|
-
|
|
9462
|
+
printBenchStatusLine(parsed.json, ` Retrying: ${selectedBenchmarks.length} of ${before} selected benchmarks had failures`);
|
|
9241
9463
|
}
|
|
9242
9464
|
if (selectedWorkItems.length === 0) {
|
|
9243
9465
|
if (parsed.retryFailed) {
|
|
9244
|
-
|
|
9466
|
+
printBenchStatusLine(parsed.json, "Nothing to re-run \u2014 no selected benchmarks had failures.");
|
|
9245
9467
|
} else {
|
|
9246
|
-
|
|
9468
|
+
printBenchStatusLine(
|
|
9469
|
+
parsed.json,
|
|
9247
9470
|
"Nothing to re-run \u2014 all selected benchmarks completed successfully in the previous run."
|
|
9248
9471
|
);
|
|
9249
9472
|
}
|
|
@@ -9289,6 +9512,7 @@ async function cmdBench(rest) {
|
|
|
9289
9512
|
}
|
|
9290
9513
|
} else {
|
|
9291
9514
|
const fallbackResultPath = await runBenchViaFallback(parsed, benchmarkId, runtimeProfile);
|
|
9515
|
+
writtenPaths.push(fallbackResultPath);
|
|
9292
9516
|
try {
|
|
9293
9517
|
await updateBenchmarkCompleted(benchStatusPath, statusId, fallbackResultPath);
|
|
9294
9518
|
} catch {
|
|
@@ -9404,13 +9628,10 @@ var [LAUNCHD_PLIST_PATH] = LAUNCHD_PLIST_PATHS;
|
|
|
9404
9628
|
var SYSTEMD_UNIT_PATHS = systemdUnitPaths(resolveHomeDir());
|
|
9405
9629
|
var [SYSTEMD_UNIT_PATH] = SYSTEMD_UNIT_PATHS;
|
|
9406
9630
|
function readPid() {
|
|
9407
|
-
|
|
9408
|
-
|
|
9409
|
-
|
|
9410
|
-
|
|
9411
|
-
}
|
|
9412
|
-
}
|
|
9413
|
-
return void 0;
|
|
9631
|
+
return readVerifiedDaemonPid({
|
|
9632
|
+
pidFiles: [PID_FILE, LEGACY_PID_FILE],
|
|
9633
|
+
expectedServerBin: resolveServerBin()
|
|
9634
|
+
});
|
|
9414
9635
|
}
|
|
9415
9636
|
function inferPort() {
|
|
9416
9637
|
try {
|
|
@@ -9442,6 +9663,36 @@ function isStandaloneServiceInstalled() {
|
|
|
9442
9663
|
if (isLinux()) return anyFileExists(SYSTEMD_UNIT_PATHS);
|
|
9443
9664
|
return false;
|
|
9444
9665
|
}
|
|
9666
|
+
function commandFailureDetail(error) {
|
|
9667
|
+
if (error && typeof error === "object") {
|
|
9668
|
+
const maybe = error;
|
|
9669
|
+
const stderr = maybe.stderr ? String(maybe.stderr).trim() : "";
|
|
9670
|
+
if (stderr) return stderr;
|
|
9671
|
+
const stdout = maybe.stdout ? String(maybe.stdout).trim() : "";
|
|
9672
|
+
if (stdout) return stdout;
|
|
9673
|
+
if (maybe.message) return maybe.message;
|
|
9674
|
+
}
|
|
9675
|
+
return String(error);
|
|
9676
|
+
}
|
|
9677
|
+
function failDaemonInstall(command, error) {
|
|
9678
|
+
console.error(`Error: daemon install failed while running ${command}.`);
|
|
9679
|
+
console.error(` ${commandFailureDetail(error)}`);
|
|
9680
|
+
process.exit(1);
|
|
9681
|
+
}
|
|
9682
|
+
function isLaunchdLabelLoaded(label) {
|
|
9683
|
+
return firstSuccessfulResult([label], (candidate) => {
|
|
9684
|
+
childProcess2.execSync(`launchctl list ${candidate} 2>/dev/null`, { stdio: "pipe" });
|
|
9685
|
+
return true;
|
|
9686
|
+
}) === true;
|
|
9687
|
+
}
|
|
9688
|
+
function isSystemdServiceActive() {
|
|
9689
|
+
return firstSuccessfulResult(SYSTEMD_SERVICE_CANDIDATES, (serviceName) => {
|
|
9690
|
+
const out = childProcess2.execSync(`systemctl --user is-active ${serviceName} 2>/dev/null`, {
|
|
9691
|
+
encoding: "utf8"
|
|
9692
|
+
}).trim();
|
|
9693
|
+
return out === "active" ? true : void 0;
|
|
9694
|
+
}) === true;
|
|
9695
|
+
}
|
|
9445
9696
|
function selectLaunchdInspection(openclawPluginModeConfigured) {
|
|
9446
9697
|
const canonical = inspectLaunchdPlist(LAUNCHD_PLIST_PATH);
|
|
9447
9698
|
if (canonical.installed) return canonical;
|
|
@@ -9489,7 +9740,13 @@ function daemonInstall() {
|
|
|
9489
9740
|
fs7.writeFileSync(LAUNCHD_PLIST_PATH, plist);
|
|
9490
9741
|
try {
|
|
9491
9742
|
launchdLoadPlist(LAUNCHD_PLIST_PATH);
|
|
9492
|
-
} catch {
|
|
9743
|
+
} catch (err) {
|
|
9744
|
+
if (!isLaunchdLabelLoaded(LAUNCHD_LABEL)) {
|
|
9745
|
+
failDaemonInstall(`launchctl load -w ${LAUNCHD_PLIST_PATH}`, err);
|
|
9746
|
+
}
|
|
9747
|
+
}
|
|
9748
|
+
if (!isLaunchdLabelLoaded(LAUNCHD_LABEL)) {
|
|
9749
|
+
failDaemonInstall(`launchctl list ${LAUNCHD_LABEL}`, new Error("service was not loaded after install"));
|
|
9493
9750
|
}
|
|
9494
9751
|
console.log(`Installed launchd service: ${LAUNCHD_PLIST_PATH}`);
|
|
9495
9752
|
console.log(` Label: ${LAUNCHD_LABEL}`);
|
|
@@ -9503,9 +9760,21 @@ function daemonInstall() {
|
|
|
9503
9760
|
fs7.writeFileSync(SYSTEMD_UNIT_PATH, unit);
|
|
9504
9761
|
try {
|
|
9505
9762
|
childProcess2.execSync("systemctl --user daemon-reload", { stdio: "pipe" });
|
|
9763
|
+
} catch (err) {
|
|
9764
|
+
failDaemonInstall("systemctl --user daemon-reload", err);
|
|
9765
|
+
}
|
|
9766
|
+
try {
|
|
9506
9767
|
childProcess2.execSync(`systemctl --user enable ${SYSTEMD_SERVICE}`, { stdio: "pipe" });
|
|
9768
|
+
} catch (err) {
|
|
9769
|
+
failDaemonInstall(`systemctl --user enable ${SYSTEMD_SERVICE}`, err);
|
|
9770
|
+
}
|
|
9771
|
+
try {
|
|
9507
9772
|
childProcess2.execSync(`systemctl --user start ${SYSTEMD_SERVICE}`, { stdio: "pipe" });
|
|
9508
|
-
} catch {
|
|
9773
|
+
} catch (err) {
|
|
9774
|
+
failDaemonInstall(`systemctl --user start ${SYSTEMD_SERVICE}`, err);
|
|
9775
|
+
}
|
|
9776
|
+
if (!isSystemdServiceActive()) {
|
|
9777
|
+
failDaemonInstall(`systemctl --user is-active ${SYSTEMD_SERVICE}`, new Error("service is not active after install"));
|
|
9509
9778
|
}
|
|
9510
9779
|
console.log(`Installed systemd user service: ${SYSTEMD_UNIT_PATH}`);
|
|
9511
9780
|
console.log(` Restart: on-failure, WantedBy: default.target`);
|
|
@@ -11273,6 +11542,8 @@ export {
|
|
|
11273
11542
|
OFFLINE_SYNC_DIRECT_PUSH_MIN_BYTES,
|
|
11274
11543
|
OFFLINE_SYNC_FILE_CONTENT_UPLOAD_CHUNK_BYTES,
|
|
11275
11544
|
OFFLINE_SYNC_REQUEST_TIMEOUT_DEFAULT_MS,
|
|
11545
|
+
OFFLINE_SYNC_SNAPSHOT_BASE_POST_MAX_FILES,
|
|
11546
|
+
OFFLINE_SYNC_SNAPSHOT_BASE_POST_PREFERRED_MAX_BODY_BYTES,
|
|
11276
11547
|
TAXONOMY_RESOLVE_BOOLEAN_FLAGS,
|
|
11277
11548
|
TAXONOMY_RESOLVE_VALUE_FLAGS,
|
|
11278
11549
|
__benchDatasetTestHooks,
|
|
@@ -11284,6 +11555,7 @@ export {
|
|
|
11284
11555
|
chunkOfflineFileContentBatches,
|
|
11285
11556
|
directHydrateLargeOfflineFiles,
|
|
11286
11557
|
extractXrayRawArgs,
|
|
11558
|
+
fetchOfflineSnapshot,
|
|
11287
11559
|
formatOfflineLargeFilePushFailureMessage,
|
|
11288
11560
|
formatOfflineRequestForError,
|
|
11289
11561
|
getBenchUsageText,
|
|
@@ -11293,6 +11565,7 @@ export {
|
|
|
11293
11565
|
offlinePartialHydrationForPaths,
|
|
11294
11566
|
offlineSnapshotBasePostBody,
|
|
11295
11567
|
offlineSnapshotBasePostBodyFits,
|
|
11568
|
+
offlineSnapshotBasePostRequest,
|
|
11296
11569
|
offlineSnapshotContentFilesForApply,
|
|
11297
11570
|
parseBenchArgs,
|
|
11298
11571
|
parseCapsuleForkArgs,
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@remnic/cli",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "9.3.515",
|
|
4
4
|
"description": "CLI for Remnic memory — init, query, doctor, daemon management",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "dist/index.js",
|
|
@@ -26,20 +26,20 @@
|
|
|
26
26
|
},
|
|
27
27
|
"dependencies": {
|
|
28
28
|
"yaml": "^2.4.2",
|
|
29
|
-
"@remnic/
|
|
30
|
-
"@remnic/
|
|
31
|
-
"@remnic/core": "^
|
|
29
|
+
"@remnic/plugin-pi": "^9.3.515",
|
|
30
|
+
"@remnic/server": "^9.3.515",
|
|
31
|
+
"@remnic/core": "^9.3.515"
|
|
32
32
|
},
|
|
33
33
|
"peerDependencies": {
|
|
34
|
-
"@remnic/bench": "^
|
|
35
|
-
"@remnic/export-weclone": "^
|
|
36
|
-
"@remnic/import-weclone": "^
|
|
37
|
-
"@remnic/import-chatgpt": "^
|
|
38
|
-
"@remnic/import-claude": "^
|
|
39
|
-
"@remnic/import-gemini": "^
|
|
40
|
-
"@remnic/import-lossless-claw": "^
|
|
41
|
-
"@remnic/import-mem0": "^
|
|
42
|
-
"@remnic/import-supermemory": "^
|
|
34
|
+
"@remnic/bench": "^9.3.515",
|
|
35
|
+
"@remnic/export-weclone": "^9.3.515",
|
|
36
|
+
"@remnic/import-weclone": "^9.3.515",
|
|
37
|
+
"@remnic/import-chatgpt": "^9.3.515",
|
|
38
|
+
"@remnic/import-claude": "^9.3.515",
|
|
39
|
+
"@remnic/import-gemini": "^9.3.515",
|
|
40
|
+
"@remnic/import-lossless-claw": "^9.3.515",
|
|
41
|
+
"@remnic/import-mem0": "^9.3.515",
|
|
42
|
+
"@remnic/import-supermemory": "^9.3.515"
|
|
43
43
|
},
|
|
44
44
|
"peerDependenciesMeta": {
|
|
45
45
|
"@remnic/bench": {
|
|
@@ -73,15 +73,15 @@
|
|
|
73
73
|
"devDependencies": {
|
|
74
74
|
"tsup": "^8.5.1",
|
|
75
75
|
"typescript": "^5.9.3",
|
|
76
|
-
"@remnic/
|
|
77
|
-
"@remnic/
|
|
78
|
-
"@remnic/import-weclone": "
|
|
79
|
-
"@remnic/import-
|
|
80
|
-
"@remnic/import-
|
|
81
|
-
"@remnic/import-
|
|
82
|
-
"@remnic/import-lossless-claw": "
|
|
83
|
-
"@remnic/import-
|
|
84
|
-
"@remnic/import-supermemory": "
|
|
76
|
+
"@remnic/bench": "9.3.515",
|
|
77
|
+
"@remnic/export-weclone": "9.3.515",
|
|
78
|
+
"@remnic/import-weclone": "9.3.515",
|
|
79
|
+
"@remnic/import-claude": "9.3.515",
|
|
80
|
+
"@remnic/import-gemini": "9.3.515",
|
|
81
|
+
"@remnic/import-mem0": "9.3.515",
|
|
82
|
+
"@remnic/import-lossless-claw": "9.3.515",
|
|
83
|
+
"@remnic/import-chatgpt": "9.3.515",
|
|
84
|
+
"@remnic/import-supermemory": "9.3.515"
|
|
85
85
|
},
|
|
86
86
|
"license": "MIT",
|
|
87
87
|
"repository": {
|