@t2000/cli 5.26.0 → 5.28.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
@@ -33115,7 +33115,7 @@ function registerMcpStart(parent) {
33115
33115
  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
33116
  let mod3;
33117
33117
  try {
33118
- mod3 = await import("./dist-BJOELEAN.js");
33118
+ mod3 = await import("./dist-7BWQQOS6.js");
33119
33119
  } catch {
33120
33120
  console.error("MCP server not installed. Run:\n npm install -g @t2000/mcp");
33121
33121
  process.exit(1);
@@ -33225,6 +33225,10 @@ Subcommands:
33225
33225
  registerMcpUninstall(group);
33226
33226
  }
33227
33227
 
33228
+ // src/commands/skills/check.ts
33229
+ import { readdir, readFile as readFile3 } from "fs/promises";
33230
+ import { join as join5 } from "path";
33231
+
33228
33232
  // src/commands/skills/lib.ts
33229
33233
  import { stat } from "fs/promises";
33230
33234
  import { join as join4 } from "path";
@@ -33298,6 +33302,133 @@ async function dirExists(path2) {
33298
33302
  }
33299
33303
  }
33300
33304
 
33305
+ // src/commands/skills/check.ts
33306
+ function slugFromEntry(entry, target) {
33307
+ return target === "cursor" ? entry.replace(/\.mdc$/, "") : entry;
33308
+ }
33309
+ async function installedSlugs(dir, target) {
33310
+ try {
33311
+ const entries = await readdir(dir);
33312
+ return entries.map((e) => slugFromEntry(e, target)).filter((slug) => isManagedSkillName(slug));
33313
+ } catch {
33314
+ return [];
33315
+ }
33316
+ }
33317
+ function classifyContent(installed, served) {
33318
+ if (served === null) {
33319
+ return "retired";
33320
+ }
33321
+ return installed.trim() === served.trim() ? "up-to-date" : "drifted";
33322
+ }
33323
+ async function checkTargetScope(manifest, servedCache, target, scope) {
33324
+ const dir = resolveTargetDir(target, scope === "global");
33325
+ if (!await dirExists(dir)) {
33326
+ return [];
33327
+ }
33328
+ const slugs = await installedSlugs(dir, target);
33329
+ const rows = [];
33330
+ for (const slug of slugs) {
33331
+ const path2 = join5(dir, filenameForTarget(slug, target));
33332
+ let installed;
33333
+ try {
33334
+ installed = await readFile3(path2, "utf-8");
33335
+ } catch {
33336
+ continue;
33337
+ }
33338
+ const entry = manifest.skills.find((s) => s.name === slug);
33339
+ let served = null;
33340
+ if (entry) {
33341
+ const cacheKey = `${target}:${slug}`;
33342
+ const cached = servedCache.get(cacheKey);
33343
+ if (cached !== void 0) {
33344
+ served = cached;
33345
+ } else {
33346
+ const raw = await fetchSkill(entry.url);
33347
+ served = transformForTarget(raw, target, entry.description);
33348
+ servedCache.set(cacheKey, served);
33349
+ }
33350
+ }
33351
+ rows.push({
33352
+ name: slug,
33353
+ target,
33354
+ scope,
33355
+ path: path2,
33356
+ status: classifyContent(installed, served)
33357
+ });
33358
+ }
33359
+ return rows;
33360
+ }
33361
+ function registerSkillsCheck(parent) {
33362
+ parent.command("check").description(
33363
+ "Compare installed skills against what t2000.ai serves \u2014 { upToDate, action } for agents"
33364
+ ).option(
33365
+ "--target <name>",
33366
+ "Only check one target layout: agents, cursor, claude-code (default: all)"
33367
+ ).action(async (opts) => {
33368
+ try {
33369
+ const targets = opts.target ? [
33370
+ (() => {
33371
+ const match = SKILL_TARGETS.find((t) => t === opts.target);
33372
+ if (!match) {
33373
+ throw new Error(
33374
+ `--target must be one of: ${SKILL_TARGETS.join(", ")}. Got: "${opts.target}"`
33375
+ );
33376
+ }
33377
+ return match;
33378
+ })()
33379
+ ] : SKILL_TARGETS;
33380
+ const manifest = await fetchManifest();
33381
+ const servedCache = /* @__PURE__ */ new Map();
33382
+ const rows = [];
33383
+ for (const target of targets) {
33384
+ rows.push(
33385
+ ...await checkTargetScope(manifest, servedCache, target, "local"),
33386
+ ...await checkTargetScope(manifest, servedCache, target, "global")
33387
+ );
33388
+ }
33389
+ const stale = rows.filter((r) => r.status !== "up-to-date");
33390
+ const upToDate = rows.length > 0 && stale.length === 0;
33391
+ if (isJsonMode()) {
33392
+ printJson({
33393
+ upToDate: rows.length === 0 ? true : upToDate,
33394
+ installed: rows.length,
33395
+ manifestVersion: manifest.version,
33396
+ skills: rows,
33397
+ action: stale.length > 0 ? "t2 skills install" : void 0
33398
+ });
33399
+ return;
33400
+ }
33401
+ printBlank();
33402
+ if (rows.length === 0) {
33403
+ printInfo(
33404
+ "No installed skills found (checked ./ and ~/ for .agents/skills, .cursor/rules, .claude/skills)."
33405
+ );
33406
+ printInfo("Install: t2 skills install \xB7 MCP clients: t2 mcp install (no files, always fresh)");
33407
+ printBlank();
33408
+ return;
33409
+ }
33410
+ for (const r of rows) {
33411
+ const mark2 = r.status === "up-to-date" ? "\u2713" : r.status === "drifted" ? "\u21BB" : "\u2717";
33412
+ console.log(` ${mark2} ${r.name} [${r.target} \xB7 ${r.scope}] ${r.status}`);
33413
+ }
33414
+ printBlank();
33415
+ if (upToDate) {
33416
+ printSuccess(`All ${rows.length} installed skills match what t2000.ai serves.`);
33417
+ } else {
33418
+ printInfo(
33419
+ `${stale.length} of ${rows.length} installed skills are stale \u2014 refresh with: t2 skills install`
33420
+ );
33421
+ if (stale.some((r) => r.status === "retired")) {
33422
+ printInfo("(\u2717 retired = no longer in the manifest \u2014 remove with: t2 skills uninstall)");
33423
+ }
33424
+ }
33425
+ printBlank();
33426
+ } catch (err) {
33427
+ handleError(err);
33428
+ }
33429
+ });
33430
+ }
33431
+
33301
33432
  // src/commands/skills/list.ts
