mnemospark 0.9.2 → 1.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/cli.js CHANGED
@@ -1915,7 +1915,7 @@ async function startProxy(options) {
1915
1915
  emitProxyTerminalFromStatus(correlation, 400, { reason: "invalid_json" });
1916
1916
  sendJson(res, 400, {
1917
1917
  error: "Bad request",
1918
- message: "Invalid JSON body for /mnemospark_cloud price-storage"
1918
+ message: "Invalid JSON body for /mnemospark cloud price-storage"
1919
1919
  });
1920
1920
  return;
1921
1921
  }
@@ -1983,7 +1983,7 @@ async function startProxy(options) {
1983
1983
  });
1984
1984
  sendJson(res, 502, {
1985
1985
  error: "proxy_error",
1986
- message: `Failed to forward /mnemospark_cloud price-storage: ${err instanceof Error ? err.message : String(err)}`
1986
+ message: `Failed to forward /mnemospark cloud price-storage: ${err instanceof Error ? err.message : String(err)}`
1987
1987
  });
1988
1988
  }
1989
1989
  return;
@@ -2162,7 +2162,7 @@ async function startProxy(options) {
2162
2162
  emitProxyTerminalFromStatus(correlation, 400, { reason: "invalid_json" });
2163
2163
  sendJson(res, 400, {
2164
2164
  error: "Bad request",
2165
- message: "Invalid JSON body for /mnemospark_cloud upload"
2165
+ message: "Invalid JSON body for /mnemospark cloud upload"
2166
2166
  });
2167
2167
  return;
2168
2168
  }
@@ -2225,7 +2225,7 @@ async function startProxy(options) {
2225
2225
  error: "insufficient_balance",
2226
2226
  message: `Insufficient USDC balance. Current: ${sufficiency.info.balanceUSD}, Required: ${requiredUSD}`,
2227
2227
  wallet: requestPayload.wallet_address,
2228
- help: `Fund wallet ${requestPayload.wallet_address} on Base before running /mnemospark_cloud upload`
2228
+ help: `Fund wallet ${requestPayload.wallet_address} on Base before running /mnemospark cloud upload`
2229
2229
  });
2230
2230
  return;
2231
2231
  }
@@ -2333,7 +2333,7 @@ async function startProxy(options) {
2333
2333
  });
2334
2334
  sendJson(res, 502, {
2335
2335
  error: "proxy_error",
2336
- message: `Failed to forward /mnemospark_cloud upload: ${err instanceof Error ? err.message : String(err)}`
2336
+ message: `Failed to forward /mnemospark cloud upload: ${err instanceof Error ? err.message : String(err)}`
2337
2337
  });
2338
2338
  }
2339
2339
  return;
@@ -2351,7 +2351,7 @@ async function startProxy(options) {
2351
2351
  emitProxyTerminalFromStatus(correlation, 400, { reason: "invalid_json" });
2352
2352
  sendJson(res, 400, {
2353
2353
  error: "Bad request",
2354
- message: "Invalid JSON body for /mnemospark_cloud upload/confirm"
2354
+ message: "Invalid JSON body for /mnemospark cloud upload/confirm"
2355
2355
  });
2356
2356
  return;
2357
2357
  }
@@ -2432,7 +2432,7 @@ async function startProxy(options) {
2432
2432
  });
2433
2433
  sendJson(res, 502, {
2434
2434
  error: "proxy_error",
2435
- message: `Failed to forward /mnemospark_cloud upload/confirm: ${err instanceof Error ? err.message : String(err)}`
2435
+ message: `Failed to forward /mnemospark cloud upload/confirm: ${err instanceof Error ? err.message : String(err)}`
2436
2436
  });
2437
2437
  }
2438
2438
  return;
@@ -2450,7 +2450,7 @@ async function startProxy(options) {
2450
2450
  emitProxyTerminalFromStatus(correlation, 400, { reason: "invalid_json" });
2451
2451
  sendJson(res, 400, {
2452
2452
  error: "Bad request",
2453
- message: "Invalid JSON body for /mnemospark_cloud ls"
2453
+ message: "Invalid JSON body for /mnemospark cloud ls"
2454
2454
  });
2455
2455
  return;
2456
2456
  }
@@ -2523,7 +2523,7 @@ async function startProxy(options) {
2523
2523
  });
2524
2524
  sendJson(res, 502, {
2525
2525
  error: "proxy_error",
2526
- message: `Failed to forward /mnemospark_cloud ls: ${err instanceof Error ? err.message : String(err)}`
2526
+ message: `Failed to forward /mnemospark cloud ls: ${err instanceof Error ? err.message : String(err)}`
2527
2527
  });
2528
2528
  }
2529
2529
  return;
@@ -2543,7 +2543,7 @@ async function startProxy(options) {
2543
2543
  emitProxyTerminalFromStatus(correlation, 400, { reason: "invalid_json" });
2544
2544
  sendJson(res, 400, {
2545
2545
  error: "Bad request",
2546
- message: "Invalid JSON body for /mnemospark_cloud download"
2546
+ message: "Invalid JSON body for /mnemospark cloud download"
2547
2547
  });
2548
2548
  return;
2549
2549
  }
@@ -2644,7 +2644,7 @@ async function startProxy(options) {
2644
2644
  });
2645
2645
  sendJson(res, 502, {
2646
2646
  error: "proxy_error",
2647
- message: `Failed to forward /mnemospark_cloud download: ${err instanceof Error ? err.message : String(err)}`
2647
+ message: `Failed to forward /mnemospark cloud download: ${err instanceof Error ? err.message : String(err)}`
2648
2648
  });
2649
2649
  }
2650
2650
  return;
@@ -2662,7 +2662,7 @@ async function startProxy(options) {
2662
2662
  emitProxyTerminalFromStatus(correlation, 400, { reason: "invalid_json" });
2663
2663
  sendJson(res, 400, {
2664
2664
  error: "Bad request",
2665
- message: "Invalid JSON body for /mnemospark_cloud delete"
2665
+ message: "Invalid JSON body for /mnemospark cloud delete"
2666
2666
  });
2667
2667
  return;
2668
2668
  }
@@ -2739,7 +2739,7 @@ async function startProxy(options) {
2739
2739
  });
2740
2740
  sendJson(res, 502, {
2741
2741
  error: "proxy_error",
2742
- message: `Failed to forward /mnemospark_cloud delete: ${err instanceof Error ? err.message : String(err)}`
2742
+ message: `Failed to forward /mnemospark cloud delete: ${err instanceof Error ? err.message : String(err)}`
2743
2743
  });
2744
2744
  }
2745
2745
  return;
@@ -2965,6 +2965,10 @@ var pkg = require2(join6(__dirname, "..", "package.json"));
2965
2965
  var VERSION = pkg.version;
2966
2966
  var USER_AGENT = `mnemospark/${VERSION}`;
2967
2967
 
2968
+ // src/mnemospark-handler.ts
2969
+ import { existsSync, readFileSync } from "fs";
2970
+ import { privateKeyToAccount as privateKeyToAccount6 } from "viem/accounts";
2971
+
2968
2972
  // src/cloud-command.ts
2969
2973
  import { spawn } from "child_process";
2970
2974
  import {
@@ -3761,6 +3765,425 @@ async function createCloudDatastore(homeDir) {
3761
3765
  };
3762
3766
  }
3763
3767
 
