mnemospark 0.9.2 → 1.0.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.js CHANGED
@@ -1960,7 +1960,7 @@ async function startProxy(options) {
1960
1960
  emitProxyTerminalFromStatus(correlation, 400, { reason: "invalid_json" });
1961
1961
  sendJson(res, 400, {
1962
1962
  error: "Bad request",
1963
- message: "Invalid JSON body for /mnemospark_cloud price-storage"
1963
+ message: "Invalid JSON body for /mnemospark cloud price-storage"
1964
1964
  });
1965
1965
  return;
1966
1966
  }
@@ -2028,7 +2028,7 @@ async function startProxy(options) {
2028
2028
  });
2029
2029
  sendJson(res, 502, {
2030
2030
  error: "proxy_error",
2031
- message: `Failed to forward /mnemospark_cloud price-storage: ${err instanceof Error ? err.message : String(err)}`
2031
+ message: `Failed to forward /mnemospark cloud price-storage: ${err instanceof Error ? err.message : String(err)}`
2032
2032
  });
2033
2033
  }
2034
2034
  return;
@@ -2207,7 +2207,7 @@ async function startProxy(options) {
2207
2207
  emitProxyTerminalFromStatus(correlation, 400, { reason: "invalid_json" });
2208
2208
  sendJson(res, 400, {
2209
2209
  error: "Bad request",
2210
- message: "Invalid JSON body for /mnemospark_cloud upload"
2210
+ message: "Invalid JSON body for /mnemospark cloud upload"
2211
2211
  });
2212
2212
  return;
2213
2213
  }
@@ -2270,7 +2270,7 @@ async function startProxy(options) {
2270
2270
  error: "insufficient_balance",
2271
2271
  message: `Insufficient USDC balance. Current: ${sufficiency.info.balanceUSD}, Required: ${requiredUSD}`,
2272
2272
  wallet: requestPayload.wallet_address,
2273
- help: `Fund wallet ${requestPayload.wallet_address} on Base before running /mnemospark_cloud upload`
2273
+ help: `Fund wallet ${requestPayload.wallet_address} on Base before running /mnemospark cloud upload`
2274
2274
  });
2275
2275
  return;
2276
2276
  }
@@ -2378,7 +2378,7 @@ async function startProxy(options) {
2378
2378
  });
2379
2379
  sendJson(res, 502, {
2380
2380
  error: "proxy_error",
2381
- message: `Failed to forward /mnemospark_cloud upload: ${err instanceof Error ? err.message : String(err)}`
2381
+ message: `Failed to forward /mnemospark cloud upload: ${err instanceof Error ? err.message : String(err)}`
2382
2382
  });
2383
2383
  }
2384
2384
  return;
@@ -2396,7 +2396,7 @@ async function startProxy(options) {
2396
2396
  emitProxyTerminalFromStatus(correlation, 400, { reason: "invalid_json" });
2397
2397
  sendJson(res, 400, {
2398
2398
  error: "Bad request",
2399
- message: "Invalid JSON body for /mnemospark_cloud upload/confirm"
2399
+ message: "Invalid JSON body for /mnemospark cloud upload/confirm"
2400
2400
  });
2401
2401
  return;
2402
2402
  }
@@ -2477,7 +2477,7 @@ async function startProxy(options) {
2477
2477
  });
2478
2478
  sendJson(res, 502, {
2479
2479
  error: "proxy_error",
2480
- message: `Failed to forward /mnemospark_cloud upload/confirm: ${err instanceof Error ? err.message : String(err)}`
2480
+ message: `Failed to forward /mnemospark cloud upload/confirm: ${err instanceof Error ? err.message : String(err)}`
2481
2481
  });
2482
2482
  }
2483
2483
  return;
@@ -2495,7 +2495,7 @@ async function startProxy(options) {
2495
2495
  emitProxyTerminalFromStatus(correlation, 400, { reason: "invalid_json" });
2496
2496
  sendJson(res, 400, {
2497
2497
  error: "Bad request",
2498
- message: "Invalid JSON body for /mnemospark_cloud ls"
2498
+ message: "Invalid JSON body for /mnemospark cloud ls"
2499
2499
  });
2500
2500
  return;
2501
2501
  }
@@ -2568,7 +2568,7 @@ async function startProxy(options) {
2568
2568
  });
2569
2569
  sendJson(res, 502, {
2570
2570
  error: "proxy_error",
2571
- message: `Failed to forward /mnemospark_cloud ls: ${err instanceof Error ? err.message : String(err)}`
2571
+ message: `Failed to forward /mnemospark cloud ls: ${err instanceof Error ? err.message : String(err)}`
2572
2572
  });
2573
2573
  }
2574
2574
  return;
@@ -2588,7 +2588,7 @@ async function startProxy(options) {
2588
2588
  emitProxyTerminalFromStatus(correlation, 400, { reason: "invalid_json" });
2589
2589
  sendJson(res, 400, {
2590
2590
  error: "Bad request",
2591
- message: "Invalid JSON body for /mnemospark_cloud download"
2591
+ message: "Invalid JSON body for /mnemospark cloud download"
2592
2592
  });
2593
2593
  return;
2594
2594
  }
@@ -2689,7 +2689,7 @@ async function startProxy(options) {
2689
2689
  });
2690
2690
  sendJson(res, 502, {
2691
2691
  error: "proxy_error",
2692
- message: `Failed to forward /mnemospark_cloud download: ${err instanceof Error ? err.message : String(err)}`
2692
+ message: `Failed to forward /mnemospark cloud download: ${err instanceof Error ? err.message : String(err)}`
2693
2693
  });
2694
2694
  }
2695
2695
  return;
@@ -2707,7 +2707,7 @@ async function startProxy(options) {
2707
2707
  emitProxyTerminalFromStatus(correlation, 400, { reason: "invalid_json" });
2708
2708
  sendJson(res, 400, {
2709
2709
  error: "Bad request",
2710
- message: "Invalid JSON body for /mnemospark_cloud delete"
2710
+ message: "Invalid JSON body for /mnemospark cloud delete"
2711
2711
  });
2712
2712
  return;
2713
2713
  }
@@ -2784,7 +2784,7 @@ async function startProxy(options) {
2784
2784
  });
2785
2785
  sendJson(res, 502, {
2786
2786
  error: "proxy_error",
2787
- message: `Failed to forward /mnemospark_cloud delete: ${err instanceof Error ? err.message : String(err)}`
2787
+ message: `Failed to forward /mnemospark cloud delete: ${err instanceof Error ? err.message : String(err)}`
2788
2788
  });
2789
2789
  }
2790
2790
  return;
@@ -2999,9 +2999,6 @@ async function resolveOrGenerateWalletKey() {
2999
2999
  return { key, address, source: "generated" };
3000
3000
  }
3001
3001
 
3002
- // src/index.ts
3003
- import { existsSync, readFileSync } from "fs";
3004
-
3005
3002
  // src/version.ts
3006
3003
  import { createRequire } from "module";
3007
3004
  import { fileURLToPath } from "url";
@@ -3013,7 +3010,8 @@ var pkg = require2(join6(__dirname, "..", "package.json"));
3013
3010
  var VERSION = pkg.version;
3014
3011
  var USER_AGENT = `mnemospark/${VERSION}`;
3015
3012
 
3016
- // src/index.ts
3013
+ // src/mnemospark-handler.ts
3014
+ import { existsSync, readFileSync } from "fs";
3017
3015
  import { privateKeyToAccount as privateKeyToAccount6 } from "viem/accounts";
3018
3016
 
3019
3017
  // src/cloud-command.ts
@@ -3812,6 +3810,425 @@ async function createCloudDatastore(homeDir) {
3812
3810
  };
3813
3811
  }
3814
3812
 