33302
33433
  function registerSkillsList(parent) {
33303
33434
  parent.command("list").description("List skills available from t2000.ai (core t2000 + MPP recipes)").action(async () => {
@@ -33325,7 +33456,7 @@ function registerSkillsList(parent) {
33325
33456
 
33326
33457
  // src/commands/skills/install.ts
33327
33458
  import { writeFile as writeFile3, mkdir as mkdir3 } from "fs/promises";
33328
- import { join as join5 } from "path";
33459
+ import { join as join6 } from "path";
33329
33460
  function registerSkillsInstall(parent) {
33330
33461
  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
33462
  try {
@@ -33346,8 +33477,8 @@ function registerSkillsInstall(parent) {
33346
33477
  const raw = await fetchSkill(s.url);
33347
33478
  const transformed = transformForTarget(raw, target, s.description);
33348
33479
  const relPath = filenameForTarget(s.name, target);
33349
- const fullPath = join5(targetDir, relPath);
33350
- await mkdir3(join5(fullPath, ".."), { recursive: true });
33480
+ const fullPath = join6(targetDir, relPath);
33481
+ await mkdir3(join6(fullPath, ".."), { recursive: true });
33351
33482
  await writeFile3(fullPath, transformed, "utf-8");
33352
33483
  installed.push({ name: s.name, path: fullPath });
33353
33484
  }
@@ -33375,8 +33506,8 @@ function registerSkillsInstall(parent) {
33375
33506
  }
33376
33507
 
33377
33508
  // src/commands/skills/uninstall.ts
33378
- import { readdir, unlink, rmdir } from "fs/promises";
33379
- import { join as join6 } from "path";
33509
+ import { readdir as readdir2, unlink, rmdir } from "fs/promises";
33510
+ import { join as join7 } from "path";
33380
33511
  function registerSkillsUninstall(parent) {
33381
33512
  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
33513
  try {
@@ -33391,10 +33522,10 @@ function registerSkillsUninstall(parent) {
33391
33522
  printInfo(`No skills installed at ${targetDir}`);
33392
33523
  return;
33393
33524
  }
33394
- const entries = await readdir(targetDir);
33525
+ const entries = await readdir2(targetDir);
33395
33526
  const removed = [];
33396
33527
  for (const entry of entries) {
33397
- const full = join6(targetDir, entry);
33528
+ const full = join7(targetDir, entry);
33398
33529
  if (target === "cursor") {
33399
33530
  const slug = entry.endsWith(".mdc") ? entry.slice(0, -".mdc".length) : entry;
33400
33531
  if (entry.endsWith(".mdc") && isManagedSkillName(slug)) {
@@ -33403,7 +33534,7 @@ function registerSkillsUninstall(parent) {
33403
33534
  }
33404
33535
  } else {
33405
33536
  if (isManagedSkillName(entry)) {
33406
- const skillFile = join6(full, "SKILL.md");
33537
+ const skillFile = join7(full, "SKILL.md");
33407
33538
  try {
33408
33539
  await unlink(skillFile);
33409
33540
  } catch {
@@ -33443,6 +33574,7 @@ Subcommands:
33443
33574
  $ t2 skills install Install all skills (default target: agents)
33444
33575
  $ t2 skills install <slug> Install one skill by name
33445
33576
  $ t2 skills install --target cursor Install as Cursor .mdc rules
33577
+ $ t2 skills check Are installed skills current? (agents: run at session start)
33446
33578
  $ t2 skills uninstall Remove installed skills
33447
33579
 
33448
33580
  For MCP-aware clients (Claude Desktop, Cursor, Windsurf), prefer
@@ -33451,17 +33583,98 @@ For MCP-aware clients (Claude Desktop, Cursor, Windsurf), prefer
33451
33583
  );
33452
33584
  registerSkillsList(group);
33453
33585
  registerSkillsInstall(group);
33586
+ registerSkillsCheck(group);
33454
33587
  registerSkillsUninstall(group);
33455
33588
  }
33456
33589
 
33457
33590
  // src/commands/agent/index.ts
33458
- import { createHash as createHash2 } from "crypto";
33591
+ import { createHash as createHash3 } from "crypto";
33459
33592
 
33460
- // src/commands/agent/services.ts
33593
+ // src/commands/agent/review.ts
33461
33594
  import { createHash } from "crypto";
33595
+ var DEFAULT_GATEWAY = "https://x402.t2000.ai";
33596
+ async function fetchJson(url, init) {
33597
+ const res = await fetch(url, {
33598
+ method: init?.method ?? "GET",
33599
+ headers: init?.body ? { "Content-Type": "application/json" } : void 0,
33600
+ body: init?.body ? JSON.stringify(init.body) : void 0
33601
+ });
33602
+ const json = await res.json().catch(() => ({}));
33603
+ if (!res.ok) {
33604
+ const err = json.error;
33605
+ throw new Error(typeof err === "string" ? err : `HTTP ${res.status}`);
33606
+ }
33607
+ return json;
33608
+ }
33609
+ function reviewMessage(digest, stars, text, timestamp) {
33610
+ const hash = createHash("sha256").update(text, "utf8").digest("hex");
33611
+ return `t2000-review:${digest}:${stars}:${hash}:${timestamp}`;
33612
+ }
33613
+ function registerAgentReview(agent) {
33614
+ agent.command("review").description(
33615
+ "Review a purchase (1-5 stars + optional text). Binds to your latest settled receipt with the seller, or --digest for a specific one. Re-run to edit. [Store v2]"
33616
+ ).argument("<seller>", "Seller address (0x\u2026)").requiredOption("--stars <n>", "Rating 1-5").option("--text <text>", "Review text (\u2264400 chars)").option("--digest <digest>", "Collect digest of the specific purchase").option("--gateway <url>", `Gateway base URL (default ${DEFAULT_GATEWAY})`).option("--key <path>", "Custom wallet path (default ~/.t2000/wallet.key)").action(
33617
+ async (seller, opts) => {
33618
+ try {
33619
+ const stars = Number(opts.stars);
33620
+ if (!Number.isInteger(stars) || stars < 1 || stars > 5) {
33621
+ throw new Error("--stars must be an integer 1-5.");
33622
+ }
33623
+ const text = (opts.text ?? "").trim();
33624
+ if (text.length > 400) {
33625
+ throw new Error("--text must be \u2264 400 chars.");
33626
+ }
33627
+ const gateway = opts.gateway ?? DEFAULT_GATEWAY;
33628
+ const agentW = await withAgent({ keyPath: opts.key });
33629
+ const buyer = agentW.address();
33630
+ let digest = (opts.digest ?? "").trim();
33631
+ if (!digest) {
33632
+ const res = await fetchJson(
33633
+ `${gateway}/commerce/review?buyer=${buyer}&seller=${encodeURIComponent(seller)}`
33634
+ );
33635
+ const reviewable = res.reviewable ?? [];
33636
+ if (reviewable.length === 0) {
33637
+ throw new Error(
33638
+ "No settled purchase from this wallet to that seller \u2014 buy first (`t2 agent pay`), then review."
33639
+ );
33640
+ }
33641
+ digest = reviewable[0].digest;
33642
+ }
33643
+ const timestamp = Date.now();
33644
+ const message = new TextEncoder().encode(
33645
+ reviewMessage(digest, stars, text, timestamp)
33646
+ );
33647
+ const { signature } = await agentW.keypair.signPersonalMessage(message);
33648
+ await fetchJson(`${gateway}/commerce/review`, {
33649
+ method: "POST",
33650
+ body: { digest, stars, text, timestamp, signature }
33651
+ });
33652
+ if (isJsonMode()) {
33653
+ printJson({ ok: true, digest, stars, text: text || null });
33654
+ return;
33655
+ }
33656
+ printBlank();
33657
+ printSuccess(
33658
+ `Review posted \u2014 ${"\u2605".repeat(stars)}${"\u2606".repeat(5 - stars)}${text ? ` "${text}"` : ""}`
33659
+ );
33660
+ printKeyValue("Receipt", digest);
33661
+ printKeyValue(
33662
+ "Listing",
33663
+ `https://agents.t2000.ai/${seller.startsWith("0x") ? seller : ""}`
33664
+ );
33665
+ printBlank();
33666
+ } catch (e) {
33667
+ handleError(e);
33668
+ }
33669
+ }
33670
+ );
33671
+ }
33672
+
33673
+ // src/commands/agent/services.ts
33674
+ import { createHash as createHash2 } from "crypto";
33462
33675
  import { readFileSync as readFileSync3 } from "fs";
33463
33676
  var SLUG_RE = /^[a-z0-9][a-z0-9-]{1,39}$/;
33464
- async function fetchJson(url, init) {
33677
+ async function fetchJson2(url, init) {
33465
33678
  const res = await fetch(url, {
33466
33679
  method: init?.method ?? "GET",
33467
33680
  headers: init?.body ? { "Content-Type": "application/json" } : void 0,
@@ -33485,7 +33698,7 @@ function canonicalServicesJson(services) {
33485
33698
  );
33486
33699
  }
33487
33700
  async function getCatalog(base, address) {
33488
- const res = await fetchJson(
33701
+ const res = await fetchJson2(
33489
33702
  `${base}/agent/services?address=${encodeURIComponent(address)}`
33490
33703
  );
33491
33704
  return Array.isArray(res.services) ? res.services : [];
@@ -33493,7 +33706,7 @@ async function getCatalog(base, address) {
33493
33706
  async function putCatalog(opts) {
33494
33707
  const agent = await withAgent({ keyPath: opts.keyPath });
33495
33708
  const address = agent.address();
33496
- const challenge = await fetchJson(`${opts.base}/agent/challenge`, {
33709
+ const challenge = await fetchJson2(`${opts.base}/agent/challenge`, {
33497
33710
  method: "POST",
33498
33711
  body: { address }
33499
33712
  });
@@ -33501,12 +33714,12 @@ async function putCatalog(opts) {
33501
33714
  if (!nonce) {
33502
33715
  throw new Error("Failed to get a challenge nonce.");
33503
33716
  }
33504
- const digest = createHash("sha256").update(canonicalServicesJson(opts.services)).digest("hex");
33717
+ const digest = createHash2("sha256").update(canonicalServicesJson(opts.services)).digest("hex");
33505
33718
  const message = new TextEncoder().encode(
33506
33719
  `t2000-agent-services:${nonce}:${digest}`
33507
33720
  );
33508
33721
  const { signature } = await agent.keypair.signPersonalMessage(message);
33509
- const res = await fetchJson(`${opts.base}/agent/services`, {
33722
+ const res = await fetchJson2(`${opts.base}/agent/services`, {
33510
33723
  method: "POST",
33511
33724
  body: { address, nonce, signature, services: opts.services }
33512
33725
  });
@@ -33687,7 +33900,7 @@ function registerAgentServices(agentGroup, defaults) {
33687
33900
 
33688
33901
  // src/commands/agent/index.ts
33689
33902
  var DEFAULT_API_BASE3 = process.env.T2000_API_URL ?? "https://api.t2000.ai/v1";
33690
- var DEFAULT_GATEWAY = process.env.T2000_GATEWAY_URL ?? "https://mpp.t2000.ai";
33903
+ var DEFAULT_GATEWAY2 = process.env.T2000_GATEWAY_URL ?? "https://mpp.t2000.ai";
33691
33904
  var DEFAULT_RAIL = process.env.T2000_RAIL_URL ?? "https://x402.t2000.ai";
33692
33905
  var AGENT_CATEGORIES = [
33693
33906
  "ai-models",
@@ -33726,19 +33939,19 @@ async function fundCredit(agent, base, amountStr, assetOpt) {
33726
33939
  throw new Error(`amount must be a positive number (got "${amountStr}").`);
33727
33940
  }
33728
33941
  const asset = normalizeTopupAsset(assetOpt);
33729
- const cfg = await fetchJson2(`${base}/agent/topup`, { method: "GET" });
33942
+ const cfg = await fetchJson3(`${base}/agent/topup`, { method: "GET" });
33730
33943
  const treasury = cfg.treasury;
33731
33944
  if (!treasury) {
33732
33945
  throw new Error("Could not resolve the t2000 treasury address.");
33733
33946
  }
33734
33947
  const sent = await agent.send({ to: treasury, amount, asset });
33735
- const topup = await fetchJson2(`${base}/agent/topup`, {
33948
+ const topup = await fetchJson3(`${base}/agent/topup`, {
33736
33949
  method: "POST",
33737
33950
  body: { address: agent.address(), digest: sent.tx }
33738
33951
  });
33739
33952
  return { amount, asset, balanceUsd: topup.balanceUsd };
33740
33953
  }
33741
- async function fetchJson2(url, init) {
33954
+ async function fetchJson3(url, init) {
33742
33955
  const res = await fetch(url, {
33743
33956
  method: init.method,
33744
33957
  headers: init.body ? { "Content-Type": "application/json" } : void 0,
@@ -33765,6 +33978,7 @@ Subcommands:
33765
33978
  `
33766
33979
  );
33767
33980
  registerAgentServices(group, { apiBase: DEFAULT_API_BASE3 });
33981
+ registerAgentReview(group);
33768
33982
  group.command("onboard").description(
33769
33983
  "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`."
33770
33984
  ).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_BASE3})`).action(
@@ -33781,7 +33995,7 @@ Subcommands:
33781
33995
  );
33782
33996
  }
33783
33997
  }
33784
- const challenge = await fetchJson2(`${base}/agent/challenge`, {
33998
+ const challenge = await fetchJson3(`${base}/agent/challenge`, {
33785
33999
  method: "POST",
33786
34000
  body: { address }
33787
34001
  });
@@ -33791,7 +34005,7 @@ Subcommands:
33791
34005
  }
33792
34006
  const message = new TextEncoder().encode(`t2000-agent-keys:${nonce}`);
33793
34007
  const { signature } = await agent.keypair.signPersonalMessage(message);
33794
- const minted = await fetchJson2(`${base}/agent/keys`, {
34008
+ const minted = await fetchJson3(`${base}/agent/keys`, {
33795
34009
  method: "POST",
33796
34010
  body: { address, nonce, signature }
33797
34011
  });
@@ -33961,7 +34175,7 @@ Subcommands:
33961
34175
  const base = opts.api ?? DEFAULT_API_BASE3;
33962
34176
  const agent = await withAgent({ keyPath: opts.key });
33963
34177
  const address = agent.address();
33964
- const challenge = await fetchJson2(`${base}/agent/challenge`, {
34178
+ const challenge = await fetchJson3(`${base}/agent/challenge`, {
33965
34179
  method: "POST",
33966
34180
  body: { address }
33967
34181
  });
@@ -33971,7 +34185,7 @@ Subcommands:
33971
34185
  }
33972
34186
  const message = new TextEncoder().encode(`t2000-agent-profile:${nonce}`);
33973
34187
  const { signature } = await agent.keypair.signPersonalMessage(message);
33974
- await fetchJson2(`${base}/agent/profile`, {
34188
+ await fetchJson3(`${base}/agent/profile`, {
33975
34189
  method: "POST",
33976
34190
  body: {
33977
34191
  address,
@@ -34081,11 +34295,11 @@ Subcommands:
34081
34295
  ).option("--remove", "Take down the deployed service").option(
34082
34296
  "--service <slug>",
34083
34297
  "Catalog service slug \u2014 wrap config for ONE SKU (Store v2; omit = the default service)"
34084
- ).option("--gateway <url>", `Gateway base URL (default ${DEFAULT_GATEWAY})`).option("--key <path>", "Custom wallet path (default ~/.t2000/wallet.key)").option("--api <url>", `API base URL (default ${DEFAULT_API_BASE3})`).action(
34298
+ ).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_BASE3})`).action(
34085
34299
  async (opts) => {
34086
34300
  try {
34087
34301
  const base = opts.api ?? DEFAULT_API_BASE3;
34088
- const gateway = opts.gateway ?? DEFAULT_GATEWAY;
34302
+ const gateway = opts.gateway ?? DEFAULT_GATEWAY2;
34089
34303
  const category = normalizeCategory(opts.category);
34090
34304
  const slug = opts.service?.trim().toLowerCase() || void 0;
34091
34305
  const agent = await withAgent({ keyPath: opts.key });
@@ -34096,7 +34310,7 @@ Subcommands:
34096
34310
  const { signature: signature2 } = await agent.keypair.signPersonalMessage(
34097
34311
  new TextEncoder().encode(msg2)
34098
34312
  );
34099
- await fetchJson2(`${gateway}/deploy/config`, {
34313
+ await fetchJson3(`${gateway}/deploy/config`, {
34100
34314
  method: "DELETE",
34101
34315
  body: { address, timestamp: ts2, signature: signature2, ...slug ? { slug } : {} }
34102
34316
  });
@@ -34128,14 +34342,14 @@ Subcommands:
34128
34342
  const method = (opts.method ?? "POST").toUpperCase() === "GET" ? "GET" : "POST";
34129
34343
  const headers = opts.header ?? {};
34130
34344
  const ts = Date.now();
34131
- const bodyHash = createHash2("sha256").update(
34345
+ const bodyHash = createHash3("sha256").update(
34132
34346
  `${opts.upstream}|${method}|${JSON.stringify(headers)}${slug ? `|${slug}` : ""}`
34133
34347
  ).digest("hex");
34134
34348
  const msg = `t2000-deploy:${ts}:${bodyHash}`;
34135
34349
  const { signature } = await agent.keypair.signPersonalMessage(
34136
34350
  new TextEncoder().encode(msg)
34137
34351
  );
34138
- await fetchJson2(`${gateway}/deploy/config`, {
34352
+ await fetchJson3(`${gateway}/deploy/config`, {
34139
34353
  method: "POST",
34140
34354
  body: {
34141
34355
  address,
@@ -34204,7 +34418,7 @@ Subcommands:
34204
34418
  "Catalog service slug \u2014 buys ONE SKU of the seller's catalog (Store v2)"
34205
34419
  ).option(
34206
34420
  "--gateway <url>",
34207
- `Gateway base URL (default ${DEFAULT_GATEWAY})`
34421
+ `Gateway base URL (default ${DEFAULT_GATEWAY2})`
34208
34422
  ).option("--force", "Override spending limits for this call (see `t2 limit`)").option("--key <path>", "Custom wallet path (default ~/.t2000/wallet.key)").action(
34209
34423
  async (seller, opts) => {
34210
34424
  try {
@@ -34215,7 +34429,7 @@ Subcommands:
34215
34429
  }
34216
34430
  }
34217
34431
  const maxPrice = opts.maxPrice ? Number.parseFloat(opts.maxPrice) : opts.amount ? Number.parseFloat(opts.amount) : 1;
34218
- const gateway = opts.gateway ?? DEFAULT_GATEWAY;
34432
+ const gateway = opts.gateway ?? DEFAULT_GATEWAY2;
34219
34433
  const agent = await withAgent({ keyPath: opts.key });
34220
34434
  const resolvedSeller = seller.startsWith("0x") ? seller : (await agent.resolveRecipient(seller)).address;
34221
34435
  const slugPath = opts.service ? `/${opts.service.trim().toLowerCase()}` : "";
@@ -34283,12 +34497,12 @@ Subcommands:
34283
34497
  );
34284
34498
  group.command("earnings").description(
34285
34499
  "Your sales as a seller \u2014 count, USDC earned (net), and unique buyers, from the on-chain settlement ledger. [Agent Commerce]"
34286
- ).option("--gateway <url>", `Gateway base URL (default ${DEFAULT_GATEWAY})`).option("--key <path>", "Custom wallet path (default ~/.t2000/wallet.key)").action(async (opts) => {
34500
+ ).option("--gateway <url>", `Gateway base URL (default ${DEFAULT_GATEWAY2})`).option("--key <path>", "Custom wallet path (default ~/.t2000/wallet.key)").action(async (opts) => {
34287
34501
  try {
34288
- const gateway = opts.gateway ?? DEFAULT_GATEWAY;
34502
+ const gateway = opts.gateway ?? DEFAULT_GATEWAY2;
34289
34503
  const agent = await withAgent({ keyPath: opts.key });
34290
34504
  const address = agent.address();
34291
- const stats = await fetchJson2(
34505
+ const stats = await fetchJson3(
34292
34506
  `${gateway}/commerce/stats/${address}`,
34293
34507
  { method: "GET" }
34294
34508
  );
@@ -34317,7 +34531,7 @@ Subcommands:
34317
34531
  const base = opts.api ?? DEFAULT_API_BASE3;
34318
34532
  const agent = await withAgent({ keyPath: opts.key });
34319
34533
  const address = agent.address();
34320
- const challenge = await fetchJson2(`${base}/agent/challenge`, {
34534
+ const challenge = await fetchJson3(`${base}/agent/challenge`, {
34321
34535
  method: "POST",
34322
34536
  body: { address }
34323
34537
  });
@@ -34329,7 +34543,7 @@ Subcommands:
34329
34543
  const message = new TextEncoder().encode(`${action}:${nonce}:${label}`);
34330
34544
  const { signature } = await agent.keypair.signPersonalMessage(message);
34331
34545
  const path2 = opts.release ? "/agent/handle/release" : "/agent/handle";
34332
- const res = await fetchJson2(`${base}${path2}`, {
34546
+ const res = await fetchJson3(`${base}${path2}`, {
34333
34547
  method: "POST",
34334
34548
  body: { address, label, nonce, signature }
34335
34549
  });
@@ -34446,7 +34660,7 @@ function registerAgents(program3) {
34446
34660
  }
34447
34661
 
34448
34662
  // src/commands/task/index.ts
34449
- var DEFAULT_GATEWAY2 = process.env.T2000_GATEWAY_URL ?? "https://mpp.t2000.ai";
34663
+ var DEFAULT_GATEWAY3 = process.env.T2000_GATEWAY_URL ?? "https://mpp.t2000.ai";
34450
34664
  async function getJson2(url) {
34451
34665
  const res = await fetch(url, { headers: { accept: "application/json" } });
34452
34666
  const json = await res.json().catch(() => ({}));
@@ -34471,9 +34685,9 @@ function registerTask(program3) {
34471
34685
  const group = program3.command("task").description(
34472
34686
  "Earn from t2000 reward tasks and work (or post) community board tasks \u2014 all paid through the rail. [Agent Commerce]"
34473
34687
  );
34474
- group.command("list").description("Live tasks: t2000 rewards (auto-verified) + the community board (poster-approved)").option("--gateway <url>", `Gateway base URL (default ${DEFAULT_GATEWAY2})`).action(async (opts) => {
34688
+ group.command("list").description("Live tasks: t2000 rewards (auto-verified) + the community board (poster-approved)").option("--gateway <url>", `Gateway base URL (default ${DEFAULT_GATEWAY3})`).action(async (opts) => {
34475
34689
  try {
34476
- const gateway = opts.gateway ?? DEFAULT_GATEWAY2;
34690
+ const gateway = opts.gateway ?? DEFAULT_GATEWAY3;
34477
34691
  const [rewards, board] = await Promise.all([
34478
34692
  getJson2(`${gateway}/tasks/stats`),
34479
34693
  getJson2(`${gateway}/tasks/board`)
@@ -34507,10 +34721,10 @@ function registerTask(program3) {
34507
34721
  handleError(error);
34508
34722
  }
34509
34723
  });
34510
- group.command("claim").argument("<task>", "Reward task id (e.g. buy-sui, share-a-read) \u2014 see `t2 task list`").description("Claim a t2000 reward task (verified in one request; also retries automated tasks)").option("--tx <digest>", "Swap tx digest (buy-manifest / buy-sui)").option("--post <url>", "Your X post URL (X-proof tasks)").option("--gateway <url>", `Gateway base URL (default ${DEFAULT_GATEWAY2})`).option("--key <path>", "Custom wallet path (default ~/.t2000/wallet.key)").action(
34724
+ group.command("claim").argument("<task>", "Reward task id (e.g. buy-sui, share-a-read) \u2014 see `t2 task list`").description("Claim a t2000 reward task (verified in one request; also retries automated tasks)").option("--tx <digest>", "Swap tx digest (buy-manifest / buy-sui)").option("--post <url>", "Your X post URL (X-proof tasks)").option("--gateway <url>", `Gateway base URL (default ${DEFAULT_GATEWAY3})`).option("--key <path>", "Custom wallet path (default ~/.t2000/wallet.key)").action(
34511
34725
  async (task, opts) => {
34512
34726
  try {
34513
- const gateway = opts.gateway ?? DEFAULT_GATEWAY2;
34727
+ const gateway = opts.gateway ?? DEFAULT_GATEWAY3;
34514
34728
  const agent = await withAgent({ keyPath: opts.key });
34515
34729
  const result = await postJson2(`${gateway}/tasks/claim`, {
34516
34730
  task,
@@ -34539,10 +34753,10 @@ function registerTask(program3) {
34539
34753
  );
34540
34754
  group.command("post").description(
34541
34755
  "Post a community task \u2014 pays the FULL budget (reward \xD7 completions) into escrow via x402; auto-moderated at post time. SAVE the returned manageKey."
34542
- ).requiredOption("--title <text>", "What needs doing (8+ chars)").requiredOption("--description <text>", "Exactly what the worker must deliver + what proof (30+ chars)").requiredOption("--reward <usdc>", "Reward per approved completion ($0.01\u2013$50)").option("--completions <n>", "Max completions (default 1)", "1").option("--expiry-days <n>", "Days until unspent budget auto-refunds (default 7)", "7").option("--category <category>", "research | data | marketing | dev | creative | other", "other").option("--notify-email <email>", "Email me when submissions arrive + when the refund settles (per-task, one-click stop in every mail)").option("--gateway <url>", `Gateway base URL (default ${DEFAULT_GATEWAY2})`).option("--force", "Override spending limits for this call (see `t2 limit`)").option("--key <path>", "Custom wallet path (default ~/.t2000/wallet.key)").action(
34756
+ ).requiredOption("--title <text>", "What needs doing (8+ chars)").requiredOption("--description <text>", "Exactly what the worker must deliver + what proof (30+ chars)").requiredOption("--reward <usdc>", "Reward per approved completion ($0.01\u2013$50)").option("--completions <n>", "Max completions (default 1)", "1").option("--expiry-days <n>", "Days until unspent budget auto-refunds (default 7)", "7").option("--category <category>", "research | data | marketing | dev | creative | other", "other").option("--notify-email <email>", "Email me when submissions arrive + when the refund settles (per-task, one-click stop in every mail)").option("--gateway <url>", `Gateway base URL (default ${DEFAULT_GATEWAY3})`).option("--force", "Override spending limits for this call (see `t2 limit`)").option("--key <path>", "Custom wallet path (default ~/.t2000/wallet.key)").action(
34543
34757
  async (opts) => {
34544
34758
  try {
34545
- const gateway = opts.gateway ?? DEFAULT_GATEWAY2;
34759
+ const gateway = opts.gateway ?? DEFAULT_GATEWAY3;
34546
34760
  const reward = Number.parseFloat(opts.reward);
34547
34761
  const completions = Number.parseInt(opts.completions, 10);
34548
34762
  if (!Number.isFinite(reward) || reward <= 0) {
@@ -34591,10 +34805,10 @@ function registerTask(program3) {
34591
34805
  }
34592
34806
  }
34593
34807
  );
34594
- group.command("submit").argument("<taskId>", "Board task id (see `t2 task list`)").description("Submit proof of completion to a board task (one submission per wallet)").requiredOption("--proof <text>", "What you did + how the poster can verify it (10+ chars)").option("--url <url>", "Proof link (https)").option("--gateway <url>", `Gateway base URL (default ${DEFAULT_GATEWAY2})`).option("--key <path>", "Custom wallet path (default ~/.t2000/wallet.key)").action(
34808
+ group.command("submit").argument("<taskId>", "Board task id (see `t2 task list`)").description("Submit proof of completion to a board task (one submission per wallet)").requiredOption("--proof <text>", "What you did + how the poster can verify it (10+ chars)").option("--url <url>", "Proof link (https)").option("--gateway <url>", `Gateway base URL (default ${DEFAULT_GATEWAY3})`).option("--key <path>", "Custom wallet path (default ~/.t2000/wallet.key)").action(
34595
34809
  async (taskId, opts) => {
34596
34810
  try {
34597
- const gateway = opts.gateway ?? DEFAULT_GATEWAY2;
34811
+ const gateway = opts.gateway ?? DEFAULT_GATEWAY3;
34598
34812
  const agent = await withAgent({ keyPath: opts.key });
34599
34813
  const result = await postJson2(
34600
34814
  `${gateway}/tasks/board/${taskId}/submit`,
@@ -34616,9 +34830,9 @@ function registerTask(program3) {
34616
34830
  }
34617
34831
  }
34618
34832
  );
34619
- group.command("review").argument("<taskId>", "Your board task id").description("List submissions on your board task (poster view \u2014 needs the manageKey)").requiredOption("--manage-key <key>", "The manageKey returned when you posted").option("--gateway <url>", `Gateway base URL (default ${DEFAULT_GATEWAY2})`).action(async (taskId, opts) => {
34833
+ group.command("review").argument("<taskId>", "Your board task id").description("List submissions on your board task (poster view \u2014 needs the manageKey)").requiredOption("--manage-key <key>", "The manageKey returned when you posted").option("--gateway <url>", `Gateway base URL (default ${DEFAULT_GATEWAY3})`).action(async (taskId, opts) => {
34620
34834
  try {
34621
- const gateway = opts.gateway ?? DEFAULT_GATEWAY2;
34835
+ const gateway = opts.gateway ?? DEFAULT_GATEWAY3;
34622
34836
  const result = await getJson2(`${gateway}/tasks/board/${taskId}?manageKey=${encodeURIComponent(opts.manageKey)}`);
34623
34837
  if (!result.posterView) {
34624
34838
  throw new Error(result.error ?? "manageKey not accepted for this task.");
@@ -34646,10 +34860,10 @@ function registerTask(program3) {
34646
34860
  handleError(error);
34647
34861
  }
34648
34862
  });
34649
- group.command("approve").argument("<taskId>", "Your board task id").description("Approve (pay) or reject submissions on your board task \u2014 batch up to 50").requiredOption("--manage-key <key>", "The manageKey returned when you posted").requiredOption("--submissions <ids>", "Comma-separated submission ids").option("--reject", "Reject instead of approving").option("--gateway <url>", `Gateway base URL (default ${DEFAULT_GATEWAY2})`).action(
34863
+ group.command("approve").argument("<taskId>", "Your board task id").description("Approve (pay) or reject submissions on your board task \u2014 batch up to 50").requiredOption("--manage-key <key>", "The manageKey returned when you posted").requiredOption("--submissions <ids>", "Comma-separated submission ids").option("--reject", "Reject instead of approving").option("--gateway <url>", `Gateway base URL (default ${DEFAULT_GATEWAY3})`).action(
34650
34864
  async (taskId, opts) => {
34651
34865
  try {
34652
- const gateway = opts.gateway ?? DEFAULT_GATEWAY2;
34866
+ const gateway = opts.gateway ?? DEFAULT_GATEWAY3;
34653
34867
  const result = await postJson2(`${gateway}/tasks/board/${taskId}/approve`, {
34654
34868
  manageKey: opts.manageKey,
34655
34869
  submissionIds: opts.submissions.split(",").map((s) => s.trim()).filter(Boolean),
@@ -34675,9 +34889,9 @@ function registerTask(program3) {
34675
34889
  }
34676
34890
  }
34677
34891
  );
34678
- group.command("close").argument("<taskId>", "Your board task id").description("Close your board task early \u2014 the unspent budget refunds to your wallet").requiredOption("--manage-key <key>", "The manageKey returned when you posted").option("--gateway <url>", `Gateway base URL (default ${DEFAULT_GATEWAY2})`).action(async (taskId, opts) => {
34892
+ group.command("close").argument("<taskId>", "Your board task id").description("Close your board task early \u2014 the unspent budget refunds to your wallet").requiredOption("--manage-key <key>", "The manageKey returned when you posted").option("--gateway <url>", `Gateway base URL (default ${DEFAULT_GATEWAY3})`).action(async (taskId, opts) => {
34679
34893
  try {
34680
- const gateway = opts.gateway ?? DEFAULT_GATEWAY2;
34894
+ const gateway = opts.gateway ?? DEFAULT_GATEWAY3;
34681
34895
  const result = await postJson2(`${gateway}/tasks/board/${taskId}/close`, { manageKey: opts.manageKey });
34682
34896
  if (isJsonMode()) {
34683
34897
  printJson(result);