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 +125 -46
- package/dist/cli.js.map +1 -1
- package/dist/index.d.ts +13 -1
- package/dist/index.js +112 -28
- package/dist/index.js.map +1 -1
- package/openclaw.plugin.json +1 -1
- package/package.json +1 -1
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
|
|
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
|
-
|
|
4496
|
-
|
|
4497
|
-
|
|
4498
|
-
|
|
4499
|
-
|
|
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 (
|
|
4502
|
-
return join8(homeDir,
|
|
4504
|
+
if (line.startsWith("~\\")) {
|
|
4505
|
+
return join8(homeDir, line.slice(2));
|
|
4503
4506
|
}
|
|
4504
|
-
return
|
|
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 =
|
|
4676
|
-
var DEFAULT_BACKUP_DIR =
|
|
4677
|
-
var BLOCKRUN_WALLET_KEY_SUBPATH =
|
|
4678
|
-
var MNEMOSPARK_WALLET_KEY_SUBPATH =
|
|
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
|
|
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(
|
|
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 =
|
|
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 =
|
|
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 =
|
|
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 =
|
|
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(
|
|
5543
|
-
const cliPath =
|
|
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,
|
|
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(
|
|
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 =
|
|
5646
|
-
const fallbackWalletPath =
|
|
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(
|
|
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 =
|
|
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
|
|
8181
|
-
import { fileURLToPath as
|
|
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
|
|
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 =
|
|
8292
|
-
var __dirname2 =
|
|
8293
|
-
var PACKAGE_ROOT =
|
|
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 =
|
|
8299
|
-
if (!
|
|
8300
|
-
const mnemoScriptsDir =
|
|
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 =
|
|
8303
|
-
if (
|
|
8385
|
+
const uninstallSrc = join12(scriptsSource, "uninstall.sh");
|
|
8386
|
+
if (existsSync3(uninstallSrc)) {
|
|
8304
8387
|
const content = await readFile5(uninstallSrc);
|
|
8305
|
-
await writeFile5(
|
|
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 =
|
|
8469
|
+
const dir = dirname8(WALLET_FILE);
|
|
8391
8470
|
await ensureDir(dir);
|
|
8392
8471
|
await writeFile5(WALLET_FILE, `${key}
|
|
8393
8472
|
`, { mode: 384 });
|