@remnic/cli 9.69.45 → 9.69.46
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 +146 -72
- package/package.json +32 -32
package/dist/index.js
CHANGED
|
@@ -2084,7 +2084,7 @@ import { buildReconcileManifest } from "@remnic/core/reconcile/manifest.js";
|
|
|
2084
2084
|
import { convergeIdentityCachePath } from "@remnic/core/reconcile/cursor.js";
|
|
2085
2085
|
|
|
2086
2086
|
// src/converge-plan-cache.ts
|
|
2087
|
-
import { createHash } from "crypto";
|
|
2087
|
+
import { createHash, randomUUID } from "crypto";
|
|
2088
2088
|
import { readFileSync } from "fs";
|
|
2089
2089
|
import * as fs16 from "fs/promises";
|
|
2090
2090
|
import * as path2 from "path";
|
|
@@ -2099,6 +2099,15 @@ var CONVERGE_PLAN_CACHE_MAX_ENTRIES = 128;
|
|
|
2099
2099
|
var CONVERGE_PLAN_CACHE_MAX_AGE_MS = 30 * 24 * 60 * 60 * 1e3;
|
|
2100
2100
|
var CONVERGE_PLAN_CACHE_MAX_SCOPE_DIRS = 8;
|
|
2101
2101
|
var SHA256_HEX = /^[0-9a-f]{64}$/i;
|
|
2102
|
+
var MEMORY_STATUSES = [
|
|
2103
|
+
"active",
|
|
2104
|
+
"pending_review",
|
|
2105
|
+
"rejected",
|
|
2106
|
+
"quarantined",
|
|
2107
|
+
"superseded",
|
|
2108
|
+
"archived",
|
|
2109
|
+
"forgotten"
|
|
2110
|
+
];
|
|
2102
2111
|
var ConvergePlanCacheBusyError = class extends Error {
|
|
2103
2112
|
constructor(holderPid) {
|
|
2104
2113
|
super(
|
|
@@ -2155,7 +2164,7 @@ function normalizeEntryFile(raw) {
|
|
|
2155
2164
|
if (typeof candidate.id !== "string" || candidate.id.length === 0) return null;
|
|
2156
2165
|
if (typeof candidate.contentHash !== "string" || !SHA256_HEX.test(candidate.contentHash)) return null;
|
|
2157
2166
|
if (typeof candidate.category !== "string") return null;
|
|
2158
|
-
if (
|
|
2167
|
+
if (!MEMORY_STATUSES.includes(candidate.status)) return null;
|
|
2159
2168
|
const normalizerVersion = typeof candidate.normalizerVersion === "number" ? candidate.normalizerVersion : void 0;
|
|
2160
2169
|
const identityResolutionVersion = typeof candidate.identityResolutionVersion === "number" ? candidate.identityResolutionVersion : void 0;
|
|
2161
2170
|
const contentHashAliases = Array.isArray(candidate.contentHashAliases) && candidate.contentHashAliases.every((alias) => typeof alias === "string") ? candidate.contentHashAliases : void 0;
|
|
@@ -2331,57 +2340,76 @@ async function pruneSiblingScopes(root, activeScope) {
|
|
|
2331
2340
|
});
|
|
2332
2341
|
}
|
|
2333
2342
|
}
|
|
2343
|
+
var heldLockPaths = /* @__PURE__ */ new Set();
|
|
2344
|
+
var failedReleaseNonces = /* @__PURE__ */ new Map();
|
|
2334
2345
|
var ConvergePlanCache = class _ConvergePlanCache {
|
|
2335
2346
|
scope;
|
|
2336
2347
|
scopeDir;
|
|
2337
2348
|
lockPath;
|
|
2349
|
+
nonce = randomUUID();
|
|
2338
2350
|
closed = false;
|
|
2339
2351
|
constructor(root, scope) {
|
|
2340
2352
|
this.scope = scope;
|
|
2341
2353
|
this.scopeDir = path2.join(root, scope);
|
|
2342
2354
|
this.lockPath = path2.join(root, "lock.json");
|
|
2343
2355
|
}
|
|
2356
|
+
lockPayload() {
|
|
2357
|
+
return `${JSON.stringify({
|
|
2358
|
+
pid: process.pid,
|
|
2359
|
+
startTicks: PROCESS_START_TICKS,
|
|
2360
|
+
savedAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
2361
|
+
nonce: this.nonce
|
|
2362
|
+
})}
|
|
2363
|
+
`;
|
|
2364
|
+
}
|
|
2344
2365
|
/**
|
|
2345
2366
|
* Open (and lock) the cache for one planning run. The lock is
|
|
2346
2367
|
* cross-process: a second live planner fails fast with
|
|
2347
2368
|
* {@link ConvergePlanCacheBusyError} instead of racing checkpoint writes.
|
|
2348
|
-
* A lock left by a dead process
|
|
2349
|
-
*
|
|
2350
|
-
*
|
|
2351
|
-
* written via rename, so
|
|
2369
|
+
* A lock left by a dead process — or by this process's own failed
|
|
2370
|
+
* release — is stolen; a lock file is only ever replaced atomically, so
|
|
2371
|
+
* a steal racing the true owner at worst causes redundant recompute —
|
|
2372
|
+
* entries themselves are content-addressed and written via rename, so
|
|
2373
|
+
* concurrent identical writes cannot interleave.
|
|
2352
2374
|
*/
|
|
2353
2375
|
static async open(memoryDir, scope) {
|
|
2354
2376
|
const root = convergePlanCacheRoot(memoryDir);
|
|
2355
2377
|
const scopeDir = path2.join(root, scope);
|
|
2356
2378
|
await ensureSafePlanCacheTree(memoryDir, scopeDir);
|
|
2357
2379
|
const lockPath = path2.join(root, "lock.json");
|
|
2358
|
-
|
|
2359
|
-
|
|
2360
|
-
|
|
2361
|
-
savedAt: (/* @__PURE__ */ new Date()).toISOString()
|
|
2362
|
-
})}
|
|
2363
|
-
`;
|
|
2380
|
+
if (heldLockPaths.has(lockPath)) throw new ConvergePlanCacheBusyError(process.pid);
|
|
2381
|
+
heldLockPaths.add(lockPath);
|
|
2382
|
+
const cache = new _ConvergePlanCache(root, scope);
|
|
2364
2383
|
try {
|
|
2365
|
-
|
|
2366
|
-
} catch (error) {
|
|
2367
|
-
if (error.code !== "EEXIST") throw error;
|
|
2368
|
-
let held = {};
|
|
2384
|
+
const payload = cache.lockPayload();
|
|
2369
2385
|
try {
|
|
2370
|
-
|
|
2386
|
+
await fs16.writeFile(lockPath, payload, { flag: "wx" });
|
|
2387
|
+
} catch (error) {
|
|
2388
|
+
if (error.code !== "EEXIST") throw error;
|
|
2389
|
+
let held = {};
|
|
2390
|
+
try {
|
|
2391
|
+
held = JSON.parse(await fs16.readFile(lockPath, "utf8"));
|
|
2392
|
+
} catch {
|
|
2393
|
+
held = {};
|
|
2394
|
+
}
|
|
2395
|
+
const sameOwner = held.pid === process.pid && (typeof held.nonce === "string" && failedReleaseNonces.get(lockPath) === held.nonce || PROCESS_START_TICKS !== null && held.startTicks === PROCESS_START_TICKS);
|
|
2396
|
+
if (!sameOwner) {
|
|
2397
|
+
const owner = lockOwnerLive(held);
|
|
2398
|
+
if (owner.live) throw new ConvergePlanCacheBusyError(owner.pid);
|
|
2399
|
+
}
|
|
2400
|
+
const tmp = `${lockPath}.${process.pid}.tmp`;
|
|
2401
|
+
await fs16.writeFile(tmp, payload);
|
|
2402
|
+
await fs16.rename(tmp, lockPath);
|
|
2403
|
+
}
|
|
2404
|
+
failedReleaseNonces.delete(lockPath);
|
|
2405
|
+
try {
|
|
2406
|
+
await pruneSiblingScopes(root, scope);
|
|
2407
|
+
await pruneScopeDir(cache.scopeDir);
|
|
2371
2408
|
} catch {
|
|
2372
|
-
held = {};
|
|
2373
2409
|
}
|
|
2374
|
-
|
|
2375
|
-
|
|
2376
|
-
|
|
2377
|
-
await fs16.writeFile(tmp, payload);
|
|
2378
|
-
await fs16.rename(tmp, lockPath);
|
|
2379
|
-
}
|
|
2380
|
-
const cache = new _ConvergePlanCache(root, scope);
|
|
2381
|
-
try {
|
|
2382
|
-
await pruneSiblingScopes(root, scope);
|
|
2383
|
-
await pruneScopeDir(cache.scopeDir);
|
|
2384
|
-
} catch {
|
|
2410
|
+
} catch (error) {
|
|
2411
|
+
heldLockPaths.delete(lockPath);
|
|
2412
|
+
throw error;
|
|
2385
2413
|
}
|
|
2386
2414
|
return cache;
|
|
2387
2415
|
}
|
|
@@ -2417,6 +2445,7 @@ var ConvergePlanCache = class _ConvergePlanCache {
|
|
|
2417
2445
|
*/
|
|
2418
2446
|
async writeEntry(entry) {
|
|
2419
2447
|
if (this.closed) return;
|
|
2448
|
+
await this.renewLease();
|
|
2420
2449
|
const fileName = entryFileName(entry.side, entry.namespace, entry.watermark);
|
|
2421
2450
|
const finalPath = path2.join(this.scopeDir, fileName);
|
|
2422
2451
|
const tmpPath = `${finalPath}.${process.pid}.${Date.now()}.tmp`;
|
|
@@ -2439,11 +2468,49 @@ var ConvergePlanCache = class _ConvergePlanCache {
|
|
|
2439
2468
|
} catch {
|
|
2440
2469
|
}
|
|
2441
2470
|
}
|
|
2442
|
-
/**
|
|
2471
|
+
/**
|
|
2472
|
+
* Refresh savedAt while the cache stays open (#2965): on hosts without
|
|
2473
|
+
* readable /proc start ticks the 24h lease is the only steal guard, and a
|
|
2474
|
+
* plan legitimately longer than that must not have its lock stolen
|
|
2475
|
+
* mid-run. Renewal rides the per-namespace checkpoint cadence; it skips
|
|
2476
|
+
* a lock that was stolen from us (nonce mismatch).
|
|
2477
|
+
*/
|
|
2478
|
+
async renewLease() {
|
|
2479
|
+
if (this.closed) return;
|
|
2480
|
+
try {
|
|
2481
|
+
const held = JSON.parse(await fs16.readFile(this.lockPath, "utf8"));
|
|
2482
|
+
if (typeof held.nonce !== "string" || held.nonce !== this.nonce) return;
|
|
2483
|
+
const tmp = `${this.lockPath}.${process.pid}.renew.tmp`;
|
|
2484
|
+
await fs16.writeFile(tmp, this.lockPayload());
|
|
2485
|
+
await fs16.rename(tmp, this.lockPath);
|
|
2486
|
+
} catch {
|
|
2487
|
+
}
|
|
2488
|
+
}
|
|
2489
|
+
/**
|
|
2490
|
+
* Release the cross-process lock. Safe to call more than once. Only the
|
|
2491
|
+
* lock instance this cache owns is unlinked (#2965): a lock stolen from
|
|
2492
|
+
* us carries another owner's nonce and must survive this close. When our
|
|
2493
|
+
* own unlink fails, the nonce is retained so a later open in this
|
|
2494
|
+
* process reclaims the orphan instead of busy-failing on it.
|
|
2495
|
+
*/
|
|
2443
2496
|
async close() {
|
|
2444
2497
|
if (this.closed) return;
|
|
2445
2498
|
this.closed = true;
|
|
2446
|
-
|
|
2499
|
+
heldLockPaths.delete(this.lockPath);
|
|
2500
|
+
let owned = false;
|
|
2501
|
+
try {
|
|
2502
|
+
const held = JSON.parse(await fs16.readFile(this.lockPath, "utf8"));
|
|
2503
|
+
owned = typeof held.nonce === "string" && held.nonce === this.nonce;
|
|
2504
|
+
} catch {
|
|
2505
|
+
}
|
|
2506
|
+
if (!owned) return;
|
|
2507
|
+
try {
|
|
2508
|
+
await fs16.unlink(this.lockPath);
|
|
2509
|
+
} catch (error) {
|
|
2510
|
+
if (error.code !== "ENOENT") {
|
|
2511
|
+
failedReleaseNonces.set(this.lockPath, this.nonce);
|
|
2512
|
+
}
|
|
2513
|
+
}
|
|
2447
2514
|
}
|
|
2448
2515
|
};
|
|
2449
2516
|
|
|
@@ -2970,20 +3037,20 @@ async function planLocalNamespaceCensus(args) {
|
|
|
2970
3037
|
identityCache,
|
|
2971
3038
|
classificationUpdates
|
|
2972
3039
|
);
|
|
3040
|
+
const priorByPath = new Map((priorFiles ?? []).map((file) => [file.path, file.sha256.toLowerCase()]));
|
|
3041
|
+
let reused = 0;
|
|
3042
|
+
for (const file of files) {
|
|
3043
|
+
if (priorByPath.get(file.path) === file.sha256.toLowerCase()) reused += 1;
|
|
3044
|
+
}
|
|
3045
|
+
args.onProgress?.({
|
|
3046
|
+
side: "local",
|
|
3047
|
+
namespace: ns,
|
|
3048
|
+
index: args.index,
|
|
3049
|
+
total: args.total,
|
|
3050
|
+
reused,
|
|
3051
|
+
computed: files.length - reused
|
|
3052
|
+
});
|
|
2973
3053
|
if (args.cache) {
|
|
2974
|
-
const priorByPath = new Map((priorFiles ?? []).map((file) => [file.path, file.sha256.toLowerCase()]));
|
|
2975
|
-
let reused = 0;
|
|
2976
|
-
for (const file of files) {
|
|
2977
|
-
if (priorByPath.get(file.path) === file.sha256.toLowerCase()) reused += 1;
|
|
2978
|
-
}
|
|
2979
|
-
args.onProgress?.({
|
|
2980
|
-
side: "local",
|
|
2981
|
-
namespace: ns,
|
|
2982
|
-
index: args.index,
|
|
2983
|
-
total: args.total,
|
|
2984
|
-
reused,
|
|
2985
|
-
computed: files.length - reused
|
|
2986
|
-
});
|
|
2987
3054
|
await args.cache.writeEntry({
|
|
2988
3055
|
version: 1,
|
|
2989
3056
|
scope: args.cache.scope,
|
|
@@ -3025,7 +3092,7 @@ import {
|
|
|
3025
3092
|
RECONCILE_MANIFEST_SCHEMA_VERSION as RECONCILE_MANIFEST_SCHEMA_VERSION2
|
|
3026
3093
|
} from "@remnic/core/reconcile/manifest.js";
|
|
3027
3094
|
var SHA256_PATTERN = /^[a-f0-9]{64}$/i;
|
|
3028
|
-
var
|
|
3095
|
+
var MEMORY_STATUSES2 = /* @__PURE__ */ new Set([
|
|
3029
3096
|
"active",
|
|
3030
3097
|
"pending_review",
|
|
3031
3098
|
"rejected",
|
|
@@ -3062,7 +3129,7 @@ function parseMemory(value) {
|
|
|
3062
3129
|
if (typeof memory.contentHash !== "string" || !SHA256_PATTERN.test(memory.contentHash)) {
|
|
3063
3130
|
throw new Error("peer manifest memory metadata had invalid contentHash");
|
|
3064
3131
|
}
|
|
3065
|
-
if (typeof memory.status !== "string" || !
|
|
3132
|
+
if (typeof memory.status !== "string" || !MEMORY_STATUSES2.has(memory.status)) {
|
|
3066
3133
|
throw new Error("peer manifest memory metadata had invalid status");
|
|
3067
3134
|
}
|
|
3068
3135
|
const contentHash = memory.contentHash.toLowerCase();
|
|
@@ -3561,7 +3628,11 @@ async function planPeerNamespaceCensus(args) {
|
|
|
3561
3628
|
const watermark = censusWatermark(peerData.files);
|
|
3562
3629
|
let peerManifest = null;
|
|
3563
3630
|
let clientBuilt = clientBuiltPrior;
|
|
3564
|
-
if (reusableEntry && reusableEntry.watermark === watermark && reusableEntry.fileCount === peerData.files.length
|
|
3631
|
+
if (reusableEntry && reusableEntry.watermark === watermark && reusableEntry.fileCount === peerData.files.length && // A peer upgraded to manifest streaming must not keep serving this
|
|
3632
|
+
// client's older parser semantics on an unchanged watermark (#2965):
|
|
3633
|
+
// client-built rows stay a warm base only; the stream runs once and
|
|
3634
|
+
// the checkpoint becomes a streamed entry.
|
|
3635
|
+
!(args.manifestStream && clientBuiltPrior)) {
|
|
3565
3636
|
const freshByPath = new Map(peerData.files.map((file) => [file.path, file]));
|
|
3566
3637
|
peerManifest = {
|
|
3567
3638
|
format: RECONCILE_MANIFEST_FORMAT2,
|
|
@@ -3640,33 +3711,35 @@ async function planPeerNamespaceCensus(args) {
|
|
|
3640
3711
|
}
|
|
3641
3712
|
const mapped = tombstonedFileDigests(evidence, peerManifests);
|
|
3642
3713
|
for (const digest of peerData.tombstones) mapped.add(digest);
|
|
3714
|
+
const priorByPath = new Map((priorPeerFiles ?? []).map((file) => [file.path, file.sha256.toLowerCase()]));
|
|
3715
|
+
let reused = 0;
|
|
3716
|
+
for (const file of peerManifests.files) {
|
|
3717
|
+
if (priorByPath.get(file.path) === file.sha256.toLowerCase()) reused += 1;
|
|
3718
|
+
}
|
|
3719
|
+
args.onProgress?.({
|
|
3720
|
+
side: "peer",
|
|
3721
|
+
namespace: ns,
|
|
3722
|
+
index: args.index,
|
|
3723
|
+
total: args.total,
|
|
3724
|
+
reused,
|
|
3725
|
+
computed: peerManifests.files.length - reused
|
|
3726
|
+
});
|
|
3643
3727
|
if (args.cache) {
|
|
3644
|
-
|
|
3645
|
-
|
|
3646
|
-
|
|
3647
|
-
|
|
3728
|
+
if (censusWatermark(peerManifests.files) === watermark) {
|
|
3729
|
+
await args.cache.writeEntry({
|
|
3730
|
+
version: 1,
|
|
3731
|
+
scope: args.cache.scope,
|
|
3732
|
+
side: "peer",
|
|
3733
|
+
namespace: ns,
|
|
3734
|
+
watermark,
|
|
3735
|
+
fileCount: peerManifests.files.length,
|
|
3736
|
+
capturedAtMs: Date.now(),
|
|
3737
|
+
savedAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
3738
|
+
...args.peerManifestRevision !== void 0 ? { peerManifestRevision: args.peerManifestRevision } : {},
|
|
3739
|
+
...clientBuilt ? { clientBuilt: true } : {},
|
|
3740
|
+
files: peerManifests.files
|
|
3741
|
+
});
|
|
3648
3742
|
}
|
|
3649
|
-
args.onProgress?.({
|
|
3650
|
-
side: "peer",
|
|
3651
|
-
namespace: ns,
|
|
3652
|
-
index: args.index,
|
|
3653
|
-
total: args.total,
|
|
3654
|
-
reused,
|
|
3655
|
-
computed: peerManifests.files.length - reused
|
|
3656
|
-
});
|
|
3657
|
-
await args.cache.writeEntry({
|
|
3658
|
-
version: 1,
|
|
3659
|
-
scope: args.cache.scope,
|
|
3660
|
-
side: "peer",
|
|
3661
|
-
namespace: ns,
|
|
3662
|
-
watermark,
|
|
3663
|
-
fileCount: peerManifests.files.length,
|
|
3664
|
-
capturedAtMs: Date.now(),
|
|
3665
|
-
savedAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
3666
|
-
...args.peerManifestRevision !== void 0 ? { peerManifestRevision: args.peerManifestRevision } : {},
|
|
3667
|
-
...clientBuilt ? { clientBuilt: true } : {},
|
|
3668
|
-
files: peerManifests.files
|
|
3669
|
-
});
|
|
3670
3743
|
}
|
|
3671
3744
|
return { manifest: peerManifests, tombstones: mapped };
|
|
3672
3745
|
}
|
|
@@ -4560,6 +4633,7 @@ async function updateCursorsForPlan(plan, options) {
|
|
|
4560
4633
|
if (!memoryDir) return;
|
|
4561
4634
|
const namespaces = new Set(plan.byNamespace.map((n) => n.namespace));
|
|
4562
4635
|
for (const ns of namespaces) {
|
|
4636
|
+
options.signal?.throwIfAborted();
|
|
4563
4637
|
const cursorPath = defaultConvergeCursorPath(memoryDir, peerUrl, ns);
|
|
4564
4638
|
const priorSemanticAgreements = options.semanticAgreementsByNamespace?.get(ns) ?? (await readConvergeCursor(cursorPath))?.semanticAgreements ?? [];
|
|
4565
4639
|
const { baseFiles, semanticAgreements } = deriveConvergeCursorBase(plan.entries, ns, priorSemanticAgreements);
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@remnic/cli",
|
|
3
|
-
"version": "9.69.
|
|
3
|
+
"version": "9.69.46",
|
|
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/plugin-pi": "^9.69.
|
|
30
|
-
"@remnic/server": "^9.69.
|
|
31
|
-
"@remnic/core": "^9.69.
|
|
29
|
+
"@remnic/plugin-pi": "^9.69.46",
|
|
30
|
+
"@remnic/server": "^9.69.46",
|
|
31
|
+
"@remnic/core": "^9.69.46"
|
|
32
32
|
},
|
|
33
33
|
"peerDependencies": {
|
|
34
|
-
"@remnic/bench": "^9.69.
|
|
35
|
-
"@remnic/plugin-openclaw": "^9.69.
|
|
36
|
-
"@remnic/export-weclone": "^9.69.
|
|
37
|
-
"@remnic/import-weclone": "^9.69.
|
|
38
|
-
"@remnic/import-chatgpt": "^9.69.
|
|
39
|
-
"@remnic/import-claude": "^9.69.
|
|
40
|
-
"@remnic/import-gemini": "^9.69.
|
|
41
|
-
"@remnic/import-lossless-claw": "^9.69.
|
|
42
|
-
"@remnic/import-mem0": "^9.69.
|
|
43
|
-
"@remnic/import-supermemory": "^9.69.
|
|
44
|
-
"@remnic/import-okf": "^9.69.
|
|
45
|
-
"@remnic/connector-limitless": "^9.69.
|
|
46
|
-
"@remnic/connector-bee": "^9.69.
|
|
47
|
-
"@remnic/connector-omi": "^9.69.
|
|
48
|
-
"@remnic/capture-audio": "^9.69.
|
|
34
|
+
"@remnic/bench": "^9.69.46",
|
|
35
|
+
"@remnic/plugin-openclaw": "^9.69.46",
|
|
36
|
+
"@remnic/export-weclone": "^9.69.46",
|
|
37
|
+
"@remnic/import-weclone": "^9.69.46",
|
|
38
|
+
"@remnic/import-chatgpt": "^9.69.46",
|
|
39
|
+
"@remnic/import-claude": "^9.69.46",
|
|
40
|
+
"@remnic/import-gemini": "^9.69.46",
|
|
41
|
+
"@remnic/import-lossless-claw": "^9.69.46",
|
|
42
|
+
"@remnic/import-mem0": "^9.69.46",
|
|
43
|
+
"@remnic/import-supermemory": "^9.69.46",
|
|
44
|
+
"@remnic/import-okf": "^9.69.46",
|
|
45
|
+
"@remnic/connector-limitless": "^9.69.46",
|
|
46
|
+
"@remnic/connector-bee": "^9.69.46",
|
|
47
|
+
"@remnic/connector-omi": "^9.69.46",
|
|
48
|
+
"@remnic/capture-audio": "^9.69.46"
|
|
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/
|
|
101
|
-
"@remnic/
|
|
102
|
-
"@remnic/
|
|
103
|
-
"@remnic/
|
|
104
|
-
"@remnic/import-
|
|
105
|
-
"@remnic/import-
|
|
106
|
-
"@remnic/import-gemini": "9.69.
|
|
107
|
-
"@remnic/import-
|
|
108
|
-
"@remnic/import-mem0": "9.69.
|
|
109
|
-
"@remnic/connector-limitless": "9.69.
|
|
110
|
-
"@remnic/
|
|
111
|
-
"@remnic/connector-omi": "9.69.
|
|
112
|
-
"@remnic/
|
|
100
|
+
"@remnic/bench": "9.69.46",
|
|
101
|
+
"@remnic/plugin-openclaw": "9.69.46",
|
|
102
|
+
"@remnic/export-weclone": "9.69.46",
|
|
103
|
+
"@remnic/import-weclone": "9.69.46",
|
|
104
|
+
"@remnic/import-chatgpt": "9.69.46",
|
|
105
|
+
"@remnic/import-claude": "9.69.46",
|
|
106
|
+
"@remnic/import-gemini": "9.69.46",
|
|
107
|
+
"@remnic/import-lossless-claw": "9.69.46",
|
|
108
|
+
"@remnic/import-mem0": "9.69.46",
|
|
109
|
+
"@remnic/connector-limitless": "9.69.46",
|
|
110
|
+
"@remnic/import-supermemory": "9.69.46",
|
|
111
|
+
"@remnic/connector-omi": "9.69.46",
|
|
112
|
+
"@remnic/connector-bee": "9.69.46"
|
|
113
113
|
},
|
|
114
114
|
"license": "MIT",
|
|
115
115
|
"repository": {
|