@t2000/cli 9.13.0 → 10.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/README.md +2 -2
- package/dist/{chunk-XPCTSCTS.js → chunk-45A36TR5.js} +11 -11
- package/dist/{chunk-XPCTSCTS.js.map → chunk-45A36TR5.js.map} +1 -1
- package/dist/{dist-ZIRF2Q6M.js → dist-6UOQ3CIE.js} +6 -6
- package/dist/{dist-WU4EKM5J.js → dist-GRR5N77K.js} +57 -57
- package/dist/{dist-WU4EKM5J.js.map → dist-GRR5N77K.js.map} +1 -1
- package/dist/index.js +71 -70
- package/dist/index.js.map +1 -1
- package/package.json +3 -3
- /package/dist/{dist-ZIRF2Q6M.js.map → dist-6UOQ3CIE.js.map} +0 -0
package/dist/index.js
CHANGED
|
@@ -7,7 +7,7 @@ import {
|
|
|
7
7
|
MAX_JOB_USDC,
|
|
8
8
|
T2000,
|
|
9
9
|
clearLimits,
|
|
10
|
-
|
|
10
|
+
fetchService,
|
|
11
11
|
formatUsd,
|
|
12
12
|
generateKeypair,
|
|
13
13
|
getAddress,
|
|
@@ -28,7 +28,7 @@ import {
|
|
|
28
28
|
verifyJobForSeller,
|
|
29
29
|
verifyReceipt,
|
|
30
30
|
walletExists
|
|
31
|
-
} from "./chunk-
|
|
31
|
+
} from "./chunk-45A36TR5.js";
|
|
32
32
|
import "./chunk-634W6JCI.js";
|
|
33
33
|
import "./chunk-BHQGGFE6.js";
|
|
34
34
|
import "./chunk-GCC33SG5.js";
|
|
@@ -22281,7 +22281,7 @@ async function runEstimate(url, opts) {
|
|
|
22281
22281
|
let req = accepts.find((a) => a.scheme === "exact" && a.network?.startsWith("sui:")) ?? accepts[0];
|
|
22282
22282
|
let dialect = "x402";
|
|
22283
22283
|
if (!req) {
|
|
22284
|
-
const { parseMppSuiChallenge } = await import("./dist-
|
|
22284
|
+
const { parseMppSuiChallenge } = await import("./dist-6UOQ3CIE.js");
|
|
22285
22285
|
const challenge = await parseMppSuiChallenge(response);
|
|
22286
22286
|
if (!challenge) {
|
|
22287
22287
|
throw new Error(
|
|
@@ -23373,7 +23373,7 @@ function registerMcpStart(parent) {
|
|
|
23373
23373
|
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) => {
|
|
23374
23374
|
let mod;
|
|
23375
23375
|
try {
|
|
23376
|
-
mod = await import("./dist-
|
|
23376
|
+
mod = await import("./dist-GRR5N77K.js");
|
|
23377
23377
|
} catch {
|
|
23378
23378
|
console.error("MCP server not installed. Run:\n npm install -g @t2000/mcp");
|
|
23379
23379
|
process.exit(1);
|
|
@@ -24219,7 +24219,7 @@ Subcommands:
|
|
|
24219
24219
|
const agent = await withAgent({ keyPath: opts.key });
|
|
24220
24220
|
const address = agent.address();
|
|
24221
24221
|
const target = opts.remove ? "" : endpoint;
|
|
24222
|
-
const prepRes = await fetch(`${base}/agent/
|
|
24222
|
+
const prepRes = await fetch(`${base}/agent/endpoint/prepare`, {
|
|
24223
24223
|
method: "POST",
|
|
24224
24224
|
headers: { "Content-Type": "application/json" },
|
|
24225
24225
|
body: JSON.stringify({ address, endpoint: target })
|
|
@@ -24237,7 +24237,7 @@ ${detail}` : msg);
|
|
|
24237
24237
|
}
|
|
24238
24238
|
const bytes = new Uint8Array(Buffer.from(prep.txBytes, "base64"));
|
|
24239
24239
|
const { signature } = await agent.keypair.signTransaction(bytes);
|
|
24240
|
-
const sub = await fetchJson2(`${base}/agent/
|
|
24240
|
+
const sub = await fetchJson2(`${base}/agent/endpoint/submit`, {
|
|
24241
24241
|
method: "POST",
|
|
24242
24242
|
body: { nonce: prep.nonce, address, signature }
|
|
24243
24243
|
});
|
|
@@ -24518,7 +24518,7 @@ var import_picocolors15 = __toESM(require_picocolors(), 1);
|
|
|
24518
24518
|
import { createHash } from "crypto";
|
|
24519
24519
|
import { readFile as readFile3 } from "fs/promises";
|
|
24520
24520
|
|
|
24521
|
-
// src/lib/
|
|
24521
|
+
// src/lib/services.ts
|
|
24522
24522
|
async function fetchJson3(url, init) {
|
|
24523
24523
|
const res = await fetch(url, {
|
|
24524
24524
|
method: init?.method ?? "GET",
|
|
@@ -24636,14 +24636,14 @@ Typical flow:
|
|
|
24636
24636
|
either $ t2 job watch 0xJOB
|
|
24637
24637
|
seller $ t2 job watch --mine (the provider inbox \u2014 all your jobs)
|
|
24638
24638
|
|
|
24639
|
-
Buying
|
|
24639
|
+
Buying a SERVICE (t2 ACP) \u2014 price + terms come from the listing:
|
|
24640
24640
|
buyer $ t2 browse "market report"
|
|
24641
|
-
buyer $ t2 job create --agent 0xSELLER --
|
|
24641
|
+
buyer $ t2 job create --agent 0xSELLER --service sui-market-report \\
|
|
24642
24642
|
--requirements '{"token":"DEEP"}'
|
|
24643
24643
|
seller $ t2 job spec 0xJOB (read the buyer's requirements)
|
|
24644
24644
|
`
|
|
24645
24645
|
);
|
|
24646
|
-
group.command("create").argument("[amount]", `USDC to escrow (max ${MAX_JOB_USDC}; omit when buying
|
|
24646
|
+
group.command("create").argument("[amount]", `USDC to escrow (max ${MAX_JOB_USDC}; omit when buying a --service)`).argument("[seller]", "The seller's Sui address (omit when buying a --service)").description("Create + fund an escrow job in one transaction (buyer)").option("--spec <file-or-text>", "Job spec \u2014 a file path or inline text (hashed on-chain), or a 0x\u2026 hash").option("--agent <address>", "Buy a service: the seller's agent address").option("--service <slug>", "The service slug (see t2 browse / t2 service list <agent>)").option("--requirements <file-or-json-or-text>", "Your requirements for the service (what the seller asked for)").option("--deadline <duration>", "Time the seller has to deliver (e.g. 30m, 24h, 7d)", "24h").option("--review <duration>", "Your accept/reject window after delivery", "24h").option("--split <bps>", "Your share in bps if you reject (0\u201310000)", String(DEFAULT_REJECT_SPLIT_BPS)).option("--key <path>", "Custom wallet path (default ~/.t2000/wallet.key)").option("--api <url>", `API base URL (default ${DEFAULT_API_BASE5})`).action(
|
|
24647
24647
|
async (amountArg, sellerArg, opts) => {
|
|
24648
24648
|
try {
|
|
24649
24649
|
const base = opts.api ?? DEFAULT_API_BASE5;
|
|
@@ -24653,19 +24653,20 @@ Buying an OFFERING (t2 ACP) \u2014 price + terms come from the listing:
|
|
|
24653
24653
|
let deliverByMs;
|
|
24654
24654
|
let reviewWindowMs;
|
|
24655
24655
|
let rejectSplitBps;
|
|
24656
|
-
let
|
|
24657
|
-
|
|
24658
|
-
|
|
24659
|
-
|
|
24656
|
+
let serviceSlug;
|
|
24657
|
+
const serviceSlugOpt = opts.service;
|
|
24658
|
+
if (serviceSlugOpt || opts.agent) {
|
|
24659
|
+
if (!(serviceSlugOpt && opts.agent)) {
|
|
24660
|
+
throw new Error("--agent and --service go together.");
|
|
24660
24661
|
}
|
|
24661
24662
|
if (amountArg || sellerArg) {
|
|
24662
24663
|
throw new Error(
|
|
24663
|
-
"Omit the amount/seller arguments when buying
|
|
24664
|
+
"Omit the amount/seller arguments when buying a service \u2014 the listing sets the price and the seller."
|
|
24664
24665
|
);
|
|
24665
24666
|
}
|
|
24666
24667
|
const sellerAgent = validateAddress(opts.agent);
|
|
24667
|
-
const
|
|
24668
|
-
|
|
24668
|
+
const service = await fetchService(base, sellerAgent, serviceSlugOpt);
|
|
24669
|
+
serviceSlug = service.slug;
|
|
24669
24670
|
let requirements = null;
|
|
24670
24671
|
if (opts.requirements) {
|
|
24671
24672
|
let text = opts.requirements;
|
|
@@ -24679,41 +24680,41 @@ Buying an OFFERING (t2 ACP) \u2014 price + terms come from the listing:
|
|
|
24679
24680
|
requirements = text.trim();
|
|
24680
24681
|
}
|
|
24681
24682
|
}
|
|
24682
|
-
if (
|
|
24683
|
-
const want = typeof
|
|
24683
|
+
if (service.requirements != null && requirements == null) {
|
|
24684
|
+
const want = typeof service.requirements === "string" ? service.requirements : `JSON matching: ${JSON.stringify(service.requirements)}`;
|
|
24684
24685
|
throw new Error(
|
|
24685
|
-
`This
|
|
24686
|
+
`This service needs --requirements. The seller asks for: ${want}`
|
|
24686
24687
|
);
|
|
24687
24688
|
}
|
|
24688
|
-
if (
|
|
24689
|
+
if (service.requirements != null && typeof service.requirements === "object" && (typeof requirements !== "object" || requirements === null)) {
|
|
24689
24690
|
throw new Error(
|
|
24690
|
-
`This
|
|
24691
|
+
`This service expects JSON requirements matching: ${JSON.stringify(service.requirements)}`
|
|
24691
24692
|
);
|
|
24692
24693
|
}
|
|
24693
24694
|
const buyer = (await withAgent({ keyPath: opts.key })).address();
|
|
24694
24695
|
const spec = JSON.stringify({
|
|
24695
24696
|
type: "t2-acp-job-spec@1",
|
|
24696
|
-
|
|
24697
|
-
agent:
|
|
24698
|
-
slug:
|
|
24699
|
-
name:
|
|
24700
|
-
priceUsdc:
|
|
24701
|
-
deliverable:
|
|
24697
|
+
service: {
|
|
24698
|
+
agent: service.agent,
|
|
24699
|
+
slug: service.slug,
|
|
24700
|
+
name: service.name,
|
|
24701
|
+
priceUsdc: service.priceUsdc,
|
|
24702
|
+
deliverable: service.deliverable
|
|
24702
24703
|
},
|
|
24703
24704
|
requirements,
|
|
24704
24705
|
buyer,
|
|
24705
24706
|
createdAtMs: Date.now()
|
|
24706
24707
|
});
|
|
24707
24708
|
specHash = `0x${await putJobSpec(base, spec)}`;
|
|
24708
|
-
amountUsdc =
|
|
24709
|
-
seller =
|
|
24710
|
-
deliverByMs = Date.now() +
|
|
24711
|
-
reviewWindowMs =
|
|
24712
|
-
rejectSplitBps =
|
|
24709
|
+
amountUsdc = service.priceUsdc;
|
|
24710
|
+
seller = service.agent;
|
|
24711
|
+
deliverByMs = Date.now() + service.slaMinutes * 6e4;
|
|
24712
|
+
reviewWindowMs = service.reviewWindowMinutes * 6e4;
|
|
24713
|
+
rejectSplitBps = service.rejectSplitBps;
|
|
24713
24714
|
} else {
|
|
24714
24715
|
if (!(amountArg && sellerArg)) {
|
|
24715
24716
|
throw new Error(
|
|
24716
|
-
"Provide <amount> <seller> (direct job) or --agent + --
|
|
24717
|
+
"Provide <amount> <seller> (direct job) or --agent + --service (buy a listing)."
|
|
24717
24718
|
);
|
|
24718
24719
|
}
|
|
24719
24720
|
if (!opts.spec) {
|
|
@@ -24751,11 +24752,11 @@ Buying an OFFERING (t2 ACP) \u2014 price + terms come from the listing:
|
|
|
24751
24752
|
}
|
|
24752
24753
|
}
|
|
24753
24754
|
if (isJsonMode()) {
|
|
24754
|
-
printJson({ jobId, digest, buyer: address, seller, amountUsdc, specHash, deliverByMs, reviewWindowMs, rejectSplitBps, ...
|
|
24755
|
+
printJson({ jobId, digest, buyer: address, seller, amountUsdc, specHash, deliverByMs, reviewWindowMs, rejectSplitBps, ...serviceSlug ? { service: serviceSlug } : {} });
|
|
24755
24756
|
return;
|
|
24756
24757
|
}
|
|
24757
24758
|
printBlank();
|
|
24758
|
-
printSuccess(`Escrowed $${amountUsdc.toFixed(2)} USDC \u2192 job for ${truncateAddress(seller)}${
|
|
24759
|
+
printSuccess(`Escrowed $${amountUsdc.toFixed(2)} USDC \u2192 job for ${truncateAddress(seller)}${serviceSlug ? ` (service: ${serviceSlug})` : ""}`);
|
|
24759
24760
|
if (jobId) printKeyValue("Job", jobId);
|
|
24760
24761
|
printKeyValue("Spec hash", specHash);
|
|
24761
24762
|
printKeyValue("Deliver by", new Date(deliverByMs).toISOString());
|
|
@@ -25013,12 +25014,12 @@ Buying an OFFERING (t2 ACP) \u2014 price + terms come from the listing:
|
|
|
25013
25014
|
});
|
|
25014
25015
|
}
|
|
25015
25016
|
|
|
25016
|
-
// src/commands/
|
|
25017
|
+
// src/commands/service.ts
|
|
25017
25018
|
var import_picocolors16 = __toESM(require_picocolors(), 1);
|
|
25018
25019
|
import { createHash as createHash2 } from "crypto";
|
|
25019
25020
|
import { readFile as readFile4 } from "fs/promises";
|
|
25020
25021
|
var DEFAULT_API_BASE6 = process.env.T2000_API_URL ?? "https://api.t2000.ai/v1";
|
|
25021
|
-
async function
|
|
25022
|
+
async function signedServiceAction(opts) {
|
|
25022
25023
|
const agent = await withAgent({ keyPath: opts.keyPath });
|
|
25023
25024
|
const address = agent.address();
|
|
25024
25025
|
const challenge = await fetchJson3(`${opts.base}/agent/challenge`, {
|
|
@@ -25031,10 +25032,10 @@ async function signedOfferingAction(opts) {
|
|
|
25031
25032
|
}
|
|
25032
25033
|
const payloadHash = createHash2("sha256").update(JSON.stringify(opts.payload), "utf8").digest("hex");
|
|
25033
25034
|
const message = new TextEncoder().encode(
|
|
25034
|
-
`t2000-agent-
|
|
25035
|
+
`t2000-agent-service:${nonce}:${payloadHash}`
|
|
25035
25036
|
);
|
|
25036
25037
|
const { signature } = await agent.keypair.signPersonalMessage(message);
|
|
25037
|
-
const response = await fetchJson3(`${opts.base}/agent/
|
|
25038
|
+
const response = await fetchJson3(`${opts.base}/agent/service`, {
|
|
25038
25039
|
method: "POST",
|
|
25039
25040
|
body: {
|
|
25040
25041
|
address,
|
|
@@ -25069,7 +25070,7 @@ function formatSla(minutes) {
|
|
|
25069
25070
|
if (minutes % 60 === 0) return `${minutes / 60}h`;
|
|
25070
25071
|
return `${minutes}m`;
|
|
25071
25072
|
}
|
|
25072
|
-
function
|
|
25073
|
+
function printService(o) {
|
|
25073
25074
|
const flag = o.retired ? import_picocolors16.default.dim(" (retired)") : "";
|
|
25074
25075
|
printLine(`${import_picocolors16.default.bold(o.name)} ${import_picocolors16.default.dim(`\xB7 ${o.slug}`)}${flag}`);
|
|
25075
25076
|
printKeyValue("Price", `$${o.priceUsdc.toFixed(2)} USDC`);
|
|
@@ -25087,29 +25088,29 @@ function printOffering(o) {
|
|
|
25087
25088
|
}
|
|
25088
25089
|
printKeyValue(
|
|
25089
25090
|
"Buy",
|
|
25090
|
-
`t2 job create --agent ${o.agent} --
|
|
25091
|
+
`t2 job create --agent ${o.agent} --service ${o.slug}`
|
|
25091
25092
|
);
|
|
25092
25093
|
}
|
|
25093
|
-
function
|
|
25094
|
-
const group = program3.command("
|
|
25094
|
+
function registerService(program3) {
|
|
25095
|
+
const group = program3.command("service").description(
|
|
25095
25096
|
"Sell deliverable work \u2014 list what you do, at what price, on what SLA (t2 ACP)"
|
|
25096
25097
|
).addHelpText(
|
|
25097
25098
|
"after",
|
|
25098
25099
|
`
|
|
25099
|
-
|
|
25100
|
+
A service needs NO server and NO endpoint: buyers fund an on-chain escrow
|
|
25100
25101
|
Job against it, you deliver with \`t2 job deliver\`, the escrow settles. Your
|
|
25101
25102
|
catalog lives on your Agent ID and shows on agents.t2000.ai.
|
|
25102
25103
|
|
|
25103
25104
|
Examples:
|
|
25104
|
-
$ t2
|
|
25105
|
+
$ t2 service create --name "Sui market report" --price 5 --sla 24h \\
|
|
25105
25106
|
--description "Daily research report on any Sui token" \\
|
|
25106
25107
|
--deliverable "PDF report, 2+ pages, sources cited" \\
|
|
25107
25108
|
--requirements "Token symbol or coin type to analyze"
|
|
25108
|
-
$ t2
|
|
25109
|
-
$ t2
|
|
25109
|
+
$ t2 service list
|
|
25110
|
+
$ t2 service retire sui-market-report
|
|
25110
25111
|
`
|
|
25111
25112
|
);
|
|
25112
|
-
group.command("create").description("List
|
|
25113
|
+
group.command("create").description("List a service under your Agent ID (re-run to update it)").requiredOption("--name <name>", "Service name (max 80 chars)").requiredOption("--price <usdc>", "Fixed price in USDC (0.01\u201350)").requiredOption("--sla <duration>", "Delivery SLA \u2014 e.g. 30m, 24h, 7d").requiredOption("--description <text>", "What this service is (max 2000 chars)").requiredOption("--deliverable <text>", "What the buyer receives (max 1000 chars)").option("--slug <slug>", "Machine name (default: derived from --name)").option(
|
|
25113
25114
|
"--requirements <file-or-json-or-text>",
|
|
25114
25115
|
"What the buyer must provide \u2014 free text or a JSON schema (file path ok)"
|
|
25115
25116
|
).option("--review <duration>", "Buyer's accept/reject window after delivery", "24h").option("--split <bps>", "Buyer's share in bps if they reject (0\u201310000)", "8000").option("--key <path>", "Custom wallet path (default ~/.t2000/wallet.key)").option("--api <url>", `API base URL (default ${DEFAULT_API_BASE6})`).action(
|
|
@@ -25136,7 +25137,7 @@ Examples:
|
|
|
25136
25137
|
deliverable: opts.deliverable.trim()
|
|
25137
25138
|
};
|
|
25138
25139
|
const base = opts.api ?? DEFAULT_API_BASE6;
|
|
25139
|
-
const { address } = await
|
|
25140
|
+
const { address } = await signedServiceAction({
|
|
25140
25141
|
base,
|
|
25141
25142
|
keyPath: opts.key,
|
|
25142
25143
|
action: "upsert",
|
|
@@ -25150,45 +25151,45 @@ Examples:
|
|
|
25150
25151
|
printSuccess(`"${payload.name}" is listed \u2014 $${priceUsdc.toFixed(2)} USDC, delivery within ${formatSla(slaMinutes)}`);
|
|
25151
25152
|
printKeyValue("Slug", slug);
|
|
25152
25153
|
printKeyValue("Storefront", `https://agents.t2000.ai/${address}`);
|
|
25153
|
-
printKeyValue("Buyers run", `t2 job create --agent ${address} --
|
|
25154
|
+
printKeyValue("Buyers run", `t2 job create --agent ${address} --service ${slug}`);
|
|
25154
25155
|
printBlank();
|
|
25155
|
-
printInfo("Watch for incoming jobs with: t2 job watch
|
|
25156
|
+
printInfo("Watch for incoming jobs with: t2 job watch --mine");
|
|
25156
25157
|
printBlank();
|
|
25157
25158
|
} catch (error) {
|
|
25158
25159
|
handleError(error);
|
|
25159
25160
|
}
|
|
25160
25161
|
}
|
|
25161
25162
|
);
|
|
25162
|
-
group.command("list").argument("[agent]", "Agent address (default: this wallet's)").description("An agent's
|
|
25163
|
+
group.command("list").argument("[agent]", "Agent address (default: this wallet's)").description("An agent's services \u2014 yours by default, retired included").option("--key <path>", "Custom wallet path (default ~/.t2000/wallet.key)").option("--api <url>", `API base URL (default ${DEFAULT_API_BASE6})`).action(async (agentArg, opts) => {
|
|
25163
25164
|
try {
|
|
25164
25165
|
const base = opts.api ?? DEFAULT_API_BASE6;
|
|
25165
25166
|
const agent = agentArg ? validateAddress(agentArg) : (await withAgent({ keyPath: opts.key })).address();
|
|
25166
25167
|
const json = await fetchJson3(
|
|
25167
|
-
`${base}/
|
|
25168
|
+
`${base}/services?agent=${encodeURIComponent(agent)}`
|
|
25168
25169
|
);
|
|
25169
|
-
const rows = json.
|
|
25170
|
+
const rows = json.services ?? [];
|
|
25170
25171
|
if (isJsonMode()) {
|
|
25171
|
-
printJson({ agent,
|
|
25172
|
+
printJson({ agent, services: rows });
|
|
25172
25173
|
return;
|
|
25173
25174
|
}
|
|
25174
25175
|
printBlank();
|
|
25175
25176
|
if (rows.length === 0) {
|
|
25176
|
-
printInfo(`No
|
|
25177
|
+
printInfo(`No services for ${truncateAddress(agent)} \u2014 list one with: t2 service create`);
|
|
25177
25178
|
printBlank();
|
|
25178
25179
|
return;
|
|
25179
25180
|
}
|
|
25180
25181
|
for (const o of rows) {
|
|
25181
|
-
|
|
25182
|
+
printService(o);
|
|
25182
25183
|
printBlank();
|
|
25183
25184
|
}
|
|
25184
25185
|
} catch (error) {
|
|
25185
25186
|
handleError(error);
|
|
25186
25187
|
}
|
|
25187
25188
|
});
|
|
25188
|
-
group.command("retire").argument("<slug>", "The
|
|
25189
|
+
group.command("retire").argument("<slug>", "The service slug to retire").description("Take a service off the board (funded jobs still settle on-chain)").option("--key <path>", "Custom wallet path (default ~/.t2000/wallet.key)").option("--api <url>", `API base URL (default ${DEFAULT_API_BASE6})`).action(async (slug, opts) => {
|
|
25189
25190
|
try {
|
|
25190
25191
|
const base = opts.api ?? DEFAULT_API_BASE6;
|
|
25191
|
-
const { address } = await
|
|
25192
|
+
const { address } = await signedServiceAction({
|
|
25192
25193
|
base,
|
|
25193
25194
|
keyPath: opts.key,
|
|
25194
25195
|
action: "retire",
|
|
@@ -25199,7 +25200,7 @@ Examples:
|
|
|
25199
25200
|
return;
|
|
25200
25201
|
}
|
|
25201
25202
|
printBlank();
|
|
25202
|
-
printSuccess(`
|
|
25203
|
+
printSuccess(`Service "${slug}" retired. Re-run t2 service create with the same slug to relist.`);
|
|
25203
25204
|
printBlank();
|
|
25204
25205
|
} catch (error) {
|
|
25205
25206
|
handleError(error);
|
|
@@ -25207,24 +25208,24 @@ Examples:
|
|
|
25207
25208
|
});
|
|
25208
25209
|
}
|
|
25209
25210
|
function registerBrowse(program3) {
|
|
25210
|
-
program3.command("browse").argument("[query]", "What you need \u2014 free-text search (empty = everything)").description("Browse
|
|
25211
|
+
program3.command("browse").argument("[query]", "What you need \u2014 free-text search (empty = everything)").description("Browse agent services \u2014 find work to buy (t2 ACP)").option("--api <url>", `API base URL (default ${DEFAULT_API_BASE6})`).action(async (query, opts) => {
|
|
25211
25212
|
try {
|
|
25212
25213
|
const base = opts.api ?? DEFAULT_API_BASE6;
|
|
25213
25214
|
const params = query ? `?q=${encodeURIComponent(query)}` : "";
|
|
25214
|
-
const json = await fetchJson3(`${base}/
|
|
25215
|
-
const rows = json.
|
|
25215
|
+
const json = await fetchJson3(`${base}/services${params}`);
|
|
25216
|
+
const rows = json.services ?? [];
|
|
25216
25217
|
if (isJsonMode()) {
|
|
25217
|
-
printJson({ query: query ?? null, total: json.total ?? rows.length,
|
|
25218
|
+
printJson({ query: query ?? null, total: json.total ?? rows.length, services: rows });
|
|
25218
25219
|
return;
|
|
25219
25220
|
}
|
|
25220
25221
|
printBlank();
|
|
25221
25222
|
if (rows.length === 0) {
|
|
25222
|
-
printInfo(query ? `No
|
|
25223
|
+
printInfo(query ? `No services match "${query}".` : "No services listed yet.");
|
|
25223
25224
|
printBlank();
|
|
25224
25225
|
return;
|
|
25225
25226
|
}
|
|
25226
25227
|
for (const o of rows) {
|
|
25227
|
-
|
|
25228
|
+
printService(o);
|
|
25228
25229
|
printBlank();
|
|
25229
25230
|
}
|
|
25230
25231
|
} catch (error) {
|
|
@@ -25256,8 +25257,8 @@ Examples:
|
|
|
25256
25257
|
$ t2 services search "image" Discover x402 services in the gateway catalog
|
|
25257
25258
|
$ t2 check <url> Validate your paid API against the listing gates (add --list to sell it)
|
|
25258
25259
|
$ t2 job create 5 0xSELLER --spec brief.md --deadline 24h Escrow USDC for deliverable work (A2A)
|
|
25259
|
-
$ t2
|
|
25260
|
-
$ t2 browse "market report" Find
|
|
25260
|
+
$ t2 service create --name "Report" --price 5 --sla 24h ... Sell deliverable work (no server needed)
|
|
25261
|
+
$ t2 browse "market report" Find agent services to buy
|
|
25261
25262
|
$ t2 agents Look up the agent directory (agents.t2000.ai)
|
|
25262
25263
|
$ t2 limit set --daily 100 Change the daily spend cap (default $100/day)
|
|
25263
25264
|
$ t2 mcp install Connect Claude / Cursor / Windsurf
|
|
@@ -25282,7 +25283,7 @@ Examples:
|
|
|
25282
25283
|
registerAgents(program3);
|
|
25283
25284
|
registerCheck(program3);
|
|
25284
25285
|
registerJob(program3);
|
|
25285
|
-
|
|
25286
|
+
registerService(program3);
|
|
25286
25287
|
registerBrowse(program3);
|
|
25287
25288
|
return program3;
|
|
25288
25289
|
}
|