3768
+ // src/args/normalize.ts
3769
+ function normalizeSmartQuotes(input) {
3770
+ return input.replace(/[\u201C\u201D]/g, '"').replace(/[\u2018\u2019]/g, "'");
3771
+ }
3772
+ function normalizeFlagPositionDashes(input) {
3773
+ const warnings = [];
3774
+ const pattern = /(^|\s)[\u2013\u2014](?=[A-Za-z_][A-Za-z0-9_-]*)/g;
3775
+ let changed = false;
3776
+ const text = input.replace(pattern, (m, prefix) => {
3777
+ changed = true;
3778
+ return `${prefix}--`;
3779
+ });
3780
+ if (changed) {
3781
+ warnings.push("Normalized en/em dash in flag position to ASCII double hyphen.");
3782
+ }
3783
+ return { text, warnings };
3784
+ }
3785
+ function normalizeInputForParsing(input) {
3786
+ const warnings = [];
3787
+ let text = normalizeSmartQuotes(input);
3788
+ const dashNorm = normalizeFlagPositionDashes(text);
3789
+ text = dashNorm.text;
3790
+ warnings.push(...dashNorm.warnings);
3791
+ return { text, warnings };
3792
+ }
3793
+
3794
+ // src/args/suggest.ts
3795
+ function levenshtein(a, b) {
3796
+ const m = a.length;
3797
+ const n = b.length;
3798
+ const dp = Array.from({ length: m + 1 }, () => new Array(n + 1).fill(0));
3799
+ for (let i = 0; i <= m; i++) dp[i][0] = i;
3800
+ for (let j = 0; j <= n; j++) dp[0][j] = j;
3801
+ for (let i = 1; i <= m; i++) {
3802
+ for (let j = 1; j <= n; j++) {
3803
+ const cost = a[i - 1] === b[j - 1] ? 0 : 1;
3804
+ dp[i][j] = Math.min(dp[i - 1][j] + 1, dp[i][j - 1] + 1, dp[i - 1][j - 1] + cost);
3805
+ }
3806
+ }
3807
+ return dp[m][n];
3808
+ }
3809
+ function suggestNearestKey(raw, candidates, maxDistance = 2) {
3810
+ const lower = raw.toLowerCase();
3811
+ let best = null;
3812
+ let bestDist = maxDistance + 1;
3813
+ for (const c of candidates) {
3814
+ const d = levenshtein(lower, c.toLowerCase());
3815
+ if (d < bestDist) {
3816
+ bestDist = d;
3817
+ best = c;
3818
+ }
3819
+ }
3820
+ return bestDist <= maxDistance ? best : null;
3821
+ }
3822
+
3823
+ // src/args/parser.ts
3824
+ function canonicalizeKey(rawKey) {
3825
+ return rawKey.normalize("NFKC").replace(/[\u2010\u2011\u2012\u2013\u2014\u2015\u2212]/g, "-").replace(/_/g, "-").toLowerCase().trim();
3826
+ }
3827
+ function buildAliasMap(schema) {
3828
+ const map = /* @__PURE__ */ new Map();
3829
+ for (const spec of schema.args) {
3830
+ map.set(canonicalizeKey(spec.name), spec);
3831
+ for (const alias of spec.aliases ?? []) {
3832
+ map.set(canonicalizeKey(alias), spec);
3833
+ }
3834
+ }
3835
+ return map;
3836
+ }
3837
+ function tokenize(input) {
3838
+ const tokens = [];
3839
+ let i = 0;
3840
+ while (i < input.length) {
3841
+ while (i < input.length && /\s/.test(input[i])) i++;
3842
+ if (i >= input.length) break;
3843
+ let raw = "";
3844
+ let value = "";
3845
+ if (input[i] === '"' || input[i] === "'") {
3846
+ const quote = input[i++];
3847
+ raw += quote;
3848
+ while (i < input.length) {
3849
+ const ch = input[i++];
3850
+ raw += ch;
3851
+ if (ch === "\\") {
3852
+ if (i < input.length) {
3853
+ const next = input[i++];
3854
+ raw += next;
3855
+ value += next;
3856
+ }
3857
+ continue;
3858
+ }
3859
+ if (ch === quote) {
3860
+ break;
3861
+ }
3862
+ value += ch;
3863
+ }
3864
+ tokens.push({ raw, value });
3865
+ continue;
3866
+ }
3867
+ while (i < input.length && !/\s/.test(input[i])) {
3868
+ const ch = input[i++];
3869
+ raw += ch;
3870
+ value += ch;
3871
+ }
3872
+ tokens.push({ raw, value });
3873
+ }
3874
+ return tokens;
3875
+ }
3876
+ function resolveKey(rawKey, aliasMap, schema, allCanonicalNames) {
3877
+ const canonical = canonicalizeKey(rawKey);
3878
+ const spec = aliasMap.get(canonical);
3879
+ if (!spec) {
3880
+ if (schema.allowUnknown) return { key: canonical };
3881
+ const suggestion = suggestNearestKey(rawKey, allCanonicalNames);
3882
+ const hint = suggestion ? ` Did you mean "${suggestion}"?` : "";
3883
+ return { error: `Unknown argument "${rawKey}".${hint}` };
3884
+ }
3885
+ return { key: spec.name, spec };
3886
+ }
3887
+ function addValue(out, key, value, spec) {
3888
+ const existing = out[key];
3889
+ if (existing === void 0) {
3890
+ out[key] = spec?.repeatable ? [value] : value;
3891
+ return null;
3892
+ }
3893
+ if (!spec?.repeatable) {
3894
+ return `Duplicate argument "${key}".`;
3895
+ }
3896
+ if (Array.isArray(existing)) {
3897
+ existing.push(value);
3898
+ } else {
3899
+ out[key] = [existing, value];
3900
+ }
3901
+ return null;
3902
+ }
3903
+ function collectCanonicalNames(schema) {
3904
+ const names = /* @__PURE__ */ new Set();
3905
+ for (const spec of schema.args) {
3906
+ names.add(spec.name);
3907
+ for (const a of spec.aliases ?? []) {
3908
+ names.add(a);
3909
+ }
3910
+ }
3911
+ return [...names];
3912
+ }
3913
+ function looksLikeDelimitedArgToken(token) {
3914
+ return /^[A-Za-z_][A-Za-z0-9_-]*[:=]/.test(token);
3915
+ }
3916
+ function tryParseDelimitedToken(token, delimiter, aliasMap, schema, allCanonicalNames, out) {
3917
+ const idx = token.indexOf(delimiter);
3918
+ if (idx <= 0) return { handled: false };
3919
+ const keyPart = token.slice(0, idx);
3920
+ if (!/^[A-Za-z_][A-Za-z0-9_-]*$/.test(keyPart)) return { handled: false };
3921
+ const rawKey = keyPart;
3922
+ const rawValue = token.slice(idx + 1);
3923
+ if (rawValue === "") {
3924
+ return { handled: true, error: `Empty value for argument "${rawKey}".` };
3925
+ }
3926
+ const resolved = resolveKey(rawKey, aliasMap, schema, allCanonicalNames);
3927
+ if (resolved.error) {
3928
+ return { handled: true, error: resolved.error };
3929
+ }
3930
+ const dupErr = addValue(out, resolved.key, rawValue, resolved.spec);
3931
+ if (dupErr) {
3932
+ return { handled: true, error: dupErr };
3933
+ }
3934
+ return { handled: true };
3935
+ }
3936
+ function parseCommandArgs(input, schema) {
3937
+ const warnings = [];
3938
+ const errors = [];
3939
+ const norm = normalizeInputForParsing(input);
3940
+ const normalized = norm.text;
3941
+ warnings.push(...norm.warnings);
3942
+ const tokens = tokenize(normalized);
3943
+ const aliasMap = buildAliasMap(schema);
3944
+ const allCanonicalNames = collectCanonicalNames(schema);
3945
+ const values = {};
3946
+ for (let i = 0; i < tokens.length; i++) {
3947
+ const token = tokens[i].value;
3948
+ {
3949
+ const parsed = tryParseDelimitedToken(
3950
+ token,
3951
+ ":",
3952
+ aliasMap,
3953
+ schema,
3954
+ allCanonicalNames,
3955
+ values
3956
+ );
3957
+ if (parsed.handled) {
3958
+ if (parsed.error) errors.push(parsed.error);
3959
+ continue;
3960
+ }
3961
+ }
3962
+ {
3963
+ const parsed = tryParseDelimitedToken(
3964
+ token,
3965
+ "=",
3966
+ aliasMap,
3967
+ schema,
3968
+ allCanonicalNames,
3969
+ values
3970
+ );
3971
+ if (parsed.handled) {
3972
+ if (parsed.error) errors.push(parsed.error);
3973
+ continue;
3974
+ }
3975
+ }
3976
+ if (token.startsWith("--")) {
3977
+ const rawKey = token.slice(2);
3978
+ if (!rawKey) {
3979
+ errors.push('Encountered "--" without an argument name.');
3980
+ continue;
3981
+ }
3982
+ const resolved = resolveKey(rawKey, aliasMap, schema, allCanonicalNames);
3983
+ if (resolved.error) {
3984
+ errors.push(resolved.error);
3985
+ continue;
3986
+ }
3987
+ const next = tokens[i + 1];
3988
+ if (!next) {
3989
+ if (resolved.spec?.bareBoolean) {
3990
+ const dupErr2 = addValue(values, resolved.key, "true", resolved.spec);
3991
+ if (dupErr2) errors.push(dupErr2);
3992
+ continue;
3993
+ }
3994
+ errors.push(`Missing value for argument "${resolved.key}".`);
3995
+ continue;
3996
+ }
3997
+ if (next.value.startsWith("--")) {
3998
+ if (resolved.spec?.bareBoolean) {
3999
+ const dupErr2 = addValue(values, resolved.key, "true", resolved.spec);
4000
+ if (dupErr2) errors.push(dupErr2);
4001
+ continue;
4002
+ }
4003
+ errors.push(`Missing value for argument "${resolved.key}".`);
4004
+ continue;
4005
+ }
4006
+ if (resolved.spec?.bareBoolean && looksLikeDelimitedArgToken(next.value)) {
4007
+ const dupErr2 = addValue(values, resolved.key, "true", resolved.spec);
4008
+ if (dupErr2) errors.push(dupErr2);
4009
+ continue;
4010
+ }
4011
+ const dupErr = addValue(values, resolved.key, next.value, resolved.spec);
4012
+ if (dupErr) errors.push(dupErr);
4013
+ i += 1;
4014
+ continue;
4015
+ }
4016
+ errors.push(`Unexpected token "${token}". Use key:value, key=value, or --key value.`);
4017
+ }
4018
+ for (const spec of schema.args) {
4019
+ if (spec.required && values[spec.name] === void 0) {
4020
+ errors.push(`Missing required argument "${spec.name}".`);
4021
+ }
4022
+ }
4023
+ if (errors.length > 0) {
4024
+ return {
4025
+ ok: false,
4026
+ normalizedInput: normalized,
4027
+ errors,
4028
+ warnings
4029
+ };
4030
+ }
4031
+ return {
4032
+ ok: true,
4033
+ normalizedInput: normalized,
4034
+ values,
4035
+ warnings
4036
+ };
4037
+ }
4038
+ function valuesToStringRecord(values) {
4039
+ const out = {};
4040
+ for (const [k, v] of Object.entries(values)) {
4041
+ out[k] = Array.isArray(v) ? v[v.length - 1] : v;
4042
+ }
4043
+ return out;
4044
+ }
4045
+
4046
+ // src/mnemospark-route.ts
4047
+ function parseVerboseToken(token) {
4048
+ const t = token.trim();
4049
+ const idx = t.indexOf(":");
4050
+ if (idx < 0) {
4051
+ return { name: t.toLowerCase(), ok: true };
4052
+ }
4053
+ const key = t.slice(0, idx).trim();
4054
+ const val = t.slice(idx + 1).trim().toLowerCase();
4055
+ if (!key) return { name: "", ok: false };
4056
+ if (val === "true") return { name: key.toLowerCase(), ok: true };
4057
+ return { name: key.toLowerCase(), ok: false };
4058
+ }
4059
+ function firstTokenAndRest(input) {
4060
+ const t = input.trim();
4061
+ if (!t) return { first: "", rest: "" };
4062
+ const spaceIdx = t.search(/\s/);
4063
+ if (spaceIdx === -1) return { first: t, rest: "" };
4064
+ return { first: t.slice(0, spaceIdx), rest: t.slice(spaceIdx + 1).trim() };
4065
+ }
4066
+ function routeMnemosparkArgs(args) {
4067
+ const trimmed = args?.trim() ?? "";
4068
+ if (!trimmed) {
4069
+ return { kind: "root-help" };
4070
+ }
4071
+ const { first, rest } = firstTokenAndRest(trimmed);
4072
+ const parsed = parseVerboseToken(first);
4073
+ if (!parsed.ok) {
4074
+ return {
4075
+ kind: "error",
4076
+ message: `Invalid token "${first}". Use name:true only with value true, or a bare name (e.g. cloud, wallet, help).`
4077
+ };
4078
+ }
4079
+ const head = parsed.name;
4080
+ if (head === "help") {
4081
+ return { kind: "root-help" };
4082
+ }
4083
+ if (head === "cloud") {
4084
+ return { kind: "cloud", rest };
4085
+ }
4086
+ if (head === "wallet") {
4087
+ return { kind: "wallet", rest };
4088
+ }
4089
+ return {
4090
+ kind: "error",
4091
+ message: [
4092
+ `Unknown command "${first}".`,
4093
+ "",
4094
+ "Try:",
4095
+ "\u2022 `/mnemospark help` \u2014 overview",
4096
+ "\u2022 `/mnemospark cloud help` \u2014 cloud commands",
4097
+ "\u2022 `/mnemospark wallet` \u2014 wallet status",
4098
+ "\u2022 `/mnemospark wallet help` \u2014 wallet commands"
4099
+ ].join("\n")
4100
+ };
4101
+ }
4102
+
4103
+ // src/arg-schemas.ts
4104
+ var priceStorageSchema = {
4105
+ args: [
4106
+ { name: "wallet-address", aliases: ["wallet"], required: true },
4107
+ { name: "object-id", aliases: ["object"], required: true },
4108
+ { name: "object-id-hash", aliases: ["hash"], required: true },
4109
+ { name: "gb", required: true },
4110
+ { name: "provider", required: true },
4111
+ { name: "region", required: true }
4112
+ ]
4113
+ };
4114
+ var uploadSchema = {
4115
+ args: [
4116
+ { name: "quote-id", aliases: ["quote"], required: true },
4117
+ { name: "wallet-address", aliases: ["wallet"], required: true },
4118
+ { name: "object-id", aliases: ["object"], required: true },
4119
+ { name: "object-id-hash", aliases: ["hash"], required: true },
4120
+ { name: "name" },
4121
+ { name: "async", bareBoolean: true },
4122
+ { name: "orchestrator" },
4123
+ { name: "timeout-seconds" }
4124
+ ]
4125
+ };
4126
+ var backupFlagsSchema = {
4127
+ args: [
4128
+ { name: "name" },
4129
+ { name: "async", bareBoolean: true },
4130
+ { name: "orchestrator" },
4131
+ { name: "timeout-seconds" }
4132
+ ]
4133
+ };
4134
+ var paymentSettleSchema = {
4135
+ args: [
4136
+ { name: "quote-id", aliases: ["quote"] },
4137
+ { name: "wallet-address", aliases: ["wallet"], required: true },
4138
+ { name: "object-id", aliases: ["object"] },
4139
+ { name: "object-key" },
4140
+ { name: "storage-price" },
4141
+ { name: "renewal", bareBoolean: true }
4142
+ ]
4143
+ };
4144
+ var lsSchema = {
4145
+ args: [
4146
+ { name: "wallet-address", aliases: ["wallet"], required: true },
4147
+ { name: "object-key" },
4148
+ { name: "name" },
4149
+ { name: "latest", bareBoolean: true },
4150
+ { name: "at" },
4151
+ { name: "location" },
4152
+ { name: "region" }
4153
+ ]
4154
+ };
4155
+ var downloadSchema = {
4156
+ args: [
4157
+ { name: "wallet-address", aliases: ["wallet"], required: true },
4158
+ { name: "object-key" },
4159
+ { name: "name" },
4160
+ { name: "latest", bareBoolean: true },
4161
+ { name: "at" },
4162
+ { name: "location" },
4163
+ { name: "region" },
4164
+ { name: "async", bareBoolean: true },
4165
+ { name: "orchestrator" },
4166
+ { name: "timeout-seconds" }
4167
+ ]
4168
+ };
4169
+ var deleteSchema = {
4170
+ args: [
4171
+ { name: "wallet-address", aliases: ["wallet"], required: true },
4172
+ { name: "object-key" },
4173
+ { name: "name" },
4174
+ { name: "latest", bareBoolean: true },
4175
+ { name: "at" },
4176
+ { name: "location" },
4177
+ { name: "region" }
4178
+ ]
4179
+ };
4180
+ var opStatusSchema = {
4181
+ args: [
4182
+ { name: "operation-id", required: true },
4183
+ { name: "cancel", bareBoolean: true }
4184
+ ]
4185
+ };
4186
+
3764
4187
  // src/cloud-command.ts