3813
+ // src/args/normalize.ts
3814
+ function normalizeSmartQuotes(input) {
3815
+ return input.replace(/[\u201C\u201D]/g, '"').replace(/[\u2018\u2019]/g, "'");
3816
+ }
3817
+ function normalizeFlagPositionDashes(input) {
3818
+ const warnings = [];
3819
+ const pattern = /(^|\s)[\u2013\u2014](?=[A-Za-z_][A-Za-z0-9_-]*)/g;
3820
+ let changed = false;
3821
+ const text = input.replace(pattern, (m, prefix) => {
3822
+ changed = true;
3823
+ return `${prefix}--`;
3824
+ });
3825
+ if (changed) {
3826
+ warnings.push("Normalized en/em dash in flag position to ASCII double hyphen.");
3827
+ }
3828
+ return { text, warnings };
3829
+ }
3830
+ function normalizeInputForParsing(input) {
3831
+ const warnings = [];
3832
+ let text = normalizeSmartQuotes(input);
3833
+ const dashNorm = normalizeFlagPositionDashes(text);
3834
+ text = dashNorm.text;
3835
+ warnings.push(...dashNorm.warnings);
3836
+ return { text, warnings };
3837
+ }
3838
+
3839
+ // src/args/suggest.ts
3840
+ function levenshtein(a, b) {
3841
+ const m = a.length;
3842
+ const n = b.length;
3843
+ const dp = Array.from({ length: m + 1 }, () => new Array(n + 1).fill(0));
3844
+ for (let i = 0; i <= m; i++) dp[i][0] = i;
3845
+ for (let j = 0; j <= n; j++) dp[0][j] = j;
3846
+ for (let i = 1; i <= m; i++) {
3847
+ for (let j = 1; j <= n; j++) {
3848
+ const cost = a[i - 1] === b[j - 1] ? 0 : 1;
3849
+ dp[i][j] = Math.min(dp[i - 1][j] + 1, dp[i][j - 1] + 1, dp[i - 1][j - 1] + cost);
3850
+ }
3851
+ }
3852
+ return dp[m][n];
3853
+ }
3854
+ function suggestNearestKey(raw, candidates, maxDistance = 2) {
3855
+ const lower = raw.toLowerCase();
3856
+ let best = null;
3857
+ let bestDist = maxDistance + 1;
3858
+ for (const c of candidates) {
3859
+ const d = levenshtein(lower, c.toLowerCase());
3860
+ if (d < bestDist) {
3861
+ bestDist = d;
3862
+ best = c;
3863
+ }
3864
+ }
3865
+ return bestDist <= maxDistance ? best : null;
3866
+ }
3867
+
3868
+ // src/args/parser.ts
3869
+ function canonicalizeKey(rawKey) {
3870
+ return rawKey.normalize("NFKC").replace(/[\u2010\u2011\u2012\u2013\u2014\u2015\u2212]/g, "-").replace(/_/g, "-").toLowerCase().trim();
3871
+ }
3872
+ function buildAliasMap(schema) {
3873
+ const map = /* @__PURE__ */ new Map();
3874
+ for (const spec of schema.args) {
3875
+ map.set(canonicalizeKey(spec.name), spec);
3876
+ for (const alias of spec.aliases ?? []) {
3877
+ map.set(canonicalizeKey(alias), spec);
3878
+ }
3879
+ }
3880
+ return map;
3881
+ }
3882
+ function tokenize(input) {
3883
+ const tokens = [];
3884
+ let i = 0;
3885
+ while (i < input.length) {
3886
+ while (i < input.length && /\s/.test(input[i])) i++;
3887
+ if (i >= input.length) break;
3888
+ let raw = "";
3889
+ let value = "";
3890
+ if (input[i] === '"' || input[i] === "'") {
3891
+ const quote = input[i++];
3892
+ raw += quote;
3893
+ while (i < input.length) {
3894
+ const ch = input[i++];
3895
+ raw += ch;
3896
+ if (ch === "\\") {
3897
+ if (i < input.length) {
3898
+ const next = input[i++];
3899
+ raw += next;
3900
+ value += next;
3901
+ }
3902
+ continue;
3903
+ }
3904
+ if (ch === quote) {
3905
+ break;
3906
+ }
3907
+ value += ch;
3908
+ }
3909
+ tokens.push({ raw, value });
3910
+ continue;
3911
+ }
3912
+ while (i < input.length && !/\s/.test(input[i])) {
3913
+ const ch = input[i++];
3914
+ raw += ch;
3915
+ value += ch;
3916
+ }
3917
+ tokens.push({ raw, value });
3918
+ }
3919
+ return tokens;
3920
+ }
3921
+ function resolveKey(rawKey, aliasMap, schema, allCanonicalNames) {
3922
+ const canonical = canonicalizeKey(rawKey);
3923
+ const spec = aliasMap.get(canonical);
3924
+ if (!spec) {
3925
+ if (schema.allowUnknown) return { key: canonical };
3926
+ const suggestion = suggestNearestKey(rawKey, allCanonicalNames);
3927
+ const hint = suggestion ? ` Did you mean "${suggestion}"?` : "";
3928
+ return { error: `Unknown argument "${rawKey}".${hint}` };
3929
+ }
3930
+ return { key: spec.name, spec };
3931
+ }
3932
+ function addValue(out, key, value, spec) {
3933
+ const existing = out[key];
3934
+ if (existing === void 0) {
3935
+ out[key] = spec?.repeatable ? [value] : value;
3936
+ return null;
3937
+ }
3938
+ if (!spec?.repeatable) {
3939
+ return `Duplicate argument "${key}".`;
3940
+ }
3941
+ if (Array.isArray(existing)) {
3942
+ existing.push(value);
3943
+ } else {
3944
+ out[key] = [existing, value];
3945
+ }
3946
+ return null;
3947
+ }
3948
+ function collectCanonicalNames(schema) {
3949
+ const names = /* @__PURE__ */ new Set();
3950
+ for (const spec of schema.args) {
3951
+ names.add(spec.name);
3952
+ for (const a of spec.aliases ?? []) {
3953
+ names.add(a);
3954
+ }
3955
+ }
3956
+ return [...names];
3957
+ }
3958
+ function looksLikeDelimitedArgToken(token) {
3959
+ return /^[A-Za-z_][A-Za-z0-9_-]*[:=]/.test(token);
3960
+ }
3961
+ function tryParseDelimitedToken(token, delimiter, aliasMap, schema, allCanonicalNames, out) {
3962
+ const idx = token.indexOf(delimiter);
3963
+ if (idx <= 0) return { handled: false };
3964
+ const keyPart = token.slice(0, idx);
3965
+ if (!/^[A-Za-z_][A-Za-z0-9_-]*$/.test(keyPart)) return { handled: false };
3966
+ const rawKey = keyPart;
3967
+ const rawValue = token.slice(idx + 1);
3968
+ if (rawValue === "") {
3969
+ return { handled: true, error: `Empty value for argument "${rawKey}".` };
3970
+ }
3971
+ const resolved = resolveKey(rawKey, aliasMap, schema, allCanonicalNames);
3972
+ if (resolved.error) {
3973
+ return { handled: true, error: resolved.error };
3974
+ }
3975
+ const dupErr = addValue(out, resolved.key, rawValue, resolved.spec);
3976
+ if (dupErr) {
3977
+ return { handled: true, error: dupErr };
3978
+ }
3979
+ return { handled: true };
3980
+ }
3981
+ function parseCommandArgs(input, schema) {
3982
+ const warnings = [];
3983
+ const errors = [];
3984
+ const norm = normalizeInputForParsing(input);
3985
+ const normalized = norm.text;
3986
+ warnings.push(...norm.warnings);
3987
+ const tokens = tokenize(normalized);
3988
+ const aliasMap = buildAliasMap(schema);
3989
+ const allCanonicalNames = collectCanonicalNames(schema);
3990
+ const values = {};
3991
+ for (let i = 0; i < tokens.length; i++) {
3992
+ const token = tokens[i].value;
3993
+ {
3994
+ const parsed = tryParseDelimitedToken(
3995
+ token,
3996
+ ":",
3997
+ aliasMap,
3998
+ schema,
3999
+ allCanonicalNames,
4000
+ values
4001
+ );
4002
+ if (parsed.handled) {
4003
+ if (parsed.error) errors.push(parsed.error);
4004
+ continue;
4005
+ }
4006
+ }
4007
+ {
4008
+ const parsed = tryParseDelimitedToken(
4009
+ token,
4010
+ "=",
4011
+ aliasMap,
4012
+ schema,
4013
+ allCanonicalNames,
4014
+ values
4015
+ );
4016
+ if (parsed.handled) {
4017
+ if (parsed.error) errors.push(parsed.error);
4018
+ continue;
4019
+ }
4020
+ }
4021
+ if (token.startsWith("--")) {
4022
+ const rawKey = token.slice(2);
4023
+ if (!rawKey) {
4024
+ errors.push('Encountered "--" without an argument name.');
4025
+ continue;
4026
+ }
4027
+ const resolved = resolveKey(rawKey, aliasMap, schema, allCanonicalNames);
4028
+ if (resolved.error) {
4029
+ errors.push(resolved.error);
4030
+ continue;
4031
+ }
4032
+ const next = tokens[i + 1];
4033
+ if (!next) {
4034
+ if (resolved.spec?.bareBoolean) {
4035
+ const dupErr2 = addValue(values, resolved.key, "true", resolved.spec);
4036
+ if (dupErr2) errors.push(dupErr2);
4037
+ continue;
4038
+ }
4039
+ errors.push(`Missing value for argument "${resolved.key}".`);
4040
+ continue;
4041
+ }
4042
+ if (next.value.startsWith("--")) {
4043
+ if (resolved.spec?.bareBoolean) {
4044
+ const dupErr2 = addValue(values, resolved.key, "true", resolved.spec);
4045
+ if (dupErr2) errors.push(dupErr2);
4046
+ continue;
4047
+ }
4048
+ errors.push(`Missing value for argument "${resolved.key}".`);
4049
+ continue;
4050
+ }
4051
+ if (resolved.spec?.bareBoolean && looksLikeDelimitedArgToken(next.value)) {
4052
+ const dupErr2 = addValue(values, resolved.key, "true", resolved.spec);
4053
+ if (dupErr2) errors.push(dupErr2);
4054
+ continue;
4055
+ }
4056
+ const dupErr = addValue(values, resolved.key, next.value, resolved.spec);
4057
+ if (dupErr) errors.push(dupErr);
4058
+ i += 1;
4059
+ continue;
4060
+ }
4061
+ errors.push(`Unexpected token "${token}". Use key:value, key=value, or --key value.`);
4062
+ }
4063
+ for (const spec of schema.args) {
4064
+ if (spec.required && values[spec.name] === void 0) {
4065
+ errors.push(`Missing required argument "${spec.name}".`);
4066
+ }
4067
+ }
4068
+ if (errors.length > 0) {
4069
+ return {
4070
+ ok: false,
4071
+ normalizedInput: normalized,
4072
+ errors,
4073
+ warnings
4074
+ };
4075
+ }
4076
+ return {
4077
+ ok: true,
4078
+ normalizedInput: normalized,
4079
+ values,
4080
+ warnings
4081
+ };
4082
+ }
4083
+ function valuesToStringRecord(values) {
4084
+ const out = {};
4085
+ for (const [k, v] of Object.entries(values)) {
4086
+ out[k] = Array.isArray(v) ? v[v.length - 1] : v;
4087
+ }
4088
+ return out;
4089
+ }
4090
+
4091
+ // src/mnemospark-route.ts
4092
+ function parseVerboseToken(token) {
4093
+ const t = token.trim();
4094
+ const idx = t.indexOf(":");
4095
+ if (idx < 0) {
4096
+ return { name: t.toLowerCase(), ok: true };
4097
+ }
4098
+ const key = t.slice(0, idx).trim();
4099
+ const val = t.slice(idx + 1).trim().toLowerCase();
4100
+ if (!key) return { name: "", ok: false };
4101
+ if (val === "true") return { name: key.toLowerCase(), ok: true };
4102
+ return { name: key.toLowerCase(), ok: false };
4103
+ }
4104
+ function firstTokenAndRest(input) {
4105
+ const t = input.trim();
4106
+ if (!t) return { first: "", rest: "" };
4107
+ const spaceIdx = t.search(/\s/);
4108
+ if (spaceIdx === -1) return { first: t, rest: "" };
4109
+ return { first: t.slice(0, spaceIdx), rest: t.slice(spaceIdx + 1).trim() };
4110
+ }
4111
+ function routeMnemosparkArgs(args) {
4112
+ const trimmed = args?.trim() ?? "";
4113
+ if (!trimmed) {
4114
+ return { kind: "root-help" };
4115
+ }
4116
+ const { first, rest } = firstTokenAndRest(trimmed);
4117
+ const parsed = parseVerboseToken(first);
4118
+ if (!parsed.ok) {
4119
+ return {
4120
+ kind: "error",
4121
+ message: `Invalid token "${first}". Use name:true only with value true, or a bare name (e.g. cloud, wallet, help).`
4122
+ };
4123
+ }
4124
+ const head = parsed.name;
4125
+ if (head === "help") {
4126
+ return { kind: "root-help" };
4127
+ }
4128
+ if (head === "cloud") {
4129
+ return { kind: "cloud", rest };
4130
+ }
4131
+ if (head === "wallet") {
4132
+ return { kind: "wallet", rest };
4133
+ }
4134
+ return {
4135
+ kind: "error",
4136
+ message: [
4137
+ `Unknown command "${first}".`,
4138
+ "",
4139
+ "Try:",
4140
+ "\u2022 `/mnemospark help` \u2014 overview",
4141
+ "\u2022 `/mnemospark cloud help` \u2014 cloud commands",
4142
+ "\u2022 `/mnemospark wallet` \u2014 wallet status",
4143
+ "\u2022 `/mnemospark wallet help` \u2014 wallet commands"
4144
+ ].join("\n")
4145
+ };
4146
+ }
4147
+
4148
+ // src/arg-schemas.ts
4149
+ var priceStorageSchema = {
4150
+ args: [
4151
+ { name: "wallet-address", aliases: ["wallet"], required: true },
4152
+ { name: "object-id", aliases: ["object"], required: true },
4153
+ { name: "object-id-hash", aliases: ["hash"], required: true },
4154
+ { name: "gb", required: true },
4155
+ { name: "provider", required: true },
4156
+ { name: "region", required: true }
4157
+ ]
4158
+ };
4159
+ var uploadSchema = {
4160
+ args: [
4161
+ { name: "quote-id", aliases: ["quote"], required: true },
4162
+ { name: "wallet-address", aliases: ["wallet"], required: true },
4163
+ { name: "object-id", aliases: ["object"], required: true },
4164
+ { name: "object-id-hash", aliases: ["hash"], required: true },
4165
+ { name: "name" },
4166
+ { name: "async", bareBoolean: true },
4167
+ { name: "orchestrator" },
4168
+ { name: "timeout-seconds" }
4169
+ ]
4170
+ };
4171
+ var backupFlagsSchema = {
4172
+ args: [
4173
+ { name: "name" },
4174
+ { name: "async", bareBoolean: true },
4175
+ { name: "orchestrator" },
4176
+ { name: "timeout-seconds" }
4177
+ ]
4178
+ };
4179
+ var paymentSettleSchema = {
4180
+ args: [
4181
+ { name: "quote-id", aliases: ["quote"] },
4182
+ { name: "wallet-address", aliases: ["wallet"], required: true },
4183
+ { name: "object-id", aliases: ["object"] },
4184
+ { name: "object-key" },
4185
+ { name: "storage-price" },
4186
+ { name: "renewal", bareBoolean: true }
4187
+ ]
4188
+ };
4189
+ var lsSchema = {
4190
+ args: [
4191
+ { name: "wallet-address", aliases: ["wallet"], required: true },
4192
+ { name: "object-key" },
4193
+ { name: "name" },
4194
+ { name: "latest", bareBoolean: true },
4195
+ { name: "at" },
4196
+ { name: "location" },
4197
+ { name: "region" }
4198
+ ]
4199
+ };
4200
+ var downloadSchema = {
4201
+ args: [
4202
+ { name: "wallet-address", aliases: ["wallet"], required: true },
4203
+ { name: "object-key" },
4204
+ { name: "name" },
4205
+ { name: "latest", bareBoolean: true },
4206
+ { name: "at" },
4207
+ { name: "location" },
4208
+ { name: "region" },
4209
+ { name: "async", bareBoolean: true },
4210
+ { name: "orchestrator" },
4211
+ { name: "timeout-seconds" }
4212
+ ]
4213
+ };
4214
+ var deleteSchema = {
4215
+ args: [
4216
+ { name: "wallet-address", aliases: ["wallet"], required: true },
4217
+ { name: "object-key" },
4218
+ { name: "name" },
4219
+ { name: "latest", bareBoolean: true },
4220
+ { name: "at" },
4221
+ { name: "location" },
4222
+ { name: "region" }
4223
+ ]
4224
+ };
4225
+ var opStatusSchema = {
4226
+ args: [
4227
+ { name: "operation-id", required: true },
4228
+ { name: "cancel", bareBoolean: true }
4229
+ ]
4230
+ };
4231
+
3815
4232
  // src/cloud-command.ts
