@remnic/cli 9.65.8 → 9.66.1
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 +860 -558
- package/package.json +35 -31
package/dist/index.js
CHANGED
|
@@ -18,20 +18,20 @@ async function persistEnrichmentCandidate(storage, entityName, candidate) {
|
|
|
18
18
|
}
|
|
19
19
|
|
|
20
20
|
// src/index.ts
|
|
21
|
-
import
|
|
21
|
+
import fs26 from "fs";
|
|
22
22
|
import os3 from "os";
|
|
23
|
-
import
|
|
23
|
+
import path19 from "path";
|
|
24
24
|
import { createHash as createHash4 } from "crypto";
|
|
25
25
|
import { writeFile as fsWriteFile } from "fs/promises";
|
|
26
26
|
import * as childProcess2 from "child_process";
|
|
27
27
|
import { fileURLToPath as fileURLToPath5 } from "url";
|
|
28
28
|
import { gzipSync } from "zlib";
|
|
29
29
|
import {
|
|
30
|
-
parseConfig as
|
|
30
|
+
parseConfig as parseConfig17,
|
|
31
31
|
isOpenaiApiKeyDisabled,
|
|
32
32
|
resolveEnvVars,
|
|
33
|
-
resolveRemnicConfigRecord as
|
|
34
|
-
Orchestrator as
|
|
33
|
+
resolveRemnicConfigRecord as resolveRemnicConfigRecord16,
|
|
34
|
+
Orchestrator as Orchestrator10,
|
|
35
35
|
EngramAccessService as EngramAccessService2,
|
|
36
36
|
initLogger as initLogger5,
|
|
37
37
|
onboard,
|
|
@@ -192,12 +192,49 @@ async function runMeetingsBinaryCommand(rest) {
|
|
|
192
192
|
}
|
|
193
193
|
}
|
|
194
194
|
|
|
195
|
-
// src/commands/
|
|
195
|
+
// src/commands/timeline.ts
|
|
196
196
|
import fs2 from "fs";
|
|
197
197
|
import {
|
|
198
|
-
Orchestrator as Orchestrator2,
|
|
199
198
|
parseConfig as parseConfig2,
|
|
200
199
|
resolveRemnicConfigRecord as resolveRemnicConfigRecord2,
|
|
200
|
+
runTimelineCliCommand
|
|
201
|
+
} from "@remnic/core";
|
|
202
|
+
async function runTimelineBinaryCommand(rest) {
|
|
203
|
+
const timelineArgs = rest.length === 0 || rest[0] === "--help" || rest[0] === "-h" ? ["help"] : rest;
|
|
204
|
+
try {
|
|
205
|
+
let qa = { enabled: false, maxRangeDays: 31 };
|
|
206
|
+
let timelineEnabled = false;
|
|
207
|
+
try {
|
|
208
|
+
const configPath = resolveConfigPath();
|
|
209
|
+
const raw = fs2.existsSync(configPath) ? JSON.parse(fs2.readFileSync(configPath, "utf8")) : {};
|
|
210
|
+
const config = parseConfig2(resolveRemnicConfigRecord2(raw));
|
|
211
|
+
timelineEnabled = config.activity.timeline.enabled;
|
|
212
|
+
qa = config.activity.timeline.qa;
|
|
213
|
+
} catch {
|
|
214
|
+
console.error(
|
|
215
|
+
"timeline: failed to load the Remnic config \u2014 run `remnic doctor` and check the config file for errors"
|
|
216
|
+
);
|
|
217
|
+
process.exitCode = 1;
|
|
218
|
+
return;
|
|
219
|
+
}
|
|
220
|
+
const code = await runTimelineCliCommand(
|
|
221
|
+
{ cards: null, qa, timelineEnabled },
|
|
222
|
+
timelineArgs,
|
|
223
|
+
{ stdout: process.stdout, stderr: process.stderr }
|
|
224
|
+
);
|
|
225
|
+
if (code !== 0) process.exitCode = code;
|
|
226
|
+
} catch (err) {
|
|
227
|
+
console.error(err instanceof Error ? err.message : String(err));
|
|
228
|
+
process.exitCode = 1;
|
|
229
|
+
}
|
|
230
|
+
}
|
|
231
|
+
|
|
232
|
+
// src/commands/wearables.ts
|
|
233
|
+
import fs3 from "fs";
|
|
234
|
+
import {
|
|
235
|
+
Orchestrator as Orchestrator2,
|
|
236
|
+
parseConfig as parseConfig3,
|
|
237
|
+
resolveRemnicConfigRecord as resolveRemnicConfigRecord3,
|
|
201
238
|
runWearablesCliCommand
|
|
202
239
|
} from "@remnic/core";
|
|
203
240
|
async function runWearablesBinaryCommand(rest) {
|
|
@@ -207,8 +244,8 @@ async function runWearablesBinaryCommand(rest) {
|
|
|
207
244
|
let wearablesService;
|
|
208
245
|
try {
|
|
209
246
|
const configPath = resolveConfigPath();
|
|
210
|
-
const raw =
|
|
211
|
-
const config =
|
|
247
|
+
const raw = fs3.existsSync(configPath) ? JSON.parse(fs3.readFileSync(configPath, "utf8")) : {};
|
|
248
|
+
const config = parseConfig3(resolveRemnicConfigRecord3(raw));
|
|
212
249
|
wearablesOrchestrator = new Orchestrator2(config);
|
|
213
250
|
await wearablesOrchestrator.initialize();
|
|
214
251
|
await wearablesOrchestrator.deferredReady;
|
|
@@ -245,17 +282,17 @@ async function runWearablesBinaryCommand(rest) {
|
|
|
245
282
|
}
|
|
246
283
|
|
|
247
284
|
// src/commands/location.ts
|
|
248
|
-
import
|
|
249
|
-
import { parseConfig as
|
|
250
|
-
import { runLocationCliCommand } from "@remnic/core/location";
|
|
285
|
+
import fs4 from "fs";
|
|
286
|
+
import { parseConfig as parseConfig4, resolveRemnicConfigRecord as resolveRemnicConfigRecord4 } from "@remnic/core";
|
|
287
|
+
import { backfillMemoryStorage, runLocationCliCommand } from "@remnic/core/location";
|
|
251
288
|
async function runLocationBinaryCommand(rest) {
|
|
252
289
|
const locationArgs = rest.length === 0 || rest[0] === "--help" || rest[0] === "-h" ? ["help"] : rest;
|
|
253
290
|
try {
|
|
254
291
|
let config;
|
|
255
292
|
try {
|
|
256
293
|
const configPath = resolveConfigPath();
|
|
257
|
-
const raw =
|
|
258
|
-
config =
|
|
294
|
+
const raw = fs4.existsSync(configPath) ? JSON.parse(fs4.readFileSync(configPath, "utf8")) : {};
|
|
295
|
+
config = parseConfig4(resolveRemnicConfigRecord4(raw));
|
|
259
296
|
} catch {
|
|
260
297
|
console.error(
|
|
261
298
|
"location: failed to load the Remnic config \u2014 run `remnic doctor` and check the config file for errors"
|
|
@@ -264,7 +301,11 @@ async function runLocationBinaryCommand(rest) {
|
|
|
264
301
|
return;
|
|
265
302
|
}
|
|
266
303
|
const code = await runLocationCliCommand(
|
|
267
|
-
{
|
|
304
|
+
{
|
|
305
|
+
config: config.location,
|
|
306
|
+
memoryDir: config.memoryDir,
|
|
307
|
+
getMemoryStorage: () => backfillMemoryStorage(config)
|
|
308
|
+
},
|
|
268
309
|
locationArgs,
|
|
269
310
|
{ stdout: process.stdout, stderr: process.stderr }
|
|
270
311
|
);
|
|
@@ -276,16 +317,16 @@ async function runLocationBinaryCommand(rest) {
|
|
|
276
317
|
}
|
|
277
318
|
|
|
278
319
|
// src/commands/okf.ts
|
|
279
|
-
import
|
|
280
|
-
import { Orchestrator as Orchestrator3, parseConfig as
|
|
320
|
+
import fs5 from "fs";
|
|
321
|
+
import { Orchestrator as Orchestrator3, parseConfig as parseConfig5, resolveRemnicConfigRecord as resolveRemnicConfigRecord5, runOkfCliCommand } from "@remnic/core";
|
|
281
322
|
async function runOkfBinaryCommand(rest) {
|
|
282
323
|
const argv = rest.length === 0 || rest[0] === "--help" || rest[0] === "-h" ? ["help"] : rest;
|
|
283
324
|
let orchestrator;
|
|
284
325
|
try {
|
|
285
326
|
try {
|
|
286
327
|
const configPath = resolveConfigPath();
|
|
287
|
-
const raw =
|
|
288
|
-
const config2 =
|
|
328
|
+
const raw = fs5.existsSync(configPath) ? JSON.parse(fs5.readFileSync(configPath, "utf8")) : {};
|
|
329
|
+
const config2 = parseConfig5(resolveRemnicConfigRecord5(raw));
|
|
289
330
|
orchestrator = new Orchestrator3(config2);
|
|
290
331
|
await orchestrator.initialize();
|
|
291
332
|
await orchestrator.deferredReady;
|
|
@@ -300,7 +341,8 @@ async function runOkfBinaryCommand(rest) {
|
|
|
300
341
|
const code = await runOkfCliCommand(argv, { stdout: process.stdout, stderr: process.stderr }, {
|
|
301
342
|
memoryDir: config.memoryDir,
|
|
302
343
|
conformanceEnabled: config.okf.conformanceEnabled,
|
|
303
|
-
sweepEnabled: config.okf.sweepEnabled
|
|
344
|
+
sweepEnabled: config.okf.sweepEnabled,
|
|
345
|
+
indexFilesEnabled: config.okf.indexFilesEnabled
|
|
304
346
|
});
|
|
305
347
|
if (code !== 0) process.exitCode = code;
|
|
306
348
|
} catch (err) {
|
|
@@ -312,15 +354,249 @@ async function runOkfBinaryCommand(rest) {
|
|
|
312
354
|
}
|
|
313
355
|
}
|
|
314
356
|
|
|
357
|
+
// src/commands/export-okf.ts
|
|
358
|
+
import fs6 from "fs";
|
|
359
|
+
import path from "path";
|
|
360
|
+
import { Orchestrator as Orchestrator4, parseConfig as parseConfig6, resolveRemnicConfigRecord as resolveRemnicConfigRecord6 } from "@remnic/core";
|
|
361
|
+
import { exportOkfBundle, parseIncludeStatus } from "@remnic/core/export-okf";
|
|
362
|
+
function takeFlag(rest, name) {
|
|
363
|
+
const index = rest.indexOf(name);
|
|
364
|
+
if (index < 0) return void 0;
|
|
365
|
+
const value = rest[index + 1];
|
|
366
|
+
if (value === void 0 || value.startsWith("-")) {
|
|
367
|
+
throw new Error(`${name} requires a value`);
|
|
368
|
+
}
|
|
369
|
+
return value;
|
|
370
|
+
}
|
|
371
|
+
async function runExportOkfBinaryCommand(rest) {
|
|
372
|
+
if (rest[0] === "--help" || rest[0] === "-h" || rest.length === 0) {
|
|
373
|
+
console.log("Usage: remnic export okf --out <dir> [--force] [--include-profile] [--log]");
|
|
374
|
+
return;
|
|
375
|
+
}
|
|
376
|
+
if (rest[0] !== "okf") {
|
|
377
|
+
console.error("Usage: remnic export okf --out <dir>");
|
|
378
|
+
process.exitCode = 1;
|
|
379
|
+
return;
|
|
380
|
+
}
|
|
381
|
+
const args = rest.slice(1);
|
|
382
|
+
let orchestrator;
|
|
383
|
+
try {
|
|
384
|
+
const out = takeFlag(args, "--out");
|
|
385
|
+
if (!out) throw new Error("Missing --out");
|
|
386
|
+
const namespace = takeFlag(args, "--namespace") ?? "";
|
|
387
|
+
const configPath = resolveConfigPath();
|
|
388
|
+
const raw = fs6.existsSync(configPath) ? JSON.parse(fs6.readFileSync(configPath, "utf8")) : {};
|
|
389
|
+
const config = parseConfig6(resolveRemnicConfigRecord6(raw));
|
|
390
|
+
orchestrator = new Orchestrator4(config);
|
|
391
|
+
await orchestrator.initialize();
|
|
392
|
+
await orchestrator.deferredReady;
|
|
393
|
+
const memoryDir = namespace ? path.join(orchestrator.config.memoryDir, "namespaces", namespace) : orchestrator.config.memoryDir;
|
|
394
|
+
const result = await exportOkfBundle({
|
|
395
|
+
memoryDir,
|
|
396
|
+
outDir: out,
|
|
397
|
+
includeStatus: parseIncludeStatus(takeFlag(args, "--include-status")),
|
|
398
|
+
includeCategories: takeFlag(args, "--include-categories")?.split(","),
|
|
399
|
+
excludeTags: takeFlag(args, "--exclude-tags")?.split(","),
|
|
400
|
+
includeProfile: args.includes("--include-profile"),
|
|
401
|
+
includeWearables: args.includes("--include-wearables"),
|
|
402
|
+
includeLog: args.includes("--log"),
|
|
403
|
+
force: args.includes("--force")
|
|
404
|
+
});
|
|
405
|
+
if (result.plaintextWarning) console.log("PLAINTEXT EXPORT: the OKF bundle is unencrypted.");
|
|
406
|
+
console.log(`OKF export: ${result.exported} concepts, ${result.excluded} excluded`);
|
|
407
|
+
} catch (err) {
|
|
408
|
+
console.error(err instanceof Error ? err.message : String(err));
|
|
409
|
+
process.exitCode = 1;
|
|
410
|
+
} finally {
|
|
411
|
+
orchestrator?.abortDeferredInit();
|
|
412
|
+
await orchestrator?.destroy();
|
|
413
|
+
}
|
|
414
|
+
}
|
|
415
|
+
|
|
416
|
+
// src/commands/codegraph.ts
|
|
417
|
+
import fs7 from "fs";
|
|
418
|
+
import { Orchestrator as Orchestrator5, parseConfig as parseConfig7, resolveRemnicConfigRecord as resolveRemnicConfigRecord7 } from "@remnic/core";
|
|
419
|
+
import {
|
|
420
|
+
exportCodegraphOkfBundle,
|
|
421
|
+
parseOkfCodegraphSymbolFilter
|
|
422
|
+
} from "@remnic/core/export-okf-codegraph";
|
|
423
|
+
function takeFlag2(rest, name) {
|
|
424
|
+
const index = rest.indexOf(name);
|
|
425
|
+
if (index < 0) return void 0;
|
|
426
|
+
const value = rest[index + 1];
|
|
427
|
+
if (value === void 0 || value.startsWith("-")) {
|
|
428
|
+
throw new Error(`${name} requires a value`);
|
|
429
|
+
}
|
|
430
|
+
return value;
|
|
431
|
+
}
|
|
432
|
+
async function runCodegraphBinaryCommand(rest) {
|
|
433
|
+
if (rest[0] === "--help" || rest[0] === "-h" || rest.length === 0) {
|
|
434
|
+
console.log(
|
|
435
|
+
"Usage: remnic codegraph export-okf --project <id> --out <dir> [--max-module-concepts <n>] [--symbols none|exported|all] [--force]"
|
|
436
|
+
);
|
|
437
|
+
return;
|
|
438
|
+
}
|
|
439
|
+
if (rest[0] !== "export-okf") {
|
|
440
|
+
console.error("Usage: remnic codegraph export-okf --project <id> --out <dir>");
|
|
441
|
+
process.exitCode = 1;
|
|
442
|
+
return;
|
|
443
|
+
}
|
|
444
|
+
const args = rest.slice(1);
|
|
445
|
+
let orchestrator;
|
|
446
|
+
try {
|
|
447
|
+
const project = takeFlag2(args, "--project");
|
|
448
|
+
const out = takeFlag2(args, "--out");
|
|
449
|
+
if (!project) throw new Error("Missing --project");
|
|
450
|
+
if (!out) throw new Error("Missing --out");
|
|
451
|
+
const configPath = resolveConfigPath();
|
|
452
|
+
const raw = fs7.existsSync(configPath) ? JSON.parse(fs7.readFileSync(configPath, "utf8")) : {};
|
|
453
|
+
const config = parseConfig7(resolveRemnicConfigRecord7(raw));
|
|
454
|
+
orchestrator = new Orchestrator5(config);
|
|
455
|
+
await orchestrator.initialize();
|
|
456
|
+
await orchestrator.deferredReady;
|
|
457
|
+
const maxRaw = takeFlag2(args, "--max-module-concepts");
|
|
458
|
+
const result = await exportCodegraphOkfBundle({
|
|
459
|
+
config: orchestrator.config,
|
|
460
|
+
memoryDir: orchestrator.config.memoryDir,
|
|
461
|
+
projectId: project,
|
|
462
|
+
outDir: out,
|
|
463
|
+
force: args.includes("--force"),
|
|
464
|
+
includeAdrs: !args.includes("--no-include-adrs"),
|
|
465
|
+
symbols: parseOkfCodegraphSymbolFilter(takeFlag2(args, "--symbols")),
|
|
466
|
+
...maxRaw !== void 0 ? { maxModuleConcepts: Number(maxRaw) } : {}
|
|
467
|
+
});
|
|
468
|
+
console.log(
|
|
469
|
+
`OKF codegraph export: ${result.moduleConcepts} modules, ${result.decisions} decisions` + (result.truncated ? " (truncated)" : "")
|
|
470
|
+
);
|
|
471
|
+
} catch (err) {
|
|
472
|
+
console.error(err instanceof Error ? err.message : String(err));
|
|
473
|
+
process.exitCode = 1;
|
|
474
|
+
} finally {
|
|
475
|
+
orchestrator?.abortDeferredInit();
|
|
476
|
+
await orchestrator?.destroy();
|
|
477
|
+
}
|
|
478
|
+
}
|
|
479
|
+
|
|
480
|
+
// src/commands/standup.ts
|
|
481
|
+
import fs8 from "fs";
|
|
482
|
+
import { Orchestrator as Orchestrator6, parseConfig as parseConfig8, resolveRemnicConfigRecord as resolveRemnicConfigRecord8 } from "@remnic/core";
|
|
483
|
+
import { buildStandup, parseStandupDate, standupHelp } from "@remnic/core/standup";
|
|
484
|
+
function takeFlag3(rest, name) {
|
|
485
|
+
const index = rest.indexOf(name);
|
|
486
|
+
if (index < 0) return void 0;
|
|
487
|
+
const value = rest[index + 1];
|
|
488
|
+
if (value === void 0 || value.startsWith("-")) throw new Error(`${name} requires a value`);
|
|
489
|
+
return value;
|
|
490
|
+
}
|
|
491
|
+
async function runStandupBinaryCommand(rest) {
|
|
492
|
+
if (rest[0] === "--help" || rest[0] === "-h") {
|
|
493
|
+
console.log(standupHelp());
|
|
494
|
+
return;
|
|
495
|
+
}
|
|
496
|
+
let orchestrator;
|
|
497
|
+
try {
|
|
498
|
+
const configPath = resolveConfigPath();
|
|
499
|
+
const raw = fs8.existsSync(configPath) ? JSON.parse(fs8.readFileSync(configPath, "utf8")) : {};
|
|
500
|
+
const config = parseConfig8(resolveRemnicConfigRecord8(raw));
|
|
501
|
+
orchestrator = new Orchestrator6(config);
|
|
502
|
+
await orchestrator.initialize();
|
|
503
|
+
await orchestrator.deferredReady;
|
|
504
|
+
const brief = buildStandup(orchestrator.config.memoryDir, parseStandupDate(takeFlag3(rest, "--date")));
|
|
505
|
+
console.log(brief.markdown);
|
|
506
|
+
} catch (err) {
|
|
507
|
+
console.error(err instanceof Error ? err.message : String(err));
|
|
508
|
+
process.exitCode = 1;
|
|
509
|
+
} finally {
|
|
510
|
+
orchestrator?.abortDeferredInit();
|
|
511
|
+
await orchestrator?.destroy();
|
|
512
|
+
}
|
|
513
|
+
}
|
|
514
|
+
|
|
515
|
+
// src/commands/journal.ts
|
|
516
|
+
import fs9 from "fs";
|
|
517
|
+
import {
|
|
518
|
+
journalPath,
|
|
519
|
+
parseConfig as parseConfig9,
|
|
520
|
+
resolveRemnicConfigRecord as resolveRemnicConfigRecord9,
|
|
521
|
+
seedJournal,
|
|
522
|
+
todayJournalDate
|
|
523
|
+
} from "@remnic/core";
|
|
524
|
+
function takeFlag4(rest, name) {
|
|
525
|
+
const index = rest.indexOf(name);
|
|
526
|
+
if (index < 0) return void 0;
|
|
527
|
+
const value = rest[index + 1];
|
|
528
|
+
if (value === void 0 || value.startsWith("-")) throw new Error(`${name} requires a value`);
|
|
529
|
+
return value;
|
|
530
|
+
}
|
|
531
|
+
function journalHelp() {
|
|
532
|
+
return `Usage: remnic journal <show|edit-path|seed> [--date YYYY-MM-DD] [--force]
|
|
533
|
+
|
|
534
|
+
show Print the journal file for the date (default: today).
|
|
535
|
+
edit-path Print the journal file path.
|
|
536
|
+
seed Write the file only if it is absent. --force overwrites.
|
|
537
|
+
`;
|
|
538
|
+
}
|
|
539
|
+
function loadMemoryDir() {
|
|
540
|
+
const configPath = resolveConfigPath();
|
|
541
|
+
const raw = fs9.existsSync(configPath) ? JSON.parse(fs9.readFileSync(configPath, "utf8")) : {};
|
|
542
|
+
return parseConfig9(resolveRemnicConfigRecord9(raw)).memoryDir;
|
|
543
|
+
}
|
|
544
|
+
async function runJournalBinaryCommand(rest) {
|
|
545
|
+
if (rest.length === 0 || rest[0] === "--help" || rest[0] === "-h" || rest[0] === "help") {
|
|
546
|
+
console.log(journalHelp());
|
|
547
|
+
return;
|
|
548
|
+
}
|
|
549
|
+
let memoryDir;
|
|
550
|
+
try {
|
|
551
|
+
memoryDir = loadMemoryDir();
|
|
552
|
+
} catch {
|
|
553
|
+
console.error(
|
|
554
|
+
"journal: failed to load the Remnic config \u2014 run `remnic doctor` and check the config file for errors"
|
|
555
|
+
);
|
|
556
|
+
process.exitCode = 1;
|
|
557
|
+
return;
|
|
558
|
+
}
|
|
559
|
+
try {
|
|
560
|
+
const action = rest[0];
|
|
561
|
+
const date = takeFlag4(rest, "--date") ?? todayJournalDate();
|
|
562
|
+
const force = rest.includes("--force");
|
|
563
|
+
const filePath = journalPath(memoryDir, date);
|
|
564
|
+
if (action === "edit-path") {
|
|
565
|
+
console.log(filePath);
|
|
566
|
+
return;
|
|
567
|
+
}
|
|
568
|
+
if (action === "show") {
|
|
569
|
+
if (!fs9.existsSync(filePath)) {
|
|
570
|
+
console.error(`journal: no file at ${filePath}. Run remnic journal seed --date ${date}.`);
|
|
571
|
+
process.exitCode = 1;
|
|
572
|
+
return;
|
|
573
|
+
}
|
|
574
|
+
process.stdout.write(fs9.readFileSync(filePath, "utf8"));
|
|
575
|
+
return;
|
|
576
|
+
}
|
|
577
|
+
if (action === "seed") {
|
|
578
|
+
const result = seedJournal({ memoryDir, date, force });
|
|
579
|
+
console.log(result.wrote ? `wrote ${result.path}` : `unchanged ${result.path}`);
|
|
580
|
+
return;
|
|
581
|
+
}
|
|
582
|
+
console.error(`journal: unknown action "${action}".`);
|
|
583
|
+
console.error(journalHelp());
|
|
584
|
+
process.exitCode = 1;
|
|
585
|
+
} catch (err) {
|
|
586
|
+
console.error(err instanceof Error ? err.message : String(err));
|
|
587
|
+
process.exitCode = 1;
|
|
588
|
+
}
|
|
589
|
+
}
|
|
590
|
+
|
|
315
591
|
// src/commands/external-wiki.ts
|
|
316
|
-
import
|
|
317
|
-
import { parseConfig as
|
|
592
|
+
import fs10 from "fs";
|
|
593
|
+
import { parseConfig as parseConfig10, resolveRemnicConfigRecord as resolveRemnicConfigRecord10, runExternalWikiCliCommand } from "@remnic/core";
|
|
318
594
|
async function runExternalWikiBinaryCommand(rest) {
|
|
319
595
|
let roots;
|
|
320
596
|
try {
|
|
321
597
|
const configPath = resolveConfigPath();
|
|
322
|
-
const raw =
|
|
323
|
-
roots =
|
|
598
|
+
const raw = fs10.existsSync(configPath) ? JSON.parse(fs10.readFileSync(configPath, "utf8")) : {};
|
|
599
|
+
roots = parseConfig10(resolveRemnicConfigRecord10(raw)).externalWikis;
|
|
324
600
|
} catch {
|
|
325
601
|
console.error(
|
|
326
602
|
"external-wiki: failed to load the Remnic config - run `remnic doctor` and check the config file for errors"
|
|
@@ -341,14 +617,14 @@ async function runExternalWikiBinaryCommand(rest) {
|
|
|
341
617
|
}
|
|
342
618
|
|
|
343
619
|
// src/commands/procedural.ts
|
|
344
|
-
import
|
|
620
|
+
import fs11 from "fs";
|
|
345
621
|
import {
|
|
346
622
|
StorageManager,
|
|
347
623
|
computeProcedureStats,
|
|
348
624
|
formatProcedureStatsText,
|
|
349
625
|
initLogger,
|
|
350
|
-
parseConfig as
|
|
351
|
-
resolveRemnicConfigRecord as
|
|
626
|
+
parseConfig as parseConfig11,
|
|
627
|
+
resolveRemnicConfigRecord as resolveRemnicConfigRecord11,
|
|
352
628
|
runProcedureLibraryMaintenance
|
|
353
629
|
} from "@remnic/core";
|
|
354
630
|
|
|
@@ -479,8 +755,8 @@ Shared with:
|
|
|
479
755
|
process.exit(1);
|
|
480
756
|
}
|
|
481
757
|
const configPath = resolveConfigPath();
|
|
482
|
-
const raw =
|
|
483
|
-
const config =
|
|
758
|
+
const raw = fs11.existsSync(configPath) ? JSON.parse(fs11.readFileSync(configPath, "utf8")) : {};
|
|
759
|
+
const config = parseConfig11(resolveRemnicConfigRecord11(raw));
|
|
484
760
|
const memoryDir = expandTilde(
|
|
485
761
|
typeof memoryDirOverride === "string" && memoryDirOverride.length > 0 ? memoryDirOverride : config.memoryDir ?? resolveMemoryDir()
|
|
486
762
|
);
|
|
@@ -535,12 +811,12 @@ function formatProcedureMaintenanceText(report) {
|
|
|
535
811
|
}
|
|
536
812
|
|
|
537
813
|
// src/commands/drift.ts
|
|
538
|
-
import
|
|
814
|
+
import fs12 from "fs";
|
|
539
815
|
import {
|
|
540
|
-
Orchestrator as
|
|
816
|
+
Orchestrator as Orchestrator7,
|
|
541
817
|
initLogger as initLogger2,
|
|
542
|
-
parseConfig as
|
|
543
|
-
resolveRemnicConfigRecord as
|
|
818
|
+
parseConfig as parseConfig12,
|
|
819
|
+
resolveRemnicConfigRecord as resolveRemnicConfigRecord12,
|
|
544
820
|
runPreferenceDriftScan
|
|
545
821
|
} from "@remnic/core";
|
|
546
822
|
async function runDriftBinaryCommand(rest) {
|
|
@@ -600,13 +876,13 @@ Resolve a drifted item with the existing review surface:
|
|
|
600
876
|
process.exit(1);
|
|
601
877
|
}
|
|
602
878
|
const configPath = resolveConfigPath();
|
|
603
|
-
const raw =
|
|
604
|
-
const config =
|
|
879
|
+
const raw = fs12.existsSync(configPath) ? JSON.parse(fs12.readFileSync(configPath, "utf8")) : {};
|
|
880
|
+
const config = parseConfig12(resolveRemnicConfigRecord12(raw));
|
|
605
881
|
const memoryDirOverridden = typeof memoryDirOverride === "string" && memoryDirOverride.length > 0;
|
|
606
882
|
const memoryDir = expandTilde(
|
|
607
883
|
memoryDirOverridden ? memoryDirOverride : config.memoryDir ?? resolveMemoryDir()
|
|
608
884
|
);
|
|
609
|
-
const orchestrator = new
|
|
885
|
+
const orchestrator = new Orchestrator7(
|
|
610
886
|
memoryDirOverridden ? { ...config, memoryDir } : config
|
|
611
887
|
);
|
|
612
888
|
await orchestrator.initialize();
|
|
@@ -714,13 +990,13 @@ async function loadWecloneExportModule() {
|
|
|
714
990
|
}
|
|
715
991
|
|
|
716
992
|
// src/converge.ts
|
|
717
|
-
import * as
|
|
993
|
+
import * as fs14 from "fs";
|
|
718
994
|
import { createHash as createHash3 } from "crypto";
|
|
719
|
-
import * as
|
|
995
|
+
import * as path3 from "path";
|
|
720
996
|
import {
|
|
721
997
|
CONVERGE_CONFLICT_POLICIES,
|
|
722
998
|
DEFAULT_CONVERGE_CONFLICT_POLICY,
|
|
723
|
-
parseConfig as
|
|
999
|
+
parseConfig as parseConfig13,
|
|
724
1000
|
buildOfflineSyncSnapshotFromBase,
|
|
725
1001
|
applyOfflineSyncFileContentChunk,
|
|
726
1002
|
isInternalRemnicStatePath as isInternalRemnicStatePath3,
|
|
@@ -746,9 +1022,9 @@ import {
|
|
|
746
1022
|
|
|
747
1023
|
// src/offline-storage-io.ts
|
|
748
1024
|
import { createDecipheriv, createHash } from "crypto";
|
|
749
|
-
import
|
|
1025
|
+
import fs13 from "fs";
|
|
750
1026
|
import { lstat, mkdtemp, readdir, rm } from "fs/promises";
|
|
751
|
-
import
|
|
1027
|
+
import path2 from "path";
|
|
752
1028
|
import {
|
|
753
1029
|
OFFLINE_SYNC_FILE_CONTENT_TRANSFER_CHUNK_BYTES,
|
|
754
1030
|
StorageManager as StorageManager2,
|
|
@@ -775,10 +1051,10 @@ import {
|
|
|
775
1051
|
} from "@remnic/core/secure-store";
|
|
776
1052
|
var OFFLINE_SYNC_EXCLUSION_CONCURRENCY = 16;
|
|
777
1053
|
function resolveOfflineDirectHydrationPath(memoryDir, relPath) {
|
|
778
|
-
const base =
|
|
779
|
-
const target =
|
|
780
|
-
const relative =
|
|
781
|
-
if (relative === "" || relative === ".." || relative.startsWith(`..${
|
|
1054
|
+
const base = path2.resolve(memoryDir);
|
|
1055
|
+
const target = path2.resolve(base, relPath);
|
|
1056
|
+
const relative = path2.relative(base, target);
|
|
1057
|
+
if (relative === "" || relative === ".." || relative.startsWith(`..${path2.sep}`) || path2.isAbsolute(relative)) {
|
|
782
1058
|
throw new Error(`offline sync direct hydration path escapes memory dir: ${relPath}`);
|
|
783
1059
|
}
|
|
784
1060
|
return target;
|
|
@@ -812,13 +1088,13 @@ async function createConfiguredOfflineStorage(memoryDir, secureStoreEncryptOnWri
|
|
|
812
1088
|
return { storage, secureStoreKey, secureStoreRequired };
|
|
813
1089
|
}
|
|
814
1090
|
async function createOfflineStorageForPath(memoryDir, filePath, configured, secureStoreEncryptOnWrite) {
|
|
815
|
-
const memoryRoot =
|
|
816
|
-
const stateDir =
|
|
817
|
-
if (
|
|
1091
|
+
const memoryRoot = path2.resolve(memoryDir);
|
|
1092
|
+
const stateDir = path2.dirname(filePath);
|
|
1093
|
+
if (path2.basename(stateDir) !== "state" || path2.basename(filePath) !== "memory-lifecycle-ledger.jsonl") {
|
|
818
1094
|
throw new Error(`invalid lifecycle ledger path: ${filePath}`);
|
|
819
1095
|
}
|
|
820
|
-
const storageRoot =
|
|
821
|
-
if (storageRoot !== memoryRoot && !storageRoot.startsWith(`${memoryRoot}${
|
|
1096
|
+
const storageRoot = path2.resolve(path2.dirname(stateDir));
|
|
1097
|
+
if (storageRoot !== memoryRoot && !storageRoot.startsWith(`${memoryRoot}${path2.sep}`)) {
|
|
822
1098
|
throw new Error(`lifecycle ledger path is outside the offline memory directory: ${filePath}`);
|
|
823
1099
|
}
|
|
824
1100
|
const storage = new StorageManager2(storageRoot);
|
|
@@ -879,7 +1155,7 @@ async function cleanupOrphanedOfflineDecryptStaging(memoryDir) {
|
|
|
879
1155
|
const now = Date.now();
|
|
880
1156
|
for (const name of entries) {
|
|
881
1157
|
if (!name.startsWith(OFFLINE_DECRYPT_STAGING_DIR_PREFIX)) continue;
|
|
882
|
-
const dir =
|
|
1158
|
+
const dir = path2.join(memoryDir, name);
|
|
883
1159
|
try {
|
|
884
1160
|
const info = await lstat(dir);
|
|
885
1161
|
if (!info.isDirectory() || info.isSymbolicLink()) continue;
|
|
@@ -908,7 +1184,7 @@ async function* readOfflineSyncFileChunks(options) {
|
|
|
908
1184
|
});
|
|
909
1185
|
}
|
|
910
1186
|
async function readFilePrefix(filePath, length) {
|
|
911
|
-
const handle = await
|
|
1187
|
+
const handle = await fs13.promises.open(filePath, "r");
|
|
912
1188
|
try {
|
|
913
1189
|
const out = Buffer.alloc(length);
|
|
914
1190
|
const { bytesRead } = await handle.read(out, 0, length, 0);
|
|
@@ -918,7 +1194,7 @@ async function readFilePrefix(filePath, length) {
|
|
|
918
1194
|
}
|
|
919
1195
|
}
|
|
920
1196
|
async function* readPlainOfflineFileChunks(filePath, chunkSize) {
|
|
921
|
-
const stream =
|
|
1197
|
+
const stream = fs13.createReadStream(filePath, { highWaterMark: chunkSize });
|
|
922
1198
|
for await (const chunk of stream) {
|
|
923
1199
|
yield Buffer.isBuffer(chunk) ? chunk : Buffer.from(chunk);
|
|
924
1200
|
}
|
|
@@ -947,17 +1223,17 @@ async function* readEncryptedOfflineFileChunks(options) {
|
|
|
947
1223
|
const aadCandidates = offlineFileAadCandidates(options.filePath, options.memoryDir);
|
|
948
1224
|
let lastError;
|
|
949
1225
|
for (const aad of aadCandidates) {
|
|
950
|
-
const tempDir = await mkdtemp(
|
|
951
|
-
const tempPath =
|
|
1226
|
+
const tempDir = await mkdtemp(path2.join(options.memoryDir, OFFLINE_DECRYPT_STAGING_DIR_PREFIX));
|
|
1227
|
+
const tempPath = path2.join(tempDir, "content");
|
|
952
1228
|
try {
|
|
953
1229
|
const decipher = createDecipheriv("aes-256-gcm", options.key, iv, {
|
|
954
1230
|
authTagLength: AUTH_TAG_LENGTH
|
|
955
1231
|
});
|
|
956
1232
|
decipher.setAuthTag(authTag);
|
|
957
1233
|
decipher.setAAD(Buffer.concat([secureStoreEnvelopeHeaderAad(salt), aad]));
|
|
958
|
-
const output =
|
|
1234
|
+
const output = fs13.createWriteStream(tempPath, { mode: 384 });
|
|
959
1235
|
try {
|
|
960
|
-
const stream =
|
|
1236
|
+
const stream = fs13.createReadStream(options.filePath, {
|
|
961
1237
|
start: MAGIC_HEADER_SIZE + ENVELOPE_HEADER_SIZE,
|
|
962
1238
|
highWaterMark: options.chunkSize
|
|
963
1239
|
});
|
|
@@ -992,17 +1268,17 @@ async function* readEncryptedOfflineFileChunks(options) {
|
|
|
992
1268
|
}
|
|
993
1269
|
function offlineFileAadCandidates(filePath, memoryDir) {
|
|
994
1270
|
const candidates = [filePathAad(filePath, memoryDir)];
|
|
995
|
-
const relative =
|
|
996
|
-
if (!relative || relative.startsWith("..") ||
|
|
997
|
-
const parts = relative.split(
|
|
1271
|
+
const relative = path2.relative(memoryDir, filePath);
|
|
1272
|
+
if (!relative || relative.startsWith("..") || path2.isAbsolute(relative)) return candidates;
|
|
1273
|
+
const parts = relative.split(path2.sep);
|
|
998
1274
|
if (parts[0] === "namespaces" && parts.length >= 3 && parts[1]) {
|
|
999
|
-
candidates.push(filePathAad(filePath,
|
|
1275
|
+
candidates.push(filePathAad(filePath, path2.join(memoryDir, "namespaces", parts[1])));
|
|
1000
1276
|
}
|
|
1001
|
-
const memoryParts =
|
|
1277
|
+
const memoryParts = path2.resolve(memoryDir).split(path2.sep);
|
|
1002
1278
|
if (memoryParts.length >= 3 && memoryParts.at(-2) === "namespaces" && memoryParts.at(-1)) {
|
|
1003
|
-
const topLevelRoot = memoryParts.slice(0, -2).join(
|
|
1004
|
-
const topRelative =
|
|
1005
|
-
if (topRelative && !topRelative.startsWith("..") && !
|
|
1279
|
+
const topLevelRoot = memoryParts.slice(0, -2).join(path2.sep) || path2.sep;
|
|
1280
|
+
const topRelative = path2.relative(topLevelRoot, filePath);
|
|
1281
|
+
if (topRelative && !topRelative.startsWith("..") && !path2.isAbsolute(topRelative) && topRelative.split(path2.sep)[0] === "namespaces" && topRelative.split(path2.sep)[1] === memoryParts.at(-1)) {
|
|
1006
1282
|
candidates.push(filePathAad(filePath, topLevelRoot));
|
|
1007
1283
|
}
|
|
1008
1284
|
}
|
|
@@ -1567,7 +1843,7 @@ async function readLocalTombstoneEvidence(rootDir) {
|
|
|
1567
1843
|
for (const relativePath of TOMBSTONE_PATHS) {
|
|
1568
1844
|
let content;
|
|
1569
1845
|
try {
|
|
1570
|
-
content = await
|
|
1846
|
+
content = await fs14.promises.readFile(path3.join(rootDir, relativePath), "utf-8");
|
|
1571
1847
|
} catch (error) {
|
|
1572
1848
|
if (error.code === "ENOENT") continue;
|
|
1573
1849
|
throw error;
|
|
@@ -1579,10 +1855,10 @@ async function readLocalTombstoneEvidence(rootDir) {
|
|
|
1579
1855
|
return merged;
|
|
1580
1856
|
}
|
|
1581
1857
|
async function discoverCursorNamespaces(memoryDir, peerUrl) {
|
|
1582
|
-
const cursorDir =
|
|
1858
|
+
const cursorDir = path3.join(path3.resolve(memoryDir), ".remnic", "state", "converge-cursors");
|
|
1583
1859
|
let entries;
|
|
1584
1860
|
try {
|
|
1585
|
-
entries = await
|
|
1861
|
+
entries = await fs14.promises.readdir(cursorDir, { withFileTypes: true });
|
|
1586
1862
|
} catch (error) {
|
|
1587
1863
|
if (error.code === "ENOENT") return [];
|
|
1588
1864
|
throw error;
|
|
@@ -1590,9 +1866,9 @@ async function discoverCursorNamespaces(memoryDir, peerUrl) {
|
|
|
1590
1866
|
const namespaces = /* @__PURE__ */ new Set();
|
|
1591
1867
|
for (const entry of entries) {
|
|
1592
1868
|
if (!entry.isFile() || !entry.name.endsWith(".json")) continue;
|
|
1593
|
-
const cursor = await readConvergeCursor(
|
|
1869
|
+
const cursor = await readConvergeCursor(path3.join(cursorDir, entry.name));
|
|
1594
1870
|
if (!cursor) throw new Error(`invalid converge cursor: ${entry.name}`);
|
|
1595
|
-
if (
|
|
1871
|
+
if (path3.basename(defaultConvergeCursorPath(memoryDir, peerUrl, cursor.namespace)) !== entry.name) continue;
|
|
1596
1872
|
namespaces.add(cursor.namespace);
|
|
1597
1873
|
}
|
|
1598
1874
|
return [...namespaces].sort();
|
|
@@ -1658,7 +1934,7 @@ async function computeConvergePlan(options = {}) {
|
|
|
1658
1934
|
let config = options.config;
|
|
1659
1935
|
if (!config) {
|
|
1660
1936
|
try {
|
|
1661
|
-
config =
|
|
1937
|
+
config = parseConfig13({});
|
|
1662
1938
|
} catch {
|
|
1663
1939
|
}
|
|
1664
1940
|
}
|
|
@@ -1704,7 +1980,7 @@ async function computeConvergePlan(options = {}) {
|
|
|
1704
1980
|
return await readFile3({
|
|
1705
1981
|
root: rootInfo.rootDir,
|
|
1706
1982
|
path: file.path,
|
|
1707
|
-
filePath:
|
|
1983
|
+
filePath: path3.join(rootInfo.rootDir, file.path)
|
|
1708
1984
|
});
|
|
1709
1985
|
} catch (error) {
|
|
1710
1986
|
manifestReadFailed = true;
|
|
@@ -1909,7 +2185,7 @@ async function executeConvergeApply(options = {}) {
|
|
|
1909
2185
|
let config = options.config;
|
|
1910
2186
|
if (!config) {
|
|
1911
2187
|
try {
|
|
1912
|
-
config =
|
|
2188
|
+
config = parseConfig13({});
|
|
1913
2189
|
} catch {
|
|
1914
2190
|
}
|
|
1915
2191
|
}
|
|
@@ -2066,13 +2342,13 @@ async function executeConvergeApply(options = {}) {
|
|
|
2066
2342
|
const rootDir = rootMap.get(entry.namespace);
|
|
2067
2343
|
if (rootDir) {
|
|
2068
2344
|
try {
|
|
2069
|
-
const filePath =
|
|
2345
|
+
const filePath = path3.join(rootDir, localPath);
|
|
2070
2346
|
const io = await createOfflineStorageIo(rootDir);
|
|
2071
2347
|
const current = await io.readFileDigest({ root: rootDir, path: localPath, filePath });
|
|
2072
2348
|
if (current.sha256 !== entry.localSha256) {
|
|
2073
2349
|
throw new Error(`local file changed during push: ${localPath}`);
|
|
2074
2350
|
}
|
|
2075
|
-
const stat2 = await
|
|
2351
|
+
const stat2 = await fs14.promises.stat(filePath);
|
|
2076
2352
|
let chunks;
|
|
2077
2353
|
let chunkOffset = 0;
|
|
2078
2354
|
const resetChunks = async () => {
|
|
@@ -2163,7 +2439,7 @@ async function executeConvergeApply(options = {}) {
|
|
|
2163
2439
|
if (rootDir && entry.localSha256) {
|
|
2164
2440
|
try {
|
|
2165
2441
|
const io = await createOfflineStorageIo(rootDir);
|
|
2166
|
-
const filePath =
|
|
2442
|
+
const filePath = path3.join(rootDir, localPath);
|
|
2167
2443
|
const current = await io.readFileDigest({ root: rootDir, path: localPath, filePath });
|
|
2168
2444
|
if (current.sha256 === entry.localSha256) {
|
|
2169
2445
|
await io.deleteFile({ root: rootDir, path: localPath, filePath });
|
|
@@ -2216,7 +2492,7 @@ async function executeConvergeApply(options = {}) {
|
|
|
2216
2492
|
if (rootDir) {
|
|
2217
2493
|
try {
|
|
2218
2494
|
const io = await createOfflineStorageIo(rootDir);
|
|
2219
|
-
const filePath =
|
|
2495
|
+
const filePath = path3.join(rootDir, localPath);
|
|
2220
2496
|
const current = await io.readFileDigest({ root: rootDir, path: localPath, filePath });
|
|
2221
2497
|
if (current.sha256 === entry.localSha256) {
|
|
2222
2498
|
await io.deleteFile({ root: rootDir, path: localPath, filePath });
|
|
@@ -2349,7 +2625,7 @@ function formatConvergeApplyReport(result) {
|
|
|
2349
2625
|
lines.push(formatConvergeReport(result.plan));
|
|
2350
2626
|
return lines.join("\n");
|
|
2351
2627
|
}
|
|
2352
|
-
async function cmdConverge(action, rest, json, config =
|
|
2628
|
+
async function cmdConverge(action, rest, json, config = parseConfig13({})) {
|
|
2353
2629
|
if (action === "help" || action === "--help" || action === "-h" || rest.includes("--help") || rest.includes("-h")) {
|
|
2354
2630
|
console.log(`Usage: remnic converge <plan|apply> [options]
|
|
2355
2631
|
|
|
@@ -2555,8 +2831,8 @@ function renderReplayResult(result, targetNamespace, format) {
|
|
|
2555
2831
|
}
|
|
2556
2832
|
|
|
2557
2833
|
// src/quarantine-replay.ts
|
|
2558
|
-
import * as
|
|
2559
|
-
import { EngramAccessService, Orchestrator as
|
|
2834
|
+
import * as fs15 from "fs";
|
|
2835
|
+
import { EngramAccessService, Orchestrator as Orchestrator8, initLogger as initLogger3, parseConfig as parseConfig14, resolveRemnicConfigRecord as resolveRemnicConfigRecord13 } from "@remnic/core";
|
|
2560
2836
|
import { WriteQuarantineStore } from "@remnic/core/write-quarantine.js";
|
|
2561
2837
|
function valueFlag(args, flag) {
|
|
2562
2838
|
const occurrences = args.filter((a) => a === flag).length;
|
|
@@ -2604,9 +2880,9 @@ async function runQuarantineReplay(rest, format, resolveConfigPath2) {
|
|
|
2604
2880
|
let orchestrator;
|
|
2605
2881
|
try {
|
|
2606
2882
|
const configPath = resolveConfigPath2();
|
|
2607
|
-
const raw =
|
|
2608
|
-
const config =
|
|
2609
|
-
orchestrator = new
|
|
2883
|
+
const raw = fs15.existsSync(configPath) ? JSON.parse(fs15.readFileSync(configPath, "utf8")) : {};
|
|
2884
|
+
const config = parseConfig14(resolveRemnicConfigRecord13(raw));
|
|
2885
|
+
orchestrator = new Orchestrator8(config);
|
|
2610
2886
|
await orchestrator.initialize();
|
|
2611
2887
|
await orchestrator.deferredReady;
|
|
2612
2888
|
const service = new EngramAccessService(orchestrator);
|
|
@@ -2636,15 +2912,15 @@ async function runQuarantineReplay(rest, format, resolveConfigPath2) {
|
|
|
2636
2912
|
}
|
|
2637
2913
|
|
|
2638
2914
|
// src/offline-impression-rotation.ts
|
|
2639
|
-
import
|
|
2640
|
-
import { parseConfig as
|
|
2915
|
+
import fs16 from "fs";
|
|
2916
|
+
import { parseConfig as parseConfig15, resolveRemnicConfigRecord as resolveRemnicConfigRecord14, drainPendingImpressionsForOfflineSync } from "@remnic/core";
|
|
2641
2917
|
import { LastRecallStore } from "@remnic/core/recall-state";
|
|
2642
2918
|
function parseConfigQuietly(raw) {
|
|
2643
2919
|
const originalWarn = console.warn;
|
|
2644
2920
|
console.warn = () => {
|
|
2645
2921
|
};
|
|
2646
2922
|
try {
|
|
2647
|
-
return
|
|
2923
|
+
return parseConfig15(resolveRemnicConfigRecord14(raw));
|
|
2648
2924
|
} finally {
|
|
2649
2925
|
console.warn = originalWarn;
|
|
2650
2926
|
}
|
|
@@ -2658,7 +2934,7 @@ var OFFLINE_CONFIG_KEYS = [
|
|
|
2658
2934
|
function pickOfflineConfigRecord(raw) {
|
|
2659
2935
|
let resolved;
|
|
2660
2936
|
try {
|
|
2661
|
-
resolved =
|
|
2937
|
+
resolved = resolveRemnicConfigRecord14(raw);
|
|
2662
2938
|
} catch {
|
|
2663
2939
|
resolved = raw && typeof raw === "object" && !Array.isArray(raw) ? raw : {};
|
|
2664
2940
|
}
|
|
@@ -2671,7 +2947,7 @@ function pickOfflineConfigRecord(raw) {
|
|
|
2671
2947
|
function resolveOfflineImpressionRotation(configPath) {
|
|
2672
2948
|
let raw;
|
|
2673
2949
|
try {
|
|
2674
|
-
raw =
|
|
2950
|
+
raw = fs16.existsSync(configPath) ? JSON.parse(fs16.readFileSync(configPath, "utf8")) : {};
|
|
2675
2951
|
} catch {
|
|
2676
2952
|
throw new Error(
|
|
2677
2953
|
`cannot read recall-impression rotation from ${configPath}: config file could not be read as JSON`
|
|
@@ -2707,15 +2983,15 @@ import {
|
|
|
2707
2983
|
readFileSync as readFileSync2,
|
|
2708
2984
|
statSync
|
|
2709
2985
|
} from "fs";
|
|
2710
|
-
import
|
|
2986
|
+
import path4 from "path";
|
|
2711
2987
|
import { fileURLToPath } from "url";
|
|
2712
2988
|
var STALE_BUILD_TOLERANCE_MS = 1e3;
|
|
2713
2989
|
function assertLocalBenchBuildFreshForDevelopment(currentModuleUrl) {
|
|
2714
2990
|
if (isTruthyEnv(process.env.REMNIC_BENCH_ALLOW_STALE_DIST)) {
|
|
2715
2991
|
return;
|
|
2716
2992
|
}
|
|
2717
|
-
const currentDir =
|
|
2718
|
-
const benchPackageDir =
|
|
2993
|
+
const currentDir = path4.dirname(fileURLToPath(currentModuleUrl));
|
|
2994
|
+
const benchPackageDir = path4.resolve(currentDir, "../../bench");
|
|
2719
2995
|
const freshness = checkBenchBuildFreshness(benchPackageDir);
|
|
2720
2996
|
if (!freshness.stale) {
|
|
2721
2997
|
return;
|
|
@@ -2732,7 +3008,7 @@ function assertLocalBenchBuildFreshForDevelopment(currentModuleUrl) {
|
|
|
2732
3008
|
);
|
|
2733
3009
|
}
|
|
2734
3010
|
function checkBenchBuildFreshness(benchPackageDir) {
|
|
2735
|
-
const packageJsonPath =
|
|
3011
|
+
const packageJsonPath = path4.join(benchPackageDir, "package.json");
|
|
2736
3012
|
if (!existsSync2(packageJsonPath)) {
|
|
2737
3013
|
return { stale: false };
|
|
2738
3014
|
}
|
|
@@ -2745,17 +3021,17 @@ function checkBenchBuildFreshness(benchPackageDir) {
|
|
|
2745
3021
|
if (packageName !== "@remnic/bench") {
|
|
2746
3022
|
return { stale: false };
|
|
2747
3023
|
}
|
|
2748
|
-
const srcDir =
|
|
3024
|
+
const srcDir = path4.join(benchPackageDir, "src");
|
|
2749
3025
|
if (!isDirectory(srcDir)) {
|
|
2750
3026
|
return { stale: false };
|
|
2751
3027
|
}
|
|
2752
3028
|
const sourceRoots = [
|
|
2753
3029
|
srcDir,
|
|
2754
3030
|
packageJsonPath,
|
|
2755
|
-
|
|
2756
|
-
|
|
3031
|
+
path4.join(benchPackageDir, "tsup.config.ts"),
|
|
3032
|
+
path4.join(benchPackageDir, "tsconfig.json")
|
|
2757
3033
|
];
|
|
2758
|
-
const distPath =
|
|
3034
|
+
const distPath = path4.join(benchPackageDir, "dist", "index.js");
|
|
2759
3035
|
if (!existsSync2(distPath)) {
|
|
2760
3036
|
return {
|
|
2761
3037
|
stale: true,
|
|
@@ -2798,7 +3074,7 @@ function newestMtime(roots) {
|
|
|
2798
3074
|
}
|
|
2799
3075
|
if (stat2.isDirectory()) {
|
|
2800
3076
|
for (const child of readdirSync(entryPath)) {
|
|
2801
|
-
visit(
|
|
3077
|
+
visit(path4.join(entryPath, child));
|
|
2802
3078
|
}
|
|
2803
3079
|
return;
|
|
2804
3080
|
}
|
|
@@ -2831,18 +3107,18 @@ function isTruthyEnv(value) {
|
|
|
2831
3107
|
|
|
2832
3108
|
// src/optional-bench.ts
|
|
2833
3109
|
import { existsSync as existsSync3 } from "fs";
|
|
2834
|
-
import
|
|
3110
|
+
import path5 from "path";
|
|
2835
3111
|
import { fileURLToPath as fileURLToPath2, pathToFileURL } from "url";
|
|
2836
3112
|
var SPECIFIER2 = "@remnic/bench";
|
|
2837
3113
|
var TSX_ESM_API_SPECIFIER = "tsx/esm/api";
|
|
2838
3114
|
var cached2;
|
|
2839
3115
|
var cachedFromLocalWorkspaceBenchSource = false;
|
|
2840
3116
|
function resolveLocalWorkspaceBenchPaths() {
|
|
2841
|
-
const currentDir =
|
|
2842
|
-
const benchPackageDir =
|
|
3117
|
+
const currentDir = path5.dirname(fileURLToPath2(import.meta.url));
|
|
3118
|
+
const benchPackageDir = path5.resolve(currentDir, "../../bench");
|
|
2843
3119
|
return {
|
|
2844
|
-
distEntry:
|
|
2845
|
-
sourceEntry:
|
|
3120
|
+
distEntry: path5.join(benchPackageDir, "dist", "index.js"),
|
|
3121
|
+
sourceEntry: path5.join(benchPackageDir, "src", "index.ts")
|
|
2846
3122
|
};
|
|
2847
3123
|
}
|
|
2848
3124
|
async function tryImportLocalWorkspaceBenchSource(err) {
|
|
@@ -2929,12 +3205,12 @@ function assertBenchModuleFreshForDevelopment() {
|
|
|
2929
3205
|
}
|
|
2930
3206
|
|
|
2931
3207
|
// src/cmd-security.ts
|
|
2932
|
-
import
|
|
3208
|
+
import fs17 from "fs";
|
|
2933
3209
|
import {
|
|
2934
|
-
Orchestrator as
|
|
2935
|
-
parseConfig as
|
|
3210
|
+
Orchestrator as Orchestrator9,
|
|
3211
|
+
parseConfig as parseConfig16,
|
|
2936
3212
|
initLogger as initLogger4,
|
|
2937
|
-
resolveRemnicConfigRecord as
|
|
3213
|
+
resolveRemnicConfigRecord as resolveRemnicConfigRecord15,
|
|
2938
3214
|
runAuditMemoryCliCommand,
|
|
2939
3215
|
formatAuditMemoryReport
|
|
2940
3216
|
} from "@remnic/core";
|
|
@@ -2949,9 +3225,9 @@ async function cmdSecurity(rest) {
|
|
|
2949
3225
|
}
|
|
2950
3226
|
initLogger4();
|
|
2951
3227
|
const configPath = resolveConfigPath();
|
|
2952
|
-
const raw =
|
|
2953
|
-
const config =
|
|
2954
|
-
const orchestrator = new
|
|
3228
|
+
const raw = fs17.existsSync(configPath) ? JSON.parse(fs17.readFileSync(configPath, "utf8")) : {};
|
|
3229
|
+
const config = parseConfig16(resolveRemnicConfigRecord15(raw));
|
|
3230
|
+
const orchestrator = new Orchestrator9(config);
|
|
2955
3231
|
await orchestrator.initialize();
|
|
2956
3232
|
try {
|
|
2957
3233
|
const sinceFlag = rest.indexOf("--since");
|
|
@@ -2974,8 +3250,8 @@ async function cmdSecurity(rest) {
|
|
|
2974
3250
|
}
|
|
2975
3251
|
|
|
2976
3252
|
// src/daemon-service-candidates.ts
|
|
2977
|
-
import
|
|
2978
|
-
import
|
|
3253
|
+
import fs18 from "fs";
|
|
3254
|
+
import path6 from "path";
|
|
2979
3255
|
var LAUNCHD_LABEL = "ai.remnic.daemon";
|
|
2980
3256
|
var LEGACY_REMNIC_SERVER_LAUNCHD_LABEL = "ai.remnic.server";
|
|
2981
3257
|
var LEGACY_LAUNCHD_LABEL = "ai.engram.daemon";
|
|
@@ -2988,15 +3264,15 @@ var SYSTEMD_SERVICE = "remnic.service";
|
|
|
2988
3264
|
var LEGACY_SYSTEMD_SERVICE = "engram.service";
|
|
2989
3265
|
var SYSTEMD_SERVICE_CANDIDATES = [SYSTEMD_SERVICE, LEGACY_SYSTEMD_SERVICE];
|
|
2990
3266
|
function launchdPlistPaths(homeDir) {
|
|
2991
|
-
return LAUNCHD_LABEL_CANDIDATES.map((label) =>
|
|
3267
|
+
return LAUNCHD_LABEL_CANDIDATES.map((label) => path6.join(homeDir, "Library", "LaunchAgents", `${label}.plist`));
|
|
2992
3268
|
}
|
|
2993
3269
|
function systemdUnitPaths(homeDir) {
|
|
2994
|
-
return SYSTEMD_SERVICE_CANDIDATES.map((service) =>
|
|
3270
|
+
return SYSTEMD_SERVICE_CANDIDATES.map((service) => path6.join(homeDir, ".config", "systemd", "user", service));
|
|
2995
3271
|
}
|
|
2996
3272
|
function anyFileExists(paths) {
|
|
2997
3273
|
return paths.some((candidate) => {
|
|
2998
3274
|
try {
|
|
2999
|
-
return
|
|
3275
|
+
return fs18.statSync(candidate).isFile();
|
|
3000
3276
|
} catch {
|
|
3001
3277
|
return false;
|
|
3002
3278
|
}
|
|
@@ -3008,7 +3284,7 @@ function commandNames(command) {
|
|
|
3008
3284
|
}
|
|
3009
3285
|
function isRunnableNodeScript(filePath) {
|
|
3010
3286
|
try {
|
|
3011
|
-
const text =
|
|
3287
|
+
const text = fs18.readFileSync(filePath, "utf8").slice(0, 4096);
|
|
3012
3288
|
const firstLine = text.split(/\r?\n/, 1)[0] ?? "";
|
|
3013
3289
|
if (/^#!.*\bnode\b/.test(firstLine)) return true;
|
|
3014
3290
|
if (firstLine.startsWith("#!")) return false;
|
|
@@ -3021,20 +3297,20 @@ function isRunnableNodeScript(filePath) {
|
|
|
3021
3297
|
function resolveShimNodeScript(filePath) {
|
|
3022
3298
|
let text;
|
|
3023
3299
|
try {
|
|
3024
|
-
text =
|
|
3300
|
+
text = fs18.readFileSync(filePath, "utf8").slice(0, 16384);
|
|
3025
3301
|
} catch {
|
|
3026
3302
|
return void 0;
|
|
3027
3303
|
}
|
|
3028
|
-
const basedir =
|
|
3304
|
+
const basedir = path6.dirname(filePath);
|
|
3029
3305
|
const jsReferencePattern = /"([^"]+\.js)"|'([^']+\.js)'|([^\s"'`]+\.js)/g;
|
|
3030
3306
|
for (const match of text.matchAll(jsReferencePattern)) {
|
|
3031
3307
|
const raw = match[1] ?? match[2] ?? match[3];
|
|
3032
3308
|
if (!raw) continue;
|
|
3033
3309
|
const candidate = raw.replaceAll("${basedir}", basedir).replaceAll("$basedir", basedir).replaceAll("\\ ", " ");
|
|
3034
|
-
const resolved =
|
|
3310
|
+
const resolved = path6.isAbsolute(candidate) ? candidate : path6.resolve(basedir, candidate);
|
|
3035
3311
|
try {
|
|
3036
|
-
if (
|
|
3037
|
-
return
|
|
3312
|
+
if (fs18.statSync(resolved).isFile() && isRunnableNodeScript(resolved)) {
|
|
3313
|
+
return fs18.realpathSync(resolved);
|
|
3038
3314
|
}
|
|
3039
3315
|
} catch {
|
|
3040
3316
|
}
|
|
@@ -3042,19 +3318,19 @@ function resolveShimNodeScript(filePath) {
|
|
|
3042
3318
|
return void 0;
|
|
3043
3319
|
}
|
|
3044
3320
|
function resolveRunnableNodeScript(filePath) {
|
|
3045
|
-
const realPath =
|
|
3321
|
+
const realPath = fs18.realpathSync(filePath);
|
|
3046
3322
|
if (isRunnableNodeScript(realPath)) return realPath;
|
|
3047
3323
|
return resolveShimNodeScript(realPath);
|
|
3048
3324
|
}
|
|
3049
3325
|
function findCommandOnPath(command, pathEnv = process.env.PATH ?? "") {
|
|
3050
|
-
for (const dir of pathEnv.split(
|
|
3326
|
+
for (const dir of pathEnv.split(path6.delimiter)) {
|
|
3051
3327
|
if (!dir) continue;
|
|
3052
3328
|
for (const name of commandNames(command)) {
|
|
3053
|
-
const candidate =
|
|
3329
|
+
const candidate = path6.join(dir, name);
|
|
3054
3330
|
try {
|
|
3055
|
-
const stat2 =
|
|
3331
|
+
const stat2 = fs18.statSync(candidate);
|
|
3056
3332
|
if (!stat2.isFile()) continue;
|
|
3057
|
-
if (process.platform !== "win32")
|
|
3333
|
+
if (process.platform !== "win32") fs18.accessSync(candidate, fs18.constants.X_OK);
|
|
3058
3334
|
const runnable = resolveRunnableNodeScript(candidate);
|
|
3059
3335
|
if (runnable) return runnable;
|
|
3060
3336
|
} catch {
|
|
@@ -3064,11 +3340,11 @@ function findCommandOnPath(command, pathEnv = process.env.PATH ?? "") {
|
|
|
3064
3340
|
return void 0;
|
|
3065
3341
|
}
|
|
3066
3342
|
function serverBinWrapperRequiredPath(candidate) {
|
|
3067
|
-
const filename =
|
|
3343
|
+
const filename = path6.basename(candidate);
|
|
3068
3344
|
if (filename !== "remnic-server.js" && filename !== "engram-server.js") return void 0;
|
|
3069
|
-
const binDir =
|
|
3070
|
-
if (
|
|
3071
|
-
return
|
|
3345
|
+
const binDir = path6.dirname(candidate);
|
|
3346
|
+
if (path6.basename(binDir) !== "bin") return void 0;
|
|
3347
|
+
return path6.join(path6.dirname(binDir), "dist", "index.js");
|
|
3072
3348
|
}
|
|
3073
3349
|
|
|
3074
3350
|
// src/service-candidates.ts
|
|
@@ -3090,7 +3366,7 @@ function firstSuccessfulCandidate(candidates, attempt) {
|
|
|
3090
3366
|
}
|
|
3091
3367
|
|
|
3092
3368
|
// src/bench-args.ts
|
|
3093
|
-
import
|
|
3369
|
+
import path8 from "path";
|
|
3094
3370
|
|
|
3095
3371
|
// src/bench-flags.ts
|
|
3096
3372
|
function readBenchOptionValue(argv, flag) {
|
|
@@ -3455,7 +3731,7 @@ function collectBenchmarks(argv) {
|
|
|
3455
3731
|
}
|
|
3456
3732
|
|
|
3457
3733
|
// src/bench-args-research.ts
|
|
3458
|
-
import
|
|
3734
|
+
import path7 from "path";
|
|
3459
3735
|
function readPositiveInteger(args, flag) {
|
|
3460
3736
|
const raw = readBenchOptionValue(args, flag);
|
|
3461
3737
|
if (raw === void 0) return void 0;
|
|
@@ -3501,7 +3777,7 @@ function parseBenchResearchArgs(action, args) {
|
|
|
3501
3777
|
}
|
|
3502
3778
|
const outRaw = readBenchOptionValue(args, "--out");
|
|
3503
3779
|
if (outRaw !== void 0) {
|
|
3504
|
-
out =
|
|
3780
|
+
out = path7.resolve(expandTilde(outRaw));
|
|
3505
3781
|
}
|
|
3506
3782
|
}
|
|
3507
3783
|
const epochs = readPositiveInteger(args, "--epochs");
|
|
@@ -3515,8 +3791,8 @@ function parseBenchResearchArgs(action, args) {
|
|
|
3515
3791
|
}
|
|
3516
3792
|
return {
|
|
3517
3793
|
runRef,
|
|
3518
|
-
memoryDir: memoryDirRaw ?
|
|
3519
|
-
qmdPath: qmdPathRaw ?
|
|
3794
|
+
memoryDir: memoryDirRaw ? path7.resolve(expandTilde(memoryDirRaw)) : void 0,
|
|
3795
|
+
qmdPath: qmdPathRaw ? path7.resolve(expandTilde(qmdPathRaw)) : void 0,
|
|
3520
3796
|
collection,
|
|
3521
3797
|
users: readPositiveInteger(args, "--users"),
|
|
3522
3798
|
epochs,
|
|
@@ -3736,7 +4012,7 @@ function parseBenchArgs(argv) {
|
|
|
3736
4012
|
}
|
|
3737
4013
|
validateBenchFlags(action, args);
|
|
3738
4014
|
const driftGenPositionals = action === "drift-gen" && driftGenAction === "validate" ? collectBenchmarks(args.slice(1)) : [];
|
|
3739
|
-
const driftGenDir = driftGenPositionals[0] ?
|
|
4015
|
+
const driftGenDir = driftGenPositionals[0] ? path8.resolve(expandTilde(driftGenPositionals[0])) : void 0;
|
|
3740
4016
|
const benchmarkArgs = action === "baseline" || action === "datasets" || action === "providers" || action === "runs" || action === "drift-gen" && (args[0] === "validate" || args[0] === "generate") ? args.slice(1) : args;
|
|
3741
4017
|
const benchmarks = collectBenchmarks(benchmarkArgs);
|
|
3742
4018
|
const datasetDir = readBenchOptionValue(args, "--dataset-dir") ?? readBenchOptionValue(args, "--dataset");
|
|
@@ -4286,13 +4562,13 @@ function parseBenchArgs(argv) {
|
|
|
4286
4562
|
mcpUrl,
|
|
4287
4563
|
mcpToolMap,
|
|
4288
4564
|
mcpDemo,
|
|
4289
|
-
datasetDir: datasetDir ?
|
|
4290
|
-
resultsDir: resultsDir ?
|
|
4291
|
-
baselinesDir: baselinesDir ?
|
|
4565
|
+
datasetDir: datasetDir ? path8.resolve(expandTilde(datasetDir)) : void 0,
|
|
4566
|
+
resultsDir: resultsDir ? path8.resolve(expandTilde(resultsDir)) : void 0,
|
|
4567
|
+
baselinesDir: baselinesDir ? path8.resolve(expandTilde(baselinesDir)) : void 0,
|
|
4292
4568
|
runtimeProfile,
|
|
4293
4569
|
matrixProfiles,
|
|
4294
|
-
remnicConfigPath: remnicConfigRaw ?
|
|
4295
|
-
openclawConfigPath: openclawConfigRaw ?
|
|
4570
|
+
remnicConfigPath: remnicConfigRaw ? path8.resolve(expandTilde(remnicConfigRaw)) : void 0,
|
|
4571
|
+
openclawConfigPath: openclawConfigRaw ? path8.resolve(expandTilde(openclawConfigRaw)) : void 0,
|
|
4296
4572
|
modelSource,
|
|
4297
4573
|
gatewayAgentId,
|
|
4298
4574
|
fastGatewayAgentId,
|
|
@@ -4315,13 +4591,13 @@ function parseBenchArgs(argv) {
|
|
|
4315
4591
|
internalDisableThinking: args.includes("--internal-disable-thinking"),
|
|
4316
4592
|
internalCodexReasoningEffort,
|
|
4317
4593
|
threshold,
|
|
4318
|
-
custom: customRaw ?
|
|
4594
|
+
custom: customRaw ? path8.resolve(expandTilde(customRaw)) : void 0,
|
|
4319
4595
|
baselineAction,
|
|
4320
4596
|
datasetAction,
|
|
4321
4597
|
providerAction,
|
|
4322
4598
|
runAction,
|
|
4323
4599
|
format,
|
|
4324
|
-
output: output ?
|
|
4600
|
+
output: output ? path8.resolve(expandTilde(output)) : void 0,
|
|
4325
4601
|
target,
|
|
4326
4602
|
publishedName,
|
|
4327
4603
|
publishedSeed,
|
|
@@ -4331,24 +4607,24 @@ function parseBenchArgs(argv) {
|
|
|
4331
4607
|
publishedIngestConcurrency,
|
|
4332
4608
|
publishedTaskFilter,
|
|
4333
4609
|
memcorrectAdapter,
|
|
4334
|
-
publishedOut: publishedOutRaw ?
|
|
4610
|
+
publishedOut: publishedOutRaw ? path8.resolve(expandTilde(publishedOutRaw)) : void 0,
|
|
4335
4611
|
publishedDryRun: args.includes("--dry-run"),
|
|
4336
4612
|
requestTimeout,
|
|
4337
4613
|
localJudgeRequestTimeout,
|
|
4338
4614
|
frontierJudgeRequestTimeout,
|
|
4339
|
-
calibrationDir: calibrationDirRaw ?
|
|
4615
|
+
calibrationDir: calibrationDirRaw ? path8.resolve(expandTilde(calibrationDirRaw)) : void 0,
|
|
4340
4616
|
calibrationLocalConfigSha256,
|
|
4341
4617
|
calibrationFrontierConfigSha256,
|
|
4342
4618
|
sourceResultId,
|
|
4343
4619
|
expectedAnswerSetSha256,
|
|
4344
4620
|
expectedQuestionIdListSha256,
|
|
4345
|
-
taskIdsFile: taskIdsFileRaw ?
|
|
4621
|
+
taskIdsFile: taskIdsFileRaw ? path8.resolve(expandTilde(taskIdsFileRaw)) : void 0,
|
|
4346
4622
|
expectedTaskIdListSha256,
|
|
4347
4623
|
drainTimeout,
|
|
4348
4624
|
// Issue #1573 PR1: surface judge-cache flags into the runner options.
|
|
4349
4625
|
noJudgeCache: args.includes("--no-judge-cache"),
|
|
4350
|
-
judgeCacheDir: judgeCacheDirRaw ?
|
|
4351
|
-
localLabManifestPath: localLabManifestRaw ?
|
|
4626
|
+
judgeCacheDir: judgeCacheDirRaw ? path8.resolve(expandTilde(judgeCacheDirRaw)) : void 0,
|
|
4627
|
+
localLabManifestPath: localLabManifestRaw ? path8.resolve(expandTilde(localLabManifestRaw)) : void 0,
|
|
4352
4628
|
max429WaitMs,
|
|
4353
4629
|
disableThinking: args.includes("--disable-thinking"),
|
|
4354
4630
|
amaBenchJudgeProtocol,
|
|
@@ -4386,9 +4662,9 @@ function assertCalibrationProvenanceMatches(binding, state, benchmarkId) {
|
|
|
4386
4662
|
|
|
4387
4663
|
// src/bench-status.ts
|
|
4388
4664
|
import { mkdir, readFile, readdir as readdir2, rename, writeFile } from "fs/promises";
|
|
4389
|
-
import
|
|
4665
|
+
import path9 from "path";
|
|
4390
4666
|
function createBenchStatusPath(resultsDir, pid, startedAtMs = Date.now()) {
|
|
4391
|
-
return
|
|
4667
|
+
return path9.join(resultsDir, `bench-status-${startedAtMs}-${pid}.json`);
|
|
4392
4668
|
}
|
|
4393
4669
|
var BENCH_STATUS_FILENAME = /^bench-status-\d+-\d+\.json$/;
|
|
4394
4670
|
var VALID_BENCH_ENTRY_STATUSES = /* @__PURE__ */ new Set(["pending", "running", "complete", "failed"]);
|
|
@@ -4401,7 +4677,7 @@ async function findLatestBenchStatusFile(resultsDir) {
|
|
|
4401
4677
|
}
|
|
4402
4678
|
const candidates = entries.filter((name) => BENCH_STATUS_FILENAME.test(name)).sort().reverse();
|
|
4403
4679
|
for (const name of candidates) {
|
|
4404
|
-
const filePath =
|
|
4680
|
+
const filePath = path9.join(resultsDir, name);
|
|
4405
4681
|
const status = await readBenchStatus(filePath);
|
|
4406
4682
|
if (status) {
|
|
4407
4683
|
return filePath;
|
|
@@ -4410,7 +4686,7 @@ async function findLatestBenchStatusFile(resultsDir) {
|
|
|
4410
4686
|
return null;
|
|
4411
4687
|
}
|
|
4412
4688
|
async function atomicWriteJSON(filePath, data) {
|
|
4413
|
-
await mkdir(
|
|
4689
|
+
await mkdir(path9.dirname(filePath), { recursive: true });
|
|
4414
4690
|
const tmp = `${filePath}.${Date.now()}-${Math.random().toString(36).slice(2)}.tmp`;
|
|
4415
4691
|
await writeFile(tmp, JSON.stringify(data, null, 2) + "\n");
|
|
4416
4692
|
await rename(tmp, filePath);
|
|
@@ -4527,8 +4803,8 @@ function finalizeBenchStatus(filePath) {
|
|
|
4527
4803
|
}
|
|
4528
4804
|
|
|
4529
4805
|
// src/bench-fallback.ts
|
|
4530
|
-
import
|
|
4531
|
-
import
|
|
4806
|
+
import fs19 from "fs";
|
|
4807
|
+
import path10 from "path";
|
|
4532
4808
|
var FALLBACK_RESULTS_DIRNAME = "fallback-runs";
|
|
4533
4809
|
function buildBenchRunnerArgs(parsed, benchmarkId, outputDir) {
|
|
4534
4810
|
const args = ["--benchmark", benchmarkId];
|
|
@@ -4592,34 +4868,34 @@ function findUnsupportedFallbackBenchOptions(parsed) {
|
|
|
4592
4868
|
return unsupported;
|
|
4593
4869
|
}
|
|
4594
4870
|
function createFallbackBenchOutputDir(resultsDir, benchmarkId, pid, startedAtMs = Date.now()) {
|
|
4595
|
-
return
|
|
4871
|
+
return path10.join(
|
|
4596
4872
|
resultsDir,
|
|
4597
4873
|
FALLBACK_RESULTS_DIRNAME,
|
|
4598
4874
|
`${benchmarkId}-${startedAtMs}-${pid}`
|
|
4599
4875
|
);
|
|
4600
4876
|
}
|
|
4601
4877
|
function resolveFallbackBenchResultPath(outputDir) {
|
|
4602
|
-
const entries =
|
|
4878
|
+
const entries = fs19.readdirSync(outputDir, { withFileTypes: true }).filter((entry) => entry.isFile() && entry.name.endsWith(".json")).map((entry) => entry.name).sort();
|
|
4603
4879
|
if (entries.length === 0) {
|
|
4604
4880
|
throw new Error(`Fallback benchmark runner did not write a JSON result artifact in ${outputDir}`);
|
|
4605
4881
|
}
|
|
4606
|
-
return
|
|
4882
|
+
return path10.join(outputDir, entries[0]);
|
|
4607
4883
|
}
|
|
4608
4884
|
|
|
4609
4885
|
// src/openclaw-upgrade-swap.ts
|
|
4610
|
-
import
|
|
4611
|
-
import
|
|
4886
|
+
import fs20 from "fs";
|
|
4887
|
+
import path11 from "path";
|
|
4612
4888
|
function describeError(error) {
|
|
4613
4889
|
return error instanceof Error ? error.message : String(error);
|
|
4614
4890
|
}
|
|
4615
4891
|
function createSiblingTempFilePath(targetPath, label) {
|
|
4616
4892
|
const nonce = `${process.pid}-${Date.now()}-${Math.random().toString(16).slice(2, 10)}`;
|
|
4617
|
-
return
|
|
4893
|
+
return path11.join(path11.dirname(targetPath), `.${path11.basename(targetPath)}.${label}.${nonce}.tmp`);
|
|
4618
4894
|
}
|
|
4619
4895
|
function resolveAtomicWriteMode(targetPath, explicitMode) {
|
|
4620
4896
|
if (explicitMode !== void 0) return explicitMode;
|
|
4621
4897
|
try {
|
|
4622
|
-
return
|
|
4898
|
+
return fs20.statSync(targetPath).mode & 4095;
|
|
4623
4899
|
} catch (error) {
|
|
4624
4900
|
if (error instanceof Error && "code" in error && error.code === "ENOENT") {
|
|
4625
4901
|
return 384;
|
|
@@ -4629,8 +4905,8 @@ function resolveAtomicWriteMode(targetPath, explicitMode) {
|
|
|
4629
4905
|
}
|
|
4630
4906
|
function resolveAtomicReplacementPath(targetPath) {
|
|
4631
4907
|
try {
|
|
4632
|
-
if (
|
|
4633
|
-
return
|
|
4908
|
+
if (fs20.lstatSync(targetPath).isSymbolicLink()) {
|
|
4909
|
+
return fs20.realpathSync(targetPath);
|
|
4634
4910
|
}
|
|
4635
4911
|
} catch (error) {
|
|
4636
4912
|
if (error instanceof Error && "code" in error && error.code === "ENOENT") {
|
|
@@ -4642,12 +4918,12 @@ function resolveAtomicReplacementPath(targetPath) {
|
|
|
4642
4918
|
}
|
|
4643
4919
|
function createSiblingSwapPath(targetDir, label) {
|
|
4644
4920
|
const nonce = `${process.pid}-${Date.now()}-${Math.random().toString(16).slice(2, 10)}`;
|
|
4645
|
-
return
|
|
4921
|
+
return path11.join(path11.dirname(targetDir), `.${path11.basename(targetDir)}.${label}.${nonce}`);
|
|
4646
4922
|
}
|
|
4647
4923
|
function cleanupDisplacedDirectoryBestEffort(displacedDir, context) {
|
|
4648
4924
|
if (!displacedDir) return void 0;
|
|
4649
4925
|
try {
|
|
4650
|
-
|
|
4926
|
+
fs20.rmSync(displacedDir, { recursive: true, force: true });
|
|
4651
4927
|
return void 0;
|
|
4652
4928
|
} catch (error) {
|
|
4653
4929
|
return `Warning: ${context}, but failed to remove the displaced plugin copy at ${displacedDir}: ${describeError(error)}`;
|
|
@@ -4655,43 +4931,43 @@ function cleanupDisplacedDirectoryBestEffort(displacedDir, context) {
|
|
|
4655
4931
|
}
|
|
4656
4932
|
function atomicWriteFileSync(targetPath, data, options = {}) {
|
|
4657
4933
|
const resolvedTargetPath = resolveAtomicReplacementPath(targetPath);
|
|
4658
|
-
|
|
4934
|
+
fs20.mkdirSync(path11.dirname(resolvedTargetPath), { recursive: true });
|
|
4659
4935
|
const tempPath = createSiblingTempFilePath(resolvedTargetPath, "write");
|
|
4660
4936
|
const mode = resolveAtomicWriteMode(resolvedTargetPath, options.mode);
|
|
4661
4937
|
try {
|
|
4662
4938
|
if (options.hooks?.writeTempFileSync) {
|
|
4663
4939
|
options.hooks.writeTempFileSync(tempPath);
|
|
4664
4940
|
} else {
|
|
4665
|
-
|
|
4941
|
+
fs20.writeFileSync(tempPath, data, { mode });
|
|
4666
4942
|
}
|
|
4667
|
-
|
|
4668
|
-
const renameTempFileSync = options.hooks?.renameTempFileSync ??
|
|
4943
|
+
fs20.chmodSync(tempPath, mode);
|
|
4944
|
+
const renameTempFileSync = options.hooks?.renameTempFileSync ?? fs20.renameSync;
|
|
4669
4945
|
renameTempFileSync(tempPath, resolvedTargetPath);
|
|
4670
4946
|
} catch (error) {
|
|
4671
|
-
|
|
4947
|
+
fs20.rmSync(tempPath, { force: true });
|
|
4672
4948
|
throw error;
|
|
4673
4949
|
}
|
|
4674
4950
|
}
|
|
4675
4951
|
function atomicCopyFileSync(sourcePath, targetPath, options = {}) {
|
|
4676
|
-
if (!
|
|
4952
|
+
if (!fs20.existsSync(sourcePath)) return;
|
|
4677
4953
|
const resolvedTargetPath = resolveAtomicReplacementPath(targetPath);
|
|
4678
|
-
|
|
4954
|
+
fs20.mkdirSync(path11.dirname(resolvedTargetPath), { recursive: true });
|
|
4679
4955
|
const tempPath = createSiblingTempFilePath(resolvedTargetPath, "copy");
|
|
4680
|
-
const mode =
|
|
4956
|
+
const mode = fs20.statSync(sourcePath).mode & 4095;
|
|
4681
4957
|
try {
|
|
4682
|
-
const copyTempFileSync = options.hooks?.copyTempFileSync ??
|
|
4958
|
+
const copyTempFileSync = options.hooks?.copyTempFileSync ?? fs20.copyFileSync;
|
|
4683
4959
|
copyTempFileSync(sourcePath, tempPath);
|
|
4684
|
-
|
|
4685
|
-
const renameTempFileSync = options.hooks?.renameTempFileSync ??
|
|
4960
|
+
fs20.chmodSync(tempPath, mode);
|
|
4961
|
+
const renameTempFileSync = options.hooks?.renameTempFileSync ?? fs20.renameSync;
|
|
4686
4962
|
renameTempFileSync(tempPath, resolvedTargetPath);
|
|
4687
4963
|
} catch (error) {
|
|
4688
|
-
|
|
4964
|
+
fs20.rmSync(tempPath, { force: true });
|
|
4689
4965
|
throw error;
|
|
4690
4966
|
}
|
|
4691
4967
|
}
|
|
4692
4968
|
function cleanupRollbackDirectory(rollbackDir) {
|
|
4693
4969
|
if (!rollbackDir) return;
|
|
4694
|
-
|
|
4970
|
+
fs20.rmSync(rollbackDir, { recursive: true, force: true });
|
|
4695
4971
|
}
|
|
4696
4972
|
function cleanupRollbackDirectoryBestEffort(rollbackDir) {
|
|
4697
4973
|
if (!rollbackDir) return void 0;
|
|
@@ -4703,20 +4979,20 @@ function cleanupRollbackDirectoryBestEffort(rollbackDir) {
|
|
|
4703
4979
|
}
|
|
4704
4980
|
}
|
|
4705
4981
|
function restoreDirectoryFromRollback(targetDir, rollbackDir) {
|
|
4706
|
-
if (!
|
|
4982
|
+
if (!fs20.existsSync(rollbackDir)) {
|
|
4707
4983
|
throw new Error(`Rollback directory is missing: ${rollbackDir}`);
|
|
4708
4984
|
}
|
|
4709
|
-
|
|
4710
|
-
const displacedDir =
|
|
4985
|
+
fs20.mkdirSync(path11.dirname(targetDir), { recursive: true });
|
|
4986
|
+
const displacedDir = fs20.existsSync(targetDir) ? createSiblingSwapPath(targetDir, "rollback-restore") : void 0;
|
|
4711
4987
|
if (displacedDir) {
|
|
4712
|
-
|
|
4988
|
+
fs20.renameSync(targetDir, displacedDir);
|
|
4713
4989
|
}
|
|
4714
4990
|
try {
|
|
4715
|
-
|
|
4991
|
+
fs20.renameSync(rollbackDir, targetDir);
|
|
4716
4992
|
} catch (restoreError) {
|
|
4717
|
-
if (displacedDir &&
|
|
4993
|
+
if (displacedDir && fs20.existsSync(displacedDir)) {
|
|
4718
4994
|
try {
|
|
4719
|
-
|
|
4995
|
+
fs20.renameSync(displacedDir, targetDir);
|
|
4720
4996
|
} catch (revertError) {
|
|
4721
4997
|
throw new AggregateError(
|
|
4722
4998
|
[restoreError, revertError],
|
|
@@ -4732,23 +5008,23 @@ function restoreDirectoryFromRollback(targetDir, rollbackDir) {
|
|
|
4732
5008
|
return cleanupDisplacedDirectoryBestEffort(displacedDir, `restored the previous plugin copy into ${targetDir}`);
|
|
4733
5009
|
}
|
|
4734
5010
|
function restoreDirectoryFromBackup(targetDir, backupDir) {
|
|
4735
|
-
if (!
|
|
5011
|
+
if (!fs20.existsSync(backupDir)) {
|
|
4736
5012
|
throw new Error(`Plugin backup directory is missing: ${backupDir}`);
|
|
4737
5013
|
}
|
|
4738
|
-
|
|
5014
|
+
fs20.mkdirSync(path11.dirname(targetDir), { recursive: true });
|
|
4739
5015
|
const stagedDir = createSiblingSwapPath(targetDir, "backup-restore");
|
|
4740
|
-
const displacedDir =
|
|
4741
|
-
|
|
5016
|
+
const displacedDir = fs20.existsSync(targetDir) ? createSiblingSwapPath(targetDir, "pre-backup-restore") : void 0;
|
|
5017
|
+
fs20.cpSync(backupDir, stagedDir, { recursive: true });
|
|
4742
5018
|
if (displacedDir) {
|
|
4743
|
-
|
|
5019
|
+
fs20.renameSync(targetDir, displacedDir);
|
|
4744
5020
|
}
|
|
4745
5021
|
try {
|
|
4746
|
-
|
|
5022
|
+
fs20.renameSync(stagedDir, targetDir);
|
|
4747
5023
|
} catch (restoreError) {
|
|
4748
|
-
|
|
4749
|
-
if (displacedDir &&
|
|
5024
|
+
fs20.rmSync(targetDir, { recursive: true, force: true });
|
|
5025
|
+
if (displacedDir && fs20.existsSync(displacedDir)) {
|
|
4750
5026
|
try {
|
|
4751
|
-
|
|
5027
|
+
fs20.renameSync(displacedDir, targetDir);
|
|
4752
5028
|
} catch (revertError) {
|
|
4753
5029
|
throw new AggregateError(
|
|
4754
5030
|
[restoreError, revertError],
|
|
@@ -4756,7 +5032,7 @@ function restoreDirectoryFromBackup(targetDir, backupDir) {
|
|
|
4756
5032
|
);
|
|
4757
5033
|
}
|
|
4758
5034
|
}
|
|
4759
|
-
|
|
5035
|
+
fs20.rmSync(stagedDir, { recursive: true, force: true });
|
|
4760
5036
|
throw new Error(
|
|
4761
5037
|
`Failed to restore the plugin backup into ${targetDir}. The durable backup remains preserved at ${backupDir}.`,
|
|
4762
5038
|
{ cause: restoreError }
|
|
@@ -4781,7 +5057,7 @@ function rollbackOpenclawUpgrade({
|
|
|
4781
5057
|
let configRemovalAttempted = false;
|
|
4782
5058
|
let pluginRestored = false;
|
|
4783
5059
|
try {
|
|
4784
|
-
if (rollbackDir &&
|
|
5060
|
+
if (rollbackDir && fs20.existsSync(rollbackDir)) {
|
|
4785
5061
|
const cleanupWarning = restoreDirectoryFromRollback(pluginDir, rollbackDir);
|
|
4786
5062
|
notes.push(`Restored previous plugin from rollback copy at ${rollbackDir}`);
|
|
4787
5063
|
if (cleanupWarning) notes.push(cleanupWarning);
|
|
@@ -4791,7 +5067,7 @@ function rollbackOpenclawUpgrade({
|
|
|
4791
5067
|
rollbackRestoreError = error instanceof Error ? error.message : String(error);
|
|
4792
5068
|
}
|
|
4793
5069
|
try {
|
|
4794
|
-
if (!pluginRestored && pluginBackupDir &&
|
|
5070
|
+
if (!pluginRestored && pluginBackupDir && fs20.existsSync(pluginBackupDir)) {
|
|
4795
5071
|
const cleanupWarning = restoreDirectoryFromBackup(pluginDir, pluginBackupDir);
|
|
4796
5072
|
if (rollbackRestoreError) {
|
|
4797
5073
|
notes.push(`Rollback copy restore failed; restored previous plugin from durable backup at ${pluginBackupDir}`);
|
|
@@ -4816,12 +5092,12 @@ function rollbackOpenclawUpgrade({
|
|
|
4816
5092
|
notes.push("No previous plugin copy was available for automatic restore");
|
|
4817
5093
|
}
|
|
4818
5094
|
try {
|
|
4819
|
-
if (configBackupPath &&
|
|
5095
|
+
if (configBackupPath && fs20.existsSync(configBackupPath)) {
|
|
4820
5096
|
restoreFileFromBackup(configPath, configBackupPath);
|
|
4821
5097
|
notes.push(`Restored OpenClaw config from backup at ${configBackupPath}`);
|
|
4822
|
-
} else if (removeConfigIfUnbacked &&
|
|
5098
|
+
} else if (removeConfigIfUnbacked && fs20.existsSync(configPath)) {
|
|
4823
5099
|
configRemovalAttempted = true;
|
|
4824
|
-
|
|
5100
|
+
fs20.rmSync(configPath, { force: true });
|
|
4825
5101
|
notes.push("Removed OpenClaw config created during the failed upgrade");
|
|
4826
5102
|
}
|
|
4827
5103
|
} catch (error) {
|
|
@@ -4874,9 +5150,9 @@ Run this manually when you're ready:
|
|
|
4874
5150
|
|
|
4875
5151
|
// src/openclaw-managed-upgrade-loader.ts
|
|
4876
5152
|
import { execFileSync } from "child_process";
|
|
4877
|
-
import
|
|
5153
|
+
import fs21 from "fs";
|
|
4878
5154
|
import os from "os";
|
|
4879
|
-
import
|
|
5155
|
+
import path12 from "path";
|
|
4880
5156
|
import { fileURLToPath as fileURLToPath3, pathToFileURL as pathToFileURL2 } from "url";
|
|
4881
5157
|
var MANAGED_UPGRADE_SPECIFIER = "@remnic/plugin-openclaw/managed-upgrade";
|
|
4882
5158
|
var OPENCLAW_PLUGIN_PACKAGE = "@remnic/plugin-openclaw";
|
|
@@ -4948,9 +5224,9 @@ function buildOpenclawManagedUpgradePackageSpec(version = "latest") {
|
|
|
4948
5224
|
return `${OPENCLAW_PLUGIN_PACKAGE}@${version}`;
|
|
4949
5225
|
}
|
|
4950
5226
|
function readCliAdapterRange() {
|
|
4951
|
-
const moduleDir =
|
|
4952
|
-
const manifestPath =
|
|
4953
|
-
const manifest = JSON.parse(
|
|
5227
|
+
const moduleDir = path12.dirname(fileURLToPath3(import.meta.url));
|
|
5228
|
+
const manifestPath = path12.resolve(moduleDir, "../package.json");
|
|
5229
|
+
const manifest = JSON.parse(fs21.readFileSync(manifestPath, "utf8"));
|
|
4954
5230
|
if (manifest.name !== "@remnic/cli") {
|
|
4955
5231
|
throw new Error(`Invalid @remnic/cli package manifest at ${manifestPath}.`);
|
|
4956
5232
|
}
|
|
@@ -4994,7 +5270,7 @@ async function loadOpenclawManagedUpgradeModule(packageSpec, hooks = {}) {
|
|
|
4994
5270
|
const adapterMissing = isSpecifierNotFoundError(error, OPENCLAW_PLUGIN_PACKAGE) || isSpecifierNotFoundError(error, MANAGED_UPGRADE_SPECIFIER) || isManagedUpgradeSubpathMissing(error);
|
|
4995
5271
|
if (!adapterMissing) throw error;
|
|
4996
5272
|
}
|
|
4997
|
-
const temporaryRoot =
|
|
5273
|
+
const temporaryRoot = fs21.mkdtempSync(path12.join(os.tmpdir(), "remnic-openclaw-upgrade-"));
|
|
4998
5274
|
try {
|
|
4999
5275
|
const toolingPackageSpec = `${OPENCLAW_PLUGIN_PACKAGE}@${readCliAdapterRange()}`;
|
|
5000
5276
|
const installArgs = [
|
|
@@ -5008,13 +5284,13 @@ async function loadOpenclawManagedUpgradeModule(packageSpec, hooks = {}) {
|
|
|
5008
5284
|
toolingPackageSpec
|
|
5009
5285
|
];
|
|
5010
5286
|
(hooks.runNpmInstall ?? runNpmInstall)(installArgs);
|
|
5011
|
-
const resolverPath =
|
|
5012
|
-
|
|
5287
|
+
const resolverPath = path12.join(temporaryRoot, "load-managed-upgrade.mjs");
|
|
5288
|
+
fs21.writeFileSync(resolverPath, `export * from ${JSON.stringify(MANAGED_UPGRADE_SPECIFIER)};
|
|
5013
5289
|
`, "utf8");
|
|
5014
5290
|
return await importModule(pathToFileURL2(resolverPath).href);
|
|
5015
5291
|
} finally {
|
|
5016
5292
|
try {
|
|
5017
|
-
|
|
5293
|
+
fs21.rmSync(temporaryRoot, { recursive: true, force: true });
|
|
5018
5294
|
} catch (error) {
|
|
5019
5295
|
const detail = error instanceof Error ? error.message : String(error);
|
|
5020
5296
|
console.warn(`Could not remove temporary managed upgrade project at ${temporaryRoot}: ${detail}`);
|
|
@@ -5023,13 +5299,13 @@ async function loadOpenclawManagedUpgradeModule(packageSpec, hooks = {}) {
|
|
|
5023
5299
|
}
|
|
5024
5300
|
|
|
5025
5301
|
// src/remote-daemon.ts
|
|
5026
|
-
import
|
|
5302
|
+
import fs22 from "fs";
|
|
5027
5303
|
function readCompatEnv(primary, legacy) {
|
|
5028
5304
|
return process.env[primary] ?? process.env[legacy];
|
|
5029
5305
|
}
|
|
5030
5306
|
function readRemnicConfigRecord(configPath) {
|
|
5031
5307
|
try {
|
|
5032
|
-
const parsed = JSON.parse(
|
|
5308
|
+
const parsed = JSON.parse(fs22.readFileSync(configPath, "utf8"));
|
|
5033
5309
|
if (parsed && typeof parsed === "object" && !Array.isArray(parsed)) {
|
|
5034
5310
|
return parsed;
|
|
5035
5311
|
}
|
|
@@ -5258,11 +5534,11 @@ async function remoteRecallXray(daemon, request) {
|
|
|
5258
5534
|
}
|
|
5259
5535
|
|
|
5260
5536
|
// src/daemon-service.ts
|
|
5261
|
-
import
|
|
5262
|
-
import
|
|
5537
|
+
import fs23 from "fs";
|
|
5538
|
+
import path13 from "path";
|
|
5263
5539
|
import * as childProcess from "child_process";
|
|
5264
5540
|
import { fileURLToPath as fileURLToPath4 } from "url";
|
|
5265
|
-
var thisModuleDir =
|
|
5541
|
+
var thisModuleDir = path13.dirname(fileURLToPath4(import.meta.url));
|
|
5266
5542
|
function launchdLoadPlist(plistPath, processApi = childProcess) {
|
|
5267
5543
|
processApi.execFileSync("launchctl", ["load", "-w", plistPath], { stdio: "pipe" });
|
|
5268
5544
|
}
|
|
@@ -5270,7 +5546,7 @@ function launchdUnloadPlist(plistPath, processApi = childProcess) {
|
|
|
5270
5546
|
processApi.execFileSync("launchctl", ["unload", plistPath], { stdio: "pipe" });
|
|
5271
5547
|
}
|
|
5272
5548
|
function resolveServerBinDetails(options = {}) {
|
|
5273
|
-
const existsSync4 = options.existsSync ??
|
|
5549
|
+
const existsSync4 = options.existsSync ?? fs23.existsSync;
|
|
5274
5550
|
const findCommandOnPath2 = options.findCommandOnPath ?? findCommandOnPath;
|
|
5275
5551
|
const moduleDir = options.moduleDir ?? thisModuleDir;
|
|
5276
5552
|
const packageResolve = options.packageResolve ?? resolveImportSpecifier;
|
|
@@ -5284,8 +5560,8 @@ function resolveServerBinDetails(options = {}) {
|
|
|
5284
5560
|
});
|
|
5285
5561
|
} catch {
|
|
5286
5562
|
}
|
|
5287
|
-
const workspaceServerBin =
|
|
5288
|
-
const workspaceDistIndex =
|
|
5563
|
+
const workspaceServerBin = path13.resolve(moduleDir, "../../remnic-server/bin/remnic-server.js");
|
|
5564
|
+
const workspaceDistIndex = path13.resolve(moduleDir, "../../remnic-server/dist/index.js");
|
|
5289
5565
|
candidates.push(
|
|
5290
5566
|
{
|
|
5291
5567
|
path: workspaceServerBin,
|
|
@@ -5306,11 +5582,11 @@ function resolveServerBinDetails(options = {}) {
|
|
|
5306
5582
|
});
|
|
5307
5583
|
}
|
|
5308
5584
|
candidates.push({
|
|
5309
|
-
path:
|
|
5585
|
+
path: path13.resolve(moduleDir, "../../remnic-server/src/index.ts"),
|
|
5310
5586
|
source: "workspace-source"
|
|
5311
5587
|
});
|
|
5312
5588
|
const selected = candidates.find((candidate) => isCandidateReady(candidate, existsSync4)) ?? candidates.find((candidate) => existsSync4(candidate.path)) ?? candidates[0] ?? {
|
|
5313
|
-
path:
|
|
5589
|
+
path: path13.resolve(moduleDir, "../../remnic-server/dist/index.js"),
|
|
5314
5590
|
source: "workspace-dist"
|
|
5315
5591
|
};
|
|
5316
5592
|
const exists = existsSync4(selected.path);
|
|
@@ -5329,8 +5605,8 @@ function resolveServerBin(options = {}) {
|
|
|
5329
5605
|
return resolveServerBinDetails(options).path;
|
|
5330
5606
|
}
|
|
5331
5607
|
function readVerifiedDaemonPid(options) {
|
|
5332
|
-
const readFileSync4 = options.readFileSync ??
|
|
5333
|
-
const unlinkSync = options.unlinkSync ??
|
|
5608
|
+
const readFileSync4 = options.readFileSync ?? fs23.readFileSync;
|
|
5609
|
+
const unlinkSync = options.unlinkSync ?? fs23.unlinkSync;
|
|
5334
5610
|
const processKill = options.processKill ?? process.kill;
|
|
5335
5611
|
const platform = options.platform ?? process.platform;
|
|
5336
5612
|
const execFileSync4 = options.execFileSync ?? ((command, args, execOptions) => childProcess.execFileSync(command, args, execOptions));
|
|
@@ -5365,7 +5641,7 @@ function readVerifiedDaemonPid(options) {
|
|
|
5365
5641
|
}
|
|
5366
5642
|
function doesProcessCommandLookLikeRemnicDaemon(command, expectedServerBin) {
|
|
5367
5643
|
const normalizedCommand = command.trim();
|
|
5368
|
-
const normalizedExpected =
|
|
5644
|
+
const normalizedExpected = path13.resolve(expandTilde(expectedServerBin));
|
|
5369
5645
|
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);
|
|
5370
5646
|
}
|
|
5371
5647
|
function parseDaemonPid(raw) {
|
|
@@ -5430,8 +5706,8 @@ function removePidFileBestEffort(file, unlinkSync) {
|
|
|
5430
5706
|
}
|
|
5431
5707
|
}
|
|
5432
5708
|
function inspectLaunchdPlist(plistPath, options = {}) {
|
|
5433
|
-
const existsSync4 = options.existsSync ??
|
|
5434
|
-
const readFileSync4 = options.readFileSync ??
|
|
5709
|
+
const existsSync4 = options.existsSync ?? fs23.existsSync;
|
|
5710
|
+
const readFileSync4 = options.readFileSync ?? fs23.readFileSync;
|
|
5435
5711
|
if (!existsSync4(plistPath)) {
|
|
5436
5712
|
return {
|
|
5437
5713
|
installed: false,
|
|
@@ -5470,7 +5746,7 @@ function inspectLaunchdPlist(plistPath, options = {}) {
|
|
|
5470
5746
|
};
|
|
5471
5747
|
}
|
|
5472
5748
|
const expandedServerArg = expandTilde(serverArg);
|
|
5473
|
-
if (!
|
|
5749
|
+
if (!path13.isAbsolute(expandedServerArg)) {
|
|
5474
5750
|
return {
|
|
5475
5751
|
installed: true,
|
|
5476
5752
|
ok: false,
|
|
@@ -5542,8 +5818,8 @@ function normalizeResolvedPath(resolved) {
|
|
|
5542
5818
|
return resolved;
|
|
5543
5819
|
}
|
|
5544
5820
|
function packageServerBinFromEntry(packageEntry) {
|
|
5545
|
-
if (
|
|
5546
|
-
return
|
|
5821
|
+
if (path13.basename(packageEntry) === "index.js" && path13.basename(path13.dirname(packageEntry)) === "dist") {
|
|
5822
|
+
return path13.join(path13.dirname(path13.dirname(packageEntry)), "bin", "remnic-server.js");
|
|
5547
5823
|
}
|
|
5548
5824
|
return packageEntry;
|
|
5549
5825
|
}
|
|
@@ -5609,7 +5885,7 @@ function stripConfigArgv(args) {
|
|
|
5609
5885
|
}
|
|
5610
5886
|
|
|
5611
5887
|
// src/import-dispatch.ts
|
|
5612
|
-
import
|
|
5888
|
+
import fs24 from "fs";
|
|
5613
5889
|
import {
|
|
5614
5890
|
runImporter,
|
|
5615
5891
|
validateImportBatchSize,
|
|
@@ -5618,7 +5894,7 @@ import {
|
|
|
5618
5894
|
|
|
5619
5895
|
// src/import-bundle-detect.ts
|
|
5620
5896
|
import { lstatSync as lstatSync2, readdirSync as readdirSync2, readFileSync as readFileSync3 } from "fs";
|
|
5621
|
-
import
|
|
5897
|
+
import path14 from "path";
|
|
5622
5898
|
function detectBundleEntries(bundleDir, options = {}) {
|
|
5623
5899
|
const readdir3 = options.readdirImpl ?? defaultReaddir;
|
|
5624
5900
|
const readFileImpl = options.readFileImpl ?? defaultReadFile;
|
|
@@ -5649,7 +5925,7 @@ function detectBundleEntries(bundleDir, options = {}) {
|
|
|
5649
5925
|
for (const filePath of roots) {
|
|
5650
5926
|
if (seenFiles.has(filePath)) continue;
|
|
5651
5927
|
seenFiles.add(filePath);
|
|
5652
|
-
const name =
|
|
5928
|
+
const name = path14.basename(filePath);
|
|
5653
5929
|
const match = classifyFile(name, filePath, readFileImpl);
|
|
5654
5930
|
if (match) entries.push(match);
|
|
5655
5931
|
}
|
|
@@ -5687,7 +5963,7 @@ function collectCandidatePaths(root, readdir3, isDirectory2, isRegularFile) {
|
|
|
5687
5963
|
return;
|
|
5688
5964
|
}
|
|
5689
5965
|
for (const entry of entries) {
|
|
5690
|
-
const full =
|
|
5966
|
+
const full = path14.join(dir, entry);
|
|
5691
5967
|
if (isDirectory2(full)) {
|
|
5692
5968
|
walk(full, depth + 1);
|
|
5693
5969
|
} else if (isRegularFile(full)) {
|
|
@@ -5766,7 +6042,8 @@ var SUPPORTED_IMPORTERS = [
|
|
|
5766
6042
|
"claude",
|
|
5767
6043
|
"gemini",
|
|
5768
6044
|
"mem0",
|
|
5769
|
-
"supermemory"
|
|
6045
|
+
"supermemory",
|
|
6046
|
+
"okf"
|
|
5770
6047
|
];
|
|
5771
6048
|
function isSupportedImporterName(value) {
|
|
5772
6049
|
return SUPPORTED_IMPORTERS.includes(value);
|
|
@@ -5824,16 +6101,16 @@ Or add it to a project:
|
|
|
5824
6101
|
}
|
|
5825
6102
|
|
|
5826
6103
|
// src/import-dispatch.ts
|
|
5827
|
-
var IMPORT_USAGE = `remnic import \u2014 Bring memory from ChatGPT, Claude, Gemini, Mem0,
|
|
6104
|
+
var IMPORT_USAGE = `remnic import \u2014 Bring memory from ChatGPT, Claude, Gemini, Mem0, Supermemory, or OKF
|
|
5828
6105
|
|
|
5829
6106
|
Usage:
|
|
5830
6107
|
remnic import --adapter <name> --file <path> [options]
|
|
6108
|
+
remnic import okf <dir> [options]
|
|
5831
6109
|
|
|
5832
6110
|
Required:
|
|
5833
6111
|
--adapter <name> One of: ${SUPPORTED_IMPORTERS.join(" | ")}
|
|
5834
|
-
--file <path> Path to a text/JSON source export
|
|
5835
|
-
|
|
5836
|
-
omitted for API-only adapters (mem0).
|
|
6112
|
+
--file <path> Path to a text/JSON source export, or an OKF directory.
|
|
6113
|
+
Archives must be unpacked first.
|
|
5837
6114
|
|
|
5838
6115
|
Options:
|
|
5839
6116
|
--dry-run Parse and transform only; do not write memories.
|
|
@@ -5849,20 +6126,17 @@ Bulk mode (slice 7):
|
|
|
5849
6126
|
mem0 exports inside <dir> and run each
|
|
5850
6127
|
matching adapter. Replaces --adapter/--file.
|
|
5851
6128
|
|
|
5852
|
-
|
|
5853
|
-
(@remnic/import-chatgpt, @remnic/import-claude, @remnic/import-gemini,
|
|
5854
|
-
@remnic/import-mem0, @remnic/import-supermemory) land in follow-up slices.
|
|
5855
|
-
Install whichever you need:
|
|
6129
|
+
Install the adapter you need:
|
|
5856
6130
|
|
|
5857
6131
|
npm install -g @remnic/import-chatgpt
|
|
5858
|
-
npm install -g @remnic/import-
|
|
5859
|
-
npm install -g @remnic/import-gemini
|
|
5860
|
-
npm install -g @remnic/import-mem0
|
|
5861
|
-
npm install -g @remnic/import-supermemory
|
|
6132
|
+
npm install -g @remnic/import-okf
|
|
5862
6133
|
`;
|
|
5863
6134
|
function parseImportArgs(rest) {
|
|
5864
6135
|
const args = [...rest];
|
|
5865
|
-
|
|
6136
|
+
let adapter = takeValue(args, "--adapter");
|
|
6137
|
+
if (!adapter && args[0] && !args[0].startsWith("--") && isSupportedImporterName(args[0])) {
|
|
6138
|
+
adapter = args.shift();
|
|
6139
|
+
}
|
|
5866
6140
|
if (!adapter) {
|
|
5867
6141
|
throw new Error(
|
|
5868
6142
|
`--adapter <name> is required. Valid values: ${SUPPORTED_IMPORTERS.join(", ")}`
|
|
@@ -5874,7 +6148,7 @@ function parseImportArgs(rest) {
|
|
|
5874
6148
|
);
|
|
5875
6149
|
}
|
|
5876
6150
|
const fileRaw = takeOptionalValue(args, "--file");
|
|
5877
|
-
|
|
6151
|
+
let file = fileRaw !== void 0 ? expandTilde(fileRaw) : void 0;
|
|
5878
6152
|
const batchSizeRaw = takeOptionalValue(args, "--batch-size");
|
|
5879
6153
|
let batchSize;
|
|
5880
6154
|
if (batchSizeRaw !== void 0) {
|
|
@@ -5899,6 +6173,9 @@ function parseImportArgs(rest) {
|
|
|
5899
6173
|
}
|
|
5900
6174
|
const dryRun = consumeFlag(args, "--dry-run");
|
|
5901
6175
|
const includeConversations = consumeFlag(args, "--include-conversations");
|
|
6176
|
+
if (file === void 0 && args[0] && !args[0].startsWith("--")) {
|
|
6177
|
+
file = expandTilde(args.shift());
|
|
6178
|
+
}
|
|
5902
6179
|
rejectLeftoverImportArgs(args, "remnic import");
|
|
5903
6180
|
return {
|
|
5904
6181
|
adapter,
|
|
@@ -5923,14 +6200,19 @@ function rejectLeftoverImportArgs(args, command) {
|
|
|
5923
6200
|
}
|
|
5924
6201
|
}
|
|
5925
6202
|
async function runImportCommand(args, io) {
|
|
5926
|
-
if (args.file && isZipFilePath(args.file)) {
|
|
6203
|
+
if (args.file && (isZipFilePath(args.file) || /\.(tgz|tar\.gz)$/i.test(args.file))) {
|
|
5927
6204
|
throw new Error(
|
|
5928
|
-
`
|
|
6205
|
+
`unpack first: archive imports are not supported ('${args.file}'). Extract the archive, then pass the directory.`
|
|
5929
6206
|
);
|
|
5930
6207
|
}
|
|
5931
6208
|
const adapter = await io.loadAdapter(args.adapter);
|
|
5932
6209
|
let input;
|
|
5933
|
-
if (args.
|
|
6210
|
+
if (args.adapter === "okf") {
|
|
6211
|
+
if (!args.file) {
|
|
6212
|
+
throw new Error("OKF import requires a directory path (remnic import okf <dir>)");
|
|
6213
|
+
}
|
|
6214
|
+
input = args.file;
|
|
6215
|
+
} else if (args.file) {
|
|
5934
6216
|
try {
|
|
5935
6217
|
input = await io.readFile(args.file);
|
|
5936
6218
|
} catch (err) {
|
|
@@ -6123,7 +6405,7 @@ async function cmdImport(rest, targetFactory, disposeTarget, ioOverrides = {}) {
|
|
|
6123
6405
|
let materializedTarget;
|
|
6124
6406
|
let materializePromise;
|
|
6125
6407
|
const io = {
|
|
6126
|
-
readFile: ioOverrides.readFile ?? (async (p) =>
|
|
6408
|
+
readFile: ioOverrides.readFile ?? (async (p) => fs24.promises.readFile(p, "utf-8")),
|
|
6127
6409
|
loadAdapter: ioOverrides.loadAdapter ?? (async (name) => (await loadImporterModule(name)).adapter),
|
|
6128
6410
|
runImporter: ioOverrides.runImporter ?? runImporter,
|
|
6129
6411
|
getWriteTarget: async () => {
|
|
@@ -6236,8 +6518,8 @@ async function cmdCapture(rest, io) {
|
|
|
6236
6518
|
}
|
|
6237
6519
|
|
|
6238
6520
|
// src/import-lossless-claw-cmd.ts
|
|
6239
|
-
import
|
|
6240
|
-
import
|
|
6521
|
+
import fs25 from "fs";
|
|
6522
|
+
import path15 from "path";
|
|
6241
6523
|
import {
|
|
6242
6524
|
applyLcmSchema,
|
|
6243
6525
|
ensureLcmStateDir,
|
|
@@ -6348,15 +6630,15 @@ async function loadImportLosslessClawModule() {
|
|
|
6348
6630
|
|
|
6349
6631
|
// src/import-lossless-claw-cmd.ts
|
|
6350
6632
|
function assertDirectoryOrAbsent(p, label) {
|
|
6351
|
-
if (
|
|
6633
|
+
if (fs25.existsSync(p) && !fs25.statSync(p).isDirectory()) {
|
|
6352
6634
|
throw new Error(`${label} is not a directory: ${p}`);
|
|
6353
6635
|
}
|
|
6354
6636
|
}
|
|
6355
6637
|
function assertFile(p, label) {
|
|
6356
|
-
if (!
|
|
6638
|
+
if (!fs25.existsSync(p)) {
|
|
6357
6639
|
throw new Error(`${label} does not exist: ${p}`);
|
|
6358
6640
|
}
|
|
6359
|
-
if (!
|
|
6641
|
+
if (!fs25.statSync(p).isFile()) {
|
|
6360
6642
|
throw new Error(`${label} is not a file: ${p}`);
|
|
6361
6643
|
}
|
|
6362
6644
|
}
|
|
@@ -6387,8 +6669,8 @@ async function cmdImportLosslessClaw(argv, io, deps = {}) {
|
|
|
6387
6669
|
let destDb;
|
|
6388
6670
|
try {
|
|
6389
6671
|
if (parsed.dryRun) {
|
|
6390
|
-
const lcmPath =
|
|
6391
|
-
if (
|
|
6672
|
+
const lcmPath = path15.join(memoryDir, "state", "lcm.sqlite");
|
|
6673
|
+
if (fs25.existsSync(lcmPath)) {
|
|
6392
6674
|
destDb = mod.openExistingLcmDatabaseReadOnly(lcmPath);
|
|
6393
6675
|
} else {
|
|
6394
6676
|
destDb = mod.openInMemoryDestinationDatabase();
|
|
@@ -6509,7 +6791,7 @@ function printBenchComparisonSummary(comparison, baseline, candidate) {
|
|
|
6509
6791
|
// src/bench-coding-commands.ts
|
|
6510
6792
|
import { lstat as lstat2, readFile as readFile2, realpath, stat } from "fs/promises";
|
|
6511
6793
|
import os2 from "os";
|
|
6512
|
-
import
|
|
6794
|
+
import path16 from "path";
|
|
6513
6795
|
var UINT32_MAX = 4294967295;
|
|
6514
6796
|
var FROZEN_GENERATOR_SEED = 81;
|
|
6515
6797
|
var FROZEN_TASK_COUNT = 30;
|
|
@@ -6519,7 +6801,7 @@ var FROZEN_MAX_STEPS = 12;
|
|
|
6519
6801
|
var FROZEN_MAX_TOOL_CALLS = 8;
|
|
6520
6802
|
var FROZEN_MAX_OUTPUT_CHARS = 16384;
|
|
6521
6803
|
var MAX_OUTPUT_BYTES = 16384;
|
|
6522
|
-
var DEFAULT_REPEATED_FAILURE_OUTPUT_DIR =
|
|
6804
|
+
var DEFAULT_REPEATED_FAILURE_OUTPUT_DIR = path16.join(
|
|
6523
6805
|
resolveHomeDir(),
|
|
6524
6806
|
".remnic",
|
|
6525
6807
|
"bench",
|
|
@@ -6853,7 +7135,7 @@ function parseBenchCodingArgs(args) {
|
|
|
6853
7135
|
throw new Error(`unknown bench coding subcommand ${args[0]}`);
|
|
6854
7136
|
}
|
|
6855
7137
|
function normalizeCommandPaths(command) {
|
|
6856
|
-
const resolve2 = (value) =>
|
|
7138
|
+
const resolve2 = (value) => path16.resolve(expandTilde(value));
|
|
6857
7139
|
if (command.kind === "repo-generate") {
|
|
6858
7140
|
return { ...command, outputDir: resolve2(command.outputDir) };
|
|
6859
7141
|
}
|
|
@@ -6884,23 +7166,23 @@ function normalizeCommandPaths(command) {
|
|
|
6884
7166
|
return command;
|
|
6885
7167
|
}
|
|
6886
7168
|
async function canonicalProspectivePath(value) {
|
|
6887
|
-
let candidate =
|
|
7169
|
+
let candidate = path16.resolve(value);
|
|
6888
7170
|
const missingSegments = [];
|
|
6889
7171
|
while (true) {
|
|
6890
7172
|
try {
|
|
6891
|
-
return
|
|
7173
|
+
return path16.join(await realpath(candidate), ...missingSegments.reverse());
|
|
6892
7174
|
} catch (error) {
|
|
6893
7175
|
if (error.code !== "ENOENT") throw error;
|
|
6894
|
-
const parent =
|
|
7176
|
+
const parent = path16.dirname(candidate);
|
|
6895
7177
|
if (parent === candidate) throw error;
|
|
6896
|
-
missingSegments.push(
|
|
7178
|
+
missingSegments.push(path16.basename(candidate));
|
|
6897
7179
|
candidate = parent;
|
|
6898
7180
|
}
|
|
6899
7181
|
}
|
|
6900
7182
|
}
|
|
6901
7183
|
function isSameOrDescendant(candidate, root) {
|
|
6902
|
-
const relative =
|
|
6903
|
-
return relative === "" || relative !== ".." && !relative.startsWith(`..${
|
|
7184
|
+
const relative = path16.relative(root, candidate);
|
|
7185
|
+
return relative === "" || relative !== ".." && !relative.startsWith(`..${path16.sep}`) && !path16.isAbsolute(relative);
|
|
6904
7186
|
}
|
|
6905
7187
|
async function pathExists(value) {
|
|
6906
7188
|
try {
|
|
@@ -6919,7 +7201,7 @@ async function assertSafeBenchmarkOutput(outputDir) {
|
|
|
6919
7201
|
const configured = process.env[variable]?.trim();
|
|
6920
7202
|
if (!configured) continue;
|
|
6921
7203
|
const memoryRoot = await canonicalProspectivePath(
|
|
6922
|
-
|
|
7204
|
+
path16.resolve(expandTilde(configured))
|
|
6923
7205
|
);
|
|
6924
7206
|
if (isSameOrDescendant(canonicalOutput, memoryRoot)) {
|
|
6925
7207
|
throw new Error(refusal);
|
|
@@ -6927,10 +7209,10 @@ async function assertSafeBenchmarkOutput(outputDir) {
|
|
|
6927
7209
|
}
|
|
6928
7210
|
let candidate = canonicalOutput;
|
|
6929
7211
|
while (true) {
|
|
6930
|
-
const hasProfile = await pathExists(
|
|
6931
|
-
const hasMemoryData = await pathExists(
|
|
7212
|
+
const hasProfile = await pathExists(path16.join(candidate, "profile.md"));
|
|
7213
|
+
const hasMemoryData = await pathExists(path16.join(candidate, "facts")) || await pathExists(path16.join(candidate, "entities")) || await pathExists(path16.join(candidate, "state"));
|
|
6932
7214
|
if (hasProfile && hasMemoryData) throw new Error(refusal);
|
|
6933
|
-
const parent =
|
|
7215
|
+
const parent = path16.dirname(candidate);
|
|
6934
7216
|
if (parent === candidate) break;
|
|
6935
7217
|
candidate = parent;
|
|
6936
7218
|
}
|
|
@@ -6942,7 +7224,7 @@ async function assertSafeBenchmarkOutput(outputDir) {
|
|
|
6942
7224
|
async function assertH6StatsRunDirectory(runDir, commandName = "stats") {
|
|
6943
7225
|
try {
|
|
6944
7226
|
const parsed = JSON.parse(
|
|
6945
|
-
await readFile2(
|
|
7227
|
+
await readFile2(path16.join(runDir, "run.json"), "utf8")
|
|
6946
7228
|
);
|
|
6947
7229
|
if (parsed.schemaVersion !== 1 || typeof parsed.runId !== "string" || parsed.runId.length === 0 || typeof parsed.suiteVersion !== "string" || !parsed.suiteVersion.startsWith("h6-failure-gate-v1-")) {
|
|
6948
7230
|
throw new Error("invalid H6 metadata");
|
|
@@ -7001,7 +7283,7 @@ async function runRepoVerification(command, bench) {
|
|
|
7001
7283
|
if (command.directory === void 0) {
|
|
7002
7284
|
dataset = await requireFunction(bench, "loadCommittedH6BenchmarkDataset")();
|
|
7003
7285
|
} else {
|
|
7004
|
-
const serialized = await readFile2(
|
|
7286
|
+
const serialized = await readFile2(path16.join(command.directory, "dataset.json"), "utf8").catch(
|
|
7005
7287
|
() => void 0
|
|
7006
7288
|
);
|
|
7007
7289
|
if (serialized === void 0) {
|
|
@@ -7129,8 +7411,8 @@ async function cmdBenchCoding(args) {
|
|
|
7129
7411
|
}
|
|
7130
7412
|
|
|
7131
7413
|
// src/bench-security-commands.ts
|
|
7132
|
-
import
|
|
7133
|
-
var DEFAULT_OUTPUT_DIR =
|
|
7414
|
+
import path17 from "path";
|
|
7415
|
+
var DEFAULT_OUTPUT_DIR = path17.join(
|
|
7134
7416
|
resolveHomeDir(),
|
|
7135
7417
|
".remnic",
|
|
7136
7418
|
"bench",
|
|
@@ -7279,7 +7561,7 @@ ${BENCH_SECURITY_USAGE}`);
|
|
|
7279
7561
|
}
|
|
7280
7562
|
|
|
7281
7563
|
// src/bench-research-commands.ts
|
|
7282
|
-
import
|
|
7564
|
+
import path18 from "path";
|
|
7283
7565
|
function emit(result) {
|
|
7284
7566
|
if (result.output) {
|
|
7285
7567
|
console.log(result.output);
|
|
@@ -7297,7 +7579,7 @@ async function runBenchResearchCommand(parsed) {
|
|
|
7297
7579
|
emit(
|
|
7298
7580
|
await runAttributeCliCommand({
|
|
7299
7581
|
runRef: parsed.runRef,
|
|
7300
|
-
resultsDir: parsed.resultsDir ??
|
|
7582
|
+
resultsDir: parsed.resultsDir ?? path18.join(resolveHomeDir(), ".remnic", "bench", "results"),
|
|
7301
7583
|
memoryDir: parsed.memoryDir,
|
|
7302
7584
|
qmdPath: parsed.qmdPath,
|
|
7303
7585
|
collection: parsed.collection,
|
|
@@ -7567,15 +7849,15 @@ registerPublisher("hermes", () => new HermesMemoryExtensionPublisher());
|
|
|
7567
7849
|
registerPublisher("pi", () => new LazyPluginPiPublisher("pi", (mod) => mod.PiMemoryExtensionPublisher));
|
|
7568
7850
|
registerPublisher("omp", () => new LazyPluginPiPublisher("omp", (mod) => mod.OmpMemoryExtensionPublisher));
|
|
7569
7851
|
registerPublisher("prime-agent", () => new LazyPluginPiPublisher("prime-agent", (mod) => mod.PrimeAgentMemoryExtensionPublisher));
|
|
7570
|
-
var PID_DIR =
|
|
7571
|
-
var LEGACY_PID_DIR =
|
|
7572
|
-
var PID_FILE =
|
|
7573
|
-
var LEGACY_PID_FILE =
|
|
7574
|
-
var LOG_FILE =
|
|
7575
|
-
var LEGACY_LOG_FILE =
|
|
7576
|
-
var CLI_MODULE_DIR =
|
|
7577
|
-
var CLI_REPO_ROOT =
|
|
7578
|
-
var EVAL_RUNNER_PATH =
|
|
7852
|
+
var PID_DIR = path19.join(resolveHomeDir(), ".remnic");
|
|
7853
|
+
var LEGACY_PID_DIR = path19.join(resolveHomeDir(), ".engram");
|
|
7854
|
+
var PID_FILE = path19.join(PID_DIR, "server.pid");
|
|
7855
|
+
var LEGACY_PID_FILE = path19.join(LEGACY_PID_DIR, "server.pid");
|
|
7856
|
+
var LOG_FILE = path19.join(PID_DIR, "server.log");
|
|
7857
|
+
var LEGACY_LOG_FILE = path19.join(LEGACY_PID_DIR, "server.log");
|
|
7858
|
+
var CLI_MODULE_DIR = path19.dirname(fileURLToPath5(import.meta.url));
|
|
7859
|
+
var CLI_REPO_ROOT = path19.resolve(CLI_MODULE_DIR, "../../..");
|
|
7860
|
+
var EVAL_RUNNER_PATH = path19.join(CLI_REPO_ROOT, "evals", "run.ts");
|
|
7579
7861
|
var OPENCLAW_GATEWAY_LABEL = "ai.openclaw.gateway";
|
|
7580
7862
|
var CLI_SUCCESS_EXIT_GRACE_MS = 5e3;
|
|
7581
7863
|
var CLI_OUTPUT_FLUSH_GRACE_MS = 250;
|
|
@@ -7740,7 +8022,7 @@ async function resolveAllBenchmarks() {
|
|
|
7740
8022
|
if (packageBenchmarks) {
|
|
7741
8023
|
return packageBenchmarks.filter((entry) => entry.runnerAvailable).map((entry) => entry.id);
|
|
7742
8024
|
}
|
|
7743
|
-
if (!
|
|
8025
|
+
if (!fs26.existsSync(EVAL_RUNNER_PATH)) {
|
|
7744
8026
|
return [];
|
|
7745
8027
|
}
|
|
7746
8028
|
return BENCHMARK_CATALOG.filter((entry) => entry.category !== "ingestion").map((entry) => entry.id);
|
|
@@ -7788,17 +8070,17 @@ async function runBenchViaFallback(parsed, benchmarkId, runtimeProfile) {
|
|
|
7788
8070
|
`Fallback benchmark runner does not support provider-backed, gateway, or thinking/timeout flags (${unsupportedOptions.join(", ")}). Build/install @remnic/bench to use those options.`
|
|
7789
8071
|
);
|
|
7790
8072
|
}
|
|
7791
|
-
if (!
|
|
8073
|
+
if (!fs26.existsSync(EVAL_RUNNER_PATH)) {
|
|
7792
8074
|
console.error(
|
|
7793
8075
|
"Benchmark runner not found. Expected eval runner at evals/run.ts or a phase-1 @remnic/bench runtime export."
|
|
7794
8076
|
);
|
|
7795
8077
|
process.exit(1);
|
|
7796
8078
|
}
|
|
7797
8079
|
const tsxCandidates = [
|
|
7798
|
-
|
|
7799
|
-
|
|
8080
|
+
path19.join(CLI_REPO_ROOT, "node_modules", ".bin", "tsx"),
|
|
8081
|
+
path19.join(CLI_REPO_ROOT, "packages", "remnic-cli", "node_modules", ".bin", "tsx")
|
|
7800
8082
|
];
|
|
7801
|
-
const tsxCmd = tsxCandidates.find((candidate) =>
|
|
8083
|
+
const tsxCmd = tsxCandidates.find((candidate) => fs26.existsSync(candidate)) ?? "tsx";
|
|
7802
8084
|
const fallbackOutputDir = createFallbackBenchOutputDir(
|
|
7803
8085
|
parsed.resultsDir ?? resolveBenchOutputDir(),
|
|
7804
8086
|
benchmarkId,
|
|
@@ -7815,7 +8097,7 @@ async function runBenchViaFallback(parsed, benchmarkId, runtimeProfile) {
|
|
|
7815
8097
|
return resolveFallbackBenchResultPath(fallbackOutputDir);
|
|
7816
8098
|
}
|
|
7817
8099
|
function resolveBenchOutputDir() {
|
|
7818
|
-
return
|
|
8100
|
+
return path19.join(resolveHomeDir(), ".remnic", "bench", "results");
|
|
7819
8101
|
}
|
|
7820
8102
|
var DOWNLOADABLE_BENCHMARK_DATASETS = [
|
|
7821
8103
|
"ama-bench",
|
|
@@ -7860,8 +8142,8 @@ var MEMORY_AGENT_BENCH_SPLIT_FILENAMES = [
|
|
|
7860
8142
|
];
|
|
7861
8143
|
var MEMORY_AGENT_BENCH_ENTITY_MAPPING_CANDIDATES = [
|
|
7862
8144
|
"entity2id.json",
|
|
7863
|
-
|
|
7864
|
-
|
|
8145
|
+
path19.join("processed_data", "Recsys_Redial", "entity2id.json"),
|
|
8146
|
+
path19.join("Recsys_Redial", "entity2id.json")
|
|
7865
8147
|
];
|
|
7866
8148
|
var DOWNLOADED_DATASET_MARKERS = {
|
|
7867
8149
|
"ama-bench": { anyOf: ["open_end_qa_set.jsonl"] },
|
|
@@ -7936,18 +8218,18 @@ var PERSONAMEM_DATASET_FILE_CANDIDATES = [
|
|
|
7936
8218
|
"benchmark/benchmark.csv",
|
|
7937
8219
|
"benchmark.csv"
|
|
7938
8220
|
];
|
|
7939
|
-
var PERSONAMEM_COMPLETION_MARKER =
|
|
8221
|
+
var PERSONAMEM_COMPLETION_MARKER = path19.join(
|
|
7940
8222
|
"data",
|
|
7941
8223
|
"chat_history_32k",
|
|
7942
8224
|
".download-complete"
|
|
7943
8225
|
);
|
|
7944
8226
|
function resolveRealpathWithinDataset(datasetPath, relativePath) {
|
|
7945
8227
|
try {
|
|
7946
|
-
const datasetRoot =
|
|
7947
|
-
const candidatePath =
|
|
7948
|
-
const candidateRealPath =
|
|
7949
|
-
const relativeToRoot =
|
|
7950
|
-
if (relativeToRoot.startsWith("..") ||
|
|
8228
|
+
const datasetRoot = fs26.realpathSync(datasetPath);
|
|
8229
|
+
const candidatePath = path19.resolve(datasetRoot, relativePath);
|
|
8230
|
+
const candidateRealPath = fs26.realpathSync(candidatePath);
|
|
8231
|
+
const relativeToRoot = path19.relative(datasetRoot, candidateRealPath);
|
|
8232
|
+
if (relativeToRoot.startsWith("..") || path19.isAbsolute(relativeToRoot)) {
|
|
7951
8233
|
return null;
|
|
7952
8234
|
}
|
|
7953
8235
|
return candidateRealPath;
|
|
@@ -8003,15 +8285,15 @@ function parseCsvRows(raw) {
|
|
|
8003
8285
|
}
|
|
8004
8286
|
function isPersonaMemDatasetComplete(datasetPath) {
|
|
8005
8287
|
try {
|
|
8006
|
-
const completionMarkerPath =
|
|
8007
|
-
if (
|
|
8288
|
+
const completionMarkerPath = path19.join(datasetPath, PERSONAMEM_COMPLETION_MARKER);
|
|
8289
|
+
if (fs26.statSync(completionMarkerPath).isFile()) {
|
|
8008
8290
|
return true;
|
|
8009
8291
|
}
|
|
8010
8292
|
} catch {
|
|
8011
8293
|
}
|
|
8012
8294
|
const datasetFile = PERSONAMEM_DATASET_FILE_CANDIDATES.find((candidate) => {
|
|
8013
8295
|
try {
|
|
8014
|
-
return
|
|
8296
|
+
return fs26.statSync(path19.join(datasetPath, candidate)).isFile();
|
|
8015
8297
|
} catch {
|
|
8016
8298
|
return false;
|
|
8017
8299
|
}
|
|
@@ -8020,7 +8302,7 @@ function isPersonaMemDatasetComplete(datasetPath) {
|
|
|
8020
8302
|
return false;
|
|
8021
8303
|
}
|
|
8022
8304
|
try {
|
|
8023
|
-
const rows = parseCsvRows(
|
|
8305
|
+
const rows = parseCsvRows(fs26.readFileSync(path19.join(datasetPath, datasetFile), "utf8"));
|
|
8024
8306
|
if (rows.length < 2) {
|
|
8025
8307
|
return false;
|
|
8026
8308
|
}
|
|
@@ -8035,7 +8317,7 @@ function isPersonaMemDatasetComplete(datasetPath) {
|
|
|
8035
8317
|
}
|
|
8036
8318
|
return historyPaths.every((relativePath) => {
|
|
8037
8319
|
const resolvedPath = resolveRealpathWithinDataset(datasetPath, relativePath);
|
|
8038
|
-
return resolvedPath !== null &&
|
|
8320
|
+
return resolvedPath !== null && fs26.statSync(resolvedPath).isFile();
|
|
8039
8321
|
});
|
|
8040
8322
|
} catch {
|
|
8041
8323
|
return false;
|
|
@@ -8043,14 +8325,14 @@ function isPersonaMemDatasetComplete(datasetPath) {
|
|
|
8043
8325
|
}
|
|
8044
8326
|
function hasDatasetFile(datasetPath, relativePath) {
|
|
8045
8327
|
try {
|
|
8046
|
-
return
|
|
8328
|
+
return fs26.statSync(path19.join(datasetPath, relativePath)).isFile();
|
|
8047
8329
|
} catch {
|
|
8048
8330
|
return false;
|
|
8049
8331
|
}
|
|
8050
8332
|
}
|
|
8051
8333
|
function hasMemoryAgentBenchEntityMapping(datasetPath) {
|
|
8052
|
-
const absoluteDatasetPath =
|
|
8053
|
-
const roots = [absoluteDatasetPath,
|
|
8334
|
+
const absoluteDatasetPath = path19.resolve(datasetPath);
|
|
8335
|
+
const roots = [absoluteDatasetPath, path19.dirname(absoluteDatasetPath)];
|
|
8054
8336
|
return hasDatasetFile(absoluteDatasetPath, "entity2id.json") || roots.some(
|
|
8055
8337
|
(root) => MEMORY_AGENT_BENCH_ENTITY_MAPPING_CANDIDATES.filter((relativePath) => relativePath !== "entity2id.json").some((relativePath) => hasDatasetFile(root, relativePath))
|
|
8056
8338
|
);
|
|
@@ -8061,12 +8343,12 @@ function memoryAgentBenchDatasetHasRecSysSamples(datasetPath) {
|
|
|
8061
8343
|
...MEMORY_AGENT_BENCH_SPLIT_FILENAMES
|
|
8062
8344
|
];
|
|
8063
8345
|
return candidateFilenames.some((filename) => {
|
|
8064
|
-
const filePath =
|
|
8346
|
+
const filePath = path19.join(datasetPath, filename);
|
|
8065
8347
|
try {
|
|
8066
|
-
if (!
|
|
8348
|
+
if (!fs26.statSync(filePath).isFile()) {
|
|
8067
8349
|
return false;
|
|
8068
8350
|
}
|
|
8069
|
-
const raw =
|
|
8351
|
+
const raw = fs26.readFileSync(filePath, "utf8");
|
|
8070
8352
|
return /"source"\s*:\s*"recsys[_-]/i.test(raw);
|
|
8071
8353
|
} catch {
|
|
8072
8354
|
return false;
|
|
@@ -8082,7 +8364,7 @@ function isMemoryAgentBenchDatasetComplete(datasetPath) {
|
|
|
8082
8364
|
function isDatasetDownloaded(datasetPath, benchmarkId) {
|
|
8083
8365
|
let stats;
|
|
8084
8366
|
try {
|
|
8085
|
-
stats =
|
|
8367
|
+
stats = fs26.statSync(datasetPath);
|
|
8086
8368
|
} catch {
|
|
8087
8369
|
return false;
|
|
8088
8370
|
}
|
|
@@ -8092,7 +8374,7 @@ function isDatasetDownloaded(datasetPath, benchmarkId) {
|
|
|
8092
8374
|
const marker = DOWNLOADED_DATASET_MARKERS[benchmarkId];
|
|
8093
8375
|
if (!marker) {
|
|
8094
8376
|
try {
|
|
8095
|
-
return
|
|
8377
|
+
return fs26.readdirSync(datasetPath).length > 0;
|
|
8096
8378
|
} catch {
|
|
8097
8379
|
return false;
|
|
8098
8380
|
}
|
|
@@ -8100,7 +8382,7 @@ function isDatasetDownloaded(datasetPath, benchmarkId) {
|
|
|
8100
8382
|
if (marker.allOf) {
|
|
8101
8383
|
const hasAllRequiredFiles = marker.allOf.every((name) => {
|
|
8102
8384
|
try {
|
|
8103
|
-
return
|
|
8385
|
+
return fs26.statSync(path19.join(datasetPath, name)).isFile();
|
|
8104
8386
|
} catch {
|
|
8105
8387
|
return false;
|
|
8106
8388
|
}
|
|
@@ -8112,7 +8394,7 @@ function isDatasetDownloaded(datasetPath, benchmarkId) {
|
|
|
8112
8394
|
if (marker.anyOf) {
|
|
8113
8395
|
const hasMarkerFile = marker.anyOf.some((name) => {
|
|
8114
8396
|
try {
|
|
8115
|
-
return
|
|
8397
|
+
return fs26.statSync(path19.join(datasetPath, name)).isFile();
|
|
8116
8398
|
} catch {
|
|
8117
8399
|
return false;
|
|
8118
8400
|
}
|
|
@@ -8130,7 +8412,7 @@ function isDatasetDownloaded(datasetPath, benchmarkId) {
|
|
|
8130
8412
|
}
|
|
8131
8413
|
if (marker.ext) {
|
|
8132
8414
|
try {
|
|
8133
|
-
return
|
|
8415
|
+
return fs26.readdirSync(datasetPath).some(
|
|
8134
8416
|
(name) => name.endsWith(marker.ext) && !marker.exclude?.includes(name)
|
|
8135
8417
|
);
|
|
8136
8418
|
} catch {
|
|
@@ -8140,9 +8422,9 @@ function isDatasetDownloaded(datasetPath, benchmarkId) {
|
|
|
8140
8422
|
return false;
|
|
8141
8423
|
}
|
|
8142
8424
|
async function launchBenchUi(resultsDir) {
|
|
8143
|
-
const benchUiDir =
|
|
8425
|
+
const benchUiDir = path19.join(CLI_REPO_ROOT, "packages", "bench-ui");
|
|
8144
8426
|
const pnpmCmd = process.platform === "win32" ? "pnpm.cmd" : "pnpm";
|
|
8145
|
-
if (!
|
|
8427
|
+
if (!fs26.existsSync(path19.join(benchUiDir, "package.json"))) {
|
|
8146
8428
|
console.error("ERROR: @remnic/bench-ui is not available in this checkout.");
|
|
8147
8429
|
process.exit(1);
|
|
8148
8430
|
}
|
|
@@ -8169,24 +8451,24 @@ async function launchBenchUi(resultsDir) {
|
|
|
8169
8451
|
});
|
|
8170
8452
|
}
|
|
8171
8453
|
function resolveRepoDatasetRoot() {
|
|
8172
|
-
const repoCandidate =
|
|
8454
|
+
const repoCandidate = path19.join(CLI_REPO_ROOT, "evals", "datasets");
|
|
8173
8455
|
if (isRepoCheckout()) {
|
|
8174
8456
|
return repoCandidate;
|
|
8175
8457
|
}
|
|
8176
|
-
return
|
|
8458
|
+
return path19.join(resolveHomeDir(), ".remnic", "bench", "datasets");
|
|
8177
8459
|
}
|
|
8178
8460
|
function listDownloadableBenchmarks() {
|
|
8179
8461
|
return [...DOWNLOADABLE_BENCHMARK_DATASETS];
|
|
8180
8462
|
}
|
|
8181
8463
|
function resolveDatasetDownloadScriptPath() {
|
|
8182
|
-
const bundled =
|
|
8183
|
-
if (
|
|
8464
|
+
const bundled = path19.join(CLI_MODULE_DIR, "assets", "download-datasets.sh");
|
|
8465
|
+
if (fs26.existsSync(bundled)) {
|
|
8184
8466
|
return bundled;
|
|
8185
8467
|
}
|
|
8186
|
-
return
|
|
8468
|
+
return path19.join(CLI_REPO_ROOT, "evals", "scripts", "download-datasets.sh");
|
|
8187
8469
|
}
|
|
8188
8470
|
function isRepoCheckout() {
|
|
8189
|
-
return
|
|
8471
|
+
return fs26.existsSync(path19.join(CLI_REPO_ROOT, "pnpm-workspace.yaml")) && fs26.existsSync(path19.join(CLI_REPO_ROOT, "evals", "scripts", "download-datasets.sh"));
|
|
8190
8472
|
}
|
|
8191
8473
|
function runDatasetDownloadScript(scriptPath, benchmarkId, datasetRoot, jsonMode) {
|
|
8192
8474
|
const stdio = jsonMode ? ["inherit", process.stderr, "inherit"] : "inherit";
|
|
@@ -8237,7 +8519,7 @@ function resolveBenchDatasetDir(benchmarkId, quick, datasetDirOverride) {
|
|
|
8237
8519
|
if (quick) {
|
|
8238
8520
|
return void 0;
|
|
8239
8521
|
}
|
|
8240
|
-
const datasetDir =
|
|
8522
|
+
const datasetDir = path19.join(resolveRepoDatasetRoot(), benchmarkId);
|
|
8241
8523
|
if (isDatasetDownloaded(datasetDir, benchmarkId)) {
|
|
8242
8524
|
return datasetDir;
|
|
8243
8525
|
}
|
|
@@ -8494,13 +8776,13 @@ async function exportBenchPackageResult(parsed) {
|
|
|
8494
8776
|
process.exit(1);
|
|
8495
8777
|
}
|
|
8496
8778
|
const result = await loadBenchmarkResult(summary.path);
|
|
8497
|
-
const reportCardProvenance = parsed.format === "html" ? await loadBenchmarkReportCardProvenance(
|
|
8779
|
+
const reportCardProvenance = parsed.format === "html" ? await loadBenchmarkReportCardProvenance(path19.dirname(summary.path), result.meta.id) : void 0;
|
|
8498
8780
|
const rendered = renderBenchmarkResultExport(result, parsed.format, {
|
|
8499
8781
|
...reportCardProvenance ? { reportCardProvenance } : {}
|
|
8500
8782
|
});
|
|
8501
8783
|
if (parsed.output) {
|
|
8502
|
-
|
|
8503
|
-
|
|
8784
|
+
fs26.mkdirSync(path19.dirname(parsed.output), { recursive: true });
|
|
8785
|
+
fs26.writeFileSync(parsed.output, rendered);
|
|
8504
8786
|
console.log(`Exported ${summary.id} as ${parsed.format} to ${parsed.output}`);
|
|
8505
8787
|
return;
|
|
8506
8788
|
}
|
|
@@ -8517,7 +8799,7 @@ async function manageBenchDatasets(parsed) {
|
|
|
8517
8799
|
process.exit(1);
|
|
8518
8800
|
}
|
|
8519
8801
|
const status = supported.map((benchmarkId) => {
|
|
8520
|
-
const datasetPath =
|
|
8802
|
+
const datasetPath = path19.join(datasetRoot, benchmarkId);
|
|
8521
8803
|
return {
|
|
8522
8804
|
benchmark: benchmarkId,
|
|
8523
8805
|
downloaded: isDatasetDownloaded(datasetPath, benchmarkId),
|
|
@@ -8545,7 +8827,7 @@ async function manageBenchDatasets(parsed) {
|
|
|
8545
8827
|
process.exit(1);
|
|
8546
8828
|
}
|
|
8547
8829
|
const scriptPath = resolveDatasetDownloadScriptPath();
|
|
8548
|
-
if (!
|
|
8830
|
+
if (!fs26.existsSync(scriptPath)) {
|
|
8549
8831
|
console.error(`ERROR: dataset download script not found: ${scriptPath}`);
|
|
8550
8832
|
process.exit(1);
|
|
8551
8833
|
}
|
|
@@ -8555,7 +8837,7 @@ async function manageBenchDatasets(parsed) {
|
|
|
8555
8837
|
runDatasetDownloadScript(scriptPath, benchmarkId, datasetRoot, parsed.json === true);
|
|
8556
8838
|
downloaded.push({
|
|
8557
8839
|
benchmark: benchmarkId,
|
|
8558
|
-
path:
|
|
8840
|
+
path: path19.join(datasetRoot, benchmarkId)
|
|
8559
8841
|
});
|
|
8560
8842
|
}
|
|
8561
8843
|
if (parsed.json) {
|
|
@@ -8694,10 +8976,10 @@ async function calibrateBenchJudges(parsed, rawArgs) {
|
|
|
8694
8976
|
}
|
|
8695
8977
|
const bench = await loadBenchModule();
|
|
8696
8978
|
const resultsDir = expandTilde(
|
|
8697
|
-
parsed.resultsDir ??
|
|
8979
|
+
parsed.resultsDir ?? path19.join(resolveHomeDir(), ".remnic", "bench", "results")
|
|
8698
8980
|
);
|
|
8699
8981
|
const calibrationDir = expandTilde(
|
|
8700
|
-
parsed.calibrationDir ??
|
|
8982
|
+
parsed.calibrationDir ?? path19.join(resolveHomeDir(), ".remnic", "bench", "calibration")
|
|
8701
8983
|
);
|
|
8702
8984
|
const stored = await bench.listBenchmarkResults(resultsDir);
|
|
8703
8985
|
const allForBenchmark = stored.filter((entry) => entry.benchmark === benchmarkId);
|
|
@@ -8745,7 +9027,7 @@ async function calibrateBenchJudges(parsed, rawArgs) {
|
|
|
8745
9027
|
);
|
|
8746
9028
|
process.exit(1);
|
|
8747
9029
|
}
|
|
8748
|
-
const sourceResultSha256 = createHash4("sha256").update(
|
|
9030
|
+
const sourceResultSha256 = createHash4("sha256").update(fs26.readFileSync(latest.path)).digest("hex");
|
|
8749
9031
|
const expandedManifestPath = expandTilde(manifestPath);
|
|
8750
9032
|
if (!bench.resolveLocalLabJudgeProviderConfig) {
|
|
8751
9033
|
console.error(
|
|
@@ -9160,7 +9442,7 @@ function loadPinnedLoCoMoTaskSelector(parsed) {
|
|
|
9160
9442
|
}
|
|
9161
9443
|
let decoded;
|
|
9162
9444
|
try {
|
|
9163
|
-
decoded = JSON.parse(
|
|
9445
|
+
decoded = JSON.parse(fs26.readFileSync(parsed.taskIdsFile, "utf8"));
|
|
9164
9446
|
} catch (error) {
|
|
9165
9447
|
throw new Error(
|
|
9166
9448
|
`Unable to read --task-ids-file ${parsed.taskIdsFile}: ${error instanceof Error ? error.message : String(error)}`
|
|
@@ -9257,7 +9539,7 @@ async function loadPublishedPromotionHelpers() {
|
|
|
9257
9539
|
return {
|
|
9258
9540
|
async promoteArtifactsToPublished(args) {
|
|
9259
9541
|
const { mkdirSync, readFileSync: readFileSync4, writeFileSync } = await import("fs");
|
|
9260
|
-
const
|
|
9542
|
+
const path20 = await import("path");
|
|
9261
9543
|
mkdirSync(args.publishedOutDir, { recursive: true });
|
|
9262
9544
|
if (args.artifactPaths.length === 0) {
|
|
9263
9545
|
console.warn(
|
|
@@ -9274,13 +9556,13 @@ async function loadPublishedPromotionHelpers() {
|
|
|
9274
9556
|
const modelSlug = args.model.replace(/[^a-zA-Z0-9_.-]/g, "-");
|
|
9275
9557
|
const rawProfile = parsedObj.config?.runtimeProfile;
|
|
9276
9558
|
const profileSlug = typeof rawProfile === "string" && rawProfile.length > 0 ? `-${rawProfile.replace(/[^a-zA-Z0-9_.-]/g, "-")}` : "";
|
|
9277
|
-
const target =
|
|
9559
|
+
const target = path20.join(
|
|
9278
9560
|
args.publishedOutDir,
|
|
9279
9561
|
`${today}-${args.benchmarkId}-${modelSlug}${profileSlug}-${gitShaShort}.json`
|
|
9280
9562
|
);
|
|
9281
9563
|
writeFileSync(target, raw, "utf8");
|
|
9282
9564
|
console.log(
|
|
9283
|
-
`[bench published] Promoted ${
|
|
9565
|
+
`[bench published] Promoted ${path20.basename(artifactPath)} \u2192 ${target}`
|
|
9284
9566
|
);
|
|
9285
9567
|
}
|
|
9286
9568
|
void benchModule;
|
|
@@ -9387,7 +9669,7 @@ async function runBenchViaPackage(parsed, benchmarkId, runtimeProfile, benchStat
|
|
|
9387
9669
|
const previousCodexDiagnosticsDir = process.env[CODEX_CLI_BENCH_DIAGNOSTICS_DIR_ENV];
|
|
9388
9670
|
const previousCodexDiagnosticsMode = process.env[CODEX_CLI_BENCH_DIAGNOSTICS_MODE_ENV];
|
|
9389
9671
|
if (!previousCodexDiagnosticsDir) {
|
|
9390
|
-
process.env[CODEX_CLI_BENCH_DIAGNOSTICS_DIR_ENV] =
|
|
9672
|
+
process.env[CODEX_CLI_BENCH_DIAGNOSTICS_DIR_ENV] = path19.join(
|
|
9391
9673
|
outputDir,
|
|
9392
9674
|
"codex-cli-diagnostics"
|
|
9393
9675
|
);
|
|
@@ -9537,7 +9819,7 @@ async function preparePersistedJudgeCalibrationAttachment(benchModule, benchmark
|
|
|
9537
9819
|
);
|
|
9538
9820
|
}
|
|
9539
9821
|
const calibrationDir = expandTilde(
|
|
9540
|
-
calibrationBinding.calibrationDir ??
|
|
9822
|
+
calibrationBinding.calibrationDir ?? path19.join(resolveHomeDir(), ".remnic", "bench", "calibration")
|
|
9541
9823
|
);
|
|
9542
9824
|
const state = await benchModule.loadJudgeCalibrationState?.(benchmarkId, calibrationDir);
|
|
9543
9825
|
if (!state) {
|
|
@@ -9835,7 +10117,7 @@ function resolveBenchReproDatasetDir(datasetDir) {
|
|
|
9835
10117
|
return void 0;
|
|
9836
10118
|
}
|
|
9837
10119
|
try {
|
|
9838
|
-
return
|
|
10120
|
+
return fs26.realpathSync(datasetDir);
|
|
9839
10121
|
} catch {
|
|
9840
10122
|
return datasetDir;
|
|
9841
10123
|
}
|
|
@@ -9889,13 +10171,13 @@ async function writeBenchReproManifestForPackageRun(args) {
|
|
|
9889
10171
|
}
|
|
9890
10172
|
function loadStandaloneConvergeCommandConfig() {
|
|
9891
10173
|
const configPath = resolveConfigPath();
|
|
9892
|
-
const raw =
|
|
9893
|
-
return
|
|
10174
|
+
const raw = fs26.existsSync(configPath) ? JSON.parse(fs26.readFileSync(configPath, "utf8")) : {};
|
|
10175
|
+
return parseConfig17(resolveRemnicConfigRecord16(raw));
|
|
9894
10176
|
}
|
|
9895
10177
|
function parseConvergePluginConfig(value) {
|
|
9896
10178
|
if (value === null || typeof value !== "object" || Array.isArray(value)) return void 0;
|
|
9897
10179
|
if (Object.keys(value).length === 0) return void 0;
|
|
9898
|
-
return
|
|
10180
|
+
return parseConfig17(resolveRemnicConfigRecord16(value));
|
|
9899
10181
|
}
|
|
9900
10182
|
function loadConvergeCommandConfig() {
|
|
9901
10183
|
if (readCompatEnv("REMNIC_CONFIG_PATH", "ENGRAM_CONFIG_PATH")) {
|
|
@@ -9908,23 +10190,23 @@ function loadConvergeCommandConfig() {
|
|
|
9908
10190
|
return loadStandaloneConvergeCommandConfig();
|
|
9909
10191
|
}
|
|
9910
10192
|
function resolveConfigPath(cliPath) {
|
|
9911
|
-
if (cliPath) return
|
|
10193
|
+
if (cliPath) return path19.resolve(expandTilde(cliPath));
|
|
9912
10194
|
const envPath = readCompatEnv("REMNIC_CONFIG_PATH", "ENGRAM_CONFIG_PATH");
|
|
9913
|
-
if (envPath) return
|
|
10195
|
+
if (envPath) return path19.resolve(expandTilde(envPath));
|
|
9914
10196
|
const candidates = [
|
|
9915
|
-
|
|
9916
|
-
|
|
9917
|
-
|
|
9918
|
-
|
|
10197
|
+
path19.join(process.cwd(), "remnic.config.json"),
|
|
10198
|
+
path19.join(process.cwd(), "engram.config.json"),
|
|
10199
|
+
path19.join(resolveHomeDir(), ".config", "remnic", "config.json"),
|
|
10200
|
+
path19.join(resolveHomeDir(), ".config", "engram", "config.json")
|
|
9919
10201
|
];
|
|
9920
10202
|
for (const candidate of candidates) {
|
|
9921
|
-
if (
|
|
10203
|
+
if (fs26.existsSync(candidate)) return candidate;
|
|
9922
10204
|
}
|
|
9923
|
-
return
|
|
10205
|
+
return path19.join(resolveHomeDir(), ".config", "remnic", "config.json");
|
|
9924
10206
|
}
|
|
9925
10207
|
function resolveExistingBenchRemnicConfigPath(cliPath) {
|
|
9926
10208
|
const configPath = resolveConfigPath(cliPath);
|
|
9927
|
-
if (
|
|
10209
|
+
if (fs26.existsSync(configPath)) {
|
|
9928
10210
|
return configPath;
|
|
9929
10211
|
}
|
|
9930
10212
|
if (cliPath) {
|
|
@@ -9934,7 +10216,7 @@ function resolveExistingBenchRemnicConfigPath(cliPath) {
|
|
|
9934
10216
|
}
|
|
9935
10217
|
function resolveExistingBenchOpenclawConfigPath(cliPath) {
|
|
9936
10218
|
const configPath = resolveOpenclawConfigPath(cliPath);
|
|
9937
|
-
if (
|
|
10219
|
+
if (fs26.existsSync(configPath)) {
|
|
9938
10220
|
return configPath;
|
|
9939
10221
|
}
|
|
9940
10222
|
if (cliPath) {
|
|
@@ -10034,34 +10316,34 @@ async function resolvePackageBenchRuntime(benchModule, parsed, runtimeProfile) {
|
|
|
10034
10316
|
);
|
|
10035
10317
|
}
|
|
10036
10318
|
function normalizeMemoryDirPath(memoryDir) {
|
|
10037
|
-
return
|
|
10319
|
+
return path19.resolve(expandTilde(memoryDir));
|
|
10038
10320
|
}
|
|
10039
10321
|
function resolveMemoryDir() {
|
|
10040
10322
|
const configMemoryDir = (() => {
|
|
10041
10323
|
const envMemoryDir = readCompatEnv("REMNIC_MEMORY_DIR", "ENGRAM_MEMORY_DIR");
|
|
10042
10324
|
if (envMemoryDir) return normalizeMemoryDirPath(envMemoryDir);
|
|
10043
10325
|
const configPath = resolveConfigPath();
|
|
10044
|
-
const raw =
|
|
10045
|
-
const remnicCfg =
|
|
10326
|
+
const raw = fs26.existsSync(configPath) ? JSON.parse(fs26.readFileSync(configPath, "utf8")) : {};
|
|
10327
|
+
const remnicCfg = resolveRemnicConfigRecord16(raw);
|
|
10046
10328
|
if (typeof remnicCfg.memoryDir === "string" && remnicCfg.memoryDir.length > 0) {
|
|
10047
10329
|
return normalizeMemoryDirPath(remnicCfg.memoryDir);
|
|
10048
10330
|
}
|
|
10049
10331
|
const home = resolveHomeDir();
|
|
10050
|
-
const standalonePath =
|
|
10051
|
-
const legacyStandalonePath =
|
|
10052
|
-
const openclawPath =
|
|
10053
|
-
if (
|
|
10054
|
-
if (
|
|
10332
|
+
const standalonePath = path19.join(home, ".remnic", "memory");
|
|
10333
|
+
const legacyStandalonePath = path19.join(home, ".engram", "memory");
|
|
10334
|
+
const openclawPath = path19.join(resolveOpenclawStateDir(), "workspace", "memory", "local");
|
|
10335
|
+
if (fs26.existsSync(standalonePath)) return standalonePath;
|
|
10336
|
+
if (fs26.existsSync(legacyStandalonePath)) return legacyStandalonePath;
|
|
10055
10337
|
return openclawPath;
|
|
10056
10338
|
})();
|
|
10057
10339
|
const manifestPath = getManifestPath();
|
|
10058
|
-
if (
|
|
10340
|
+
if (fs26.existsSync(manifestPath)) {
|
|
10059
10341
|
try {
|
|
10060
10342
|
const active = getActiveSpace();
|
|
10061
10343
|
if (active?.memoryDir) {
|
|
10062
10344
|
const activeMemoryDir = normalizeMemoryDirPath(active.memoryDir);
|
|
10063
|
-
if (!
|
|
10064
|
-
|
|
10345
|
+
if (!fs26.existsSync(activeMemoryDir)) {
|
|
10346
|
+
fs26.mkdirSync(activeMemoryDir, { recursive: true });
|
|
10065
10347
|
}
|
|
10066
10348
|
return activeMemoryDir;
|
|
10067
10349
|
}
|
|
@@ -10098,25 +10380,25 @@ function resolveFlagStrict(args, flag) {
|
|
|
10098
10380
|
var REMNIC_OPENCLAW_LEGACY_PLUGIN_ID = "openclaw-engram";
|
|
10099
10381
|
function resolveOpenclawStateDir() {
|
|
10100
10382
|
const configuredStateDir = process.env.OPENCLAW_STATE_DIR?.trim();
|
|
10101
|
-
return configuredStateDir ?
|
|
10383
|
+
return configuredStateDir ? path19.resolve(expandTilde(configuredStateDir)) : path19.join(resolveHomeDir(), ".openclaw");
|
|
10102
10384
|
}
|
|
10103
10385
|
var DEFAULT_OPENCLAW_CONFIG_PATHS_FOR_DOCTOR = [
|
|
10104
10386
|
process.env.OPENCLAW_CONFIG_PATH,
|
|
10105
10387
|
process.env.OPENCLAW_ENGRAM_CONFIG_PATH,
|
|
10106
|
-
|
|
10388
|
+
path19.join(resolveOpenclawStateDir(), "openclaw.json")
|
|
10107
10389
|
].filter(Boolean);
|
|
10108
10390
|
function resolveOpenclawConfigPath(cliPath) {
|
|
10109
|
-
if (cliPath) return
|
|
10391
|
+
if (cliPath) return path19.resolve(expandTilde(cliPath));
|
|
10110
10392
|
const envPath = process.env.OPENCLAW_CONFIG_PATH || process.env.OPENCLAW_ENGRAM_CONFIG_PATH;
|
|
10111
|
-
if (envPath) return
|
|
10393
|
+
if (envPath) return path19.resolve(expandTilde(envPath));
|
|
10112
10394
|
for (const candidate of DEFAULT_OPENCLAW_CONFIG_PATHS_FOR_DOCTOR) {
|
|
10113
|
-
if (
|
|
10395
|
+
if (fs26.existsSync(candidate)) return candidate;
|
|
10114
10396
|
}
|
|
10115
|
-
return
|
|
10397
|
+
return path19.join(resolveOpenclawStateDir(), "openclaw.json");
|
|
10116
10398
|
}
|
|
10117
10399
|
function readOpenclawConfig(configPath) {
|
|
10118
|
-
if (!
|
|
10119
|
-
const raw =
|
|
10400
|
+
if (!fs26.existsSync(configPath)) return {};
|
|
10401
|
+
const raw = fs26.readFileSync(configPath, "utf-8");
|
|
10120
10402
|
let parsed;
|
|
10121
10403
|
try {
|
|
10122
10404
|
parsed = JSON.parse(raw);
|
|
@@ -10171,10 +10453,10 @@ function buildRemnicOpenclawHooksPolicy(legacyHooks, existingHooks) {
|
|
|
10171
10453
|
function resolveOpenclawInstallMemoryDir(args) {
|
|
10172
10454
|
const existingMemoryDir = (typeof args.existingNewEntryConfig.memoryDir === "string" ? args.existingNewEntryConfig.memoryDir : void 0) || (args.migrateLegacy && typeof args.legacyConfigToMerge.memoryDir === "string" ? args.legacyConfigToMerge.memoryDir : void 0);
|
|
10173
10455
|
if (args.requestedMemoryDir) {
|
|
10174
|
-
return
|
|
10456
|
+
return path19.resolve(expandTilde(args.requestedMemoryDir));
|
|
10175
10457
|
}
|
|
10176
10458
|
if (existingMemoryDir) {
|
|
10177
|
-
return
|
|
10459
|
+
return path19.resolve(expandTilde(existingMemoryDir));
|
|
10178
10460
|
}
|
|
10179
10461
|
return args.fallbackMemoryDir;
|
|
10180
10462
|
}
|
|
@@ -10192,21 +10474,21 @@ function resolveCurrentOpenclawMemoryDir(entries, slots, fallbackMemoryDir) {
|
|
|
10192
10474
|
if (!config || typeof config !== "object" || Array.isArray(config)) continue;
|
|
10193
10475
|
const memoryDir = config.memoryDir;
|
|
10194
10476
|
if (typeof memoryDir === "string" && memoryDir.trim().length > 0) {
|
|
10195
|
-
return
|
|
10477
|
+
return path19.resolve(expandTilde(memoryDir));
|
|
10196
10478
|
}
|
|
10197
10479
|
}
|
|
10198
10480
|
return fallbackMemoryDir;
|
|
10199
10481
|
}
|
|
10200
10482
|
function resolveOpenclawPluginDir(cliPath) {
|
|
10201
|
-
if (cliPath) return
|
|
10483
|
+
if (cliPath) return path19.resolve(expandTilde(cliPath));
|
|
10202
10484
|
return resolveOpenclawManagedPluginDir();
|
|
10203
10485
|
}
|
|
10204
10486
|
function resolveOpenclawManagedPluginDir() {
|
|
10205
|
-
return
|
|
10487
|
+
return path19.join(resolveOpenclawStateDir(), "extensions", REMNIC_OPENCLAW_PLUGIN_ID);
|
|
10206
10488
|
}
|
|
10207
10489
|
function resolveOpenclawLegacyPluginDir(cliPath) {
|
|
10208
|
-
if (cliPath) return
|
|
10209
|
-
return
|
|
10490
|
+
if (cliPath) return path19.resolve(expandTilde(cliPath));
|
|
10491
|
+
return path19.join(resolveOpenclawStateDir(), "extensions", REMNIC_OPENCLAW_LEGACY_PLUGIN_ID);
|
|
10210
10492
|
}
|
|
10211
10493
|
function formatOpenclawUpgradeStamp(now = /* @__PURE__ */ new Date()) {
|
|
10212
10494
|
const yyyy = now.getFullYear().toString();
|
|
@@ -10218,9 +10500,9 @@ function formatOpenclawUpgradeStamp(now = /* @__PURE__ */ new Date()) {
|
|
|
10218
10500
|
return `${yyyy}${mm}${dd}-${hh}${min}${ss}`;
|
|
10219
10501
|
}
|
|
10220
10502
|
function backupPathIfPresent(sourcePath, backupPath) {
|
|
10221
|
-
if (!
|
|
10222
|
-
|
|
10223
|
-
|
|
10503
|
+
if (!fs26.existsSync(sourcePath)) return false;
|
|
10504
|
+
fs26.mkdirSync(path19.dirname(backupPath), { recursive: true });
|
|
10505
|
+
fs26.cpSync(sourcePath, backupPath, { recursive: true });
|
|
10224
10506
|
return true;
|
|
10225
10507
|
}
|
|
10226
10508
|
function restartOpenclawGateway() {
|
|
@@ -10238,15 +10520,15 @@ function restartOpenclawGateway() {
|
|
|
10238
10520
|
});
|
|
10239
10521
|
}
|
|
10240
10522
|
function cmdInit() {
|
|
10241
|
-
const configPath =
|
|
10242
|
-
if (
|
|
10523
|
+
const configPath = path19.join(process.cwd(), "remnic.config.json");
|
|
10524
|
+
if (fs26.existsSync(configPath)) {
|
|
10243
10525
|
console.log(`Config already exists: ${configPath}`);
|
|
10244
10526
|
return;
|
|
10245
10527
|
}
|
|
10246
10528
|
const template = {
|
|
10247
10529
|
remnic: {
|
|
10248
10530
|
openaiApiKey: "${OPENAI_API_KEY}",
|
|
10249
|
-
memoryDir:
|
|
10531
|
+
memoryDir: path19.join(process.cwd(), ".remnic", "memory"),
|
|
10250
10532
|
memoryOsPreset: "balanced"
|
|
10251
10533
|
},
|
|
10252
10534
|
server: {
|
|
@@ -10255,7 +10537,7 @@ function cmdInit() {
|
|
|
10255
10537
|
authToken: "${REMNIC_AUTH_TOKEN}"
|
|
10256
10538
|
}
|
|
10257
10539
|
};
|
|
10258
|
-
|
|
10540
|
+
fs26.writeFileSync(configPath, JSON.stringify(template, null, 2) + "\n");
|
|
10259
10541
|
console.log(`Created ${configPath}`);
|
|
10260
10542
|
console.log("\nSet these environment variables:");
|
|
10261
10543
|
console.log(" export OPENAI_API_KEY=sk-...");
|
|
@@ -10308,7 +10590,7 @@ async function cmdStatus(json) {
|
|
|
10308
10590
|
console.log(`Remnic server: running${pid ? ` (pid ${pid})` : ""}`);
|
|
10309
10591
|
await printHealthCheck(resolveDaemonBaseUrl(resolveConfigPath()), resolveStatusProbeToken());
|
|
10310
10592
|
}
|
|
10311
|
-
async function oauthFetch(method,
|
|
10593
|
+
async function oauthFetch(method, path20, token, body) {
|
|
10312
10594
|
const controller = new AbortController();
|
|
10313
10595
|
const timeoutId = setTimeout(() => controller.abort(), 5e3);
|
|
10314
10596
|
try {
|
|
@@ -10327,7 +10609,7 @@ async function oauthFetch(method, path19, token, body) {
|
|
|
10327
10609
|
if (body !== void 0) {
|
|
10328
10610
|
init.body = JSON.stringify(body);
|
|
10329
10611
|
}
|
|
10330
|
-
const response = await fetch(`${resolveDaemonBaseUrl(resolveConfigPath())}${
|
|
10612
|
+
const response = await fetch(`${resolveDaemonBaseUrl(resolveConfigPath())}${path20}`, init);
|
|
10331
10613
|
if (response.status === 401) {
|
|
10332
10614
|
throw new Error(
|
|
10333
10615
|
"operator token rejected by remnic-server (HTTP 401). Update `server.authToken` or `REMNIC_AUTH_TOKEN` to match the running daemon."
|
|
@@ -10677,10 +10959,10 @@ async function cmdQuery(queryText, json, explain) {
|
|
|
10677
10959
|
}
|
|
10678
10960
|
initLogger5();
|
|
10679
10961
|
const configPath = resolveConfigPath();
|
|
10680
|
-
const raw =
|
|
10681
|
-
const remnicCfg =
|
|
10682
|
-
const config =
|
|
10683
|
-
const orchestrator = new
|
|
10962
|
+
const raw = fs26.existsSync(configPath) ? JSON.parse(fs26.readFileSync(configPath, "utf8")) : {};
|
|
10963
|
+
const remnicCfg = resolveRemnicConfigRecord16(raw);
|
|
10964
|
+
const config = parseConfig17(remnicCfg);
|
|
10965
|
+
const orchestrator = new Orchestrator10(config);
|
|
10684
10966
|
await orchestrator.initialize();
|
|
10685
10967
|
const service = new EngramAccessService2(orchestrator);
|
|
10686
10968
|
const recallRequest = buildQueryRecallRequest(queryText);
|
|
@@ -10857,10 +11139,10 @@ async function cmdXray(rest) {
|
|
|
10857
11139
|
}
|
|
10858
11140
|
initLogger5();
|
|
10859
11141
|
const configPath = resolveConfigPath();
|
|
10860
|
-
const raw =
|
|
10861
|
-
const remnicCfg =
|
|
10862
|
-
const config =
|
|
10863
|
-
const orchestrator = new
|
|
11142
|
+
const raw = fs26.existsSync(configPath) ? JSON.parse(fs26.readFileSync(configPath, "utf8")) : {};
|
|
11143
|
+
const remnicCfg = resolveRemnicConfigRecord16(raw);
|
|
11144
|
+
const config = parseConfig17(remnicCfg);
|
|
11145
|
+
const orchestrator = new Orchestrator10(config);
|
|
10864
11146
|
await orchestrator.initialize();
|
|
10865
11147
|
await orchestrator.deferredReady;
|
|
10866
11148
|
const service = new EngramAccessService2(orchestrator);
|
|
@@ -10890,8 +11172,8 @@ async function runWhoKnowsCommand(rest, io) {
|
|
|
10890
11172
|
async function withLocalService(fn) {
|
|
10891
11173
|
initLogger5();
|
|
10892
11174
|
const configPath = resolveConfigPath();
|
|
10893
|
-
const raw =
|
|
10894
|
-
const orchestrator = new
|
|
11175
|
+
const raw = fs26.existsSync(configPath) ? JSON.parse(fs26.readFileSync(configPath, "utf8")) : {};
|
|
11176
|
+
const orchestrator = new Orchestrator10(parseConfig17(resolveRemnicConfigRecord16(raw)));
|
|
10895
11177
|
await orchestrator.initialize();
|
|
10896
11178
|
await orchestrator.deferredReady;
|
|
10897
11179
|
const service = new EngramAccessService2(orchestrator);
|
|
@@ -10923,9 +11205,9 @@ async function cmdPromotionCandidates(rest) {
|
|
|
10923
11205
|
async function cmdVersions(rest) {
|
|
10924
11206
|
initLogger5();
|
|
10925
11207
|
const configPath = resolveConfigPath();
|
|
10926
|
-
const raw =
|
|
10927
|
-
const remnicCfg =
|
|
10928
|
-
const config =
|
|
11208
|
+
const raw = fs26.existsSync(configPath) ? JSON.parse(fs26.readFileSync(configPath, "utf8")) : {};
|
|
11209
|
+
const remnicCfg = resolveRemnicConfigRecord16(raw);
|
|
11210
|
+
const config = parseConfig17(remnicCfg);
|
|
10929
11211
|
if (!config.versioningEnabled) {
|
|
10930
11212
|
console.error("Page versioning is disabled (versioningEnabled = false).");
|
|
10931
11213
|
process.exit(1);
|
|
@@ -10945,7 +11227,7 @@ async function cmdVersions(rest) {
|
|
|
10945
11227
|
console.error("Usage: remnic versions list <page-path>");
|
|
10946
11228
|
process.exit(1);
|
|
10947
11229
|
}
|
|
10948
|
-
const absPath =
|
|
11230
|
+
const absPath = path19.resolve(pagePath);
|
|
10949
11231
|
const history = await listVersions(absPath, versioningConfig, memDir);
|
|
10950
11232
|
if (json) {
|
|
10951
11233
|
console.log(JSON.stringify(history, null, 2));
|
|
@@ -10970,7 +11252,7 @@ async function cmdVersions(rest) {
|
|
|
10970
11252
|
console.error("Usage: remnic versions show <page-path> <version-id>");
|
|
10971
11253
|
process.exit(1);
|
|
10972
11254
|
}
|
|
10973
|
-
const absPath =
|
|
11255
|
+
const absPath = path19.resolve(pagePath);
|
|
10974
11256
|
try {
|
|
10975
11257
|
const content = await getVersion(absPath, versionId, versioningConfig, memDir);
|
|
10976
11258
|
console.log(content);
|
|
@@ -10988,7 +11270,7 @@ async function cmdVersions(rest) {
|
|
|
10988
11270
|
console.error("Usage: remnic versions diff <page-path> <v1> <v2>");
|
|
10989
11271
|
process.exit(1);
|
|
10990
11272
|
}
|
|
10991
|
-
const absPath =
|
|
11273
|
+
const absPath = path19.resolve(pagePath);
|
|
10992
11274
|
try {
|
|
10993
11275
|
const diffOutput = await diffVersions(absPath, v1, v2, versioningConfig, memDir);
|
|
10994
11276
|
console.log(diffOutput);
|
|
@@ -11005,7 +11287,7 @@ async function cmdVersions(rest) {
|
|
|
11005
11287
|
console.error("Usage: remnic versions revert <page-path> <version-id>");
|
|
11006
11288
|
process.exit(1);
|
|
11007
11289
|
}
|
|
11008
|
-
const absPath =
|
|
11290
|
+
const absPath = path19.resolve(pagePath);
|
|
11009
11291
|
try {
|
|
11010
11292
|
const version = await revertToVersion(absPath, versionId, versioningConfig, void 0, memDir);
|
|
11011
11293
|
if (json) {
|
|
@@ -11039,13 +11321,13 @@ Options:
|
|
|
11039
11321
|
async function cmdEnrich(rest) {
|
|
11040
11322
|
initLogger5();
|
|
11041
11323
|
const configPath = resolveConfigPath();
|
|
11042
|
-
const raw =
|
|
11043
|
-
const remnicCfg =
|
|
11044
|
-
const config =
|
|
11324
|
+
const raw = fs26.existsSync(configPath) ? JSON.parse(fs26.readFileSync(configPath, "utf8")) : {};
|
|
11325
|
+
const remnicCfg = resolveRemnicConfigRecord16(raw);
|
|
11326
|
+
const config = parseConfig17(remnicCfg);
|
|
11045
11327
|
const subcommand = rest[0];
|
|
11046
11328
|
if (subcommand === "audit") {
|
|
11047
11329
|
const memoryDir2 = expandTilde(config.memoryDir);
|
|
11048
|
-
const auditDir2 =
|
|
11330
|
+
const auditDir2 = path19.join(memoryDir2, "enrichment");
|
|
11049
11331
|
const sinceFlag = resolveFlag(rest.slice(1), "--since");
|
|
11050
11332
|
const entries = await readAuditLog(auditDir2, sinceFlag ?? void 0);
|
|
11051
11333
|
if (entries.length === 0) {
|
|
@@ -11069,7 +11351,7 @@ async function cmdEnrich(rest) {
|
|
|
11069
11351
|
pipelineConfig2.providers = [
|
|
11070
11352
|
{ id: "web-search", enabled: true, costTier: "cheap" }
|
|
11071
11353
|
];
|
|
11072
|
-
const orchestrator2 = new
|
|
11354
|
+
const orchestrator2 = new Orchestrator10(config);
|
|
11073
11355
|
await orchestrator2.initialize();
|
|
11074
11356
|
await orchestrator2.deferredReady;
|
|
11075
11357
|
const searchBackend2 = orchestrator2.qmd;
|
|
@@ -11105,7 +11387,7 @@ Registered providers:`);
|
|
|
11105
11387
|
console.error("Usage: remnic enrich <entity-name> | --all | --dry-run | audit | providers");
|
|
11106
11388
|
process.exit(1);
|
|
11107
11389
|
}
|
|
11108
|
-
const orchestrator = new
|
|
11390
|
+
const orchestrator = new Orchestrator10(config);
|
|
11109
11391
|
await orchestrator.initialize();
|
|
11110
11392
|
await orchestrator.deferredReady;
|
|
11111
11393
|
const storage = await orchestrator.getStorage(config.defaultNamespace);
|
|
@@ -11170,7 +11452,7 @@ Registered providers:`);
|
|
|
11170
11452
|
return;
|
|
11171
11453
|
}
|
|
11172
11454
|
const memoryDir = expandTilde(config.memoryDir);
|
|
11173
|
-
const auditDir =
|
|
11455
|
+
const auditDir = path19.join(memoryDir, "enrichment");
|
|
11174
11456
|
let totalPersisted = 0;
|
|
11175
11457
|
for (const result of results) {
|
|
11176
11458
|
for (const candidate of result.acceptedCandidates) {
|
|
@@ -11233,9 +11515,9 @@ Registered providers:`);
|
|
|
11233
11515
|
async function cmdExtensions(action, rest) {
|
|
11234
11516
|
initLogger5();
|
|
11235
11517
|
const configPath = resolveConfigPath();
|
|
11236
|
-
const raw =
|
|
11237
|
-
const remnicCfg =
|
|
11238
|
-
const config =
|
|
11518
|
+
const raw = fs26.existsSync(configPath) ? JSON.parse(fs26.readFileSync(configPath, "utf8")) : {};
|
|
11519
|
+
const remnicCfg = resolveRemnicConfigRecord16(raw);
|
|
11520
|
+
const config = parseConfig17(remnicCfg);
|
|
11239
11521
|
const root = resolveExtensionsRoot(config);
|
|
11240
11522
|
const noopLog = { warn: () => {
|
|
11241
11523
|
}, debug: () => {
|
|
@@ -11284,7 +11566,7 @@ Root: ${root}`);
|
|
|
11284
11566
|
const extensions = await discoverMemoryExtensions(root, warnLog);
|
|
11285
11567
|
let entries = [];
|
|
11286
11568
|
try {
|
|
11287
|
-
entries =
|
|
11569
|
+
entries = fs26.readdirSync(root);
|
|
11288
11570
|
} catch {
|
|
11289
11571
|
console.log(`Extensions root does not exist: ${root}`);
|
|
11290
11572
|
process.exitCode = 0;
|
|
@@ -11293,9 +11575,9 @@ Root: ${root}`);
|
|
|
11293
11575
|
const validNames = new Set(extensions.map((e) => e.name));
|
|
11294
11576
|
let errors = 0;
|
|
11295
11577
|
for (const entry of entries) {
|
|
11296
|
-
const entryPath =
|
|
11578
|
+
const entryPath = path19.join(root, entry);
|
|
11297
11579
|
try {
|
|
11298
|
-
if (!
|
|
11580
|
+
if (!fs26.statSync(entryPath).isDirectory()) continue;
|
|
11299
11581
|
} catch {
|
|
11300
11582
|
continue;
|
|
11301
11583
|
}
|
|
@@ -11327,9 +11609,9 @@ Root: ${root}`);
|
|
|
11327
11609
|
async function cmdBriefing(rest) {
|
|
11328
11610
|
initLogger5();
|
|
11329
11611
|
const configPath = resolveConfigPath();
|
|
11330
|
-
const raw =
|
|
11331
|
-
const remnicCfg =
|
|
11332
|
-
const config =
|
|
11612
|
+
const raw = fs26.existsSync(configPath) ? JSON.parse(fs26.readFileSync(configPath, "utf8")) : {};
|
|
11613
|
+
const remnicCfg = resolveRemnicConfigRecord16(raw);
|
|
11614
|
+
const config = parseConfig17(remnicCfg);
|
|
11333
11615
|
if (!config.briefing.enabled) {
|
|
11334
11616
|
console.error("Briefing is disabled in config (briefing.enabled = false).");
|
|
11335
11617
|
process.exit(1);
|
|
@@ -11382,7 +11664,7 @@ async function cmdBriefing(rest) {
|
|
|
11382
11664
|
process.exit(1);
|
|
11383
11665
|
}
|
|
11384
11666
|
const format = effectiveFormatFlag === "json" ? "json" : effectiveFormatFlag === "markdown" ? "markdown" : config.briefing.defaultFormat;
|
|
11385
|
-
const orchestrator = new
|
|
11667
|
+
const orchestrator = new Orchestrator10(config);
|
|
11386
11668
|
await orchestrator.initialize();
|
|
11387
11669
|
const storage = await orchestrator.getStorage(config.defaultNamespace);
|
|
11388
11670
|
const calendarSource = config.briefing.calendarSource ? new FileCalendarSource(config.briefing.calendarSource) : void 0;
|
|
@@ -11407,10 +11689,10 @@ async function cmdBriefing(rest) {
|
|
|
11407
11689
|
if (save) {
|
|
11408
11690
|
try {
|
|
11409
11691
|
const saveDir = resolveBriefingSaveDir(config.briefing.saveDir);
|
|
11410
|
-
|
|
11692
|
+
fs26.mkdirSync(saveDir, { recursive: true });
|
|
11411
11693
|
const filename = briefingFilename(new Date(result.window.to), format);
|
|
11412
|
-
const filePath =
|
|
11413
|
-
|
|
11694
|
+
const filePath = path19.join(saveDir, filename);
|
|
11695
|
+
fs26.writeFileSync(filePath, payload + (payload.endsWith("\n") ? "" : "\n"));
|
|
11414
11696
|
console.error(`Saved briefing: ${filePath}`);
|
|
11415
11697
|
} catch (err) {
|
|
11416
11698
|
console.error(`Failed to save briefing: ${err instanceof Error ? err.message : String(err)}`);
|
|
@@ -11428,7 +11710,7 @@ async function cmdDoctor() {
|
|
|
11428
11710
|
detail: `${nodeVersion} (requires >= 22.12.0)`
|
|
11429
11711
|
});
|
|
11430
11712
|
const configPath = resolveConfigPath();
|
|
11431
|
-
const configExists =
|
|
11713
|
+
const configExists = fs26.existsSync(configPath);
|
|
11432
11714
|
checks.push({ name: "Config file", ok: configExists, detail: configPath });
|
|
11433
11715
|
let standaloneConfig;
|
|
11434
11716
|
let standaloneConfigError;
|
|
@@ -11436,11 +11718,11 @@ async function cmdDoctor() {
|
|
|
11436
11718
|
let configuredNs = { invalid: false };
|
|
11437
11719
|
if (configExists) {
|
|
11438
11720
|
try {
|
|
11439
|
-
const raw = JSON.parse(
|
|
11440
|
-
const remnicCfg =
|
|
11721
|
+
const raw = JSON.parse(fs26.readFileSync(configPath, "utf8"));
|
|
11722
|
+
const remnicCfg = resolveRemnicConfigRecord16(raw);
|
|
11441
11723
|
standaloneOpenaiApiKeyExplicitlyFalse = isOpenaiApiKeyDisabled(remnicCfg.openaiApiKey);
|
|
11442
11724
|
configuredNs = readConfiguredNamespace(remnicCfg);
|
|
11443
|
-
standaloneConfig =
|
|
11725
|
+
standaloneConfig = parseConfig17(remnicCfg);
|
|
11444
11726
|
} catch (err) {
|
|
11445
11727
|
standaloneConfigError = err instanceof Error ? err.message : String(err);
|
|
11446
11728
|
}
|
|
@@ -11449,10 +11731,10 @@ async function cmdDoctor() {
|
|
|
11449
11731
|
try {
|
|
11450
11732
|
memoryDir = resolveMemoryDir();
|
|
11451
11733
|
} catch {
|
|
11452
|
-
memoryDir =
|
|
11734
|
+
memoryDir = parseConfig17({}).memoryDir;
|
|
11453
11735
|
}
|
|
11454
11736
|
try {
|
|
11455
|
-
|
|
11737
|
+
fs26.mkdirSync(memoryDir, { recursive: true });
|
|
11456
11738
|
checks.push({ name: "Memory directory", ok: true, detail: memoryDir });
|
|
11457
11739
|
} catch {
|
|
11458
11740
|
checks.push({ name: "Memory directory", ok: false, detail: `cannot create ${memoryDir}` });
|
|
@@ -11481,7 +11763,7 @@ async function cmdDoctor() {
|
|
|
11481
11763
|
});
|
|
11482
11764
|
if (nsPolicyCheck) checks.push(nsPolicyCheck);
|
|
11483
11765
|
const openclawConfigPath = resolveOpenclawConfigPath();
|
|
11484
|
-
const openclawConfigExists =
|
|
11766
|
+
const openclawConfigExists = fs26.existsSync(openclawConfigPath);
|
|
11485
11767
|
let openclawConfig = {};
|
|
11486
11768
|
let openclawConfigValid = false;
|
|
11487
11769
|
let openclawPluginModeConfigured = false;
|
|
@@ -11489,7 +11771,7 @@ async function cmdDoctor() {
|
|
|
11489
11771
|
let activeOpenclawEntryConfig = null;
|
|
11490
11772
|
if (openclawConfigExists) {
|
|
11491
11773
|
try {
|
|
11492
|
-
const parsed = JSON.parse(
|
|
11774
|
+
const parsed = JSON.parse(fs26.readFileSync(openclawConfigPath, "utf-8"));
|
|
11493
11775
|
if (typeof parsed === "object" && parsed !== null && !Array.isArray(parsed)) {
|
|
11494
11776
|
openclawConfig = parsed;
|
|
11495
11777
|
openclawConfigValid = true;
|
|
@@ -11565,13 +11847,13 @@ async function cmdDoctor() {
|
|
|
11565
11847
|
const rawMemoryDir = entryConfig?.memoryDir;
|
|
11566
11848
|
const configuredMemoryDir = typeof rawMemoryDir === "string" ? rawMemoryDir : void 0;
|
|
11567
11849
|
if (configuredMemoryDir) {
|
|
11568
|
-
const resolvedMemDir =
|
|
11850
|
+
const resolvedMemDir = path19.resolve(expandTilde(configuredMemoryDir));
|
|
11569
11851
|
let memDirOk = false;
|
|
11570
11852
|
let memDirDetail = `${resolvedMemDir} (not found)`;
|
|
11571
11853
|
let memDirRemediation = `Run \`remnic openclaw install --memory-dir "${resolvedMemDir}"\` to create the directory.`;
|
|
11572
|
-
if (
|
|
11854
|
+
if (fs26.existsSync(resolvedMemDir)) {
|
|
11573
11855
|
try {
|
|
11574
|
-
const stat2 =
|
|
11856
|
+
const stat2 = fs26.statSync(resolvedMemDir);
|
|
11575
11857
|
if (stat2.isDirectory()) {
|
|
11576
11858
|
memDirOk = true;
|
|
11577
11859
|
memDirDetail = resolvedMemDir;
|
|
@@ -11726,12 +12008,12 @@ async function cmdDoctor() {
|
|
|
11726
12008
|
}
|
|
11727
12009
|
function cmdConfig() {
|
|
11728
12010
|
const configPath = resolveConfigPath();
|
|
11729
|
-
if (!
|
|
12011
|
+
if (!fs26.existsSync(configPath)) {
|
|
11730
12012
|
console.log("No config file found. Run `remnic init` to create one.");
|
|
11731
12013
|
return;
|
|
11732
12014
|
}
|
|
11733
12015
|
console.log(`Config: ${configPath}`);
|
|
11734
|
-
const rawConfig =
|
|
12016
|
+
const rawConfig = fs26.readFileSync(configPath, "utf8");
|
|
11735
12017
|
const redacted = rawConfig.replace(
|
|
11736
12018
|
/("(?:openaiApiKey|localLlmApiKey|authToken|apiKey|remoteSearchApiKey|meilisearchApiKey|opikApiKey)"\s*:\s*")([^"]*)(")/g,
|
|
11737
12019
|
"$1[REDACTED]$3"
|
|
@@ -11778,7 +12060,7 @@ async function cmdMigrate(json, rollback) {
|
|
|
11778
12060
|
console.log(` Rollback: ${result.rollbackCommand}`);
|
|
11779
12061
|
}
|
|
11780
12062
|
function cmdOnboard(dirPath, json) {
|
|
11781
|
-
const directory =
|
|
12063
|
+
const directory = path19.resolve(dirPath || process.cwd());
|
|
11782
12064
|
const result = onboard({ directory });
|
|
11783
12065
|
if (json) {
|
|
11784
12066
|
console.log(JSON.stringify(result, null, 2));
|
|
@@ -11797,7 +12079,7 @@ Suggested namespace: ${result.plan.suggestedNamespace}`);
|
|
|
11797
12079
|
async function cmdCurate(targetPath, json) {
|
|
11798
12080
|
const memoryDir = resolveMemoryDir();
|
|
11799
12081
|
const result = await curate({
|
|
11800
|
-
targetPath:
|
|
12082
|
+
targetPath: path19.resolve(targetPath),
|
|
11801
12083
|
memoryDir,
|
|
11802
12084
|
source: "curation",
|
|
11803
12085
|
checkDuplicates: true,
|
|
@@ -11839,9 +12121,9 @@ async function cmdReview(action, rest) {
|
|
|
11839
12121
|
const configPath = resolveConfigPath();
|
|
11840
12122
|
let tombstonesConfig = null;
|
|
11841
12123
|
try {
|
|
11842
|
-
const rawCfg =
|
|
11843
|
-
const remnicCfg =
|
|
11844
|
-
const config =
|
|
12124
|
+
const rawCfg = fs26.existsSync(configPath) ? JSON.parse(fs26.readFileSync(configPath, "utf8")) : {};
|
|
12125
|
+
const remnicCfg = resolveRemnicConfigRecord16(rawCfg);
|
|
12126
|
+
const config = parseConfig17(remnicCfg);
|
|
11845
12127
|
tombstonesConfig = {
|
|
11846
12128
|
enabled: config.tombstonesEnabled,
|
|
11847
12129
|
semanticMatch: config.tombstonesSemanticMatch,
|
|
@@ -11927,7 +12209,7 @@ async function cmdSync(action, rest, json) {
|
|
|
11927
12209
|
}
|
|
11928
12210
|
function localOfflineSourceId(memoryDir) {
|
|
11929
12211
|
const host = os3.hostname() || "unknown-host";
|
|
11930
|
-
const dirHash = createHash4("sha256").update(
|
|
12212
|
+
const dirHash = createHash4("sha256").update(path19.resolve(memoryDir)).digest("hex").slice(0, 16);
|
|
11931
12213
|
return `remnic-local:${host}:${dirHash}`;
|
|
11932
12214
|
}
|
|
11933
12215
|
function normalizeOfflineRemoteUrl(raw) {
|
|
@@ -12325,10 +12607,10 @@ var OFFLINE_SYNC_CONTENT_MISSING_RETRY_MAX = 3;
|
|
|
12325
12607
|
var OFFLINE_SYNC_CONTENT_MISSING_RETRY_DELAY_MS = 250;
|
|
12326
12608
|
var OfflineRemoteFileChangedError = class extends Error {
|
|
12327
12609
|
path;
|
|
12328
|
-
constructor(
|
|
12329
|
-
super(`remote file changed while fetching offline content: ${
|
|
12610
|
+
constructor(path20) {
|
|
12611
|
+
super(`remote file changed while fetching offline content: ${path20}`);
|
|
12330
12612
|
this.name = "OfflineRemoteFileChangedError";
|
|
12331
|
-
this.path =
|
|
12613
|
+
this.path = path20;
|
|
12332
12614
|
}
|
|
12333
12615
|
};
|
|
12334
12616
|
function isOfflineRemoteFileChangedError(error) {
|
|
@@ -12583,13 +12865,13 @@ async function pushOfflineFileContent(args) {
|
|
|
12583
12865
|
}
|
|
12584
12866
|
async function pushOfflineFileContentFromChunkReader(args) {
|
|
12585
12867
|
const filePath = resolveOfflineDirectHydrationPath(args.memoryDir, args.file.path);
|
|
12586
|
-
const stat2 =
|
|
12868
|
+
const stat2 = fs26.statSync(filePath);
|
|
12587
12869
|
if (stat2.mtimeMs !== args.file.mtimeMs) {
|
|
12588
12870
|
throw new Error(`local file changed while pushing offline content: ${args.file.path}`);
|
|
12589
12871
|
}
|
|
12590
12872
|
const hash = createHash4("sha256");
|
|
12591
12873
|
const chunks = args.readFileChunks({
|
|
12592
|
-
root:
|
|
12874
|
+
root: path19.resolve(args.memoryDir),
|
|
12593
12875
|
path: args.file.path,
|
|
12594
12876
|
filePath,
|
|
12595
12877
|
chunkSize: OFFLINE_SYNC_FILE_CONTENT_UPLOAD_CHUNK_BYTES
|
|
@@ -13074,7 +13356,7 @@ function advanceOfflineBaseFilesForSuccessfulPush(options) {
|
|
|
13074
13356
|
return [...next.values()].sort((left, right) => left.path.localeCompare(right.path));
|
|
13075
13357
|
}
|
|
13076
13358
|
async function runOfflineSyncOnce(options) {
|
|
13077
|
-
|
|
13359
|
+
fs26.mkdirSync(options.memoryDir, { recursive: true });
|
|
13078
13360
|
let activeStatePath = options.statePath;
|
|
13079
13361
|
let priorState = await readOfflineSyncState(activeStatePath);
|
|
13080
13362
|
let syncNamespace = options.namespace ?? priorState?.namespace;
|
|
@@ -13699,7 +13981,7 @@ Environment fallbacks:
|
|
|
13699
13981
|
REMNIC_OFFLINE_REMOTE_URL, REMNIC_OFFLINE_TOKEN, REMNIC_AUTH_TOKEN`);
|
|
13700
13982
|
return;
|
|
13701
13983
|
}
|
|
13702
|
-
const memoryDir =
|
|
13984
|
+
const memoryDir = path19.resolve(expandTilde(resolveRequiredValueFlag(rest, "--memory-dir") ?? resolveMemoryDir()));
|
|
13703
13985
|
const namespace = resolveRequiredValueFlag(rest, "--namespace");
|
|
13704
13986
|
const includeTranscripts = !hasFlag(rest, "--no-transcripts");
|
|
13705
13987
|
const stateOverride = resolveRequiredValueFlag(rest, "--state");
|
|
@@ -13707,7 +13989,7 @@ Environment fallbacks:
|
|
|
13707
13989
|
const configPath = resolveConfigPath();
|
|
13708
13990
|
let config;
|
|
13709
13991
|
try {
|
|
13710
|
-
const rawConfig =
|
|
13992
|
+
const rawConfig = fs26.existsSync(configPath) ? JSON.parse(fs26.readFileSync(configPath, "utf8")) : {};
|
|
13711
13993
|
config = parseConfigQuietly(pickOfflineConfigRecord(rawConfig));
|
|
13712
13994
|
} catch {
|
|
13713
13995
|
throw new Error(
|
|
@@ -13719,10 +14001,10 @@ Environment fallbacks:
|
|
|
13719
14001
|
const needsRemote = action === "prepare" || action === "sync" || action === "watch";
|
|
13720
14002
|
const remoteUrl = needsRemote ? resolveOfflineRemoteUrl(rest) : resolveOptionalOfflineRemoteUrl(rest);
|
|
13721
14003
|
const token = needsRemote ? resolveOfflineToken(rest) : void 0;
|
|
13722
|
-
const statePath = statePathExplicit ?
|
|
14004
|
+
const statePath = statePathExplicit ? path19.resolve(expandTilde(stateOverride)) : remoteUrl !== void 0 ? defaultOfflineSyncStatePath(memoryDir, remoteUrl, namespace) : void 0;
|
|
13723
14005
|
if (action === "prepare") {
|
|
13724
14006
|
if (!remoteUrl || !token || !statePath) throw new Error("offline prepare requires remote URL and token");
|
|
13725
|
-
|
|
14007
|
+
fs26.mkdirSync(memoryDir, { recursive: true });
|
|
13726
14008
|
const remoteSnapshot = await fetchOfflineSnapshot({
|
|
13727
14009
|
remoteUrl,
|
|
13728
14010
|
token,
|
|
@@ -13821,7 +14103,7 @@ Environment fallbacks:
|
|
|
13821
14103
|
return;
|
|
13822
14104
|
}
|
|
13823
14105
|
if (action === "status") {
|
|
13824
|
-
|
|
14106
|
+
fs26.mkdirSync(memoryDir, { recursive: true });
|
|
13825
14107
|
const state = statePath ? await readOfflineSyncState(statePath) : null;
|
|
13826
14108
|
if (state && remoteUrl && statePath) {
|
|
13827
14109
|
assertOfflineStateMatches({
|
|
@@ -13901,11 +14183,11 @@ Environment fallbacks:
|
|
|
13901
14183
|
failures: result.largeFilePushFailures
|
|
13902
14184
|
});
|
|
13903
14185
|
largeFileFailureCounts = advanced.counts;
|
|
13904
|
-
for (const
|
|
13905
|
-
if (skippedLargeFiles.has(
|
|
13906
|
-
skippedLargeFiles.add(
|
|
14186
|
+
for (const path20 of advanced.newlySkipped) {
|
|
14187
|
+
if (skippedLargeFiles.has(path20)) continue;
|
|
14188
|
+
skippedLargeFiles.add(path20);
|
|
13907
14189
|
console.warn(
|
|
13908
|
-
`offline sync: permanently skipping ${
|
|
14190
|
+
`offline sync: permanently skipping ${path20} after ${OFFLINE_LARGE_FILE_SKIP_AFTER_FAILURES} failed large-file pushes for this watcher process (see issue #1786; use --exclude or offlineSyncExcludes to silence permanently)`
|
|
13909
14191
|
);
|
|
13910
14192
|
}
|
|
13911
14193
|
const pulled = result.pull ? result.pull.upserted + result.pull.deleted : 0;
|
|
@@ -13920,11 +14202,11 @@ Environment fallbacks:
|
|
|
13920
14202
|
failures: error.failures
|
|
13921
14203
|
});
|
|
13922
14204
|
largeFileFailureCounts = advanced.counts;
|
|
13923
|
-
for (const
|
|
13924
|
-
if (skippedLargeFiles.has(
|
|
13925
|
-
skippedLargeFiles.add(
|
|
14205
|
+
for (const path20 of advanced.newlySkipped) {
|
|
14206
|
+
if (skippedLargeFiles.has(path20)) continue;
|
|
14207
|
+
skippedLargeFiles.add(path20);
|
|
13926
14208
|
console.warn(
|
|
13927
|
-
`offline sync: permanently skipping ${
|
|
14209
|
+
`offline sync: permanently skipping ${path20} after ${OFFLINE_LARGE_FILE_SKIP_AFTER_FAILURES} failed large-file pushes for this watcher process (see issue #1786; use --exclude or offlineSyncExcludes to silence permanently)`
|
|
13928
14210
|
);
|
|
13929
14211
|
}
|
|
13930
14212
|
}
|
|
@@ -13959,7 +14241,7 @@ function cmdDedup(json) {
|
|
|
13959
14241
|
function readInstalledConnectorConfig(configPath, fallback) {
|
|
13960
14242
|
if (!configPath) return fallback;
|
|
13961
14243
|
try {
|
|
13962
|
-
const parsed = JSON.parse(
|
|
14244
|
+
const parsed = JSON.parse(fs26.readFileSync(configPath, "utf8"));
|
|
13963
14245
|
if (!parsed || typeof parsed !== "object" || Array.isArray(parsed)) return fallback;
|
|
13964
14246
|
const { token: _token, ...config } = parsed;
|
|
13965
14247
|
return config;
|
|
@@ -14065,7 +14347,7 @@ async function cmdConnectors(action, rest, json) {
|
|
|
14065
14347
|
const connectorDaemonUrl = typeof effectiveConnectorConfig.remnicDaemonUrl === "string" && effectiveConnectorConfig.remnicDaemonUrl.trim().length > 0 ? effectiveConnectorConfig.remnicDaemonUrl.trim() : void 0;
|
|
14066
14348
|
const pubResult = await pub.publish({
|
|
14067
14349
|
config: { memoryDir, namespace: connectorNamespace, daemonUrl: connectorDaemonUrl },
|
|
14068
|
-
skillsRoot:
|
|
14350
|
+
skillsRoot: path19.join(memoryDir, "skills"),
|
|
14069
14351
|
rollbackTokenEntry: preInstallTokenEntry,
|
|
14070
14352
|
log: { info: console.log, warn: console.warn, error: console.error }
|
|
14071
14353
|
});
|
|
@@ -14137,7 +14419,7 @@ async function cmdConnectors(action, rest, json) {
|
|
|
14137
14419
|
const pub = factory();
|
|
14138
14420
|
const available = await pub.isHostAvailable();
|
|
14139
14421
|
const extRoot = available ? await pub.resolveExtensionRoot() : "(host not installed)";
|
|
14140
|
-
const extensionExists = available && extRoot ?
|
|
14422
|
+
const extensionExists = available && extRoot ? fs26.existsSync(extRoot) : false;
|
|
14141
14423
|
publisherChecks.push({
|
|
14142
14424
|
name: `Publisher: ${targetHostId}`,
|
|
14143
14425
|
ok: !available || extensionExists,
|
|
@@ -14211,7 +14493,7 @@ async function cmdConnectors(action, rest, json) {
|
|
|
14211
14493
|
let connectorsCfg;
|
|
14212
14494
|
const configPath = resolveConfigPath();
|
|
14213
14495
|
try {
|
|
14214
|
-
const raw =
|
|
14496
|
+
const raw = fs26.existsSync(configPath) ? JSON.parse(fs26.readFileSync(configPath, "utf8")) : {};
|
|
14215
14497
|
connectorsCfg = parseConfigQuietly(raw).connectors;
|
|
14216
14498
|
} catch {
|
|
14217
14499
|
process.stderr.write(
|
|
@@ -14287,10 +14569,10 @@ async function cmdConnectors(action, rest, json) {
|
|
|
14287
14569
|
}
|
|
14288
14570
|
initLogger5();
|
|
14289
14571
|
const configPath = resolveConfigPath();
|
|
14290
|
-
const raw =
|
|
14291
|
-
const remnicCfg =
|
|
14292
|
-
const config =
|
|
14293
|
-
const orchestrator = new
|
|
14572
|
+
const raw = fs26.existsSync(configPath) ? JSON.parse(fs26.readFileSync(configPath, "utf8")) : {};
|
|
14573
|
+
const remnicCfg = resolveRemnicConfigRecord16(raw);
|
|
14574
|
+
const config = parseConfig17(remnicCfg);
|
|
14575
|
+
const orchestrator = new Orchestrator10(config);
|
|
14294
14576
|
try {
|
|
14295
14577
|
await orchestrator.initialize();
|
|
14296
14578
|
await orchestrator.deferredReady;
|
|
@@ -14412,9 +14694,9 @@ async function cmdConnectorsMarketplace(subAction, rest, json) {
|
|
|
14412
14694
|
console.error(`connectors marketplace: ${err instanceof Error ? err.message : String(err)}`);
|
|
14413
14695
|
process.exit(1);
|
|
14414
14696
|
}
|
|
14415
|
-
const rawConfig =
|
|
14416
|
-
const pluginConfig =
|
|
14417
|
-
const config =
|
|
14697
|
+
const rawConfig = fs26.existsSync(configPath) ? JSON.parse(fs26.readFileSync(configPath, "utf8")) : {};
|
|
14698
|
+
const pluginConfig = resolveRemnicConfigRecord16(rawConfig);
|
|
14699
|
+
const config = parseConfig17(pluginConfig);
|
|
14418
14700
|
if (subAction === "generate") {
|
|
14419
14701
|
let outputDir;
|
|
14420
14702
|
try {
|
|
@@ -14425,22 +14707,22 @@ async function cmdConnectorsMarketplace(subAction, rest, json) {
|
|
|
14425
14707
|
}
|
|
14426
14708
|
const manifest = generateMarketplaceManifest();
|
|
14427
14709
|
await writeMarketplaceManifest(outputDir, manifest);
|
|
14428
|
-
const outPath =
|
|
14710
|
+
const outPath = path19.join(outputDir, "marketplace.json");
|
|
14429
14711
|
if (json) {
|
|
14430
14712
|
console.log(JSON.stringify({ status: "generated", path: outPath }, null, 2));
|
|
14431
14713
|
} else {
|
|
14432
14714
|
console.log(`Generated marketplace.json at ${outPath}`);
|
|
14433
14715
|
}
|
|
14434
14716
|
} else if (subAction === "validate") {
|
|
14435
|
-
const targetPath = rest.filter((a) => !a.startsWith("--"))[0] ??
|
|
14436
|
-
const resolved =
|
|
14437
|
-
if (!
|
|
14717
|
+
const targetPath = rest.filter((a) => !a.startsWith("--"))[0] ?? path19.join(process.cwd(), "marketplace.json");
|
|
14718
|
+
const resolved = path19.resolve(targetPath);
|
|
14719
|
+
if (!fs26.existsSync(resolved)) {
|
|
14438
14720
|
console.error(`File not found: ${resolved}`);
|
|
14439
14721
|
process.exit(1);
|
|
14440
14722
|
}
|
|
14441
14723
|
let parsed;
|
|
14442
14724
|
try {
|
|
14443
|
-
parsed = JSON.parse(
|
|
14725
|
+
parsed = JSON.parse(fs26.readFileSync(resolved, "utf8"));
|
|
14444
14726
|
} catch {
|
|
14445
14727
|
console.error(`Invalid JSON in ${resolved}`);
|
|
14446
14728
|
process.exit(1);
|
|
@@ -14643,10 +14925,10 @@ async function cmdSpace(action, rest, json) {
|
|
|
14643
14925
|
async function cmdLegacyBenchmark(action, rest, json) {
|
|
14644
14926
|
initLogger5();
|
|
14645
14927
|
const configPath = resolveConfigPath();
|
|
14646
|
-
const raw =
|
|
14647
|
-
const remnicCfg =
|
|
14648
|
-
const config =
|
|
14649
|
-
const orchestrator = new
|
|
14928
|
+
const raw = fs26.existsSync(configPath) ? JSON.parse(fs26.readFileSync(configPath, "utf8")) : {};
|
|
14929
|
+
const remnicCfg = resolveRemnicConfigRecord16(raw);
|
|
14930
|
+
const config = parseConfig17(remnicCfg);
|
|
14931
|
+
const orchestrator = new Orchestrator10(config);
|
|
14650
14932
|
const service = new EngramAccessService2(orchestrator);
|
|
14651
14933
|
const { runBenchSuite, loadBaseline, checkRegression } = await loadBenchModule();
|
|
14652
14934
|
const benchConfig = {
|
|
@@ -14845,7 +15127,7 @@ async function cmdBench(rest) {
|
|
|
14845
15127
|
}
|
|
14846
15128
|
const completeCount = prevStatus.benchmarks.filter((b) => b.status === "complete").length;
|
|
14847
15129
|
const failedCount = prevStatus.benchmarks.filter((b) => b.status === "failed").length;
|
|
14848
|
-
printBenchStatusLine(parsed.json, `Resuming from: ${
|
|
15130
|
+
printBenchStatusLine(parsed.json, `Resuming from: ${path19.basename(latestStatusPath)}`);
|
|
14849
15131
|
printBenchStatusLine(parsed.json, ` Previous run: ${prevStatus.startedAt}`);
|
|
14850
15132
|
printBenchStatusLine(parsed.json, ` Benchmarks: ${prevStatus.benchmarks.length} total, ${completeCount} complete, ${failedCount} failed`);
|
|
14851
15133
|
const before = selectedBenchmarks.length;
|
|
@@ -15013,9 +15295,9 @@ Options:
|
|
|
15013
15295
|
);
|
|
15014
15296
|
process.exit(1);
|
|
15015
15297
|
} else {
|
|
15016
|
-
fixturePath =
|
|
15298
|
+
fixturePath = path19.resolve(expandTilde(fixturePathRaw));
|
|
15017
15299
|
}
|
|
15018
|
-
const outPath =
|
|
15300
|
+
const outPath = path19.resolve(expandTilde(outPathRaw));
|
|
15019
15301
|
const benchModule = await loadBenchModule();
|
|
15020
15302
|
const runner = benchModule.runProceduralAblationCli;
|
|
15021
15303
|
if (typeof runner !== "function") {
|
|
@@ -15034,7 +15316,7 @@ Options:
|
|
|
15034
15316
|
);
|
|
15035
15317
|
console.log(`wrote ${outPath}`);
|
|
15036
15318
|
}
|
|
15037
|
-
var LOGS_DIR =
|
|
15319
|
+
var LOGS_DIR = path19.join(PID_DIR, "logs");
|
|
15038
15320
|
var LAUNCHD_PLIST_PATHS = launchdPlistPaths(resolveHomeDir());
|
|
15039
15321
|
var [LAUNCHD_PLIST_PATH] = LAUNCHD_PLIST_PATHS;
|
|
15040
15322
|
var SYSTEMD_UNIT_PATHS = systemdUnitPaths(resolveHomeDir());
|
|
@@ -15048,7 +15330,7 @@ function readPid() {
|
|
|
15048
15330
|
function inferPort() {
|
|
15049
15331
|
try {
|
|
15050
15332
|
const configPath = resolveConfigPath();
|
|
15051
|
-
const raw = JSON.parse(
|
|
15333
|
+
const raw = JSON.parse(fs26.readFileSync(configPath, "utf8"));
|
|
15052
15334
|
return raw.server?.port ?? 4318;
|
|
15053
15335
|
} catch {
|
|
15054
15336
|
return 4318;
|
|
@@ -15111,7 +15393,7 @@ function selectLaunchdInspection(openclawPluginModeConfigured) {
|
|
|
15111
15393
|
for (const plistPath of LAUNCHD_PLIST_PATHS.slice(1)) {
|
|
15112
15394
|
const legacy = inspectLaunchdPlist(plistPath);
|
|
15113
15395
|
if (!legacy.installed) continue;
|
|
15114
|
-
const label =
|
|
15396
|
+
const label = path19.basename(plistPath, ".plist");
|
|
15115
15397
|
return legacy.ok ? {
|
|
15116
15398
|
...legacy,
|
|
15117
15399
|
warn: true,
|
|
@@ -15143,13 +15425,13 @@ function daemonInstall() {
|
|
|
15143
15425
|
process.exit(1);
|
|
15144
15426
|
}
|
|
15145
15427
|
const vars = { HOME: home, NODE_PATH: nodePath, REMNIC_SERVER_BIN: serverBin };
|
|
15146
|
-
|
|
15428
|
+
fs26.mkdirSync(LOGS_DIR, { recursive: true });
|
|
15147
15429
|
if (isMacOS()) {
|
|
15148
|
-
const templatePath =
|
|
15149
|
-
const template =
|
|
15430
|
+
const templatePath = path19.resolve(import.meta.dirname, "../templates/launchd/ai.remnic.daemon.plist");
|
|
15431
|
+
const template = fs26.readFileSync(templatePath, "utf8");
|
|
15150
15432
|
const plist = renderTemplate(template, vars);
|
|
15151
|
-
|
|
15152
|
-
|
|
15433
|
+
fs26.mkdirSync(path19.dirname(LAUNCHD_PLIST_PATH), { recursive: true });
|
|
15434
|
+
fs26.writeFileSync(LAUNCHD_PLIST_PATH, plist);
|
|
15153
15435
|
try {
|
|
15154
15436
|
launchdLoadPlist(LAUNCHD_PLIST_PATH);
|
|
15155
15437
|
} catch (err) {
|
|
@@ -15165,11 +15447,11 @@ function daemonInstall() {
|
|
|
15165
15447
|
console.log(` RunAtLoad: true, KeepAlive: true`);
|
|
15166
15448
|
console.log(` Logs: ${LOGS_DIR}/daemon.log`);
|
|
15167
15449
|
} else if (isLinux()) {
|
|
15168
|
-
const templatePath =
|
|
15169
|
-
const template =
|
|
15450
|
+
const templatePath = path19.resolve(import.meta.dirname, "../templates/systemd/remnic.service");
|
|
15451
|
+
const template = fs26.readFileSync(templatePath, "utf8");
|
|
15170
15452
|
const unit = renderTemplate(template, vars);
|
|
15171
|
-
|
|
15172
|
-
|
|
15453
|
+
fs26.mkdirSync(path19.dirname(SYSTEMD_UNIT_PATH), { recursive: true });
|
|
15454
|
+
fs26.writeFileSync(SYSTEMD_UNIT_PATH, unit);
|
|
15173
15455
|
try {
|
|
15174
15456
|
childProcess2.execSync("systemctl --user daemon-reload", { stdio: "pipe" });
|
|
15175
15457
|
} catch (err) {
|
|
@@ -15205,7 +15487,7 @@ function daemonUninstall() {
|
|
|
15205
15487
|
} catch {
|
|
15206
15488
|
}
|
|
15207
15489
|
try {
|
|
15208
|
-
|
|
15490
|
+
fs26.unlinkSync(plistPath);
|
|
15209
15491
|
removed = true;
|
|
15210
15492
|
console.log(`Removed launchd service: ${plistPath}`);
|
|
15211
15493
|
} catch {
|
|
@@ -15225,7 +15507,7 @@ function daemonUninstall() {
|
|
|
15225
15507
|
let removed = false;
|
|
15226
15508
|
for (const unitPath of SYSTEMD_UNIT_PATHS) {
|
|
15227
15509
|
try {
|
|
15228
|
-
|
|
15510
|
+
fs26.unlinkSync(unitPath);
|
|
15229
15511
|
removed = true;
|
|
15230
15512
|
console.log(`Removed systemd service: ${unitPath}`);
|
|
15231
15513
|
} catch {
|
|
@@ -15292,13 +15574,13 @@ async function daemonStatus() {
|
|
|
15292
15574
|
console.log(` Port: ${port}`);
|
|
15293
15575
|
console.log(` Service: ${serviceInstalled ? "installed" : "not installed"}`);
|
|
15294
15576
|
console.log(` Platform: ${process.platform}`);
|
|
15295
|
-
console.log(` PID file: ${
|
|
15296
|
-
console.log(` Log file: ${
|
|
15577
|
+
console.log(` PID file: ${fs26.existsSync(PID_FILE) ? PID_FILE : LEGACY_PID_FILE}`);
|
|
15578
|
+
console.log(` Log file: ${fs26.existsSync(LOG_FILE) ? LOG_FILE : LEGACY_LOG_FILE}`);
|
|
15297
15579
|
try {
|
|
15298
15580
|
const configPath = resolveConfigPath();
|
|
15299
|
-
const raw =
|
|
15300
|
-
const remnicCfg =
|
|
15301
|
-
const config =
|
|
15581
|
+
const raw = fs26.existsSync(configPath) ? JSON.parse(fs26.readFileSync(configPath, "utf8")) : {};
|
|
15582
|
+
const remnicCfg = resolveRemnicConfigRecord16(raw);
|
|
15583
|
+
const config = parseConfig17(remnicCfg);
|
|
15302
15584
|
const extRoot = resolveExtensionsRoot(config);
|
|
15303
15585
|
const noopLog = { warn: () => {
|
|
15304
15586
|
}, debug: () => {
|
|
@@ -15337,9 +15619,9 @@ function daemonStart() {
|
|
|
15337
15619
|
return;
|
|
15338
15620
|
}
|
|
15339
15621
|
}
|
|
15340
|
-
|
|
15341
|
-
|
|
15342
|
-
const logStream =
|
|
15622
|
+
fs26.mkdirSync(PID_DIR, { recursive: true });
|
|
15623
|
+
fs26.mkdirSync(LOGS_DIR, { recursive: true });
|
|
15624
|
+
const logStream = fs26.openSync(LOG_FILE, "a");
|
|
15343
15625
|
const serverBin = resolveServerBin();
|
|
15344
15626
|
const isSource = serverBin.endsWith(".ts");
|
|
15345
15627
|
let cmd;
|
|
@@ -15361,7 +15643,7 @@ function daemonStart() {
|
|
|
15361
15643
|
}
|
|
15362
15644
|
});
|
|
15363
15645
|
child.unref();
|
|
15364
|
-
|
|
15646
|
+
fs26.writeFileSync(PID_FILE, String(child.pid));
|
|
15365
15647
|
console.log(`Started remnic server (pid ${child.pid})`);
|
|
15366
15648
|
console.log(` Log: ${LOG_FILE}`);
|
|
15367
15649
|
}
|
|
@@ -15395,11 +15677,11 @@ function daemonStop() {
|
|
|
15395
15677
|
console.log("Process not found (cleaning up PID file)");
|
|
15396
15678
|
}
|
|
15397
15679
|
try {
|
|
15398
|
-
|
|
15680
|
+
fs26.unlinkSync(PID_FILE);
|
|
15399
15681
|
} catch {
|
|
15400
15682
|
}
|
|
15401
15683
|
try {
|
|
15402
|
-
|
|
15684
|
+
fs26.unlinkSync(LEGACY_PID_FILE);
|
|
15403
15685
|
} catch {
|
|
15404
15686
|
}
|
|
15405
15687
|
}
|
|
@@ -15527,9 +15809,9 @@ async function promptYesNo(question, defaultYes = true) {
|
|
|
15527
15809
|
async function cmdBinary(rest) {
|
|
15528
15810
|
initLogger5();
|
|
15529
15811
|
const configPath = resolveConfigPath();
|
|
15530
|
-
const raw =
|
|
15531
|
-
const remnicCfg =
|
|
15532
|
-
const config =
|
|
15812
|
+
const raw = fs26.existsSync(configPath) ? JSON.parse(fs26.readFileSync(configPath, "utf8")) : {};
|
|
15813
|
+
const remnicCfg = resolveRemnicConfigRecord16(raw);
|
|
15814
|
+
const config = parseConfig17(remnicCfg);
|
|
15533
15815
|
const memoryDir = resolveMemoryDir();
|
|
15534
15816
|
const blConfig = {
|
|
15535
15817
|
enabled: config.binaryLifecycleEnabled,
|
|
@@ -15647,7 +15929,7 @@ Clean complete: cleaned=${result.cleaned}`
|
|
|
15647
15929
|
}
|
|
15648
15930
|
async function cmdOpenclawInstall(opts) {
|
|
15649
15931
|
const configPath = resolveOpenclawConfigPath(opts.configPath);
|
|
15650
|
-
const fallbackMemoryDir =
|
|
15932
|
+
const fallbackMemoryDir = path19.join(resolveOpenclawStateDir(), "workspace", "memory", "local");
|
|
15651
15933
|
console.log(`OpenClaw config: ${configPath}`);
|
|
15652
15934
|
const existingConfig = readOpenclawConfig(configPath);
|
|
15653
15935
|
const { plugins, entries, slots } = parseOpenclawPluginState(existingConfig, configPath);
|
|
@@ -15718,7 +16000,7 @@ async function cmdOpenclawInstall(opts) {
|
|
|
15718
16000
|
} else if (slotIsActiveLegacy) {
|
|
15719
16001
|
changes.push(` Slot left as "${REMNIC_OPENCLAW_LEGACY_PLUGIN_ID}" \u2014 re-run with --yes to activate the new entry`);
|
|
15720
16002
|
}
|
|
15721
|
-
if (!
|
|
16003
|
+
if (!fs26.existsSync(memoryDir)) changes.push(`+ Will create memory directory: ${memoryDir}`);
|
|
15722
16004
|
if (hasLegacy && migrateLegacy) {
|
|
15723
16005
|
changes.push(`~ Legacy '${REMNIC_OPENCLAW_LEGACY_PLUGIN_ID}' entry retained (safe to remove after verifying hooks fire)`);
|
|
15724
16006
|
}
|
|
@@ -15738,8 +16020,8 @@ async function cmdOpenclawInstall(opts) {
|
|
|
15738
16020
|
Resulting plugins.slots.memory: ${dryRunPlugins.slots?.memory ?? "(unset)"}`);
|
|
15739
16021
|
return;
|
|
15740
16022
|
}
|
|
15741
|
-
if (
|
|
15742
|
-
const st =
|
|
16023
|
+
if (fs26.existsSync(memoryDir)) {
|
|
16024
|
+
const st = fs26.statSync(memoryDir);
|
|
15743
16025
|
if (!st.isDirectory()) {
|
|
15744
16026
|
throw new Error(
|
|
15745
16027
|
`Cannot use ${memoryDir} as the memory directory \u2014 a file already exists at that path.
|
|
@@ -15747,12 +16029,12 @@ Remove it first and re-run, or choose a different path with --memory-dir.`
|
|
|
15747
16029
|
);
|
|
15748
16030
|
}
|
|
15749
16031
|
} else {
|
|
15750
|
-
|
|
16032
|
+
fs26.mkdirSync(memoryDir, { recursive: true });
|
|
15751
16033
|
console.log(`Created memory directory: ${memoryDir}`);
|
|
15752
16034
|
}
|
|
15753
|
-
const configDir =
|
|
15754
|
-
if (!
|
|
15755
|
-
|
|
16035
|
+
const configDir = path19.dirname(configPath);
|
|
16036
|
+
if (!fs26.existsSync(configDir)) {
|
|
16037
|
+
fs26.mkdirSync(configDir, { recursive: true });
|
|
15756
16038
|
}
|
|
15757
16039
|
atomicWriteFileSync(configPath, JSON.stringify(updatedConfig, null, 2) + "\n");
|
|
15758
16040
|
console.log("\nDone! Summary of changes:");
|
|
@@ -15779,12 +16061,12 @@ async function cmdOpenclawUpgrade(opts) {
|
|
|
15779
16061
|
const pluginDir = resolveOpenclawPluginDir(opts.pluginDir);
|
|
15780
16062
|
const managedTargetDir = resolveOpenclawManagedPluginDir();
|
|
15781
16063
|
const legacyPluginDirForBackup = opts.legacyPluginDirForBackup ? resolveOpenclawLegacyPluginDir(opts.legacyPluginDirForBackup) : void 0;
|
|
15782
|
-
const fallbackMemoryDir =
|
|
16064
|
+
const fallbackMemoryDir = path19.join(resolveOpenclawStateDir(), "workspace", "memory", "local");
|
|
15783
16065
|
const packageSpec = buildOpenclawManagedUpgradePackageSpec(opts.version);
|
|
15784
|
-
const configExistedBefore =
|
|
16066
|
+
const configExistedBefore = fs26.existsSync(configPath);
|
|
15785
16067
|
const existingConfig = readOpenclawConfig(configPath);
|
|
15786
16068
|
const { entries, slots } = parseOpenclawPluginState(existingConfig, configPath);
|
|
15787
|
-
const preservedMemoryDir = opts.memoryDir ?
|
|
16069
|
+
const preservedMemoryDir = opts.memoryDir ? path19.resolve(expandTilde(opts.memoryDir)) : resolveCurrentOpenclawMemoryDir(entries, slots, fallbackMemoryDir);
|
|
15788
16070
|
console.log(`OpenClaw config: ${configPath}`);
|
|
15789
16071
|
console.log(`Plugin dir: ${pluginDir}`);
|
|
15790
16072
|
if (legacyPluginDirForBackup) {
|
|
@@ -15792,7 +16074,7 @@ async function cmdOpenclawUpgrade(opts) {
|
|
|
15792
16074
|
}
|
|
15793
16075
|
console.log(`Memory dir: ${preservedMemoryDir}`);
|
|
15794
16076
|
console.log(`Package spec: ${packageSpec}`);
|
|
15795
|
-
console.log(`Backup root: ${
|
|
16077
|
+
console.log(`Backup root: ${path19.join(resolveOpenclawStateDir(), "backups")}`);
|
|
15796
16078
|
const plannedActions = [
|
|
15797
16079
|
`backup openclaw.json and the existing ${REMNIC_OPENCLAW_PLUGIN_ID} extension`,
|
|
15798
16080
|
...legacyPluginDirForBackup ? [`backup the existing ${REMNIC_OPENCLAW_LEGACY_PLUGIN_ID} extension without modifying it`] : [],
|
|
@@ -15830,9 +16112,9 @@ async function cmdOpenclawUpgrade(opts) {
|
|
|
15830
16112
|
assertDirectoryPathOrMissing(legacyPluginDirForBackup, "Legacy OpenClaw plugin dir");
|
|
15831
16113
|
}
|
|
15832
16114
|
const backupDir = createOpenclawUpgradeBackupDir();
|
|
15833
|
-
const configBackupPath =
|
|
15834
|
-
const pluginBackupDir =
|
|
15835
|
-
const legacyPluginBackupDir = legacyPluginDirForBackup ?
|
|
16115
|
+
const configBackupPath = path19.join(backupDir, "openclaw.json");
|
|
16116
|
+
const pluginBackupDir = path19.join(backupDir, "extensions", REMNIC_OPENCLAW_PLUGIN_ID);
|
|
16117
|
+
const legacyPluginBackupDir = legacyPluginDirForBackup ? path19.join(backupDir, "extensions", REMNIC_OPENCLAW_LEGACY_PLUGIN_ID) : void 0;
|
|
15836
16118
|
const backupNotes = [];
|
|
15837
16119
|
if (backupPathIfPresent(configPath, configBackupPath)) {
|
|
15838
16120
|
backupNotes.push(`+ Backed up config to ${configBackupPath}`);
|
|
@@ -15882,7 +16164,7 @@ async function cmdOpenclawUpgrade(opts) {
|
|
|
15882
16164
|
const managedRollbackDir = publishedInstallError ? publishedInstallError.managedRollbackDir : installResult?.managedRollbackDir;
|
|
15883
16165
|
const managedRollbackTargetDir = publishedInstallError?.managedRollbackTargetDir ?? installResult?.managedRollbackTargetDir ?? managedTargetDir;
|
|
15884
16166
|
const requiresHostManagedRestore = publishedInstallError?.requiresHostManagedRestore ?? installResult?.requiresHostManagedRestore ?? false;
|
|
15885
|
-
const managedRollbackSharesPluginDir = managedRollbackDir &&
|
|
16167
|
+
const managedRollbackSharesPluginDir = managedRollbackDir && path19.resolve(managedRollbackTargetDir) === path19.resolve(pluginDir);
|
|
15886
16168
|
const pluginRollbackDir = managedRollbackSharesPluginDir ? requiresHostManagedRestore ? rollbackDir : rollbackDir ?? managedRollbackDir : rollbackDir;
|
|
15887
16169
|
const shouldRestorePlugin = Boolean(
|
|
15888
16170
|
installResult && !requiresHostManagedRestore || pluginRollbackDir || publishedInstallError?.shouldRestoreBackup
|
|
@@ -15939,7 +16221,7 @@ async function cmdOpenclawUpgrade(opts) {
|
|
|
15939
16221
|
rollbackErrors.push(error);
|
|
15940
16222
|
}
|
|
15941
16223
|
if (pendingConfigRestoreError) rollbackErrors.push(pendingConfigRestoreError);
|
|
15942
|
-
if (managedRollbackDir &&
|
|
16224
|
+
if (managedRollbackDir && path19.resolve(managedRollbackTargetDir) !== path19.resolve(pluginDir) && !requiresHostManagedRestore) {
|
|
15943
16225
|
try {
|
|
15944
16226
|
rollbackNotes.push(
|
|
15945
16227
|
...rollbackOpenclawUpgrade({
|
|
@@ -16005,16 +16287,16 @@ async function cmdOpenclawMigrateEngram(opts) {
|
|
|
16005
16287
|
console.log(" - Re-apply any local source patches to the new package only after verifying the published build.");
|
|
16006
16288
|
}
|
|
16007
16289
|
function createOpenclawUpgradeBackupDir() {
|
|
16008
|
-
const backupsRoot =
|
|
16009
|
-
|
|
16010
|
-
return
|
|
16290
|
+
const backupsRoot = path19.join(resolveOpenclawStateDir(), "backups");
|
|
16291
|
+
fs26.mkdirSync(backupsRoot, { recursive: true });
|
|
16292
|
+
return fs26.mkdtempSync(path19.join(backupsRoot, `remnic-openclaw-upgrade-${formatOpenclawUpgradeStamp()}-`));
|
|
16011
16293
|
}
|
|
16012
16294
|
async function cmdTaxonomy(rest) {
|
|
16013
16295
|
initLogger5();
|
|
16014
16296
|
const configPath = resolveConfigPath();
|
|
16015
|
-
const raw =
|
|
16016
|
-
const remnicCfg =
|
|
16017
|
-
const config =
|
|
16297
|
+
const raw = fs26.existsSync(configPath) ? JSON.parse(fs26.readFileSync(configPath, "utf8")) : {};
|
|
16298
|
+
const remnicCfg = resolveRemnicConfigRecord16(raw);
|
|
16299
|
+
const config = parseConfig17(remnicCfg);
|
|
16018
16300
|
if (!config.taxonomyEnabled) {
|
|
16019
16301
|
console.error(
|
|
16020
16302
|
"Taxonomy is disabled in config (taxonomyEnabled = false). Enable it to use taxonomy commands."
|
|
@@ -16049,9 +16331,9 @@ async function cmdTaxonomy(rest) {
|
|
|
16049
16331
|
const doc = generateResolverDocument(taxonomy);
|
|
16050
16332
|
console.log(doc);
|
|
16051
16333
|
if (config.taxonomyAutoGenResolver) {
|
|
16052
|
-
const resolverPath =
|
|
16053
|
-
|
|
16054
|
-
|
|
16334
|
+
const resolverPath = path19.join(config.memoryDir, ".taxonomy", "RESOLVER.md");
|
|
16335
|
+
fs26.mkdirSync(path19.dirname(resolverPath), { recursive: true });
|
|
16336
|
+
fs26.writeFileSync(resolverPath, doc);
|
|
16055
16337
|
console.error(`Written: ${resolverPath}`);
|
|
16056
16338
|
}
|
|
16057
16339
|
break;
|
|
@@ -16096,8 +16378,8 @@ async function cmdTaxonomy(rest) {
|
|
|
16096
16378
|
console.log(`Added category "${id}" (${name}).`);
|
|
16097
16379
|
if (config.taxonomyAutoGenResolver) {
|
|
16098
16380
|
const doc = generateResolverDocument(taxonomy);
|
|
16099
|
-
const resolverPath =
|
|
16100
|
-
|
|
16381
|
+
const resolverPath = path19.join(config.memoryDir, ".taxonomy", "RESOLVER.md");
|
|
16382
|
+
fs26.writeFileSync(resolverPath, doc);
|
|
16101
16383
|
console.error(`Regenerated: ${resolverPath}`);
|
|
16102
16384
|
}
|
|
16103
16385
|
break;
|
|
@@ -16127,8 +16409,8 @@ async function cmdTaxonomy(rest) {
|
|
|
16127
16409
|
console.log(`Removed category "${id}".`);
|
|
16128
16410
|
if (config.taxonomyAutoGenResolver) {
|
|
16129
16411
|
const doc = generateResolverDocument(taxonomy);
|
|
16130
|
-
const resolverPath =
|
|
16131
|
-
|
|
16412
|
+
const resolverPath = path19.join(config.memoryDir, ".taxonomy", "RESOLVER.md");
|
|
16413
|
+
fs26.writeFileSync(resolverPath, doc);
|
|
16132
16414
|
console.error(`Regenerated: ${resolverPath}`);
|
|
16133
16415
|
}
|
|
16134
16416
|
break;
|
|
@@ -16319,12 +16601,12 @@ async function runTrainingExport(args, stdout = process.stdout) {
|
|
|
16319
16601
|
`Unknown training-export format "${args.format}". ${validList}`
|
|
16320
16602
|
);
|
|
16321
16603
|
}
|
|
16322
|
-
if (!
|
|
16604
|
+
if (!fs26.existsSync(args.memoryDir)) {
|
|
16323
16605
|
throw new Error(
|
|
16324
16606
|
`--memory-dir "${args.memoryDir}" does not exist. Provide the path to an existing memory directory.`
|
|
16325
16607
|
);
|
|
16326
16608
|
}
|
|
16327
|
-
if (!
|
|
16609
|
+
if (!fs26.statSync(args.memoryDir).isDirectory()) {
|
|
16328
16610
|
throw new Error(
|
|
16329
16611
|
`--memory-dir "${args.memoryDir}" is not a directory. Provide the path to a memory directory, not a file.`
|
|
16330
16612
|
);
|
|
@@ -16409,11 +16691,11 @@ async function runTrainingExport(args, stdout = process.stdout) {
|
|
|
16409
16691
|
);
|
|
16410
16692
|
}
|
|
16411
16693
|
const formatted = adapter.formatRecords(records);
|
|
16412
|
-
const outDir =
|
|
16413
|
-
|
|
16694
|
+
const outDir = path19.dirname(args.output);
|
|
16695
|
+
fs26.mkdirSync(outDir, { recursive: true });
|
|
16414
16696
|
const tmpPath = `${args.output}.tmp-${process.pid}-${Date.now()}`;
|
|
16415
|
-
|
|
16416
|
-
|
|
16697
|
+
fs26.writeFileSync(tmpPath, formatted, "utf-8");
|
|
16698
|
+
fs26.renameSync(tmpPath, args.output);
|
|
16417
16699
|
stdout.write(
|
|
16418
16700
|
`Exported ${records.length} records to ${args.output} (${adapter.name} format)
|
|
16419
16701
|
`
|
|
@@ -16526,7 +16808,7 @@ async function main(argv = process.argv.slice(2)) {
|
|
|
16526
16808
|
case "tree": {
|
|
16527
16809
|
const subAction = rest[0];
|
|
16528
16810
|
const json = rest.includes("--json");
|
|
16529
|
-
const outputDir = resolveFlag(rest, "--output") ??
|
|
16811
|
+
const outputDir = resolveFlag(rest, "--output") ?? path19.join(process.cwd(), ".remnic", "context-tree");
|
|
16530
16812
|
const categoriesFlag = resolveFlag(rest, "--categories");
|
|
16531
16813
|
const categories = categoriesFlag ? categoriesFlag.split(",") : void 0;
|
|
16532
16814
|
const maxPerCategoryRaw = resolveFlag(rest, "--max-per-category");
|
|
@@ -16591,7 +16873,7 @@ async function main(argv = process.argv.slice(2)) {
|
|
|
16591
16873
|
}
|
|
16592
16874
|
}, 500);
|
|
16593
16875
|
};
|
|
16594
|
-
|
|
16876
|
+
fs26.watch(memoryDir, { recursive: true }, (_event, filename) => {
|
|
16595
16877
|
if (filename && filename.startsWith(".")) return;
|
|
16596
16878
|
rebuild();
|
|
16597
16879
|
});
|
|
@@ -16599,12 +16881,12 @@ async function main(argv = process.argv.slice(2)) {
|
|
|
16599
16881
|
});
|
|
16600
16882
|
} else if (subAction === "validate") {
|
|
16601
16883
|
const treeDir = outputDir;
|
|
16602
|
-
if (!
|
|
16884
|
+
if (!fs26.existsSync(treeDir)) {
|
|
16603
16885
|
console.error(`Context tree not found at ${treeDir}. Run 'remnic tree generate' first.`);
|
|
16604
16886
|
process.exit(1);
|
|
16605
16887
|
}
|
|
16606
|
-
const indexPath =
|
|
16607
|
-
if (!
|
|
16888
|
+
const indexPath = path19.join(treeDir, "INDEX.md");
|
|
16889
|
+
if (!fs26.existsSync(indexPath)) {
|
|
16608
16890
|
console.error(`INDEX.md missing in ${treeDir}. Tree may be corrupt \u2014 regenerate.`);
|
|
16609
16891
|
process.exit(1);
|
|
16610
16892
|
}
|
|
@@ -16791,12 +17073,28 @@ Other:
|
|
|
16791
17073
|
await runMeetingsBinaryCommand(rest);
|
|
16792
17074
|
break;
|
|
16793
17075
|
}
|
|
17076
|
+
case "timeline": {
|
|
17077
|
+
await runTimelineBinaryCommand(rest);
|
|
17078
|
+
break;
|
|
17079
|
+
}
|
|
16794
17080
|
case "location":
|
|
16795
17081
|
await runLocationBinaryCommand(rest);
|
|
16796
17082
|
break;
|
|
16797
17083
|
case "okf":
|
|
16798
17084
|
await runOkfBinaryCommand(rest);
|
|
16799
17085
|
break;
|
|
17086
|
+
case "export":
|
|
17087
|
+
await runExportOkfBinaryCommand(rest);
|
|
17088
|
+
break;
|
|
17089
|
+
case "standup":
|
|
17090
|
+
await runStandupBinaryCommand(rest);
|
|
17091
|
+
break;
|
|
17092
|
+
case "journal":
|
|
17093
|
+
await runJournalBinaryCommand(rest);
|
|
17094
|
+
break;
|
|
17095
|
+
case "codegraph":
|
|
17096
|
+
await runCodegraphBinaryCommand(rest);
|
|
17097
|
+
break;
|
|
16800
17098
|
case "external-wiki": {
|
|
16801
17099
|
await runExternalWikiBinaryCommand(rest);
|
|
16802
17100
|
break;
|
|
@@ -16810,10 +17108,10 @@ Other:
|
|
|
16810
17108
|
const targetFactory = async () => {
|
|
16811
17109
|
if (!orchestratorSingleton) {
|
|
16812
17110
|
const configPath = resolveConfigPath();
|
|
16813
|
-
const raw =
|
|
16814
|
-
const remnicCfg =
|
|
16815
|
-
const config =
|
|
16816
|
-
orchestratorSingleton = new
|
|
17111
|
+
const raw = fs26.existsSync(configPath) ? JSON.parse(fs26.readFileSync(configPath, "utf8")) : {};
|
|
17112
|
+
const remnicCfg = resolveRemnicConfigRecord16(raw);
|
|
17113
|
+
const config = parseConfig17(remnicCfg);
|
|
17114
|
+
orchestratorSingleton = new Orchestrator10(config);
|
|
16817
17115
|
await orchestratorSingleton.initialize();
|
|
16818
17116
|
await orchestratorSingleton.deferredReady;
|
|
16819
17117
|
}
|
|
@@ -17014,6 +17312,10 @@ Usage:
|
|
|
17014
17312
|
remnic okf <lint|sweep> [--json]
|
|
17015
17313
|
OKF v0.1 conformance: lint reports missing frontmatter/type findings,
|
|
17016
17314
|
sweep backfills missing type values (okf.sweepEnabled).
|
|
17315
|
+
remnic export okf --out <dir>
|
|
17316
|
+
Write a portable OKF v0.1 knowledge bundle (plaintext interchange).
|
|
17317
|
+
remnic standup [--date YYYY-MM-DD]
|
|
17318
|
+
Deterministic yesterday/today/blockers brief plus an activity grid.
|
|
17017
17319
|
remnic external-wiki search <query...> [--wiki-id <id>] [--limit <1-20>] [--max-chars-per-hit <100-8000>] [--json]
|
|
17018
17320
|
remnic doctor Run diagnostics
|
|
17019
17321
|
remnic config Show current config
|