mnemospark 1.2.2 → 1.4.0

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
@@ -3004,17 +3004,17 @@ var CLOUD_ONBOARDING_BLOCK_LINES = [
3004
3004
  ];
3005
3005
 
3006
3006
  // src/cloud-command.ts
3007
- import { spawn } from "child_process";
3007
+ import { spawn as spawn2 } from "child_process";
3008
3008
  import {
3009
3009
  createCipheriv,
3010
3010
  createHash as createHash2,
3011
3011
  randomBytes as randomBytesNode,
3012
- randomUUID as randomUUID3
3012
+ randomUUID as randomUUID4
3013
3013
  } from "crypto";
3014
3014
  import { createReadStream as createReadStream2, createWriteStream as createWriteStream2, statfsSync } from "fs";
3015
- import { lstat, mkdir as mkdir5, readFile as readFile3, readdir as readdir2, rm, stat as stat2, writeFile as writeFile3 } from "fs/promises";
3016
- import { homedir as homedir6, tmpdir } from "os";
3017
- import { basename as basename2, dirname as dirname5, join as join8, resolve as resolve2 } from "path";
3015
+ import { lstat, mkdir as mkdir6, readFile as readFile4, readdir as readdir2, rm, stat as stat2, writeFile as writeFile4 } from "fs/promises";
3016
+ import { homedir as homedir7, tmpdir } from "os";
3017
+ import { basename as basename2, dirname as dirname6, join as join10, resolve as resolve2 } from "path";
3018
3018
  import { Readable } from "stream";
3019
3019
  import { finished } from "stream/promises";
3020
3020
  import { privateKeyToAccount as privateKeyToAccount5 } from "viem/accounts";
@@ -4219,12 +4219,219 @@ var opStatusSchema = {
4219
4219
  ]
4220
4220
  };
4221
4221
 
