@t2000/cli 5.29.0 → 5.31.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
@@ -10784,7 +10784,7 @@ var require_lib2 = __commonJS({
10784
10784
  return matches;
10785
10785
  };
10786
10786
  exports.analyse = analyse;
10787
- var detectFile = (filepath, opts = {}) => new Promise((resolve2, reject) => {
10787
+ var detectFile = (filepath, opts = {}) => new Promise((resolve3, reject) => {
10788
10788
  let fd;
10789
10789
  const fs = (0, node_1.default)();
10790
10790
  const handler = (err, buffer) => {
@@ -10794,7 +10794,7 @@ var require_lib2 = __commonJS({
10794
10794
  if (err) {
10795
10795
  reject(err);
10796
10796
  } else if (buffer) {
10797
- resolve2((0, exports.detect)(buffer));
10797
+ resolve3((0, exports.detect)(buffer));
10798
10798
  } else {
10799
10799
  reject(new Error("No error and no buffer received"));
10800
10800
  }
@@ -18970,10 +18970,10 @@ var require_browser = __commonJS({
18970
18970
  text = canvas;
18971
18971
  canvas = void 0;
18972
18972
  }
18973
- return new Promise(function(resolve2, reject) {
18973
+ return new Promise(function(resolve3, reject) {
18974
18974
  try {
18975
18975
  const data = QRCode.create(text, opts);
18976
- resolve2(renderFunc(data, canvas, opts));
18976
+ resolve3(renderFunc(data, canvas, opts));
18977
18977
  } catch (e) {
18978
18978
  reject(e);
18979
18979
  }
@@ -19055,11 +19055,11 @@ var require_server = __commonJS({
19055
19055
  }
19056
19056
  function render(renderFunc, text, params) {
19057
19057
  if (!params.cb) {
19058
- return new Promise(function(resolve2, reject) {
19058
+ return new Promise(function(resolve3, reject) {
19059
19059
  try {
19060
19060
  const data = QRCode.create(text, params.opts);
19061
19061
  return renderFunc(data, params.opts, function(err, data2) {
19062
- return err ? reject(err) : resolve2(data2);
19062
+ return err ? reject(err) : resolve3(data2);
19063
19063
  });
19064
19064
  } catch (e) {
19065
19065
  reject(e);
@@ -30298,13 +30298,13 @@ var PromisePolyfill = class extends Promise {
30298
30298
  // Available starting from Node 22
30299
30299
  // https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise/withResolvers
30300
30300
  static withResolver() {
30301
- let resolve2;
30301
+ let resolve3;
30302
30302
  let reject;
30303
30303
  const promise = new Promise((res, rej) => {
30304
- resolve2 = res;
30304
+ resolve3 = res;
30305
30305
  reject = rej;
30306
30306
  });
30307
- return { promise, resolve: resolve2, reject };
30307
+ return { promise, resolve: resolve3, reject };
30308
30308
  }
30309
30309
  };
30310
30310
 
@@ -30338,7 +30338,7 @@ function createPrompt(view) {
30338
30338
  output
30339
30339
  });
30340
30340
  const screen = new ScreenManager(rl);
30341
- const { promise, resolve: resolve2, reject } = PromisePolyfill.withResolver();
30341
+ const { promise, resolve: resolve3, reject } = PromisePolyfill.withResolver();
30342
30342
  const cancel = () => reject(new CancelPromptError());
30343
30343
  if (signal) {
30344
30344
  const abort = () => reject(new AbortPromptError({ cause: signal.reason }));
@@ -30365,7 +30365,7 @@ function createPrompt(view) {
30365
30365
  cycle(() => {
30366
30366
  try {
30367
30367
  const nextView = view(config, (value) => {
30368
- setImmediate(() => resolve2(value));
30368
+ setImmediate(() => resolve3(value));
30369
30369
  });
30370
30370
  if (nextView === void 0) {
30371
30371
  const callerFilename = callSites[1]?.getFileName();
@@ -33122,7 +33122,7 @@ function registerMcpStart(parent) {
33122
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) => {
33123
33123
  let mod3;
33124
33124
  try {
33125
- mod3 = await import("./dist-D6VG3LUN.js");
33125
+ mod3 = await import("./dist-L3E4Q45J.js");
33126
33126
  } catch {
33127
33127
  console.error("MCP server not installed. Run:\n npm install -g @t2000/mcp");
33128
33128
  process.exit(1);
@@ -33595,7 +33595,7 @@ For MCP-aware clients (Claude Desktop, Cursor, Windsurf), prefer
33595
33595
  }
33596
33596
 
33597
33597
  // src/commands/agent/index.ts
33598
- import { createHash as createHash3 } from "crypto";
33598
+ import { createHash as createHash4 } from "crypto";
33599
33599
 
33600
33600
  // src/commands/agent/create.ts
33601
33601
  var DEFAULT_API_BASE3 = process.env.T2000_API_URL ?? "https://api.t2000.ai/v1";
@@ -33834,6 +33834,13 @@ function registerAgentReview(agent) {
33834
33834
  );
33835
33835
  }
33836
33836
 
33837
+ // src/commands/agent/serve.ts
33838
+ import { createHash as createHash3 } from "crypto";
33839
+ import { existsSync as existsSync4, mkdirSync as mkdirSync2, readFileSync as readFileSync4, writeFileSync as writeFileSync3 } from "fs";
33840
+ import { createServer } from "http";
33841
+ import { join as join8, resolve as resolve2 } from "path";
33842
+ import { pathToFileURL } from "url";
33843
+
33837
33844
  // src/commands/agent/services.ts
33838
33845
  import { createHash as createHash2 } from "crypto";
33839
33846
  import { readFileSync as readFileSync3 } from "fs";
@@ -34062,9 +34069,372 @@ function registerAgentServices(agentGroup, defaults) {
34062
34069
  });
34063
34070
  }
34064
34071
 
34065
- // src/commands/agent/index.ts
34072
+ // src/commands/agent/serve.ts
34066
34073
  var DEFAULT_API_BASE4 = process.env.T2000_API_URL ?? "https://api.t2000.ai/v1";
34067
34074
  var DEFAULT_GATEWAY2 = process.env.T2000_GATEWAY_URL ?? "https://mpp.t2000.ai";
34075
+ var SLUG_RE2 = /^[a-z0-9][a-z0-9-]{1,39}$/;
34076
+ var MANIFEST = "t2serve.json";
34077
+ var HANDLER = "handler.mjs";
34078
+ var HANDLER_TEMPLATE = `// t2000 hosted handler (R1). Deploys with: t2 agent serve deploy
34079
+ //
34080
+ // Contract: one self-contained ES module (no imports \u2014 fetch/crypto/URL are
34081
+ // available as Workers globals). The gateway calls this ONLY for paid,
34082
+ // escrowed deliveries; on a 2xx your wallet is paid, on failure the buyer is
34083
+ // auto-refunded. Keep it fast (15s delivery timeout, 5s CPU cap).
34084
+ //
34085
+ // input \u2014 the buyer's request body (parsed JSON, or a raw string)
34086
+ // ctx \u2014 { agent, slug, buyer }
34087
+ export default async function handle(input, ctx) {
34088
+ // Example: compose public data and return a result.
34089
+ // const res = await fetch('https://api.example.com/data');
34090
+ // const data = await res.json();
34091
+ return {
34092
+ echo: input,
34093
+ from: ctx.slug,
34094
+ note: 'Replace this with your service logic.',
34095
+ };
34096
+ }
34097
+ `;
34098
+ function readManifest(dir) {
34099
+ const p = join8(dir, MANIFEST);
34100
+ if (!existsSync4(p)) {
34101
+ throw new Error(
34102
+ `No ${MANIFEST} here \u2014 run \`t2 agent serve init\` first (or --dir <path>).`
34103
+ );
34104
+ }
34105
+ const m = JSON.parse(readFileSync4(p, "utf8"));
34106
+ const slug = String(m.slug ?? "").trim().toLowerCase();
34107
+ if (!SLUG_RE2.test(slug)) {
34108
+ throw new Error(`${MANIFEST}: slug must match [a-z0-9-], 2-40 chars.`);
34109
+ }
34110
+ if (!m.title?.trim() || !m.description?.trim()) {
34111
+ throw new Error(`${MANIFEST}: title and description are required.`);
34112
+ }
34113
+ const price = Number(m.price);
34114
+ if (!Number.isFinite(price) || price <= 0) {
34115
+ throw new Error(`${MANIFEST}: price must be a positive USDC amount.`);
34116
+ }
34117
+ return { ...m, slug };
34118
+ }
34119
+ function readHandler(dir) {
34120
+ const p = join8(dir, HANDLER);
34121
+ if (!existsSync4(p)) {
34122
+ throw new Error(`No ${HANDLER} here \u2014 run \`t2 agent serve init\` first.`);
34123
+ }
34124
+ const src = readFileSync4(p, "utf8");
34125
+ if (!src.trim()) {
34126
+ throw new Error(`${HANDLER} is empty.`);
34127
+ }
34128
+ if (/^\s*import\s.+from\s/m.test(src)) {
34129
+ throw new Error(
34130
+ `${HANDLER} must be self-contained (no imports) \u2014 fetch, crypto, and URL are available as globals.`
34131
+ );
34132
+ }
34133
+ return src;
34134
+ }
34135
+ async function fetchJson4(url, init) {
34136
+ const res = await fetch(url, {
34137
+ method: init?.method ?? "GET",
34138
+ headers: init?.body ? { "Content-Type": "application/json" } : void 0,
34139
+ body: init?.body ? JSON.stringify(init.body) : void 0
34140
+ });
34141
+ const json = await res.json().catch(() => ({}));
34142
+ if (!res.ok) {
34143
+ const err = json.error;
34144
+ const msg = typeof err === "string" ? err : err?.message ?? `HTTP ${res.status}`;
34145
+ throw new Error(msg);
34146
+ }
34147
+ return json;
34148
+ }
34149
+ function registerAgentServe(agentGroup) {
34150
+ const group = agentGroup.command("serve").description(
34151
+ "Hosted handlers \u2014 deploy a function to t2000 compute and sell it per call. No server, no wrap. [R1]"
34152
+ );
34153
+ group.command("init").description(`Scaffold ${HANDLER} + ${MANIFEST} in the current directory.`).option("--slug <slug>", "Service slug (in the buy URL)", "my-service").option("--dir <path>", "Target directory (default: cwd)").action((opts) => {
34154
+ try {
34155
+ const dir = resolve2(opts.dir ?? ".");
34156
+ mkdirSync2(dir, { recursive: true });
34157
+ const slug = opts.slug.trim().toLowerCase();
34158
+ if (!SLUG_RE2.test(slug)) {
34159
+ throw new Error("--slug must match [a-z0-9-], 2-40 chars.");
34160
+ }
34161
+ const manifestPath = join8(dir, MANIFEST);
34162
+ const handlerPath = join8(dir, HANDLER);
34163
+ if (existsSync4(manifestPath) || existsSync4(handlerPath)) {
34164
+ throw new Error(`${MANIFEST} or ${HANDLER} already exists here.`);
34165
+ }
34166
+ writeFileSync3(
34167
+ manifestPath,
34168
+ `${JSON.stringify(
34169
+ {
34170
+ slug,
34171
+ title: "My service",
34172
+ description: "What the buyer gets, in one or two sentences. Provide: 1. \u2026",
34173
+ price: "0.02",
34174
+ input: "JSON body with your parameters"
34175
+ },
34176
+ null,
34177
+ 2
34178
+ )}
34179
+ `
34180
+ );
34181
+ writeFileSync3(handlerPath, HANDLER_TEMPLATE);
34182
+ if (isJsonMode()) {
34183
+ printJson({ dir, files: [MANIFEST, HANDLER] });
34184
+ return;
34185
+ }
34186
+ printBlank();
34187
+ printSuccess("Scaffolded a hosted handler");
34188
+ printKeyValue("Handler", handlerPath);
34189
+ printKeyValue("Manifest", manifestPath);
34190
+ printBlank();
34191
+ printLine("Next:");
34192
+ printLine(" t2 agent serve dev # try it locally");
34193
+ printLine(" t2 agent serve deploy # deploy + list it for sale");
34194
+ printBlank();
34195
+ } catch (error) {
34196
+ handleError(error);
34197
+ }
34198
+ });
34199
+ group.command("dev").description(
34200
+ "Run the handler locally against the delivery contract (POST {input} to :8787)."
34201
+ ).option("--dir <path>", "Handler directory (default: cwd)").option("--port <port>", "Port (default 8787)", "8787").option("--input <json>", "One-shot: invoke once with this input and exit").action(async (opts) => {
34202
+ try {
34203
+ const dir = resolve2(opts.dir ?? ".");
34204
+ const manifest = readManifest(dir);
34205
+ readHandler(dir);
34206
+ const mod3 = await import(pathToFileURL(join8(dir, HANDLER)).href);
34207
+ const fn = mod3.default;
34208
+ if (typeof fn !== "function") {
34209
+ throw new Error(`${HANDLER} must default-export a function.`);
34210
+ }
34211
+ const ctx = {
34212
+ agent: "0xLOCAL",
34213
+ slug: manifest.slug,
34214
+ buyer: "0xBUYER"
34215
+ };
34216
+ if (opts.input !== void 0) {
34217
+ let input = opts.input;
34218
+ try {
34219
+ input = JSON.parse(opts.input);
34220
+ } catch {
34221
+ }
34222
+ const out = await fn(input, ctx);
34223
+ printJson({ ok: true, output: out });
34224
+ return;
34225
+ }
34226
+ const port = Number(opts.port) || 8787;
34227
+ const server = createServer(async (req, res) => {
34228
+ const chunks = [];
34229
+ for await (const c of req) {
34230
+ chunks.push(c);
34231
+ }
34232
+ const raw = Buffer.concat(chunks).toString("utf8");
34233
+ let input = raw;
34234
+ try {
34235
+ input = raw ? JSON.parse(raw) : {};
34236
+ } catch {
34237
+ }
34238
+ try {
34239
+ const out = await fn(input, ctx);
34240
+ res.writeHead(200, { "content-type": "application/json" });
34241
+ res.end(JSON.stringify(out));
34242
+ } catch (e) {
34243
+ res.writeHead(500, { "content-type": "application/json" });
34244
+ res.end(
34245
+ JSON.stringify({ error: e instanceof Error ? e.message : String(e) })
34246
+ );
34247
+ }
34248
+ });
34249
+ server.listen(port, () => {
34250
+ printBlank();
34251
+ printSuccess(`Local handler running \u2014 slug "${manifest.slug}"`);
34252
+ printLine(` curl -X POST http://localhost:${port} -d '{"hello":"world"}'`);
34253
+ printLine(" Ctrl-C to stop.");
34254
+ printBlank();
34255
+ });
34256
+ } catch (error) {
34257
+ handleError(error);
34258
+ }
34259
+ });
34260
+ group.command("deploy").description(
34261
+ "Deploy the handler to t2000 compute + list the SKU in your catalog. Sponsored listing, per-call earnings to your wallet."
34262
+ ).option("--dir <path>", "Handler directory (default: cwd)").option("--key <path>", "Custom wallet path (default ~/.t2000/wallet.key)").option("--api <url>", `API base URL (default ${DEFAULT_API_BASE4})`).option("--gateway <url>", `Gateway URL (default ${DEFAULT_GATEWAY2})`).action(
34263
+ async (opts) => {
34264
+ try {
34265
+ const dir = resolve2(opts.dir ?? ".");
34266
+ const base = opts.api ?? DEFAULT_API_BASE4;
34267
+ const gateway = opts.gateway ?? DEFAULT_GATEWAY2;
34268
+ const manifest = readManifest(dir);
34269
+ const script = readHandler(dir);
34270
+ const scriptB64 = Buffer.from(script, "utf8").toString("base64");
34271
+ const agent = await withAgent({ keyPath: opts.key });
34272
+ const address = agent.address();
34273
+ const ts = Date.now();
34274
+ const bodyHash = createHash3("sha256").update(`${manifest.slug}|${scriptB64}`).digest("hex");
34275
+ const message = new TextEncoder().encode(
34276
+ `t2000-serve:${ts}:${bodyHash}`
34277
+ );
34278
+ const { signature } = await agent.keypair.signPersonalMessage(message);
34279
+ const deployed = await fetchJson4(`${gateway}/serve/deploy`, {
34280
+ method: "POST",
34281
+ body: {
34282
+ address,
34283
+ slug: manifest.slug,
34284
+ script: scriptB64,
34285
+ timestamp: ts,
34286
+ signature
34287
+ }
34288
+ });
34289
+ const catalog = await getCatalog(base, address);
34290
+ const entry = {
34291
+ slug: manifest.slug,
34292
+ title: manifest.title,
34293
+ description: manifest.description,
34294
+ priceUsdc: String(manifest.price),
34295
+ input: manifest.input ?? null,
34296
+ endpoint: null,
34297
+ method: "POST",
34298
+ active: true
34299
+ };
34300
+ const next = [
34301
+ ...catalog.filter((s) => s.slug !== manifest.slug),
34302
+ entry
34303
+ ];
34304
+ await putCatalog({ base, keyPath: opts.key, services: next });
34305
+ const buyUrl = String(
34306
+ deployed.buyUrl ?? `https://x402.t2000.ai/commerce/pay/${address}/${manifest.slug}`
34307
+ );
34308
+ if (isJsonMode()) {
34309
+ printJson({
34310
+ address,
34311
+ slug: manifest.slug,
34312
+ sizeBytes: deployed.sizeBytes,
34313
+ listed: true,
34314
+ buyUrl
34315
+ });
34316
+ return;
34317
+ }
34318
+ printBlank();
34319
+ printSuccess(`Deployed "${manifest.slug}" to t2000 compute`);
34320
+ printKeyValue("Buy URL", buyUrl);
34321
+ printKeyValue("Price", `$${manifest.price} per call`);
34322
+ printKeyValue("Store", `https://agents.t2000.ai/${address}`);
34323
+ printBlank();
34324
+ printLine(" t2 agent serve logs # invocations");
34325
+ printLine(" t2 agent serve undeploy --slug " + manifest.slug);
34326
+ printBlank();
34327
+ } catch (error) {
34328
+ handleError(error);
34329
+ }
34330
+ }
34331
+ );
34332
+ group.command("status").description("Deployed handlers + invocation stats.").option("--key <path>", "Custom wallet path (default ~/.t2000/wallet.key)").option("--gateway <url>", `Gateway URL (default ${DEFAULT_GATEWAY2})`).action(async (opts) => {
34333
+ try {
34334
+ const gateway = opts.gateway ?? DEFAULT_GATEWAY2;
34335
+ const agent = await withAgent({ keyPath: opts.key });
34336
+ const address = agent.address();
34337
+ const res = await fetchJson4(
34338
+ `${gateway}/serve/status?address=${encodeURIComponent(address)}`
34339
+ );
34340
+ if (isJsonMode()) {
34341
+ printJson(res);
34342
+ return;
34343
+ }
34344
+ const handlers = res.handlers ?? [];
34345
+ printBlank();
34346
+ if (handlers.length === 0) {
34347
+ printLine("No hosted handlers. Start one: t2 agent serve init");
34348
+ printBlank();
34349
+ return;
34350
+ }
34351
+ for (const h of handlers) {
34352
+ printLine(
34353
+ ` ${h.slug} ${h.active ? "live" : "undeployed"} \xB7 ${(h.sizeBytes / 1024).toFixed(1)} KB \xB7 ${h.invocations} invocation${h.invocations === 1 ? "" : "s"}${h.lastInvocation ? ` \xB7 last ${h.lastInvocation.status} @ ${h.lastInvocation.at}` : ""}`
34354
+ );
34355
+ }
34356
+ printBlank();
34357
+ } catch (error) {
34358
+ handleError(error);
34359
+ }
34360
+ });
34361
+ group.command("logs").description("Recent invocations (status \xB7 duration \xB7 error).").option("--slug <slug>", "Filter to one handler").option("--limit <n>", "Rows (default 50)", "50").option("--key <path>", "Custom wallet path (default ~/.t2000/wallet.key)").option("--gateway <url>", `Gateway URL (default ${DEFAULT_GATEWAY2})`).action(
34362
+ async (opts) => {
34363
+ try {
34364
+ const gateway = opts.gateway ?? DEFAULT_GATEWAY2;
34365
+ const agent = await withAgent({ keyPath: opts.key });
34366
+ const address = agent.address();
34367
+ const params = new URLSearchParams({
34368
+ address,
34369
+ limit: opts.limit
34370
+ });
34371
+ if (opts.slug) {
34372
+ params.set("slug", opts.slug);
34373
+ }
34374
+ const res = await fetchJson4(`${gateway}/serve/logs?${params}`);
34375
+ if (isJsonMode()) {
34376
+ printJson(res);
34377
+ return;
34378
+ }
34379
+ const rows = res.invocations ?? [];
34380
+ printBlank();
34381
+ if (rows.length === 0) {
34382
+ printLine("No invocations yet.");
34383
+ printBlank();
34384
+ return;
34385
+ }
34386
+ for (const r of rows) {
34387
+ printLine(
34388
+ ` ${r.at} ${r.slug} ${r.status} ${r.durationMs}ms${r.error ? ` ${r.error}` : ""}`
34389
+ );
34390
+ }
34391
+ printBlank();
34392
+ } catch (error) {
34393
+ handleError(error);
34394
+ }
34395
+ }
34396
+ );
34397
+ group.command("undeploy").description(
34398
+ "Remove a hosted handler (the SKU stays in the catalog \u2014 deactivate it with `t2 agent services update --slug \u2026 --inactive` if wanted)."
34399
+ ).requiredOption("--slug <slug>", "Handler slug to remove").option("--key <path>", "Custom wallet path (default ~/.t2000/wallet.key)").option("--gateway <url>", `Gateway URL (default ${DEFAULT_GATEWAY2})`).action(
34400
+ async (opts) => {
34401
+ try {
34402
+ const gateway = opts.gateway ?? DEFAULT_GATEWAY2;
34403
+ const slug = opts.slug.trim().toLowerCase();
34404
+ if (!SLUG_RE2.test(slug)) {
34405
+ throw new Error("--slug must match [a-z0-9-], 2-40 chars.");
34406
+ }
34407
+ const agent = await withAgent({ keyPath: opts.key });
34408
+ const address = agent.address();
34409
+ const ts = Date.now();
34410
+ const message = new TextEncoder().encode(
34411
+ `t2000-serve-remove:${ts}:${slug}`
34412
+ );
34413
+ const { signature } = await agent.keypair.signPersonalMessage(message);
34414
+ await fetchJson4(`${gateway}/serve/undeploy`, {
34415
+ method: "POST",
34416
+ body: { address, slug, timestamp: ts, signature }
34417
+ });
34418
+ if (isJsonMode()) {
34419
+ printJson({ address, slug, undeployed: true });
34420
+ return;
34421
+ }
34422
+ printBlank();
34423
+ printSuccess(`Undeployed "${slug}"`);
34424
+ printInfo(
34425
+ "Buys against it now fail closed (auto-refund). Redeploy anytime: t2 agent serve deploy"
34426
+ );
34427
+ printBlank();
34428
+ } catch (error) {
34429
+ handleError(error);
34430
+ }
34431
+ }
34432
+ );
34433
+ }
34434
+
34435
+ // src/commands/agent/index.ts
34436
+ var DEFAULT_API_BASE5 = process.env.T2000_API_URL ?? "https://api.t2000.ai/v1";
34437
+ var DEFAULT_GATEWAY3 = process.env.T2000_GATEWAY_URL ?? "https://mpp.t2000.ai";
34068
34438
  var DEFAULT_RAIL = process.env.T2000_RAIL_URL ?? "https://x402.t2000.ai";
34069
34439
  var AGENT_CATEGORIES2 = [
34070
34440
  "ai-models",
@@ -34103,19 +34473,19 @@ async function fundCredit(agent, base, amountStr, assetOpt) {
34103
34473
  throw new Error(`amount must be a positive number (got "${amountStr}").`);
34104
34474
  }
34105
34475
  const asset = normalizeTopupAsset(assetOpt);
34106
- const cfg = await fetchJson4(`${base}/agent/topup`, { method: "GET" });
34476
+ const cfg = await fetchJson5(`${base}/agent/topup`, { method: "GET" });
34107
34477
  const treasury = cfg.treasury;
34108
34478
  if (!treasury) {
34109
34479
  throw new Error("Could not resolve the t2000 treasury address.");
34110
34480
  }
34111
34481
  const sent = await agent.send({ to: treasury, amount, asset });
34112
- const topup = await fetchJson4(`${base}/agent/topup`, {
34482
+ const topup = await fetchJson5(`${base}/agent/topup`, {
34113
34483
  method: "POST",
34114
34484
  body: { address: agent.address(), digest: sent.tx }
34115
34485
  });
34116
34486
  return { amount, asset, balanceUsd: topup.balanceUsd };
34117
34487
  }
34118
- async function fetchJson4(url, init) {
34488
+ async function fetchJson5(url, init) {
34119
34489
  const res = await fetch(url, {
34120
34490
  method: init.method,
34121
34491
  headers: init.body ? { "Content-Type": "application/json" } : void 0,
@@ -34143,14 +34513,15 @@ Subcommands:
34143
34513
  `
34144
34514
  );
34145
34515
  registerAgentCreate(group);
34146
- registerAgentServices(group, { apiBase: DEFAULT_API_BASE4 });
34516
+ registerAgentServices(group, { apiBase: DEFAULT_API_BASE5 });
34517
+ registerAgentServe(group);
34147
34518
  registerAgentReview(group);
34148
34519
  group.command("onboard").description(
34149
34520
  "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`."
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(
34521
+ ).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_BASE5})`).action(
34151
34522
  async (opts) => {
34152
34523
  try {
34153
- const base = opts.api ?? DEFAULT_API_BASE4;
34524
+ const base = opts.api ?? DEFAULT_API_BASE5;
34154
34525
  const agent = await withAgent({ keyPath: opts.key });
34155
34526
  const address = agent.address();
34156
34527
  if (opts.fund !== void 0) {
@@ -34161,7 +34532,7 @@ Subcommands:
34161
34532
  );
34162
34533
  }
34163
34534
  }
34164
- const challenge = await fetchJson4(`${base}/agent/challenge`, {
34535
+ const challenge = await fetchJson5(`${base}/agent/challenge`, {
34165
34536
  method: "POST",
34166
34537
  body: { address }
34167
34538
  });
@@ -34171,7 +34542,7 @@ Subcommands:
34171
34542
  }
34172
34543
  const message = new TextEncoder().encode(`t2000-agent-keys:${nonce}`);
34173
34544
  const { signature } = await agent.keypair.signPersonalMessage(message);
34174
- const minted = await fetchJson4(`${base}/agent/keys`, {
34545
+ const minted = await fetchJson5(`${base}/agent/keys`, {
34175
34546
  method: "POST",
34176
34547
  body: { address, nonce, signature }
34177
34548
  });
@@ -34208,10 +34579,10 @@ Subcommands:
34208
34579
  );
34209
34580
  group.command("topup").argument("<amount>", "Stablecoin amount to deposit as credit").description(
34210
34581
  "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."
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(
34582
+ ).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_BASE5})`).action(
34212
34583
  async (amount, opts) => {
34213
34584
  try {
34214
- const base = opts.api ?? DEFAULT_API_BASE4;
34585
+ const base = opts.api ?? DEFAULT_API_BASE5;
34215
34586
  const agent = await withAgent({ keyPath: opts.key });
34216
34587
  const funded = await fundCredit(agent, base, amount, opts.asset);
34217
34588
  if (isJsonMode()) {
@@ -34235,9 +34606,9 @@ Subcommands:
34235
34606
  );
34236
34607
  group.command("register").description(
34237
34608
  "Register this wallet on-chain as an Agent ID (sponsored, gasless). Idempotent \u2014 safe to re-run."
34238
- ).option("--key <path>", "Custom wallet path (default ~/.t2000/wallet.key)").option("--api <url>", `API base URL (default ${DEFAULT_API_BASE4})`).action(async (opts) => {
34609
+ ).option("--key <path>", "Custom wallet path (default ~/.t2000/wallet.key)").option("--api <url>", `API base URL (default ${DEFAULT_API_BASE5})`).action(async (opts) => {
34239
34610
  try {
34240
- const base = opts.api ?? DEFAULT_API_BASE4;
34611
+ const base = opts.api ?? DEFAULT_API_BASE5;
34241
34612
  const agent = await withAgent({ keyPath: opts.key });
34242
34613
  const address = agent.address();
34243
34614
  const reg = await registerWallet({ keypair: agent.keypair, address, base });
@@ -34265,9 +34636,9 @@ Subcommands:
34265
34636
  });
34266
34637
  group.command("link").argument("<owner>", "The owner's Sui address (Passport) to propose").description(
34267
34638
  "Propose an owner for this agent (two-sided \u2014 the owner must then confirm). Sponsored, gasless."
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) => {
34639
+ ).option("--key <path>", "Custom wallet path (default ~/.t2000/wallet.key)").option("--api <url>", `API base URL (default ${DEFAULT_API_BASE5})`).action(async (owner, opts) => {
34269
34640
  try {
34270
- const base = opts.api ?? DEFAULT_API_BASE4;
34641
+ const base = opts.api ?? DEFAULT_API_BASE5;
34271
34642
  const agent = await withAgent({ keyPath: opts.key });
34272
34643
  const address = agent.address();
34273
34644
  if (!isValidSuiAddress(owner)) {
@@ -34304,9 +34675,9 @@ Subcommands:
34304
34675
  });
34305
34676
  group.command("confirm").argument("<agent>", "The agent Sui address to confirm ownership of").description(
34306
34677
  "Confirm ownership of an agent that proposed you as its owner. Sponsored, gasless."
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) => {
34678
+ ).option("--key <path>", "Custom wallet path (default ~/.t2000/wallet.key)").option("--api <url>", `API base URL (default ${DEFAULT_API_BASE5})`).action(async (agentAddress, opts) => {
34308
34679
  try {
34309
- const base = opts.api ?? DEFAULT_API_BASE4;
34680
+ const base = opts.api ?? DEFAULT_API_BASE5;
34310
34681
  const owner = await withAgent({ keyPath: opts.key });
34311
34682
  const address = owner.address();
34312
34683
  const { digest } = await runSponsoredTx({
@@ -34328,9 +34699,36 @@ Subcommands:
34328
34699
  handleError(error);
34329
34700
  }
34330
34701
  });
34702
+ group.command("unlink").argument("<agent>", "The agent Sui address to renounce ownership of").description(
34703
+ "Renounce ownership of an agent you own \u2014 the record returns to autonomous (public, on-chain). Sponsored, gasless. Re-link = the agent proposes again."
34704
+ ).option("--key <path>", "Custom wallet path (default ~/.t2000/wallet.key)").option("--api <url>", `API base URL (default ${DEFAULT_API_BASE5})`).action(async (agentAddress, opts) => {
34705
+ try {
34706
+ const base = opts.api ?? DEFAULT_API_BASE5;
34707
+ const owner = await withAgent({ keyPath: opts.key });
34708
+ const address = owner.address();
34709
+ const { digest } = await runSponsoredTx({
34710
+ keypair: owner.keypair,
34711
+ actor: address,
34712
+ prepareUrl: `${base}/agent/owner/renounce`,
34713
+ prepareBody: { owner: address, agent: agentAddress },
34714
+ submitUrl: `${base}/agent/owner/submit`
34715
+ });
34716
+ if (isJsonMode()) {
34717
+ printJson({ owner: address, agent: agentAddress, unlinked: true, digest });
34718
+ return;
34719
+ }
34720
+ printBlank();
34721
+ printSuccess(`Renounced ownership of ${truncateAddress(agentAddress)}`);
34722
+ printInfo("The agent is autonomous again \u2014 it can re-propose you anytime.");
34723
+ printKeyValue("Tx", String(digest));
34724
+ printBlank();
34725
+ } catch (error) {
34726
+ handleError(error);
34727
+ }
34728
+ });
34331
34729
  group.command("profile").description(
34332
34730
  "Set this agent's public profile (name \xB7 image \xB7 description \xB7 links). Signed, no gas \u2014 shows in the directory."
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(
34731
+ ).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_BASE5})`).action(
34334
34732
  async (opts) => {
34335
34733
  try {
34336
34734
  if (!(opts.name || opts.image || opts.description || opts.website || opts.twitter || opts.github)) {
@@ -34338,10 +34736,10 @@ Subcommands:
34338
34736
  "Provide at least one of --name, --image, --description, --website, --twitter, --github."
34339
34737
  );
34340
34738
  }
34341
- const base = opts.api ?? DEFAULT_API_BASE4;
34739
+ const base = opts.api ?? DEFAULT_API_BASE5;
34342
34740
  const agent = await withAgent({ keyPath: opts.key });
34343
34741
  const address = agent.address();
34344
- const challenge = await fetchJson4(`${base}/agent/challenge`, {
34742
+ const challenge = await fetchJson5(`${base}/agent/challenge`, {
34345
34743
  method: "POST",
34346
34744
  body: { address }
34347
34745
  });
@@ -34351,7 +34749,7 @@ Subcommands:
34351
34749
  }
34352
34750
  const message = new TextEncoder().encode(`t2000-agent-profile:${nonce}`);
34353
34751
  const { signature } = await agent.keypair.signPersonalMessage(message);
34354
- await fetchJson4(`${base}/agent/profile`, {
34752
+ await fetchJson5(`${base}/agent/profile`, {
34355
34753
  method: "POST",
34356
34754
  body: {
34357
34755
  address,
@@ -34385,7 +34783,7 @@ Subcommands:
34385
34783
  ).option("--price <usdc>", "Price per call in USDC (e.g. 0.02) \u2014 buyers pay this").option(
34386
34784
  "--category <category>",
34387
34785
  `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(
34786
+ ).option("--key <path>", "Custom wallet path (default ~/.t2000/wallet.key)").option("--api <url>", `API base URL (default ${DEFAULT_API_BASE5})`).action(
34389
34787
  async (opts) => {
34390
34788
  try {
34391
34789
  if (opts.mcpEndpoint === void 0 && opts.paymentMethods === void 0 && opts.price === void 0 && opts.category === void 0) {
@@ -34400,7 +34798,7 @@ Subcommands:
34400
34798
  }
34401
34799
  }
34402
34800
  const category = normalizeCategory(opts.category);
34403
- const base = opts.api ?? DEFAULT_API_BASE4;
34801
+ const base = opts.api ?? DEFAULT_API_BASE5;
34404
34802
  const agent = await withAgent({ keyPath: opts.key });
34405
34803
  const address = agent.address();
34406
34804
  const prepareBody = { address };
@@ -34461,11 +34859,11 @@ Subcommands:
34461
34859
  ).option("--remove", "Take down the deployed service").option(
34462
34860
  "--service <slug>",
34463
34861
  "Catalog service slug \u2014 wrap config for ONE SKU (Store v2; omit = the default service)"
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(
34862
+ ).option("--gateway <url>", `Gateway base URL (default ${DEFAULT_GATEWAY3})`).option("--key <path>", "Custom wallet path (default ~/.t2000/wallet.key)").option("--api <url>", `API base URL (default ${DEFAULT_API_BASE5})`).action(
34465
34863
  async (opts) => {
34466
34864
  try {
34467
- const base = opts.api ?? DEFAULT_API_BASE4;
34468
- const gateway = opts.gateway ?? DEFAULT_GATEWAY2;
34865
+ const base = opts.api ?? DEFAULT_API_BASE5;
34866
+ const gateway = opts.gateway ?? DEFAULT_GATEWAY3;
34469
34867
  const category = normalizeCategory(opts.category);
34470
34868
  const slug = opts.service?.trim().toLowerCase() || void 0;
34471
34869
  const agent = await withAgent({ keyPath: opts.key });
@@ -34476,7 +34874,7 @@ Subcommands:
34476
34874
  const { signature: signature2 } = await agent.keypair.signPersonalMessage(
34477
34875
  new TextEncoder().encode(msg2)
34478
34876
  );
34479
- await fetchJson4(`${gateway}/deploy/config`, {
34877
+ await fetchJson5(`${gateway}/deploy/config`, {
34480
34878
  method: "DELETE",
34481
34879
  body: { address, timestamp: ts2, signature: signature2, ...slug ? { slug } : {} }
34482
34880
  });
@@ -34508,14 +34906,14 @@ Subcommands:
34508
34906
  const method = (opts.method ?? "POST").toUpperCase() === "GET" ? "GET" : "POST";
34509
34907
  const headers = opts.header ?? {};
34510
34908
  const ts = Date.now();
34511
- const bodyHash = createHash3("sha256").update(
34909
+ const bodyHash = createHash4("sha256").update(
34512
34910
  `${opts.upstream}|${method}|${JSON.stringify(headers)}${slug ? `|${slug}` : ""}`
34513
34911
  ).digest("hex");
34514
34912
  const msg = `t2000-deploy:${ts}:${bodyHash}`;
34515
34913
  const { signature } = await agent.keypair.signPersonalMessage(
34516
34914
  new TextEncoder().encode(msg)
34517
34915
  );
34518
- await fetchJson4(`${gateway}/deploy/config`, {
34916
+ await fetchJson5(`${gateway}/deploy/config`, {
34519
34917
  method: "POST",
34520
34918
  body: {
34521
34919
  address,
@@ -34584,7 +34982,7 @@ Subcommands:
34584
34982
  "Catalog service slug \u2014 buys ONE SKU of the seller's catalog (Store v2)"
34585
34983
  ).option(
34586
34984
  "--gateway <url>",
34587
- `Gateway base URL (default ${DEFAULT_GATEWAY2})`
34985
+ `Gateway base URL (default ${DEFAULT_GATEWAY3})`
34588
34986
  ).option("--force", "Override spending limits for this call (see `t2 limit`)").option("--key <path>", "Custom wallet path (default ~/.t2000/wallet.key)").action(
34589
34987
  async (seller, opts) => {
34590
34988
  try {
@@ -34595,7 +34993,7 @@ Subcommands:
34595
34993
  }
34596
34994
  }
34597
34995
  const maxPrice = opts.maxPrice ? Number.parseFloat(opts.maxPrice) : opts.amount ? Number.parseFloat(opts.amount) : 1;
34598
- const gateway = opts.gateway ?? DEFAULT_GATEWAY2;
34996
+ const gateway = opts.gateway ?? DEFAULT_GATEWAY3;
34599
34997
  const agent = await withAgent({ keyPath: opts.key });
34600
34998
  const resolvedSeller = seller.startsWith("0x") ? seller : (await agent.resolveRecipient(seller)).address;
34601
34999
  const slugPath = opts.service ? `/${opts.service.trim().toLowerCase()}` : "";
@@ -34663,12 +35061,12 @@ Subcommands:
34663
35061
  );
34664
35062
  group.command("earnings").description(
34665
35063
  "Your sales as a seller \u2014 count, USDC earned (net), and unique buyers, from the on-chain settlement ledger. [Agent Commerce]"
34666
- ).option("--gateway <url>", `Gateway base URL (default ${DEFAULT_GATEWAY2})`).option("--key <path>", "Custom wallet path (default ~/.t2000/wallet.key)").action(async (opts) => {
35064
+ ).option("--gateway <url>", `Gateway base URL (default ${DEFAULT_GATEWAY3})`).option("--key <path>", "Custom wallet path (default ~/.t2000/wallet.key)").action(async (opts) => {
34667
35065
  try {
34668
- const gateway = opts.gateway ?? DEFAULT_GATEWAY2;
35066
+ const gateway = opts.gateway ?? DEFAULT_GATEWAY3;
34669
35067
  const agent = await withAgent({ keyPath: opts.key });
34670
35068
  const address = agent.address();
34671
- const stats = await fetchJson4(
35069
+ const stats = await fetchJson5(
34672
35070
  `${gateway}/commerce/stats/${address}`,
34673
35071
  { method: "GET" }
34674
35072
  );
@@ -34691,13 +35089,13 @@ Subcommands:
34691
35089
  });
34692
35090
  group.command("handle").argument("<label>", "Handle label (3\u201320 chars: lowercase a\u2013z, 0\u20139, hyphens)").description(
34693
35091
  "Claim <label>.agent-id.sui \u2192 this wallet (custody-minted, gasless). Use --release to give it up."
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(
35092
+ ).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_BASE5})`).action(
34695
35093
  async (label, opts) => {
34696
35094
  try {
34697
- const base = opts.api ?? DEFAULT_API_BASE4;
35095
+ const base = opts.api ?? DEFAULT_API_BASE5;
34698
35096
  const agent = await withAgent({ keyPath: opts.key });
34699
35097
  const address = agent.address();
34700
- const challenge = await fetchJson4(`${base}/agent/challenge`, {
35098
+ const challenge = await fetchJson5(`${base}/agent/challenge`, {
34701
35099
  method: "POST",
34702
35100
  body: { address }
34703
35101
  });
@@ -34709,7 +35107,7 @@ Subcommands:
34709
35107
  const message = new TextEncoder().encode(`${action}:${nonce}:${label}`);
34710
35108
  const { signature } = await agent.keypair.signPersonalMessage(message);
34711
35109
  const path2 = opts.release ? "/agent/handle/release" : "/agent/handle";
34712
- const res = await fetchJson4(`${base}${path2}`, {
35110
+ const res = await fetchJson5(`${base}${path2}`, {
34713
35111
  method: "POST",
34714
35112
  body: { address, label, nonce, signature }
34715
35113
  });
@@ -34735,7 +35133,7 @@ Subcommands:
34735
35133
  }
34736
35134
 
34737
35135
  // src/commands/agents.ts
34738
- var DEFAULT_API_BASE5 = process.env.T2000_API_URL ?? "https://api.t2000.ai/v1";
35136
+ var DEFAULT_API_BASE6 = process.env.T2000_API_URL ?? "https://api.t2000.ai/v1";
34739
35137
  async function getJson(url) {
34740
35138
  const res = await fetch(url, { headers: { accept: "application/json" } });
34741
35139
  if (!res.ok) {
@@ -34750,10 +35148,10 @@ function firstLine(text, max = 76) {
34750
35148
  function registerAgents(program3) {
34751
35149
  program3.command("agents").argument("[address]", "Show one agent\u2019s full listing (profile + reputation)").description(
34752
35150
  "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]"
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(
35151
+ ).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_BASE6})`).action(
34754
35152
  async (address, opts) => {
34755
35153
  try {
34756
- const base = opts.api ?? DEFAULT_API_BASE5;
35154
+ const base = opts.api ?? DEFAULT_API_BASE6;
34757
35155
  if (address) {
34758
35156
  const profile = await getJson(`${base}/agents/${address}`);
34759
35157
  if (isJsonMode()) {
@@ -34826,7 +35224,7 @@ function registerAgents(program3) {
34826
35224
  }
34827
35225
 
34828
35226
  // src/commands/task/index.ts
34829
- var DEFAULT_GATEWAY3 = process.env.T2000_GATEWAY_URL ?? "https://mpp.t2000.ai";
35227
+ var DEFAULT_GATEWAY4 = process.env.T2000_GATEWAY_URL ?? "https://mpp.t2000.ai";
34830
35228
  async function getJson2(url) {
34831
35229
  const res = await fetch(url, { headers: { accept: "application/json" } });
34832
35230
  const json = await res.json().catch(() => ({}));
@@ -34851,9 +35249,9 @@ function registerTask(program3) {
34851
35249
  const group = program3.command("task").description(
34852
35250
  "Earn from t2000 reward tasks and work (or post) community board tasks \u2014 all paid through the rail. [Agent Commerce]"
34853
35251
  );
34854
- 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) => {
35252
+ group.command("list").description("Live tasks: t2000 rewards (auto-verified) + the community board (poster-approved)").option("--gateway <url>", `Gateway base URL (default ${DEFAULT_GATEWAY4})`).action(async (opts) => {
34855
35253
  try {
34856
- const gateway = opts.gateway ?? DEFAULT_GATEWAY3;
35254
+ const gateway = opts.gateway ?? DEFAULT_GATEWAY4;
34857
35255
  const [rewards, board] = await Promise.all([
34858
35256
  getJson2(`${gateway}/tasks/stats`),
34859
35257
  getJson2(`${gateway}/tasks/board`)
@@ -34887,10 +35285,10 @@ function registerTask(program3) {
34887
35285
  handleError(error);
34888
35286
  }
34889
35287
  });
34890
- 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(
35288
+ 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_GATEWAY4})`).option("--key <path>", "Custom wallet path (default ~/.t2000/wallet.key)").action(
34891
35289
  async (task, opts) => {
34892
35290
  try {
34893
- const gateway = opts.gateway ?? DEFAULT_GATEWAY3;
35291
+ const gateway = opts.gateway ?? DEFAULT_GATEWAY4;
34894
35292
  const agent = await withAgent({ keyPath: opts.key });
34895
35293
  const result = await postJson2(`${gateway}/tasks/claim`, {
34896
35294
  task,
@@ -34919,10 +35317,10 @@ function registerTask(program3) {
34919
35317
  );
34920
35318
  group.command("post").description(
34921
35319
  "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."
34922
- ).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(
35320
+ ).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_GATEWAY4})`).option("--force", "Override spending limits for this call (see `t2 limit`)").option("--key <path>", "Custom wallet path (default ~/.t2000/wallet.key)").action(
34923
35321
  async (opts) => {
34924
35322
  try {
34925
- const gateway = opts.gateway ?? DEFAULT_GATEWAY3;
35323
+ const gateway = opts.gateway ?? DEFAULT_GATEWAY4;
34926
35324
  const reward = Number.parseFloat(opts.reward);
34927
35325
  const completions = Number.parseInt(opts.completions, 10);
34928
35326
  if (!Number.isFinite(reward) || reward <= 0) {
@@ -34971,10 +35369,10 @@ function registerTask(program3) {
34971
35369
  }
34972
35370
  }
34973
35371
  );
34974
- 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(
35372
+ 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_GATEWAY4})`).option("--key <path>", "Custom wallet path (default ~/.t2000/wallet.key)").action(
34975
35373
  async (taskId, opts) => {
34976
35374
  try {
34977
- const gateway = opts.gateway ?? DEFAULT_GATEWAY3;
35375
+ const gateway = opts.gateway ?? DEFAULT_GATEWAY4;
34978
35376
  const agent = await withAgent({ keyPath: opts.key });
34979
35377
  const result = await postJson2(
34980
35378
  `${gateway}/tasks/board/${taskId}/submit`,
@@ -34996,9 +35394,9 @@ function registerTask(program3) {
34996
35394
  }
34997
35395
  }
34998
35396
  );
34999
- 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) => {
35397
+ 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_GATEWAY4})`).action(async (taskId, opts) => {
35000
35398
  try {
35001
- const gateway = opts.gateway ?? DEFAULT_GATEWAY3;
35399
+ const gateway = opts.gateway ?? DEFAULT_GATEWAY4;
35002
35400
  const result = await getJson2(`${gateway}/tasks/board/${taskId}?manageKey=${encodeURIComponent(opts.manageKey)}`);
35003
35401
  if (!result.posterView) {
35004
35402
  throw new Error(result.error ?? "manageKey not accepted for this task.");
@@ -35026,10 +35424,10 @@ function registerTask(program3) {
35026
35424
  handleError(error);
35027
35425
  }
35028
35426
  });
35029
- 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(
35427
+ 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_GATEWAY4})`).action(
35030
35428
  async (taskId, opts) => {
35031
35429
  try {
35032
- const gateway = opts.gateway ?? DEFAULT_GATEWAY3;
35430
+ const gateway = opts.gateway ?? DEFAULT_GATEWAY4;
35033
35431
  const result = await postJson2(`${gateway}/tasks/board/${taskId}/approve`, {
35034
35432
  manageKey: opts.manageKey,
35035
35433
  submissionIds: opts.submissions.split(",").map((s) => s.trim()).filter(Boolean),
@@ -35055,9 +35453,9 @@ function registerTask(program3) {
35055
35453
  }
35056
35454
  }
35057
35455
  );
35058
- 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) => {
35456
+ 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_GATEWAY4})`).action(async (taskId, opts) => {
35059
35457
  try {
35060
- const gateway = opts.gateway ?? DEFAULT_GATEWAY3;
35458
+ const gateway = opts.gateway ?? DEFAULT_GATEWAY4;
35061
35459
  const result = await postJson2(`${gateway}/tasks/board/${taskId}/close`, { manageKey: opts.manageKey });
35062
35460
  if (isJsonMode()) {
35063
35461
  printJson(result);