mnemospark 2026.4.11 → 2026.4.13

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/cli.js CHANGED
@@ -3216,7 +3216,7 @@ import {
3216
3216
  import { createReadStream as createReadStream2, createWriteStream as createWriteStream2, statfsSync } from "fs";
3217
3217
  import { lstat, mkdir as mkdir6, readFile as readFile4, readdir as readdir2, rm, stat as stat2, writeFile as writeFile4 } from "fs/promises";
3218
3218
  import { homedir as homedir7, tmpdir } from "os";
3219
- import { basename as basename2, dirname as dirname6, join as join10, resolve as resolve2 } from "path";
3219
+ import { basename as basename2, dirname as dirname7, join as join11, resolve as resolve2 } from "path";
3220
3220
  import { Readable } from "stream";
3221
3221
  import { finished } from "stream/promises";
3222
3222
  import { privateKeyToAccount as privateKeyToAccount5 } from "viem/accounts";
@@ -4450,6 +4450,8 @@ var opStatusSchema = {
4450
4450
  // src/openclaw-cli.ts
4451
4451
  import { spawn } from "child_process";
4452
4452
  import { join as join8 } from "path";
4453
+ var ANSI_ESCAPE_RE = new RegExp(`${String.fromCharCode(27)}\\[[0-9;]*m`, "g");
4454
+ var BOX_DRAWING_RE = /[\u2500-\u257F]/g;
4453
4455
  async function runOpenClawCli(args, homeDir) {
4454
4456
  return await new Promise((resolvePromise, rejectPromise) => {
4455
4457
  let stdout = "";
@@ -4492,16 +4494,59 @@ function parseOpenClawCliJson(stdout, commandLabel) {
4492
4494
  throw new Error(`openclaw ${commandLabel} returned invalid JSON output`);
4493
4495
  }
4494
4496
  }
4495
- async function resolveOpenClawConfigFilePath(homeDir) {
4496
- const { stdout } = await runOpenClawCli(["config", "file"], homeDir);
4497
- const trimmed = stdout.trim();
4498
- if (trimmed.startsWith("~/")) {
4499
- return join8(homeDir, trimmed.slice(2));
4497
+ function stripCliDecorations(line) {
4498
+ return line.replace(ANSI_ESCAPE_RE, "").replace(BOX_DRAWING_RE, "").trim();
4499
+ }
4500
+ function expandHomePath(homeDir, line) {
4501
+ if (line.startsWith("~/")) {
4502
+ return join8(homeDir, line.slice(2));
4500
4503
  }
4501
- if (trimmed.startsWith("~\\")) {
4502
- return join8(homeDir, trimmed.slice(2));
4504
+ if (line.startsWith("~\\")) {
4505
+ return join8(homeDir, line.slice(2));
4503
4506
  }
4504
- return trimmed;
4507
+ return line;
4508
+ }
4509
+ function looksLikeOpenClawConfigPath(line) {
4510
+ if (!line || line.includes("\n")) {
4511
+ return false;
4512
+ }
4513
+ if (line.endsWith("openclaw.json")) {
4514
+ return true;
4515
+ }
4516
+ if (line.startsWith("~/") || line.startsWith("~\\")) {
4517
+ return true;
4518
+ }
4519
+ if (line.startsWith("/")) {
4520
+ return true;
4521
+ }
4522
+ return /^[A-Za-z]:\\/.test(line);
4523
+ }
4524
+ function parseOpenClawConfigFileStdout(stdout, homeDir) {
4525
+ const lines = stdout.split(/\r?\n/);
4526
+ for (let i = lines.length - 1; i >= 0; i--) {
4527
+ const line = stripCliDecorations(lines[i] ?? "");
4528
+ if (!line || !looksLikeOpenClawConfigPath(line)) {
4529
+ continue;
4530
+ }
4531
+ return expandHomePath(homeDir, line);
4532
+ }
4533
+ return null;
4534
+ }
4535
+ function getOpenClawConfigPath(homeDir, env = process.env) {
4536
+ const stateDir = env.OPENCLAW_STATE_DIR ?? join8(homeDir, ".openclaw");
4537
+ return join8(stateDir, "openclaw.json");
4538
+ }
4539
+ async function resolveOpenClawConfigFilePath(homeDir) {
4540
+ const fallback = getOpenClawConfigPath(homeDir);
4541
+ try {
4542
+ const { stdout } = await runOpenClawCli(["config", "file"], homeDir);
4543
+ const parsed = parseOpenClawConfigFileStdout(stdout, homeDir);
4544
+ if (parsed) {
4545
+ return parsed;
4546
+ }
4547
+ } catch {
4548
+ }
4549
+ return fallback;
4505
4550
  }
4506
4551
 
4507
4552
  // src/openclaw-renewal-runbook.ts
@@ -4509,6 +4554,15 @@ import { mkdir as mkdir5, readFile as readFile3, rename as rename2, writeFile as
4509
4554
  import { homedir as homedir6 } from "os";
4510
4555
  import { dirname as dirname5, join as join9 } from "path";
4511
4556
  import { randomUUID as randomUUID3 } from "crypto";
4557
+ var MAX_CONFIG_PATH_LENGTH = 4096;
4558
+ function assertValidConfigPath(configPath) {
4559
+ if (configPath.includes("\n") || configPath.includes("\r")) {
4560
+ throw new Error("openclaw config path must not contain newlines");
4561
+ }
4562
+ if (configPath.length > MAX_CONFIG_PATH_LENGTH) {
4563
+ throw new Error("openclaw config path is too long");
4564
+ }
4565
+ }
4512
4566
  var DEFAULT_RENEWAL_AGENT_ID = "mnemospark-renewal";
4513
4567
  var DEFAULT_MNEMOSPARK_AGENT_ID = "mnemospark";
4514
4568
  var RENEWAL_NODE_ALLOWLIST_ID = "node-usr-bin-node";
@@ -4617,6 +4671,7 @@ async function ensureOpenClawRenewalPrerequisites(options = {}) {
4617
4671
  const desiredPlugin = runbookDedicatedAgentEntry(pluginAgentId);
4618
4672
  const nodeBinary = getRenewalNodeBinary();
4619
4673
  const configPath = await resolveOpenClawConfigFilePath(homeDir);
4674
+ assertValidConfigPath(configPath);
4620
4675
  let configRaw = "{}";
4621
4676
  try {
4622
4677
  configRaw = await readFile3(configPath, "utf-8");
@@ -4670,12 +4725,41 @@ async function ensureOpenClawRenewalPrerequisites(options = {}) {
4670
4725
  }
4671
4726
  }
4672
4727
 
4728
+ // src/mnemospark-cli-path.ts
4729
+ import { existsSync as existsSync2 } from "fs";
4730
+ import { dirname as dirname6, join as join10 } from "path";
4731
+ import { fileURLToPath as fileURLToPath2 } from "url";
4732
+ var DEFAULT_MODULE_URL = import.meta.url;
4733
+ function resolveMnemosparkCliPath(options = {}) {
4734
+ const fromEnv = process.env.MNEMOSPARK_CLI_PATH?.trim();
4735
+ if (fromEnv) {
4736
+ assertCliExists(fromEnv, options.requireExists);
4737
+ return fromEnv;
4738
+ }
4739
+ const moduleDir = dirname6(fileURLToPath2(options.moduleUrl ?? DEFAULT_MODULE_URL));
4740
+ const candidates = [join10(moduleDir, "cli.js"), join10(moduleDir, "cli.ts")];
4741
+ const resolved = candidates.find((candidate) => existsSync2(candidate)) ?? candidates[0];
4742
+ assertCliExists(resolved, options.requireExists);
4743
+ return resolved;
4744
+ }
4745
+ function assertCliExists(cliPath, requireExists) {
4746
+ if (requireExists === false) {
4747
+ return;
4748
+ }
4749
+ if (existsSync2(cliPath)) {
4750
+ return;
4751
+ }
4752
+ throw new Error(
4753
+ `mnemospark CLI not found at ${cliPath}. Install the plugin or set MNEMOSPARK_CLI_PATH to the installed dist/cli.js.`
4754
+ );
4755
+ }
4756
+
4673
4757
  // src/cloud-command.ts
4674
4758
  var SUPPORTED_BACKUP_PLATFORMS = /* @__PURE__ */ new Set(["darwin", "linux"]);
4675
- var BACKUP_DIR_SUBPATH = join10(".openclaw", "mnemospark", "backup");
4676
- var DEFAULT_BACKUP_DIR = join10(homedir7(), BACKUP_DIR_SUBPATH);
4677
- var BLOCKRUN_WALLET_KEY_SUBPATH = join10(".openclaw", "blockrun", "wallet.key");
4678
- var MNEMOSPARK_WALLET_KEY_SUBPATH = join10(".openclaw", "mnemospark", "wallet", "wallet.key");
4759
+ var BACKUP_DIR_SUBPATH = join11(".openclaw", "mnemospark", "backup");
4760
+ var DEFAULT_BACKUP_DIR = join11(homedir7(), BACKUP_DIR_SUBPATH);
4761
+ var BLOCKRUN_WALLET_KEY_SUBPATH = join11(".openclaw", "blockrun", "wallet.key");
4762
+ var MNEMOSPARK_WALLET_KEY_SUBPATH = join11(".openclaw", "mnemospark", "wallet", "wallet.key");
4679
4763
  var INLINE_UPLOAD_MAX_BYTES = 45e5;
4680
4764
  var NODE_FS_MAX_READFILE_BYTES = 2147483648;
4681
4765
  var PAYMENT_CRON_SCHEDULE = "0 0 1 * *";
@@ -4696,7 +4780,7 @@ function expandTilde(path) {
4696
4780
  return homedir7();
4697
4781
  }
4698
4782
  if (trimmed.startsWith("~/") || trimmed.startsWith("~\\")) {
4699
- return join10(homedir7(), trimmed.slice(2));
4783
+ return join11(homedir7(), trimmed.slice(2));
4700
4784
  }
4701
4785
  return path;
4702
4786
  }
@@ -5288,7 +5372,7 @@ async function calculateInputSizeBytes(targetPath) {
5288
5372
  let total = 0;
5289
5373
  const entries = await readdir2(targetPath, { withFileTypes: true });
5290
5374
  for (const entry of entries) {
5291
- total += await calculateInputSizeBytes(join10(targetPath, entry.name));
5375
+ total += await calculateInputSizeBytes(join11(targetPath, entry.name));
5292
5376
  }
5293
5377
  return total;
5294
5378
  }
@@ -5300,7 +5384,7 @@ function getAvailableDiskBytes(tmpDir, options) {
5300
5384
  return stats.bavail * stats.bsize;
5301
5385
  }
5302
5386
  async function runTarGzip(archivePath, sourcePath) {
5303
- const sourceDir = dirname6(sourcePath);
5387
+ const sourceDir = dirname7(sourcePath);
5304
5388
  const sourceName = basename2(sourcePath);
5305
5389
  await new Promise((resolvePromise, rejectPromise) => {
5306
5390
  let stderr = "";
@@ -5334,7 +5418,7 @@ async function resolveLocalUploadArchivePath(backupDir, objectId, friendlyName)
5334
5418
  if (friendlyName?.trim()) {
5335
5419
  try {
5336
5420
  const sanitized = sanitizeFriendlyNameForLocalBasename(friendlyName);
5337
- const candidate = join10(backupDir, sanitized);
5421
+ const candidate = join11(backupDir, sanitized);
5338
5422
  try {
5339
5423
  const st = await stat2(candidate);
5340
5424
  if (st.isFile()) {
@@ -5345,7 +5429,7 @@ async function resolveLocalUploadArchivePath(backupDir, objectId, friendlyName)
5345
5429
  } catch {
5346
5430
  }
5347
5431
  }
5348
- const legacyPath = join10(backupDir, objectId);
5432
+ const legacyPath = join11(backupDir, objectId);
5349
5433
  try {
5350
5434
  const legacyStats = await stat2(legacyPath);
5351
5435
  if (!legacyStats.isFile()) {
@@ -5400,7 +5484,7 @@ async function buildBackupObject(targetPathArg, options = {}) {
5400
5484
  }
5401
5485
  const objectId = createObjectId(options);
5402
5486
  const archiveBaseSegment = options.archiveBasename?.trim() || objectId;
5403
- const archivePath = join10(tmpDir, archiveBaseSegment);
5487
+ const archivePath = join11(tmpDir, archiveBaseSegment);
5404
5488
  if (options.archiveBasename?.trim()) {
5405
5489
  try {
5406
5490
  const existing = await stat2(archivePath);
@@ -5539,8 +5623,8 @@ function buildStoragePaymentRenewalArgs(job) {
5539
5623
  function buildStoragePaymentCronCommand(job) {
5540
5624
  return `/mnemospark cloud ${buildStoragePaymentRenewalArgs(job)}`;
5541
5625
  }
5542
- function buildOpenClawRenewalAgentMessage(openClawHome, renewalArgs) {
5543
- const cliPath = join10(openClawHome, ".openclaw/extensions/mnemospark/dist/cli.js");
5626
+ function buildOpenClawRenewalAgentMessage(renewalArgs) {
5627
+ const cliPath = resolveMnemosparkCliPath();
5544
5628
  const nodeBin = getRenewalNodeBinary();
5545
5629
  return `Command: ${nodeBin} ${cliPath} cloud ${renewalArgs}`;
5546
5630
  }
@@ -5595,7 +5679,7 @@ async function appendStoragePaymentCronJob(cronJob, adapter, payloadMessage) {
5595
5679
  async function removeStoragePaymentCronJob(cronId, adapter) {
5596
5680
  return adapter.remove(cronId);
5597
5681
  }
5598
- async function createStoragePaymentCronJob(upload, storagePrice, openClawCronAdapter, openClawHomeDir, nowDateFn = () => /* @__PURE__ */ new Date()) {
5682
+ async function createStoragePaymentCronJob(upload, storagePrice, openClawCronAdapter, nowDateFn = () => /* @__PURE__ */ new Date()) {
5599
5683
  const renewalFields = {
5600
5684
  walletAddress: upload.addr,
5601
5685
  objectId: upload.object_id,
@@ -5618,7 +5702,7 @@ async function createStoragePaymentCronJob(upload, storagePrice, openClawCronAda
5618
5702
  bucketName: upload.bucket_name,
5619
5703
  location: upload.location
5620
5704
  };
5621
- const payloadMessage = buildOpenClawRenewalAgentMessage(openClawHomeDir, renewalArgs);
5705
+ const payloadMessage = buildOpenClawRenewalAgentMessage(renewalArgs);
5622
5706
  const created = await appendStoragePaymentCronJob(cronJob, openClawCronAdapter, payloadMessage);
5623
5707
  if (created.jobId?.trim()) {
5624
5708
  cronJob.cronId = created.jobId.trim();
@@ -5642,8 +5726,8 @@ async function resolveWalletPrivateKey(homeDir) {
5642
5726
  return envKey;
5643
5727
  }
5644
5728
  const baseHome = homeDir ?? homedir7();
5645
- const primaryWalletPath = join10(baseHome, MNEMOSPARK_WALLET_KEY_SUBPATH);
5646
- const fallbackWalletPath = join10(baseHome, BLOCKRUN_WALLET_KEY_SUBPATH);
5729
+ const primaryWalletPath = join11(baseHome, MNEMOSPARK_WALLET_KEY_SUBPATH);
5730
+ const fallbackWalletPath = join11(baseHome, BLOCKRUN_WALLET_KEY_SUBPATH);
5647
5731
  const fromPrimary = await readWalletKeyIfPresent(primaryWalletPath);
5648
5732
  if (fromPrimary) {
5649
5733
  return fromPrimary;
@@ -5707,7 +5791,7 @@ async function encryptPlaintextFileToAesGcmPath(plaintextPath, dek, outPath, ran
5707
5791
  }
5708
5792
  async function loadOrCreateKek(walletAddress, homeDir) {
5709
5793
  const keyPath = resolveWalletKekPath(walletAddress, homeDir);
5710
- await mkdir6(dirname6(keyPath), { recursive: true });
5794
+ await mkdir6(dirname7(keyPath), { recursive: true });
5711
5795
  try {
5712
5796
  const existing = await readFile4(keyPath);
5713
5797
  return { kek: parseStoredAes256Key(existing), keyPath };
@@ -5729,7 +5813,7 @@ async function prepareUploadPayload(archivePath, walletAddress, homeDir) {
5729
5813
  const dek = randomBytesNode(32);
5730
5814
  const wrappedDek = encryptAesGcm(dek, kek);
5731
5815
  if (archiveStat.size >= NODE_FS_MAX_READFILE_BYTES) {
5732
- const encryptedTempPath = join10(tmpdir(), `mnemospark-upload-${randomUUID4()}.enc`);
5816
+ const encryptedTempPath = join11(tmpdir(), `mnemospark-upload-${randomUUID4()}.enc`);
5733
5817
  try {
5734
5818
  await encryptPlaintextFileToAesGcmPath(archivePath, dek, encryptedTempPath);
5735
5819
  const encStat = await stat2(encryptedTempPath);
@@ -7428,7 +7512,6 @@ operation-id: ${operationId}`,
7428
7512
  finalizedUploadResponse,
7429
7513
  cronStoragePrice,
7430
7514
  openClawCronAdapter,
7431
- mnemosparkHomeDir ?? homedir7(),
7432
7515
  nowDateFn
7433
7516
  );
7434
7517
  await datastore.upsertObject({
@@ -8177,10 +8260,10 @@ async function buildWalletExportResponse() {
8177
8260
 
8178
8261
  // src/cli.ts
8179
8262
  import { spawn as spawn3 } from "child_process";
8180
- import { dirname as dirname7, join as join11 } from "path";
8181
- import { fileURLToPath as fileURLToPath2 } from "url";
8263
+ import { dirname as dirname8, join as join12 } from "path";
8264
+ import { fileURLToPath as fileURLToPath3 } from "url";
8182
8265
  import { mkdir as mkdir7, readFile as readFile5, writeFile as writeFile5 } from "fs/promises";
8183
- import { existsSync as existsSync2 } from "fs";
8266
+ import { existsSync as existsSync3 } from "fs";
8184
8267
  import { homedir as homedir8 } from "os";
8185
8268
  function isHexPrivateKey(value) {
8186
8269
  return typeof value === "string" && /^0x[0-9a-fA-F]{64}$/.test(value.trim());
@@ -8288,21 +8371,21 @@ function parseArgs(args) {
8288
8371
  }
8289
8372
  return result;
8290
8373
  }
8291
- var __filename2 = fileURLToPath2(import.meta.url);
8292
- var __dirname2 = dirname7(__filename2);
8293
- var PACKAGE_ROOT = dirname7(__dirname2);
8374
+ var __filename2 = fileURLToPath3(import.meta.url);
8375
+ var __dirname2 = dirname8(__filename2);
8376
+ var PACKAGE_ROOT = dirname8(__dirname2);
8294
8377
  async function ensureDir(path) {
8295
8378
  await mkdir7(path, { recursive: true });
8296
8379
  }
8297
8380
  async function deployExtensionFiles() {
8298
- const scriptsSource = join11(PACKAGE_ROOT, "scripts");
8299
- if (!existsSync2(scriptsSource)) return;
8300
- const mnemoScriptsDir = join11(homedir8(), ".openclaw", "mnemospark", "scripts");
8381
+ const scriptsSource = join12(PACKAGE_ROOT, "scripts");
8382
+ if (!existsSync3(scriptsSource)) return;
8383
+ const mnemoScriptsDir = join12(homedir8(), ".openclaw", "mnemospark", "scripts");
8301
8384
  await ensureDir(mnemoScriptsDir);
8302
- const uninstallSrc = join11(scriptsSource, "uninstall.sh");
8303
- if (existsSync2(uninstallSrc)) {
8385
+ const uninstallSrc = join12(scriptsSource, "uninstall.sh");
8386
+ if (existsSync3(uninstallSrc)) {
8304
8387
  const content = await readFile5(uninstallSrc);
8305
- await writeFile5(join11(mnemoScriptsDir, "uninstall.sh"), content, { mode: 493 });
8388
+ await writeFile5(join12(mnemoScriptsDir, "uninstall.sh"), content, { mode: 493 });
8306
8389
  }
8307
8390
  }
8308
8391
  function isOpenClawAvailable() {
@@ -8315,12 +8398,8 @@ function isOpenClawAvailable() {
8315
8398
  child.on("close", (code) => resolve3(code === 0));
8316
8399
  });
8317
8400
  }
8318
- function getOpenClawConfigPath() {
8319
- const stateDir = process.env.OPENCLAW_STATE_DIR ?? join11(homedir8(), ".openclaw");
8320
- return join11(stateDir, "openclaw.json");
8321
- }
8322
8401
  async function ensureMnemosparkInPluginsAllow() {
8323
- const configPath = getOpenClawConfigPath();
8402
+ const configPath = getOpenClawConfigPath(homedir8());
8324
8403
  try {
8325
8404
  const raw = await readFile5(configPath, "utf-8");
8326
8405
  const config = JSON.parse(raw);
@@ -8387,7 +8466,7 @@ async function readLegacyWalletIfPresent() {
8387
8466
  }
8388
8467
  }
8389
8468
  async function writeMnemosparkWallet(key) {
8390
- const dir = dirname7(WALLET_FILE);
8469
+ const dir = dirname8(WALLET_FILE);
8391
8470
  await ensureDir(dir);
8392
8471
  await writeFile5(WALLET_FILE, `${key}
8393
8472
  `, { mode: 384 });