3765
4188
  var SUPPORTED_BACKUP_PLATFORMS = /* @__PURE__ */ new Set(["darwin", "linux"]);
3766
4189
  var BACKUP_DIR_SUBPATH = join8(".openclaw", "mnemospark", "backup");
@@ -3774,25 +4197,12 @@ var TAR_OVERHEAD_BYTES = 10 * 1024 * 1024;
3774
4197
  var QUOTE_VALIDITY_USER_NOTE = "Quotes are valid for one hour. Please run price-storage again if you need a new quote.";
3775
4198
  var MNEMOSPARK_SUPPORT_EMAIL = "pluggedin@mnemospark.ai";
3776
4199
  var CLOUD_HELP_FOOTER_STATE = "Local state: mnemospark records quotes, objects, payments, cron jobs, friendly names, and operation metadata in ~/.openclaw/mnemospark/state.db (SQLite). For troubleshooting and correlation, commands and the HTTP proxy append structured JSON lines to ~/.openclaw/mnemospark/events.jsonl. Monthly storage billing jobs are listed in ~/.openclaw/cron/jobs.json for OpenClaw scheduling.";
3777
- var REQUIRED_PRICE_STORAGE = "--wallet-address, --object-id, --object-id-hash, --gb, --provider, --region";
3778
- var REQUIRED_UPLOAD = "--quote-id, --wallet-address, --object-id, --object-id-hash";
3779
- var REQUIRED_BACKUP = "<file|directory> and --name <friendly-name>";
3780
- var REQUIRED_PAYMENT_SETTLE = "--wallet-address and (--quote-id | --renewal with --object-key)";
3781
- var PAYMENT_SETTLE_BOOLEAN_FLAGS = /* @__PURE__ */ new Set(["renewal"]);
3782
- var REQUIRED_STORAGE_OBJECT = "--wallet-address and one of (--object-key | --name [--latest|--at])";
3783
- var REQUIRED_LS = "--wallet-address (for one object add --object-key or --name [--latest|--at]; omit both to list the bucket)";
3784
- var PAYMENT_SETTLE_FLAG_NAMES = /* @__PURE__ */ new Set([
3785
- "quote-id",
3786
- "wallet-address",
3787
- "object-id",
3788
- "object-key",
3789
- "storage-price",
3790
- "renewal"
3791
- ]);
3792
- var BOOLEAN_SELECTOR_FLAGS = /* @__PURE__ */ new Set(["latest"]);
3793
- var BOOLEAN_ASYNC_FLAGS = /* @__PURE__ */ new Set(["async"]);
3794
- var BOOLEAN_OP_STATUS_FLAGS = /* @__PURE__ */ new Set(["cancel"]);
3795
- var BOOLEAN_SELECTOR_AND_ASYNC_FLAGS = /* @__PURE__ */ new Set(["latest", "async"]);
4200
+ var REQUIRED_PRICE_STORAGE = "wallet-address:, object-id:, object-id-hash:, gb:, provider:, region:";
4201
+ var REQUIRED_UPLOAD = "quote-id:, wallet-address:, object-id:, object-id-hash:";
4202
+ var REQUIRED_BACKUP = "<file|directory> and name:<friendly-name>";
4203
+ var REQUIRED_PAYMENT_SETTLE = "wallet-address: and (quote-id: | renewal:true with object-key:)";
4204
+ var REQUIRED_STORAGE_OBJECT = "wallet-address: and one of (object-key: | name: [latest:true|at:<timestamp>])";
4205
+ var REQUIRED_LS = "wallet-address: (for one object add object-key: or name: [latest:true|at:<timestamp>]; omit both to list the bucket)";
3796
4206
  var ORCHESTRATOR_MODES = /* @__PURE__ */ new Set(["inline", "subagent"]);
