mnemospark 1.2.2 → 1.3.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/index.d.ts CHANGED
@@ -715,17 +715,14 @@ type OpenClawCronPayload = {
715
715
  kind: "agentTurn";
716
716
  message: string;
717
717
  };
718
- type OpenClawCronDelivery = {
719
- mode: "announce";
720
- text: string;
721
- };
722
718
  type OpenClawCronJobEntry = {
723
719
  jobId: string;
724
720
  name: string;
725
721
  schedule: OpenClawCronSchedule;
726
722
  payload: OpenClawCronPayload;
727
723
  sessionTarget: "isolated";
728
- delivery: OpenClawCronDelivery;
724
+ /** OpenClaw 2026.4.x: bind isolated renewal work to the dedicated agent. */
725
+ agentId: string;
729
726
  };
730
727
  type OpenClawCronJobForLookup = {
731
728
  jobId: string;
@@ -740,6 +737,24 @@ type OpenClawCronAdapter = {
740
737
  };
741
738
  declare function createCloudCommand(options?: CreateCloudCommandOptions): OpenClawPluginCommandDefinition;
742
739
 
740
+ declare function getRenewalAgentId(): string;
741
+ /** Absolute path to node for renewal exec (override with MNEMOSPARK_CRON_NODE_BIN). */
742
+ declare function getRenewalNodeBinary(): string;
743
+ type EnsureOpenClawRenewalPrerequisitesOptions = {
744
+ homeDir?: string;
745
+ /** Skip all OpenClaw mutations (tests). */
746
+ disabled?: boolean;
747
+ /** Skip gateway restart (tests). */
748
+ skipGatewayRestart?: boolean;
749
+ };
750
+ /**
751
+ * Apply the Mnemospark Renewal Agent Runbook before registering the first renewal cron:
752
+ * - `agents.list` entry via `openclaw config set` + `openclaw config validate`
753
+ * - `~/.openclaw/exec-approvals.json` merge for the node binary
754
+ * - best-effort `openclaw gateway restart`
755
+ */
756
+ declare function ensureOpenClawRenewalPrerequisites(options?: EnsureOpenClawRenewalPrerequisitesOptions): Promise<void>;
757
+
743
758
  type RunMnemosparkSlashHandlerOptions = {
744
759
  cloudCommandHandler?: PluginCommandHandler;
745
760
  };
@@ -757,4 +772,4 @@ declare function runMnemosparkSlashHandler(ctx: PluginCommandContext, options?:
757
772
 
758
773
  declare const plugin: OpenClawPluginDefinition;
759
774
 
760
- export { BALANCE_THRESHOLDS, type BalanceInfo, BalanceMonitor, type CachedPaymentParams, DEFAULT_RETRY_CONFIG, EmptyWalletError, InsufficientFundsError, type InsufficientFundsInfo, type LowBalanceInfo, PaymentCache, type PaymentFetchResult, type PreAuthParams, type ProxyHandle, type ProxyOptions, type RetryConfig, RpcError, type SufficiencyResult, createCloudCommand, createPaymentFetch, plugin as default, fetchWithRetry, getProxyPort, isBalanceError, isEmptyWalletError, isInsufficientFundsError, isRetryable, isRpcError, runMnemosparkSlashHandler, startProxy };
775
+ export { BALANCE_THRESHOLDS, type BalanceInfo, BalanceMonitor, type CachedPaymentParams, DEFAULT_RETRY_CONFIG, EmptyWalletError, type EnsureOpenClawRenewalPrerequisitesOptions, InsufficientFundsError, type InsufficientFundsInfo, type LowBalanceInfo, PaymentCache, type PaymentFetchResult, type PreAuthParams, type ProxyHandle, type ProxyOptions, type RetryConfig, RpcError, type SufficiencyResult, createCloudCommand, createPaymentFetch, plugin as default, ensureOpenClawRenewalPrerequisites, fetchWithRetry, getProxyPort, getRenewalAgentId, getRenewalNodeBinary, isBalanceError, isEmptyWalletError, isInsufficientFundsError, isRetryable, isRpcError, runMnemosparkSlashHandler, startProxy };
package/dist/index.js CHANGED
@@ -3049,17 +3049,17 @@ var CLOUD_ONBOARDING_BLOCK_LINES = [
3049
3049
  ];
3050
3050
 
3051
3051
  // src/cloud-command.ts
3052
- import { spawn } from "child_process";
3052
+ import { spawn as spawn2 } from "child_process";
3053
3053
  import {
3054
3054
  createCipheriv,
3055
3055
  createHash as createHash2,
3056
3056
  randomBytes as randomBytesNode,
3057
- randomUUID as randomUUID3
3057
+ randomUUID as randomUUID4
3058
3058
  } from "crypto";
3059
3059
  import { createReadStream as createReadStream2, createWriteStream as createWriteStream2, statfsSync } from "fs";
3060
- import { lstat, mkdir as mkdir5, readFile as readFile3, readdir as readdir2, rm, stat as stat2, writeFile as writeFile3 } from "fs/promises";
3061
- import { homedir as homedir6, tmpdir } from "os";
3062
- import { basename as basename2, dirname as dirname5, join as join8, resolve as resolve2 } from "path";
3060
+ import { lstat, mkdir as mkdir6, readFile as readFile4, readdir as readdir2, rm, stat as stat2, writeFile as writeFile4 } from "fs/promises";
3061
+ import { homedir as homedir7, tmpdir } from "os";
3062
+ import { basename as basename2, dirname as dirname6, join as join10, resolve as resolve2 } from "path";
3063
3063
  import { Readable } from "stream";
3064
3064
  import { finished } from "stream/promises";
3065
3065
  import { privateKeyToAccount as privateKeyToAccount5 } from "viem/accounts";
@@ -4264,12 +4264,226 @@ var opStatusSchema = {
4264
4264
  ]
4265
4265
  };
4266
4266
 
4267
+ // src/openclaw-cli.ts
4268
+ import { spawn } from "child_process";
4269
+ import { join as join8 } from "path";
4270
+ async function runOpenClawCli(args, homeDir) {
4271
+ return await new Promise((resolvePromise, rejectPromise) => {
4272
+ let stdout = "";
4273
+ let stderr = "";
4274
+ const child = spawn("openclaw", args, {
4275
+ stdio: ["ignore", "pipe", "pipe"],
4276
+ env: {
4277
+ ...process.env,
4278
+ HOME: homeDir ?? process.env.HOME
4279
+ }
4280
+ });
4281
+ child.stdout.on("data", (chunk) => {
4282
+ stdout += chunk.toString();
4283
+ });
4284
+ child.stderr.on("data", (chunk) => {
4285
+ stderr += chunk.toString();
4286
+ });
4287
+ child.on("error", rejectPromise);
4288
+ child.on("close", (code) => {
4289
+ if (code === 0) {
4290
+ resolvePromise({ stdout, stderr });
4291
+ return;
4292
+ }
4293
+ rejectPromise(
4294
+ new Error(
4295
+ stderr.trim() || stdout.trim() || `openclaw ${args.join(" ")} exited with code ${code ?? "unknown"}`
4296
+ )
4297
+ );
4298
+ });
4299
+ });
4300
+ }
4301
+ function parseOpenClawCliJson(stdout, commandLabel) {
4302
+ const trimmed = stdout.trim();
4303
+ if (!trimmed) {
4304
+ throw new Error(`openclaw ${commandLabel} returned empty JSON output`);
4305
+ }
4306
+ try {
4307
+ return JSON.parse(trimmed);
4308
+ } catch {
4309
+ throw new Error(`openclaw ${commandLabel} returned invalid JSON output`);
4310
+ }
4311
+ }
4312
+ async function resolveOpenClawConfigFilePath(homeDir) {
4313
+ const { stdout } = await runOpenClawCli(["config", "file"], homeDir);
4314
+ const trimmed = stdout.trim();
4315
+ if (trimmed.startsWith("~/")) {
4316
+ return join8(homeDir, trimmed.slice(2));
4317
+ }
4318
+ if (trimmed.startsWith("~\\")) {
4319
+ return join8(homeDir, trimmed.slice(2));
4320
+ }
4321
+ return trimmed;
4322
+ }
4323
+
4324
+ // src/openclaw-renewal-runbook.ts
4325
+ import { mkdir as mkdir5, readFile as readFile3, rename as rename2, writeFile as writeFile3 } from "fs/promises";
4326
+ import { homedir as homedir6 } from "os";
4327
+ import { dirname as dirname5, join as join9 } from "path";
4328
+ import { randomUUID as randomUUID3 } from "crypto";
4329
+ var DEFAULT_RENEWAL_AGENT_ID = "mnemospark-renewal";
4330
+ var RENEWAL_NODE_ALLOWLIST_ID = "node-usr-bin-node";
4331
+ function getRenewalAgentId() {
4332
+ const fromEnv = process.env.MNEMOSPARK_CRON_AGENT_ID?.trim();
4333
+ return fromEnv && fromEnv.length > 0 ? fromEnv : DEFAULT_RENEWAL_AGENT_ID;
4334
+ }
4335
+ function getRenewalNodeBinary() {
4336
+ const fromEnv = process.env.MNEMOSPARK_CRON_NODE_BIN?.trim();
4337
+ return fromEnv && fromEnv.length > 0 ? fromEnv : "/usr/bin/node";
4338
+ }
4339
+ function runbookRenewalAgentEntry(agentId = getRenewalAgentId()) {
4340
+ return {
4341
+ id: agentId,
4342
+ tools: {
4343
+ deny: ["subagents"],
4344
+ exec: { ask: "off" }
4345
+ }
4346
+ };
4347
+ }
4348
+ function isRecord(value) {
4349
+ return Boolean(value) && typeof value === "object" && !Array.isArray(value);
4350
+ }
4351
+ function renewalAgentEntrySatisfied(existing, desired) {
4352
+ if (!isRecord(existing)) {
4353
+ return false;
4354
+ }
4355
+ if (existing.id !== desired.id) {
4356
+ return false;
4357
+ }
4358
+ const tools = existing.tools;
4359
+ if (!isRecord(tools)) {
4360
+ return false;
4361
+ }
4362
+ const deny = tools.deny;
4363
+ if (!Array.isArray(deny) || !deny.includes("subagents")) {
4364
+ return false;
4365
+ }
4366
+ const exec = tools.exec;
4367
+ if (!isRecord(exec) || exec.ask !== "off") {
4368
+ return false;
4369
+ }
4370
+ return true;
4371
+ }
4372
+ function mergeRenewalAgentIntoAgentsList(list, desired) {
4373
+ const arr = Array.isArray(list) ? [...list] : [];
4374
+ const idx = arr.findIndex((e) => isRecord(e) && typeof e.id === "string" && e.id === desired.id);
4375
+ if (idx === -1) {
4376
+ return { list: [...arr, desired], changed: true };
4377
+ }
4378
+ if (renewalAgentEntrySatisfied(arr[idx], desired)) {
4379
+ return { list: arr, changed: false };
4380
+ }
4381
+ const next = [...arr];
4382
+ next[idx] = desired;
4383
+ return { list: next, changed: true };
4384
+ }
4385
+ function mergeExecApprovalsAllowlist(doc, agentId, nodeBinary) {
4386
+ const prevAgents = doc.agents && isRecord(doc.agents) ? doc.agents : {};
4387
+ const block = prevAgents[agentId];
4388
+ const allowlist = Array.isArray(block?.allowlist) ? [...block.allowlist] : [];
4389
+ const hasPattern = allowlist.some((e) => e?.pattern === nodeBinary);
4390
+ if (hasPattern) {
4391
+ return { doc, changed: false };
4392
+ }
4393
+ allowlist.push({
4394
+ id: RENEWAL_NODE_ALLOWLIST_ID,
4395
+ pattern: nodeBinary,
4396
+ source: "manual",
4397
+ lastUsedAt: Date.now()
4398
+ });
4399
+ const nextAgents = {
4400
+ ...prevAgents,
4401
+ [agentId]: {
4402
+ ...block && isRecord(block) ? block : {},
4403
+ allowlist
4404
+ }
4405
+ };
4406
+ return { doc: { ...doc, agents: nextAgents }, changed: true };
4407
+ }
4408
+ async function readJsonFile(path) {
4409
+ const raw = await readFile3(path, "utf-8");
4410
+ return JSON.parse(raw);
4411
+ }
4412
+ async function writeFileAtomic(path, contents) {
4413
+ await mkdir5(dirname5(path), { recursive: true });
4414
+ const tmp = join9(dirname5(path), `.tmp-${randomUUID3()}`);
4415
+ await writeFile3(tmp, contents, "utf-8");
4416
+ await rename2(tmp, path);
4417
+ }
4418
+ async function ensureOpenClawRenewalPrerequisites(options = {}) {
4419
+ if (options.disabled ?? process.env.MNEMOSPARK_DISABLE_OPENCLAW_PREREQ === "1") {
4420
+ return;
4421
+ }
4422
+ const homeDir = options.homeDir ?? homedir6();
4423
+ const agentId = getRenewalAgentId();
4424
+ const desired = runbookRenewalAgentEntry(agentId);
4425
+ const nodeBinary = getRenewalNodeBinary();
4426
+ const configPath = await resolveOpenClawConfigFilePath(homeDir);
4427
+ let configRaw = "{}";
4428
+ try {
4429
+ configRaw = await readFile3(configPath, "utf-8");
4430
+ } catch (err) {
4431
+ if (err.code !== "ENOENT") {
4432
+ throw err;
4433
+ }
4434
+ }
4435
+ let parsed;
4436
+ try {
4437
+ parsed = JSON.parse(configRaw);
4438
+ } catch {
4439
+ throw new Error(
4440
+ `openclaw.json at ${configPath} is not valid JSON; fix or remove it before upload.`
4441
+ );
4442
+ }
4443
+ const agents = isRecord(parsed.agents) ? parsed.agents : {};
4444
+ const { list: mergedList, changed: agentChanged } = mergeRenewalAgentIntoAgentsList(
4445
+ agents.list,
4446
+ desired
4447
+ );
4448
+ if (agentChanged) {
4449
+ const listJson = JSON.stringify(mergedList);
4450
+ await runOpenClawCli(["config", "set", "agents.list", listJson, "--strict-json"], homeDir);
4451
+ await runOpenClawCli(["config", "validate"], homeDir);
4452
+ }
4453
+ const execPath = join9(homeDir, ".openclaw", "exec-approvals.json");
4454
+ let execDoc = {};
4455
+ try {
4456
+ const raw = await readJsonFile(execPath);
4457
+ execDoc = isRecord(raw) ? raw : {};
4458
+ } catch (err) {
4459
+ if (err.code !== "ENOENT") {
4460
+ throw err;
4461
+ }
4462
+ }
4463
+ const { doc: mergedExec, changed: execChanged } = mergeExecApprovalsAllowlist(
4464
+ execDoc,
4465
+ agentId,
4466
+ nodeBinary
4467
+ );
4468
+ if (execChanged) {
4469
+ await writeFileAtomic(execPath, `${JSON.stringify(mergedExec, null, 2)}
4470
+ `);
4471
+ }
4472
+ const skipRestart = options.skipGatewayRestart ?? process.env.MNEMOSPARK_SKIP_GATEWAY_RESTART === "1";
4473
+ if (!skipRestart && (agentChanged || execChanged)) {
4474
+ try {
4475
+ await runOpenClawCli(["gateway", "restart", "--json"], homeDir);
4476
+ } catch {
4477
+ }
4478
+ }
4479
+ }
4480
+
4267
4481
  // src/cloud-command.ts
4268
4482
  var SUPPORTED_BACKUP_PLATFORMS = /* @__PURE__ */ new Set(["darwin", "linux"]);
4269
- var BACKUP_DIR_SUBPATH = join8(".openclaw", "mnemospark", "backup");
4270
- var DEFAULT_BACKUP_DIR = join8(homedir6(), BACKUP_DIR_SUBPATH);
4271
- var BLOCKRUN_WALLET_KEY_SUBPATH = join8(".openclaw", "blockrun", "wallet.key");
4272
- var MNEMOSPARK_WALLET_KEY_SUBPATH = join8(".openclaw", "mnemospark", "wallet", "wallet.key");
4483
+ var BACKUP_DIR_SUBPATH = join10(".openclaw", "mnemospark", "backup");
4484
+ var DEFAULT_BACKUP_DIR = join10(homedir7(), BACKUP_DIR_SUBPATH);
4485
+ var BLOCKRUN_WALLET_KEY_SUBPATH = join10(".openclaw", "blockrun", "wallet.key");
4486
+ var MNEMOSPARK_WALLET_KEY_SUBPATH = join10(".openclaw", "mnemospark", "wallet", "wallet.key");
4273
4487
  var INLINE_UPLOAD_MAX_BYTES = 45e5;
4274
4488
  var NODE_FS_MAX_READFILE_BYTES = 2147483648;
4275
4489
  var PAYMENT_CRON_SCHEDULE = "0 0 1 * *";
@@ -4287,10 +4501,10 @@ var ORCHESTRATOR_MODES = /* @__PURE__ */ new Set(["inline", "subagent"]);
4287
4501
  function expandTilde(path) {
4288
4502
  const trimmed = path.trim();
4289
4503
  if (trimmed === "~") {
4290
- return homedir6();
4504
+ return homedir7();
4291
4505
  }
4292
4506
  if (trimmed.startsWith("~/") || trimmed.startsWith("~\\")) {
4293
- return join8(homedir6(), trimmed.slice(2));
4507
+ return join10(homedir7(), trimmed.slice(2));
4294
4508
  }
4295
4509
  return path;
4296
4510
  }
@@ -4858,7 +5072,7 @@ async function calculateInputSizeBytes(targetPath) {
4858
5072
  let total = 0;
4859
5073
  const entries = await readdir2(targetPath, { withFileTypes: true });
4860
5074
  for (const entry of entries) {
4861
- total += await calculateInputSizeBytes(join8(targetPath, entry.name));
5075
+ total += await calculateInputSizeBytes(join10(targetPath, entry.name));
4862
5076
  }
4863
5077
  return total;
4864
5078
  }
@@ -4870,11 +5084,11 @@ function getAvailableDiskBytes(tmpDir, options) {
4870
5084
  return stats.bavail * stats.bsize;
4871
5085
  }
4872
5086
  async function runTarGzip(archivePath, sourcePath) {
4873
- const sourceDir = dirname5(sourcePath);
5087
+ const sourceDir = dirname6(sourcePath);
4874
5088
  const sourceName = basename2(sourcePath);
4875
5089
  await new Promise((resolvePromise, rejectPromise) => {
4876
5090
  let stderr = "";
4877
- const child = spawn("tar", ["-czf", archivePath, "-C", sourceDir, sourceName], {
5091
+ const child = spawn2("tar", ["-czf", archivePath, "-C", sourceDir, sourceName], {
4878
5092
  stdio: ["ignore", "ignore", "pipe"]
4879
5093
  });
4880
5094
  child.stderr.on("data", (chunk) => {
@@ -4904,7 +5118,7 @@ async function resolveLocalUploadArchivePath(backupDir, objectId, friendlyName)
4904
5118
  if (friendlyName?.trim()) {
4905
5119
  try {
4906
5120
  const sanitized = sanitizeFriendlyNameForLocalBasename(friendlyName);
4907
- const candidate = join8(backupDir, sanitized);
5121
+ const candidate = join10(backupDir, sanitized);
4908
5122
  try {
4909
5123
  const st = await stat2(candidate);
4910
5124
  if (st.isFile()) {
@@ -4915,7 +5129,7 @@ async function resolveLocalUploadArchivePath(backupDir, objectId, friendlyName)
4915
5129
  } catch {
4916
5130
  }
4917
5131
  }
4918
- const legacyPath = join8(backupDir, objectId);
5132
+ const legacyPath = join10(backupDir, objectId);
4919
5133
  try {
4920
5134
  const legacyStats = await stat2(legacyPath);
4921
5135
  if (!legacyStats.isFile()) {
@@ -4953,7 +5167,7 @@ async function buildBackupObject(targetPathArg, options = {}) {
4953
5167
  tmpStats = await stat2(tmpDir);
4954
5168
  } catch (error) {
4955
5169
  if (error.code === "ENOENT") {
4956
- await mkdir5(tmpDir, { recursive: true });
5170
+ await mkdir6(tmpDir, { recursive: true });
4957
5171
  tmpStats = await stat2(tmpDir);
4958
5172
  } else {
4959
5173
  throw error;
@@ -4970,7 +5184,7 @@ async function buildBackupObject(targetPathArg, options = {}) {
4970
5184
  }
4971
5185
  const objectId = createObjectId(options);
4972
5186
  const archiveBaseSegment = options.archiveBasename?.trim() || objectId;
4973
- const archivePath = join8(tmpDir, archiveBaseSegment);
5187
+ const archivePath = join10(tmpDir, archiveBaseSegment);
4974
5188
  if (options.archiveBasename?.trim()) {
4975
5189
  try {
4976
5190
  const existing = await stat2(archivePath);
@@ -5026,48 +5240,6 @@ function normalizeOpenClawCronJobForLookup(value) {
5026
5240
  message: payloadMessage
5027
5241
  };
5028
5242
  }
5029
- async function runOpenClawCli(args, homeDir) {
5030
- return await new Promise((resolvePromise, rejectPromise) => {
5031
- let stdout = "";
5032
- let stderr = "";
5033
- const child = spawn("openclaw", args, {
5034
- stdio: ["ignore", "pipe", "pipe"],
5035
- env: {
5036
- ...process.env,
5037
- HOME: homeDir ?? process.env.HOME
5038
- }
5039
- });
5040
- child.stdout.on("data", (chunk) => {
5041
- stdout += chunk.toString();
5042
- });
5043
- child.stderr.on("data", (chunk) => {
5044
- stderr += chunk.toString();
5045
- });
5046
- child.on("error", rejectPromise);
5047
- child.on("close", (code) => {
5048
- if (code === 0) {
5049
- resolvePromise({ stdout, stderr });
5050
- return;
5051
- }
5052
- rejectPromise(
5053
- new Error(
5054
- stderr.trim() || stdout.trim() || `openclaw ${args.join(" ")} exited with code ${code ?? "unknown"}`
5055
- )
5056
- );
5057
- });
5058
- });
5059
- }
5060
- function parseOpenClawCliJson(stdout, commandLabel) {
5061
- const trimmed = stdout.trim();
5062
- if (!trimmed) {
5063
- throw new Error(`openclaw ${commandLabel} returned empty JSON output`);
5064
- }
5065
- try {
5066
- return JSON.parse(trimmed);
5067
- } catch {
5068
- throw new Error(`openclaw ${commandLabel} returned invalid JSON output`);
5069
- }
5070
- }
5071
5243
  function createOpenClawCliCronAdapter(homeDir) {
5072
5244
  return {
5073
5245
  add: async (job) => {
@@ -5083,11 +5255,11 @@ function createOpenClawCliCronAdapter(homeDir) {
5083
5255
  job.schedule.tz,
5084
5256
  "--session",
5085
5257
  job.sessionTarget,
5258
+ "--agent",
5259
+ job.agentId,
5086
5260
  "--message",
5087
5261
  job.payload.message,
5088
- "--announce",
5089
- "--description",
5090
- job.delivery.text,
5262
+ "--no-deliver",
5091
5263
  "--json"
5092
5264
  ],
5093
5265
  homeDir
@@ -5152,8 +5324,9 @@ function buildStoragePaymentCronCommand(job) {
5152
5324
  return `/mnemospark cloud ${buildStoragePaymentRenewalArgs(job)}`;
5153
5325
  }
5154
5326
  function buildOpenClawRenewalAgentMessage(openClawHome, renewalArgs) {
5155
- const cliPath = join8(openClawHome, ".openclaw/extensions/mnemospark/dist/cli.js");
5156
- return `Execute: node ${cliPath} cloud ${renewalArgs}`;
5327
+ const cliPath = join10(openClawHome, ".openclaw/extensions/mnemospark/dist/cli.js");
5328
+ const nodeBin = getRenewalNodeBinary();
5329
+ return `Command: ${nodeBin} ${cliPath} cloud ${renewalArgs}`;
5157
5330
  }
5158
5331
  function parseStoragePaymentCronCommand(command) {
5159
5332
  const objectIdMatch = command.match(/--object-id\s+("([^"\\]|\\.)*"|'([^'\\]|\\.)*'|\S+)/);
@@ -5199,10 +5372,7 @@ async function appendStoragePaymentCronJob(cronJob, adapter, payloadMessage) {
5199
5372
  message: payloadMessage
5200
5373
  },
5201
5374
  sessionTarget: "isolated",
5202
- delivery: {
5203
- mode: "announce",
5204
- text: "Thank you for using mnemospark cloud storage. Your renewal has been processed."
5205
- }
5375
+ agentId: getRenewalAgentId()
5206
5376
  };
5207
5377
  return adapter.add(openClawJob);
5208
5378
  }
@@ -5210,6 +5380,7 @@ async function removeStoragePaymentCronJob(cronId, adapter) {
5210
5380
  return adapter.remove(cronId);
5211
5381
  }
5212
5382
  async function createStoragePaymentCronJob(upload, storagePrice, openClawCronAdapter, openClawHomeDir, nowDateFn = () => /* @__PURE__ */ new Date()) {
5383
+ await ensureOpenClawRenewalPrerequisites({ homeDir: openClawHomeDir });
5213
5384
  const renewalFields = {
5214
5385
  walletAddress: upload.addr,
5215
5386
  objectId: upload.object_id,
@@ -5217,7 +5388,7 @@ async function createStoragePaymentCronJob(upload, storagePrice, openClawCronAda
5217
5388
  storagePrice
5218
5389
  };
5219
5390
  const renewalArgs = buildStoragePaymentRenewalArgs(renewalFields);
5220
- const provisionalCronId = randomUUID3();
5391
+ const provisionalCronId = randomUUID4();
5221
5392
  const cronJob = {
5222
5393
  cronId: provisionalCronId,
5223
5394
  createdAt: nowDateFn().toISOString(),
@@ -5241,7 +5412,7 @@ async function createStoragePaymentCronJob(upload, storagePrice, openClawCronAda
5241
5412
  }
5242
5413
  async function readWalletKeyIfPresent(walletPath) {
5243
5414
  try {
5244
- const key = (await readFile3(walletPath, "utf-8")).trim();
5415
+ const key = (await readFile4(walletPath, "utf-8")).trim();
5245
5416
  return isValidWalletPrivateKey(key) ? key : null;
5246
5417
  } catch (error) {
5247
5418
  if (error.code === "ENOENT") {
@@ -5255,9 +5426,9 @@ async function resolveWalletPrivateKey(homeDir) {
5255
5426
  if (isValidWalletPrivateKey(envKey)) {
5256
5427
  return envKey;
5257
5428
  }
5258
- const baseHome = homeDir ?? homedir6();
5259
- const primaryWalletPath = join8(baseHome, MNEMOSPARK_WALLET_KEY_SUBPATH);
5260
- const fallbackWalletPath = join8(baseHome, BLOCKRUN_WALLET_KEY_SUBPATH);
5429
+ const baseHome = homeDir ?? homedir7();
5430
+ const primaryWalletPath = join10(baseHome, MNEMOSPARK_WALLET_KEY_SUBPATH);
5431
+ const fallbackWalletPath = join10(baseHome, BLOCKRUN_WALLET_KEY_SUBPATH);
5261
5432
  const fromPrimary = await readWalletKeyIfPresent(primaryWalletPath);
5262
5433
  if (fromPrimary) {
5263
5434
  return fromPrimary;
@@ -5321,9 +5492,9 @@ async function encryptPlaintextFileToAesGcmPath(plaintextPath, dek, outPath, ran
5321
5492
  }
5322
5493
  async function loadOrCreateKek(walletAddress, homeDir) {
5323
5494
  const keyPath = resolveWalletKekPath(walletAddress, homeDir);
5324
- await mkdir5(dirname5(keyPath), { recursive: true });
5495
+ await mkdir6(dirname6(keyPath), { recursive: true });
5325
5496
  try {
5326
- const existing = await readFile3(keyPath);
5497
+ const existing = await readFile4(keyPath);
5327
5498
  return { kek: parseStoredAes256Key(existing), keyPath };
5328
5499
  } catch (error) {
5329
5500
  if (error.code !== "ENOENT") {
@@ -5331,7 +5502,7 @@ async function loadOrCreateKek(walletAddress, homeDir) {
5331
5502
  }
5332
5503
  }
5333
5504
  const generated = randomBytesNode(32);
5334
- await writeFile3(keyPath, generated, { mode: 384 });
5505
+ await writeFile4(keyPath, generated, { mode: 384 });
5335
5506
  return { kek: generated, keyPath };
5336
5507
  }
5337
5508
  async function prepareUploadPayload(archivePath, walletAddress, homeDir) {
@@ -5343,7 +5514,7 @@ async function prepareUploadPayload(archivePath, walletAddress, homeDir) {
5343
5514
  const dek = randomBytesNode(32);
5344
5515
  const wrappedDek = encryptAesGcm(dek, kek);
5345
5516
  if (archiveStat.size >= NODE_FS_MAX_READFILE_BYTES) {
5346
- const encryptedTempPath = join8(tmpdir(), `mnemospark-upload-${randomUUID3()}.enc`);
5517
+ const encryptedTempPath = join10(tmpdir(), `mnemospark-upload-${randomUUID4()}.enc`);
5347
5518
  try {
5348
5519
  await encryptPlaintextFileToAesGcmPath(archivePath, dek, encryptedTempPath);
5349
5520
  const encStat = await stat2(encryptedTempPath);
@@ -5369,7 +5540,7 @@ async function prepareUploadPayload(archivePath, walletAddress, homeDir) {
5369
5540
  throw err;
5370
5541
  }
5371
5542
  }
5372
- const plaintext = await readFile3(archivePath);
5543
+ const plaintext = await readFile4(archivePath);
5373
5544
  const encryptedContent = encryptAesGcm(plaintext, dek);
5374
5545
  const payloadHash = sha256Buffer(encryptedContent);
5375
5546
  const payload = {
@@ -5614,7 +5785,7 @@ function createInProcessSubagentOrchestrator() {
5614
5785
  };
5615
5786
  return {
5616
5787
  dispatch: async (input) => {
5617
- const sessionId = `agent:mnemospark:subagent:${randomUUID3()}`;
5788
+ const sessionId = `agent:mnemospark:subagent:${randomUUID4()}`;
5618
5789
  const state = {
5619
5790
  terminal: false,
5620
5791
  cancelRequested: false,
@@ -5716,7 +5887,7 @@ function createCloudCommand(options = {}) {
5716
5887
  createPaymentFetchFn: options.createPaymentFetchFn ?? createPaymentFetch,
5717
5888
  fetchImpl: options.fetchImpl ?? fetch,
5718
5889
  nowDateFn: options.nowDateFn ?? (() => /* @__PURE__ */ new Date()),
5719
- idempotencyKeyFn: options.idempotencyKeyFn ?? randomUUID3,
5890
+ idempotencyKeyFn: options.idempotencyKeyFn ?? randomUUID4,
5720
5891
  requestStorageLsFn: options.requestStorageLsFn ?? requestStorageLsViaProxy,
5721
5892
  requestStorageDownloadFn: options.requestStorageDownloadFn ?? requestStorageDownloadViaProxy,
5722
5893
  requestStorageDeleteFn: options.requestStorageDeleteFn ?? requestStorageDeleteViaProxy,
@@ -5860,8 +6031,8 @@ async function emitOperationEventBestEffort(eventType, context, homeDir) {
5860
6031
  }
5861
6032
  }
5862
6033
  function buildRequestCorrelation(forcedOperationId, forcedTraceId) {
5863
- const operationId = forcedOperationId?.trim() || randomUUID3();
5864
- const traceId = forcedTraceId?.trim() || randomUUID3();
6034
+ const operationId = forcedOperationId?.trim() || randomUUID4();
6035
+ const traceId = forcedTraceId?.trim() || randomUUID4();
5865
6036
  return { operationId, traceId };
5866
6037
  }
5867
6038
  function parseTransIdFromPaymentSettleBody(bodyText) {
@@ -6149,7 +6320,7 @@ ${operation.result_text}` : meta;
6149
6320
  };
6150
6321
  }
6151
6322
  if (!isTerminalOperationStatus(operation.status)) {
6152
- const traceId = operation.trace_id ?? randomUUID3();
6323
+ const traceId = operation.trace_id ?? randomUUID4();
6153
6324
  const cancelRequestedAt = (/* @__PURE__ */ new Date()).toISOString();
6154
6325
  await datastore.upsertOperation({
6155
6326
  operation_id: operation.operation_id,
@@ -6747,7 +6918,7 @@ operation-id: ${operationId}`,
6747
6918
  await emitCloudEventBestEffort(
6748
6919
  "backup.completed",
6749
6920
  {
6750
- operation_id: executionContext.forcedOperationId?.trim() || randomUUID3(),
6921
+ operation_id: executionContext.forcedOperationId?.trim() || randomUUID4(),
6751
6922
  object_id: result.objectId,
6752
6923
  status: "succeeded",
6753
6924
  details: {
@@ -7034,7 +7205,7 @@ operation-id: ${operationId}`,
7034
7205
  finalizedUploadResponse,
7035
7206
  cronStoragePrice,
7036
7207
  openClawCronAdapter,
7037
- mnemosparkHomeDir ?? homedir6(),
7208
+ mnemosparkHomeDir ?? homedir7(),
7038
7209
  nowDateFn
7039
7210
  );
7040
7211
  await datastore.upsertObject({
@@ -7828,8 +7999,11 @@ export {
7828
7999
  createCloudCommand,
7829
8000
  createPaymentFetch,
7830
8001
  index_default as default,
8002
+ ensureOpenClawRenewalPrerequisites,
7831
8003
  fetchWithRetry,
7832
8004
  getProxyPort,
8005
+ getRenewalAgentId,
8006
+ getRenewalNodeBinary,
7833
8007
  isBalanceError,
7834
8008
  isEmptyWalletError,
7835
8009
  isInsufficientFundsError,