4222
+ // src/openclaw-cli.ts
4223
+ import { spawn } from "child_process";
4224
+ import { join as join8 } from "path";
4225
+ async function runOpenClawCli(args, homeDir) {
4226
+ return await new Promise((resolvePromise, rejectPromise) => {
4227
+ let stdout = "";
4228
+ let stderr = "";
4229
+ const child = spawn("openclaw", args, {
4230
+ stdio: ["ignore", "pipe", "pipe"],
4231
+ env: {
4232
+ ...process.env,
4233
+ HOME: homeDir ?? process.env.HOME
4234
+ }
4235
+ });
4236
+ child.stdout.on("data", (chunk) => {
4237
+ stdout += chunk.toString();
4238
+ });
4239
+ child.stderr.on("data", (chunk) => {
4240
+ stderr += chunk.toString();
4241
+ });
4242
+ child.on("error", rejectPromise);
4243
+ child.on("close", (code) => {
4244
+ if (code === 0) {
4245
+ resolvePromise({ stdout, stderr });
4246
+ return;
4247
+ }
4248
+ rejectPromise(
4249
+ new Error(
4250
+ stderr.trim() || stdout.trim() || `openclaw ${args.join(" ")} exited with code ${code ?? "unknown"}`
4251
+ )
4252
+ );
4253
+ });
4254
+ });
4255
+ }
4256
+ function parseOpenClawCliJson(stdout, commandLabel) {
4257
+ const trimmed = stdout.trim();
4258
+ if (!trimmed) {
4259
+ throw new Error(`openclaw ${commandLabel} returned empty JSON output`);
4260
+ }
4261
+ try {
4262
+ return JSON.parse(trimmed);
4263
+ } catch {
4264
+ throw new Error(`openclaw ${commandLabel} returned invalid JSON output`);
4265
+ }
4266
+ }
4267
+ async function resolveOpenClawConfigFilePath(homeDir) {
4268
+ const { stdout } = await runOpenClawCli(["config", "file"], homeDir);
4269
+ const trimmed = stdout.trim();
4270
+ if (trimmed.startsWith("~/")) {
4271
+ return join8(homeDir, trimmed.slice(2));
4272
+ }
4273
+ if (trimmed.startsWith("~\\")) {
4274
+ return join8(homeDir, trimmed.slice(2));
4275
+ }
4276
+ return trimmed;
4277
+ }
4278
+
4279
+ // src/openclaw-renewal-runbook.ts
4280
+ import { mkdir as mkdir5, readFile as readFile3, rename as rename2, writeFile as writeFile3 } from "fs/promises";
4281
+ import { homedir as homedir6 } from "os";
4282
+ import { dirname as dirname5, join as join9 } from "path";
4283
+ import { randomUUID as randomUUID3 } from "crypto";
4284
+ var DEFAULT_RENEWAL_AGENT_ID = "mnemospark-renewal";
4285
+ var RENEWAL_NODE_ALLOWLIST_ID = "node-usr-bin-node";
4286
+ function getRenewalAgentId() {
4287
+ const fromEnv = process.env.MNEMOSPARK_CRON_AGENT_ID?.trim();
4288
+ return fromEnv && fromEnv.length > 0 ? fromEnv : DEFAULT_RENEWAL_AGENT_ID;
4289
+ }
4290
+ function getRenewalNodeBinary() {
4291
+ const fromEnv = process.env.MNEMOSPARK_CRON_NODE_BIN?.trim();
4292
+ return fromEnv && fromEnv.length > 0 ? fromEnv : "/usr/bin/node";
4293
+ }
4294
+ function runbookRenewalAgentEntry(agentId = getRenewalAgentId()) {
4295
+ return {
4296
+ id: agentId,
4297
+ tools: {
4298
+ deny: ["subagents"],
4299
+ exec: { ask: "off" }
4300
+ }
4301
+ };
4302
+ }
4303
+ function isRecord(value) {
4304
+ return Boolean(value) && typeof value === "object" && !Array.isArray(value);
4305
+ }
4306
+ function renewalAgentEntrySatisfied(existing, desired) {
4307
+ if (!isRecord(existing)) {
4308
+ return false;
4309
+ }
4310
+ if (existing.id !== desired.id) {
4311
+ return false;
4312
+ }
4313
+ const tools = existing.tools;
4314
+ if (!isRecord(tools)) {
4315
+ return false;
4316
+ }
4317
+ const deny = tools.deny;
4318
+ if (!Array.isArray(deny) || !deny.includes("subagents")) {
4319
+ return false;
4320
+ }
4321
+ const exec = tools.exec;
4322
+ if (!isRecord(exec) || exec.ask !== "off") {
4323
+ return false;
4324
+ }
4325
+ return true;
4326
+ }
4327
+ function mergeRenewalAgentIntoAgentsList(list, desired) {
4328
+ const arr = Array.isArray(list) ? [...list] : [];
4329
+ const idx = arr.findIndex((e) => isRecord(e) && typeof e.id === "string" && e.id === desired.id);
4330
+ if (idx === -1) {
4331
+ return { list: [...arr, desired], changed: true };
4332
+ }
4333
+ if (renewalAgentEntrySatisfied(arr[idx], desired)) {
4334
+ return { list: arr, changed: false };
4335
+ }
4336
+ const next = [...arr];
4337
+ next[idx] = desired;
4338
+ return { list: next, changed: true };
4339
+ }
4340
+ function mergeExecApprovalsAllowlist(doc, agentId, nodeBinary) {
4341
+ const prevAgents = doc.agents && isRecord(doc.agents) ? doc.agents : {};
4342
+ const block = prevAgents[agentId];
4343
+ const allowlist = Array.isArray(block?.allowlist) ? [...block.allowlist] : [];
4344
+ const hasPattern = allowlist.some((e) => e?.pattern === nodeBinary);
4345
+ if (hasPattern) {
4346
+ return { doc, changed: false };
4347
+ }
4348
+ allowlist.push({
4349
+ id: RENEWAL_NODE_ALLOWLIST_ID,
4350
+ pattern: nodeBinary,
4351
+ source: "manual",
4352
+ lastUsedAt: Date.now()
4353
+ });
4354
+ const nextAgents = {
4355
+ ...prevAgents,
4356
+ [agentId]: {
4357
+ ...block && isRecord(block) ? block : {},
4358
+ allowlist
4359
+ }
4360
+ };
4361
+ return { doc: { ...doc, agents: nextAgents }, changed: true };
4362
+ }
4363
+ async function readJsonFile(path) {
4364
+ const raw = await readFile3(path, "utf-8");
4365
+ return JSON.parse(raw);
4366
+ }
4367
+ async function writeFileAtomic(path, contents) {
4368
+ await mkdir5(dirname5(path), { recursive: true });
4369
+ const tmp = join9(dirname5(path), `.tmp-${randomUUID3()}`);
4370
+ await writeFile3(tmp, contents, "utf-8");
4371
+ await rename2(tmp, path);
4372
+ }
4373
+ async function ensureOpenClawRenewalPrerequisites(options = {}) {
4374
+ if (options.disabled ?? process.env.MNEMOSPARK_DISABLE_OPENCLAW_PREREQ === "1") {
4375
+ return;
4376
+ }
4377
+ const homeDir = options.homeDir ?? homedir6();
4378
+ const agentId = getRenewalAgentId();
4379
+ const desired = runbookRenewalAgentEntry(agentId);
4380
+ const nodeBinary = getRenewalNodeBinary();
4381
+ const configPath = await resolveOpenClawConfigFilePath(homeDir);
4382
+ let configRaw = "{}";
4383
+ try {
4384
+ configRaw = await readFile3(configPath, "utf-8");
4385
+ } catch (err) {
4386
+ if (err.code !== "ENOENT") {
4387
+ throw err;
4388
+ }
4389
+ }
4390
+ let parsed;
4391
+ try {
4392
+ parsed = JSON.parse(configRaw);
4393
+ } catch {
4394
+ throw new Error(
4395
+ `openclaw.json at ${configPath} is not valid JSON; fix or remove it before applying renewal prerequisites.`
4396
+ );
4397
+ }
4398
+ const agents = isRecord(parsed.agents) ? parsed.agents : {};
4399
+ const { list: mergedList, changed: agentChanged } = mergeRenewalAgentIntoAgentsList(
4400
+ agents.list,
4401
+ desired
4402
+ );
4403
+ if (agentChanged) {
4404
+ const listJson = JSON.stringify(mergedList);
4405
+ await runOpenClawCli(["config", "set", "agents.list", listJson, "--strict-json"], homeDir);
4406
+ await runOpenClawCli(["config", "validate"], homeDir);
4407
+ }
4408
+ const execPath = join9(homeDir, ".openclaw", "exec-approvals.json");
4409
+ let execDoc = {};
4410
+ try {
4411
+ const raw = await readJsonFile(execPath);
4412
+ execDoc = isRecord(raw) ? raw : {};
4413
+ } catch (err) {
4414
+ if (err.code !== "ENOENT") {
4415
+ throw err;
4416
+ }
4417
+ }
4418
+ const { doc: mergedExec, changed: execChanged } = mergeExecApprovalsAllowlist(
4419
+ execDoc,
4420
+ agentId,
4421
+ nodeBinary
4422
+ );
4423
+ if (execChanged) {
4424
+ await writeFileAtomic(execPath, `${JSON.stringify(mergedExec, null, 2)}
4425
+ `);
4426
+ }
4427
+ }
4428
+
4222
4429
  // src/cloud-command.ts
