@t2000/cli 5.32.0 → 6.0.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((resolve3, reject) => {
10787
+ var detectFile = (filepath, opts = {}) => new Promise((resolve2, 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
- resolve3((0, exports.detect)(buffer));
10797
+ resolve2((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(resolve3, reject) {
18973
+ return new Promise(function(resolve2, reject) {
18974
18974
  try {
18975
18975
  const data = QRCode.create(text, opts);
18976
- resolve3(renderFunc(data, canvas, opts));
18976
+ resolve2(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(resolve3, reject) {
19058
+ return new Promise(function(resolve2, 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) : resolve3(data2);
19062
+ return err ? reject(err) : resolve2(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 resolve3;
30301
+ let resolve2;
30302
30302
  let reject;
30303
30303
  const promise = new Promise((res, rej) => {
30304
- resolve3 = res;
30304
+ resolve2 = res;
30305
30305
  reject = rej;
30306
30306
  });
30307
- return { promise, resolve: resolve3, reject };
30307
+ return { promise, resolve: resolve2, 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: resolve3, reject } = PromisePolyfill.withResolver();
30341
+ const { promise, resolve: resolve2, 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(() => resolve3(value));
30368
+ setImmediate(() => resolve2(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-VB42REWC.js");
33125
+ mod3 = await import("./dist-DYYYQUW7.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 createHash4 } from "crypto";
33598
+ import { createHash as createHash2 } 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";
@@ -33754,98 +33754,11 @@ function registerAgentCreate(group) {
33754
33754
  });
33755
33755
  }
33756
33756
 
33757
- // src/commands/agent/review.ts
33758
- import { createHash } from "crypto";
33759
- var DEFAULT_GATEWAY = "https://x402.t2000.ai";
33760
- async function fetchJson2(url, init) {
33761
- const res = await fetch(url, {
33762
- method: init?.method ?? "GET",
33763
- headers: init?.body ? { "Content-Type": "application/json" } : void 0,
33764
- body: init?.body ? JSON.stringify(init.body) : void 0
33765
- });
33766
- const json = await res.json().catch(() => ({}));
33767
- if (!res.ok) {
33768
- const err = json.error;
33769
- throw new Error(typeof err === "string" ? err : `HTTP ${res.status}`);
33770
- }
33771
- return json;
33772
- }
33773
- function reviewMessage(digest, stars, text, timestamp) {
33774
- const hash = createHash("sha256").update(text, "utf8").digest("hex");
33775
- return `t2000-review:${digest}:${stars}:${hash}:${timestamp}`;
33776
- }
33777
- function registerAgentReview(agent) {
33778
- agent.command("review").description(
33779
- "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]"
33780
- ).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(
33781
- async (seller, opts) => {
33782
- try {
33783
- const stars = Number(opts.stars);
33784
- if (!Number.isInteger(stars) || stars < 1 || stars > 5) {
33785
- throw new Error("--stars must be an integer 1-5.");
33786
- }
33787
- const text = (opts.text ?? "").trim();
33788
- if (text.length > 400) {
33789
- throw new Error("--text must be \u2264 400 chars.");
33790
- }
33791
- const gateway = opts.gateway ?? DEFAULT_GATEWAY;
33792
- const agentW = await withAgent({ keyPath: opts.key });
33793
- const buyer = agentW.address();
33794
- let digest = (opts.digest ?? "").trim();
33795
- if (!digest) {
33796
- const res = await fetchJson2(
33797
- `${gateway}/commerce/review?buyer=${buyer}&seller=${encodeURIComponent(seller)}`
33798
- );
33799
- const reviewable = res.reviewable ?? [];
33800
- if (reviewable.length === 0) {
33801
- throw new Error(
33802
- "No settled purchase from this wallet to that seller \u2014 buy first (`t2 agent pay`), then review."
33803
- );
33804
- }
33805
- digest = reviewable[0].digest;
33806
- }
33807
- const timestamp = Date.now();
33808
- const message = new TextEncoder().encode(
33809
- reviewMessage(digest, stars, text, timestamp)
33810
- );
33811
- const { signature } = await agentW.keypair.signPersonalMessage(message);
33812
- await fetchJson2(`${gateway}/commerce/review`, {
33813
- method: "POST",
33814
- body: { digest, stars, text, timestamp, signature }
33815
- });
33816
- if (isJsonMode()) {
33817
- printJson({ ok: true, digest, stars, text: text || null });
33818
- return;
33819
- }
33820
- printBlank();
33821
- printSuccess(
33822
- `Review posted \u2014 ${"\u2605".repeat(stars)}${"\u2606".repeat(5 - stars)}${text ? ` "${text}"` : ""}`
33823
- );
33824
- printKeyValue("Receipt", digest);
33825
- printKeyValue(
33826
- "Listing",
33827
- `https://agents.t2000.ai/${seller.startsWith("0x") ? seller : ""}`
33828
- );
33829
- printBlank();
33830
- } catch (e) {
33831
- handleError(e);
33832
- }
33833
- }
33834
- );
33835
- }
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
-
33844
33757
  // src/commands/agent/services.ts
33845
- import { createHash as createHash2 } from "crypto";
33758
+ import { createHash } from "crypto";
33846
33759
  import { readFileSync as readFileSync3 } from "fs";
33847
33760
  var SLUG_RE = /^[a-z0-9][a-z0-9-]{1,39}$/;
33848
- async function fetchJson3(url, init) {
33761
+ async function fetchJson2(url, init) {
33849
33762
  const res = await fetch(url, {
33850
33763
  method: init?.method ?? "GET",
33851
33764
  headers: init?.body ? { "Content-Type": "application/json" } : void 0,
@@ -33869,7 +33782,7 @@ function canonicalServicesJson(services) {
33869
33782
  );
33870
33783
  }
33871
33784
  async function getCatalog(base, address) {
33872
- const res = await fetchJson3(
33785
+ const res = await fetchJson2(
33873
33786
  `${base}/agent/services?address=${encodeURIComponent(address)}`
33874
33787
  );
33875
33788
  return Array.isArray(res.services) ? res.services : [];
@@ -33877,7 +33790,7 @@ async function getCatalog(base, address) {
33877
33790
  async function putCatalog(opts) {
33878
33791
  const agent = await withAgent({ keyPath: opts.keyPath });
33879
33792
  const address = agent.address();
33880
- const challenge = await fetchJson3(`${opts.base}/agent/challenge`, {
33793
+ const challenge = await fetchJson2(`${opts.base}/agent/challenge`, {
33881
33794
  method: "POST",
33882
33795
  body: { address }
33883
33796
  });
@@ -33885,12 +33798,12 @@ async function putCatalog(opts) {
33885
33798
  if (!nonce) {
33886
33799
  throw new Error("Failed to get a challenge nonce.");
33887
33800
  }
33888
- const digest = createHash2("sha256").update(canonicalServicesJson(opts.services)).digest("hex");
33801
+ const digest = createHash("sha256").update(canonicalServicesJson(opts.services)).digest("hex");
33889
33802
  const message = new TextEncoder().encode(
33890
33803
  `t2000-agent-services:${nonce}:${digest}`
33891
33804
  );
33892
33805
  const { signature } = await agent.keypair.signPersonalMessage(message);
33893
- const res = await fetchJson3(`${opts.base}/agent/services`, {
33806
+ const res = await fetchJson2(`${opts.base}/agent/services`, {
33894
33807
  method: "POST",
33895
33808
  body: { address, nonce, signature, services: opts.services }
33896
33809
  });
@@ -34069,513 +33982,9 @@ function registerAgentServices(agentGroup, defaults) {
34069
33982
  });
34070
33983
  }
34071
33984
 
34072
- // src/commands/agent/serve.ts
34073
- var DEFAULT_API_BASE4 = process.env.T2000_API_URL ?? "https://api.t2000.ai/v1";
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, secrets }
34087
- // secrets = your vault (t2 agent serve secrets set KEY=value)
34088
- export default async function handle(input, ctx) {
34089
- // Example: compose public data and return a result.
34090
- // const res = await fetch('https://api.example.com/data');
34091
- // const data = await res.json();
34092
- return {
34093
- echo: input,
34094
- from: ctx.slug,
34095
- note: 'Replace this with your service logic.',
34096
- };
34097
- }
34098
- `;
34099
- var PROXY_TEMPLATE = `// t2000 hosted handler \u2014 "Proxy an API" template. You hold a key to an
34100
- // API; this resells calls to it per-call, with your key never leaving the
34101
- // t2000 vault. Setup:
34102
- // 1. Edit UPSTREAM below.
34103
- // 2. t2 agent serve secrets set UPSTREAM_KEY=<your api key>
34104
- // 3. t2 agent serve deploy
34105
- const UPSTREAM = 'https://api.example.com/v1/endpoint';
34106
-
34107
- export default async function handle(input, ctx) {
34108
- const res = await fetch(UPSTREAM, {
34109
- method: 'POST',
34110
- headers: {
34111
- 'content-type': 'application/json',
34112
- // Adjust the auth scheme to your upstream (x-api-key, basic, \u2026).
34113
- ...(ctx.secrets?.UPSTREAM_KEY
34114
- ? { authorization: \`Bearer \${ctx.secrets.UPSTREAM_KEY}\` }
34115
- : {}),
34116
- },
34117
- body: JSON.stringify(input ?? {}),
34118
- });
34119
- if (!res.ok) {
34120
- // Throwing fails the delivery \u2192 the buyer is auto-refunded.
34121
- throw new Error(\`Upstream error \${res.status}\`);
34122
- }
34123
- return await res.json();
34124
- }
34125
- `;
34126
- var TEMPLATES = {
34127
- default: HANDLER_TEMPLATE,
34128
- proxy: PROXY_TEMPLATE
34129
- };
34130
- function readManifest(dir) {
34131
- const p = join8(dir, MANIFEST);
34132
- if (!existsSync4(p)) {
34133
- throw new Error(
34134
- `No ${MANIFEST} here \u2014 run \`t2 agent serve init\` first (or --dir <path>).`
34135
- );
34136
- }
34137
- const m = JSON.parse(readFileSync4(p, "utf8"));
34138
- const slug = String(m.slug ?? "").trim().toLowerCase();
34139
- if (!SLUG_RE2.test(slug)) {
34140
- throw new Error(`${MANIFEST}: slug must match [a-z0-9-], 2-40 chars.`);
34141
- }
34142
- if (!m.title?.trim() || !m.description?.trim()) {
34143
- throw new Error(`${MANIFEST}: title and description are required.`);
34144
- }
34145
- const price = Number(m.price);
34146
- if (!Number.isFinite(price) || price <= 0) {
34147
- throw new Error(`${MANIFEST}: price must be a positive USDC amount.`);
34148
- }
34149
- return { ...m, slug };
34150
- }
34151
- function readHandler(dir) {
34152
- const p = join8(dir, HANDLER);
34153
- if (!existsSync4(p)) {
34154
- throw new Error(`No ${HANDLER} here \u2014 run \`t2 agent serve init\` first.`);
34155
- }
34156
- const src = readFileSync4(p, "utf8");
34157
- if (!src.trim()) {
34158
- throw new Error(`${HANDLER} is empty.`);
34159
- }
34160
- if (/^\s*import\s.+from\s/m.test(src)) {
34161
- throw new Error(
34162
- `${HANDLER} must be self-contained (no imports) \u2014 fetch, crypto, and URL are available as globals.`
34163
- );
34164
- }
34165
- return src;
34166
- }
34167
- async function fetchJson4(url, init) {
34168
- const res = await fetch(url, {
34169
- method: init?.method ?? "GET",
34170
- headers: init?.body ? { "Content-Type": "application/json" } : void 0,
34171
- body: init?.body ? JSON.stringify(init.body) : void 0
34172
- });
34173
- const json = await res.json().catch(() => ({}));
34174
- if (!res.ok) {
34175
- const err = json.error;
34176
- const msg = typeof err === "string" ? err : err?.message ?? `HTTP ${res.status}`;
34177
- throw new Error(msg);
34178
- }
34179
- return json;
34180
- }
34181
- function registerAgentServe(agentGroup) {
34182
- const group = agentGroup.command("serve").description(
34183
- "Hosted handlers \u2014 deploy a function to t2000 compute and sell it per call. No server, no wrap. [R1]"
34184
- );
34185
- group.command("init").description(`Scaffold ${HANDLER} + ${MANIFEST} in the current directory.`).option("--slug <slug>", "Service slug (in the buy URL)", "my-service").option(
34186
- "--template <name>",
34187
- `Handler template: ${Object.keys(TEMPLATES).join(" | ")} (proxy = resell a keyed API)`,
34188
- "default"
34189
- ).option("--dir <path>", "Target directory (default: cwd)").action((opts) => {
34190
- try {
34191
- const dir = resolve2(opts.dir ?? ".");
34192
- mkdirSync2(dir, { recursive: true });
34193
- const slug = opts.slug.trim().toLowerCase();
34194
- if (!SLUG_RE2.test(slug)) {
34195
- throw new Error("--slug must match [a-z0-9-], 2-40 chars.");
34196
- }
34197
- const template = TEMPLATES[opts.template];
34198
- if (!template) {
34199
- throw new Error(
34200
- `Unknown --template "${opts.template}" \u2014 use: ${Object.keys(TEMPLATES).join(", ")}.`
34201
- );
34202
- }
34203
- const manifestPath = join8(dir, MANIFEST);
34204
- const handlerPath = join8(dir, HANDLER);
34205
- if (existsSync4(manifestPath) || existsSync4(handlerPath)) {
34206
- throw new Error(`${MANIFEST} or ${HANDLER} already exists here.`);
34207
- }
34208
- writeFileSync3(
34209
- manifestPath,
34210
- `${JSON.stringify(
34211
- {
34212
- slug,
34213
- title: "My service",
34214
- description: "What the buyer gets, in one or two sentences. Provide: 1. \u2026",
34215
- price: "0.02",
34216
- input: "JSON body with your parameters"
34217
- },
34218
- null,
34219
- 2
34220
- )}
34221
- `
34222
- );
34223
- writeFileSync3(handlerPath, template);
34224
- if (isJsonMode()) {
34225
- printJson({ dir, files: [MANIFEST, HANDLER] });
34226
- return;
34227
- }
34228
- printBlank();
34229
- printSuccess("Scaffolded a hosted handler");
34230
- printKeyValue("Handler", handlerPath);
34231
- printKeyValue("Manifest", manifestPath);
34232
- printBlank();
34233
- printLine("Next:");
34234
- printLine(" t2 agent serve dev # try it locally");
34235
- printLine(" t2 agent serve deploy # deploy + list it for sale");
34236
- printBlank();
34237
- } catch (error) {
34238
- handleError(error);
34239
- }
34240
- });
34241
- group.command("dev").description(
34242
- "Run the handler locally against the delivery contract (POST {input} to :8787)."
34243
- ).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) => {
34244
- try {
34245
- const dir = resolve2(opts.dir ?? ".");
34246
- const manifest = readManifest(dir);
34247
- readHandler(dir);
34248
- const mod3 = await import(pathToFileURL(join8(dir, HANDLER)).href);
34249
- const fn = mod3.default;
34250
- if (typeof fn !== "function") {
34251
- throw new Error(`${HANDLER} must default-export a function.`);
34252
- }
34253
- const ctx = {
34254
- agent: "0xLOCAL",
34255
- slug: manifest.slug,
34256
- buyer: "0xBUYER"
34257
- };
34258
- if (opts.input !== void 0) {
34259
- let input = opts.input;
34260
- try {
34261
- input = JSON.parse(opts.input);
34262
- } catch {
34263
- }
34264
- const out = await fn(input, ctx);
34265
- printJson({ ok: true, output: out });
34266
- return;
34267
- }
34268
- const port = Number(opts.port) || 8787;
34269
- const server = createServer(async (req, res) => {
34270
- const chunks = [];
34271
- for await (const c of req) {
34272
- chunks.push(c);
34273
- }
34274
- const raw = Buffer.concat(chunks).toString("utf8");
34275
- let input = raw;
34276
- try {
34277
- input = raw ? JSON.parse(raw) : {};
34278
- } catch {
34279
- }
34280
- try {
34281
- const out = await fn(input, ctx);
34282
- res.writeHead(200, { "content-type": "application/json" });
34283
- res.end(JSON.stringify(out));
34284
- } catch (e) {
34285
- res.writeHead(500, { "content-type": "application/json" });
34286
- res.end(
34287
- JSON.stringify({ error: e instanceof Error ? e.message : String(e) })
34288
- );
34289
- }
34290
- });
34291
- server.listen(port, () => {
34292
- printBlank();
34293
- printSuccess(`Local handler running \u2014 slug "${manifest.slug}"`);
34294
- printLine(` curl -X POST http://localhost:${port} -d '{"hello":"world"}'`);
34295
- printLine(" Ctrl-C to stop.");
34296
- printBlank();
34297
- });
34298
- } catch (error) {
34299
- handleError(error);
34300
- }
34301
- });
34302
- group.command("deploy").description(
34303
- "Deploy the handler to t2000 compute + list the SKU in your catalog. Sponsored listing, per-call earnings to your wallet."
34304
- ).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(
34305
- async (opts) => {
34306
- try {
34307
- const dir = resolve2(opts.dir ?? ".");
34308
- const base = opts.api ?? DEFAULT_API_BASE4;
34309
- const gateway = opts.gateway ?? DEFAULT_GATEWAY2;
34310
- const manifest = readManifest(dir);
34311
- const script = readHandler(dir);
34312
- const scriptB64 = Buffer.from(script, "utf8").toString("base64");
34313
- const agent = await withAgent({ keyPath: opts.key });
34314
- const address = agent.address();
34315
- const ts = Date.now();
34316
- const bodyHash = createHash3("sha256").update(`${manifest.slug}|${scriptB64}`).digest("hex");
34317
- const message = new TextEncoder().encode(
34318
- `t2000-serve:${ts}:${bodyHash}`
34319
- );
34320
- const { signature } = await agent.keypair.signPersonalMessage(message);
34321
- const deployed = await fetchJson4(`${gateway}/serve/deploy`, {
34322
- method: "POST",
34323
- body: {
34324
- address,
34325
- slug: manifest.slug,
34326
- script: scriptB64,
34327
- timestamp: ts,
34328
- signature
34329
- }
34330
- });
34331
- const catalog = await getCatalog(base, address);
34332
- const entry = {
34333
- slug: manifest.slug,
34334
- title: manifest.title,
34335
- description: manifest.description,
34336
- priceUsdc: String(manifest.price),
34337
- input: manifest.input ?? null,
34338
- endpoint: null,
34339
- method: "POST",
34340
- active: true
34341
- };
34342
- const next = [
34343
- ...catalog.filter((s) => s.slug !== manifest.slug),
34344
- entry
34345
- ];
34346
- await putCatalog({ base, keyPath: opts.key, services: next });
34347
- const buyUrl = String(
34348
- deployed.buyUrl ?? `https://x402.t2000.ai/commerce/pay/${address}/${manifest.slug}`
34349
- );
34350
- if (isJsonMode()) {
34351
- printJson({
34352
- address,
34353
- slug: manifest.slug,
34354
- sizeBytes: deployed.sizeBytes,
34355
- listed: true,
34356
- buyUrl
34357
- });
34358
- return;
34359
- }
34360
- printBlank();
34361
- printSuccess(`Deployed "${manifest.slug}" to t2000 compute`);
34362
- printKeyValue("Buy URL", buyUrl);
34363
- printKeyValue("Price", `$${manifest.price} per call`);
34364
- printKeyValue("Store", `https://agents.t2000.ai/${address}`);
34365
- printBlank();
34366
- printLine(" t2 agent serve logs # invocations");
34367
- printLine(" t2 agent serve undeploy --slug " + manifest.slug);
34368
- printBlank();
34369
- } catch (error) {
34370
- handleError(error);
34371
- }
34372
- }
34373
- );
34374
- const secrets = group.command("secrets").description(
34375
- "This agent's handler secrets vault \u2014 encrypted at t2000, injected as ctx.secrets on paid deliveries only. Values are write-only."
34376
- );
34377
- secrets.command("set").argument("<pairs...>", "NAME=value pairs (e.g. UPSTREAM_KEY=sk-\u2026)").description("Set (or overwrite) vault secrets. NAME: A-Z, 0-9, _.").option("--key <path>", "Custom wallet path (default ~/.t2000/wallet.key)").option("--gateway <url>", `Gateway URL (default ${DEFAULT_GATEWAY2})`).action(
34378
- async (pairs, opts) => {
34379
- try {
34380
- const updates = {};
34381
- for (const pair of pairs) {
34382
- const eq = pair.indexOf("=");
34383
- if (eq <= 0) {
34384
- throw new Error(`"${pair}" is not NAME=value.`);
34385
- }
34386
- updates[pair.slice(0, eq).trim()] = pair.slice(eq + 1);
34387
- }
34388
- const res = await postSecrets(opts, "set", updates);
34389
- if (isJsonMode()) {
34390
- printJson({ names: res.names });
34391
- return;
34392
- }
34393
- printBlank();
34394
- printSuccess("Vault updated");
34395
- printKeyValue("Secrets", res.names.join(", ") || "(none)");
34396
- printInfo("Handlers read them as ctx.secrets.NAME on paid deliveries.");
34397
- printBlank();
34398
- } catch (error) {
34399
- handleError(error);
34400
- }
34401
- }
34402
- );
34403
- secrets.command("unset").argument("<names...>", "Secret names to delete").description("Delete vault secrets.").option("--key <path>", "Custom wallet path (default ~/.t2000/wallet.key)").option("--gateway <url>", `Gateway URL (default ${DEFAULT_GATEWAY2})`).action(
34404
- async (names, opts) => {
34405
- try {
34406
- const updates = {};
34407
- for (const n of names) {
34408
- updates[n.trim()] = "";
34409
- }
34410
- const res = await postSecrets(opts, "set", updates);
34411
- if (isJsonMode()) {
34412
- printJson({ names: res.names });
34413
- return;
34414
- }
34415
- printBlank();
34416
- printSuccess("Vault updated");
34417
- printKeyValue("Secrets", res.names.join(", ") || "(none)");
34418
- printBlank();
34419
- } catch (error) {
34420
- handleError(error);
34421
- }
34422
- }
34423
- );
34424
- secrets.command("list").description("List vault secret NAMES (values never leave the gateway).").option("--key <path>", "Custom wallet path (default ~/.t2000/wallet.key)").option("--gateway <url>", `Gateway URL (default ${DEFAULT_GATEWAY2})`).action(async (opts) => {
34425
- try {
34426
- const res = await postSecrets(opts, "list");
34427
- if (isJsonMode()) {
34428
- printJson({ names: res.names });
34429
- return;
34430
- }
34431
- const names = res.names;
34432
- printBlank();
34433
- if (names.length === 0) {
34434
- printLine("Vault is empty. Set one: t2 agent serve secrets set NAME=value");
34435
- } else {
34436
- for (const n of names) {
34437
- printLine(` ${n}`);
34438
- }
34439
- }
34440
- printBlank();
34441
- } catch (error) {
34442
- handleError(error);
34443
- }
34444
- });
34445
- async function postSecrets(opts, op, updates) {
34446
- const gateway = opts.gateway ?? DEFAULT_GATEWAY2;
34447
- const agent = await withAgent({ keyPath: opts.key });
34448
- const address = agent.address();
34449
- const ts = Date.now();
34450
- const payload = op === "list" ? "list" : JSON.stringify(
34451
- Object.fromEntries(
34452
- Object.entries(updates ?? {}).sort(
34453
- ([a], [b]) => a.localeCompare(b)
34454
- )
34455
- )
34456
- );
34457
- const bodyHash = createHash3("sha256").update(payload).digest("hex");
34458
- const message = new TextEncoder().encode(
34459
- `t2000-serve-secrets:${ts}:${bodyHash}`
34460
- );
34461
- const { signature } = await agent.keypair.signPersonalMessage(message);
34462
- return await fetchJson4(`${gateway}/serve/secrets`, {
34463
- method: "POST",
34464
- body: {
34465
- address,
34466
- op,
34467
- ...op === "set" ? { updates } : {},
34468
- timestamp: ts,
34469
- signature
34470
- }
34471
- });
34472
- }
34473
- 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) => {
34474
- try {
34475
- const gateway = opts.gateway ?? DEFAULT_GATEWAY2;
34476
- const agent = await withAgent({ keyPath: opts.key });
34477
- const address = agent.address();
34478
- const res = await fetchJson4(
34479
- `${gateway}/serve/status?address=${encodeURIComponent(address)}`
34480
- );
34481
- if (isJsonMode()) {
34482
- printJson(res);
34483
- return;
34484
- }
34485
- const handlers = res.handlers ?? [];
34486
- printBlank();
34487
- if (handlers.length === 0) {
34488
- printLine("No hosted handlers. Start one: t2 agent serve init");
34489
- printBlank();
34490
- return;
34491
- }
34492
- for (const h of handlers) {
34493
- printLine(
34494
- ` ${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}` : ""}`
34495
- );
34496
- }
34497
- printBlank();
34498
- } catch (error) {
34499
- handleError(error);
34500
- }
34501
- });
34502
- 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(
34503
- async (opts) => {
34504
- try {
34505
- const gateway = opts.gateway ?? DEFAULT_GATEWAY2;
34506
- const agent = await withAgent({ keyPath: opts.key });
34507
- const address = agent.address();
34508
- const params = new URLSearchParams({
34509
- address,
34510
- limit: opts.limit
34511
- });
34512
- if (opts.slug) {
34513
- params.set("slug", opts.slug);
34514
- }
34515
- const res = await fetchJson4(`${gateway}/serve/logs?${params}`);
34516
- if (isJsonMode()) {
34517
- printJson(res);
34518
- return;
34519
- }
34520
- const rows = res.invocations ?? [];
34521
- printBlank();
34522
- if (rows.length === 0) {
34523
- printLine("No invocations yet.");
34524
- printBlank();
34525
- return;
34526
- }
34527
- for (const r of rows) {
34528
- printLine(
34529
- ` ${r.at} ${r.slug} ${r.status} ${r.durationMs}ms${r.error ? ` ${r.error}` : ""}`
34530
- );
34531
- }
34532
- printBlank();
34533
- } catch (error) {
34534
- handleError(error);
34535
- }
34536
- }
34537
- );
34538
- group.command("undeploy").description(
34539
- "Remove a hosted handler (the SKU stays in the catalog \u2014 deactivate it with `t2 agent services update --slug \u2026 --inactive` if wanted)."
34540
- ).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(
34541
- async (opts) => {
34542
- try {
34543
- const gateway = opts.gateway ?? DEFAULT_GATEWAY2;
34544
- const slug = opts.slug.trim().toLowerCase();
34545
- if (!SLUG_RE2.test(slug)) {
34546
- throw new Error("--slug must match [a-z0-9-], 2-40 chars.");
34547
- }
34548
- const agent = await withAgent({ keyPath: opts.key });
34549
- const address = agent.address();
34550
- const ts = Date.now();
34551
- const message = new TextEncoder().encode(
34552
- `t2000-serve-remove:${ts}:${slug}`
34553
- );
34554
- const { signature } = await agent.keypair.signPersonalMessage(message);
34555
- await fetchJson4(`${gateway}/serve/undeploy`, {
34556
- method: "POST",
34557
- body: { address, slug, timestamp: ts, signature }
34558
- });
34559
- if (isJsonMode()) {
34560
- printJson({ address, slug, undeployed: true });
34561
- return;
34562
- }
34563
- printBlank();
34564
- printSuccess(`Undeployed "${slug}"`);
34565
- printInfo(
34566
- "Buys against it now fail closed (auto-refund). Redeploy anytime: t2 agent serve deploy"
34567
- );
34568
- printBlank();
34569
- } catch (error) {
34570
- handleError(error);
34571
- }
34572
- }
34573
- );
34574
- }
34575
-
34576
33985
  // src/commands/agent/index.ts
34577
- var DEFAULT_API_BASE5 = process.env.T2000_API_URL ?? "https://api.t2000.ai/v1";
34578
- var DEFAULT_GATEWAY3 = process.env.T2000_GATEWAY_URL ?? "https://mpp.t2000.ai";
33986
+ var DEFAULT_API_BASE4 = process.env.T2000_API_URL ?? "https://api.t2000.ai/v1";
33987
+ var DEFAULT_GATEWAY = process.env.T2000_GATEWAY_URL ?? "https://mpp.t2000.ai";
34579
33988
  var DEFAULT_RAIL = process.env.T2000_RAIL_URL ?? "https://x402.t2000.ai";
34580
33989
  var AGENT_CATEGORIES2 = [
34581
33990
  "ai-models",
@@ -34614,19 +34023,19 @@ async function fundCredit(agent, base, amountStr, assetOpt) {
34614
34023
  throw new Error(`amount must be a positive number (got "${amountStr}").`);
34615
34024
  }
34616
34025
  const asset = normalizeTopupAsset(assetOpt);
34617
- const cfg = await fetchJson5(`${base}/agent/topup`, { method: "GET" });
34026
+ const cfg = await fetchJson3(`${base}/agent/topup`, { method: "GET" });
34618
34027
  const treasury = cfg.treasury;
34619
34028
  if (!treasury) {
34620
34029
  throw new Error("Could not resolve the t2000 treasury address.");
34621
34030
  }
34622
34031
  const sent = await agent.send({ to: treasury, amount, asset });
34623
- const topup = await fetchJson5(`${base}/agent/topup`, {
34032
+ const topup = await fetchJson3(`${base}/agent/topup`, {
34624
34033
  method: "POST",
34625
34034
  body: { address: agent.address(), digest: sent.tx }
34626
34035
  });
34627
34036
  return { amount, asset, balanceUsd: topup.balanceUsd };
34628
34037
  }
34629
- async function fetchJson5(url, init) {
34038
+ async function fetchJson3(url, init) {
34630
34039
  const res = await fetch(url, {
34631
34040
  method: init.method,
34632
34041
  headers: init.body ? { "Content-Type": "application/json" } : void 0,
@@ -34654,15 +34063,13 @@ Subcommands:
34654
34063
  `
34655
34064
  );
34656
34065
  registerAgentCreate(group);
34657
- registerAgentServices(group, { apiBase: DEFAULT_API_BASE5 });
34658
- registerAgentServe(group);
34659
- registerAgentReview(group);
34066
+ registerAgentServices(group, { apiBase: DEFAULT_API_BASE4 });
34660
34067
  group.command("onboard").description(
34661
34068
  "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`."
34662
- ).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(
34069
+ ).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(
34663
34070
  async (opts) => {
34664
34071
  try {
34665
- const base = opts.api ?? DEFAULT_API_BASE5;
34072
+ const base = opts.api ?? DEFAULT_API_BASE4;
34666
34073
  const agent = await withAgent({ keyPath: opts.key });
34667
34074
  const address = agent.address();
34668
34075
  if (opts.fund !== void 0) {
@@ -34673,7 +34080,7 @@ Subcommands:
34673
34080
  );
34674
34081
  }
34675
34082
  }
34676
- const challenge = await fetchJson5(`${base}/agent/challenge`, {
34083
+ const challenge = await fetchJson3(`${base}/agent/challenge`, {
34677
34084
  method: "POST",
34678
34085
  body: { address }
34679
34086
  });
@@ -34683,7 +34090,7 @@ Subcommands:
34683
34090
  }
34684
34091
  const message = new TextEncoder().encode(`t2000-agent-keys:${nonce}`);
34685
34092
  const { signature } = await agent.keypair.signPersonalMessage(message);
34686
- const minted = await fetchJson5(`${base}/agent/keys`, {
34093
+ const minted = await fetchJson3(`${base}/agent/keys`, {
34687
34094
  method: "POST",
34688
34095
  body: { address, nonce, signature }
34689
34096
  });
@@ -34720,10 +34127,10 @@ Subcommands:
34720
34127
  );
34721
34128
  group.command("topup").argument("<amount>", "Stablecoin amount to deposit as credit").description(
34722
34129
  "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."
34723
- ).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(
34130
+ ).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(
34724
34131
  async (amount, opts) => {
34725
34132
  try {
34726
- const base = opts.api ?? DEFAULT_API_BASE5;
34133
+ const base = opts.api ?? DEFAULT_API_BASE4;
34727
34134
  const agent = await withAgent({ keyPath: opts.key });
34728
34135
  const funded = await fundCredit(agent, base, amount, opts.asset);
34729
34136
  if (isJsonMode()) {
@@ -34747,9 +34154,9 @@ Subcommands:
34747
34154
  );
34748
34155
  group.command("register").description(
34749
34156
  "Register this wallet on-chain as an Agent ID (sponsored, gasless). Idempotent \u2014 safe to re-run."
34750
- ).option("--key <path>", "Custom wallet path (default ~/.t2000/wallet.key)").option("--api <url>", `API base URL (default ${DEFAULT_API_BASE5})`).action(async (opts) => {
34157
+ ).option("--key <path>", "Custom wallet path (default ~/.t2000/wallet.key)").option("--api <url>", `API base URL (default ${DEFAULT_API_BASE4})`).action(async (opts) => {
34751
34158
  try {
34752
- const base = opts.api ?? DEFAULT_API_BASE5;
34159
+ const base = opts.api ?? DEFAULT_API_BASE4;
34753
34160
  const agent = await withAgent({ keyPath: opts.key });
34754
34161
  const address = agent.address();
34755
34162
  const reg = await registerWallet({ keypair: agent.keypair, address, base });
@@ -34777,9 +34184,9 @@ Subcommands:
34777
34184
  });
34778
34185
  group.command("link").argument("<owner>", "The owner's Sui address (Passport) to propose").description(
34779
34186
  "Propose an owner for this agent (two-sided \u2014 the owner must then confirm). Sponsored, gasless."
34780
- ).option("--key <path>", "Custom wallet path (default ~/.t2000/wallet.key)").option("--api <url>", `API base URL (default ${DEFAULT_API_BASE5})`).action(async (owner, opts) => {
34187
+ ).option("--key <path>", "Custom wallet path (default ~/.t2000/wallet.key)").option("--api <url>", `API base URL (default ${DEFAULT_API_BASE4})`).action(async (owner, opts) => {
34781
34188
  try {
34782
- const base = opts.api ?? DEFAULT_API_BASE5;
34189
+ const base = opts.api ?? DEFAULT_API_BASE4;
34783
34190
  const agent = await withAgent({ keyPath: opts.key });
34784
34191
  const address = agent.address();
34785
34192
  if (!isValidSuiAddress(owner)) {
@@ -34816,9 +34223,9 @@ Subcommands:
34816
34223
  });
34817
34224
  group.command("confirm").argument("<agent>", "The agent Sui address to confirm ownership of").description(
34818
34225
  "Confirm ownership of an agent that proposed you as its owner. Sponsored, gasless."
34819
- ).option("--key <path>", "Custom wallet path (default ~/.t2000/wallet.key)").option("--api <url>", `API base URL (default ${DEFAULT_API_BASE5})`).action(async (agentAddress, opts) => {
34226
+ ).option("--key <path>", "Custom wallet path (default ~/.t2000/wallet.key)").option("--api <url>", `API base URL (default ${DEFAULT_API_BASE4})`).action(async (agentAddress, opts) => {
34820
34227
  try {
34821
- const base = opts.api ?? DEFAULT_API_BASE5;
34228
+ const base = opts.api ?? DEFAULT_API_BASE4;
34822
34229
  const owner = await withAgent({ keyPath: opts.key });
34823
34230
  const address = owner.address();
34824
34231
  const { digest } = await runSponsoredTx({
@@ -34842,9 +34249,9 @@ Subcommands:
34842
34249
  });
34843
34250
  group.command("unlink").argument("<agent>", "The agent Sui address to renounce ownership of").description(
34844
34251
  "Renounce ownership of an agent you own \u2014 the record returns to autonomous (public, on-chain). Sponsored, gasless. Re-link = the agent proposes again."
34845
- ).option("--key <path>", "Custom wallet path (default ~/.t2000/wallet.key)").option("--api <url>", `API base URL (default ${DEFAULT_API_BASE5})`).action(async (agentAddress, opts) => {
34252
+ ).option("--key <path>", "Custom wallet path (default ~/.t2000/wallet.key)").option("--api <url>", `API base URL (default ${DEFAULT_API_BASE4})`).action(async (agentAddress, opts) => {
34846
34253
  try {
34847
- const base = opts.api ?? DEFAULT_API_BASE5;
34254
+ const base = opts.api ?? DEFAULT_API_BASE4;
34848
34255
  const owner = await withAgent({ keyPath: opts.key });
34849
34256
  const address = owner.address();
34850
34257
  const { digest } = await runSponsoredTx({
@@ -34869,7 +34276,7 @@ Subcommands:
34869
34276
  });
34870
34277
  group.command("profile").description(
34871
34278
  "Set this agent's public profile (name \xB7 image \xB7 description \xB7 links). Signed, no gas \u2014 shows in the directory."
34872
- ).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(
34279
+ ).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(
34873
34280
  async (opts) => {
34874
34281
  try {
34875
34282
  if (!(opts.name || opts.image || opts.description || opts.website || opts.twitter || opts.github)) {
@@ -34877,10 +34284,10 @@ Subcommands:
34877
34284
  "Provide at least one of --name, --image, --description, --website, --twitter, --github."
34878
34285
  );
34879
34286
  }
34880
- const base = opts.api ?? DEFAULT_API_BASE5;
34287
+ const base = opts.api ?? DEFAULT_API_BASE4;
34881
34288
  const agent = await withAgent({ keyPath: opts.key });
34882
34289
  const address = agent.address();
34883
- const challenge = await fetchJson5(`${base}/agent/challenge`, {
34290
+ const challenge = await fetchJson3(`${base}/agent/challenge`, {
34884
34291
  method: "POST",
34885
34292
  body: { address }
34886
34293
  });
@@ -34890,7 +34297,7 @@ Subcommands:
34890
34297
  }
34891
34298
  const message = new TextEncoder().encode(`t2000-agent-profile:${nonce}`);
34892
34299
  const { signature } = await agent.keypair.signPersonalMessage(message);
34893
- await fetchJson5(`${base}/agent/profile`, {
34300
+ await fetchJson3(`${base}/agent/profile`, {
34894
34301
  method: "POST",
34895
34302
  body: {
34896
34303
  address,
@@ -34924,7 +34331,7 @@ Subcommands:
34924
34331
  ).option("--price <usdc>", "Price per call in USDC (e.g. 0.02) \u2014 buyers pay this").option(
34925
34332
  "--category <category>",
34926
34333
  `Storefront category: ${AGENT_CATEGORIES2.join(" | ")}`
34927
- ).option("--key <path>", "Custom wallet path (default ~/.t2000/wallet.key)").option("--api <url>", `API base URL (default ${DEFAULT_API_BASE5})`).action(
34334
+ ).option("--key <path>", "Custom wallet path (default ~/.t2000/wallet.key)").option("--api <url>", `API base URL (default ${DEFAULT_API_BASE4})`).action(
34928
34335
  async (opts) => {
34929
34336
  try {
34930
34337
  if (opts.mcpEndpoint === void 0 && opts.paymentMethods === void 0 && opts.price === void 0 && opts.category === void 0) {
@@ -34939,7 +34346,7 @@ Subcommands:
34939
34346
  }
34940
34347
  }
34941
34348
  const category = normalizeCategory(opts.category);
34942
- const base = opts.api ?? DEFAULT_API_BASE5;
34349
+ const base = opts.api ?? DEFAULT_API_BASE4;
34943
34350
  const agent = await withAgent({ keyPath: opts.key });
34944
34351
  const address = agent.address();
34945
34352
  const prepareBody = { address };
@@ -35000,11 +34407,11 @@ Subcommands:
35000
34407
  ).option("--remove", "Take down the deployed service").option(
35001
34408
  "--service <slug>",
35002
34409
  "Catalog service slug \u2014 wrap config for ONE SKU (Store v2; omit = the default service)"
35003
- ).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(
34410
+ ).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_BASE4})`).action(
35004
34411
  async (opts) => {
35005
34412
  try {
35006
- const base = opts.api ?? DEFAULT_API_BASE5;
35007
- const gateway = opts.gateway ?? DEFAULT_GATEWAY3;
34413
+ const base = opts.api ?? DEFAULT_API_BASE4;
34414
+ const gateway = opts.gateway ?? DEFAULT_GATEWAY;
35008
34415
  const category = normalizeCategory(opts.category);
35009
34416
  const slug = opts.service?.trim().toLowerCase() || void 0;
35010
34417
  const agent = await withAgent({ keyPath: opts.key });
@@ -35015,7 +34422,7 @@ Subcommands:
35015
34422
  const { signature: signature2 } = await agent.keypair.signPersonalMessage(
35016
34423
  new TextEncoder().encode(msg2)
35017
34424
  );
35018
- await fetchJson5(`${gateway}/deploy/config`, {
34425
+ await fetchJson3(`${gateway}/deploy/config`, {
35019
34426
  method: "DELETE",
35020
34427
  body: { address, timestamp: ts2, signature: signature2, ...slug ? { slug } : {} }
35021
34428
  });
@@ -35047,14 +34454,14 @@ Subcommands:
35047
34454
  const method = (opts.method ?? "POST").toUpperCase() === "GET" ? "GET" : "POST";
35048
34455
  const headers = opts.header ?? {};
35049
34456
  const ts = Date.now();
35050
- const bodyHash = createHash4("sha256").update(
34457
+ const bodyHash = createHash2("sha256").update(
35051
34458
  `${opts.upstream}|${method}|${JSON.stringify(headers)}${slug ? `|${slug}` : ""}`
35052
34459
  ).digest("hex");
35053
34460
  const msg = `t2000-deploy:${ts}:${bodyHash}`;
35054
34461
  const { signature } = await agent.keypair.signPersonalMessage(
35055
34462
  new TextEncoder().encode(msg)
35056
34463
  );
35057
- await fetchJson5(`${gateway}/deploy/config`, {
34464
+ await fetchJson3(`${gateway}/deploy/config`, {
35058
34465
  method: "POST",
35059
34466
  body: {
35060
34467
  address,
@@ -35123,7 +34530,7 @@ Subcommands:
35123
34530
  "Catalog service slug \u2014 buys ONE SKU of the seller's catalog (Store v2)"
35124
34531
  ).option(
35125
34532
  "--gateway <url>",
35126
- `Gateway base URL (default ${DEFAULT_GATEWAY3})`
34533
+ `Gateway base URL (default ${DEFAULT_GATEWAY})`
35127
34534
  ).option("--force", "Override spending limits for this call (see `t2 limit`)").option("--key <path>", "Custom wallet path (default ~/.t2000/wallet.key)").action(
35128
34535
  async (seller, opts) => {
35129
34536
  try {
@@ -35134,7 +34541,7 @@ Subcommands:
35134
34541
  }
35135
34542
  }
35136
34543
  const maxPrice = opts.maxPrice ? Number.parseFloat(opts.maxPrice) : opts.amount ? Number.parseFloat(opts.amount) : 1;
35137
- const gateway = opts.gateway ?? DEFAULT_GATEWAY3;
34544
+ const gateway = opts.gateway ?? DEFAULT_GATEWAY;
35138
34545
  const agent = await withAgent({ keyPath: opts.key });
35139
34546
  const resolvedSeller = seller.startsWith("0x") ? seller : (await agent.resolveRecipient(seller)).address;
35140
34547
  const slugPath = opts.service ? `/${opts.service.trim().toLowerCase()}` : "";
@@ -35202,12 +34609,12 @@ Subcommands:
35202
34609
  );
35203
34610
  group.command("earnings").description(
35204
34611
  "Your sales as a seller \u2014 count, USDC earned (net), and unique buyers, from the on-chain settlement ledger. [Agent Commerce]"
35205
- ).option("--gateway <url>", `Gateway base URL (default ${DEFAULT_GATEWAY3})`).option("--key <path>", "Custom wallet path (default ~/.t2000/wallet.key)").action(async (opts) => {
34612
+ ).option("--gateway <url>", `Gateway base URL (default ${DEFAULT_GATEWAY})`).option("--key <path>", "Custom wallet path (default ~/.t2000/wallet.key)").action(async (opts) => {
35206
34613
  try {
35207
- const gateway = opts.gateway ?? DEFAULT_GATEWAY3;
34614
+ const gateway = opts.gateway ?? DEFAULT_GATEWAY;
35208
34615
  const agent = await withAgent({ keyPath: opts.key });
35209
34616
  const address = agent.address();
35210
- const stats = await fetchJson5(
34617
+ const stats = await fetchJson3(
35211
34618
  `${gateway}/commerce/stats/${address}`,
35212
34619
  { method: "GET" }
35213
34620
  );
@@ -35230,13 +34637,13 @@ Subcommands:
35230
34637
  });
35231
34638
  group.command("handle").argument("<label>", "Handle label (3\u201320 chars: lowercase a\u2013z, 0\u20139, hyphens)").description(
35232
34639
  "Claim <label>.agent-id.sui \u2192 this wallet (custody-minted, gasless). Use --release to give it up."
35233
- ).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(
34640
+ ).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(
35234
34641
  async (label, opts) => {
35235
34642
  try {
35236
- const base = opts.api ?? DEFAULT_API_BASE5;
34643
+ const base = opts.api ?? DEFAULT_API_BASE4;
35237
34644
  const agent = await withAgent({ keyPath: opts.key });
35238
34645
  const address = agent.address();
35239
- const challenge = await fetchJson5(`${base}/agent/challenge`, {
34646
+ const challenge = await fetchJson3(`${base}/agent/challenge`, {
35240
34647
  method: "POST",
35241
34648
  body: { address }
35242
34649
  });
@@ -35248,7 +34655,7 @@ Subcommands:
35248
34655
  const message = new TextEncoder().encode(`${action}:${nonce}:${label}`);
35249
34656
  const { signature } = await agent.keypair.signPersonalMessage(message);
35250
34657
  const path2 = opts.release ? "/agent/handle/release" : "/agent/handle";
35251
- const res = await fetchJson5(`${base}${path2}`, {
34658
+ const res = await fetchJson3(`${base}${path2}`, {
35252
34659
  method: "POST",
35253
34660
  body: { address, label, nonce, signature }
35254
34661
  });
@@ -35274,7 +34681,7 @@ Subcommands:
35274
34681
  }
35275
34682
 
35276
34683
  // src/commands/agents.ts
35277
- var DEFAULT_API_BASE6 = process.env.T2000_API_URL ?? "https://api.t2000.ai/v1";
34684
+ var DEFAULT_API_BASE5 = process.env.T2000_API_URL ?? "https://api.t2000.ai/v1";
35278
34685
  async function getJson(url) {
35279
34686
  const res = await fetch(url, { headers: { accept: "application/json" } });
35280
34687
  if (!res.ok) {
@@ -35289,10 +34696,10 @@ function firstLine(text, max = 76) {
35289
34696
  function registerAgents(program3) {
35290
34697
  program3.command("agents").argument("[address]", "Show one agent\u2019s full listing (profile + reputation)").description(
35291
34698
  "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]"
35292
- ).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(
34699
+ ).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(
35293
34700
  async (address, opts) => {
35294
34701
  try {
35295
- const base = opts.api ?? DEFAULT_API_BASE6;
34702
+ const base = opts.api ?? DEFAULT_API_BASE5;
35296
34703
  if (address) {
35297
34704
  const profile = await getJson(`${base}/agents/${address}`);
35298
34705
  if (isJsonMode()) {
@@ -35364,256 +34771,6 @@ function registerAgents(program3) {
35364
34771
  );
35365
34772
  }
35366
34773
 
35367
- // src/commands/task/index.ts
35368
- var DEFAULT_GATEWAY4 = process.env.T2000_GATEWAY_URL ?? "https://mpp.t2000.ai";
35369
- async function getJson2(url) {
35370
- const res = await fetch(url, { headers: { accept: "application/json" } });
35371
- const json = await res.json().catch(() => ({}));
35372
- if (!res.ok) {
35373
- throw new Error(json.error ?? `Request failed (${res.status}).`);
35374
- }
35375
- return json;
35376
- }
35377
- async function postJson2(url, body2) {
35378
- const res = await fetch(url, {
35379
- method: "POST",
35380
- headers: { "content-type": "application/json" },
35381
- body: JSON.stringify(body2)
35382
- });
35383
- const json = await res.json().catch(() => ({}));
35384
- if (!res.ok) {
35385
- throw new Error(json.error ?? `Request failed (${res.status}).`);
35386
- }
35387
- return json;
35388
- }
35389
- function registerTask(program3) {
35390
- const group = program3.command("task").description(
35391
- "Earn from t2000 reward tasks and work (or post) community board tasks \u2014 all paid through the rail. [Agent Commerce]"
35392
- );
35393
- 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) => {
35394
- try {
35395
- const gateway = opts.gateway ?? DEFAULT_GATEWAY4;
35396
- const [rewards, board] = await Promise.all([
35397
- getJson2(`${gateway}/tasks/stats`),
35398
- getJson2(`${gateway}/tasks/board`)
35399
- ]);
35400
- if (isJsonMode()) {
35401
- printJson({ rewards: rewards.tasks, board: board.tasks });
35402
- return;
35403
- }
35404
- printBlank();
35405
- printHeader("t2000 reward tasks (auto-verified, one per wallet)");
35406
- for (const t of rewards.tasks) {
35407
- printLine(
35408
- ` ${formatUsd(t.rewardNetUsd).padStart(6)} ${t.id.padEnd(20)} ${t.kind.padEnd(8)} ${t.status === "live" ? "live" : "budget spent"}`
35409
- );
35410
- }
35411
- printBlank();
35412
- printHeader(`Community board (${board.tasks.length} live, poster approves)`);
35413
- if (board.tasks.length === 0) {
35414
- printLine(" (none live \u2014 post one: t2 task post --help)");
35415
- }
35416
- for (const t of board.tasks) {
35417
- const days = Math.max(0, Math.ceil((Date.parse(t.expiresAt) - Date.now()) / 864e5));
35418
- printLine(
35419
- ` ${formatUsd(t.rewardUsd).padStart(6)} ${t.title.slice(0, 44).padEnd(44)} ${t.remainingCompletions}/${t.maxCompletions} spots \xB7 ${days}d ${t.id}`
35420
- );
35421
- }
35422
- printBlank();
35423
- printInfo("Claim a reward: t2 task claim <task> \xB7 Work the board: t2 task submit <taskId>");
35424
- printBlank();
35425
- } catch (error) {
35426
- handleError(error);
35427
- }
35428
- });
35429
- 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(
35430
- async (task, opts) => {
35431
- try {
35432
- const gateway = opts.gateway ?? DEFAULT_GATEWAY4;
35433
- const agent = await withAgent({ keyPath: opts.key });
35434
- const result = await postJson2(`${gateway}/tasks/claim`, {
35435
- task,
35436
- address: agent.address(),
35437
- ...opts.tx ? { txDigest: opts.tx } : {},
35438
- ...opts.post ? { postUrl: opts.post } : {}
35439
- });
35440
- if (isJsonMode()) {
35441
- printJson(result);
35442
- return;
35443
- }
35444
- printBlank();
35445
- if (result.paid) {
35446
- printSuccess(`Paid ${formatUsd(result.netUsd ?? 0)} to your agent.`);
35447
- if (result.suiscan) {
35448
- printKeyValue("Receipt", result.suiscan);
35449
- }
35450
- } else {
35451
- printWarning(result.note ?? "Not paid.");
35452
- }
35453
- printBlank();
35454
- } catch (error) {
35455
- handleError(error);
35456
- }
35457
- }
35458
- );
35459
- group.command("post").description(
35460
- "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."
35461
- ).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(
35462
- async (opts) => {
35463
- try {
35464
- const gateway = opts.gateway ?? DEFAULT_GATEWAY4;
35465
- const reward = Number.parseFloat(opts.reward);
35466
- const completions = Number.parseInt(opts.completions, 10);
35467
- if (!Number.isFinite(reward) || reward <= 0) {
35468
- throw new Error(`--reward must be a positive number (got "${opts.reward}").`);
35469
- }
35470
- const budget = Math.round(reward * completions * 1e6) / 1e6;
35471
- const agent = await withAgent({ keyPath: opts.key });
35472
- const result = await agent.pay({
35473
- url: `${gateway}/tasks/board`,
35474
- method: "POST",
35475
- body: JSON.stringify({
35476
- title: opts.title,
35477
- description: opts.description,
35478
- rewardUsd: reward,
35479
- maxCompletions: completions,
35480
- expiryDays: Number.parseInt(opts.expiryDays, 10),
35481
- category: opts.category,
35482
- ...opts.notifyEmail ? { notifyEmail: opts.notifyEmail } : {}
35483
- }),
35484
- maxPrice: budget,
35485
- force: opts.force
35486
- });
35487
- const body2 = result.body;
35488
- if (isJsonMode()) {
35489
- printJson(body2 ?? result);
35490
- return;
35491
- }
35492
- printBlank();
35493
- if (body2?.ok && body2.manageKey) {
35494
- printSuccess(body2.moderation ?? "Task posted.");
35495
- printKeyValue("Task", body2.task?.id ?? "\u2014");
35496
- printKeyValue("Escrow", formatUsd(budget));
35497
- printBlank();
35498
- printWarning("SAVE THIS manageKey \u2014 shown once. It approves/rejects/closes this task:");
35499
- printLine(` ${body2.manageKey}`);
35500
- printBlank();
35501
- printInfo(`Review: t2 task review ${body2.task?.id ?? "<taskId>"} --manage-key <key>`);
35502
- } else {
35503
- printWarning(
35504
- `${body2?.error ?? "Posting failed."}${body2?.refunded ? " (Budget refunded.)" : ""}`
35505
- );
35506
- }
35507
- printBlank();
35508
- } catch (error) {
35509
- handleError(error);
35510
- }
35511
- }
35512
- );
35513
- 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(
35514
- async (taskId, opts) => {
35515
- try {
35516
- const gateway = opts.gateway ?? DEFAULT_GATEWAY4;
35517
- const agent = await withAgent({ keyPath: opts.key });
35518
- const result = await postJson2(
35519
- `${gateway}/tasks/board/${taskId}/submit`,
35520
- {
35521
- address: agent.address(),
35522
- proof: opts.proof,
35523
- ...opts.url ? { url: opts.url } : {}
35524
- }
35525
- );
35526
- if (isJsonMode()) {
35527
- printJson(result);
35528
- return;
35529
- }
35530
- printBlank();
35531
- printSuccess(result.note ?? "Submitted \u2014 the poster reviews next.");
35532
- printBlank();
35533
- } catch (error) {
35534
- handleError(error);
35535
- }
35536
- }
35537
- );
35538
- 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) => {
35539
- try {
35540
- const gateway = opts.gateway ?? DEFAULT_GATEWAY4;
35541
- const result = await getJson2(`${gateway}/tasks/board/${taskId}?manageKey=${encodeURIComponent(opts.manageKey)}`);
35542
- if (!result.posterView) {
35543
- throw new Error(result.error ?? "manageKey not accepted for this task.");
35544
- }
35545
- if (isJsonMode()) {
35546
- printJson(result);
35547
- return;
35548
- }
35549
- const subs = result.submissions ?? [];
35550
- printBlank();
35551
- printHeader(`${result.task?.title ?? taskId} \u2014 ${subs.length} submission${subs.length === 1 ? "" : "s"}`);
35552
- for (const s of subs) {
35553
- printLine(` [${s.status.padEnd(8)}] ${s.id} ${truncateAddress(s.worker)}`);
35554
- if (s.proof) {
35555
- printLine(` ${s.proof.slice(0, 90)}`);
35556
- }
35557
- if (s.url) {
35558
- printLine(` ${s.url}`);
35559
- }
35560
- }
35561
- printBlank();
35562
- printInfo(`Pay: t2 task approve ${taskId} --manage-key <key> --submissions <id,id,\u2026>`);
35563
- printBlank();
35564
- } catch (error) {
35565
- handleError(error);
35566
- }
35567
- });
35568
- 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(
35569
- async (taskId, opts) => {
35570
- try {
35571
- const gateway = opts.gateway ?? DEFAULT_GATEWAY4;
35572
- const result = await postJson2(`${gateway}/tasks/board/${taskId}/approve`, {
35573
- manageKey: opts.manageKey,
35574
- submissionIds: opts.submissions.split(",").map((s) => s.trim()).filter(Boolean),
35575
- action: opts.reject ? "reject" : "approve"
35576
- });
35577
- if (isJsonMode()) {
35578
- printJson(result);
35579
- return;
35580
- }
35581
- printBlank();
35582
- for (const r of result.results ?? []) {
35583
- if (r.status === "paid") {
35584
- printSuccess(`${r.submissionId} paid${r.payoutTx ? ` (tx ${r.payoutTx.slice(0, 10)}\u2026)` : ""}`);
35585
- } else if (r.error) {
35586
- printWarning(`${r.submissionId}: ${r.error}`);
35587
- } else {
35588
- printLine(` ${r.submissionId}: ${r.status}`);
35589
- }
35590
- }
35591
- printBlank();
35592
- } catch (error) {
35593
- handleError(error);
35594
- }
35595
- }
35596
- );
35597
- 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) => {
35598
- try {
35599
- const gateway = opts.gateway ?? DEFAULT_GATEWAY4;
35600
- const result = await postJson2(`${gateway}/tasks/board/${taskId}/close`, { manageKey: opts.manageKey });
35601
- if (isJsonMode()) {
35602
- printJson(result);
35603
- return;
35604
- }
35605
- printBlank();
35606
- printSuccess(`Task closed${result.refunded ? " \u2014 unspent budget refunded" : ""}.`);
35607
- if (result.suiscan) {
35608
- printKeyValue("Refund", result.suiscan);
35609
- }
35610
- printBlank();
35611
- } catch (error) {
35612
- handleError(error);
35613
- }
35614
- });
35615
- }
35616
-
35617
34774
  // src/program.ts
35618
34775
  var require3 = createRequire2(import.meta.url);
35619
34776
  var { version: CLI_VERSION2 } = require3("../package.json");
@@ -35637,8 +34794,6 @@ Examples:
35637
34794
  $ t2 services search "image" Discover x402 services in the gateway catalog
35638
34795
  $ t2 agents Browse the agent store (agents.t2000.ai)
35639
34796
  $ t2 agent pay <address> Buy an agent's service (escrowed, auto-refund on failure)
35640
- $ t2 task list Live reward tasks + the community board
35641
- $ t2 task claim share-a-read --post <url> Claim an X-proof reward
35642
34797
  $ t2 limit set --daily 100 Change the daily spend cap (default $100/day)
35643
34798
  $ t2 mcp install Connect Claude / Cursor / Windsurf
35644
34799
  $ t2 skills install Install skills as local SKILL.md files`);
@@ -35659,7 +34814,6 @@ Examples:
35659
34814
  registerSkills(program3);
35660
34815
  registerAgent(program3);
35661
34816
  registerAgents(program3);
35662
- registerTask(program3);
35663
34817
  return program3;
35664
34818
  }
35665
34819