3816
4233
  var SUPPORTED_BACKUP_PLATFORMS = /* @__PURE__ */ new Set(["darwin", "linux"]);
3817
4234
  var BACKUP_DIR_SUBPATH = join8(".openclaw", "mnemospark", "backup");
@@ -3829,21 +4246,8 @@ var REQUIRED_PRICE_STORAGE = "--wallet-address, --object-id, --object-id-hash, -
3829
4246
  var REQUIRED_UPLOAD = "--quote-id, --wallet-address, --object-id, --object-id-hash";
3830
4247
  var REQUIRED_BACKUP = "<file|directory> and --name <friendly-name>";
3831
4248
  var REQUIRED_PAYMENT_SETTLE = "--wallet-address and (--quote-id | --renewal with --object-key)";
3832
- var PAYMENT_SETTLE_BOOLEAN_FLAGS = /* @__PURE__ */ new Set(["renewal"]);
3833
4249
  var REQUIRED_STORAGE_OBJECT = "--wallet-address and one of (--object-key | --name [--latest|--at])";
3834
4250
  var REQUIRED_LS = "--wallet-address (for one object add --object-key or --name [--latest|--at]; omit both to list the bucket)";
3835
- var PAYMENT_SETTLE_FLAG_NAMES = /* @__PURE__ */ new Set([
3836
- "quote-id",
3837
- "wallet-address",
3838
- "object-id",
3839
- "object-key",
3840
- "storage-price",
3841
- "renewal"
3842
- ]);
3843
- var BOOLEAN_SELECTOR_FLAGS = /* @__PURE__ */ new Set(["latest"]);
3844
- var BOOLEAN_ASYNC_FLAGS = /* @__PURE__ */ new Set(["async"]);
3845
- var BOOLEAN_OP_STATUS_FLAGS = /* @__PURE__ */ new Set(["cancel"]);
3846
- var BOOLEAN_SELECTOR_AND_ASYNC_FLAGS = /* @__PURE__ */ new Set(["latest", "async"]);
3847
4251
  var ORCHESTRATOR_MODES = /* @__PURE__ */ new Set(["inline", "subagent"]);
