agentcash 0.7.7 → 0.8.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 +1 -1
- package/dist/cjs/run-server.cjs +59 -28
- package/dist/esm/{chunk-5EMDWOPZ.js → chunk-4R52CY5Q.js} +23 -23
- package/dist/esm/chunk-4R52CY5Q.js.map +1 -0
- package/dist/esm/{chunk-2XMLNLWS.js → chunk-5ELAEV2M.js} +9 -7
- package/dist/esm/{chunk-2XMLNLWS.js.map → chunk-5ELAEV2M.js.map} +1 -1
- package/dist/esm/{chunk-SRV57WB2.js → chunk-62B3GENJ.js} +8 -6
- package/dist/esm/{chunk-SRV57WB2.js.map → chunk-62B3GENJ.js.map} +1 -1
- package/dist/esm/{chunk-TRPO7BKD.js → chunk-6PU3XK6I.js} +8 -228
- package/dist/esm/chunk-6PU3XK6I.js.map +1 -0
- package/dist/esm/{chunk-FLIDR6EU.js → chunk-7ZEXMJYJ.js} +5 -3
- package/dist/esm/{chunk-FLIDR6EU.js.map → chunk-7ZEXMJYJ.js.map} +1 -1
- package/dist/esm/{chunk-QPL3AVUK.js → chunk-C36IAW7R.js} +5 -3
- package/dist/esm/{chunk-QPL3AVUK.js.map → chunk-C36IAW7R.js.map} +1 -1
- package/dist/esm/chunk-FBPC4LGY.js +7 -0
- package/dist/esm/{chunk-PWYZN62H.js → chunk-OHA3LLUQ.js} +3 -3
- package/dist/esm/{chunk-24E2V3PA.js → chunk-UN3PRLTL.js} +15 -43
- package/dist/esm/chunk-UN3PRLTL.js.map +1 -0
- package/dist/esm/{chunk-JKCEMNAF.js → chunk-VR5I67WE.js} +2 -2
- package/dist/esm/{chunk-XNU6FVCF.js → chunk-W7DAJMFQ.js} +87 -19
- package/dist/esm/chunk-W7DAJMFQ.js.map +1 -0
- package/dist/esm/chunk-YQFK4U62.js +230 -0
- package/dist/esm/chunk-YQFK4U62.js.map +1 -0
- package/dist/esm/{chunk-X6KM3YLG.js → chunk-Z2R7VYNM.js} +11 -9
- package/dist/esm/{chunk-X6KM3YLG.js.map → chunk-Z2R7VYNM.js.map} +1 -1
- package/dist/esm/chunk-ZDDDU5O2.js +41 -0
- package/dist/esm/chunk-ZDDDU5O2.js.map +1 -0
- package/dist/esm/{chunk-KPEJO3KV.js → chunk-ZOVLXKVL.js} +8 -8
- package/dist/esm/chunk-ZOVLXKVL.js.map +1 -0
- package/dist/esm/{commands-IFU565JX.js → commands-YSOBBE4N.js} +625 -504
- package/dist/esm/commands-YSOBBE4N.js.map +1 -0
- package/dist/esm/{fund-N47ZRBRZ.js → fund-PRV53MDA.js} +7 -5
- package/dist/esm/{fund-N47ZRBRZ.js.map → fund-PRV53MDA.js.map} +1 -1
- package/dist/esm/index.js +65 -23
- package/dist/esm/index.js.map +1 -1
- package/dist/esm/{install-WJ645IFJ.js → install-QT37XD4R.js} +10 -8
- package/dist/esm/{install-WJ645IFJ.js.map → install-QT37XD4R.js.map} +1 -1
- package/dist/esm/lib.js +4 -3
- package/dist/esm/{server-VU3UAM7K.js → server-QARME5NA.js} +26 -19
- package/dist/esm/server-QARME5NA.js.map +1 -0
- package/dist/esm/shared/operations/index.js +7 -6
- package/dist/esm/shared/operations/index.js.map +1 -1
- package/package.json +1 -1
- package/dist/esm/chunk-24E2V3PA.js.map +0 -1
- package/dist/esm/chunk-5EMDWOPZ.js.map +0 -1
- package/dist/esm/chunk-KPEJO3KV.js.map +0 -1
- package/dist/esm/chunk-L7FC4RVF.js +0 -7
- package/dist/esm/chunk-TRPO7BKD.js.map +0 -1
- package/dist/esm/chunk-XNU6FVCF.js.map +0 -1
- package/dist/esm/commands-IFU565JX.js.map +0 -1
- package/dist/esm/server-VU3UAM7K.js.map +0 -1
- /package/dist/esm/{chunk-L7FC4RVF.js.map → chunk-FBPC4LGY.js.map} +0 -0
- /package/dist/esm/{chunk-PWYZN62H.js.map → chunk-OHA3LLUQ.js.map} +0 -0
- /package/dist/esm/{chunk-JKCEMNAF.js.map → chunk-VR5I67WE.js.map} +0 -0
|
@@ -1,51 +1,61 @@
|
|
|
1
1
|
import {
|
|
2
2
|
registerOrigin
|
|
3
|
-
} from "./chunk-
|
|
3
|
+
} from "./chunk-C36IAW7R.js";
|
|
4
4
|
import {
|
|
5
5
|
buildRequest,
|
|
6
6
|
createFetchWithAuth,
|
|
7
7
|
createFetchWithPayment,
|
|
8
8
|
requestSchema
|
|
9
|
-
} from "./chunk-
|
|
10
|
-
import
|
|
9
|
+
} from "./chunk-Z2R7VYNM.js";
|
|
10
|
+
import {
|
|
11
|
+
ORIGIN_METADATA,
|
|
12
|
+
PRIMARY_ORIGINS,
|
|
13
|
+
addUserOrigin,
|
|
14
|
+
loadUserOrigins,
|
|
15
|
+
removeUserOrigin
|
|
16
|
+
} from "./chunk-W7DAJMFQ.js";
|
|
11
17
|
import {
|
|
12
18
|
TEMPO_RPC_URL,
|
|
13
19
|
getOnboardingCta,
|
|
14
20
|
getWalletInfo,
|
|
15
21
|
submitErrorReport
|
|
16
|
-
} from "./chunk-
|
|
17
|
-
import "./chunk-
|
|
22
|
+
} from "./chunk-62B3GENJ.js";
|
|
23
|
+
import "./chunk-FBPC4LGY.js";
|
|
18
24
|
import {
|
|
19
25
|
checkEndpoint,
|
|
20
26
|
discoverResources
|
|
21
|
-
} from "./chunk-
|
|
27
|
+
} from "./chunk-4R52CY5Q.js";
|
|
22
28
|
import {
|
|
23
29
|
getPlatformPath,
|
|
24
30
|
tryAddServer
|
|
25
|
-
} from "./chunk-
|
|
26
|
-
import "./chunk-
|
|
31
|
+
} from "./chunk-5ELAEV2M.js";
|
|
32
|
+
import "./chunk-ZOVLXKVL.js";
|
|
27
33
|
import {
|
|
28
34
|
MCP_VERSION
|
|
29
|
-
} from "./chunk-
|
|
35
|
+
} from "./chunk-VR5I67WE.js";
|
|
30
36
|
import "./chunk-DZNSJ2BA.js";
|
|
31
37
|
import {
|
|
32
38
|
DEFAULT_NETWORK,
|
|
33
39
|
getWallet,
|
|
34
|
-
redeemInviteCode
|
|
40
|
+
redeemInviteCode
|
|
41
|
+
} from "./chunk-UN3PRLTL.js";
|
|
42
|
+
import {
|
|
35
43
|
safeParseJson,
|
|
36
44
|
toJsonObject
|
|
37
|
-
} from "./chunk-
|
|
45
|
+
} from "./chunk-ZDDDU5O2.js";
|
|
38
46
|
import {
|
|
39
47
|
getBaseUrl,
|
|
40
48
|
getDepositLink
|
|
41
|
-
} from "./chunk-
|
|
49
|
+
} from "./chunk-7ZEXMJYJ.js";
|
|
42
50
|
import {
|
|
43
51
|
DEFAULT_USER_FETCH_TIMEOUT,
|
|
44
|
-
resultFromPromise,
|
|
45
52
|
safeFetch,
|
|
46
53
|
safeFetchJson,
|
|
47
54
|
safeParseResponse
|
|
48
|
-
} from "./chunk-
|
|
55
|
+
} from "./chunk-YQFK4U62.js";
|
|
56
|
+
import {
|
|
57
|
+
resultFromPromise
|
|
58
|
+
} from "./chunk-6PU3XK6I.js";
|
|
49
59
|
import "./chunk-ISR6DJ53.js";
|
|
50
60
|
|
|
51
61
|
// src/cli/commands/fetch.ts
|
|
@@ -317,348 +327,66 @@ function parseRequestInput(surface, args, flags) {
|
|
|
317
327
|
return inputResult.data;
|
|
318
328
|
}
|
|
319
329
|
|
|
320
|
-
// src/cli/commands/
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
const
|
|
324
|
-
const
|
|
325
|
-
|
|
326
|
-
const publicClient = createPublicClient({
|
|
327
|
-
chain: base,
|
|
328
|
-
transport: http()
|
|
329
|
-
});
|
|
330
|
-
const coreClient = x402Client.fromConfig({
|
|
331
|
-
schemes: [
|
|
332
|
-
{
|
|
333
|
-
network: DEFAULT_NETWORK,
|
|
334
|
-
client: new ExactEvmScheme(toClientEvmSigner(account, publicClient))
|
|
335
|
-
}
|
|
336
|
-
]
|
|
337
|
-
});
|
|
338
|
-
const x402HttpClient = new x402HTTPClient(coreClient);
|
|
339
|
-
const mppxClient = Mppx.create({
|
|
340
|
-
polyfill: false,
|
|
341
|
-
methods: [
|
|
342
|
-
tempoMethod({
|
|
343
|
-
account,
|
|
344
|
-
getClient: () => createClient({ chain: tempo, transport: http(TEMPO_RPC_URL) })
|
|
345
|
-
})
|
|
346
|
-
]
|
|
347
|
-
});
|
|
348
|
-
const provider = flags.provider ?? `agentcash@${MCP_VERSION}`;
|
|
349
|
-
const paymentMethod = args.paymentMethod ?? "auto";
|
|
350
|
-
const request = buildRequest({
|
|
351
|
-
input,
|
|
352
|
-
address: account.address,
|
|
353
|
-
sessionId,
|
|
354
|
-
provider
|
|
355
|
-
});
|
|
356
|
-
const fetchResult = await createFetchWithPayment({
|
|
357
|
-
surface: SURFACE,
|
|
358
|
-
clients: { x402: x402HttpClient, mpp: mppxClient },
|
|
359
|
-
paymentMethod,
|
|
360
|
-
account,
|
|
361
|
-
flags
|
|
362
|
-
})(request);
|
|
363
|
-
if (fetchResult.isErr()) {
|
|
364
|
-
return outputAndExit(fromNeverthrowError(fetchResult), flags);
|
|
365
|
-
}
|
|
366
|
-
const { response, paymentInfo } = fetchResult.value;
|
|
367
|
-
if (!response.ok) {
|
|
368
|
-
const parseResult = await safeParseResponse(SURFACE, response);
|
|
369
|
-
const details = { statusCode: response.status };
|
|
370
|
-
let serverMessage;
|
|
371
|
-
if (parseResult.isOk()) {
|
|
372
|
-
const { type } = parseResult.value;
|
|
373
|
-
if (type === "json") {
|
|
374
|
-
details.body = parseResult.value.data;
|
|
375
|
-
serverMessage = extractJsonErrorMessage(parseResult.value.data);
|
|
376
|
-
} else if (type === "text") {
|
|
377
|
-
details.body = parseResult.value.data;
|
|
378
|
-
serverMessage = parseResult.value.data;
|
|
379
|
-
} else {
|
|
380
|
-
details.bodyType = type;
|
|
381
|
-
}
|
|
382
|
-
}
|
|
383
|
-
return outputAndExit(
|
|
384
|
-
errorResponse({
|
|
385
|
-
code: "HTTP_ERROR",
|
|
386
|
-
message: serverMessage ?? response.statusText,
|
|
387
|
-
surface: SURFACE,
|
|
388
|
-
cause: "http",
|
|
389
|
-
details
|
|
390
|
-
}),
|
|
391
|
-
flags
|
|
392
|
-
);
|
|
393
|
-
}
|
|
394
|
-
const parseResponseResult = await safeParseResponse(SURFACE, response);
|
|
395
|
-
if (parseResponseResult.isErr()) {
|
|
396
|
-
return outputAndExit(fromNeverthrowError(parseResponseResult), flags);
|
|
397
|
-
}
|
|
398
|
-
const data = parseResponseResult.value.type === "json" ? parseResponseResult.value.data : parseResponseResult.value.type === "text" ? parseResponseResult.value.data : { type: parseResponseResult.value.type };
|
|
399
|
-
const metadata = paymentInfo ? {
|
|
400
|
-
protocol: paymentInfo.protocol,
|
|
401
|
-
...paymentInfo.price ? { price: paymentInfo.price } : {},
|
|
402
|
-
...paymentInfo.payment ? { payment: paymentInfo.payment } : {}
|
|
403
|
-
} : void 0;
|
|
404
|
-
outputAndExit(successResponse(data, metadata), flags);
|
|
330
|
+
// src/cli/commands/lib/resolve-origin.ts
|
|
331
|
+
function resolveTitle(result, url) {
|
|
332
|
+
if (result.info?.title) return result.info.title;
|
|
333
|
+
const hostname = new URL(url).hostname.replace(/^www\./, "");
|
|
334
|
+
const parts = hostname.split(".");
|
|
335
|
+
return parts.length > 1 ? parts.slice(0, -1).join(".") : hostname;
|
|
405
336
|
}
|
|
406
|
-
function
|
|
407
|
-
if (
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
if (typeof obj.error === "object" && obj.error !== null && typeof obj.error.message === "string") {
|
|
411
|
-
return obj.error.message;
|
|
412
|
-
}
|
|
413
|
-
if (typeof obj.message === "string") return obj.message;
|
|
414
|
-
}
|
|
415
|
-
return void 0;
|
|
337
|
+
function resolveDescription(result) {
|
|
338
|
+
if (result.info?.description) return result.info.description;
|
|
339
|
+
if (result.guidance) return result.guidance.slice(0, 100);
|
|
340
|
+
return null;
|
|
416
341
|
}
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
const sessionId = randomBytes2(16).toString("hex");
|
|
424
|
-
const input = parseRequestInput(SURFACE2, args, flags);
|
|
425
|
-
const result = await createFetchWithAuth({
|
|
426
|
-
surface: SURFACE2,
|
|
427
|
-
account,
|
|
428
|
-
timeout: input.timeout ?? DEFAULT_USER_FETCH_TIMEOUT
|
|
429
|
-
})(buildRequest({ input, address: account.address, sessionId }));
|
|
430
|
-
if (result.isErr()) {
|
|
431
|
-
return outputAndExit(fromNeverthrowError(result), flags);
|
|
432
|
-
}
|
|
433
|
-
const value = result.value;
|
|
434
|
-
if (value.outcome === "no_siwx_extension") {
|
|
435
|
-
return outputAndExit(
|
|
436
|
-
errorResponse({
|
|
342
|
+
async function resolveOrigin(rawUrl, surface) {
|
|
343
|
+
const url = /^https?:\/\//i.test(rawUrl) ? rawUrl : `https://${rawUrl}`;
|
|
344
|
+
if (!URL.canParse(url)) {
|
|
345
|
+
return {
|
|
346
|
+
ok: false,
|
|
347
|
+
error: errorResponse({
|
|
437
348
|
code: "GENERAL_ERROR",
|
|
438
|
-
message:
|
|
439
|
-
surface
|
|
440
|
-
cause: "
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
flags
|
|
444
|
-
);
|
|
445
|
-
}
|
|
446
|
-
const { response } = value;
|
|
447
|
-
if (!response.ok) {
|
|
448
|
-
return outputAndExit(
|
|
449
|
-
errorResponse({
|
|
450
|
-
code: "HTTP_ERROR",
|
|
451
|
-
message: response.statusText,
|
|
452
|
-
surface: SURFACE2,
|
|
453
|
-
cause: "http",
|
|
454
|
-
details: { statusCode: response.status }
|
|
455
|
-
}),
|
|
456
|
-
flags
|
|
457
|
-
);
|
|
458
|
-
}
|
|
459
|
-
const parseResult = await safeParseResponse(SURFACE2, response);
|
|
460
|
-
if (parseResult.isErr()) {
|
|
461
|
-
return outputAndExit(fromNeverthrowError(parseResult), flags);
|
|
349
|
+
message: `Invalid URL: ${url}`,
|
|
350
|
+
surface,
|
|
351
|
+
cause: "invalid_url"
|
|
352
|
+
})
|
|
353
|
+
};
|
|
462
354
|
}
|
|
463
|
-
const
|
|
464
|
-
outputAndExit(successResponse(data), flags);
|
|
465
|
-
}
|
|
466
|
-
|
|
467
|
-
// src/cli/commands/check.ts
|
|
468
|
-
import { randomBytes as randomBytes3 } from "crypto";
|
|
469
|
-
var SURFACE3 = "cli:check";
|
|
470
|
-
async function checkCommand(args, flags) {
|
|
471
|
-
const { account } = await getWalletOrExit(flags);
|
|
472
|
-
const sessionId = randomBytes3(16).toString("hex");
|
|
473
|
-
const parsedBody = args.body ? JSON.parse(args.body) : void 0;
|
|
474
|
-
const parsedHeaders = args.headers ? JSON.parse(args.headers) : void 0;
|
|
475
|
-
const result = await checkEndpoint(
|
|
476
|
-
SURFACE3,
|
|
477
|
-
args.url,
|
|
478
|
-
args.method ? [args.method] : void 0,
|
|
479
|
-
parsedBody,
|
|
480
|
-
{
|
|
481
|
-
...parsedHeaders,
|
|
482
|
-
"X-Wallet-Address": account.address,
|
|
483
|
-
"X-Session-ID": sessionId
|
|
484
|
-
}
|
|
485
|
-
);
|
|
355
|
+
const result = await discoverResources(surface, url);
|
|
486
356
|
if (!result.found) {
|
|
487
|
-
return
|
|
488
|
-
|
|
489
|
-
|
|
490
|
-
|
|
491
|
-
|
|
492
|
-
|
|
493
|
-
|
|
494
|
-
)
|
|
495
|
-
|
|
496
|
-
);
|
|
357
|
+
return {
|
|
358
|
+
ok: false,
|
|
359
|
+
error: errorResponse({
|
|
360
|
+
code: "GENERAL_ERROR",
|
|
361
|
+
message: result.message ?? `No OpenAPI spec found for ${url}`,
|
|
362
|
+
surface,
|
|
363
|
+
cause: result.cause
|
|
364
|
+
})
|
|
365
|
+
};
|
|
497
366
|
}
|
|
498
|
-
const
|
|
499
|
-
|
|
500
|
-
|
|
501
|
-
|
|
502
|
-
|
|
503
|
-
|
|
504
|
-
|
|
505
|
-
);
|
|
506
|
-
}
|
|
507
|
-
|
|
508
|
-
// src/cli/commands/discover.ts
|
|
509
|
-
async function discoverCommand(args, flags) {
|
|
510
|
-
const result = await discoverResources("cli:discover", args.url, {
|
|
511
|
-
includeGuidance: args.includeGuidance
|
|
512
|
-
});
|
|
513
|
-
if (result.found) {
|
|
514
|
-
return outputAndExit(
|
|
515
|
-
successResponse({
|
|
516
|
-
found: true,
|
|
517
|
-
origin: result.origin,
|
|
518
|
-
source: result.source,
|
|
519
|
-
...result.info ? { info: result.info } : {},
|
|
520
|
-
guidanceAvailable: result.guidanceAvailable,
|
|
521
|
-
...result.guidanceTokens != null ? { guidanceTokens: result.guidanceTokens } : {},
|
|
522
|
-
...result.guidance ? { guidance: result.guidance } : {},
|
|
523
|
-
endpoints: result.endpoints.map((e) => ({ ...e }))
|
|
524
|
-
}),
|
|
525
|
-
flags
|
|
367
|
+
const description = resolveDescription(result) ?? "";
|
|
368
|
+
const warnings = [];
|
|
369
|
+
if (!result.info?.title)
|
|
370
|
+
warnings.push("No title found in OpenAPI spec; derived from URL.");
|
|
371
|
+
if (!result.info?.description)
|
|
372
|
+
warnings.push(
|
|
373
|
+
description ? "No description found in OpenAPI spec; derived from guidance." : "No description could be found."
|
|
526
374
|
);
|
|
527
|
-
|
|
528
|
-
|
|
529
|
-
|
|
530
|
-
|
|
531
|
-
|
|
532
|
-
|
|
533
|
-
|
|
534
|
-
|
|
535
|
-
|
|
536
|
-
}),
|
|
537
|
-
flags
|
|
538
|
-
);
|
|
375
|
+
return {
|
|
376
|
+
ok: true,
|
|
377
|
+
origin: {
|
|
378
|
+
url,
|
|
379
|
+
title: resolveTitle(result, url),
|
|
380
|
+
description,
|
|
381
|
+
warnings
|
|
382
|
+
}
|
|
383
|
+
};
|
|
539
384
|
}
|
|
540
385
|
|
|
541
|
-
// src/cli/commands/
|
|
542
|
-
|
|
543
|
-
|
|
544
|
-
|
|
545
|
-
if (result.isErr()) {
|
|
546
|
-
return outputAndExit(fromNeverthrowError(result), flags);
|
|
547
|
-
}
|
|
548
|
-
const { origin, resourceCount } = result.value;
|
|
549
|
-
return outputAndExit(
|
|
550
|
-
successResponse({
|
|
551
|
-
origin: {
|
|
552
|
-
id: origin.id,
|
|
553
|
-
origin: origin.origin,
|
|
554
|
-
name: origin.name
|
|
555
|
-
},
|
|
556
|
-
resourceCount
|
|
557
|
-
}),
|
|
558
|
-
flags
|
|
559
|
-
);
|
|
560
|
-
}
|
|
561
|
-
|
|
562
|
-
// src/cli/commands/wallet.ts
|
|
563
|
-
var SURFACE5 = "cli:wallet";
|
|
564
|
-
async function walletInfoCommand(_args, flags) {
|
|
565
|
-
const { account } = await getWalletOrExit(flags);
|
|
566
|
-
const result = await getWalletInfo(SURFACE5, account.address, flags);
|
|
567
|
-
if (result.isErr()) {
|
|
568
|
-
return outputAndExit(fromNeverthrowError(result), flags);
|
|
569
|
-
}
|
|
570
|
-
return outputAndExit(
|
|
571
|
-
successResponse({
|
|
572
|
-
address: result.value.address,
|
|
573
|
-
balance: result.value.balance,
|
|
574
|
-
chains: result.value.chains.map((c) => ({
|
|
575
|
-
chain: c.chain,
|
|
576
|
-
balance: c.balance
|
|
577
|
-
})),
|
|
578
|
-
isNewWallet: result.value.isNewWallet,
|
|
579
|
-
depositLink: result.value.depositLink,
|
|
580
|
-
...result.value.onboardingCta ? {
|
|
581
|
-
onboardingCta: {
|
|
582
|
-
onboardLink: result.value.onboardingCta.onboardLink,
|
|
583
|
-
depositLink: result.value.onboardingCta.depositLink,
|
|
584
|
-
message: result.value.onboardingCta.message
|
|
585
|
-
}
|
|
586
|
-
} : {},
|
|
587
|
-
...result.value.message ? { message: result.value.message } : {}
|
|
588
|
-
}),
|
|
589
|
-
flags
|
|
590
|
-
);
|
|
591
|
-
}
|
|
592
|
-
async function walletRedeemCommand(args, flags) {
|
|
593
|
-
const { account } = await getWalletOrExit(flags);
|
|
594
|
-
const result = await redeemInviteCode({
|
|
595
|
-
code: args.code,
|
|
596
|
-
address: account.address,
|
|
597
|
-
surface: SURFACE5,
|
|
598
|
-
dev: flags.dev
|
|
599
|
-
});
|
|
600
|
-
if (result.isErr()) {
|
|
601
|
-
return outputAndExit(fromNeverthrowError(result), flags);
|
|
602
|
-
}
|
|
603
|
-
return outputAndExit(
|
|
604
|
-
successResponse({
|
|
605
|
-
redeemed: true,
|
|
606
|
-
amount: `${result.value.amount} USDC`,
|
|
607
|
-
txHash: result.value.txHash
|
|
608
|
-
}),
|
|
609
|
-
flags
|
|
610
|
-
);
|
|
611
|
-
}
|
|
612
|
-
async function walletAddressCommand(_args, flags) {
|
|
613
|
-
const { account } = await getWalletOrExit(flags);
|
|
614
|
-
return outputAndExit(successResponse({ address: account.address }), flags);
|
|
615
|
-
}
|
|
616
|
-
|
|
617
|
-
// src/cli/commands/report-error.ts
|
|
618
|
-
var SURFACE6 = "cli:report-error";
|
|
619
|
-
async function reportErrorCommand(args, flags) {
|
|
620
|
-
const { account } = await getWalletOrExit(flags);
|
|
621
|
-
const result = await submitErrorReport(
|
|
622
|
-
SURFACE6,
|
|
623
|
-
{
|
|
624
|
-
tool: args.tool,
|
|
625
|
-
summary: args.summary,
|
|
626
|
-
errorMessage: args.errorMessage,
|
|
627
|
-
resource: args.resource,
|
|
628
|
-
stack: args.stack,
|
|
629
|
-
fullReport: args.fullReport
|
|
630
|
-
},
|
|
631
|
-
account.address,
|
|
632
|
-
flags.dev
|
|
633
|
-
);
|
|
634
|
-
if (result.isErr()) {
|
|
635
|
-
return outputAndExit(fromNeverthrowError(result), flags);
|
|
636
|
-
}
|
|
637
|
-
return outputAndExit(
|
|
638
|
-
successResponse({
|
|
639
|
-
submitted: result.value.submitted,
|
|
640
|
-
reportId: result.value.reportId,
|
|
641
|
-
message: result.value.message
|
|
642
|
-
}),
|
|
643
|
-
flags
|
|
644
|
-
);
|
|
645
|
-
}
|
|
646
|
-
|
|
647
|
-
// src/cli/commands/server.ts
|
|
648
|
-
async function serverCommand(flags) {
|
|
649
|
-
if (process.stdout.isTTY) {
|
|
650
|
-
process.stdout.write(
|
|
651
|
-
"MCP server started. If you meant to explore the CLI, run: npx agentcash --help\n"
|
|
652
|
-
);
|
|
653
|
-
}
|
|
654
|
-
const { startServer } = await import("./server-VU3UAM7K.js");
|
|
655
|
-
await startServer(flags);
|
|
656
|
-
}
|
|
657
|
-
|
|
658
|
-
// src/cli/commands/add-skill.ts
|
|
659
|
-
import * as fs2 from "fs/promises";
|
|
660
|
-
import * as os2 from "os";
|
|
661
|
-
import * as path2 from "path";
|
|
386
|
+
// src/cli/commands/lib/add-origin-skill.ts
|
|
387
|
+
import * as fs2 from "fs/promises";
|
|
388
|
+
import * as os2 from "os";
|
|
389
|
+
import * as path2 from "path";
|
|
662
390
|
|
|
663
391
|
// src/shared/skills/agents.ts
|
|
664
392
|
import * as fs from "fs";
|
|
@@ -829,175 +557,558 @@ var all = [
|
|
|
829
557
|
function detect() {
|
|
830
558
|
return all.filter((a) => a.detect());
|
|
831
559
|
}
|
|
832
|
-
function installSkills(sourceDir, options = {}) {
|
|
833
|
-
const isGlobal = options.global !== false;
|
|
834
|
-
const cwd = options.cwd ?? process.cwd();
|
|
835
|
-
const base2 = isGlobal ? home : cwd;
|
|
836
|
-
const canonicalBase = path.join(base2, ".agents", "skills");
|
|
837
|
-
const detected = options.agents ?? detect();
|
|
838
|
-
const paths = [];
|
|
839
|
-
const agents = [];
|
|
840
|
-
for (const skill of discoverSkills(sourceDir)) {
|
|
841
|
-
const canonicalDir = path.join(canonicalBase, skill.name);
|
|
842
|
-
rmForce(canonicalDir);
|
|
843
|
-
fs.mkdirSync(canonicalDir, { recursive: true });
|
|
844
|
-
if (skill.root)
|
|
845
|
-
fs.copyFileSync(
|
|
846
|
-
path.join(skill.dir, "SKILL.md"),
|
|
847
|
-
path.join(canonicalDir, "SKILL.md")
|
|
848
|
-
);
|
|
849
|
-
else fs.cpSync(skill.dir, canonicalDir, { recursive: true });
|
|
850
|
-
paths.push(canonicalDir);
|
|
851
|
-
for (const agent of detected) {
|
|
852
|
-
if (agent.universal) continue;
|
|
853
|
-
const agentSkillsDir = isGlobal ? agent.globalSkillsDir : path.join(cwd, agent.projectSkillsDir);
|
|
854
|
-
const agentDir = path.join(agentSkillsDir, skill.name);
|
|
855
|
-
if (agentDir === canonicalDir) continue;
|
|
856
|
-
try {
|
|
857
|
-
rmForce(agentDir);
|
|
858
|
-
fs.mkdirSync(path.dirname(agentDir), { recursive: true });
|
|
859
|
-
const realLinkDir = resolveParent(path.dirname(agentDir));
|
|
860
|
-
const realTarget = resolveParent(canonicalDir);
|
|
861
|
-
const rel = path.relative(realLinkDir, realTarget);
|
|
862
|
-
fs.symlinkSync(rel, agentDir);
|
|
863
|
-
agents.push({ agent: agent.name, path: agentDir, mode: "symlink" });
|
|
864
|
-
} catch {
|
|
865
|
-
try {
|
|
866
|
-
fs.cpSync(canonicalDir, agentDir, { recursive: true });
|
|
867
|
-
agents.push({ agent: agent.name, path: agentDir, mode: "copy" });
|
|
868
|
-
} catch {
|
|
869
|
-
}
|
|
870
|
-
}
|
|
871
|
-
}
|
|
560
|
+
function installSkills(sourceDir, options = {}) {
|
|
561
|
+
const isGlobal = options.global !== false;
|
|
562
|
+
const cwd = options.cwd ?? process.cwd();
|
|
563
|
+
const base2 = isGlobal ? home : cwd;
|
|
564
|
+
const canonicalBase = path.join(base2, ".agents", "skills");
|
|
565
|
+
const detected = options.agents ?? detect();
|
|
566
|
+
const paths = [];
|
|
567
|
+
const agents = [];
|
|
568
|
+
for (const skill of discoverSkills(sourceDir)) {
|
|
569
|
+
const canonicalDir = path.join(canonicalBase, skill.name);
|
|
570
|
+
rmForce(canonicalDir);
|
|
571
|
+
fs.mkdirSync(canonicalDir, { recursive: true });
|
|
572
|
+
if (skill.root)
|
|
573
|
+
fs.copyFileSync(
|
|
574
|
+
path.join(skill.dir, "SKILL.md"),
|
|
575
|
+
path.join(canonicalDir, "SKILL.md")
|
|
576
|
+
);
|
|
577
|
+
else fs.cpSync(skill.dir, canonicalDir, { recursive: true });
|
|
578
|
+
paths.push(canonicalDir);
|
|
579
|
+
for (const agent of detected) {
|
|
580
|
+
if (agent.universal) continue;
|
|
581
|
+
const agentSkillsDir = isGlobal ? agent.globalSkillsDir : path.join(cwd, agent.projectSkillsDir);
|
|
582
|
+
const agentDir = path.join(agentSkillsDir, skill.name);
|
|
583
|
+
if (agentDir === canonicalDir) continue;
|
|
584
|
+
try {
|
|
585
|
+
rmForce(agentDir);
|
|
586
|
+
fs.mkdirSync(path.dirname(agentDir), { recursive: true });
|
|
587
|
+
const realLinkDir = resolveParent(path.dirname(agentDir));
|
|
588
|
+
const realTarget = resolveParent(canonicalDir);
|
|
589
|
+
const rel = path.relative(realLinkDir, realTarget);
|
|
590
|
+
fs.symlinkSync(rel, agentDir);
|
|
591
|
+
agents.push({ agent: agent.name, path: agentDir, mode: "symlink" });
|
|
592
|
+
} catch {
|
|
593
|
+
try {
|
|
594
|
+
fs.cpSync(canonicalDir, agentDir, { recursive: true });
|
|
595
|
+
agents.push({ agent: agent.name, path: agentDir, mode: "copy" });
|
|
596
|
+
} catch {
|
|
597
|
+
}
|
|
598
|
+
}
|
|
599
|
+
}
|
|
600
|
+
}
|
|
601
|
+
return { paths, agents };
|
|
602
|
+
}
|
|
603
|
+
function discoverSkills(rootDir) {
|
|
604
|
+
const results = [];
|
|
605
|
+
function visit(dir) {
|
|
606
|
+
let entries;
|
|
607
|
+
try {
|
|
608
|
+
entries = fs.readdirSync(dir, { withFileTypes: true });
|
|
609
|
+
} catch {
|
|
610
|
+
return;
|
|
611
|
+
}
|
|
612
|
+
for (const entry of entries) {
|
|
613
|
+
if (!entry.isDirectory()) continue;
|
|
614
|
+
const subDir = path.join(dir, entry.name);
|
|
615
|
+
const skillPath = path.join(subDir, "SKILL.md");
|
|
616
|
+
if (fs.existsSync(skillPath)) {
|
|
617
|
+
const content = fs.readFileSync(skillPath, "utf8");
|
|
618
|
+
const nameMatch = /^name:\s*(.+)$/m.exec(content);
|
|
619
|
+
results.push({
|
|
620
|
+
name: sanitizeName(nameMatch?.[1] ?? entry.name),
|
|
621
|
+
dir: subDir
|
|
622
|
+
});
|
|
623
|
+
}
|
|
624
|
+
visit(subDir);
|
|
625
|
+
}
|
|
626
|
+
}
|
|
627
|
+
visit(rootDir);
|
|
628
|
+
const rootSkill = path.join(rootDir, "SKILL.md");
|
|
629
|
+
if (fs.existsSync(rootSkill)) {
|
|
630
|
+
const content = fs.readFileSync(rootSkill, "utf8");
|
|
631
|
+
const nameMatch = /^name:\s*(.+)$/m.exec(content);
|
|
632
|
+
const name = sanitizeName(nameMatch?.[1] ?? "skill");
|
|
633
|
+
if (!results.some((r) => r.name === name))
|
|
634
|
+
results.push({ name, dir: rootDir, root: true });
|
|
635
|
+
}
|
|
636
|
+
return results;
|
|
637
|
+
}
|
|
638
|
+
function sanitizeName(name) {
|
|
639
|
+
return name.trim().replace(/[/\\]/g, "-").replace(/\.\./g, "").slice(0, 255);
|
|
640
|
+
}
|
|
641
|
+
function rmForce(target) {
|
|
642
|
+
try {
|
|
643
|
+
const stat = fs.lstatSync(target);
|
|
644
|
+
if (stat.isSymbolicLink()) fs.unlinkSync(target);
|
|
645
|
+
else fs.rmSync(target, { recursive: true, force: true });
|
|
646
|
+
} catch {
|
|
647
|
+
}
|
|
648
|
+
}
|
|
649
|
+
function resolveParent(dir) {
|
|
650
|
+
try {
|
|
651
|
+
return fs.realpathSync(dir);
|
|
652
|
+
} catch {
|
|
653
|
+
const parent = path.dirname(dir);
|
|
654
|
+
if (parent === dir) return dir;
|
|
655
|
+
try {
|
|
656
|
+
return path.join(fs.realpathSync(parent), path.relative(parent, dir));
|
|
657
|
+
} catch {
|
|
658
|
+
return dir;
|
|
659
|
+
}
|
|
660
|
+
}
|
|
661
|
+
}
|
|
662
|
+
|
|
663
|
+
// src/cli/commands/lib/add-origin-skill.ts
|
|
664
|
+
async function addOriginSkill(origin, surface, options) {
|
|
665
|
+
const title = origin.title.toLowerCase().replace(/[ .]/g, "-");
|
|
666
|
+
const tmpDir = await fs2.mkdtemp(path2.join(os2.tmpdir(), "incur-skill-add-"));
|
|
667
|
+
const result = await resultFromPromise(
|
|
668
|
+
"add-origin-skill",
|
|
669
|
+
surface,
|
|
670
|
+
(async () => {
|
|
671
|
+
const skillDir = path2.join(tmpDir, title);
|
|
672
|
+
await fs2.mkdir(skillDir, { recursive: true });
|
|
673
|
+
await fs2.writeFile(
|
|
674
|
+
path2.join(skillDir, "SKILL.md"),
|
|
675
|
+
`---
|
|
676
|
+
name: ${title}
|
|
677
|
+
description: ${origin.description}
|
|
678
|
+
command: npx agentcash discover ${origin.url}
|
|
679
|
+
---
|
|
680
|
+
Call \`npx agentcash discover ${origin.url}\` to discover how to use ${origin.title}.`
|
|
681
|
+
);
|
|
682
|
+
return installSkills(tmpDir, { cwd: options.cwd });
|
|
683
|
+
})(),
|
|
684
|
+
(e) => ({
|
|
685
|
+
cause: "install_failed",
|
|
686
|
+
message: e instanceof Error ? e.message : "Skill could not be written to /skills directory."
|
|
687
|
+
})
|
|
688
|
+
);
|
|
689
|
+
await fs2.rm(tmpDir, { recursive: true, force: true }).catch(() => void 0);
|
|
690
|
+
return result;
|
|
691
|
+
}
|
|
692
|
+
|
|
693
|
+
// src/cli/commands/fetch.ts
|
|
694
|
+
var SURFACE = "cli:fetch";
|
|
695
|
+
async function fetchCommand(args, flags) {
|
|
696
|
+
const { account } = await getWalletOrExit(flags);
|
|
697
|
+
const sessionId = randomBytes(16).toString("hex");
|
|
698
|
+
const input = parseRequestInput(SURFACE, args, flags);
|
|
699
|
+
const publicClient = createPublicClient({
|
|
700
|
+
chain: base,
|
|
701
|
+
transport: http()
|
|
702
|
+
});
|
|
703
|
+
const coreClient = x402Client.fromConfig({
|
|
704
|
+
schemes: [
|
|
705
|
+
{
|
|
706
|
+
network: DEFAULT_NETWORK,
|
|
707
|
+
client: new ExactEvmScheme(toClientEvmSigner(account, publicClient))
|
|
708
|
+
}
|
|
709
|
+
]
|
|
710
|
+
});
|
|
711
|
+
const x402HttpClient = new x402HTTPClient(coreClient);
|
|
712
|
+
const mppxClient = Mppx.create({
|
|
713
|
+
polyfill: false,
|
|
714
|
+
methods: [
|
|
715
|
+
tempoMethod({
|
|
716
|
+
account,
|
|
717
|
+
getClient: () => createClient({ chain: tempo, transport: http(TEMPO_RPC_URL) })
|
|
718
|
+
})
|
|
719
|
+
]
|
|
720
|
+
});
|
|
721
|
+
const provider = flags.provider ?? `agentcash@${MCP_VERSION}`;
|
|
722
|
+
const paymentMethod = args.paymentMethod ?? "auto";
|
|
723
|
+
const request = buildRequest({
|
|
724
|
+
input,
|
|
725
|
+
address: account.address,
|
|
726
|
+
sessionId,
|
|
727
|
+
provider
|
|
728
|
+
});
|
|
729
|
+
const fetchResult = await createFetchWithPayment({
|
|
730
|
+
surface: SURFACE,
|
|
731
|
+
clients: { x402: x402HttpClient, mpp: mppxClient },
|
|
732
|
+
paymentMethod,
|
|
733
|
+
account,
|
|
734
|
+
flags
|
|
735
|
+
})(request);
|
|
736
|
+
if (fetchResult.isErr()) {
|
|
737
|
+
return outputAndExit(fromNeverthrowError(fetchResult), flags);
|
|
738
|
+
}
|
|
739
|
+
const { response, paymentInfo } = fetchResult.value;
|
|
740
|
+
if (!response.ok) {
|
|
741
|
+
const parseResult = await safeParseResponse(SURFACE, response);
|
|
742
|
+
const details = { statusCode: response.status };
|
|
743
|
+
let serverMessage;
|
|
744
|
+
if (parseResult.isOk()) {
|
|
745
|
+
const { type } = parseResult.value;
|
|
746
|
+
if (type === "json") {
|
|
747
|
+
details.body = parseResult.value.data;
|
|
748
|
+
serverMessage = extractJsonErrorMessage(parseResult.value.data);
|
|
749
|
+
} else if (type === "text") {
|
|
750
|
+
details.body = parseResult.value.data;
|
|
751
|
+
serverMessage = parseResult.value.data;
|
|
752
|
+
} else {
|
|
753
|
+
details.bodyType = type;
|
|
754
|
+
}
|
|
755
|
+
}
|
|
756
|
+
return outputAndExit(
|
|
757
|
+
errorResponse({
|
|
758
|
+
code: "HTTP_ERROR",
|
|
759
|
+
message: serverMessage ?? response.statusText,
|
|
760
|
+
surface: SURFACE,
|
|
761
|
+
cause: "http",
|
|
762
|
+
details
|
|
763
|
+
}),
|
|
764
|
+
flags
|
|
765
|
+
);
|
|
766
|
+
}
|
|
767
|
+
const parseResponseResult = await safeParseResponse(SURFACE, response);
|
|
768
|
+
if (parseResponseResult.isErr()) {
|
|
769
|
+
return outputAndExit(fromNeverthrowError(parseResponseResult), flags);
|
|
770
|
+
}
|
|
771
|
+
const data = parseResponseResult.value.type === "json" ? parseResponseResult.value.data : parseResponseResult.value.type === "text" ? parseResponseResult.value.data : { type: parseResponseResult.value.type };
|
|
772
|
+
const metadata = paymentInfo ? {
|
|
773
|
+
protocol: paymentInfo.protocol,
|
|
774
|
+
...paymentInfo.price ? { price: paymentInfo.price } : {},
|
|
775
|
+
...paymentInfo.payment ? { payment: paymentInfo.payment } : {}
|
|
776
|
+
} : void 0;
|
|
777
|
+
outputAndExit(successResponse(data, metadata), flags);
|
|
778
|
+
}
|
|
779
|
+
function extractJsonErrorMessage(body) {
|
|
780
|
+
if (typeof body === "object" && body !== null) {
|
|
781
|
+
const obj = body;
|
|
782
|
+
if (typeof obj.error === "string") return obj.error;
|
|
783
|
+
if (typeof obj.error === "object" && obj.error !== null && typeof obj.error.message === "string") {
|
|
784
|
+
return obj.error.message;
|
|
785
|
+
}
|
|
786
|
+
if (typeof obj.message === "string") return obj.message;
|
|
787
|
+
}
|
|
788
|
+
return void 0;
|
|
789
|
+
}
|
|
790
|
+
|
|
791
|
+
// src/cli/commands/fetch-auth.ts
|
|
792
|
+
import { randomBytes as randomBytes2 } from "crypto";
|
|
793
|
+
var SURFACE2 = "cli:fetch-auth";
|
|
794
|
+
async function fetchAuthCommand(args, flags) {
|
|
795
|
+
const { account } = await getWalletOrExit(flags);
|
|
796
|
+
const sessionId = randomBytes2(16).toString("hex");
|
|
797
|
+
const input = parseRequestInput(SURFACE2, args, flags);
|
|
798
|
+
const result = await createFetchWithAuth({
|
|
799
|
+
surface: SURFACE2,
|
|
800
|
+
account,
|
|
801
|
+
timeout: input.timeout ?? DEFAULT_USER_FETCH_TIMEOUT
|
|
802
|
+
})(buildRequest({ input, address: account.address, sessionId }));
|
|
803
|
+
if (result.isErr()) {
|
|
804
|
+
return outputAndExit(fromNeverthrowError(result), flags);
|
|
805
|
+
}
|
|
806
|
+
const value = result.value;
|
|
807
|
+
if (value.outcome === "no_siwx_extension") {
|
|
808
|
+
return outputAndExit(
|
|
809
|
+
errorResponse({
|
|
810
|
+
code: "GENERAL_ERROR",
|
|
811
|
+
message: "Endpoint returned 402 but no sign-in-with-x extension found. Use `fetch` for paid endpoints.",
|
|
812
|
+
surface: SURFACE2,
|
|
813
|
+
cause: "no_siwx_extension",
|
|
814
|
+
details: { extensions: value.extensions }
|
|
815
|
+
}),
|
|
816
|
+
flags
|
|
817
|
+
);
|
|
818
|
+
}
|
|
819
|
+
const { response } = value;
|
|
820
|
+
if (!response.ok) {
|
|
821
|
+
return outputAndExit(
|
|
822
|
+
errorResponse({
|
|
823
|
+
code: "HTTP_ERROR",
|
|
824
|
+
message: response.statusText,
|
|
825
|
+
surface: SURFACE2,
|
|
826
|
+
cause: "http",
|
|
827
|
+
details: { statusCode: response.status }
|
|
828
|
+
}),
|
|
829
|
+
flags
|
|
830
|
+
);
|
|
831
|
+
}
|
|
832
|
+
const parseResult = await safeParseResponse(SURFACE2, response);
|
|
833
|
+
if (parseResult.isErr()) {
|
|
834
|
+
return outputAndExit(fromNeverthrowError(parseResult), flags);
|
|
835
|
+
}
|
|
836
|
+
const data = parseResult.value.type === "json" ? parseResult.value.data : parseResult.value.type === "text" ? parseResult.value.data : { type: parseResult.value.type };
|
|
837
|
+
outputAndExit(successResponse(data), flags);
|
|
838
|
+
}
|
|
839
|
+
|
|
840
|
+
// src/cli/commands/check.ts
|
|
841
|
+
import { randomBytes as randomBytes3 } from "crypto";
|
|
842
|
+
var SURFACE3 = "cli:check";
|
|
843
|
+
async function checkCommand(args, flags) {
|
|
844
|
+
const { account } = await getWalletOrExit(flags);
|
|
845
|
+
const sessionId = randomBytes3(16).toString("hex");
|
|
846
|
+
const parsedBody = args.body ? JSON.parse(args.body) : void 0;
|
|
847
|
+
const parsedHeaders = args.headers ? JSON.parse(args.headers) : void 0;
|
|
848
|
+
const result = await checkEndpoint(
|
|
849
|
+
SURFACE3,
|
|
850
|
+
args.url,
|
|
851
|
+
args.method ? [args.method] : void 0,
|
|
852
|
+
parsedBody,
|
|
853
|
+
{
|
|
854
|
+
...parsedHeaders,
|
|
855
|
+
"X-Wallet-Address": account.address,
|
|
856
|
+
"X-Session-ID": sessionId
|
|
857
|
+
}
|
|
858
|
+
);
|
|
859
|
+
if (!result.found) {
|
|
860
|
+
return outputAndExit(
|
|
861
|
+
successResponse(
|
|
862
|
+
toJsonObject({
|
|
863
|
+
url: args.url,
|
|
864
|
+
error: result.cause,
|
|
865
|
+
message: result.message
|
|
866
|
+
})
|
|
867
|
+
),
|
|
868
|
+
flags
|
|
869
|
+
);
|
|
870
|
+
}
|
|
871
|
+
const results = result.advisories.map((a) => ({
|
|
872
|
+
...a,
|
|
873
|
+
requiresPayment: a.authMode === "paid" || a.authMode === "apiKey+paid"
|
|
874
|
+
}));
|
|
875
|
+
return outputAndExit(
|
|
876
|
+
successResponse(toJsonObject({ url: args.url, results })),
|
|
877
|
+
flags
|
|
878
|
+
);
|
|
879
|
+
}
|
|
880
|
+
|
|
881
|
+
// src/cli/commands/discover.ts
|
|
882
|
+
async function discoverCommand(args, flags) {
|
|
883
|
+
const result = await discoverResources("cli:discover", args.url, {
|
|
884
|
+
includeGuidance: args.includeGuidance
|
|
885
|
+
});
|
|
886
|
+
if (result.found) {
|
|
887
|
+
return outputAndExit(
|
|
888
|
+
successResponse({
|
|
889
|
+
found: true,
|
|
890
|
+
origin: result.origin,
|
|
891
|
+
source: result.source,
|
|
892
|
+
...result.info ? { info: result.info } : {},
|
|
893
|
+
guidanceAvailable: result.guidanceAvailable,
|
|
894
|
+
...result.guidanceTokens != null ? { guidanceTokens: result.guidanceTokens } : {},
|
|
895
|
+
...result.guidance ? { guidance: result.guidance } : {},
|
|
896
|
+
endpoints: result.endpoints.map((e) => ({ ...e }))
|
|
897
|
+
}),
|
|
898
|
+
flags
|
|
899
|
+
);
|
|
900
|
+
}
|
|
901
|
+
const origin = URL.canParse(args.url) ? new URL(args.url).origin : args.url;
|
|
902
|
+
return outputAndExit(
|
|
903
|
+
errorResponse({
|
|
904
|
+
code: "GENERAL_ERROR",
|
|
905
|
+
message: result.message ?? `No OpenAPI spec found for ${origin}. Tried: /openapi.json, /.well-known/x402`,
|
|
906
|
+
surface: "cli:discover",
|
|
907
|
+
cause: result.cause,
|
|
908
|
+
details: { origin }
|
|
909
|
+
}),
|
|
910
|
+
flags
|
|
911
|
+
);
|
|
912
|
+
}
|
|
913
|
+
|
|
914
|
+
// src/cli/commands/register.ts
|
|
915
|
+
var SURFACE4 = "cli:register";
|
|
916
|
+
async function registerCommand(args, flags) {
|
|
917
|
+
const result = await registerOrigin(SURFACE4, { url: args.url }, flags.dev);
|
|
918
|
+
if (result.isErr()) {
|
|
919
|
+
return outputAndExit(fromNeverthrowError(result), flags);
|
|
872
920
|
}
|
|
873
|
-
|
|
921
|
+
const { origin, resourceCount } = result.value;
|
|
922
|
+
return outputAndExit(
|
|
923
|
+
successResponse({
|
|
924
|
+
origin: {
|
|
925
|
+
id: origin.id,
|
|
926
|
+
origin: origin.origin,
|
|
927
|
+
name: origin.name
|
|
928
|
+
},
|
|
929
|
+
resourceCount
|
|
930
|
+
}),
|
|
931
|
+
flags
|
|
932
|
+
);
|
|
874
933
|
}
|
|
875
|
-
|
|
876
|
-
|
|
877
|
-
|
|
878
|
-
|
|
879
|
-
|
|
880
|
-
|
|
881
|
-
|
|
882
|
-
|
|
883
|
-
}
|
|
884
|
-
for (const entry of entries) {
|
|
885
|
-
if (!entry.isDirectory()) continue;
|
|
886
|
-
const subDir = path.join(dir, entry.name);
|
|
887
|
-
const skillPath = path.join(subDir, "SKILL.md");
|
|
888
|
-
if (fs.existsSync(skillPath)) {
|
|
889
|
-
const content = fs.readFileSync(skillPath, "utf8");
|
|
890
|
-
const nameMatch = /^name:\s*(.+)$/m.exec(content);
|
|
891
|
-
results.push({
|
|
892
|
-
name: sanitizeName(nameMatch?.[1] ?? entry.name),
|
|
893
|
-
dir: subDir
|
|
894
|
-
});
|
|
895
|
-
}
|
|
896
|
-
visit(subDir);
|
|
897
|
-
}
|
|
934
|
+
|
|
935
|
+
// src/cli/commands/wallet.ts
|
|
936
|
+
var SURFACE5 = "cli:wallet";
|
|
937
|
+
async function walletInfoCommand(_args, flags) {
|
|
938
|
+
const { account } = await getWalletOrExit(flags);
|
|
939
|
+
const result = await getWalletInfo(SURFACE5, account.address, flags);
|
|
940
|
+
if (result.isErr()) {
|
|
941
|
+
return outputAndExit(fromNeverthrowError(result), flags);
|
|
898
942
|
}
|
|
899
|
-
|
|
900
|
-
|
|
901
|
-
|
|
902
|
-
|
|
903
|
-
|
|
904
|
-
|
|
905
|
-
|
|
906
|
-
|
|
943
|
+
return outputAndExit(
|
|
944
|
+
successResponse({
|
|
945
|
+
address: result.value.address,
|
|
946
|
+
balance: result.value.balance,
|
|
947
|
+
chains: result.value.chains.map((c) => ({
|
|
948
|
+
chain: c.chain,
|
|
949
|
+
balance: c.balance
|
|
950
|
+
})),
|
|
951
|
+
isNewWallet: result.value.isNewWallet,
|
|
952
|
+
depositLink: result.value.depositLink,
|
|
953
|
+
...result.value.onboardingCta ? {
|
|
954
|
+
onboardingCta: {
|
|
955
|
+
onboardLink: result.value.onboardingCta.onboardLink,
|
|
956
|
+
depositLink: result.value.onboardingCta.depositLink,
|
|
957
|
+
message: result.value.onboardingCta.message
|
|
958
|
+
}
|
|
959
|
+
} : {},
|
|
960
|
+
...result.value.message ? { message: result.value.message } : {}
|
|
961
|
+
}),
|
|
962
|
+
flags
|
|
963
|
+
);
|
|
964
|
+
}
|
|
965
|
+
async function walletRedeemCommand(args, flags) {
|
|
966
|
+
const { account } = await getWalletOrExit(flags);
|
|
967
|
+
const result = await redeemInviteCode({
|
|
968
|
+
code: args.code,
|
|
969
|
+
address: account.address,
|
|
970
|
+
surface: SURFACE5,
|
|
971
|
+
dev: flags.dev
|
|
972
|
+
});
|
|
973
|
+
if (result.isErr()) {
|
|
974
|
+
return outputAndExit(fromNeverthrowError(result), flags);
|
|
907
975
|
}
|
|
908
|
-
return
|
|
976
|
+
return outputAndExit(
|
|
977
|
+
successResponse({
|
|
978
|
+
redeemed: true,
|
|
979
|
+
amount: `${result.value.amount} USDC`,
|
|
980
|
+
txHash: result.value.txHash
|
|
981
|
+
}),
|
|
982
|
+
flags
|
|
983
|
+
);
|
|
909
984
|
}
|
|
910
|
-
function
|
|
911
|
-
|
|
985
|
+
async function walletAddressCommand(_args, flags) {
|
|
986
|
+
const { account } = await getWalletOrExit(flags);
|
|
987
|
+
return outputAndExit(successResponse({ address: account.address }), flags);
|
|
912
988
|
}
|
|
913
|
-
|
|
914
|
-
|
|
915
|
-
|
|
916
|
-
|
|
917
|
-
|
|
918
|
-
|
|
989
|
+
|
|
990
|
+
// src/cli/commands/report-error.ts
|
|
991
|
+
var SURFACE6 = "cli:report-error";
|
|
992
|
+
async function reportErrorCommand(args, flags) {
|
|
993
|
+
const { account } = await getWalletOrExit(flags);
|
|
994
|
+
const result = await submitErrorReport(
|
|
995
|
+
SURFACE6,
|
|
996
|
+
{
|
|
997
|
+
tool: args.tool,
|
|
998
|
+
summary: args.summary,
|
|
999
|
+
errorMessage: args.errorMessage,
|
|
1000
|
+
resource: args.resource,
|
|
1001
|
+
stack: args.stack,
|
|
1002
|
+
fullReport: args.fullReport
|
|
1003
|
+
},
|
|
1004
|
+
account.address,
|
|
1005
|
+
flags.dev
|
|
1006
|
+
);
|
|
1007
|
+
if (result.isErr()) {
|
|
1008
|
+
return outputAndExit(fromNeverthrowError(result), flags);
|
|
919
1009
|
}
|
|
1010
|
+
return outputAndExit(
|
|
1011
|
+
successResponse({
|
|
1012
|
+
submitted: result.value.submitted,
|
|
1013
|
+
reportId: result.value.reportId,
|
|
1014
|
+
message: result.value.message
|
|
1015
|
+
}),
|
|
1016
|
+
flags
|
|
1017
|
+
);
|
|
920
1018
|
}
|
|
921
|
-
|
|
922
|
-
|
|
923
|
-
|
|
924
|
-
|
|
925
|
-
|
|
926
|
-
|
|
927
|
-
|
|
928
|
-
return path.join(fs.realpathSync(parent), path.relative(parent, dir));
|
|
929
|
-
} catch {
|
|
930
|
-
return dir;
|
|
931
|
-
}
|
|
1019
|
+
|
|
1020
|
+
// src/cli/commands/server.ts
|
|
1021
|
+
async function serverCommand(flags) {
|
|
1022
|
+
if (process.stdout.isTTY) {
|
|
1023
|
+
process.stdout.write(
|
|
1024
|
+
"MCP server started. If you meant to explore the CLI, run: npx agentcash --help\n"
|
|
1025
|
+
);
|
|
932
1026
|
}
|
|
1027
|
+
const { startServer } = await import("./server-QARME5NA.js");
|
|
1028
|
+
await startServer(flags);
|
|
933
1029
|
}
|
|
934
1030
|
|
|
935
1031
|
// src/cli/commands/add-skill.ts
|
|
936
1032
|
var SURFACE7 = "cli:add-skill";
|
|
937
1033
|
async function addSkillCommand(args, flags) {
|
|
938
|
-
|
|
939
|
-
|
|
940
|
-
}
|
|
941
|
-
|
|
942
|
-
|
|
943
|
-
|
|
944
|
-
|
|
945
|
-
|
|
946
|
-
|
|
947
|
-
|
|
948
|
-
})
|
|
949
|
-
);
|
|
950
|
-
}
|
|
951
|
-
const result = await discoverResources("cli:add-skill", args.url);
|
|
952
|
-
if (!result.found) {
|
|
953
|
-
return outputAndExit(
|
|
954
|
-
errorResponse({
|
|
955
|
-
code: "GENERAL_ERROR",
|
|
956
|
-
message: result.message ?? `No OpenAPI spec found for ${args.url}`,
|
|
957
|
-
surface: SURFACE7,
|
|
958
|
-
cause: result.cause
|
|
959
|
-
}),
|
|
960
|
-
flags
|
|
1034
|
+
const resolved = await resolveOrigin(args.url, SURFACE7);
|
|
1035
|
+
if (!resolved.ok) return outputAndExit(resolved.error, flags);
|
|
1036
|
+
const { origin } = resolved;
|
|
1037
|
+
addUserOrigin(origin);
|
|
1038
|
+
const skillResult = await addOriginSkill(origin, SURFACE7, {
|
|
1039
|
+
cwd: process.cwd()
|
|
1040
|
+
});
|
|
1041
|
+
if (!skillResult.isOk()) {
|
|
1042
|
+
origin.warnings.push(
|
|
1043
|
+
"Failed to install skill: " + skillResult.error.cause + " " + skillResult.error.message
|
|
961
1044
|
);
|
|
962
1045
|
}
|
|
963
|
-
|
|
964
|
-
|
|
965
|
-
|
|
966
|
-
|
|
967
|
-
|
|
968
|
-
|
|
969
|
-
|
|
1046
|
+
const installedPaths = skillResult.isOk() ? skillResult.value.paths : [];
|
|
1047
|
+
return outputAndExit(
|
|
1048
|
+
successResponse(
|
|
1049
|
+
toJsonObject({
|
|
1050
|
+
url: origin.url,
|
|
1051
|
+
title: origin.title,
|
|
1052
|
+
description: origin.description,
|
|
1053
|
+
installed: installedPaths,
|
|
1054
|
+
note: "Restart your MCP server for this origin to appear in the model context.",
|
|
1055
|
+
...origin.warnings.length > 0 && { warnings: origin.warnings }
|
|
970
1056
|
})
|
|
971
|
-
)
|
|
972
|
-
|
|
973
|
-
|
|
974
|
-
|
|
975
|
-
|
|
976
|
-
|
|
977
|
-
|
|
978
|
-
|
|
979
|
-
|
|
980
|
-
|
|
981
|
-
|
|
982
|
-
|
|
983
|
-
|
|
984
|
-
|
|
985
|
-
|
|
986
|
-
|
|
987
|
-
|
|
988
|
-
|
|
989
|
-
|
|
1057
|
+
),
|
|
1058
|
+
flags
|
|
1059
|
+
);
|
|
1060
|
+
}
|
|
1061
|
+
|
|
1062
|
+
// src/cli/commands/origins.ts
|
|
1063
|
+
var SURFACE8 = "cli:origins";
|
|
1064
|
+
async function originsAddCommand(args, flags) {
|
|
1065
|
+
const resolved = await resolveOrigin(args.url, SURFACE8);
|
|
1066
|
+
if (!resolved.ok) return outputAndExit(resolved.error, flags);
|
|
1067
|
+
const origin = addUserOrigin(resolved.origin);
|
|
1068
|
+
return outputAndExit(
|
|
1069
|
+
successResponse({
|
|
1070
|
+
url: origin.url,
|
|
1071
|
+
title: origin.title,
|
|
1072
|
+
description: origin.description,
|
|
1073
|
+
note: "Restart your MCP server for this origin to appear in the model context.",
|
|
1074
|
+
...resolved.origin.warnings.length > 0 && {
|
|
1075
|
+
warnings: resolved.origin.warnings
|
|
1076
|
+
}
|
|
1077
|
+
}),
|
|
1078
|
+
flags
|
|
1079
|
+
);
|
|
1080
|
+
}
|
|
1081
|
+
function originsListCommand(_args, flags) {
|
|
1082
|
+
const primary = PRIMARY_ORIGINS.flatMap((o) => {
|
|
1083
|
+
const meta = ORIGIN_METADATA[o];
|
|
1084
|
+
return meta ? [{ url: o, title: meta.title, description: meta.description }] : [];
|
|
1085
|
+
});
|
|
1086
|
+
const added = loadUserOrigins();
|
|
1087
|
+
return outputAndExit(successResponse({ primary, added }), flags);
|
|
1088
|
+
}
|
|
1089
|
+
function originsRemoveCommand(args, flags) {
|
|
1090
|
+
const url = /^https?:\/\//i.test(args.url) ? args.url : `https://${args.url}`;
|
|
1091
|
+
const result = removeUserOrigin(url);
|
|
1092
|
+
if (!result.removed) {
|
|
1093
|
+
const isPrimary = PRIMARY_ORIGINS.some((o) => String(o) === url);
|
|
990
1094
|
return outputAndExit(
|
|
991
|
-
|
|
992
|
-
|
|
993
|
-
|
|
994
|
-
|
|
1095
|
+
errorResponse(
|
|
1096
|
+
isPrimary ? {
|
|
1097
|
+
code: "GENERAL_ERROR",
|
|
1098
|
+
message: `Cannot remove primary origin: ${url}. Only user-added origins can be removed.`,
|
|
1099
|
+
surface: SURFACE8,
|
|
1100
|
+
cause: "primary_origin"
|
|
1101
|
+
} : {
|
|
1102
|
+
code: "GENERAL_ERROR",
|
|
1103
|
+
message: `Origin not found: ${url}`,
|
|
1104
|
+
surface: SURFACE8,
|
|
1105
|
+
cause: "not_found"
|
|
1106
|
+
}
|
|
995
1107
|
),
|
|
996
1108
|
flags
|
|
997
1109
|
);
|
|
998
|
-
} finally {
|
|
999
|
-
await fs2.rm(tmpDir, { recursive: true, force: true });
|
|
1000
1110
|
}
|
|
1111
|
+
return outputAndExit(successResponse({ removed: true, url }), flags);
|
|
1001
1112
|
}
|
|
1002
1113
|
|
|
1003
1114
|
// src/cli/commands/onboard.ts
|
|
@@ -1017,7 +1128,7 @@ var agentClientMap = {
|
|
|
1017
1128
|
Cursor: "cursor" /* Cursor */,
|
|
1018
1129
|
"Gemini CLI": "gemini-cli" /* GeminiCli */,
|
|
1019
1130
|
Goose: "goose" /* Goose */,
|
|
1020
|
-
OpenCode: "opencode" /*
|
|
1131
|
+
OpenCode: "opencode" /* OpenCode */,
|
|
1021
1132
|
Roo: "roo-cline" /* RooCline */,
|
|
1022
1133
|
Windsurf: "windsurf" /* Windsurf */
|
|
1023
1134
|
};
|
|
@@ -1225,7 +1336,7 @@ function formatDemoPromptsJson(baseUrl) {
|
|
|
1225
1336
|
}
|
|
1226
1337
|
|
|
1227
1338
|
// src/cli/commands/onboard.ts
|
|
1228
|
-
var
|
|
1339
|
+
var SURFACE9 = "cli:onboard";
|
|
1229
1340
|
var AGENTCASH_SKILL = {
|
|
1230
1341
|
owner: "merit-systems",
|
|
1231
1342
|
repo: "agentcash-skills",
|
|
@@ -1287,14 +1398,14 @@ function installAgentcashWalletSkill() {
|
|
|
1287
1398
|
const detectedAgents = detect();
|
|
1288
1399
|
return resultFromPromise(
|
|
1289
1400
|
"skill",
|
|
1290
|
-
|
|
1401
|
+
SURFACE9,
|
|
1291
1402
|
(async () => {
|
|
1292
1403
|
const tmpDir = await fs5.mkdtemp(
|
|
1293
1404
|
path5.join(os4.tmpdir(), "agentcash-onboard-")
|
|
1294
1405
|
);
|
|
1295
1406
|
const installPromise = (async () => {
|
|
1296
1407
|
const downloaded = await downloadGitHubSkill(
|
|
1297
|
-
|
|
1408
|
+
SURFACE9,
|
|
1298
1409
|
AGENTCASH_SKILL,
|
|
1299
1410
|
tmpDir
|
|
1300
1411
|
);
|
|
@@ -1357,7 +1468,7 @@ async function onboardCommand(args, flags) {
|
|
|
1357
1468
|
errorResponse({
|
|
1358
1469
|
code: "GENERAL_ERROR",
|
|
1359
1470
|
message: skillInstallResult.error.message,
|
|
1360
|
-
surface:
|
|
1471
|
+
surface: SURFACE9,
|
|
1361
1472
|
cause: "skill_install_failed"
|
|
1362
1473
|
}),
|
|
1363
1474
|
flags
|
|
@@ -1374,7 +1485,7 @@ async function onboardCommand(args, flags) {
|
|
|
1374
1485
|
address,
|
|
1375
1486
|
code: args.code,
|
|
1376
1487
|
dev: flags.dev,
|
|
1377
|
-
surface:
|
|
1488
|
+
surface: SURFACE9
|
|
1378
1489
|
});
|
|
1379
1490
|
if (redeemResult.isErr()) {
|
|
1380
1491
|
const format2 = getOutputFormat(flags.format);
|
|
@@ -1425,7 +1536,7 @@ async function onboardCommand(args, flags) {
|
|
|
1425
1536
|
redeemValue = redeemResult.value;
|
|
1426
1537
|
}
|
|
1427
1538
|
progress(flags, "Fetching wallet balance...");
|
|
1428
|
-
const walletInfoResult = await getWalletInfo(
|
|
1539
|
+
const walletInfoResult = await getWalletInfo(SURFACE9, address, flags);
|
|
1429
1540
|
const walletInfo = walletInfoResult.isOk() ? walletInfoResult.value : void 0;
|
|
1430
1541
|
if (!args.code && (!walletInfo?.balance || walletInfo.balance <= 0)) {
|
|
1431
1542
|
const cta = getOnboardingCta(address, flags);
|
|
@@ -1433,7 +1544,7 @@ async function onboardCommand(args, flags) {
|
|
|
1433
1544
|
errorResponse({
|
|
1434
1545
|
code: "GENERAL_ERROR",
|
|
1435
1546
|
message: cta.message,
|
|
1436
|
-
surface:
|
|
1547
|
+
surface: SURFACE9,
|
|
1437
1548
|
cause: "no_funds"
|
|
1438
1549
|
}),
|
|
1439
1550
|
flags
|
|
@@ -1556,6 +1667,12 @@ async function tryCommand(args, flags) {
|
|
|
1556
1667
|
`If you have the AgentCash MCP installed, you can also call this directly using the check_endpoint_schema and fetch tools.`
|
|
1557
1668
|
].join("\n");
|
|
1558
1669
|
}
|
|
1670
|
+
const modelInstructions = [
|
|
1671
|
+
`Present the originSummary to the user, then ask them what they would like to do \u2014 e.g. "What would you like to do with ${title}?"`,
|
|
1672
|
+
...onboardingCta ? [
|
|
1673
|
+
`IMPORTANT: The user has not yet onboarded. Show the onboard link VERBATIM as a clickable URL so the user can click it: ${onboardingCta.onboardLink}`
|
|
1674
|
+
] : []
|
|
1675
|
+
].join("\n");
|
|
1559
1676
|
return outputAndExit(
|
|
1560
1677
|
successResponse({
|
|
1561
1678
|
...onboardingCta ? {
|
|
@@ -1563,7 +1680,8 @@ async function tryCommand(args, flags) {
|
|
|
1563
1680
|
onboardLink: onboardingCta.onboardLink
|
|
1564
1681
|
} : {},
|
|
1565
1682
|
originSummary,
|
|
1566
|
-
...callToAction ? { callToAction } : {}
|
|
1683
|
+
...callToAction ? { callToAction } : {},
|
|
1684
|
+
modelInstructions
|
|
1567
1685
|
}),
|
|
1568
1686
|
flags
|
|
1569
1687
|
);
|
|
@@ -1575,6 +1693,9 @@ export {
|
|
|
1575
1693
|
fetchAuthCommand,
|
|
1576
1694
|
fetchCommand,
|
|
1577
1695
|
onboardCommand,
|
|
1696
|
+
originsAddCommand,
|
|
1697
|
+
originsListCommand,
|
|
1698
|
+
originsRemoveCommand,
|
|
1578
1699
|
registerCommand,
|
|
1579
1700
|
reportErrorCommand,
|
|
1580
1701
|
serverCommand,
|
|
@@ -1583,4 +1704,4 @@ export {
|
|
|
1583
1704
|
walletInfoCommand,
|
|
1584
1705
|
walletRedeemCommand
|
|
1585
1706
|
};
|
|
1586
|
-
//# sourceMappingURL=commands-
|
|
1707
|
+
//# sourceMappingURL=commands-YSOBBE4N.js.map
|