3797
4207
  function expandTilde(path) {
3798
4208
  const trimmed = path.trim();
@@ -3807,63 +4217,66 @@ function expandTilde(path) {
3807
4217
  var CLOUD_HELP_TEXT = [
3808
4218
  "\u2601\uFE0F **mnemospark - Wallet and go.** \u{1F499}",
3809
4219
  "",
4220
+ "**Syntax:** use `/mnemospark cloud \u2026`. Prefer `key:value` for arguments; `key=value` and `--key value` are also accepted. Optional verbose markers: `cloud:true`, `price-storage:true`, etc. Aliases: `wallet:` \u2192 wallet-address, `object:` \u2192 object-id, `quote:` \u2192 quote-id, `hash:` \u2192 object-id-hash.",
4221
+ "",
3810
4222
  "**Cloud Commands**",
3811
4223
  "",
3812
- "\u2022 `/mnemospark_cloud` or `/mnemospark_cloud help` \u2014 show this message",
4224
+ "\u2022 `/mnemospark cloud` or `/mnemospark cloud help` \u2014 show this message (equivalent: `/mnemospark cloud:true help:true`)",
3813
4225
  "",
3814
- "\u2022 `/mnemospark_cloud backup <file|directory> --name <friendly-name> [--async] [--orchestrator <inline|subagent>] [--timeout-seconds <n>]`",
4226
+ "\u2022 `/mnemospark cloud backup <file|directory> name:<friendly-name> [async:true] [orchestrator:<inline|subagent>] [timeout-seconds:<n>]`",
3815
4227
  " Purpose: create a local tar+gzip archive under ~/.openclaw/mnemospark/backup (filename from sanitized friendly name) and record metadata in SQLite for later price-storage and upload.",
3816
4228
  " Required: " + REQUIRED_BACKUP,
3817
4229
  "",
3818
- "\u2022 `/mnemospark_cloud price-storage --wallet-address <addr> --object-id <id> --object-id-hash <hash> --gb <gb> --provider aws --region us-east-1`",
3819
- " Purpose: request a storage quote before upload (defaults shown; override `--provider` / `--region` for other regions).",
4230
+ "\u2022 `/mnemospark cloud price-storage wallet-address:<addr> object-id:<id> object-id-hash:<hash> gb:<gb> provider:aws region:us-east-1`",
4231
+ " Purpose: request a storage quote before upload (defaults shown; override `provider:` / `region:` for other regions).",
3820
4232
  " Required: " + REQUIRED_PRICE_STORAGE,
4233
+ " Shorter: `wallet:\u2026 object:\u2026 hash:\u2026 gb:\u2026 provider:\u2026 region:\u2026`",
3821
4234
  "",
3822
- "\u2022 `/mnemospark_cloud upload --quote-id <quote-id> --wallet-address <addr> --object-id <id> --object-id-hash <hash> [--name <friendly-name>] [--async] [--orchestrator <inline|subagent>] [--timeout-seconds <n>]`",
4235
+ "\u2022 `/mnemospark cloud upload quote-id:<quote-id> wallet-address:<addr> object-id:<id> object-id-hash:<hash> [name:<friendly-name>] [async:true] [orchestrator:<inline|subagent>] [timeout-seconds:<n>]`",
3823
4236
  " Purpose: upload an encrypted object using a valid quote-id.",
3824
4237
  " Required: " + REQUIRED_UPLOAD,
3825
4238
  "",
3826
- "\u2022 `/mnemospark_cloud payment-settle (--quote-id <quote-id> | --renewal --object-key <key>) --wallet-address <addr> [--object-id <id>] [--storage-price <n>]`",
4239
+ "\u2022 `/mnemospark cloud payment-settle (quote-id:<quote-id> | renewal:true object-key:<key>) wallet-address:<addr> [object-id:<id>] [storage-price:<n>]`",
3827
4240
  " Purpose: settle storage payment before upload (quote) or on the monthly cron (renewal, no new quote). Uses the same proxy + x402 path as upload pre-settlement.",
3828
4241
  " Required: " + REQUIRED_PAYMENT_SETTLE + " (wallet private key must match the address).",
3829
4242
  "",
3830
- "\u2022 `/mnemospark_cloud ls --wallet-address <addr> [--object-key <key> | --name <friendly-name> | omit both to list bucket] [--latest|--at <timestamp>]`",
4243
+ "\u2022 `/mnemospark cloud ls wallet-address:<addr> [object-key:<key> | name:<friendly-name> | omit both to list bucket] [latest:true|at:<timestamp>]`",
3831
4244
  " Purpose: stat one object or list all keys in the wallet bucket (S3).",
3832
4245
  " Required: " + REQUIRED_LS,
3833
4246
  "",
3834
- "\u2022 `/mnemospark_cloud download --wallet-address <addr> [--object-key <object-key> | --name <friendly-name>] [--latest|--at <timestamp>] [--async] [--orchestrator <inline|subagent>] [--timeout-seconds <n>]`",
4247
+ "\u2022 `/mnemospark cloud download wallet-address:<addr> [object-key:<object-key> | name:<friendly-name>] [latest:true|at:<timestamp>] [async:true] [orchestrator:<inline|subagent>] [timeout-seconds:<n>]`",
3835
4248
  " Purpose: fetch an object to local disk.",
3836
4249
  " Required: " + REQUIRED_STORAGE_OBJECT,
3837
4250
  "",
3838
- "\u2022 `/mnemospark_cloud delete --wallet-address <addr> [--object-key <object-key> | --name <friendly-name>] [--latest|--at <timestamp>]`",
4251
+ "\u2022 `/mnemospark cloud delete wallet-address:<addr> [object-key:<object-key> | name:<friendly-name>] [latest:true|at:<timestamp>]`",
3839
4252
  " Purpose: remove a remote object and local cron tracking when present.",
3840
4253
  " Required: " + REQUIRED_STORAGE_OBJECT,
3841
4254
  "",
3842
- "\u2022 `/mnemospark_cloud op-status --operation-id <id> [--cancel]`",
4255
+ "\u2022 `/mnemospark cloud op-status operation-id:<id> [cancel:true]`",
3843
4256
  " Purpose: inspect async operation status, or request cancellation for subagent runs.",
3844
- " Required: --operation-id",
4257
+ " Required: operation-id:<id>",
3845
4258
  "",
3846
4259
  "Async orchestration flags (`backup`, `upload`, `download` only):",
3847
- "\u2022 `--async`",
4260
+ "\u2022 `async:true`",
3848
4261
  " Start operation in background and return quickly with operation-id.",
3849
- "\u2022 `--orchestrator <inline|subagent>`",
4262
+ "\u2022 `orchestrator:<inline|subagent>`",
3850
4263
  " Choose async engine. Default when omitted is `inline`.",
3851
4264
  " Use `subagent` for explicit subagent session tracking and cancellation.",
3852
- "\u2022 `--timeout-seconds <n>`",
3853
- " Optional per-operation timeout. Valid only with `--async --orchestrator subagent`.",
4265
+ "\u2022 `timeout-seconds:<n>`",
4266
+ " Optional per-operation timeout. Valid only with `async:true` and `orchestrator:subagent`.",
3854
4267
  " `n` must be a positive integer (seconds).",
3855
- "\u2022 `op-status --cancel`",
4268
+ "\u2022 `op-status` with `cancel:true`",
3856
4269
  " Cancel a subagent-orchestrated operation by operation-id (idempotent).",
3857
4270
  "",
3858
4271
  "Examples:",
3859
- "\u2022 `/mnemospark_cloud upload ... --async --orchestrator subagent`",
3860
- "\u2022 `/mnemospark_cloud download ... --async --orchestrator subagent --timeout-seconds 900`",
3861
- "\u2022 `/mnemospark_cloud op-status --operation-id <id>`",
3862
- "\u2022 `/mnemospark_cloud op-status --operation-id <id> --cancel`",
4272
+ "\u2022 `/mnemospark cloud upload ... async:true orchestrator:subagent`",
4273
+ "\u2022 `/mnemospark cloud download ... async:true orchestrator:subagent timeout-seconds:900`",
4274
+ "\u2022 `/mnemospark cloud op-status operation-id:<id>`",
4275
+ "\u2022 `/mnemospark cloud op-status operation-id:<id> cancel:true`",
3863
4276
  "",
3864
4277
  CLOUD_HELP_FOOTER_STATE,
3865
4278
  "",
3866
- "Backup uses your configured mnemospark wallet key (no `--wallet-address` flag). Commands price-storage, upload, ls, download, delete, and payment-settle require `--wallet-address` on the command line (must match that wallet)."
4279
+ "Backup uses your configured mnemospark wallet key (no `wallet-address:` argument). Commands price-storage, upload, ls, download, delete, and payment-settle require `wallet-address:<addr>` (or `wallet:<addr>`) on the command line (must match that wallet)."
3867
4280
  ].join("\n");
3868
4281
  var UnsupportedBackupPlatformError = class extends Error {
3869
4282
  constructor(platform) {
@@ -3892,37 +4305,6 @@ function tokenizeArgsRaw(input) {
3892
4305
  }
3893
4306
  return tokens;
3894
4307
  }
3895
- function tokenizeArgs(input) {
3896
- return tokenizeArgsRaw(input).map((token) => stripWrappingQuotes(token));
3897
- }
3898
- function parseNamedFlagsTokens(tokens, booleanFlags = /* @__PURE__ */ new Set()) {
3899
- if (tokens.length === 0) {
3900
- return null;
3901
- }
3902
- const parsed = {};
3903
- for (let i = 0; i < tokens.length; i += 1) {
3904
- const keyToken = tokens[i];
3905
- if (!keyToken.startsWith("--")) {
3906
- return null;
3907
- }
3908
- const key = keyToken.slice(2).toLowerCase().replace(/_/g, "-");
3909
- const value = tokens[i + 1];
3910
- if (!value || value.startsWith("--")) {
3911
- if (booleanFlags.has(key)) {
3912
- parsed[key] = "true";
3913
- continue;
3914
- }
3915
- return null;
3916
- }
3917
- parsed[key] = value;
3918
- i += 1;
3919
- }
3920
- return parsed;
3921
- }
3922
- function parseNamedFlags(input, booleanFlags = /* @__PURE__ */ new Set()) {
3923
- const tokens = tokenizeArgs(input);
3924
- return parseNamedFlagsTokens(tokens, booleanFlags);
3925
- }
3926
4308
  function parseObjectSelector(flags) {
3927
4309
  const objectKey = flags["object-key"]?.trim();
3928
4310
  const name = flags.name?.trim();
@@ -4015,10 +4397,18 @@ function parseAsyncOperationArgs(flags) {
4015
4397
  timeoutSeconds: parsedTimeoutSeconds === void 0 ? void 0 : parsedTimeoutSeconds
4016
4398
  };
4017
4399
  }
4018
- var INVALID_ASYNC_FLAGS_MESSAGE = "invalid async flags. `--orchestrator`/`--timeout-seconds` require `--async`, and `--timeout-seconds` is only valid with `--orchestrator subagent`.";
4400
+ var INVALID_ASYNC_FLAGS_MESSAGE = "invalid async flags. `orchestrator:` and `timeout-seconds:` require `async:true`, and `timeout-seconds:` is only valid with `orchestrator:subagent`.";
4019
4401
  function stripAsyncControlFlags(args) {
4020
4402
  const tokens = tokenizeArgsRaw(args ?? "");
4021
4403
  const filtered = [];
4404
+ const isAsyncControlKey = (rawKey) => {
4405
+ const canonical = rawKey.trim().toLowerCase().replace(/_/g, "-");
4406
+ return canonical === "async" || canonical === "orchestrator" || canonical === "timeout-seconds";
4407
+ };
4408
+ const isBareBooleanFlag = (rawToken) => {
4409
+ const canonical = rawToken.trim().toLowerCase().replace(/^--/, "").replace(/_/g, "-");
4410
+ return canonical === "async" || canonical === "latest";
4411
+ };
4022
4412
  for (let idx = 0; idx < tokens.length; idx += 1) {
4023
4413
  const token = tokens[idx];
4024
4414
  const lowerToken = token.toLowerCase();
@@ -4029,35 +4419,71 @@ function stripAsyncControlFlags(args) {
4029
4419
  idx += 1;
4030
4420
  continue;
4031
4421
  }
4422
+ const previousToken = tokens[idx - 1];
4423
+ if (previousToken && previousToken.startsWith("--") && !isBareBooleanFlag(previousToken)) {
4424
+ filtered.push(token);
4425
+ continue;
4426
+ }
4427
+ const unwrapped = stripWrappingQuotes(token);
4428
+ const colonIdx = unwrapped.indexOf(":");
4429
+ const equalsIdx = unwrapped.indexOf("=");
4430
+ const splitIdx = colonIdx > 0 && equalsIdx > 0 ? Math.min(colonIdx, equalsIdx) : Math.max(colonIdx, equalsIdx);
4431
+ if (splitIdx > 0) {
4432
+ const candidateKey = unwrapped.slice(0, splitIdx);
4433
+ if (/^[A-Za-z_][A-Za-z0-9_-]*$/.test(candidateKey) && isAsyncControlKey(candidateKey)) {
4434
+ continue;
4435
+ }
4436
+ }
4032
4437
  filtered.push(token);
4033
4438
  }
4034
4439
  return filtered.join(" ");
4035
4440
  }
4441
+ function mergeArgParseWarnings(a, b) {
4442
+ return [...a, ...b];
4443
+ }
4036
4444
  function parseCloudArgs(args) {
4037
4445
  const trimmed = args?.trim() ?? "";
4038
4446
  if (!trimmed) {
4039
4447
  return { mode: "help" };
4040
4448
  }
4041
- const spaceIdx = trimmed.indexOf(" ");
4042
- const subcommand = (spaceIdx === -1 ? trimmed : trimmed.slice(0, spaceIdx)).toLowerCase();
4043
- const rest = spaceIdx === -1 ? "" : trimmed.slice(spaceIdx + 1);
4449
+ const norm = normalizeInputForParsing(trimmed);
4450
+ const text = norm.text;
4451
+ const normWarnings = norm.warnings;
4452
+ const spaceIdx = text.search(/\s/);
4453
+ const rawFirst = spaceIdx === -1 ? text : text.slice(0, spaceIdx);
4454
+ const rest = spaceIdx === -1 ? "" : text.slice(spaceIdx + 1).trim();
4455
+ const subParsed = parseVerboseToken(rawFirst);
4456
+ if (!subParsed.ok) {
4457
+ return {
4458
+ mode: "arg-parse-failure",
4459
+ errors: [`Invalid subcommand token "${rawFirst}". Use name:true only with value true.`],
4460
+ warnings: normWarnings
4461
+ };
4462
+ }
4463
+ const subcommand = subParsed.name;
4044
4464
  if (subcommand === "help") {
4045
4465
  return { mode: "help" };
4046
4466
  }
4047
4467
  if (subcommand === "backup") {
4048
- const tokens = tokenizeArgs(rest);
4468
+ const tokens = tokenizeArgsRaw(rest);
4049
4469
  if (tokens.length === 0) {
4050
4470
  return { mode: "unknown" };
4051
4471
  }
4052
- const backupTarget = tokens[0] ?? "";
4472
+ const backupTarget = stripWrappingQuotes(tokens[0] ?? "");
4053
4473
  if (!backupTarget) {
4054
4474
  return { mode: "unknown" };
4055
4475
  }
4056
4476
  const remainingTokens = tokens.slice(1);
4057
- const flags = remainingTokens.length === 0 ? {} : parseNamedFlagsTokens(remainingTokens, BOOLEAN_ASYNC_FLAGS);
4058
- if (!flags) {
4059
- return { mode: "backup-invalid" };
4477
+ const flagsPart = remainingTokens.join(" ");
4478
+ const parsed = parseCommandArgs(flagsPart, backupFlagsSchema);
4479
+ if (!parsed.ok) {
4480
+ return {
4481
+ mode: "arg-parse-failure",
4482
+ errors: parsed.errors,
4483
+ warnings: mergeArgParseWarnings(normWarnings, parsed.warnings)
4484
+ };
4060
4485
  }
4486
+ const flags = valuesToStringRecord(parsed.values);
4061
4487
  const asyncArgs = parseAsyncOperationArgs(flags);
4062
4488
  if (!asyncArgs) {
4063
4489
  return { mode: "backup-invalid-async" };
@@ -4074,10 +4500,15 @@ function parseCloudArgs(args) {
4074
4500
  };
4075
4501
  }
4076
4502
  if (subcommand === "price-storage") {
4077
- const flags = parseNamedFlags(rest);
4078
- if (!flags) {
4079
- return { mode: "price-storage-invalid" };
4503
+ const parsed = parseCommandArgs(rest, priceStorageSchema);
4504
+ if (!parsed.ok) {
4505
+ return {
4506
+ mode: "arg-parse-failure",
4507
+ errors: parsed.errors,
4508
+ warnings: mergeArgParseWarnings(normWarnings, parsed.warnings)
4509
+ };
4080
4510
  }
4511
+ const flags = valuesToStringRecord(parsed.values);
4081
4512
  const gb = Number.parseFloat(flags.gb ?? "");
4082
4513
  const request = parsePriceStorageQuoteRequest({
4083
4514
  wallet_address: flags["wallet-address"],
@@ -4093,10 +4524,15 @@ function parseCloudArgs(args) {
4093
4524
  return { mode: "price-storage", priceStorageRequest: request };
4094
4525
  }
4095
4526
  if (subcommand === "upload") {
4096
- const flags = parseNamedFlags(rest, BOOLEAN_ASYNC_FLAGS);
4097
- if (!flags) {
4098
- return { mode: "upload-invalid" };
4527
+ const parsed = parseCommandArgs(rest, uploadSchema);
4528
+ if (!parsed.ok) {
4529
+ return {
4530
+ mode: "arg-parse-failure",
4531
+ errors: parsed.errors,
4532
+ warnings: mergeArgParseWarnings(normWarnings, parsed.warnings)
4533
+ };
4099
4534
  }
4535
+ const flags = valuesToStringRecord(parsed.values);
4100
4536
  const asyncArgs = parseAsyncOperationArgs(flags);
4101
4537
  if (!asyncArgs) {
4102
4538
  return { mode: "upload-invalid-async" };
@@ -4121,15 +4557,15 @@ function parseCloudArgs(args) {
4121
4557
  };
4122
4558
  }
4123
4559
  if (subcommand === "payment-settle") {
4124
- const flags = parseNamedFlags(rest, PAYMENT_SETTLE_BOOLEAN_FLAGS);
4125
- if (!flags) {
4126
- return { mode: "payment-settle-invalid" };
4127
- }
4128
- for (const key of Object.keys(flags)) {
4129
- if (!PAYMENT_SETTLE_FLAG_NAMES.has(key)) {
4130
- return { mode: "payment-settle-invalid" };
4131
- }
4560
+ const parsed = parseCommandArgs(rest, paymentSettleSchema);
4561
+ if (!parsed.ok) {
4562
+ return {
4563
+ mode: "arg-parse-failure",
4564
+ errors: parsed.errors,
4565
+ warnings: mergeArgParseWarnings(normWarnings, parsed.warnings)
4566
+ };
4132
4567
  }
4568
+ const flags = valuesToStringRecord(parsed.values);
4133
4569
  const walletAddress = flags["wallet-address"]?.trim();
4134
4570
  if (!walletAddress) {
4135
4571
  return { mode: "payment-settle-invalid" };
@@ -4169,11 +4605,16 @@ function parseCloudArgs(args) {
4169
4605
  };
4170
4606
  }
4171
4607
  if (subcommand === "ls") {
4172
- const flags = parseNamedFlags(rest, BOOLEAN_SELECTOR_FLAGS);
4173
- if (!flags) {
4174
- return { mode: "ls-invalid" };
4608
+ const parsed = parseCommandArgs(rest, lsSchema);
4609
+ if (!parsed.ok) {
4610
+ return {
4611
+ mode: "arg-parse-failure",
4612
+ errors: parsed.errors,
4613
+ warnings: mergeArgParseWarnings(normWarnings, parsed.warnings)
4614
+ };
4175
4615
  }
4176
- const walletAddress = flags["wallet-address"]?.trim() ?? flags["wallet_address"]?.trim() ?? "";
4616
+ const flags = valuesToStringRecord(parsed.values);
4617
+ const walletAddress = flags["wallet-address"]?.trim() ?? "";
4177
4618
  if (!walletAddress) {
4178
4619
  return { mode: "ls-invalid" };
4179
4620
  }
@@ -4205,10 +4646,15 @@ function parseCloudArgs(args) {
4205
4646
  };
4206
4647
  }
4207
4648
  if (subcommand === "download") {
4208
- const flags = parseNamedFlags(rest, BOOLEAN_SELECTOR_AND_ASYNC_FLAGS);
4209
- if (!flags) {
4210
- return { mode: "download-invalid" };
4649
+ const parsed = parseCommandArgs(rest, downloadSchema);
4650
+ if (!parsed.ok) {
4651
+ return {
4652
+ mode: "arg-parse-failure",
4653
+ errors: parsed.errors,
4654
+ warnings: mergeArgParseWarnings(normWarnings, parsed.warnings)
4655
+ };
4211
4656
  }
4657
+ const flags = valuesToStringRecord(parsed.values);
4212
4658
  const asyncArgs = parseAsyncOperationArgs(flags);
4213
4659
  if (!asyncArgs) {
4214
4660
  return { mode: "download-invalid-async" };
@@ -4229,10 +4675,15 @@ function parseCloudArgs(args) {
4229
4675
  };
4230
4676
  }
4231
4677
  if (subcommand === "delete") {
4232
- const flags = parseNamedFlags(rest, BOOLEAN_SELECTOR_FLAGS);
4233
- if (!flags) {
4234
- return { mode: "delete-invalid" };
4678
+ const parsed = parseCommandArgs(rest, deleteSchema);
4679
+ if (!parsed.ok) {
4680
+ return {
4681
+ mode: "arg-parse-failure",
4682
+ errors: parsed.errors,
4683
+ warnings: mergeArgParseWarnings(normWarnings, parsed.warnings)
4684
+ };
4235
4685
  }
4686
+ const flags = valuesToStringRecord(parsed.values);
4236
4687
  const selector = parseObjectSelector(flags);
4237
4688
  if (!selector) {
4238
4689
  return { mode: "delete-invalid" };
@@ -4244,12 +4695,20 @@ function parseCloudArgs(args) {
4244
4695
  return { mode: "delete", storageObjectRequest: request, nameSelector: selector.nameSelector };
4245
4696
  }
4246
4697
  if (subcommand === "op-status") {
4247
- const flags = parseNamedFlags(rest, BOOLEAN_OP_STATUS_FLAGS);
4248
- const operationId = flags?.["operation-id"]?.trim();
4698
+ const parsed = parseCommandArgs(rest, opStatusSchema);
4699
+ if (!parsed.ok) {
4700
+ return {
4701
+ mode: "arg-parse-failure",
4702
+ errors: parsed.errors,
4703
+ warnings: mergeArgParseWarnings(normWarnings, parsed.warnings)
4704
+ };
4705
+ }
4706
+ const flags = valuesToStringRecord(parsed.values);
4707
+ const operationId = flags["operation-id"]?.trim();
4249
4708
  if (!operationId) {
4250
4709
  return { mode: "op-status-invalid" };
4251
4710
  }
4252
- return { mode: "op-status", operationId, cancel: flags?.cancel === "true" };
4711
+ return { mode: "op-status", operationId, cancel: flags.cancel === "true" };
4253
4712
  }
4254
4713
  return { mode: "unknown" };
4255
4714
  }
@@ -4334,7 +4793,7 @@ async function resolveLocalUploadArchivePath(backupDir, objectId, friendlyName)
4334
4793
  } catch {
4335
4794
  return {
4336
4795
  ok: false,
4337
- message: `Cannot upload storage object: local archive not found. Run /mnemospark_cloud backup with --name (canonical layout) or restore the legacy file at ${legacyPath}.`
4796
+ message: `Cannot upload storage object: local archive not found. Run /mnemospark cloud backup with name:<friendly-name> (canonical layout) or restore the legacy file at ${legacyPath}.`
4338
4797
  };
4339
4798
  }
4340
4799
  }
@@ -4555,7 +5014,7 @@ function buildStoragePaymentRenewalArgs(job) {
4555
5014
  ].join(" ");
4556
5015
  }
4557
5016
  function buildStoragePaymentCronCommand(job) {
4558
- return `/mnemospark_cloud ${buildStoragePaymentRenewalArgs(job)}`;
5017
+ return `/mnemospark cloud ${buildStoragePaymentRenewalArgs(job)}`;
4559
5018
  }
4560
5019
  function buildOpenClawRenewalAgentMessage(openClawHome, renewalArgs) {
4561
5020
  const cliPath = join8(openClawHome, ".openclaw/extensions/mnemospark/dist/cli.js");
@@ -4895,7 +5354,7 @@ async function maybeCleanupLocalBackupArchive(archivePath) {
4895
5354
  }
4896
5355
  }
4897
5356
  function formatStorageUploadUserMessage(upload, cronJobId) {
4898
- const lsLine = `/mnemospark_cloud ls --wallet-address \`${upload.addr}\``;
5357
+ const lsLine = `/mnemospark cloud ls wallet-address:\`${upload.addr}\``;
4899
5358
  return [
4900
5359
  `Your file \`${upload.object_id}\` with key \`${upload.object_key}\` has been stored using \`${upload.provider}\` in folder \`${upload.bucket_name}\` in region \`${upload.location}\``,
4901
5360
  "",
@@ -4953,7 +5412,7 @@ function extractLsErrorMessage(error) {
4953
5412
  return null;
4954
5413
  }
4955
5414
  function formatPriceStorageUserMessage(quote, localArchiveHint) {
4956
- const uploadLine = `/mnemospark_cloud upload --quote-id \`${quote.quote_id}\` --wallet-address \`${quote.addr}\` --object-id \`${quote.object_id}\` --object-id-hash \`${quote.object_id_hash}\``;
5415
+ const uploadLine = `/mnemospark cloud upload quote-id:\`${quote.quote_id}\` wallet-address:\`${quote.addr}\` object-id:\`${quote.object_id}\` object-id-hash:\`${quote.object_id_hash}\``;
4957
5416
  const lines = [
4958
5417
  `Your storage quote \`${quote.quote_id}\`: storage price \`$${quote.storage_price}\` for file \`${quote.object_id}\` with file size \`${quote.object_size_gb}\` in \`${quote.provider}\` \`${quote.location}\`.`,
4959
5418
  "",
@@ -4978,7 +5437,7 @@ var DEFAULT_BACKUP_QUOTE_PROVIDER = "aws";
4978
5437
  var DEFAULT_BACKUP_QUOTE_REGION = "us-east-1";
4979
5438
  function formatBackupSuccessUserMessage(result, walletAddress, friendlyName) {
4980
5439
  const hash = result.objectIdHash.replace(/\s/g, "");
4981
- const priceStorageLine = `/mnemospark_cloud price-storage --wallet-address \`${walletAddress}\` --object-id \`${result.objectId}\` --object-id-hash \`${hash}\` --gb \`${result.objectSizeGb}\` --provider ${DEFAULT_BACKUP_QUOTE_PROVIDER} --region ${DEFAULT_BACKUP_QUOTE_REGION}`;
5440
+ const priceStorageLine = `/mnemospark cloud price-storage wallet-address:\`${walletAddress}\` object-id:\`${result.objectId}\` object-id-hash:\`${hash}\` gb:\`${result.objectSizeGb}\` provider:${DEFAULT_BACKUP_QUOTE_PROVIDER} region:${DEFAULT_BACKUP_QUOTE_REGION}`;
4982
5441
  return [
4983
5442
  `Backup archive: \`${result.archivePath}\``,
4984
5443
  "",
@@ -4994,10 +5453,10 @@ function formatBackupSuccessUserMessage(result, walletAddress, friendlyName) {
4994
5453
  `The default region is ${DEFAULT_BACKUP_QUOTE_REGION}. Change the command parameters to switch regions (not required).`,
4995
5454
  "",
4996
5455
  "Region examples (merge into the command above):",
4997
- "North America: `--provider aws --region us-east-1`",
4998
- "Europe: `--provider aws --region eu-north-1`",
4999
- "South America: `--provider aws --region sa-east-1`",
5000
- "Asia Pacific: `--provider aws --region ap-northeast-1`"
5456
+ "North America: `provider:aws region:us-east-1`",
5457
+ "Europe: `provider:aws region:eu-north-1`",
5458
+ "South America: `provider:aws region:sa-east-1`",
5459
+ "Asia Pacific: `provider:aws region:ap-northeast-1`"
5001
5460
  ].join("\n");
5002
5461
  }
5003
5462
  function createInProcessSubagentOrchestrator() {
@@ -5101,9 +5560,9 @@ function createInProcessSubagentOrchestrator() {
5101
5560
  function createCloudCommand(options = {}) {
5102
5561
  const subagentOrchestrator = options.subagentOrchestrator ?? createInProcessSubagentOrchestrator();
5103
5562
  return {
5104
- name: "mnemospark_cloud",
5563
+ name: "mnemospark",
5105
5564
  nativeNames: {
5106
- default: "mnemospark_cloud"
5565
+ default: "mnemospark"
5107
5566
  },
5108
5567
  description: "Manage mnemospark cloud storage workflow commands",
5109
5568
  acceptsArgs: true,
@@ -5431,15 +5890,24 @@ async function runCloudCommandHandler(ctx, options, executionContext = {}) {
5431
5890
  isError: parsed.mode === "unknown"
5432
5891
  };
5433
5892
  }
5434
- if (parsed.mode === "price-storage-invalid") {
5893
+ if (parsed.mode === "arg-parse-failure") {
5435
5894
  return {
5436
- text: `Cannot price storage: required arguments are ${REQUIRED_PRICE_STORAGE}.`,
5895
+ text: [
5896
+ "Could not parse command arguments.",
5897
+ ...parsed.errors.map((e) => `- ${e}`),
5898
+ ...parsed.warnings.length > 0 ? ["", "Notes:", ...parsed.warnings.map((w) => `- ${w}`)] : [],
5899
+ "",
5900
+ "Accepted formats:",
5901
+ "- key:value",
5902
+ "- key=value",
5903
+ "- --key value"
5904
+ ].join("\n"),
5437
5905
  isError: true
5438
5906
  };
5439
5907
  }
5440
- if (parsed.mode === "backup-invalid") {
5908
+ if (parsed.mode === "price-storage-invalid") {
5441
5909
  return {
5442
- text: "Cannot build storage object",
5910
+ text: `Cannot price storage: required arguments are ${REQUIRED_PRICE_STORAGE}.`,
5443
5911
  isError: true
5444
5912
  };
5445
5913
  }
@@ -5469,7 +5937,7 @@ async function runCloudCommandHandler(ctx, options, executionContext = {}) {
5469
5937
  }
5470
5938
  if (parsed.mode === "payment-settle-invalid") {
5471
5939
  return {
5472
- text: `Cannot settle payment: required arguments are ${REQUIRED_PAYMENT_SETTLE}. Optional: --object-id, --storage-price.`,
5940
+ text: `Cannot settle payment: required arguments are ${REQUIRED_PAYMENT_SETTLE}. Optional: object-id:, storage-price:.`,
5473
5941
  isError: true
5474
5942
  };
5475
5943
  }
@@ -5499,7 +5967,7 @@ async function runCloudCommandHandler(ctx, options, executionContext = {}) {
5499
5967
  }
5500
5968
  if (parsed.mode === "op-status-invalid") {
5501
5969
  return {
5502
- text: "Cannot get operation status: required arguments are --operation-id.",
5970
+ text: "Cannot get operation status: required arguments are operation-id:<id>.",
5503
5971
  isError: true
5504
5972
  };
5505
5973
  }
@@ -5635,7 +6103,7 @@ ${operation.result_text}` : meta;
5635
6103
  const walletAccount = privateKeyToAccount5(walletKey);
5636
6104
  if (walletAccount.address.toLowerCase() !== req.wallet_address.toLowerCase()) {
5637
6105
  return {
5638
- text: `Cannot settle payment: wallet key address ${walletAccount.address} does not match --wallet-address ${req.wallet_address}.`,
6106
+ text: `Cannot settle payment: wallet key address ${walletAccount.address} does not match wallet-address: ${req.wallet_address}.`,
5639
6107
  isError: true
5640
6108
  };
5641
6109
  }
@@ -5729,7 +6197,7 @@ ${operation.result_text}` : meta;
5729
6197
  });
5730
6198
  const label = req.renewal ? `object ${req.object_key}` : `quote ${req.quote_id}`;
5731
6199
  return {
5732
- text: transId ? `Payment settled for ${label} (trans_id: ${transId}).` : `Payment settled for ${label}.`
6200
+ text: transId ? `Payment settled for ${label} (trans-id: ${transId}).` : `Payment settled for ${label}.`
5733
6201
  };
5734
6202
  }
5735
6203
  await datastore.upsertPayment({
@@ -5808,7 +6276,7 @@ ${operation.result_text}` : meta;
5808
6276
  args: syncArgs,
5809
6277
  timeoutSeconds: parsed.timeoutSeconds,
5810
6278
  requestedBy: {
5811
- pluginCommand: "mnemospark_cloud",
6279
+ pluginCommand: "mnemospark",
5812
6280
  chatId: ctx.channel,
5813
6281
  senderId: ctx.senderId
5814
6282
  }
@@ -5991,7 +6459,7 @@ ${operation.result_text}` : meta;
5991
6459
  `orchestrator: subagent`,
5992
6460
  `subagent-session-id: ${dispatchResult.sessionId}`,
5993
6461
  timeoutSeconds ? `timeout-seconds: ${timeoutSeconds}` : null,
5994
- `Use /mnemospark_cloud op-status --operation-id ${operationId}`
6462
+ `Use /mnemospark cloud op-status operation-id:${operationId}`
5995
6463
  ].filter((line) => Boolean(line)).join("\n")
5996
6464
  };
5997
6465
  } catch (dispatchError) {
@@ -6094,7 +6562,7 @@ operation-id: ${operationId}`,
6094
6562
  text: [
6095
6563
  `Operation started in background. operation-id: ${operationId}`,
6096
6564
  `orchestrator: inline`,
6097
- `Use /mnemospark_cloud op-status --operation-id ${operationId}`
6565
+ `Use /mnemospark cloud op-status operation-id:${operationId}`
6098
6566
  ].join("\n")
6099
6567
  };
6100
6568
  }
@@ -6264,7 +6732,7 @@ operation-id: ${operationId}`,
6264
6732
  const loggedQuote = await datastore.findQuoteById(parsed.uploadRequest.quote_id);
6265
6733
  if (!loggedQuote) {
6266
6734
  return {
6267
- text: "Cannot upload storage object: quote-id not found in local SQLite. Run /mnemospark_cloud price-storage first (quotes expire after about one hour on the server).",
6735
+ text: "Cannot upload storage object: quote-id not found in local SQLite. Run /mnemospark cloud price-storage first (quotes expire after about one hour on the server).",
6268
6736
  isError: true
6269
6737
  };
6270
6738
  }
@@ -6280,7 +6748,7 @@ operation-id: ${operationId}`,
6280
6748
  );
6281
6749
  if (!dbFriendly?.trim()) {
6282
6750
  return {
6283
- text: "Cannot upload storage object: no friendly name in local SQLite for this object-id. Run /mnemospark_cloud backup with --name first.",
6751
+ text: "Cannot upload storage object: no friendly name in local SQLite for this object-id. Run /mnemospark cloud backup with --name first.",
6284
6752
  isError: true
6285
6753
  };
6286
6754
  }
@@ -6306,7 +6774,7 @@ operation-id: ${operationId}`,
6306
6774
  archiveStats = await stat2(archivePath);
6307
6775
  } catch {
6308
6776
  return {
6309
- text: `Cannot upload storage object: local archive not found at ${archivePath}. Run /mnemospark_cloud backup first.`,
6777
+ text: `Cannot upload storage object: local archive not found at ${archivePath}. Run /mnemospark cloud backup first.`,
6310
6778
  isError: true
6311
6779
  };
6312
6780
  }
@@ -6327,7 +6795,7 @@ operation-id: ${operationId}`,
6327
6795
  const walletAccount = privateKeyToAccount5(walletKey);
6328
6796
  if (walletAccount.address.toLowerCase() !== parsed.uploadRequest.wallet_address.toLowerCase()) {
6329
6797
  return {
6330
- text: `Cannot upload storage object: wallet key address ${walletAccount.address} does not match --wallet-address ${parsed.uploadRequest.wallet_address}.`,
6798
+ text: `Cannot upload storage object: wallet key address ${walletAccount.address} does not match wallet-address: ${parsed.uploadRequest.wallet_address}.`,
6331
6799
  isError: true
6332
6800
  };
6333
6801
  }
@@ -6833,12 +7301,192 @@ operation-id: ${operationId}`,
6833
7301
  };
6834
7302
  }
6835
7303
 
7304
+ // src/mnemospark-handler.ts
7305
+ var MNEMOSPARK_ROOT_HELP_TEXT = [
7306
+ "\u2601\uFE0F **mnemospark - Wallet and go.** \u{1F499}",
7307
+ "",
7308
+ "**Syntax:** `/mnemospark cloud \u2026` or `/mnemospark wallet \u2026`",
7309
+ "Arguments may use `key:value`, `key=value`, or `--key value`. Optional verbose markers: `cloud:true`, `price-storage:true`, etc. (same as bare words).",
7310
+ "Aliases include `wallet:` \u2192 wallet-address, `object:` \u2192 object-id, `quote:` \u2192 quote-id (see `/mnemospark cloud help`).",
7311
+ "",
7312
+ "**Cloud storage** \u2014 full reference:",
7313
+ "\u2022 `/mnemospark cloud help`",
7314
+ "",
7315
+ "**Wallet** \u2014 status:",
7316
+ "\u2022 `/mnemospark wallet`",
7317
+ "\u2022 `/mnemospark wallet help` \u2014 commands and funding link"
7318
+ ].join("\n");
7319
+ var MNEMOSPARK_WALLET_HELP_TEXT = (address) => [
7320
+ "\u2601\uFE0F **mnemospark Wallet**",
7321
+ "",
7322
+ "**Commands:**",
7323
+ "\u2022 `/mnemospark wallet` \u2014 Show address, balance, and key file path",
7324
+ "\u2022 `/mnemospark wallet help` \u2014 This message",
7325
+ "\u2022 `/mnemospark wallet export` \u2014 Export private key for backup (sensitive)",
7326
+ "",
7327
+ `**Fund with USDC on Base:** https://basescan.org/address/${address}`
7328
+ ].join("\n");
7329
+ var defaultCloudCommandHandler;
7330
+ function getDefaultCloudCommandHandler() {
7331
+ defaultCloudCommandHandler ??= createCloudCommand().handler;
7332
+ return defaultCloudCommandHandler;
7333
+ }
7334
+ var NO_WALLET_FOUND_TEXT = "No mnemospark wallet found. Run `openclaw plugins install mnemospark`.";
7335
+ function resolveWalletFileSync() {
7336
+ try {
7337
+ if (!existsSync(WALLET_FILE)) {
7338
+ return null;
7339
+ }
7340
+ const walletKey = readFileSync(WALLET_FILE, "utf-8").trim();
7341
+ if (!walletKey.startsWith("0x") || walletKey.length !== 66) {
7342
+ return null;
7343
+ }
7344
+ const account = privateKeyToAccount6(walletKey);
7345
+ const address = account.address.replace(/\s/g, "");
7346
+ if (!address) {
7347
+ return null;
7348
+ }
7349
+ return { walletKey, address };
7350
+ } catch {
7351
+ return null;
7352
+ }
7353
+ }
7354
+ async function runMnemosparkSlashHandler(ctx, options) {
7355
+ const route = routeMnemosparkArgs(ctx.args);
7356
+ if (route.kind === "root-help") {
7357
+ return { text: MNEMOSPARK_ROOT_HELP_TEXT };
7358
+ }
7359
+ if (route.kind === "error") {
7360
+ return { text: route.message, isError: true };
7361
+ }
7362
+ if (route.kind === "cloud") {
7363
+ const cloudCommandHandler = options?.cloudCommandHandler ?? getDefaultCloudCommandHandler();
7364
+ return cloudCommandHandler({ ...ctx, args: route.rest });
7365
+ }
7366
+ return handleWalletSlash(route.rest);
7367
+ }
7368
+ async function handleWalletSlash(rest) {
7369
+ const trimmed = rest.trim();
7370
+ if (!trimmed) {
7371
+ return buildWalletStatusResponse();
7372
+ }
7373
+ const { first, rest: afterFirst } = firstTokenAndRest(trimmed);
7374
+ const parsed = parseVerboseToken(first);
7375
+ if (!parsed.ok) {
7376
+ return {
7377
+ text: `Invalid token "${first}". Use name:true only with value true.`,
7378
+ isError: true
7379
+ };
7380
+ }
7381
+ if (parsed.name === "help") {
7382
+ if (afterFirst.trim()) {
7383
+ return {
7384
+ text: "Unexpected extra arguments after `help`. Use `/mnemospark wallet help` alone.",
7385
+ isError: true
7386
+ };
7387
+ }
7388
+ return buildWalletHelpResponse();
7389
+ }
7390
+ if (parsed.name === "export") {
7391
+ if (afterFirst.trim()) {
7392
+ return {
7393
+ text: "Unexpected extra arguments after `export`. Use `/mnemospark wallet export` alone.",
7394
+ isError: true
7395
+ };
7396
+ }
7397
+ return buildWalletExportResponse();
7398
+ }
7399
+ if (parsed.name === "status") {
7400
+ return buildWalletStatusResponse();
7401
+ }
7402
+ return {
7403
+ text: `Unknown wallet command "${parsed.name}". Try \`/mnemospark wallet help\`.`,
7404
+ isError: true
7405
+ };
7406
+ }
7407
+ async function buildWalletStatusResponse() {
7408
+ const wallet = resolveWalletFileSync();
7409
+ if (!wallet) {
7410
+ return {
7411
+ text: NO_WALLET_FOUND_TEXT,
7412
+ isError: true
7413
+ };
7414
+ }
7415
+ const { address } = wallet;
7416
+ let balanceText = "Balance: (checking...)";
7417
+ try {
7418
+ const monitor = new BalanceMonitor(address);
7419
+ const balance = await monitor.checkBalance();
7420
+ balanceText = `Balance: ${balance.balanceUSD}`;
7421
+ } catch {
7422
+ balanceText = "Balance: (could not check)";
7423
+ }
7424
+ return {
7425
+ text: [
7426
+ "\u2601\uFE0F **mnemospark Wallet**",
7427
+ "",
7428
+ `**Address:** \`${address}\``,
7429
+ `**${balanceText}**`,
7430
+ `**Key File:** \`${WALLET_FILE}\``,
7431
+ "",
7432
+ "**Commands:**",
7433
+ "\u2022 `/mnemospark wallet` \u2014 Show this status",
7434
+ "\u2022 `/mnemospark wallet help` \u2014 Commands and funding link",
7435
+ "\u2022 `/mnemospark wallet export` \u2014 Export private key for backup",
7436
+ "",
7437
+ `**Fund with USDC on Base:** https://basescan.org/address/${address}`
7438
+ ].join("\n")
7439
+ };
7440
+ }
7441
+ async function buildWalletHelpResponse() {
7442
+ const wallet = resolveWalletFileSync();
7443
+ if (!wallet) {
7444
+ return {
7445
+ text: NO_WALLET_FOUND_TEXT,
7446
+ isError: true
7447
+ };
7448
+ }
7449
+ const { address } = wallet;
7450
+ return { text: MNEMOSPARK_WALLET_HELP_TEXT(address) };
7451
+ }
7452
+ async function buildWalletExportResponse() {
7453
+ const wallet = resolveWalletFileSync();
7454
+ if (!wallet) {
7455
+ return {
7456
+ text: NO_WALLET_FOUND_TEXT,
7457
+ isError: true
7458
+ };
7459
+ }
7460
+ const { walletKey, address } = wallet;
7461
+ const addressDisplay = address.replace(/\s/g, "");
7462
+ const keyDisplay = walletKey.replace(/\s/g, "");
7463
+ return {
7464
+ text: [
7465
+ "\u2601\uFE0F **mnemospark Wallet Export**",
7466
+ "",
7467
+ "\u26A0\uFE0F **SECURITY WARNING**: Your private key controls your wallet funds.",
7468
+ "Never share this key. Anyone with this key can spend your USDC.",
7469
+ "",
7470
+ `**Address:** \`${addressDisplay}\``,
7471
+ "",
7472
+ "**Private Key:**",
7473
+ `\`${keyDisplay}\``,
7474
+ "",
7475
+ "**To restore on a new machine:**",
7476
+ "1. Set the environment variable before running OpenClaw:",
7477
+ ` \`export MNEMOSPARK_WALLET_KEY=${keyDisplay}\``,
7478
+ "2. Or save to file:",
7479
+ ` \`mkdir -p ~/.openclaw/mnemospark/wallet && echo "${keyDisplay}" > ~/.openclaw/mnemospark/wallet/wallet.key && chmod 600 ~/.openclaw/mnemospark/wallet/wallet.key\``
7480
+ ].join("\n")
7481
+ };
7482
+ }
7483
+
6836
7484
  // src/cli.ts
6837
7485
  import { spawn as spawn2 } from "child_process";
6838
7486
  import { dirname as dirname6, join as join9 } from "path";
6839
7487
  import { fileURLToPath as fileURLToPath2 } from "url";
6840
7488
  import { mkdir as mkdir6, readFile as readFile4, writeFile as writeFile4 } from "fs/promises";
6841
- import { existsSync } from "fs";
7489
+ import { existsSync as existsSync2 } from "fs";
6842
7490
  import { homedir as homedir7 } from "os";
6843
7491
  function isHexPrivateKey(value) {
6844
7492
  return typeof value === "string" && /^0x[0-9a-fA-F]{64}$/.test(value.trim());
@@ -6900,6 +7548,7 @@ function parseArgs(args) {
6900
7548
  command: void 0,
6901
7549
  installMode: void 0,
6902
7550
  cloudArgs: void 0,
7551
+ walletArgs: void 0,
6903
7552
  proxySubcommand: void 0
6904
7553
  };
6905
7554
  for (let i = 0; i < args.length; i++) {
@@ -6913,6 +7562,8 @@ function parseArgs(args) {
6913
7562
  result.command = "check-update";
6914
7563
  } else if (arg === "wallet") {
6915
7564
  result.command = "wallet";
7565
+ result.walletArgs = args.slice(i + 1).join(" ");
7566
+ return result;
6916
7567
  } else if (arg === "cloud") {
6917
7568
  result.command = "cloud";
6918
7569
  result.cloudArgs = args.slice(i + 1).join(" ");
@@ -6951,11 +7602,11 @@ async function ensureDir(path) {
6951
7602
  }
6952
7603
  async function deployExtensionFiles() {
6953
7604
  const scriptsSource = join9(PACKAGE_ROOT, "scripts");
6954
- if (!existsSync(scriptsSource)) return;
7605
+ if (!existsSync2(scriptsSource)) return;
6955
7606
  const mnemoScriptsDir = join9(homedir7(), ".openclaw", "mnemospark", "scripts");
6956
7607
  await ensureDir(mnemoScriptsDir);
6957
7608
  const uninstallSrc = join9(scriptsSource, "uninstall.sh");
6958
- if (existsSync(uninstallSrc)) {
7609
+ if (existsSync2(uninstallSrc)) {
6959
7610
  const content = await readFile4(uninstallSrc);
6960
7611
  await writeFile4(join9(mnemoScriptsDir, "uninstall.sh"), content, { mode: 493 });
6961
7612
  }
@@ -7159,28 +7810,15 @@ async function runInstall(mode) {
7159
7810
  );
7160
7811
  await promptOrRunOpenClawPluginInstall();
7161
7812
  }
7162
- async function runWallet() {
7163
- const { address, source } = await resolveOrGenerateWalletKey();
7164
- console.log(`[mnemospark] Wallet address: ${address}`);
7165
- console.log(`[mnemospark] Key file: ${WALLET_FILE}`);
7166
- if (source === "generated") {
7167
- console.log("[mnemospark] New wallet generated and saved.");
7168
- } else if (source === "saved") {
7169
- console.log("[mnemospark] Loaded saved wallet.");
7170
- } else {
7171
- console.log("[mnemospark] Using wallet from MNEMOSPARK_WALLET_KEY.");
7172
- }
7173
- }
7174
- async function runCloud(cloudArgs) {
7175
- const cloudCmd = createCloudCommand();
7813
+ async function runMnemosparkCli(argsLine) {
7176
7814
  const ctx = {
7177
7815
  channel: "cli",
7178
7816
  isAuthorizedSender: true,
7179
- args: cloudArgs,
7180
- commandBody: `cloud ${cloudArgs}`,
7817
+ args: argsLine.trim(),
7818
+ commandBody: argsLine.trim(),
7181
7819
  config: {}
7182
7820
  };
7183
- const result = await cloudCmd.handler(ctx);
7821
+ const result = await runMnemosparkSlashHandler(ctx);
7184
7822
  if (result.text) {
7185
7823
  console.log(result.text);
7186
7824
  }
@@ -7189,7 +7827,12 @@ async function runCloud(cloudArgs) {
7189
7827
  }
7190
7828
  }
7191
7829
  async function main() {
7192
- const args = parseArgs(process.argv.slice(2));
7830
+ const argv = process.argv.slice(2);
7831
+ if (argv.length === 1 && argv[0] === "help") {
7832
+ await runMnemosparkCli("help");
7833
+ return;
7834
+ }
7835
+ const args = parseArgs(argv);
7193
7836
  if (args.version) {
7194
7837
  console.log(VERSION);
7195
7838
  process.exit(0);
@@ -7212,11 +7855,13 @@ async function main() {
7212
7855
  return;
7213
7856
  }
7214
7857
  if (args.command === "wallet") {
7215
- await runWallet();
7858
+ const line = `wallet ${args.walletArgs ?? ""}`.trim();
7859
+ await runMnemosparkCli(line);
7216
7860
  return;
7217
7861
  }
7218
7862
  if (args.command === "cloud") {
7219
- await runCloud(args.cloudArgs ?? "");
7863
+ const line = `cloud ${args.cloudArgs ?? ""}`.trim();
7864
+ await runMnemosparkCli(line);
7220
7865
  return;
7221
7866
  }
7222
7867
  if (args.command === "proxy") {