3848
4252
  function expandTilde(path) {
3849
4253
  const trimmed = path.trim();
@@ -3858,39 +4262,42 @@ function expandTilde(path) {
3858
4262
  var CLOUD_HELP_TEXT = [
3859
4263
  "\u2601\uFE0F **mnemospark - Wallet and go.** \u{1F499}",
3860
4264
  "",
4265
+ "**Syntax:** use `/mnemospark cloud \u2026`. Arguments may use `key:value`, `key=value`, or `--key value`. 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.",
4266
+ "",
3861
4267
  "**Cloud Commands**",
3862
4268
  "",
3863
- "\u2022 `/mnemospark_cloud` or `/mnemospark_cloud help` \u2014 show this message",
4269
+ "\u2022 `/mnemospark cloud` or `/mnemospark cloud help` \u2014 show this message (equivalent: `/mnemospark cloud:true help:true`)",
3864
4270
  "",
3865
- "\u2022 `/mnemospark_cloud backup <file|directory> --name <friendly-name> [--async] [--orchestrator <inline|subagent>] [--timeout-seconds <n>]`",
4271
+ "\u2022 `/mnemospark cloud backup <file|directory> --name <friendly-name> [--async] [--orchestrator <inline|subagent>] [--timeout-seconds <n>]`",
3866
4272
  " 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.",
3867
4273
  " Required: " + REQUIRED_BACKUP,
3868
4274
  "",
3869
- "\u2022 `/mnemospark_cloud price-storage --wallet-address <addr> --object-id <id> --object-id-hash <hash> --gb <gb> --provider aws --region us-east-1`",
4275
+ "\u2022 `/mnemospark cloud price-storage --wallet-address <addr> --object-id <id> --object-id-hash <hash> --gb <gb> --provider aws --region us-east-1`",
3870
4276
  " Purpose: request a storage quote before upload (defaults shown; override `--provider` / `--region` for other regions).",
3871
4277
  " Required: " + REQUIRED_PRICE_STORAGE,
4278
+ " Shorter: `wallet:\u2026 object:\u2026 hash:\u2026 gb:\u2026 provider:\u2026 region:\u2026`",
3872
4279
  "",
3873
- "\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>]`",
4280
+ "\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>]`",
3874
4281
  " Purpose: upload an encrypted object using a valid quote-id.",
3875
4282
  " Required: " + REQUIRED_UPLOAD,
3876
4283
  "",
3877
- "\u2022 `/mnemospark_cloud payment-settle (--quote-id <quote-id> | --renewal --object-key <key>) --wallet-address <addr> [--object-id <id>] [--storage-price <n>]`",
4284
+ "\u2022 `/mnemospark cloud payment-settle (--quote-id <quote-id> | --renewal --object-key <key>) --wallet-address <addr> [--object-id <id>] [--storage-price <n>]`",
3878
4285
  " 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.",
3879
4286
  " Required: " + REQUIRED_PAYMENT_SETTLE + " (wallet private key must match the address).",
3880
4287
  "",
3881
- "\u2022 `/mnemospark_cloud ls --wallet-address <addr> [--object-key <key> | --name <friendly-name> | omit both to list bucket] [--latest|--at <timestamp>]`",
4288
+ "\u2022 `/mnemospark cloud ls --wallet-address <addr> [--object-key <key> | --name <friendly-name> | omit both to list bucket] [--latest|--at <timestamp>]`",
3882
4289
  " Purpose: stat one object or list all keys in the wallet bucket (S3).",
3883
4290
  " Required: " + REQUIRED_LS,
3884
4291
  "",
3885
- "\u2022 `/mnemospark_cloud download --wallet-address <addr> [--object-key <object-key> | --name <friendly-name>] [--latest|--at <timestamp>] [--async] [--orchestrator <inline|subagent>] [--timeout-seconds <n>]`",
4292
+ "\u2022 `/mnemospark cloud download --wallet-address <addr> [--object-key <object-key> | --name <friendly-name>] [--latest|--at <timestamp>] [--async] [--orchestrator <inline|subagent>] [--timeout-seconds <n>]`",
3886
4293
  " Purpose: fetch an object to local disk.",
3887
4294
  " Required: " + REQUIRED_STORAGE_OBJECT,
3888
4295
  "",
3889
- "\u2022 `/mnemospark_cloud delete --wallet-address <addr> [--object-key <object-key> | --name <friendly-name>] [--latest|--at <timestamp>]`",
4296
+ "\u2022 `/mnemospark cloud delete --wallet-address <addr> [--object-key <object-key> | --name <friendly-name>] [--latest|--at <timestamp>]`",
3890
4297
  " Purpose: remove a remote object and local cron tracking when present.",
3891
4298
  " Required: " + REQUIRED_STORAGE_OBJECT,
3892
4299
  "",
3893
- "\u2022 `/mnemospark_cloud op-status --operation-id <id> [--cancel]`",
4300
+ "\u2022 `/mnemospark cloud op-status --operation-id <id> [--cancel]`",
3894
4301
  " Purpose: inspect async operation status, or request cancellation for subagent runs.",
3895
4302
  " Required: --operation-id",
3896
4303
  "",
@@ -3907,10 +4314,10 @@ var CLOUD_HELP_TEXT = [
3907
4314
  " Cancel a subagent-orchestrated operation by operation-id (idempotent).",
3908
4315
  "",
3909
4316
  "Examples:",
3910
- "\u2022 `/mnemospark_cloud upload ... --async --orchestrator subagent`",
3911
- "\u2022 `/mnemospark_cloud download ... --async --orchestrator subagent --timeout-seconds 900`",
3912
- "\u2022 `/mnemospark_cloud op-status --operation-id <id>`",
3913
- "\u2022 `/mnemospark_cloud op-status --operation-id <id> --cancel`",
4317
+ "\u2022 `/mnemospark cloud upload ... --async --orchestrator subagent`",
4318
+ "\u2022 `/mnemospark cloud download ... --async --orchestrator subagent --timeout-seconds 900`",
4319
+ "\u2022 `/mnemospark cloud op-status --operation-id <id>`",
4320
+ "\u2022 `/mnemospark cloud op-status --operation-id <id> --cancel`",
3914
4321
  "",
3915
4322
  CLOUD_HELP_FOOTER_STATE,
3916
4323
  "",
@@ -3943,37 +4350,6 @@ function tokenizeArgsRaw(input) {
3943
4350
  }
3944
4351
  return tokens;
3945
4352
  }
3946
- function tokenizeArgs(input) {
3947
- return tokenizeArgsRaw(input).map((token) => stripWrappingQuotes(token));
3948
- }
3949
- function parseNamedFlagsTokens(tokens, booleanFlags = /* @__PURE__ */ new Set()) {
3950
- if (tokens.length === 0) {
3951
- return null;
3952
- }
3953
- const parsed = {};
3954
- for (let i = 0; i < tokens.length; i += 1) {
3955
- const keyToken = tokens[i];
3956
- if (!keyToken.startsWith("--")) {
3957
- return null;
3958
- }
3959
- const key = keyToken.slice(2).toLowerCase().replace(/_/g, "-");
3960
- const value = tokens[i + 1];
3961
- if (!value || value.startsWith("--")) {
3962
- if (booleanFlags.has(key)) {
3963
- parsed[key] = "true";
3964
- continue;
3965
- }
3966
- return null;
3967
- }
3968
- parsed[key] = value;
3969
- i += 1;
3970
- }
3971
- return parsed;
3972
- }
3973
- function parseNamedFlags(input, booleanFlags = /* @__PURE__ */ new Set()) {
3974
- const tokens = tokenizeArgs(input);
3975
- return parseNamedFlagsTokens(tokens, booleanFlags);
3976
- }
3977
4353
  function parseObjectSelector(flags) {
3978
4354
  const objectKey = flags["object-key"]?.trim();
3979
4355
  const name = flags.name?.trim();
@@ -4070,6 +4446,14 @@ var INVALID_ASYNC_FLAGS_MESSAGE = "invalid async flags. `--orchestrator`/`--time
4070
4446
  function stripAsyncControlFlags(args) {
4071
4447
  const tokens = tokenizeArgsRaw(args ?? "");
4072
4448
  const filtered = [];
4449
+ const isAsyncControlKey = (rawKey) => {
4450
+ const canonical = rawKey.trim().toLowerCase().replace(/_/g, "-");
4451
+ return canonical === "async" || canonical === "orchestrator" || canonical === "timeout-seconds";
4452
+ };
4453
+ const isBareBooleanFlag = (rawToken) => {
4454
+ const canonical = rawToken.trim().toLowerCase().replace(/^--/, "").replace(/_/g, "-");
4455
+ return canonical === "async" || canonical === "latest";
4456
+ };
4073
4457
  for (let idx = 0; idx < tokens.length; idx += 1) {
4074
4458
  const token = tokens[idx];
4075
4459
  const lowerToken = token.toLowerCase();
@@ -4080,35 +4464,71 @@ function stripAsyncControlFlags(args) {
4080
4464
  idx += 1;
4081
4465
  continue;
4082
4466
  }
4467
+ const previousToken = tokens[idx - 1];
4468
+ if (previousToken && previousToken.startsWith("--") && !isBareBooleanFlag(previousToken)) {
4469
+ filtered.push(token);
4470
+ continue;
4471
+ }
4472
+ const unwrapped = stripWrappingQuotes(token);
4473
+ const colonIdx = unwrapped.indexOf(":");
4474
+ const equalsIdx = unwrapped.indexOf("=");
4475
+ const splitIdx = colonIdx > 0 && equalsIdx > 0 ? Math.min(colonIdx, equalsIdx) : Math.max(colonIdx, equalsIdx);
4476
+ if (splitIdx > 0) {
4477
+ const candidateKey = unwrapped.slice(0, splitIdx);
4478
+ if (/^[A-Za-z_][A-Za-z0-9_-]*$/.test(candidateKey) && isAsyncControlKey(candidateKey)) {
4479
+ continue;
4480
+ }
4481
+ }
4083
4482
  filtered.push(token);
4084
4483
  }
4085
4484
  return filtered.join(" ");
4086
4485
  }
4486
+ function mergeArgParseWarnings(a, b) {
4487
+ return [...a, ...b];
4488
+ }
4087
4489
  function parseCloudArgs(args) {
4088
4490
  const trimmed = args?.trim() ?? "";
4089
4491
  if (!trimmed) {
4090
4492
  return { mode: "help" };
4091
4493
  }
4092
- const spaceIdx = trimmed.indexOf(" ");
4093
- const subcommand = (spaceIdx === -1 ? trimmed : trimmed.slice(0, spaceIdx)).toLowerCase();
4094
- const rest = spaceIdx === -1 ? "" : trimmed.slice(spaceIdx + 1);
4494
+ const norm = normalizeInputForParsing(trimmed);
4495
+ const text = norm.text;
4496
+ const normWarnings = norm.warnings;
4497
+ const spaceIdx = text.search(/\s/);
4498
+ const rawFirst = spaceIdx === -1 ? text : text.slice(0, spaceIdx);
4499
+ const rest = spaceIdx === -1 ? "" : text.slice(spaceIdx + 1).trim();
4500
+ const subParsed = parseVerboseToken(rawFirst);
4501
+ if (!subParsed.ok) {
4502
+ return {
4503
+ mode: "arg-parse-failure",
4504
+ errors: [`Invalid subcommand token "${rawFirst}". Use name:true only with value true.`],
4505
+ warnings: normWarnings
4506
+ };
4507
+ }
4508
+ const subcommand = subParsed.name;
4095
4509
  if (subcommand === "help") {
4096
4510
  return { mode: "help" };
4097
4511
  }
4098
4512
  if (subcommand === "backup") {
4099
- const tokens = tokenizeArgs(rest);
4513
+ const tokens = tokenizeArgsRaw(rest);
4100
4514
  if (tokens.length === 0) {
4101
4515
  return { mode: "unknown" };
4102
4516
  }
4103
- const backupTarget = tokens[0] ?? "";
4517
+ const backupTarget = stripWrappingQuotes(tokens[0] ?? "");
4104
4518
  if (!backupTarget) {
4105
4519
  return { mode: "unknown" };
4106
4520
  }
4107
4521
  const remainingTokens = tokens.slice(1);
4108
- const flags = remainingTokens.length === 0 ? {} : parseNamedFlagsTokens(remainingTokens, BOOLEAN_ASYNC_FLAGS);
4109
- if (!flags) {
4110
- return { mode: "backup-invalid" };
4522
+ const flagsPart = remainingTokens.join(" ");
4523
+ const parsed = parseCommandArgs(flagsPart, backupFlagsSchema);
4524
+ if (!parsed.ok) {
4525
+ return {
4526
+ mode: "arg-parse-failure",
4527
+ errors: parsed.errors,
4528
+ warnings: mergeArgParseWarnings(normWarnings, parsed.warnings)
4529
+ };
4111
4530
  }
4531
+ const flags = valuesToStringRecord(parsed.values);
4112
4532
  const asyncArgs = parseAsyncOperationArgs(flags);
4113
4533
  if (!asyncArgs) {
4114
4534
  return { mode: "backup-invalid-async" };
@@ -4125,10 +4545,15 @@ function parseCloudArgs(args) {
4125
4545
  };
4126
4546
  }
4127
4547
  if (subcommand === "price-storage") {
4128
- const flags = parseNamedFlags(rest);
4129
- if (!flags) {
4130
- return { mode: "price-storage-invalid" };
4548
+ const parsed = parseCommandArgs(rest, priceStorageSchema);
4549
+ if (!parsed.ok) {
4550
+ return {
4551
+ mode: "arg-parse-failure",
4552
+ errors: parsed.errors,
4553
+ warnings: mergeArgParseWarnings(normWarnings, parsed.warnings)
4554
+ };
4131
4555
  }
4556
+ const flags = valuesToStringRecord(parsed.values);
4132
4557
  const gb = Number.parseFloat(flags.gb ?? "");
4133
4558
  const request = parsePriceStorageQuoteRequest({
4134
4559
  wallet_address: flags["wallet-address"],
@@ -4144,10 +4569,15 @@ function parseCloudArgs(args) {
4144
4569
  return { mode: "price-storage", priceStorageRequest: request };
4145
4570
  }
4146
4571
  if (subcommand === "upload") {
4147
- const flags = parseNamedFlags(rest, BOOLEAN_ASYNC_FLAGS);
4148
- if (!flags) {
4149
- return { mode: "upload-invalid" };
4572
+ const parsed = parseCommandArgs(rest, uploadSchema);
4573
+ if (!parsed.ok) {
4574
+ return {
4575
+ mode: "arg-parse-failure",
4576
+ errors: parsed.errors,
4577
+ warnings: mergeArgParseWarnings(normWarnings, parsed.warnings)
4578
+ };
4150
4579
  }
4580
+ const flags = valuesToStringRecord(parsed.values);
4151
4581
  const asyncArgs = parseAsyncOperationArgs(flags);
4152
4582
  if (!asyncArgs) {
4153
4583
  return { mode: "upload-invalid-async" };
@@ -4172,15 +4602,15 @@ function parseCloudArgs(args) {
4172
4602
  };
4173
4603
  }
4174
4604
  if (subcommand === "payment-settle") {
4175
- const flags = parseNamedFlags(rest, PAYMENT_SETTLE_BOOLEAN_FLAGS);
4176
- if (!flags) {
4177
- return { mode: "payment-settle-invalid" };
4178
- }
4179
- for (const key of Object.keys(flags)) {
4180
- if (!PAYMENT_SETTLE_FLAG_NAMES.has(key)) {
4181
- return { mode: "payment-settle-invalid" };
4182
- }
4605
+ const parsed = parseCommandArgs(rest, paymentSettleSchema);
4606
+ if (!parsed.ok) {
4607
+ return {
4608
+ mode: "arg-parse-failure",
4609
+ errors: parsed.errors,
4610
+ warnings: mergeArgParseWarnings(normWarnings, parsed.warnings)
4611
+ };
4183
4612
  }
4613
+ const flags = valuesToStringRecord(parsed.values);
4184
4614
  const walletAddress = flags["wallet-address"]?.trim();
4185
4615
  if (!walletAddress) {
4186
4616
  return { mode: "payment-settle-invalid" };
@@ -4220,11 +4650,16 @@ function parseCloudArgs(args) {
4220
4650
  };
4221
4651
  }
4222
4652
  if (subcommand === "ls") {
4223
- const flags = parseNamedFlags(rest, BOOLEAN_SELECTOR_FLAGS);
4224
- if (!flags) {
4225
- return { mode: "ls-invalid" };
4653
+ const parsed = parseCommandArgs(rest, lsSchema);
4654
+ if (!parsed.ok) {
4655
+ return {
4656
+ mode: "arg-parse-failure",
4657
+ errors: parsed.errors,
4658
+ warnings: mergeArgParseWarnings(normWarnings, parsed.warnings)
4659
+ };
4226
4660
  }
4227
- const walletAddress = flags["wallet-address"]?.trim() ?? flags["wallet_address"]?.trim() ?? "";
4661
+ const flags = valuesToStringRecord(parsed.values);
4662
+ const walletAddress = flags["wallet-address"]?.trim() ?? "";
4228
4663
  if (!walletAddress) {
4229
4664
  return { mode: "ls-invalid" };
4230
4665
  }
@@ -4256,10 +4691,15 @@ function parseCloudArgs(args) {
4256
4691
  };
4257
4692
  }
4258
4693
  if (subcommand === "download") {
4259
- const flags = parseNamedFlags(rest, BOOLEAN_SELECTOR_AND_ASYNC_FLAGS);
4260
- if (!flags) {
4261
- return { mode: "download-invalid" };
4694
+ const parsed = parseCommandArgs(rest, downloadSchema);
4695
+ if (!parsed.ok) {
4696
+ return {
4697
+ mode: "arg-parse-failure",
4698
+ errors: parsed.errors,
4699
+ warnings: mergeArgParseWarnings(normWarnings, parsed.warnings)
4700
+ };
4262
4701
  }
4702
+ const flags = valuesToStringRecord(parsed.values);
4263
4703
  const asyncArgs = parseAsyncOperationArgs(flags);
4264
4704
  if (!asyncArgs) {
4265
4705
  return { mode: "download-invalid-async" };
@@ -4280,10 +4720,15 @@ function parseCloudArgs(args) {
4280
4720
  };
4281
4721
  }
4282
4722
  if (subcommand === "delete") {
4283
- const flags = parseNamedFlags(rest, BOOLEAN_SELECTOR_FLAGS);
4284
- if (!flags) {
4285
- return { mode: "delete-invalid" };
4723
+ const parsed = parseCommandArgs(rest, deleteSchema);
4724
+ if (!parsed.ok) {
4725
+ return {
4726
+ mode: "arg-parse-failure",
4727
+ errors: parsed.errors,
4728
+ warnings: mergeArgParseWarnings(normWarnings, parsed.warnings)
4729
+ };
4286
4730
  }
4731
+ const flags = valuesToStringRecord(parsed.values);
4287
4732
  const selector = parseObjectSelector(flags);
4288
4733
  if (!selector) {
4289
4734
  return { mode: "delete-invalid" };
@@ -4295,12 +4740,20 @@ function parseCloudArgs(args) {
4295
4740
  return { mode: "delete", storageObjectRequest: request, nameSelector: selector.nameSelector };
4296
4741
  }
4297
4742
  if (subcommand === "op-status") {
4298
- const flags = parseNamedFlags(rest, BOOLEAN_OP_STATUS_FLAGS);
4299
- const operationId = flags?.["operation-id"]?.trim();
4743
+ const parsed = parseCommandArgs(rest, opStatusSchema);
4744
+ if (!parsed.ok) {
4745
+ return {
4746
+ mode: "arg-parse-failure",
4747
+ errors: parsed.errors,
4748
+ warnings: mergeArgParseWarnings(normWarnings, parsed.warnings)
4749
+ };
4750
+ }
4751
+ const flags = valuesToStringRecord(parsed.values);
4752
+ const operationId = flags["operation-id"]?.trim();
4300
4753
  if (!operationId) {
4301
4754
  return { mode: "op-status-invalid" };
4302
4755
  }
4303
- return { mode: "op-status", operationId, cancel: flags?.cancel === "true" };
4756
+ return { mode: "op-status", operationId, cancel: flags.cancel === "true" };
4304
4757
  }
4305
4758
  return { mode: "unknown" };
4306
4759
  }
@@ -4385,7 +4838,7 @@ async function resolveLocalUploadArchivePath(backupDir, objectId, friendlyName)
4385
4838
  } catch {
4386
4839
  return {
4387
4840
  ok: false,
4388
- message: `Cannot upload storage object: local archive not found. Run /mnemospark_cloud backup with --name (canonical layout) or restore the legacy file at ${legacyPath}.`
4841
+ message: `Cannot upload storage object: local archive not found. Run /mnemospark cloud backup with --name (canonical layout) or restore the legacy file at ${legacyPath}.`
4389
4842
  };
4390
4843
  }
4391
4844
  }
@@ -4606,7 +5059,7 @@ function buildStoragePaymentRenewalArgs(job) {
4606
5059
  ].join(" ");
4607
5060
  }
4608
5061
  function buildStoragePaymentCronCommand(job) {
4609
- return `/mnemospark_cloud ${buildStoragePaymentRenewalArgs(job)}`;
5062
+ return `/mnemospark cloud ${buildStoragePaymentRenewalArgs(job)}`;
4610
5063
  }
4611
5064
  function buildOpenClawRenewalAgentMessage(openClawHome, renewalArgs) {
4612
5065
  const cliPath = join8(openClawHome, ".openclaw/extensions/mnemospark/dist/cli.js");
@@ -4946,7 +5399,7 @@ async function maybeCleanupLocalBackupArchive(archivePath) {
4946
5399
  }
4947
5400
  }
4948
5401
  function formatStorageUploadUserMessage(upload, cronJobId) {
4949
- const lsLine = `/mnemospark_cloud ls --wallet-address \`${upload.addr}\``;
5402
+ const lsLine = `/mnemospark cloud ls --wallet-address \`${upload.addr}\``;
4950
5403
  return [
4951
5404
  `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}\``,
4952
5405
  "",
@@ -5004,7 +5457,7 @@ function extractLsErrorMessage(error) {
5004
5457
  return null;
5005
5458
  }
5006
5459
  function formatPriceStorageUserMessage(quote, localArchiveHint) {
5007
- 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}\``;
5460
+ 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}\``;
5008
5461
  const lines = [
5009
5462
  `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}\`.`,
5010
5463
  "",
@@ -5029,7 +5482,7 @@ var DEFAULT_BACKUP_QUOTE_PROVIDER = "aws";
5029
5482
  var DEFAULT_BACKUP_QUOTE_REGION = "us-east-1";
5030
5483
  function formatBackupSuccessUserMessage(result, walletAddress, friendlyName) {
5031
5484
  const hash = result.objectIdHash.replace(/\s/g, "");
5032
- 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}`;
5485
+ 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}`;
5033
5486
  return [
5034
5487
  `Backup archive: \`${result.archivePath}\``,
5035
5488
  "",
@@ -5152,9 +5605,9 @@ function createInProcessSubagentOrchestrator() {
5152
5605
  function createCloudCommand(options = {}) {
5153
5606
  const subagentOrchestrator = options.subagentOrchestrator ?? createInProcessSubagentOrchestrator();
5154
5607
  return {
5155
- name: "mnemospark_cloud",
5608
+ name: "mnemospark",
5156
5609
  nativeNames: {
5157
- default: "mnemospark_cloud"
5610
+ default: "mnemospark"
5158
5611
  },
5159
5612
  description: "Manage mnemospark cloud storage workflow commands",
5160
5613
  acceptsArgs: true,
@@ -5482,15 +5935,24 @@ async function runCloudCommandHandler(ctx, options, executionContext = {}) {
5482
5935
  isError: parsed.mode === "unknown"
5483
5936
  };
5484
5937
  }
5485
- if (parsed.mode === "price-storage-invalid") {
5938
+ if (parsed.mode === "arg-parse-failure") {
5486
5939
  return {
5487
- text: `Cannot price storage: required arguments are ${REQUIRED_PRICE_STORAGE}.`,
5940
+ text: [
5941
+ "Could not parse command arguments.",
5942
+ ...parsed.errors.map((e) => `- ${e}`),
5943
+ ...parsed.warnings.length > 0 ? ["", "Notes:", ...parsed.warnings.map((w) => `- ${w}`)] : [],
5944
+ "",
5945
+ "Accepted formats:",
5946
+ "- key:value",
5947
+ "- key=value",
5948
+ "- --key value"
5949
+ ].join("\n"),
5488
5950
  isError: true
5489
5951
  };
5490
5952
  }
5491
- if (parsed.mode === "backup-invalid") {
5953
+ if (parsed.mode === "price-storage-invalid") {
5492
5954
  return {
5493
- text: "Cannot build storage object",
5955
+ text: `Cannot price storage: required arguments are ${REQUIRED_PRICE_STORAGE}.`,
5494
5956
  isError: true
5495
5957
  };
5496
5958
  }
@@ -5859,7 +6321,7 @@ ${operation.result_text}` : meta;
5859
6321
  args: syncArgs,
5860
6322
  timeoutSeconds: parsed.timeoutSeconds,
5861
6323
  requestedBy: {
5862
- pluginCommand: "mnemospark_cloud",
6324
+ pluginCommand: "mnemospark",
5863
6325
  chatId: ctx.channel,
5864
6326
  senderId: ctx.senderId
5865
6327
  }
@@ -6042,7 +6504,7 @@ ${operation.result_text}` : meta;
6042
6504
  `orchestrator: subagent`,
6043
6505
  `subagent-session-id: ${dispatchResult.sessionId}`,
6044
6506
  timeoutSeconds ? `timeout-seconds: ${timeoutSeconds}` : null,
6045
- `Use /mnemospark_cloud op-status --operation-id ${operationId}`
6507
+ `Use /mnemospark cloud op-status --operation-id ${operationId}`
6046
6508
  ].filter((line) => Boolean(line)).join("\n")
6047
6509
  };
6048
6510
  } catch (dispatchError) {
@@ -6145,7 +6607,7 @@ operation-id: ${operationId}`,
6145
6607
  text: [
6146
6608
  `Operation started in background. operation-id: ${operationId}`,
6147
6609
  `orchestrator: inline`,
6148
- `Use /mnemospark_cloud op-status --operation-id ${operationId}`
6610
+ `Use /mnemospark cloud op-status --operation-id ${operationId}`
6149
6611
  ].join("\n")
6150
6612
  };
6151
6613
  }
@@ -6315,7 +6777,7 @@ operation-id: ${operationId}`,
6315
6777
  const loggedQuote = await datastore.findQuoteById(parsed.uploadRequest.quote_id);
6316
6778
  if (!loggedQuote) {
6317
6779
  return {
6318
- 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).",
6780
+ 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).",
6319
6781
  isError: true
6320
6782
  };
6321
6783
  }
@@ -6331,7 +6793,7 @@ operation-id: ${operationId}`,
6331
6793
  );
6332
6794
  if (!dbFriendly?.trim()) {
6333
6795
  return {
6334
- text: "Cannot upload storage object: no friendly name in local SQLite for this object-id. Run /mnemospark_cloud backup with --name first.",
6796
+ text: "Cannot upload storage object: no friendly name in local SQLite for this object-id. Run /mnemospark cloud backup with --name first.",
6335
6797
  isError: true
6336
6798
  };
6337
6799
  }
@@ -6357,7 +6819,7 @@ operation-id: ${operationId}`,
6357
6819
  archiveStats = await stat2(archivePath);
6358
6820
  } catch {
6359
6821
  return {
6360
- text: `Cannot upload storage object: local archive not found at ${archivePath}. Run /mnemospark_cloud backup first.`,
6822
+ text: `Cannot upload storage object: local archive not found at ${archivePath}. Run /mnemospark cloud backup first.`,
6361
6823
  isError: true
6362
6824
  };
6363
6825
  }
@@ -6884,6 +7346,186 @@ operation-id: ${operationId}`,
6884
7346
  };
6885
7347
  }
6886
7348
 
7349
+ // src/mnemospark-handler.ts
7350
+ var MNEMOSPARK_ROOT_HELP_TEXT = [
7351
+ "\u2601\uFE0F **mnemospark - Wallet and go.** \u{1F499}",
7352
+ "",
7353
+ "**Syntax:** `/mnemospark cloud \u2026` or `/mnemospark wallet \u2026`",
7354
+ "Arguments may use `key:value`, `key=value`, or `--key value`. Optional verbose markers: `cloud:true`, `price-storage:true`, etc. (same as bare words).",
7355
+ "Aliases include `wallet:` \u2192 wallet-address, `object:` \u2192 object-id, `quote:` \u2192 quote-id (see `/mnemospark cloud help`).",
7356
+ "",
7357
+ "**Cloud storage** \u2014 full reference:",
7358
+ "\u2022 `/mnemospark cloud help`",
7359
+ "",
7360
+ "**Wallet** \u2014 status:",
7361
+ "\u2022 `/mnemospark wallet`",
7362
+ "\u2022 `/mnemospark wallet help` \u2014 commands and funding link"
7363
+ ].join("\n");
7364
+ var MNEMOSPARK_WALLET_HELP_TEXT = (address) => [
7365
+ "\u2601\uFE0F **mnemospark Wallet**",
7366
+ "",
7367
+ "**Commands:**",
7368
+ "\u2022 `/mnemospark wallet` \u2014 Show address, balance, and key file path",
7369
+ "\u2022 `/mnemospark wallet help` \u2014 This message",
7370
+ "\u2022 `/mnemospark wallet export` \u2014 Export private key for backup (sensitive)",
7371
+ "",
7372
+ `**Fund with USDC on Base:** https://basescan.org/address/${address}`
7373
+ ].join("\n");
7374
+ var defaultCloudCommandHandler;
7375
+ function getDefaultCloudCommandHandler() {
7376
+ defaultCloudCommandHandler ??= createCloudCommand().handler;
7377
+ return defaultCloudCommandHandler;
7378
+ }
7379
+ var NO_WALLET_FOUND_TEXT = "No mnemospark wallet found. Run `openclaw plugins install mnemospark`.";
7380
+ function resolveWalletFileSync() {
7381
+ try {
7382
+ if (!existsSync(WALLET_FILE)) {
7383
+ return null;
7384
+ }
7385
+ const walletKey = readFileSync(WALLET_FILE, "utf-8").trim();
7386
+ if (!walletKey.startsWith("0x") || walletKey.length !== 66) {
7387
+ return null;
7388
+ }
7389
+ const account = privateKeyToAccount6(walletKey);
7390
+ const address = account.address.replace(/\s/g, "");
7391
+ if (!address) {
7392
+ return null;
7393
+ }
7394
+ return { walletKey, address };
7395
+ } catch {
7396
+ return null;
7397
+ }
7398
+ }
7399
+ async function runMnemosparkSlashHandler(ctx, options) {
7400
+ const route = routeMnemosparkArgs(ctx.args);
7401
+ if (route.kind === "root-help") {
7402
+ return { text: MNEMOSPARK_ROOT_HELP_TEXT };
7403
+ }
7404
+ if (route.kind === "error") {
7405
+ return { text: route.message, isError: true };
7406
+ }
7407
+ if (route.kind === "cloud") {
7408
+ const cloudCommandHandler = options?.cloudCommandHandler ?? getDefaultCloudCommandHandler();
7409
+ return cloudCommandHandler({ ...ctx, args: route.rest });
7410
+ }
7411
+ return handleWalletSlash(route.rest);
7412
+ }
7413
+ async function handleWalletSlash(rest) {
7414
+ const trimmed = rest.trim();
7415
+ if (!trimmed) {
7416
+ return buildWalletStatusResponse();
7417
+ }
7418
+ const { first, rest: afterFirst } = firstTokenAndRest(trimmed);
7419
+ const parsed = parseVerboseToken(first);
7420
+ if (!parsed.ok) {
7421
+ return {
7422
+ text: `Invalid token "${first}". Use name:true only with value true.`,
7423
+ isError: true
7424
+ };
7425
+ }
7426
+ if (parsed.name === "help") {
7427
+ if (afterFirst.trim()) {
7428
+ return {
7429
+ text: "Unexpected extra arguments after `help`. Use `/mnemospark wallet help` alone.",
7430
+ isError: true
7431
+ };
7432
+ }
7433
+ return buildWalletHelpResponse();
7434
+ }
7435
+ if (parsed.name === "export") {
7436
+ if (afterFirst.trim()) {
7437
+ return {
7438
+ text: "Unexpected extra arguments after `export`. Use `/mnemospark wallet export` alone.",
7439
+ isError: true
7440
+ };
7441
+ }
7442
+ return buildWalletExportResponse();
7443
+ }
7444
+ if (parsed.name === "status") {
7445
+ return buildWalletStatusResponse();
7446
+ }
7447
+ return {
7448
+ text: `Unknown wallet command "${parsed.name}". Try \`/mnemospark wallet help\`.`,
7449
+ isError: true
7450
+ };
7451
+ }
7452
+ async function buildWalletStatusResponse() {
7453
+ const wallet = resolveWalletFileSync();
7454
+ if (!wallet) {
7455
+ return {
7456
+ text: NO_WALLET_FOUND_TEXT,
7457
+ isError: true
7458
+ };
7459
+ }
7460
+ const { address } = wallet;
7461
+ let balanceText = "Balance: (checking...)";
7462
+ try {
7463
+ const monitor = new BalanceMonitor(address);
7464
+ const balance = await monitor.checkBalance();
7465
+ balanceText = `Balance: ${balance.balanceUSD}`;
7466
+ } catch {
7467
+ balanceText = "Balance: (could not check)";
7468
+ }
7469
+ return {
7470
+ text: [
7471
+ "\u2601\uFE0F **mnemospark Wallet**",
7472
+ "",
7473
+ `**Address:** \`${address}\``,
7474
+ `**${balanceText}**`,
7475
+ `**Key File:** \`${WALLET_FILE}\``,
7476
+ "",
7477
+ "**Commands:**",
7478
+ "\u2022 `/mnemospark wallet` \u2014 Show this status",
7479
+ "\u2022 `/mnemospark wallet help` \u2014 Commands and funding link",
7480
+ "\u2022 `/mnemospark wallet export` \u2014 Export private key for backup",
7481
+ "",
7482
+ `**Fund with USDC on Base:** https://basescan.org/address/${address}`
7483
+ ].join("\n")
7484
+ };
7485
+ }
7486
+ async function buildWalletHelpResponse() {
7487
+ const wallet = resolveWalletFileSync();
7488
+ if (!wallet) {
7489
+ return {
7490
+ text: NO_WALLET_FOUND_TEXT,
7491
+ isError: true
7492
+ };
7493
+ }
7494
+ const { address } = wallet;
7495
+ return { text: MNEMOSPARK_WALLET_HELP_TEXT(address) };
7496
+ }
7497
+ async function buildWalletExportResponse() {
7498
+ const wallet = resolveWalletFileSync();
7499
+ if (!wallet) {
7500
+ return {
7501
+ text: NO_WALLET_FOUND_TEXT,
7502
+ isError: true
7503
+ };
7504
+ }
7505
+ const { walletKey, address } = wallet;
7506
+ const addressDisplay = address.replace(/\s/g, "");
7507
+ const keyDisplay = walletKey.replace(/\s/g, "");
7508
+ return {
7509
+ text: [
7510
+ "\u2601\uFE0F **mnemospark Wallet Export**",
7511
+ "",
7512
+ "\u26A0\uFE0F **SECURITY WARNING**: Your private key controls your wallet funds.",
7513
+ "Never share this key. Anyone with this key can spend your USDC.",
7514
+ "",
7515
+ `**Address:** \`${addressDisplay}\``,
7516
+ "",
7517
+ "**Private Key:**",
7518
+ `\`${keyDisplay}\``,
7519
+ "",
7520
+ "**To restore on a new machine:**",
7521
+ "1. Set the environment variable before running OpenClaw:",
7522
+ ` \`export MNEMOSPARK_WALLET_KEY=${keyDisplay}\``,
7523
+ "2. Or save to file:",
7524
+ ` \`mkdir -p ~/.openclaw/mnemospark/wallet && echo "${keyDisplay}" > ~/.openclaw/mnemospark/wallet/wallet.key && chmod 600 ~/.openclaw/mnemospark/wallet/wallet.key\``
7525
+ ].join("\n")
7526
+ };
7527
+ }
7528
+
6887
7529
  // src/retry.ts
6888
7530
  var DEFAULT_RETRY_CONFIG = {
6889
7531
  maxRetries: 2,
@@ -6991,84 +7633,6 @@ async function startProxyInBackground(api) {
6991
7633
  api.logger.info(`Wallet: ${address} | Balance: (checking...)`);
6992
7634
  });
6993
7635
  }
6994
- async function createWalletCommand() {
6995
- return {
6996
- name: "mnemospark_wallet",
6997
- nativeNames: {
6998
- default: "mnemospark_wallet"
6999
- },
7000
- description: "Show mnemospark wallet info or export private key for backup",
7001
- acceptsArgs: true,
7002
- requireAuth: true,
7003
- handler: async (ctx) => {
7004
- const subcommand = ctx.args?.trim().toLowerCase() || "status";
7005
- let walletKey;
7006
- let address;
7007
- try {
7008
- if (existsSync(WALLET_FILE)) {
7009
- walletKey = readFileSync(WALLET_FILE, "utf-8").trim();
7010
- if (walletKey.startsWith("0x") && walletKey.length === 66) {
7011
- const account = privateKeyToAccount6(walletKey);
7012
- address = account.address.replace(/\s/g, "");
7013
- }
7014
- }
7015
- } catch {
7016
- }
7017
- if (!walletKey || !address) {
7018
- return {
7019
- text: "No mnemospark wallet found. Run `openclaw plugins install mnemospark`.",
7020
- isError: true
7021
- };
7022
- }
7023
- if (subcommand === "export") {
7024
- const addressDisplay = address.replace(/\s/g, "");
7025
- const keyDisplay = walletKey.replace(/\s/g, "");
7026
- return {
7027
- text: [
7028
- "\u2601\uFE0F **mnemospark Wallet Export**",
7029
- "",
7030
- "\u26A0\uFE0F **SECURITY WARNING**: Your private key controls your wallet funds.",
7031
- "Never share this key. Anyone with this key can spend your USDC.",
7032
- "",
7033
- `**Address:** \`${addressDisplay}\``,
7034
- "",
7035
- "**Private Key:**",
7036
- `\`${keyDisplay}\``,
7037
- "",
7038
- "**To restore on a new machine:**",
7039
- "1. Set the environment variable before running OpenClaw:",
7040
- ` \`export MNEMOSPARK_WALLET_KEY=${keyDisplay}\``,
7041
- "2. Or save to file:",
7042
- ` \`mkdir -p ~/.openclaw/mnemospark/wallet && echo "${keyDisplay}" > ~/.openclaw/mnemospark/wallet/wallet.key && chmod 600 ~/.openclaw/mnemospark/wallet/wallet.key\``
7043
- ].join("\n")
7044
- };
7045
- }
7046
- let balanceText = "Balance: (checking...)";
7047
- try {
7048
- const monitor = new BalanceMonitor(address);
7049
- const balance = await monitor.checkBalance();
7050
- balanceText = `Balance: ${balance.balanceUSD}`;
7051
- } catch {
7052
- balanceText = "Balance: (could not check)";
7053
- }
7054
- return {
7055
- text: [
7056
- "\u2601\uFE0F **mnemospark Wallet**",
7057
- "",
7058
- `**Address:** \`${address}\``,
7059
- `**${balanceText}**`,
7060
- `**Key File:** \`${WALLET_FILE}\``,
7061
- "",
7062
- "**Commands:**",
7063
- "\u2022 `/mnemospark_wallet` - Show this status",
7064
- "\u2022 `/mnemospark_wallet export` - Export private key for backup",
7065
- "",
7066
- `**Fund with USDC on Base:** https://basescan.org/address/${address}`
7067
- ].join("\n")
7068
- };
7069
- }
7070
- };
7071
- }
7072
7636
  var plugin = {
7073
7637
  id: "mnemospark",
7074
7638
  name: "mnemospark",
@@ -7083,18 +7647,27 @@ var plugin = {
7083
7647
  if (isCompletionMode()) {
7084
7648
  return;
7085
7649
  }
7086
- createWalletCommand().then((walletCommand) => {
7087
- api.registerCommand(walletCommand);
7088
- }).catch((err) => {
7089
- api.logger.warn(
7090
- `Failed to register /mnemospark_wallet command: ${err instanceof Error ? err.message : String(err)}`
7091
- );
7092
- });
7093
7650
  try {
7094
- api.registerCommand(createCloudCommand());
7651
+ api.registerCommand({
7652
+ name: "mnemospark",
7653
+ nativeNames: {
7654
+ default: "mnemospark"
7655
+ },
7656
+ description: "mnemospark wallet and cloud storage commands",
7657
+ acceptsArgs: true,
7658
+ requireAuth: true,
7659
+ handler: async (ctx) => {
7660
+ try {
7661
+ return await runMnemosparkSlashHandler(ctx);
7662
+ } catch (err) {
7663
+ const message = err instanceof Error ? err.message : typeof err === "string" ? err : "An unexpected error occurred";
7664
+ return { text: message.trim() || "An unexpected error occurred", isError: true };
7665
+ }
7666
+ }
7667
+ });
7095
7668
  } catch (err) {
7096
7669
  api.logger.warn(
7097
- `Failed to register /mnemospark_cloud command: ${err instanceof Error ? err.message : String(err)}`
7670
+ `Failed to register /mnemospark command: ${err instanceof Error ? err.message : String(err)}`
7098
7671
  );
7099
7672
  }
7100
7673
  api.registerService({
@@ -7145,6 +7718,7 @@ export {
7145
7718
  isInsufficientFundsError,
7146
7719
  isRetryable,
7147
7720
  isRpcError,
7721
+ runMnemosparkSlashHandler,
7148
7722
  startProxy
7149
7723
  };
7150
7724
  //# sourceMappingURL=index.js.map