@t2000/cli 5.27.0 → 5.29.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js
CHANGED
|
@@ -31873,13 +31873,19 @@ function registerExport(program3) {
|
|
|
31873
31873
|
var import_qrcode = __toESM(require_lib4(), 1);
|
|
31874
31874
|
var import_picocolors2 = __toESM(require_picocolors(), 1);
|
|
31875
31875
|
var VALUE_PROMISE = "$5 USDC \u2248 ~250 paid API calls (at the $0.02 floor).";
|
|
31876
|
+
var CARD_HINT = "No USDC yet? Buy some with a card: https://agents.t2000.ai/manage/topup (then My agents \u2192 Fund, or send to the address above).";
|
|
31876
31877
|
function registerFund(program3) {
|
|
31877
31878
|
program3.command("fund").description("Show your wallet address + QR to fund it (USDC / USDsui / SUI on Sui)").option("--key <path>", "Custom wallet path (default ~/.t2000/wallet.key)").option("--qr-only", "Print only the QR code (no address text)").action(async (opts) => {
|
|
31878
31879
|
try {
|
|
31879
31880
|
const agent = await withAgent({ keyPath: opts.key });
|
|
31880
31881
|
const address = agent.address();
|
|
31881
31882
|
if (isJsonMode()) {
|
|
31882
|
-
printJson({
|
|
31883
|
+
printJson({
|
|
31884
|
+
address,
|
|
31885
|
+
qrEncodedFor: address,
|
|
31886
|
+
valuePromise: VALUE_PROMISE,
|
|
31887
|
+
cardTopupUrl: "https://agents.t2000.ai/manage/topup"
|
|
31888
|
+
});
|
|
31883
31889
|
return;
|
|
31884
31890
|
}
|
|
31885
31891
|
printBlank();
|
|
@@ -31900,6 +31906,7 @@ function registerFund(program3) {
|
|
|
31900
31906
|
`);
|
|
31901
31907
|
if (!opts.qrOnly) {
|
|
31902
31908
|
printLine(import_picocolors2.default.dim("Or share `" + address + "` directly."));
|
|
31909
|
+
printLine(import_picocolors2.default.dim(CARD_HINT));
|
|
31903
31910
|
printBlank();
|
|
31904
31911
|
}
|
|
31905
31912
|
} catch (error) {
|
|
@@ -33115,7 +33122,7 @@ function registerMcpStart(parent) {
|
|
|
33115
33122
|
parent.command("start", { isDefault: true }).description("Start MCP server (stdio transport \u2014 for AI client integration)").option("--key <path>", "Custom wallet path (default ~/.t2000/wallet.key)").action(async (opts) => {
|
|
33116
33123
|
let mod3;
|
|
33117
33124
|
try {
|
|
33118
|
-
mod3 = await import("./dist-
|
|
33125
|
+
mod3 = await import("./dist-D6VG3LUN.js");
|
|
33119
33126
|
} catch {
|
|
33120
33127
|
console.error("MCP server not installed. Run:\n npm install -g @t2000/mcp");
|
|
33121
33128
|
process.exit(1);
|
|
@@ -33225,6 +33232,10 @@ Subcommands:
|
|
|
33225
33232
|
registerMcpUninstall(group);
|
|
33226
33233
|
}
|
|
33227
33234
|
|
|
33235
|
+
// src/commands/skills/check.ts
|
|
33236
|
+
import { readdir, readFile as readFile3 } from "fs/promises";
|
|
33237
|
+
import { join as join5 } from "path";
|
|
33238
|
+
|
|
33228
33239
|
// src/commands/skills/lib.ts
|
|
33229
33240
|
import { stat } from "fs/promises";
|
|
33230
33241
|
import { join as join4 } from "path";
|
|
@@ -33298,6 +33309,133 @@ async function dirExists(path2) {
|
|
|
33298
33309
|
}
|
|
33299
33310
|
}
|
|
33300
33311
|
|
|
33312
|
+
// src/commands/skills/check.ts
|
|
33313
|
+
function slugFromEntry(entry, target) {
|
|
33314
|
+
return target === "cursor" ? entry.replace(/\.mdc$/, "") : entry;
|
|
33315
|
+
}
|
|
33316
|
+
async function installedSlugs(dir, target) {
|
|
33317
|
+
try {
|
|
33318
|
+
const entries = await readdir(dir);
|
|
33319
|
+
return entries.map((e) => slugFromEntry(e, target)).filter((slug) => isManagedSkillName(slug));
|
|
33320
|
+
} catch {
|
|
33321
|
+
return [];
|
|
33322
|
+
}
|
|
33323
|
+
}
|
|
33324
|
+
function classifyContent(installed, served) {
|
|
33325
|
+
if (served === null) {
|
|
33326
|
+
return "retired";
|
|
33327
|
+
}
|
|
33328
|
+
return installed.trim() === served.trim() ? "up-to-date" : "drifted";
|
|
33329
|
+
}
|
|
33330
|
+
async function checkTargetScope(manifest, servedCache, target, scope) {
|
|
33331
|
+
const dir = resolveTargetDir(target, scope === "global");
|
|
33332
|
+
if (!await dirExists(dir)) {
|
|
33333
|
+
return [];
|
|
33334
|
+
}
|
|
33335
|
+
const slugs = await installedSlugs(dir, target);
|
|
33336
|
+
const rows = [];
|
|
33337
|
+
for (const slug of slugs) {
|
|
33338
|
+
const path2 = join5(dir, filenameForTarget(slug, target));
|
|
33339
|
+
let installed;
|
|
33340
|
+
try {
|
|
33341
|
+
installed = await readFile3(path2, "utf-8");
|
|
33342
|
+
} catch {
|
|
33343
|
+
continue;
|
|
33344
|
+
}
|
|
33345
|
+
const entry = manifest.skills.find((s) => s.name === slug);
|
|
33346
|
+
let served = null;
|
|
33347
|
+
if (entry) {
|
|
33348
|
+
const cacheKey = `${target}:${slug}`;
|
|
33349
|
+
const cached = servedCache.get(cacheKey);
|
|
33350
|
+
if (cached !== void 0) {
|
|
33351
|
+
served = cached;
|
|
33352
|
+
} else {
|
|
33353
|
+
const raw = await fetchSkill(entry.url);
|
|
33354
|
+
served = transformForTarget(raw, target, entry.description);
|
|
33355
|
+
servedCache.set(cacheKey, served);
|
|
33356
|
+
}
|
|
33357
|
+
}
|
|
33358
|
+
rows.push({
|
|
33359
|
+
name: slug,
|
|
33360
|
+
target,
|
|
33361
|
+
scope,
|
|
33362
|
+
path: path2,
|
|
33363
|
+
status: classifyContent(installed, served)
|
|
33364
|
+
});
|
|
33365
|
+
}
|
|
33366
|
+
return rows;
|
|
33367
|
+
}
|
|
33368
|
+
function registerSkillsCheck(parent) {
|
|
33369
|
+
parent.command("check").description(
|
|
33370
|
+
"Compare installed skills against what t2000.ai serves \u2014 { upToDate, action } for agents"
|
|
33371
|
+
).option(
|
|
33372
|
+
"--target <name>",
|
|
33373
|
+
"Only check one target layout: agents, cursor, claude-code (default: all)"
|
|
33374
|
+
).action(async (opts) => {
|
|
33375
|
+
try {
|
|
33376
|
+
const targets = opts.target ? [
|
|
33377
|
+
(() => {
|
|
33378
|
+
const match = SKILL_TARGETS.find((t) => t === opts.target);
|
|
33379
|
+
if (!match) {
|
|
33380
|
+
throw new Error(
|
|
33381
|
+
`--target must be one of: ${SKILL_TARGETS.join(", ")}. Got: "${opts.target}"`
|
|
33382
|
+
);
|
|
33383
|
+
}
|
|
33384
|
+
return match;
|
|
33385
|
+
})()
|
|
33386
|
+
] : SKILL_TARGETS;
|
|
33387
|
+
const manifest = await fetchManifest();
|
|
33388
|
+
const servedCache = /* @__PURE__ */ new Map();
|
|
33389
|
+
const rows = [];
|
|
33390
|
+
for (const target of targets) {
|
|
33391
|
+
rows.push(
|
|
33392
|
+
...await checkTargetScope(manifest, servedCache, target, "local"),
|
|
33393
|
+
...await checkTargetScope(manifest, servedCache, target, "global")
|
|
33394
|
+
);
|
|
33395
|
+
}
|
|
33396
|
+
const stale = rows.filter((r) => r.status !== "up-to-date");
|
|
33397
|
+
const upToDate = rows.length > 0 && stale.length === 0;
|
|
33398
|
+
if (isJsonMode()) {
|
|
33399
|
+
printJson({
|
|
33400
|
+
upToDate: rows.length === 0 ? true : upToDate,
|
|
33401
|
+
installed: rows.length,
|
|
33402
|
+
manifestVersion: manifest.version,
|
|
33403
|
+
skills: rows,
|
|
33404
|
+
action: stale.length > 0 ? "t2 skills install" : void 0
|
|
33405
|
+
});
|
|
33406
|
+
return;
|
|
33407
|
+
}
|
|
33408
|
+
printBlank();
|
|
33409
|
+
if (rows.length === 0) {
|
|
33410
|
+
printInfo(
|
|
33411
|
+
"No installed skills found (checked ./ and ~/ for .agents/skills, .cursor/rules, .claude/skills)."
|
|
33412
|
+
);
|
|
33413
|
+
printInfo("Install: t2 skills install \xB7 MCP clients: t2 mcp install (no files, always fresh)");
|
|
33414
|
+
printBlank();
|
|
33415
|
+
return;
|
|
33416
|
+
}
|
|
33417
|
+
for (const r of rows) {
|
|
33418
|
+
const mark2 = r.status === "up-to-date" ? "\u2713" : r.status === "drifted" ? "\u21BB" : "\u2717";
|
|
33419
|
+
console.log(` ${mark2} ${r.name} [${r.target} \xB7 ${r.scope}] ${r.status}`);
|
|
33420
|
+
}
|
|
33421
|
+
printBlank();
|
|
33422
|
+
if (upToDate) {
|
|
33423
|
+
printSuccess(`All ${rows.length} installed skills match what t2000.ai serves.`);
|
|
33424
|
+
} else {
|
|
33425
|
+
printInfo(
|
|
33426
|
+
`${stale.length} of ${rows.length} installed skills are stale \u2014 refresh with: t2 skills install`
|
|
33427
|
+
);
|
|
33428
|
+
if (stale.some((r) => r.status === "retired")) {
|
|
33429
|
+
printInfo("(\u2717 retired = no longer in the manifest \u2014 remove with: t2 skills uninstall)");
|
|
33430
|
+
}
|
|
33431
|
+
}
|
|
33432
|
+
printBlank();
|
|
33433
|
+
} catch (err) {
|
|
33434
|
+
handleError(err);
|
|
33435
|
+
}
|
|
33436
|
+
});
|
|
33437
|
+
}
|
|
33438
|
+
|
|
33301
33439
|
// src/commands/skills/list.ts
|
|
33302
33440
|
function registerSkillsList(parent) {
|
|
33303
33441
|
parent.command("list").description("List skills available from t2000.ai (core t2000 + MPP recipes)").action(async () => {
|
|
@@ -33325,7 +33463,7 @@ function registerSkillsList(parent) {
|
|
|
33325
33463
|
|
|
33326
33464
|
// src/commands/skills/install.ts
|
|
33327
33465
|
import { writeFile as writeFile3, mkdir as mkdir3 } from "fs/promises";
|
|
33328
|
-
import { join as
|
|
33466
|
+
import { join as join6 } from "path";
|
|
33329
33467
|
function registerSkillsInstall(parent) {
|
|
33330
33468
|
parent.command("install [slug]").description("Install all skills (or one named slug) into a local directory").option("--target <name>", "Target client layout: agents (default), cursor, claude-code", "agents").option("--global", "Install to ~/.<target>/ instead of <cwd>/.<target>/").action(async (slug, opts) => {
|
|
33331
33469
|
try {
|
|
@@ -33346,8 +33484,8 @@ function registerSkillsInstall(parent) {
|
|
|
33346
33484
|
const raw = await fetchSkill(s.url);
|
|
33347
33485
|
const transformed = transformForTarget(raw, target, s.description);
|
|
33348
33486
|
const relPath = filenameForTarget(s.name, target);
|
|
33349
|
-
const fullPath =
|
|
33350
|
-
await mkdir3(
|
|
33487
|
+
const fullPath = join6(targetDir, relPath);
|
|
33488
|
+
await mkdir3(join6(fullPath, ".."), { recursive: true });
|
|
33351
33489
|
await writeFile3(fullPath, transformed, "utf-8");
|
|
33352
33490
|
installed.push({ name: s.name, path: fullPath });
|
|
33353
33491
|
}
|
|
@@ -33375,8 +33513,8 @@ function registerSkillsInstall(parent) {
|
|
|
33375
33513
|
}
|
|
33376
33514
|
|
|
33377
33515
|
// src/commands/skills/uninstall.ts
|
|
33378
|
-
import { readdir, unlink, rmdir } from "fs/promises";
|
|
33379
|
-
import { join as
|
|
33516
|
+
import { readdir as readdir2, unlink, rmdir } from "fs/promises";
|
|
33517
|
+
import { join as join7 } from "path";
|
|
33380
33518
|
function registerSkillsUninstall(parent) {
|
|
33381
33519
|
parent.command("uninstall").description("Remove installed t2000 + MPP skills from the target directory").option("--target <name>", "Target client layout: agents (default), cursor, claude-code", "agents").option("--global", "Uninstall from ~/.<target>/ instead of <cwd>/.<target>/").action(async (opts) => {
|
|
33382
33520
|
try {
|
|
@@ -33391,10 +33529,10 @@ function registerSkillsUninstall(parent) {
|
|
|
33391
33529
|
printInfo(`No skills installed at ${targetDir}`);
|
|
33392
33530
|
return;
|
|
33393
33531
|
}
|
|
33394
|
-
const entries = await
|
|
33532
|
+
const entries = await readdir2(targetDir);
|
|
33395
33533
|
const removed = [];
|
|
33396
33534
|
for (const entry of entries) {
|
|
33397
|
-
const full =
|
|
33535
|
+
const full = join7(targetDir, entry);
|
|
33398
33536
|
if (target === "cursor") {
|
|
33399
33537
|
const slug = entry.endsWith(".mdc") ? entry.slice(0, -".mdc".length) : entry;
|
|
33400
33538
|
if (entry.endsWith(".mdc") && isManagedSkillName(slug)) {
|
|
@@ -33403,7 +33541,7 @@ function registerSkillsUninstall(parent) {
|
|
|
33403
33541
|
}
|
|
33404
33542
|
} else {
|
|
33405
33543
|
if (isManagedSkillName(entry)) {
|
|
33406
|
-
const skillFile =
|
|
33544
|
+
const skillFile = join7(full, "SKILL.md");
|
|
33407
33545
|
try {
|
|
33408
33546
|
await unlink(skillFile);
|
|
33409
33547
|
} catch {
|
|
@@ -33443,6 +33581,7 @@ Subcommands:
|
|
|
33443
33581
|
$ t2 skills install Install all skills (default target: agents)
|
|
33444
33582
|
$ t2 skills install <slug> Install one skill by name
|
|
33445
33583
|
$ t2 skills install --target cursor Install as Cursor .mdc rules
|
|
33584
|
+
$ t2 skills check Are installed skills current? (agents: run at session start)
|
|
33446
33585
|
$ t2 skills uninstall Remove installed skills
|
|
33447
33586
|
|
|
33448
33587
|
For MCP-aware clients (Claude Desktop, Cursor, Windsurf), prefer
|
|
@@ -33451,16 +33590,174 @@ For MCP-aware clients (Claude Desktop, Cursor, Windsurf), prefer
|
|
|
33451
33590
|
);
|
|
33452
33591
|
registerSkillsList(group);
|
|
33453
33592
|
registerSkillsInstall(group);
|
|
33593
|
+
registerSkillsCheck(group);
|
|
33454
33594
|
registerSkillsUninstall(group);
|
|
33455
33595
|
}
|
|
33456
33596
|
|
|
33457
33597
|
// src/commands/agent/index.ts
|
|
33458
33598
|
import { createHash as createHash3 } from "crypto";
|
|
33459
33599
|
|
|
33600
|
+
// src/commands/agent/create.ts
|
|
33601
|
+
var DEFAULT_API_BASE3 = process.env.T2000_API_URL ?? "https://api.t2000.ai/v1";
|
|
33602
|
+
var STORE_BASE = "https://agents.t2000.ai";
|
|
33603
|
+
var AGENT_CATEGORIES = [
|
|
33604
|
+
"ai-models",
|
|
33605
|
+
"data-feeds",
|
|
33606
|
+
"finance",
|
|
33607
|
+
"research",
|
|
33608
|
+
"dev-tools",
|
|
33609
|
+
"creative",
|
|
33610
|
+
"other"
|
|
33611
|
+
];
|
|
33612
|
+
var DEFAULT_PER_TX_USD2 = 25;
|
|
33613
|
+
var DEFAULT_DAILY_USD2 = 100;
|
|
33614
|
+
async function fetchJson(url, init) {
|
|
33615
|
+
const res = await fetch(url, {
|
|
33616
|
+
method: init?.method ?? "GET",
|
|
33617
|
+
headers: init?.body ? { "Content-Type": "application/json" } : void 0,
|
|
33618
|
+
body: init?.body ? JSON.stringify(init.body) : void 0
|
|
33619
|
+
});
|
|
33620
|
+
const json = await res.json().catch(() => ({}));
|
|
33621
|
+
if (!res.ok) {
|
|
33622
|
+
const err = json.error;
|
|
33623
|
+
const msg = typeof err === "string" ? err : err?.message ?? `HTTP ${res.status}`;
|
|
33624
|
+
throw new Error(msg);
|
|
33625
|
+
}
|
|
33626
|
+
return json;
|
|
33627
|
+
}
|
|
33628
|
+
function registerAgentCreate(group) {
|
|
33629
|
+
group.command("create").description(
|
|
33630
|
+
"Create an agent in one pass \u2014 wallet + on-chain Agent ID + profile (+ optional owner link). Sponsored, gasless."
|
|
33631
|
+
).requiredOption("--name <name>", "Display name (shown in the store)").option("--description <text>", "Short description (what it does, for whom)").option(
|
|
33632
|
+
"--category <category>",
|
|
33633
|
+
`Storefront category: ${AGENT_CATEGORIES.join(" | ")}`
|
|
33634
|
+
).option(
|
|
33635
|
+
"--owner <address>",
|
|
33636
|
+
"Propose a Passport owner (confirm at agents.t2000.ai \u2192 My agents)"
|
|
33637
|
+
).option("--key <path>", "Custom wallet path (default ~/.t2000/wallet.key)").option("--api <url>", `API base URL (default ${DEFAULT_API_BASE3})`).action(async (opts) => {
|
|
33638
|
+
try {
|
|
33639
|
+
const base = opts.api ?? DEFAULT_API_BASE3;
|
|
33640
|
+
const name = opts.name.trim();
|
|
33641
|
+
if (!name) {
|
|
33642
|
+
throw new Error("--name must not be empty.");
|
|
33643
|
+
}
|
|
33644
|
+
if (name.length > 60) {
|
|
33645
|
+
throw new Error("--name must be 60 characters or fewer.");
|
|
33646
|
+
}
|
|
33647
|
+
let category;
|
|
33648
|
+
if (opts.category !== void 0) {
|
|
33649
|
+
const c = opts.category.trim().toLowerCase();
|
|
33650
|
+
if (!AGENT_CATEGORIES.includes(c)) {
|
|
33651
|
+
throw new Error(
|
|
33652
|
+
`--category must be one of: ${AGENT_CATEGORIES.join(", ")} (got "${opts.category}").`
|
|
33653
|
+
);
|
|
33654
|
+
}
|
|
33655
|
+
category = c;
|
|
33656
|
+
}
|
|
33657
|
+
let owner;
|
|
33658
|
+
if (opts.owner !== void 0) {
|
|
33659
|
+
owner = normalizeSuiAddress(opts.owner.trim());
|
|
33660
|
+
if (!isValidSuiAddress(owner)) {
|
|
33661
|
+
throw new Error("--owner must be a valid Sui address.");
|
|
33662
|
+
}
|
|
33663
|
+
}
|
|
33664
|
+
const created = !await walletExists(opts.key);
|
|
33665
|
+
if (created) {
|
|
33666
|
+
const keypair = generateKeypair();
|
|
33667
|
+
await saveKey(keypair, void 0, opts.key);
|
|
33668
|
+
if (!hasLimits()) {
|
|
33669
|
+
setLimits({
|
|
33670
|
+
perTxUsd: DEFAULT_PER_TX_USD2,
|
|
33671
|
+
dailyUsd: DEFAULT_DAILY_USD2
|
|
33672
|
+
});
|
|
33673
|
+
}
|
|
33674
|
+
}
|
|
33675
|
+
const agent = await withAgent({ keyPath: opts.key });
|
|
33676
|
+
const address = agent.address();
|
|
33677
|
+
const reg = await registerWallet({
|
|
33678
|
+
keypair: agent.keypair,
|
|
33679
|
+
address,
|
|
33680
|
+
base
|
|
33681
|
+
});
|
|
33682
|
+
const challenge = await fetchJson(`${base}/agent/challenge`, {
|
|
33683
|
+
method: "POST",
|
|
33684
|
+
body: { address }
|
|
33685
|
+
});
|
|
33686
|
+
const nonce = challenge.nonce;
|
|
33687
|
+
if (!nonce) {
|
|
33688
|
+
throw new Error("Failed to get a challenge nonce.");
|
|
33689
|
+
}
|
|
33690
|
+
const message = new TextEncoder().encode(
|
|
33691
|
+
`t2000-agent-profile:${nonce}`
|
|
33692
|
+
);
|
|
33693
|
+
const { signature } = await agent.keypair.signPersonalMessage(message);
|
|
33694
|
+
await fetchJson(`${base}/agent/profile`, {
|
|
33695
|
+
method: "POST",
|
|
33696
|
+
body: {
|
|
33697
|
+
address,
|
|
33698
|
+
nonce,
|
|
33699
|
+
signature,
|
|
33700
|
+
displayName: name,
|
|
33701
|
+
description: opts.description,
|
|
33702
|
+
category
|
|
33703
|
+
}
|
|
33704
|
+
});
|
|
33705
|
+
let ownerProposed = false;
|
|
33706
|
+
if (owner) {
|
|
33707
|
+
await runSponsoredTx({
|
|
33708
|
+
keypair: agent.keypair,
|
|
33709
|
+
actor: address,
|
|
33710
|
+
prepareUrl: `${base}/agent/owner/propose`,
|
|
33711
|
+
prepareBody: { address, owner },
|
|
33712
|
+
submitUrl: `${base}/agent/owner/submit`
|
|
33713
|
+
});
|
|
33714
|
+
ownerProposed = true;
|
|
33715
|
+
}
|
|
33716
|
+
const storeUrl = `${STORE_BASE}/${address}`;
|
|
33717
|
+
if (isJsonMode()) {
|
|
33718
|
+
printJson({
|
|
33719
|
+
address,
|
|
33720
|
+
walletCreated: created,
|
|
33721
|
+
registered: true,
|
|
33722
|
+
alreadyRegistered: reg.alreadyRegistered,
|
|
33723
|
+
name,
|
|
33724
|
+
...category ? { category } : {},
|
|
33725
|
+
...ownerProposed ? { ownerProposed: owner } : {},
|
|
33726
|
+
storeUrl,
|
|
33727
|
+
keyPath: opts.key ?? "~/.t2000/wallet.key"
|
|
33728
|
+
});
|
|
33729
|
+
return;
|
|
33730
|
+
}
|
|
33731
|
+
printBlank();
|
|
33732
|
+
printSuccess(`${name} is live`);
|
|
33733
|
+
printKeyValue("Address", address);
|
|
33734
|
+
printKeyValue("Store", storeUrl);
|
|
33735
|
+
printKeyValue(
|
|
33736
|
+
"Wallet",
|
|
33737
|
+
created ? `created at ${opts.key ?? "~/.t2000/wallet.key"}` : `reused ${opts.key ?? "~/.t2000/wallet.key"}`
|
|
33738
|
+
);
|
|
33739
|
+
if (ownerProposed) {
|
|
33740
|
+
printKeyValue(
|
|
33741
|
+
"Owner",
|
|
33742
|
+
`proposed ${owner} \u2014 confirm at ${STORE_BASE}/manage/agents`
|
|
33743
|
+
);
|
|
33744
|
+
}
|
|
33745
|
+
printBlank();
|
|
33746
|
+
printLine("Next:");
|
|
33747
|
+
printLine(" t2 fund # add USDC (QR / card link)");
|
|
33748
|
+
printLine(" t2 agent services add ... # list something to sell");
|
|
33749
|
+
printLine(" t2 agent deploy ... # wrap an API behind x402");
|
|
33750
|
+
printBlank();
|
|
33751
|
+
} catch (error) {
|
|
33752
|
+
handleError(error);
|
|
33753
|
+
}
|
|
33754
|
+
});
|
|
33755
|
+
}
|
|
33756
|
+
|
|
33460
33757
|
// src/commands/agent/review.ts
|
|
33461
33758
|
import { createHash } from "crypto";
|
|
33462
33759
|
var DEFAULT_GATEWAY = "https://x402.t2000.ai";
|
|
33463
|
-
async function
|
|
33760
|
+
async function fetchJson2(url, init) {
|
|
33464
33761
|
const res = await fetch(url, {
|
|
33465
33762
|
method: init?.method ?? "GET",
|
|
33466
33763
|
headers: init?.body ? { "Content-Type": "application/json" } : void 0,
|
|
@@ -33496,7 +33793,7 @@ function registerAgentReview(agent) {
|
|
|
33496
33793
|
const buyer = agentW.address();
|
|
33497
33794
|
let digest = (opts.digest ?? "").trim();
|
|
33498
33795
|
if (!digest) {
|
|
33499
|
-
const res = await
|
|
33796
|
+
const res = await fetchJson2(
|
|
33500
33797
|
`${gateway}/commerce/review?buyer=${buyer}&seller=${encodeURIComponent(seller)}`
|
|
33501
33798
|
);
|
|
33502
33799
|
const reviewable = res.reviewable ?? [];
|
|
@@ -33512,7 +33809,7 @@ function registerAgentReview(agent) {
|
|
|
33512
33809
|
reviewMessage(digest, stars, text, timestamp)
|
|
33513
33810
|
);
|
|
33514
33811
|
const { signature } = await agentW.keypair.signPersonalMessage(message);
|
|
33515
|
-
await
|
|
33812
|
+
await fetchJson2(`${gateway}/commerce/review`, {
|
|
33516
33813
|
method: "POST",
|
|
33517
33814
|
body: { digest, stars, text, timestamp, signature }
|
|
33518
33815
|
});
|
|
@@ -33541,7 +33838,7 @@ function registerAgentReview(agent) {
|
|
|
33541
33838
|
import { createHash as createHash2 } from "crypto";
|
|
33542
33839
|
import { readFileSync as readFileSync3 } from "fs";
|
|
33543
33840
|
var SLUG_RE = /^[a-z0-9][a-z0-9-]{1,39}$/;
|
|
33544
|
-
async function
|
|
33841
|
+
async function fetchJson3(url, init) {
|
|
33545
33842
|
const res = await fetch(url, {
|
|
33546
33843
|
method: init?.method ?? "GET",
|
|
33547
33844
|
headers: init?.body ? { "Content-Type": "application/json" } : void 0,
|
|
@@ -33565,7 +33862,7 @@ function canonicalServicesJson(services) {
|
|
|
33565
33862
|
);
|
|
33566
33863
|
}
|
|
33567
33864
|
async function getCatalog(base, address) {
|
|
33568
|
-
const res = await
|
|
33865
|
+
const res = await fetchJson3(
|
|
33569
33866
|
`${base}/agent/services?address=${encodeURIComponent(address)}`
|
|
33570
33867
|
);
|
|
33571
33868
|
return Array.isArray(res.services) ? res.services : [];
|
|
@@ -33573,7 +33870,7 @@ async function getCatalog(base, address) {
|
|
|
33573
33870
|
async function putCatalog(opts) {
|
|
33574
33871
|
const agent = await withAgent({ keyPath: opts.keyPath });
|
|
33575
33872
|
const address = agent.address();
|
|
33576
|
-
const challenge = await
|
|
33873
|
+
const challenge = await fetchJson3(`${opts.base}/agent/challenge`, {
|
|
33577
33874
|
method: "POST",
|
|
33578
33875
|
body: { address }
|
|
33579
33876
|
});
|
|
@@ -33586,7 +33883,7 @@ async function putCatalog(opts) {
|
|
|
33586
33883
|
`t2000-agent-services:${nonce}:${digest}`
|
|
33587
33884
|
);
|
|
33588
33885
|
const { signature } = await agent.keypair.signPersonalMessage(message);
|
|
33589
|
-
const res = await
|
|
33886
|
+
const res = await fetchJson3(`${opts.base}/agent/services`, {
|
|
33590
33887
|
method: "POST",
|
|
33591
33888
|
body: { address, nonce, signature, services: opts.services }
|
|
33592
33889
|
});
|
|
@@ -33766,10 +34063,10 @@ function registerAgentServices(agentGroup, defaults) {
|
|
|
33766
34063
|
}
|
|
33767
34064
|
|
|
33768
34065
|
// src/commands/agent/index.ts
|
|
33769
|
-
var
|
|
34066
|
+
var DEFAULT_API_BASE4 = process.env.T2000_API_URL ?? "https://api.t2000.ai/v1";
|
|
33770
34067
|
var DEFAULT_GATEWAY2 = process.env.T2000_GATEWAY_URL ?? "https://mpp.t2000.ai";
|
|
33771
34068
|
var DEFAULT_RAIL = process.env.T2000_RAIL_URL ?? "https://x402.t2000.ai";
|
|
33772
|
-
var
|
|
34069
|
+
var AGENT_CATEGORIES2 = [
|
|
33773
34070
|
"ai-models",
|
|
33774
34071
|
"data-feeds",
|
|
33775
34072
|
"finance",
|
|
@@ -33783,9 +34080,9 @@ function normalizeCategory(input) {
|
|
|
33783
34080
|
return;
|
|
33784
34081
|
}
|
|
33785
34082
|
const c = input.trim().toLowerCase();
|
|
33786
|
-
if (!
|
|
34083
|
+
if (!AGENT_CATEGORIES2.includes(c)) {
|
|
33787
34084
|
throw new Error(
|
|
33788
|
-
`--category must be one of: ${
|
|
34085
|
+
`--category must be one of: ${AGENT_CATEGORIES2.join(", ")} (got "${input}").`
|
|
33789
34086
|
);
|
|
33790
34087
|
}
|
|
33791
34088
|
return c;
|
|
@@ -33806,19 +34103,19 @@ async function fundCredit(agent, base, amountStr, assetOpt) {
|
|
|
33806
34103
|
throw new Error(`amount must be a positive number (got "${amountStr}").`);
|
|
33807
34104
|
}
|
|
33808
34105
|
const asset = normalizeTopupAsset(assetOpt);
|
|
33809
|
-
const cfg = await
|
|
34106
|
+
const cfg = await fetchJson4(`${base}/agent/topup`, { method: "GET" });
|
|
33810
34107
|
const treasury = cfg.treasury;
|
|
33811
34108
|
if (!treasury) {
|
|
33812
34109
|
throw new Error("Could not resolve the t2000 treasury address.");
|
|
33813
34110
|
}
|
|
33814
34111
|
const sent = await agent.send({ to: treasury, amount, asset });
|
|
33815
|
-
const topup = await
|
|
34112
|
+
const topup = await fetchJson4(`${base}/agent/topup`, {
|
|
33816
34113
|
method: "POST",
|
|
33817
34114
|
body: { address: agent.address(), digest: sent.tx }
|
|
33818
34115
|
});
|
|
33819
34116
|
return { amount, asset, balanceUsd: topup.balanceUsd };
|
|
33820
34117
|
}
|
|
33821
|
-
async function
|
|
34118
|
+
async function fetchJson4(url, init) {
|
|
33822
34119
|
const res = await fetch(url, {
|
|
33823
34120
|
method: init.method,
|
|
33824
34121
|
headers: init.body ? { "Content-Type": "application/json" } : void 0,
|
|
@@ -33837,6 +34134,7 @@ function registerAgent(program3) {
|
|
|
33837
34134
|
"after",
|
|
33838
34135
|
`
|
|
33839
34136
|
Subcommands:
|
|
34137
|
+
$ t2 agent create --name "Atlas Research" Wallet + Agent ID + profile in one pass
|
|
33840
34138
|
$ t2 agent onboard --fund 5 Fund 5 USDC \u2192 mint an API key (ready to call)
|
|
33841
34139
|
$ t2 agent onboard --fund 5 --asset USDsui
|
|
33842
34140
|
$ t2 agent onboard Already funded \u2192 just mint a key
|
|
@@ -33844,14 +34142,15 @@ Subcommands:
|
|
|
33844
34142
|
$ t2 agent services sync ./services.json Manifest IS the catalog (catalog-scale sellers)
|
|
33845
34143
|
`
|
|
33846
34144
|
);
|
|
33847
|
-
|
|
34145
|
+
registerAgentCreate(group);
|
|
34146
|
+
registerAgentServices(group, { apiBase: DEFAULT_API_BASE4 });
|
|
33848
34147
|
registerAgentReview(group);
|
|
33849
34148
|
group.command("onboard").description(
|
|
33850
34149
|
"Buy-side setup: fund credit (gasless USDC/USDsui) + mint a Private API key. Registering an Agent ID is free and separate \u2014 `t2 init` / `t2 agent register`."
|
|
33851
|
-
).option("--fund <amount>", "Stablecoin amount to deposit as credit (omit if already funded)").option("--asset <asset>", "USDC (default) or USDsui", "USDC").option("--key <path>", "Custom wallet path (default ~/.t2000/wallet.key)").option("--api <url>", `API base URL (default ${
|
|
34150
|
+
).option("--fund <amount>", "Stablecoin amount to deposit as credit (omit if already funded)").option("--asset <asset>", "USDC (default) or USDsui", "USDC").option("--key <path>", "Custom wallet path (default ~/.t2000/wallet.key)").option("--api <url>", `API base URL (default ${DEFAULT_API_BASE4})`).action(
|
|
33852
34151
|
async (opts) => {
|
|
33853
34152
|
try {
|
|
33854
|
-
const base = opts.api ??
|
|
34153
|
+
const base = opts.api ?? DEFAULT_API_BASE4;
|
|
33855
34154
|
const agent = await withAgent({ keyPath: opts.key });
|
|
33856
34155
|
const address = agent.address();
|
|
33857
34156
|
if (opts.fund !== void 0) {
|
|
@@ -33862,7 +34161,7 @@ Subcommands:
|
|
|
33862
34161
|
);
|
|
33863
34162
|
}
|
|
33864
34163
|
}
|
|
33865
|
-
const challenge = await
|
|
34164
|
+
const challenge = await fetchJson4(`${base}/agent/challenge`, {
|
|
33866
34165
|
method: "POST",
|
|
33867
34166
|
body: { address }
|
|
33868
34167
|
});
|
|
@@ -33872,7 +34171,7 @@ Subcommands:
|
|
|
33872
34171
|
}
|
|
33873
34172
|
const message = new TextEncoder().encode(`t2000-agent-keys:${nonce}`);
|
|
33874
34173
|
const { signature } = await agent.keypair.signPersonalMessage(message);
|
|
33875
|
-
const minted = await
|
|
34174
|
+
const minted = await fetchJson4(`${base}/agent/keys`, {
|
|
33876
34175
|
method: "POST",
|
|
33877
34176
|
body: { address, nonce, signature }
|
|
33878
34177
|
});
|
|
@@ -33909,10 +34208,10 @@ Subcommands:
|
|
|
33909
34208
|
);
|
|
33910
34209
|
group.command("topup").argument("<amount>", "Stablecoin amount to deposit as credit").description(
|
|
33911
34210
|
"Top up this wallet's t2000 credit with gasless USDC/USDsui (no new key). The 'never runs dry' primitive \u2014 call it on a 402 or a schedule."
|
|
33912
|
-
).option("--asset <asset>", "USDC (default) or USDsui", "USDC").option("--key <path>", "Custom wallet path (default ~/.t2000/wallet.key)").option("--api <url>", `API base URL (default ${
|
|
34211
|
+
).option("--asset <asset>", "USDC (default) or USDsui", "USDC").option("--key <path>", "Custom wallet path (default ~/.t2000/wallet.key)").option("--api <url>", `API base URL (default ${DEFAULT_API_BASE4})`).action(
|
|
33913
34212
|
async (amount, opts) => {
|
|
33914
34213
|
try {
|
|
33915
|
-
const base = opts.api ??
|
|
34214
|
+
const base = opts.api ?? DEFAULT_API_BASE4;
|
|
33916
34215
|
const agent = await withAgent({ keyPath: opts.key });
|
|
33917
34216
|
const funded = await fundCredit(agent, base, amount, opts.asset);
|
|
33918
34217
|
if (isJsonMode()) {
|
|
@@ -33936,9 +34235,9 @@ Subcommands:
|
|
|
33936
34235
|
);
|
|
33937
34236
|
group.command("register").description(
|
|
33938
34237
|
"Register this wallet on-chain as an Agent ID (sponsored, gasless). Idempotent \u2014 safe to re-run."
|
|
33939
|
-
).option("--key <path>", "Custom wallet path (default ~/.t2000/wallet.key)").option("--api <url>", `API base URL (default ${
|
|
34238
|
+
).option("--key <path>", "Custom wallet path (default ~/.t2000/wallet.key)").option("--api <url>", `API base URL (default ${DEFAULT_API_BASE4})`).action(async (opts) => {
|
|
33940
34239
|
try {
|
|
33941
|
-
const base = opts.api ??
|
|
34240
|
+
const base = opts.api ?? DEFAULT_API_BASE4;
|
|
33942
34241
|
const agent = await withAgent({ keyPath: opts.key });
|
|
33943
34242
|
const address = agent.address();
|
|
33944
34243
|
const reg = await registerWallet({ keypair: agent.keypair, address, base });
|
|
@@ -33966,9 +34265,9 @@ Subcommands:
|
|
|
33966
34265
|
});
|
|
33967
34266
|
group.command("link").argument("<owner>", "The owner's Sui address (Passport) to propose").description(
|
|
33968
34267
|
"Propose an owner for this agent (two-sided \u2014 the owner must then confirm). Sponsored, gasless."
|
|
33969
|
-
).option("--key <path>", "Custom wallet path (default ~/.t2000/wallet.key)").option("--api <url>", `API base URL (default ${
|
|
34268
|
+
).option("--key <path>", "Custom wallet path (default ~/.t2000/wallet.key)").option("--api <url>", `API base URL (default ${DEFAULT_API_BASE4})`).action(async (owner, opts) => {
|
|
33970
34269
|
try {
|
|
33971
|
-
const base = opts.api ??
|
|
34270
|
+
const base = opts.api ?? DEFAULT_API_BASE4;
|
|
33972
34271
|
const agent = await withAgent({ keyPath: opts.key });
|
|
33973
34272
|
const address = agent.address();
|
|
33974
34273
|
if (!isValidSuiAddress(owner)) {
|
|
@@ -34005,9 +34304,9 @@ Subcommands:
|
|
|
34005
34304
|
});
|
|
34006
34305
|
group.command("confirm").argument("<agent>", "The agent Sui address to confirm ownership of").description(
|
|
34007
34306
|
"Confirm ownership of an agent that proposed you as its owner. Sponsored, gasless."
|
|
34008
|
-
).option("--key <path>", "Custom wallet path (default ~/.t2000/wallet.key)").option("--api <url>", `API base URL (default ${
|
|
34307
|
+
).option("--key <path>", "Custom wallet path (default ~/.t2000/wallet.key)").option("--api <url>", `API base URL (default ${DEFAULT_API_BASE4})`).action(async (agentAddress, opts) => {
|
|
34009
34308
|
try {
|
|
34010
|
-
const base = opts.api ??
|
|
34309
|
+
const base = opts.api ?? DEFAULT_API_BASE4;
|
|
34011
34310
|
const owner = await withAgent({ keyPath: opts.key });
|
|
34012
34311
|
const address = owner.address();
|
|
34013
34312
|
const { digest } = await runSponsoredTx({
|
|
@@ -34031,7 +34330,7 @@ Subcommands:
|
|
|
34031
34330
|
});
|
|
34032
34331
|
group.command("profile").description(
|
|
34033
34332
|
"Set this agent's public profile (name \xB7 image \xB7 description \xB7 links). Signed, no gas \u2014 shows in the directory."
|
|
34034
|
-
).option("--name <name>", "Display name").option("--image <url>", "Image URL (https)").option("--description <text>", "Short description").option("--website <url>", "Website link (https)").option("--twitter <url>", "X / Twitter link (https)").option("--github <url>", "GitHub link (https)").option("--key <path>", "Custom wallet path (default ~/.t2000/wallet.key)").option("--api <url>", `API base URL (default ${
|
|
34333
|
+
).option("--name <name>", "Display name").option("--image <url>", "Image URL (https)").option("--description <text>", "Short description").option("--website <url>", "Website link (https)").option("--twitter <url>", "X / Twitter link (https)").option("--github <url>", "GitHub link (https)").option("--key <path>", "Custom wallet path (default ~/.t2000/wallet.key)").option("--api <url>", `API base URL (default ${DEFAULT_API_BASE4})`).action(
|
|
34035
34334
|
async (opts) => {
|
|
34036
34335
|
try {
|
|
34037
34336
|
if (!(opts.name || opts.image || opts.description || opts.website || opts.twitter || opts.github)) {
|
|
@@ -34039,10 +34338,10 @@ Subcommands:
|
|
|
34039
34338
|
"Provide at least one of --name, --image, --description, --website, --twitter, --github."
|
|
34040
34339
|
);
|
|
34041
34340
|
}
|
|
34042
|
-
const base = opts.api ??
|
|
34341
|
+
const base = opts.api ?? DEFAULT_API_BASE4;
|
|
34043
34342
|
const agent = await withAgent({ keyPath: opts.key });
|
|
34044
34343
|
const address = agent.address();
|
|
34045
|
-
const challenge = await
|
|
34344
|
+
const challenge = await fetchJson4(`${base}/agent/challenge`, {
|
|
34046
34345
|
method: "POST",
|
|
34047
34346
|
body: { address }
|
|
34048
34347
|
});
|
|
@@ -34052,7 +34351,7 @@ Subcommands:
|
|
|
34052
34351
|
}
|
|
34053
34352
|
const message = new TextEncoder().encode(`t2000-agent-profile:${nonce}`);
|
|
34054
34353
|
const { signature } = await agent.keypair.signPersonalMessage(message);
|
|
34055
|
-
await
|
|
34354
|
+
await fetchJson4(`${base}/agent/profile`, {
|
|
34056
34355
|
method: "POST",
|
|
34057
34356
|
body: {
|
|
34058
34357
|
address,
|
|
@@ -34085,8 +34384,8 @@ Subcommands:
|
|
|
34085
34384
|
'Comma-separated methods you accept, e.g. "x402"'
|
|
34086
34385
|
).option("--price <usdc>", "Price per call in USDC (e.g. 0.02) \u2014 buyers pay this").option(
|
|
34087
34386
|
"--category <category>",
|
|
34088
|
-
`Storefront category: ${
|
|
34089
|
-
).option("--key <path>", "Custom wallet path (default ~/.t2000/wallet.key)").option("--api <url>", `API base URL (default ${
|
|
34387
|
+
`Storefront category: ${AGENT_CATEGORIES2.join(" | ")}`
|
|
34388
|
+
).option("--key <path>", "Custom wallet path (default ~/.t2000/wallet.key)").option("--api <url>", `API base URL (default ${DEFAULT_API_BASE4})`).action(
|
|
34090
34389
|
async (opts) => {
|
|
34091
34390
|
try {
|
|
34092
34391
|
if (opts.mcpEndpoint === void 0 && opts.paymentMethods === void 0 && opts.price === void 0 && opts.category === void 0) {
|
|
@@ -34101,7 +34400,7 @@ Subcommands:
|
|
|
34101
34400
|
}
|
|
34102
34401
|
}
|
|
34103
34402
|
const category = normalizeCategory(opts.category);
|
|
34104
|
-
const base = opts.api ??
|
|
34403
|
+
const base = opts.api ?? DEFAULT_API_BASE4;
|
|
34105
34404
|
const agent = await withAgent({ keyPath: opts.key });
|
|
34106
34405
|
const address = agent.address();
|
|
34107
34406
|
const prepareBody = { address };
|
|
@@ -34158,14 +34457,14 @@ Subcommands:
|
|
|
34158
34457
|
{}
|
|
34159
34458
|
).option("--method <method>", "Upstream method: GET or POST (default POST)").option("--price <usdc>", "Price per call in USDC (e.g. 0.02)").option(
|
|
34160
34459
|
"--category <category>",
|
|
34161
|
-
`Storefront category: ${
|
|
34460
|
+
`Storefront category: ${AGENT_CATEGORIES2.join(" | ")}`
|
|
34162
34461
|
).option("--remove", "Take down the deployed service").option(
|
|
34163
34462
|
"--service <slug>",
|
|
34164
34463
|
"Catalog service slug \u2014 wrap config for ONE SKU (Store v2; omit = the default service)"
|
|
34165
|
-
).option("--gateway <url>", `Gateway base URL (default ${DEFAULT_GATEWAY2})`).option("--key <path>", "Custom wallet path (default ~/.t2000/wallet.key)").option("--api <url>", `API base URL (default ${
|
|
34464
|
+
).option("--gateway <url>", `Gateway base URL (default ${DEFAULT_GATEWAY2})`).option("--key <path>", "Custom wallet path (default ~/.t2000/wallet.key)").option("--api <url>", `API base URL (default ${DEFAULT_API_BASE4})`).action(
|
|
34166
34465
|
async (opts) => {
|
|
34167
34466
|
try {
|
|
34168
|
-
const base = opts.api ??
|
|
34467
|
+
const base = opts.api ?? DEFAULT_API_BASE4;
|
|
34169
34468
|
const gateway = opts.gateway ?? DEFAULT_GATEWAY2;
|
|
34170
34469
|
const category = normalizeCategory(opts.category);
|
|
34171
34470
|
const slug = opts.service?.trim().toLowerCase() || void 0;
|
|
@@ -34177,7 +34476,7 @@ Subcommands:
|
|
|
34177
34476
|
const { signature: signature2 } = await agent.keypair.signPersonalMessage(
|
|
34178
34477
|
new TextEncoder().encode(msg2)
|
|
34179
34478
|
);
|
|
34180
|
-
await
|
|
34479
|
+
await fetchJson4(`${gateway}/deploy/config`, {
|
|
34181
34480
|
method: "DELETE",
|
|
34182
34481
|
body: { address, timestamp: ts2, signature: signature2, ...slug ? { slug } : {} }
|
|
34183
34482
|
});
|
|
@@ -34216,7 +34515,7 @@ Subcommands:
|
|
|
34216
34515
|
const { signature } = await agent.keypair.signPersonalMessage(
|
|
34217
34516
|
new TextEncoder().encode(msg)
|
|
34218
34517
|
);
|
|
34219
|
-
await
|
|
34518
|
+
await fetchJson4(`${gateway}/deploy/config`, {
|
|
34220
34519
|
method: "POST",
|
|
34221
34520
|
body: {
|
|
34222
34521
|
address,
|
|
@@ -34369,7 +34668,7 @@ Subcommands:
|
|
|
34369
34668
|
const gateway = opts.gateway ?? DEFAULT_GATEWAY2;
|
|
34370
34669
|
const agent = await withAgent({ keyPath: opts.key });
|
|
34371
34670
|
const address = agent.address();
|
|
34372
|
-
const stats = await
|
|
34671
|
+
const stats = await fetchJson4(
|
|
34373
34672
|
`${gateway}/commerce/stats/${address}`,
|
|
34374
34673
|
{ method: "GET" }
|
|
34375
34674
|
);
|
|
@@ -34392,13 +34691,13 @@ Subcommands:
|
|
|
34392
34691
|
});
|
|
34393
34692
|
group.command("handle").argument("<label>", "Handle label (3\u201320 chars: lowercase a\u2013z, 0\u20139, hyphens)").description(
|
|
34394
34693
|
"Claim <label>.agent-id.sui \u2192 this wallet (custody-minted, gasless). Use --release to give it up."
|
|
34395
|
-
).option("--release", "Release (revoke) this handle instead of claiming it").option("--key <path>", "Custom wallet path (default ~/.t2000/wallet.key)").option("--api <url>", `API base URL (default ${
|
|
34694
|
+
).option("--release", "Release (revoke) this handle instead of claiming it").option("--key <path>", "Custom wallet path (default ~/.t2000/wallet.key)").option("--api <url>", `API base URL (default ${DEFAULT_API_BASE4})`).action(
|
|
34396
34695
|
async (label, opts) => {
|
|
34397
34696
|
try {
|
|
34398
|
-
const base = opts.api ??
|
|
34697
|
+
const base = opts.api ?? DEFAULT_API_BASE4;
|
|
34399
34698
|
const agent = await withAgent({ keyPath: opts.key });
|
|
34400
34699
|
const address = agent.address();
|
|
34401
|
-
const challenge = await
|
|
34700
|
+
const challenge = await fetchJson4(`${base}/agent/challenge`, {
|
|
34402
34701
|
method: "POST",
|
|
34403
34702
|
body: { address }
|
|
34404
34703
|
});
|
|
@@ -34410,7 +34709,7 @@ Subcommands:
|
|
|
34410
34709
|
const message = new TextEncoder().encode(`${action}:${nonce}:${label}`);
|
|
34411
34710
|
const { signature } = await agent.keypair.signPersonalMessage(message);
|
|
34412
34711
|
const path2 = opts.release ? "/agent/handle/release" : "/agent/handle";
|
|
34413
|
-
const res = await
|
|
34712
|
+
const res = await fetchJson4(`${base}${path2}`, {
|
|
34414
34713
|
method: "POST",
|
|
34415
34714
|
body: { address, label, nonce, signature }
|
|
34416
34715
|
});
|
|
@@ -34436,7 +34735,7 @@ Subcommands:
|
|
|
34436
34735
|
}
|
|
34437
34736
|
|
|
34438
34737
|
// src/commands/agents.ts
|
|
34439
|
-
var
|
|
34738
|
+
var DEFAULT_API_BASE5 = process.env.T2000_API_URL ?? "https://api.t2000.ai/v1";
|
|
34440
34739
|
async function getJson(url) {
|
|
34441
34740
|
const res = await fetch(url, { headers: { accept: "application/json" } });
|
|
34442
34741
|
if (!res.ok) {
|
|
@@ -34451,10 +34750,10 @@ function firstLine(text, max = 76) {
|
|
|
34451
34750
|
function registerAgents(program3) {
|
|
34452
34751
|
program3.command("agents").argument("[address]", "Show one agent\u2019s full listing (profile + reputation)").description(
|
|
34453
34752
|
"Browse the agent store (agents.t2000.ai): priced services from the live directory, or one agent\u2019s full listing. Buy with `t2 agent pay <address>`. [Agent Commerce]"
|
|
34454
|
-
).option("--category <category>", "Filter the list by store category").option("--all", "Include agents without a priced service").option("--limit <n>", "Max rows (default: all)").option("--api <url>", `API base URL (default ${
|
|
34753
|
+
).option("--category <category>", "Filter the list by store category").option("--all", "Include agents without a priced service").option("--limit <n>", "Max rows (default: all)").option("--api <url>", `API base URL (default ${DEFAULT_API_BASE5})`).action(
|
|
34455
34754
|
async (address, opts) => {
|
|
34456
34755
|
try {
|
|
34457
|
-
const base = opts.api ??
|
|
34756
|
+
const base = opts.api ?? DEFAULT_API_BASE5;
|
|
34458
34757
|
if (address) {
|
|
34459
34758
|
const profile = await getJson(`${base}/agents/${address}`);
|
|
34460
34759
|
if (isJsonMode()) {
|