4223
4430
  var SUPPORTED_BACKUP_PLATFORMS = /* @__PURE__ */ new Set(["darwin", "linux"]);
4224
- var BACKUP_DIR_SUBPATH = join8(".openclaw", "mnemospark", "backup");
4225
- var DEFAULT_BACKUP_DIR = join8(homedir6(), BACKUP_DIR_SUBPATH);
4226
- var BLOCKRUN_WALLET_KEY_SUBPATH = join8(".openclaw", "blockrun", "wallet.key");
4227
- var MNEMOSPARK_WALLET_KEY_SUBPATH = join8(".openclaw", "mnemospark", "wallet", "wallet.key");
4431
+ var BACKUP_DIR_SUBPATH = join10(".openclaw", "mnemospark", "backup");
4432
+ var DEFAULT_BACKUP_DIR = join10(homedir7(), BACKUP_DIR_SUBPATH);
4433
+ var BLOCKRUN_WALLET_KEY_SUBPATH = join10(".openclaw", "blockrun", "wallet.key");
4434
+ var MNEMOSPARK_WALLET_KEY_SUBPATH = join10(".openclaw", "mnemospark", "wallet", "wallet.key");
4228
4435
  var INLINE_UPLOAD_MAX_BYTES = 45e5;
4229
4436
  var NODE_FS_MAX_READFILE_BYTES = 2147483648;
4230
4437
  var PAYMENT_CRON_SCHEDULE = "0 0 1 * *";
@@ -4242,10 +4449,10 @@ var ORCHESTRATOR_MODES = /* @__PURE__ */ new Set(["inline", "subagent"]);
4242
4449
  function expandTilde(path) {
4243
4450
  const trimmed = path.trim();
4244
4451
  if (trimmed === "~") {
4245
- return homedir6();
4452
+ return homedir7();
4246
4453
  }
4247
4454
  if (trimmed.startsWith("~/") || trimmed.startsWith("~\\")) {
4248
- return join8(homedir6(), trimmed.slice(2));
4455
+ return join10(homedir7(), trimmed.slice(2));
4249
4456
  }
4250
4457
  return path;
4251
4458
  }
@@ -4813,7 +5020,7 @@ async function calculateInputSizeBytes(targetPath) {
4813
5020
  let total = 0;
4814
5021
  const entries = await readdir2(targetPath, { withFileTypes: true });
4815
5022
  for (const entry of entries) {
4816
- total += await calculateInputSizeBytes(join8(targetPath, entry.name));
5023
+ total += await calculateInputSizeBytes(join10(targetPath, entry.name));
4817
5024
  }
4818
5025
  return total;
4819
5026
  }
