mnemospark 1.2.0 → 1.2.2
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 +48 -12
- package/dist/cli.js +135 -41
- package/dist/cli.js.map +1 -1
- package/dist/index.js +135 -41
- package/dist/index.js.map +1 -1
- package/openclaw.plugin.json +1 -1
- package/package.json +1 -1
- package/skills/mnemospark/SKILL.md +4 -2
- package/skills/mnemospark/references/commands.md +1 -1
- package/scripts/README.md +0 -55
- package/scripts/install-aws-cli.sh +0 -28
- package/scripts/install-jq.sh +0 -13
- package/scripts/install-pnpm.sh +0 -20
- package/scripts/reinstall.sh +0 -102
- package/scripts/uninstall.sh +0 -67
- package/scripts/verify-dev-tools.sh +0 -56
package/dist/index.js
CHANGED
|
@@ -202,6 +202,10 @@ var PROXY_PORT = (() => {
|
|
|
202
202
|
return DEFAULT_PORT;
|
|
203
203
|
})();
|
|
204
204
|
var MNEMOSPARK_BACKEND_API_BASE_URL = (process.env.MNEMOSPARK_BACKEND_API_BASE_URL ?? "").trim();
|
|
205
|
+
var MNEMOSPARK_PROXY_VERBOSE_404 = (() => {
|
|
206
|
+
const v = process.env.MNEMOSPARK_PROXY_VERBOSE_404?.trim().toLowerCase();
|
|
207
|
+
return v === "1" || v === "true" || v === "yes";
|
|
208
|
+
})();
|
|
205
209
|
|
|
206
210
|
// src/mnemospark-request-sign.ts
|
|
207
211
|
import { getAddress } from "viem";
|
|
@@ -1778,8 +1782,15 @@ async function readProxyJsonBody(req) {
|
|
|
1778
1782
|
}
|
|
1779
1783
|
return JSON.parse(bodyText);
|
|
1780
1784
|
}
|
|
1785
|
+
function createJsonResponseHeaders() {
|
|
1786
|
+
return {
|
|
1787
|
+
"Content-Type": "application/json",
|
|
1788
|
+
"X-Content-Type-Options": "nosniff",
|
|
1789
|
+
"Cache-Control": "no-store"
|
|
1790
|
+
};
|
|
1791
|
+
}
|
|
1781
1792
|
function sendJson(res, status, body) {
|
|
1782
|
-
res.writeHead(status,
|
|
1793
|
+
res.writeHead(status, createJsonResponseHeaders());
|
|
1783
1794
|
res.end(JSON.stringify(body));
|
|
1784
1795
|
}
|
|
1785
1796
|
function logProxyEvent(level, event, fields = {}) {
|
|
@@ -1839,7 +1850,9 @@ function isAlreadySettledConflict(status, bodyText) {
|
|
|
1839
1850
|
}
|
|
1840
1851
|
function createBackendForwardHeaders(response) {
|
|
1841
1852
|
const responseHeaders = {
|
|
1842
|
-
"Content-Type": response.contentType
|
|
1853
|
+
"Content-Type": response.contentType,
|
|
1854
|
+
"X-Content-Type-Options": "nosniff",
|
|
1855
|
+
"Cache-Control": "no-store"
|
|
1843
1856
|
};
|
|
1844
1857
|
if (response.paymentRequired) {
|
|
1845
1858
|
responseHeaders["PAYMENT-REQUIRED"] = response.paymentRequired;
|
|
@@ -1877,6 +1890,10 @@ function createWalletRequiredBody() {
|
|
|
1877
1890
|
message: "wallet required for storage endpoints"
|
|
1878
1891
|
});
|
|
1879
1892
|
}
|
|
1893
|
+
function sendWalletRequired(res) {
|
|
1894
|
+
res.writeHead(400, createJsonResponseHeaders());
|
|
1895
|
+
res.end(createWalletRequiredBody());
|
|
1896
|
+
}
|
|
1880
1897
|
function getProxyPort() {
|
|
1881
1898
|
return PROXY_PORT;
|
|
1882
1899
|
}
|
|
@@ -1976,6 +1993,18 @@ async function startProxy(options) {
|
|
|
1976
1993
|
}
|
|
1977
1994
|
correlation.wallet_address = requestPayload.wallet_address;
|
|
1978
1995
|
correlation.object_id = requestPayload.object_id;
|
|
1996
|
+
if (requestPayload.wallet_address.toLowerCase() !== proxyWalletAddressLower) {
|
|
1997
|
+
logProxyEvent("warn", "proxy_price_storage_wallet_mismatch", {
|
|
1998
|
+
request_wallet: requestPayload.wallet_address,
|
|
1999
|
+
proxy_wallet: account.address
|
|
2000
|
+
});
|
|
2001
|
+
emitProxyTerminalFromStatus(correlation, 403, { reason: "wallet_mismatch" });
|
|
2002
|
+
sendJson(res, 403, {
|
|
2003
|
+
error: "wallet_proof_invalid",
|
|
2004
|
+
message: "wallet proof invalid"
|
|
2005
|
+
});
|
|
2006
|
+
return;
|
|
2007
|
+
}
|
|
1979
2008
|
emitProxyEvent("storage.call", "start", correlation, { target: "price-storage" });
|
|
1980
2009
|
const walletSignature = await createBackendWalletSignature(
|
|
1981
2010
|
"POST",
|
|
@@ -1984,8 +2013,7 @@ async function startProxy(options) {
|
|
|
1984
2013
|
);
|
|
1985
2014
|
if (!walletSignature) {
|
|
1986
2015
|
logProxyEvent("warn", "proxy_price_storage_wallet_signature_missing");
|
|
1987
|
-
res
|
|
1988
|
-
res.end(createWalletRequiredBody());
|
|
2016
|
+
sendWalletRequired(res);
|
|
1989
2017
|
emitProxyTerminalFromStatus(correlation, 400, { reason: "wallet_signature_missing" });
|
|
1990
2018
|
return;
|
|
1991
2019
|
}
|
|
@@ -2134,8 +2162,7 @@ async function startProxy(options) {
|
|
|
2134
2162
|
);
|
|
2135
2163
|
if (!walletSignature) {
|
|
2136
2164
|
logProxyEvent("warn", "proxy_payment_settle_wallet_signature_missing");
|
|
2137
|
-
res
|
|
2138
|
-
res.end(createWalletRequiredBody());
|
|
2165
|
+
sendWalletRequired(res);
|
|
2139
2166
|
emitProxyTerminalFromStatus(correlation, 400, { reason: "wallet_signature_missing" });
|
|
2140
2167
|
return;
|
|
2141
2168
|
}
|
|
@@ -2243,8 +2270,7 @@ async function startProxy(options) {
|
|
|
2243
2270
|
);
|
|
2244
2271
|
if (!walletSignature) {
|
|
2245
2272
|
logProxyEvent("warn", "proxy_upload_wallet_signature_missing");
|
|
2246
|
-
res
|
|
2247
|
-
res.end(createWalletRequiredBody());
|
|
2273
|
+
sendWalletRequired(res);
|
|
2248
2274
|
emitProxyTerminalFromStatus(correlation, 400, { reason: "wallet_signature_missing" });
|
|
2249
2275
|
return;
|
|
2250
2276
|
}
|
|
@@ -2291,8 +2317,7 @@ async function startProxy(options) {
|
|
|
2291
2317
|
);
|
|
2292
2318
|
if (!settleWalletSignature) {
|
|
2293
2319
|
logProxyEvent("warn", "proxy_upload_settle_signature_missing");
|
|
2294
|
-
res
|
|
2295
|
-
res.end(createWalletRequiredBody());
|
|
2320
|
+
sendWalletRequired(res);
|
|
2296
2321
|
emitProxyTerminalFromStatus(correlation, 400, { reason: "settle_signature_missing" });
|
|
2297
2322
|
return;
|
|
2298
2323
|
}
|
|
@@ -2432,8 +2457,7 @@ async function startProxy(options) {
|
|
|
2432
2457
|
);
|
|
2433
2458
|
if (!walletSignature) {
|
|
2434
2459
|
logProxyEvent("warn", "proxy_upload_confirm_wallet_signature_missing");
|
|
2435
|
-
res
|
|
2436
|
-
res.end(createWalletRequiredBody());
|
|
2460
|
+
sendWalletRequired(res);
|
|
2437
2461
|
emitProxyTerminalFromStatus(correlation, 400, { reason: "wallet_signature_missing" });
|
|
2438
2462
|
return;
|
|
2439
2463
|
}
|
|
@@ -2527,8 +2551,7 @@ async function startProxy(options) {
|
|
|
2527
2551
|
);
|
|
2528
2552
|
if (!walletSignature) {
|
|
2529
2553
|
logProxyEvent("warn", "proxy_ls_wallet_signature_missing");
|
|
2530
|
-
res
|
|
2531
|
-
res.end(createWalletRequiredBody());
|
|
2554
|
+
sendWalletRequired(res);
|
|
2532
2555
|
emitProxyTerminalFromStatus(correlation, 400, { reason: "wallet_signature_missing" });
|
|
2533
2556
|
return;
|
|
2534
2557
|
}
|
|
@@ -2622,8 +2645,7 @@ async function startProxy(options) {
|
|
|
2622
2645
|
);
|
|
2623
2646
|
if (!walletSignature) {
|
|
2624
2647
|
logProxyEvent("warn", "proxy_download_wallet_signature_missing");
|
|
2625
|
-
res
|
|
2626
|
-
res.end(createWalletRequiredBody());
|
|
2648
|
+
sendWalletRequired(res);
|
|
2627
2649
|
emitProxyTerminalFromStatus(correlation, 400, { reason: "wallet_signature_missing" });
|
|
2628
2650
|
return;
|
|
2629
2651
|
}
|
|
@@ -2739,8 +2761,7 @@ async function startProxy(options) {
|
|
|
2739
2761
|
);
|
|
2740
2762
|
if (!walletSignature) {
|
|
2741
2763
|
logProxyEvent("warn", "proxy_delete_wallet_signature_missing");
|
|
2742
|
-
res
|
|
2743
|
-
res.end(createWalletRequiredBody());
|
|
2764
|
+
sendWalletRequired(res);
|
|
2744
2765
|
emitProxyTerminalFromStatus(correlation, 400, { reason: "wallet_signature_missing" });
|
|
2745
2766
|
return;
|
|
2746
2767
|
}
|
|
@@ -2810,10 +2831,14 @@ async function startProxy(options) {
|
|
|
2810
2831
|
sendJson(res, 200, response);
|
|
2811
2832
|
return;
|
|
2812
2833
|
}
|
|
2813
|
-
|
|
2814
|
-
|
|
2815
|
-
|
|
2816
|
-
|
|
2834
|
+
if (MNEMOSPARK_PROXY_VERBOSE_404) {
|
|
2835
|
+
sendJson(res, 404, {
|
|
2836
|
+
error: "Not found",
|
|
2837
|
+
message: "Supported paths: /health and /mnemospark/* storage endpoints"
|
|
2838
|
+
});
|
|
2839
|
+
} else {
|
|
2840
|
+
sendJson(res, 404, { error: "Not found" });
|
|
2841
|
+
}
|
|
2817
2842
|
});
|
|
2818
2843
|
const tryListen = (attempt) => {
|
|
2819
2844
|
return new Promise((resolveAttempt, rejectAttempt) => {
|
|
@@ -4159,7 +4184,8 @@ var priceStorageSchema = {
|
|
|
4159
4184
|
args: [
|
|
4160
4185
|
{ name: "wallet-address", aliases: ["wallet"], required: true },
|
|
4161
4186
|
{ name: "object-id", aliases: ["object"], required: true },
|
|
4162
|
-
|
|
4187
|
+
// Optional: omit when the object exists in local SQLite after backup; CLI resolves sha256 from state.db.
|
|
4188
|
+
{ name: "object-id-hash", aliases: ["hash"] },
|
|
4163
4189
|
{ name: "gb", required: true },
|
|
4164
4190
|
{ name: "provider", required: true },
|
|
4165
4191
|
{ name: "region", required: true }
|
|
@@ -4251,7 +4277,7 @@ var TAR_OVERHEAD_BYTES = 10 * 1024 * 1024;
|
|
|
4251
4277
|
var QUOTE_VALIDITY_USER_NOTE = "Quotes are valid for one hour. Please run price-storage again if you need a new quote.";
|
|
4252
4278
|
var MNEMOSPARK_SUPPORT_EMAIL = "pluggedin@mnemospark.ai";
|
|
4253
4279
|
var CLOUD_HELP_FOOTER_STATE = "Local state: mnemospark records quotes, objects, payments, cron jobs, friendly names, and operation metadata in ~/.openclaw/mnemospark/state.db (SQLite). For troubleshooting and correlation, commands and the HTTP proxy append structured JSON lines to ~/.openclaw/mnemospark/events.jsonl. Monthly storage billing jobs are listed in ~/.openclaw/cron/jobs.json for OpenClaw scheduling.";
|
|
4254
|
-
var REQUIRED_PRICE_STORAGE = "wallet-address:, object-id:, object-id-hash
|
|
4280
|
+
var REQUIRED_PRICE_STORAGE = "wallet-address:, object-id:, gb:, provider:, region: (object-id-hash: optional if the object exists in local SQLite after backup)";
|
|
4255
4281
|
var REQUIRED_UPLOAD = "quote-id:, wallet-address:, object-id:, object-id-hash:";
|
|
4256
4282
|
var REQUIRED_BACKUP = "<file|directory> and name:<friendly-name>";
|
|
4257
4283
|
var REQUIRED_PAYMENT_SETTLE = "wallet-address: and (quote-id: | renewal:true with object-key:)";
|
|
@@ -4281,10 +4307,10 @@ var CLOUD_HELP_TEXT = [
|
|
|
4281
4307
|
" 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.",
|
|
4282
4308
|
" Required: " + REQUIRED_BACKUP,
|
|
4283
4309
|
"",
|
|
4284
|
-
"\u2022 `/mnemospark cloud price-storage wallet-address:<addr> object-id:<id> object-id-hash:<hash> gb:<gb> provider:aws region:us-east-1`",
|
|
4285
|
-
" Purpose: request a storage quote before upload (defaults shown; override `provider:` / `region:` for other regions).",
|
|
4310
|
+
"\u2022 `/mnemospark cloud price-storage wallet-address:<addr> object-id:<id> [object-id-hash:<hash>] gb:<gb> provider:aws region:us-east-1`",
|
|
4311
|
+
" Purpose: request a storage quote before upload (defaults shown; override `provider:` / `region:` for other regions). Omit `object-id-hash:` when the object is already in local SQLite (e.g. after backup); mnemospark reads sha256 from ~/.openclaw/mnemospark/state.db.",
|
|
4286
4312
|
" Required: " + REQUIRED_PRICE_STORAGE,
|
|
4287
|
-
" Shorter: `wallet:\u2026 object:\u2026 hash:\u2026 gb:\u2026 provider:\u2026 region:\u2026`",
|
|
4313
|
+
" Shorter: `wallet:\u2026 object:\u2026 [hash:\u2026] gb:\u2026 provider:\u2026 region:\u2026`",
|
|
4288
4314
|
"",
|
|
4289
4315
|
"\u2022 `/mnemospark cloud upload quote-id:<quote-id> wallet-address:<addr> object-id:<id> object-id-hash:<hash> [name:<friendly-name>] [async:true] [orchestrator:<inline|subagent>] [timeout-seconds:<n>]`",
|
|
4290
4316
|
" Purpose: upload an encrypted object using a valid quote-id.",
|
|
@@ -4495,6 +4521,41 @@ function stripAsyncControlFlags(args) {
|
|
|
4495
4521
|
function mergeArgParseWarnings(a, b) {
|
|
4496
4522
|
return [...a, ...b];
|
|
4497
4523
|
}
|
|
4524
|
+
async function resolvePriceStorageHashFromDatastore(datastore, partial) {
|
|
4525
|
+
await datastore.ensureReady();
|
|
4526
|
+
const row = await datastore.findObjectById(partial.object_id.trim());
|
|
4527
|
+
const wallet = partial.wallet_address.trim().toLowerCase();
|
|
4528
|
+
if (!row) {
|
|
4529
|
+
return {
|
|
4530
|
+
ok: false,
|
|
4531
|
+
message: "Cannot resolve object-id-hash: no object found in local SQLite for this object-id. Run backup first, or pass --object-id-hash explicitly."
|
|
4532
|
+
};
|
|
4533
|
+
}
|
|
4534
|
+
if (row.wallet_address.trim().toLowerCase() !== wallet) {
|
|
4535
|
+
return {
|
|
4536
|
+
ok: false,
|
|
4537
|
+
message: "Cannot resolve object-id-hash: wallet-address does not match the object record in ~/.openclaw/mnemospark/state.db."
|
|
4538
|
+
};
|
|
4539
|
+
}
|
|
4540
|
+
const sha = row.sha256?.trim();
|
|
4541
|
+
if (!sha) {
|
|
4542
|
+
return {
|
|
4543
|
+
ok: false,
|
|
4544
|
+
message: "Cannot resolve object-id-hash: local object record has no sha256 yet. Run backup first, or pass --object-id-hash explicitly."
|
|
4545
|
+
};
|
|
4546
|
+
}
|
|
4547
|
+
return {
|
|
4548
|
+
ok: true,
|
|
4549
|
+
request: {
|
|
4550
|
+
wallet_address: partial.wallet_address.trim(),
|
|
4551
|
+
object_id: partial.object_id.trim(),
|
|
4552
|
+
object_id_hash: sha.replace(/\s/g, ""),
|
|
4553
|
+
gb: partial.gb,
|
|
4554
|
+
provider: partial.provider.trim(),
|
|
4555
|
+
region: partial.region.trim()
|
|
4556
|
+
}
|
|
4557
|
+
};
|
|
4558
|
+
}
|
|
4498
4559
|
function parseCloudArgs(args) {
|
|
4499
4560
|
const trimmed = args?.trim() ?? "";
|
|
4500
4561
|
if (!trimmed) {
|
|
@@ -4564,18 +4625,38 @@ function parseCloudArgs(args) {
|
|
|
4564
4625
|
}
|
|
4565
4626
|
const flags = valuesToStringRecord(parsed.values);
|
|
4566
4627
|
const gb = Number.parseFloat(flags.gb ?? "");
|
|
4567
|
-
const
|
|
4568
|
-
|
|
4569
|
-
|
|
4570
|
-
|
|
4571
|
-
|
|
4572
|
-
|
|
4573
|
-
region: flags.region
|
|
4574
|
-
});
|
|
4575
|
-
if (!request) {
|
|
4628
|
+
const hashRaw = flags["object-id-hash"]?.trim();
|
|
4629
|
+
const walletAddress = flags["wallet-address"]?.trim();
|
|
4630
|
+
const objectId = flags["object-id"]?.trim();
|
|
4631
|
+
const provider = flags.provider?.trim();
|
|
4632
|
+
const region = flags.region?.trim();
|
|
4633
|
+
if (!walletAddress || !objectId || !provider || !region || !Number.isFinite(gb)) {
|
|
4576
4634
|
return { mode: "price-storage-invalid" };
|
|
4577
4635
|
}
|
|
4578
|
-
|
|
4636
|
+
if (hashRaw) {
|
|
4637
|
+
const request = parsePriceStorageQuoteRequest({
|
|
4638
|
+
wallet_address: walletAddress,
|
|
4639
|
+
object_id: objectId,
|
|
4640
|
+
object_id_hash: hashRaw,
|
|
4641
|
+
gb,
|
|
4642
|
+
provider,
|
|
4643
|
+
region
|
|
4644
|
+
});
|
|
4645
|
+
if (!request) {
|
|
4646
|
+
return { mode: "price-storage-invalid" };
|
|
4647
|
+
}
|
|
4648
|
+
return { mode: "price-storage", priceStorageRequest: request };
|
|
4649
|
+
}
|
|
4650
|
+
return {
|
|
4651
|
+
mode: "price-storage-resolve-hash",
|
|
4652
|
+
priceStoragePartial: {
|
|
4653
|
+
wallet_address: walletAddress,
|
|
4654
|
+
object_id: objectId,
|
|
4655
|
+
gb,
|
|
4656
|
+
provider,
|
|
4657
|
+
region
|
|
4658
|
+
}
|
|
4659
|
+
};
|
|
4579
4660
|
}
|
|
4580
4661
|
if (subcommand === "upload") {
|
|
4581
4662
|
const parsed = parseCommandArgs(rest, uploadSchema);
|
|
@@ -6712,10 +6793,23 @@ operation-id: ${operationId}`,
|
|
|
6712
6793
|
};
|
|
6713
6794
|
}
|
|
6714
6795
|
}
|
|
6715
|
-
if (parsed.mode === "price-storage") {
|
|
6796
|
+
if (parsed.mode === "price-storage" || parsed.mode === "price-storage-resolve-hash") {
|
|
6797
|
+
let priceStorageRequest;
|
|
6798
|
+
if (parsed.mode === "price-storage-resolve-hash") {
|
|
6799
|
+
const resolved = await resolvePriceStorageHashFromDatastore(
|
|
6800
|
+
datastore,
|
|
6801
|
+
parsed.priceStoragePartial
|
|
6802
|
+
);
|
|
6803
|
+
if (!resolved.ok) {
|
|
6804
|
+
return { text: resolved.message, isError: true };
|
|
6805
|
+
}
|
|
6806
|
+
priceStorageRequest = resolved.request;
|
|
6807
|
+
} else {
|
|
6808
|
+
priceStorageRequest = parsed.priceStorageRequest;
|
|
6809
|
+
}
|
|
6716
6810
|
const correlation = buildRequestCorrelation();
|
|
6717
6811
|
try {
|
|
6718
|
-
const quote = await requestPriceStorageQuote(
|
|
6812
|
+
const quote = await requestPriceStorageQuote(priceStorageRequest, {
|
|
6719
6813
|
...options.proxyQuoteOptions,
|
|
6720
6814
|
correlation
|
|
6721
6815
|
});
|
|
@@ -6773,8 +6867,8 @@ operation-id: ${operationId}`,
|
|
|
6773
6867
|
{
|
|
6774
6868
|
operation_id: correlation.operationId,
|
|
6775
6869
|
trace_id: correlation.traceId,
|
|
6776
|
-
wallet_address:
|
|
6777
|
-
object_id:
|
|
6870
|
+
wallet_address: priceStorageRequest.wallet_address,
|
|
6871
|
+
object_id: priceStorageRequest.object_id,
|
|
6778
6872
|
status: "failed"
|
|
6779
6873
|
},
|
|
6780
6874
|
mnemosparkHomeDir
|