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/README.md +8 -8
- package/dist/cli.js +790 -145
- package/dist/cli.js.map +1 -1
- package/dist/index.d.ts +10 -2
- package/dist/index.js +787 -213
- package/dist/index.js.map +1 -1
- package/openclaw.plugin.json +1 -1
- package/package.json +1 -1
- package/skills/mnemospark/SKILL.md +14 -14
- package/skills/mnemospark/references/commands.md +7 -5
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 /
|
|
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 /
|
|
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 /
|
|
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 /
|
|
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 /
|
|
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 /
|
|
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 /
|
|
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 /
|
|
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 /
|
|
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 /
|
|
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 /
|
|
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 /
|
|
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 /
|
|
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/
|
|
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 `/
|
|
4269
|
+
"\u2022 `/mnemospark cloud` or `/mnemospark cloud help` \u2014 show this message (equivalent: `/mnemospark cloud:true help:true`)",
|
|
3864
4270
|
"",
|
|
3865
|
-
"\u2022 `/
|
|
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 `/
|
|
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 `/
|
|
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 `/
|
|
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 `/
|
|
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 `/
|
|
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 `/
|
|
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 `/
|
|
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 `/
|
|
3911
|
-
"\u2022 `/
|
|
3912
|
-
"\u2022 `/
|
|
3913
|
-
"\u2022 `/
|
|
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
|
|
4093
|
-
const
|
|
4094
|
-
const
|
|
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 =
|
|
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
|
|
4109
|
-
|
|
4110
|
-
|
|
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
|
|
4129
|
-
if (!
|
|
4130
|
-
return {
|
|
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
|
|
4148
|
-
if (!
|
|
4149
|
-
return {
|
|
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
|
|
4176
|
-
if (!
|
|
4177
|
-
return {
|
|
4178
|
-
|
|
4179
|
-
|
|
4180
|
-
|
|
4181
|
-
|
|
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
|
|
4224
|
-
if (!
|
|
4225
|
-
return {
|
|
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
|
|
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
|
|
4260
|
-
if (!
|
|
4261
|
-
return {
|
|
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
|
|
4284
|
-
if (!
|
|
4285
|
-
return {
|
|
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
|
|
4299
|
-
|
|
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
|
|
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 /
|
|
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 `/
|
|
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 = `/
|
|
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 = `/
|
|
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 = `/
|
|
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: "
|
|
5608
|
+
name: "mnemospark",
|
|
5156
5609
|
nativeNames: {
|
|
5157
|
-
default: "
|
|
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 === "
|
|
5938
|
+
if (parsed.mode === "arg-parse-failure") {
|
|
5486
5939
|
return {
|
|
5487
|
-
text:
|
|
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 === "
|
|
5953
|
+
if (parsed.mode === "price-storage-invalid") {
|
|
5492
5954
|
return {
|
|
5493
|
-
text:
|
|
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: "
|
|
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 /
|
|
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 /
|
|
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 /
|
|
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 /
|
|
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 /
|
|
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(
|
|
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 /
|
|
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
|