@remnic/cli 10.0.12 → 10.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 +55 -9
- package/package.json +32 -32
package/dist/index.js
CHANGED
|
@@ -2944,9 +2944,20 @@ async function createOfflineStorageForPath(memoryDir, filePath, configured, secu
|
|
|
2944
2944
|
}
|
|
2945
2945
|
return storage;
|
|
2946
2946
|
}
|
|
2947
|
-
async function createOfflineStorageIo(memoryDir, configuredStorage, persistedExclusion) {
|
|
2947
|
+
async function createOfflineStorageIo(memoryDir, configuredStorage, persistedExclusion, captureWriteLockBackoff, signal) {
|
|
2948
2948
|
await cleanupOrphanedOfflineDecryptStaging(memoryDir);
|
|
2949
2949
|
const { storage, secureStoreKey } = configuredStorage ?? await createConfiguredOfflineStorage(memoryDir);
|
|
2950
|
+
if (captureWriteLockBackoff || signal) {
|
|
2951
|
+
storage.factHashIndexLockOptions = {
|
|
2952
|
+
...storage.factHashIndexLockOptions,
|
|
2953
|
+
...captureWriteLockBackoff ? {
|
|
2954
|
+
captureWriteLockInitialDelayMs: captureWriteLockBackoff.initialDelayMs,
|
|
2955
|
+
captureWriteLockMaxDelayMs: captureWriteLockBackoff.maxDelayMs,
|
|
2956
|
+
captureWriteLockDeadlineMs: captureWriteLockBackoff.deadlineMs
|
|
2957
|
+
} : {},
|
|
2958
|
+
...signal ? { captureWriteLockSignal: signal } : {}
|
|
2959
|
+
};
|
|
2960
|
+
}
|
|
2950
2961
|
return {
|
|
2951
2962
|
// With persisted classifications the warm path skips the per-file
|
|
2952
2963
|
// read+parse the plain exclusion performs for every candidate.
|
|
@@ -2965,8 +2976,15 @@ async function createOfflineStorageIo(memoryDir, configuredStorage, persistedExc
|
|
|
2965
2976
|
chunkSize
|
|
2966
2977
|
}),
|
|
2967
2978
|
writeFile: async ({ filePath, content }) => storage.writeOfflineSyncFile(filePath, content),
|
|
2968
|
-
writeStagingFile: async ({ filePath, content, finalAadFilePath }) => storage.writeOfflineSyncStagingFile(
|
|
2969
|
-
|
|
2979
|
+
writeStagingFile: async ({ filePath, content, finalAadFilePath }) => storage.writeOfflineSyncStagingFile(
|
|
2980
|
+
filePath,
|
|
2981
|
+
content,
|
|
2982
|
+
finalAadFilePath === void 0 ? void 0 : { aadFilePath: finalAadFilePath }
|
|
2983
|
+
),
|
|
2984
|
+
readStagingFile: async ({ filePath, finalAadFilePath }) => storage.readOfflineSyncFile(
|
|
2985
|
+
filePath,
|
|
2986
|
+
finalAadFilePath === void 0 ? void 0 : { aadFilePath: finalAadFilePath }
|
|
2987
|
+
),
|
|
2970
2988
|
writeFileChunks: async ({ filePath, chunks }) => storage.writeOfflineSyncFileChunks(filePath, chunks),
|
|
2971
2989
|
deleteFile: async ({ filePath, mtimeMs }) => storage.deleteOfflineSyncFile(filePath, mtimeMs ?? null),
|
|
2972
2990
|
recordDeletionRevision: async ({ filePath, mtimeMs }) => storage.recordReplicatedDeletionRevision(filePath, mtimeMs)
|
|
@@ -4518,6 +4536,32 @@ function resolveCredentialChannel(input, env, hooks) {
|
|
|
4518
4536
|
return { ok: true, token: void 0, tokenFromArgv: false };
|
|
4519
4537
|
}
|
|
4520
4538
|
|
|
4539
|
+
// src/converge-capture-lock.ts
|
|
4540
|
+
import { resolveConvergeCaptureWriteLockBackoff } from "@remnic/core";
|
|
4541
|
+
import { isTombstoneBlockedCaptureWriteLockBusy } from "@remnic/core/capture-write-lock-backoff.js";
|
|
4542
|
+
function createConvergeStorageIoOpener(convergeConfig, signal) {
|
|
4543
|
+
const backoff = resolveConvergeCaptureWriteLockBackoff(convergeConfig);
|
|
4544
|
+
return (rootDir) => createOfflineStorageIo(rootDir, void 0, void 0, backoff, signal);
|
|
4545
|
+
}
|
|
4546
|
+
function handleConvergeTransferResults(results, batch, onFailed) {
|
|
4547
|
+
for (let index = 0; index < results.length; index += 1) {
|
|
4548
|
+
const result = results[index];
|
|
4549
|
+
if (!result || result.status === "fulfilled") continue;
|
|
4550
|
+
if (isTombstoneBlockedCaptureWriteLockBusy(result.reason)) {
|
|
4551
|
+
onFailed();
|
|
4552
|
+
const entry = batch[index];
|
|
4553
|
+
const namespace = entry?.namespace ?? "unknown";
|
|
4554
|
+
const entryPath = entry?.path ?? "";
|
|
4555
|
+
process.stderr.write(
|
|
4556
|
+
`converge: tombstone-blocked capture write lock remained busy for ${namespace} ${entryPath}; continuing the cycle
|
|
4557
|
+
`
|
|
4558
|
+
);
|
|
4559
|
+
continue;
|
|
4560
|
+
}
|
|
4561
|
+
throw result.reason;
|
|
4562
|
+
}
|
|
4563
|
+
}
|
|
4564
|
+
|
|
4521
4565
|
// src/converge.ts
|
|
4522
4566
|
async function discoverCursorNamespaces(memoryDir, peerUrl) {
|
|
4523
4567
|
const cursorDir = path7.join(path7.resolve(memoryDir), ".remnic", "state", "converge-cursors");
|
|
@@ -4853,6 +4897,7 @@ async function executeConvergeApply(options = {}) {
|
|
|
4853
4897
|
}
|
|
4854
4898
|
const fetchFn = options.fetchImpl ?? globalThis.fetch;
|
|
4855
4899
|
const timeoutMs = options.peerRequestTimeoutMs ?? config?.converge.peerRequestTimeoutMs ?? envConvergePeerRequestTimeoutMs2() ?? DEFAULT_PEER_REQUEST_TIMEOUT_MS;
|
|
4900
|
+
const openStorageIo = createConvergeStorageIoOpener(config?.converge, options.signal);
|
|
4856
4901
|
const rootMap = /* @__PURE__ */ new Map();
|
|
4857
4902
|
if (config) {
|
|
4858
4903
|
try {
|
|
@@ -4924,7 +4969,7 @@ async function executeConvergeApply(options = {}) {
|
|
|
4924
4969
|
actualTransfers.failed += 1;
|
|
4925
4970
|
return;
|
|
4926
4971
|
}
|
|
4927
|
-
const io = await
|
|
4972
|
+
const io = await openStorageIo(rootDir);
|
|
4928
4973
|
const expectedLocalSha256 = entry.action === "conflict" ? entry.localSha256 : entry.baseSha256;
|
|
4929
4974
|
let transferComplete = false;
|
|
4930
4975
|
let transferRejected = false;
|
|
@@ -5011,7 +5056,7 @@ async function executeConvergeApply(options = {}) {
|
|
|
5011
5056
|
if (rootDir) {
|
|
5012
5057
|
try {
|
|
5013
5058
|
const filePath = path7.join(rootDir, localPath);
|
|
5014
|
-
const io = await
|
|
5059
|
+
const io = await openStorageIo(rootDir);
|
|
5015
5060
|
const current = await io.readFileDigest({ root: rootDir, path: localPath, filePath });
|
|
5016
5061
|
if (current.sha256 !== entry.localSha256) {
|
|
5017
5062
|
throw new Error(`local file changed during push: ${localPath}`);
|
|
@@ -5108,7 +5153,7 @@ async function executeConvergeApply(options = {}) {
|
|
|
5108
5153
|
const rootDir = rootMap.get(entry.namespace);
|
|
5109
5154
|
if (rootDir && entry.localSha256) {
|
|
5110
5155
|
try {
|
|
5111
|
-
const io = await
|
|
5156
|
+
const io = await openStorageIo(rootDir);
|
|
5112
5157
|
const filePath = path7.join(rootDir, localPath);
|
|
5113
5158
|
const current = await io.readFileDigest({ root: rootDir, path: localPath, filePath });
|
|
5114
5159
|
if (current.sha256 === entry.localSha256) {
|
|
@@ -5163,7 +5208,7 @@ async function executeConvergeApply(options = {}) {
|
|
|
5163
5208
|
const rootDir = rootMap.get(entry.namespace);
|
|
5164
5209
|
if (rootDir) {
|
|
5165
5210
|
try {
|
|
5166
|
-
const io = await
|
|
5211
|
+
const io = await openStorageIo(rootDir);
|
|
5167
5212
|
const filePath = path7.join(rootDir, localPath);
|
|
5168
5213
|
const current = await io.readFileDigest({ root: rootDir, path: localPath, filePath });
|
|
5169
5214
|
if (current.sha256 === entry.localSha256) {
|
|
@@ -5213,8 +5258,9 @@ async function executeConvergeApply(options = {}) {
|
|
|
5213
5258
|
options.signal?.throwIfAborted();
|
|
5214
5259
|
const batch = actionable.slice(i, i + TRANSFER_BATCH_SIZE);
|
|
5215
5260
|
const results = await Promise.allSettled(batch.map((entry) => executeTransferEntry(entry)));
|
|
5216
|
-
|
|
5217
|
-
|
|
5261
|
+
handleConvergeTransferResults(results, batch, () => {
|
|
5262
|
+
actualTransfers.failed += 1;
|
|
5263
|
+
});
|
|
5218
5264
|
}
|
|
5219
5265
|
options.signal?.throwIfAborted();
|
|
5220
5266
|
if (options.peerUrl && peerMutatedNamespaces.size > 0) {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@remnic/cli",
|
|
3
|
-
"version": "10.0.
|
|
3
|
+
"version": "10.0.14",
|
|
4
4
|
"description": "CLI for Remnic memory — init, query, doctor, daemon management",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "dist/index.js",
|
|
@@ -26,26 +26,26 @@
|
|
|
26
26
|
},
|
|
27
27
|
"dependencies": {
|
|
28
28
|
"yaml": "^2.4.2",
|
|
29
|
-
"@remnic/
|
|
30
|
-
"@remnic/
|
|
31
|
-
"@remnic/core": "^10.0.
|
|
29
|
+
"@remnic/plugin-pi": "^10.0.14",
|
|
30
|
+
"@remnic/server": "^10.0.14",
|
|
31
|
+
"@remnic/core": "^10.0.14"
|
|
32
32
|
},
|
|
33
33
|
"peerDependencies": {
|
|
34
|
-
"@remnic/bench": "^10.0.
|
|
35
|
-
"@remnic/plugin-openclaw": "^10.0.
|
|
36
|
-
"@remnic/export-weclone": "^10.0.
|
|
37
|
-
"@remnic/import-weclone": "^10.0.
|
|
38
|
-
"@remnic/import-chatgpt": "^10.0.
|
|
39
|
-
"@remnic/import-claude": "^10.0.
|
|
40
|
-
"@remnic/import-gemini": "^10.0.
|
|
41
|
-
"@remnic/import-lossless-claw": "^10.0.
|
|
42
|
-
"@remnic/import-mem0": "^10.0.
|
|
43
|
-
"@remnic/import-supermemory": "^10.0.
|
|
44
|
-
"@remnic/import-okf": "^10.0.
|
|
45
|
-
"@remnic/connector-limitless": "^10.0.
|
|
46
|
-
"@remnic/connector-bee": "^10.0.
|
|
47
|
-
"@remnic/connector-omi": "^10.0.
|
|
48
|
-
"@remnic/capture-audio": "^10.0.
|
|
34
|
+
"@remnic/bench": "^10.0.14",
|
|
35
|
+
"@remnic/plugin-openclaw": "^10.0.14",
|
|
36
|
+
"@remnic/export-weclone": "^10.0.14",
|
|
37
|
+
"@remnic/import-weclone": "^10.0.14",
|
|
38
|
+
"@remnic/import-chatgpt": "^10.0.14",
|
|
39
|
+
"@remnic/import-claude": "^10.0.14",
|
|
40
|
+
"@remnic/import-gemini": "^10.0.14",
|
|
41
|
+
"@remnic/import-lossless-claw": "^10.0.14",
|
|
42
|
+
"@remnic/import-mem0": "^10.0.14",
|
|
43
|
+
"@remnic/import-supermemory": "^10.0.14",
|
|
44
|
+
"@remnic/import-okf": "^10.0.14",
|
|
45
|
+
"@remnic/connector-limitless": "^10.0.14",
|
|
46
|
+
"@remnic/connector-bee": "^10.0.14",
|
|
47
|
+
"@remnic/connector-omi": "^10.0.14",
|
|
48
|
+
"@remnic/capture-audio": "^10.0.14"
|
|
49
49
|
},
|
|
50
50
|
"peerDependenciesMeta": {
|
|
51
51
|
"@remnic/bench": {
|
|
@@ -97,19 +97,19 @@
|
|
|
97
97
|
"devDependencies": {
|
|
98
98
|
"tsup": "^8.5.1",
|
|
99
99
|
"typescript": "^5.9.3",
|
|
100
|
-
"@remnic/bench": "10.0.
|
|
101
|
-
"@remnic/plugin-openclaw": "10.0.
|
|
102
|
-
"@remnic/
|
|
103
|
-
"@remnic/import-
|
|
104
|
-
"@remnic/import-chatgpt": "10.0.
|
|
105
|
-
"@remnic/import-
|
|
106
|
-
"@remnic/import-
|
|
107
|
-
"@remnic/import-
|
|
108
|
-
"@remnic/import-
|
|
109
|
-
"@remnic/
|
|
110
|
-
"@remnic/connector-omi": "10.0.
|
|
111
|
-
"@remnic/
|
|
112
|
-
"@remnic/connector-
|
|
100
|
+
"@remnic/bench": "10.0.14",
|
|
101
|
+
"@remnic/plugin-openclaw": "10.0.14",
|
|
102
|
+
"@remnic/export-weclone": "10.0.14",
|
|
103
|
+
"@remnic/import-weclone": "10.0.14",
|
|
104
|
+
"@remnic/import-chatgpt": "10.0.14",
|
|
105
|
+
"@remnic/import-claude": "10.0.14",
|
|
106
|
+
"@remnic/import-gemini": "10.0.14",
|
|
107
|
+
"@remnic/import-lossless-claw": "10.0.14",
|
|
108
|
+
"@remnic/import-supermemory": "10.0.14",
|
|
109
|
+
"@remnic/import-mem0": "10.0.14",
|
|
110
|
+
"@remnic/connector-omi": "10.0.14",
|
|
111
|
+
"@remnic/connector-bee": "10.0.14",
|
|
112
|
+
"@remnic/connector-limitless": "10.0.14"
|
|
113
113
|
},
|
|
114
114
|
"license": "MIT",
|
|
115
115
|
"repository": {
|