@@ -4825,11 +5032,11 @@ function getAvailableDiskBytes(tmpDir, options) {
4825
5032
  return stats.bavail * stats.bsize;
4826
5033
  }
4827
5034
  async function runTarGzip(archivePath, sourcePath) {
4828
- const sourceDir = dirname5(sourcePath);
5035
+ const sourceDir = dirname6(sourcePath);
4829
5036
  const sourceName = basename2(sourcePath);
4830
5037
  await new Promise((resolvePromise, rejectPromise) => {
4831
5038
  let stderr = "";
4832
- const child = spawn("tar", ["-czf", archivePath, "-C", sourceDir, sourceName], {
5039
+ const child = spawn2("tar", ["-czf", archivePath, "-C", sourceDir, sourceName], {
4833
5040
  stdio: ["ignore", "ignore", "pipe"]
4834
5041
  });
4835
5042
  child.stderr.on("data", (chunk) => {
@@ -4859,7 +5066,7 @@ async function resolveLocalUploadArchivePath(backupDir, objectId, friendlyName)
4859
5066
  if (friendlyName?.trim()) {
4860
5067
  try {
4861
5068
  const sanitized = sanitizeFriendlyNameForLocalBasename(friendlyName);
4862
- const candidate = join8(backupDir, sanitized);
5069
+ const candidate = join10(backupDir, sanitized);
4863
5070
  try {
4864
5071
  const st = await stat2(candidate);
4865
5072
  if (st.isFile()) {
@@ -4870,7 +5077,7 @@ async function resolveLocalUploadArchivePath(backupDir, objectId, friendlyName)
4870
5077
  } catch {
4871
5078
  }
4872
5079
  }
4873
- const legacyPath = join8(backupDir, objectId);
5080
+ const legacyPath = join10(backupDir, objectId);
4874
5081
  try {
4875
5082
  const legacyStats = await stat2(legacyPath);
4876
5083
  if (!legacyStats.isFile()) {
@@ -4908,7 +5115,7 @@ async function buildBackupObject(targetPathArg, options = {}) {
4908
5115
  tmpStats = await stat2(tmpDir);
4909
5116
  } catch (error) {
4910
5117
  if (error.code === "ENOENT") {
4911
- await mkdir5(tmpDir, { recursive: true });
5118
+ await mkdir6(tmpDir, { recursive: true });
4912
5119
  tmpStats = await stat2(tmpDir);
4913
5120
  } else {
4914
5121
  throw error;
@@ -4925,7 +5132,7 @@ async function buildBackupObject(targetPathArg, options = {}) {
4925
5132
  }
4926
5133
  const objectId = createObjectId(options);
4927
5134
  const archiveBaseSegment = options.archiveBasename?.trim() || objectId;
4928
- const archivePath = join8(tmpDir, archiveBaseSegment);
5135
+ const archivePath = join10(tmpDir, archiveBaseSegment);
4929
5136
  if (options.archiveBasename?.trim()) {
4930
5137
  try {
4931
5138
  const existing = await stat2(archivePath);
@@ -4981,48 +5188,6 @@ function normalizeOpenClawCronJobForLookup(value) {
4981
5188
  message: payloadMessage
4982
5189
  };
4983
5190
  }
4984
- async function runOpenClawCli(args, homeDir) {
4985
- return await new Promise((resolvePromise, rejectPromise) => {
4986
- let stdout = "";
4987
- let stderr = "";
4988
- const child = spawn("openclaw", args, {
4989
- stdio: ["ignore", "pipe", "pipe"],
4990
- env: {
4991
- ...process.env,
4992
- HOME: homeDir ?? process.env.HOME
4993
- }
4994
- });
4995
- child.stdout.on("data", (chunk) => {
4996
- stdout += chunk.toString();
4997
- });
4998
- child.stderr.on("data", (chunk) => {
4999
- stderr += chunk.toString();
5000
- });
5001
- child.on("error", rejectPromise);
5002
- child.on("close", (code) => {
5003
- if (code === 0) {
5004
- resolvePromise({ stdout, stderr });
5005
- return;
5006
- }
5007
- rejectPromise(
5008
- new Error(
5009
- stderr.trim() || stdout.trim() || `openclaw ${args.join(" ")} exited with code ${code ?? "unknown"}`
5010
- )
5011
- );
5012
- });
5013
- });
5014
- }
5015
- function parseOpenClawCliJson(stdout, commandLabel) {
5016
- const trimmed = stdout.trim();
5017
- if (!trimmed) {
5018
- throw new Error(`openclaw ${commandLabel} returned empty JSON output`);
5019
- }
5020
- try {
5021
- return JSON.parse(trimmed);
5022
- } catch {
5023
- throw new Error(`openclaw ${commandLabel} returned invalid JSON output`);
5024
- }
5025
- }
5026
5191
  function createOpenClawCliCronAdapter(homeDir) {
5027
5192
  return {
5028
5193
  add: async (job) => {
@@ -5038,11 +5203,11 @@ function createOpenClawCliCronAdapter(homeDir) {
5038
5203
  job.schedule.tz,
5039
5204
  "--session",
5040
5205
  job.sessionTarget,
5206
+ "--agent",
5207
+ job.agentId,
5041
5208
  "--message",
5042
5209
  job.payload.message,
5043
- "--announce",
5044
- "--description",
5045
- job.delivery.text,
5210
+ "--no-deliver",
5046
5211
  "--json"
5047
5212
  ],
5048
5213
  homeDir
@@ -5107,8 +5272,9 @@ function buildStoragePaymentCronCommand(job) {
5107
5272
  return `/mnemospark cloud ${buildStoragePaymentRenewalArgs(job)}`;
5108
5273
  }
5109
5274
  function buildOpenClawRenewalAgentMessage(openClawHome, renewalArgs) {
5110
- const cliPath = join8(openClawHome, ".openclaw/extensions/mnemospark/dist/cli.js");
5111
- return `Execute: node ${cliPath} cloud ${renewalArgs}`;
5275
+ const cliPath = join10(openClawHome, ".openclaw/extensions/mnemospark/dist/cli.js");
5276
+ const nodeBin = getRenewalNodeBinary();
5277
+ return `Command: ${nodeBin} ${cliPath} cloud ${renewalArgs}`;
5112
5278
  }
5113
5279
  function parseStoragePaymentCronCommand(command) {
5114
5280
  const objectIdMatch = command.match(/--object-id\s+("([^"\\]|\\.)*"|'([^'\\]|\\.)*'|\S+)/);
@@ -5154,10 +5320,7 @@ async function appendStoragePaymentCronJob(cronJob, adapter, payloadMessage) {
5154
5320
  message: payloadMessage
5155
5321
  },
5156
5322
  sessionTarget: "isolated",
5157
- delivery: {
5158
- mode: "announce",
5159
- text: "Thank you for using mnemospark cloud storage. Your renewal has been processed."
5160
- }
5323
+ agentId: getRenewalAgentId()
5161
5324
  };
5162
5325
  return adapter.add(openClawJob);
5163
5326
  }
@@ -5172,7 +5335,7 @@ async function createStoragePaymentCronJob(upload, storagePrice, openClawCronAda
5172
5335
  storagePrice
5173
5336
  };
5174
5337
  const renewalArgs = buildStoragePaymentRenewalArgs(renewalFields);
5175
- const provisionalCronId = randomUUID3();
5338
+ const provisionalCronId = randomUUID4();
5176
5339
  const cronJob = {
5177
5340
  cronId: provisionalCronId,
5178
5341
  createdAt: nowDateFn().toISOString(),
@@ -5196,7 +5359,7 @@ async function createStoragePaymentCronJob(upload, storagePrice, openClawCronAda
5196
5359
  }
5197
5360
  async function readWalletKeyIfPresent(walletPath) {
5198
5361
  try {
5199
- const key = (await readFile3(walletPath, "utf-8")).trim();
5362
+ const key = (await readFile4(walletPath, "utf-8")).trim();
5200
5363
  return isValidWalletPrivateKey(key) ? key : null;
5201
5364
  } catch (error) {
5202
5365
  if (error.code === "ENOENT") {
@@ -5210,9 +5373,9 @@ async function resolveWalletPrivateKey(homeDir) {
5210
5373
  if (isValidWalletPrivateKey(envKey)) {
5211
5374
  return envKey;
5212
5375
  }
5213
- const baseHome = homeDir ?? homedir6();
5214
- const primaryWalletPath = join8(baseHome, MNEMOSPARK_WALLET_KEY_SUBPATH);
5215
- const fallbackWalletPath = join8(baseHome, BLOCKRUN_WALLET_KEY_SUBPATH);
5376
+ const baseHome = homeDir ?? homedir7();
5377
+ const primaryWalletPath = join10(baseHome, MNEMOSPARK_WALLET_KEY_SUBPATH);
5378
+ const fallbackWalletPath = join10(baseHome, BLOCKRUN_WALLET_KEY_SUBPATH);
5216
5379
  const fromPrimary = await readWalletKeyIfPresent(primaryWalletPath);
5217
5380
  if (fromPrimary) {
5218
5381
  return fromPrimary;
@@ -5276,9 +5439,9 @@ async function encryptPlaintextFileToAesGcmPath(plaintextPath, dek, outPath, ran
5276
5439
  }
5277
5440
  async function loadOrCreateKek(walletAddress, homeDir) {
5278
5441
  const keyPath = resolveWalletKekPath(walletAddress, homeDir);
5279
- await mkdir5(dirname5(keyPath), { recursive: true });
5442
+ await mkdir6(dirname6(keyPath), { recursive: true });
5280
5443
  try {
5281
- const existing = await readFile3(keyPath);
5444
+ const existing = await readFile4(keyPath);
5282
5445
  return { kek: parseStoredAes256Key(existing), keyPath };
5283
5446
  } catch (error) {
5284
5447
  if (error.code !== "ENOENT") {
@@ -5286,7 +5449,7 @@ async function loadOrCreateKek(walletAddress, homeDir) {
5286
5449
  }
5287
5450
  }
5288
5451
  const generated = randomBytesNode(32);
5289
- await writeFile3(keyPath, generated, { mode: 384 });
5452
+ await writeFile4(keyPath, generated, { mode: 384 });
5290
5453
  return { kek: generated, keyPath };
5291
5454
  }
5292
5455
  async function prepareUploadPayload(archivePath, walletAddress, homeDir) {
@@ -5298,7 +5461,7 @@ async function prepareUploadPayload(archivePath, walletAddress, homeDir) {
5298
5461
  const dek = randomBytesNode(32);
5299
5462
  const wrappedDek = encryptAesGcm(dek, kek);
5300
5463
  if (archiveStat.size >= NODE_FS_MAX_READFILE_BYTES) {
5301
- const encryptedTempPath = join8(tmpdir(), `mnemospark-upload-${randomUUID3()}.enc`);
5464
+ const encryptedTempPath = join10(tmpdir(), `mnemospark-upload-${randomUUID4()}.enc`);
5302
5465
  try {
5303
5466
  await encryptPlaintextFileToAesGcmPath(archivePath, dek, encryptedTempPath);
5304
5467
  const encStat = await stat2(encryptedTempPath);
@@ -5324,7 +5487,7 @@ async function prepareUploadPayload(archivePath, walletAddress, homeDir) {
5324
5487
  throw err;
5325
5488
  }
5326
5489
  }
5327
- const plaintext = await readFile3(archivePath);
5490
+ const plaintext = await readFile4(archivePath);
5328
5491
  const encryptedContent = encryptAesGcm(plaintext, dek);
5329
5492
  const payloadHash = sha256Buffer(encryptedContent);
5330
5493
  const payload = {
@@ -5569,7 +5732,7 @@ function createInProcessSubagentOrchestrator() {
5569
5732
  };
5570
5733
  return {
5571
5734
  dispatch: async (input) => {
5572
- const sessionId = `agent:mnemospark:subagent:${randomUUID3()}`;
5735
+ const sessionId = `agent:mnemospark:subagent:${randomUUID4()}`;
5573
5736
  const state = {
5574
5737
  terminal: false,
5575
5738
  cancelRequested: false,
@@ -5671,7 +5834,7 @@ function createCloudCommand(options = {}) {
5671
5834
  createPaymentFetchFn: options.createPaymentFetchFn ?? createPaymentFetch,
5672
5835
  fetchImpl: options.fetchImpl ?? fetch,
5673
5836
  nowDateFn: options.nowDateFn ?? (() => /* @__PURE__ */ new Date()),
5674
- idempotencyKeyFn: options.idempotencyKeyFn ?? randomUUID3,
5837
+ idempotencyKeyFn: options.idempotencyKeyFn ?? randomUUID4,
5675
5838
  requestStorageLsFn: options.requestStorageLsFn ?? requestStorageLsViaProxy,
5676
5839
  requestStorageDownloadFn: options.requestStorageDownloadFn ?? requestStorageDownloadViaProxy,
5677
5840
  requestStorageDeleteFn: options.requestStorageDeleteFn ?? requestStorageDeleteViaProxy,
@@ -5815,8 +5978,8 @@ async function emitOperationEventBestEffort(eventType, context, homeDir) {
5815
5978
  }
5816
5979
  }
5817
5980
  function buildRequestCorrelation(forcedOperationId, forcedTraceId) {
5818
- const operationId = forcedOperationId?.trim() || randomUUID3();
5819
- const traceId = forcedTraceId?.trim() || randomUUID3();
5981
+ const operationId = forcedOperationId?.trim() || randomUUID4();
5982
+ const traceId = forcedTraceId?.trim() || randomUUID4();
5820
5983
  return { operationId, traceId };
5821
5984
  }
5822
5985
  function parseTransIdFromPaymentSettleBody(bodyText) {
@@ -6104,7 +6267,7 @@ ${operation.result_text}` : meta;
6104
6267
  };
6105
6268
  }
6106
6269
  if (!isTerminalOperationStatus(operation.status)) {
6107
- const traceId = operation.trace_id ?? randomUUID3();
6270
+ const traceId = operation.trace_id ?? randomUUID4();
6108
6271
  const cancelRequestedAt = (/* @__PURE__ */ new Date()).toISOString();
6109
6272
  await datastore.upsertOperation({
6110
6273
  operation_id: operation.operation_id,
@@ -6702,7 +6865,7 @@ operation-id: ${operationId}`,
6702
6865
  await emitCloudEventBestEffort(
6703
6866
  "backup.completed",
6704
6867
  {
6705
- operation_id: executionContext.forcedOperationId?.trim() || randomUUID3(),
6868
+ operation_id: executionContext.forcedOperationId?.trim() || randomUUID4(),
6706
6869
  object_id: result.objectId,
6707
6870
  status: "succeeded",
6708
6871
  details: {
@@ -6989,7 +7152,7 @@ operation-id: ${operationId}`,
6989
7152
  finalizedUploadResponse,
6990
7153
  cronStoragePrice,
6991
7154
  openClawCronAdapter,
6992
- mnemosparkHomeDir ?? homedir6(),
7155
+ mnemosparkHomeDir ?? homedir7(),
6993
7156
  nowDateFn
6994
7157
  );
6995
7158
  await datastore.upsertObject({
@@ -7599,12 +7762,12 @@ async function buildWalletExportResponse() {
7599
7762
  }
7600
7763
 
7601
7764
  // src/cli.ts
7602
- import { spawn as spawn2 } from "child_process";
7603
- import { dirname as dirname6, join as join9 } from "path";
7765
+ import { spawn as spawn3 } from "child_process";
7766
+ import { dirname as dirname7, join as join11 } from "path";
7604
7767
  import { fileURLToPath as fileURLToPath2 } from "url";
7605
- import { mkdir as mkdir6, readFile as readFile4, writeFile as writeFile4 } from "fs/promises";
7768
+ import { mkdir as mkdir7, readFile as readFile5, writeFile as writeFile5 } from "fs/promises";
7606
7769
  import { existsSync as existsSync2 } from "fs";
7607
- import { homedir as homedir7 } from "os";
7770
+ import { homedir as homedir8 } from "os";
7608
7771
  function isHexPrivateKey(value) {
7609
7772
  return typeof value === "string" && /^0x[0-9a-fA-F]{64}$/.test(value.trim());
7610
7773
  }
@@ -7712,25 +7875,25 @@ function parseArgs(args) {
7712
7875
  return result;
7713
7876
  }
7714
7877
  var __filename2 = fileURLToPath2(import.meta.url);
7715
- var __dirname2 = dirname6(__filename2);
7716
- var PACKAGE_ROOT = dirname6(__dirname2);
7878
+ var __dirname2 = dirname7(__filename2);
7879
+ var PACKAGE_ROOT = dirname7(__dirname2);
7717
7880
  async function ensureDir(path) {
7718
- await mkdir6(path, { recursive: true });
7881
+ await mkdir7(path, { recursive: true });
7719
7882
  }
7720
7883
  async function deployExtensionFiles() {
7721
- const scriptsSource = join9(PACKAGE_ROOT, "scripts");
7884
+ const scriptsSource = join11(PACKAGE_ROOT, "scripts");
7722
7885
  if (!existsSync2(scriptsSource)) return;
7723
- const mnemoScriptsDir = join9(homedir7(), ".openclaw", "mnemospark", "scripts");
7886
+ const mnemoScriptsDir = join11(homedir8(), ".openclaw", "mnemospark", "scripts");
7724
7887
  await ensureDir(mnemoScriptsDir);
7725
- const uninstallSrc = join9(scriptsSource, "uninstall.sh");
7888
+ const uninstallSrc = join11(scriptsSource, "uninstall.sh");
7726
7889
  if (existsSync2(uninstallSrc)) {
7727
- const content = await readFile4(uninstallSrc);
7728
- await writeFile4(join9(mnemoScriptsDir, "uninstall.sh"), content, { mode: 493 });
7890
+ const content = await readFile5(uninstallSrc);
7891
+ await writeFile5(join11(mnemoScriptsDir, "uninstall.sh"), content, { mode: 493 });
7729
7892
  }
7730
7893
  }
7731
7894
  function isOpenClawAvailable() {
7732
7895
  return new Promise((resolve3) => {
7733
- const child = spawn2("openclaw", ["--version"], {
7896
+ const child = spawn3("openclaw", ["--version"], {
7734
7897
  stdio: "ignore",
7735
7898
  shell: true
7736
7899
  });
@@ -7739,13 +7902,13 @@ function isOpenClawAvailable() {
7739
7902
  });
7740
7903
  }
7741
7904
  function getOpenClawConfigPath() {
7742
- const stateDir = process.env.OPENCLAW_STATE_DIR ?? join9(homedir7(), ".openclaw");
7743
- return join9(stateDir, "openclaw.json");
7905
+ const stateDir = process.env.OPENCLAW_STATE_DIR ?? join11(homedir8(), ".openclaw");
7906
+ return join11(stateDir, "openclaw.json");
7744
7907
  }
7745
7908
  async function ensureMnemosparkInPluginsAllow() {
7746
7909
  const configPath = getOpenClawConfigPath();
7747
7910
  try {
7748
- const raw = await readFile4(configPath, "utf-8");
7911
+ const raw = await readFile5(configPath, "utf-8");
7749
7912
  const config = JSON.parse(raw);
7750
7913
  if (!config.plugins || typeof config.plugins !== "object") {
7751
7914
  config.plugins = {};
@@ -7757,7 +7920,7 @@ async function ensureMnemosparkInPluginsAllow() {
7757
7920
  const allow = plugins.allow;
7758
7921
  if (!allow.includes("mnemospark")) {
7759
7922
  allow.push("mnemospark");
7760
- await writeFile4(configPath, JSON.stringify(config, null, 2), "utf-8");
7923
+ await writeFile5(configPath, JSON.stringify(config, null, 2), "utf-8");
7761
7924
  console.log("[mnemospark] Added mnemospark to plugins.allow in openclaw.json.");
7762
7925
  }
7763
7926
  } catch (err) {
@@ -7770,7 +7933,7 @@ async function promptOrRunOpenClawPluginInstall() {
7770
7933
  const available = await isOpenClawAvailable();
7771
7934
  if (available) {
7772
7935
  console.log("\n[mnemospark] Registering plugin with OpenClaw...");
7773
- const child = spawn2("openclaw", ["plugins", "install", "mnemospark"], {
7936
+ const child = spawn3("openclaw", ["plugins", "install", "mnemospark"], {
7774
7937
  stdio: "inherit",
7775
7938
  shell: true
7776
7939
  });
@@ -7779,6 +7942,14 @@ async function promptOrRunOpenClawPluginInstall() {
7779
7942
  });
7780
7943
  if (exitCode === 0) {
7781
7944
  await ensureMnemosparkInPluginsAllow();
7945
+ try {
7946
+ await ensureOpenClawRenewalPrerequisites();
7947
+ } catch (err) {
7948
+ console.warn(
7949
+ "[mnemospark] Renewal prerequisites:",
7950
+ err instanceof Error ? err.message : String(err)
7951
+ );
7952
+ }
7782
7953
  } else {
7783
7954
  console.log(
7784
7955
  "\n[mnemospark] OpenClaw plugin install did not succeed. Run manually: openclaw plugins install mnemospark"
@@ -7792,7 +7963,7 @@ async function promptOrRunOpenClawPluginInstall() {
7792
7963
  }
7793
7964
  async function readLegacyWalletIfPresent() {
7794
7965
  try {
7795
- const key = (await readFile4(LEGACY_WALLET_FILE, "utf-8")).trim();
7966
+ const key = (await readFile5(LEGACY_WALLET_FILE, "utf-8")).trim();
7796
7967
  return isHexPrivateKey(key) ? key : null;
7797
7968
  } catch (error) {
7798
7969
  if (error.code === "ENOENT") {
@@ -7802,9 +7973,9 @@ async function readLegacyWalletIfPresent() {
7802
7973
  }
7803
7974
  }
7804
7975
  async function writeMnemosparkWallet(key) {
7805
- const dir = dirname6(WALLET_FILE);
7976
+ const dir = dirname7(WALLET_FILE);
7806
7977
  await ensureDir(dir);
7807
- await writeFile4(WALLET_FILE, `${key}
7978
+ await writeFile5(WALLET_FILE, `${key}
7808
7979
  `, { mode: 384 });
7809
7980
  }
7810
7981
  async function promptReuseLegacyWallet() {
@@ -7878,6 +8049,14 @@ async function runUpdate() {
7878
8049
  try {
7879
8050
  execSync(`npm install mnemospark@${latest}`, { stdio: "inherit" });
7880
8051
  console.log(`[mnemospark] Updated to ${latest}.`);
8052
+ try {
8053
+ await ensureOpenClawRenewalPrerequisites();
8054
+ } catch (err) {
8055
+ console.warn(
8056
+ "[mnemospark] Renewal prerequisites:",
8057
+ err instanceof Error ? err.message : String(err)
8058
+ );
8059
+ }
7881
8060
  } catch {
7882
8061
  console.log(
7883
8062
  "[mnemospark] npm install failed. You can update manually: npm install mnemospark@latest"