@t2000/cli 5.31.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((
|
|
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
|
-
|
|
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(
|
|
18973
|
+
return new Promise(function(resolve2, reject) {
|
|
18974
18974
|
try {
|
|
18975
18975
|
const data = QRCode.create(text, opts);
|
|
18976
|
-
|
|
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(
|
|
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) :
|
|
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
|
|
30301
|
+
let resolve2;
|
|
30302
30302
|
let reject;
|
|
30303
30303
|
const promise = new Promise((res, rej) => {
|
|
30304
|
-
|
|
30304
|
+
resolve2 = res;
|
|
30305
30305
|
reject = rej;
|
|
30306
30306
|
});
|
|
30307
|
-
return { promise, resolve:
|
|
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:
|
|
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(() =>
|
|
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-
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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 =
|
|
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
|
|
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,372 +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 }
|
|
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
33985
|
// src/commands/agent/index.ts
|
|
34436
|
-
var
|
|
34437
|
-
var
|
|
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";
|
|
34438
33988
|
var DEFAULT_RAIL = process.env.T2000_RAIL_URL ?? "https://x402.t2000.ai";
|
|
34439
33989
|
var AGENT_CATEGORIES2 = [
|
|
34440
33990
|
"ai-models",
|
|
@@ -34473,19 +34023,19 @@ async function fundCredit(agent, base, amountStr, assetOpt) {
|
|
|
34473
34023
|
throw new Error(`amount must be a positive number (got "${amountStr}").`);
|
|
34474
34024
|
}
|
|
34475
34025
|
const asset = normalizeTopupAsset(assetOpt);
|
|
34476
|
-
const cfg = await
|
|
34026
|
+
const cfg = await fetchJson3(`${base}/agent/topup`, { method: "GET" });
|
|
34477
34027
|
const treasury = cfg.treasury;
|
|
34478
34028
|
if (!treasury) {
|
|
34479
34029
|
throw new Error("Could not resolve the t2000 treasury address.");
|
|
34480
34030
|
}
|
|
34481
34031
|
const sent = await agent.send({ to: treasury, amount, asset });
|
|
34482
|
-
const topup = await
|
|
34032
|
+
const topup = await fetchJson3(`${base}/agent/topup`, {
|
|
34483
34033
|
method: "POST",
|
|
34484
34034
|
body: { address: agent.address(), digest: sent.tx }
|
|
34485
34035
|
});
|
|
34486
34036
|
return { amount, asset, balanceUsd: topup.balanceUsd };
|
|
34487
34037
|
}
|
|
34488
|
-
async function
|
|
34038
|
+
async function fetchJson3(url, init) {
|
|
34489
34039
|
const res = await fetch(url, {
|
|
34490
34040
|
method: init.method,
|
|
34491
34041
|
headers: init.body ? { "Content-Type": "application/json" } : void 0,
|
|
@@ -34513,15 +34063,13 @@ Subcommands:
|
|
|
34513
34063
|
`
|
|
34514
34064
|
);
|
|
34515
34065
|
registerAgentCreate(group);
|
|
34516
|
-
registerAgentServices(group, { apiBase:
|
|
34517
|
-
registerAgentServe(group);
|
|
34518
|
-
registerAgentReview(group);
|
|
34066
|
+
registerAgentServices(group, { apiBase: DEFAULT_API_BASE4 });
|
|
34519
34067
|
group.command("onboard").description(
|
|
34520
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`."
|
|
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 ${
|
|
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(
|
|
34522
34070
|
async (opts) => {
|
|
34523
34071
|
try {
|
|
34524
|
-
const base = opts.api ??
|
|
34072
|
+
const base = opts.api ?? DEFAULT_API_BASE4;
|
|
34525
34073
|
const agent = await withAgent({ keyPath: opts.key });
|
|
34526
34074
|
const address = agent.address();
|
|
34527
34075
|
if (opts.fund !== void 0) {
|
|
@@ -34532,7 +34080,7 @@ Subcommands:
|
|
|
34532
34080
|
);
|
|
34533
34081
|
}
|
|
34534
34082
|
}
|
|
34535
|
-
const challenge = await
|
|
34083
|
+
const challenge = await fetchJson3(`${base}/agent/challenge`, {
|
|
34536
34084
|
method: "POST",
|
|
34537
34085
|
body: { address }
|
|
34538
34086
|
});
|
|
@@ -34542,7 +34090,7 @@ Subcommands:
|
|
|
34542
34090
|
}
|
|
34543
34091
|
const message = new TextEncoder().encode(`t2000-agent-keys:${nonce}`);
|
|
34544
34092
|
const { signature } = await agent.keypair.signPersonalMessage(message);
|
|
34545
|
-
const minted = await
|
|
34093
|
+
const minted = await fetchJson3(`${base}/agent/keys`, {
|
|
34546
34094
|
method: "POST",
|
|
34547
34095
|
body: { address, nonce, signature }
|
|
34548
34096
|
});
|
|
@@ -34579,10 +34127,10 @@ Subcommands:
|
|
|
34579
34127
|
);
|
|
34580
34128
|
group.command("topup").argument("<amount>", "Stablecoin amount to deposit as credit").description(
|
|
34581
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."
|
|
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 ${
|
|
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(
|
|
34583
34131
|
async (amount, opts) => {
|
|
34584
34132
|
try {
|
|
34585
|
-
const base = opts.api ??
|
|
34133
|
+
const base = opts.api ?? DEFAULT_API_BASE4;
|
|
34586
34134
|
const agent = await withAgent({ keyPath: opts.key });
|
|
34587
34135
|
const funded = await fundCredit(agent, base, amount, opts.asset);
|
|
34588
34136
|
if (isJsonMode()) {
|
|
@@ -34606,9 +34154,9 @@ Subcommands:
|
|
|
34606
34154
|
);
|
|
34607
34155
|
group.command("register").description(
|
|
34608
34156
|
"Register this wallet on-chain as an Agent ID (sponsored, gasless). Idempotent \u2014 safe to re-run."
|
|
34609
|
-
).option("--key <path>", "Custom wallet path (default ~/.t2000/wallet.key)").option("--api <url>", `API base URL (default ${
|
|
34157
|
+
).option("--key <path>", "Custom wallet path (default ~/.t2000/wallet.key)").option("--api <url>", `API base URL (default ${DEFAULT_API_BASE4})`).action(async (opts) => {
|
|
34610
34158
|
try {
|
|
34611
|
-
const base = opts.api ??
|
|
34159
|
+
const base = opts.api ?? DEFAULT_API_BASE4;
|
|
34612
34160
|
const agent = await withAgent({ keyPath: opts.key });
|
|
34613
34161
|
const address = agent.address();
|
|
34614
34162
|
const reg = await registerWallet({ keypair: agent.keypair, address, base });
|
|
@@ -34636,9 +34184,9 @@ Subcommands:
|
|
|
34636
34184
|
});
|
|
34637
34185
|
group.command("link").argument("<owner>", "The owner's Sui address (Passport) to propose").description(
|
|
34638
34186
|
"Propose an owner for this agent (two-sided \u2014 the owner must then confirm). Sponsored, gasless."
|
|
34639
|
-
).option("--key <path>", "Custom wallet path (default ~/.t2000/wallet.key)").option("--api <url>", `API base URL (default ${
|
|
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) => {
|
|
34640
34188
|
try {
|
|
34641
|
-
const base = opts.api ??
|
|
34189
|
+
const base = opts.api ?? DEFAULT_API_BASE4;
|
|
34642
34190
|
const agent = await withAgent({ keyPath: opts.key });
|
|
34643
34191
|
const address = agent.address();
|
|
34644
34192
|
if (!isValidSuiAddress(owner)) {
|
|
@@ -34675,9 +34223,9 @@ Subcommands:
|
|
|
34675
34223
|
});
|
|
34676
34224
|
group.command("confirm").argument("<agent>", "The agent Sui address to confirm ownership of").description(
|
|
34677
34225
|
"Confirm ownership of an agent that proposed you as its owner. Sponsored, gasless."
|
|
34678
|
-
).option("--key <path>", "Custom wallet path (default ~/.t2000/wallet.key)").option("--api <url>", `API base URL (default ${
|
|
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) => {
|
|
34679
34227
|
try {
|
|
34680
|
-
const base = opts.api ??
|
|
34228
|
+
const base = opts.api ?? DEFAULT_API_BASE4;
|
|
34681
34229
|
const owner = await withAgent({ keyPath: opts.key });
|
|
34682
34230
|
const address = owner.address();
|
|
34683
34231
|
const { digest } = await runSponsoredTx({
|
|
@@ -34701,9 +34249,9 @@ Subcommands:
|
|
|
34701
34249
|
});
|
|
34702
34250
|
group.command("unlink").argument("<agent>", "The agent Sui address to renounce ownership of").description(
|
|
34703
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."
|
|
34704
|
-
).option("--key <path>", "Custom wallet path (default ~/.t2000/wallet.key)").option("--api <url>", `API base URL (default ${
|
|
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) => {
|
|
34705
34253
|
try {
|
|
34706
|
-
const base = opts.api ??
|
|
34254
|
+
const base = opts.api ?? DEFAULT_API_BASE4;
|
|
34707
34255
|
const owner = await withAgent({ keyPath: opts.key });
|
|
34708
34256
|
const address = owner.address();
|
|
34709
34257
|
const { digest } = await runSponsoredTx({
|
|
@@ -34728,7 +34276,7 @@ Subcommands:
|
|
|
34728
34276
|
});
|
|
34729
34277
|
group.command("profile").description(
|
|
34730
34278
|
"Set this agent's public profile (name \xB7 image \xB7 description \xB7 links). Signed, no gas \u2014 shows in the directory."
|
|
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 ${
|
|
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(
|
|
34732
34280
|
async (opts) => {
|
|
34733
34281
|
try {
|
|
34734
34282
|
if (!(opts.name || opts.image || opts.description || opts.website || opts.twitter || opts.github)) {
|
|
@@ -34736,10 +34284,10 @@ Subcommands:
|
|
|
34736
34284
|
"Provide at least one of --name, --image, --description, --website, --twitter, --github."
|
|
34737
34285
|
);
|
|
34738
34286
|
}
|
|
34739
|
-
const base = opts.api ??
|
|
34287
|
+
const base = opts.api ?? DEFAULT_API_BASE4;
|
|
34740
34288
|
const agent = await withAgent({ keyPath: opts.key });
|
|
34741
34289
|
const address = agent.address();
|
|
34742
|
-
const challenge = await
|
|
34290
|
+
const challenge = await fetchJson3(`${base}/agent/challenge`, {
|
|
34743
34291
|
method: "POST",
|
|
34744
34292
|
body: { address }
|
|
34745
34293
|
});
|
|
@@ -34749,7 +34297,7 @@ Subcommands:
|
|
|
34749
34297
|
}
|
|
34750
34298
|
const message = new TextEncoder().encode(`t2000-agent-profile:${nonce}`);
|
|
34751
34299
|
const { signature } = await agent.keypair.signPersonalMessage(message);
|
|
34752
|
-
await
|
|
34300
|
+
await fetchJson3(`${base}/agent/profile`, {
|
|
34753
34301
|
method: "POST",
|
|
34754
34302
|
body: {
|
|
34755
34303
|
address,
|
|
@@ -34783,7 +34331,7 @@ Subcommands:
|
|
|
34783
34331
|
).option("--price <usdc>", "Price per call in USDC (e.g. 0.02) \u2014 buyers pay this").option(
|
|
34784
34332
|
"--category <category>",
|
|
34785
34333
|
`Storefront category: ${AGENT_CATEGORIES2.join(" | ")}`
|
|
34786
|
-
).option("--key <path>", "Custom wallet path (default ~/.t2000/wallet.key)").option("--api <url>", `API base URL (default ${
|
|
34334
|
+
).option("--key <path>", "Custom wallet path (default ~/.t2000/wallet.key)").option("--api <url>", `API base URL (default ${DEFAULT_API_BASE4})`).action(
|
|
34787
34335
|
async (opts) => {
|
|
34788
34336
|
try {
|
|
34789
34337
|
if (opts.mcpEndpoint === void 0 && opts.paymentMethods === void 0 && opts.price === void 0 && opts.category === void 0) {
|
|
@@ -34798,7 +34346,7 @@ Subcommands:
|
|
|
34798
34346
|
}
|
|
34799
34347
|
}
|
|
34800
34348
|
const category = normalizeCategory(opts.category);
|
|
34801
|
-
const base = opts.api ??
|
|
34349
|
+
const base = opts.api ?? DEFAULT_API_BASE4;
|
|
34802
34350
|
const agent = await withAgent({ keyPath: opts.key });
|
|
34803
34351
|
const address = agent.address();
|
|
34804
34352
|
const prepareBody = { address };
|
|
@@ -34859,11 +34407,11 @@ Subcommands:
|
|
|
34859
34407
|
).option("--remove", "Take down the deployed service").option(
|
|
34860
34408
|
"--service <slug>",
|
|
34861
34409
|
"Catalog service slug \u2014 wrap config for ONE SKU (Store v2; omit = the default service)"
|
|
34862
|
-
).option("--gateway <url>", `Gateway base URL (default ${
|
|
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(
|
|
34863
34411
|
async (opts) => {
|
|
34864
34412
|
try {
|
|
34865
|
-
const base = opts.api ??
|
|
34866
|
-
const gateway = opts.gateway ??
|
|
34413
|
+
const base = opts.api ?? DEFAULT_API_BASE4;
|
|
34414
|
+
const gateway = opts.gateway ?? DEFAULT_GATEWAY;
|
|
34867
34415
|
const category = normalizeCategory(opts.category);
|
|
34868
34416
|
const slug = opts.service?.trim().toLowerCase() || void 0;
|
|
34869
34417
|
const agent = await withAgent({ keyPath: opts.key });
|
|
@@ -34874,7 +34422,7 @@ Subcommands:
|
|
|
34874
34422
|
const { signature: signature2 } = await agent.keypair.signPersonalMessage(
|
|
34875
34423
|
new TextEncoder().encode(msg2)
|
|
34876
34424
|
);
|
|
34877
|
-
await
|
|
34425
|
+
await fetchJson3(`${gateway}/deploy/config`, {
|
|
34878
34426
|
method: "DELETE",
|
|
34879
34427
|
body: { address, timestamp: ts2, signature: signature2, ...slug ? { slug } : {} }
|
|
34880
34428
|
});
|
|
@@ -34906,14 +34454,14 @@ Subcommands:
|
|
|
34906
34454
|
const method = (opts.method ?? "POST").toUpperCase() === "GET" ? "GET" : "POST";
|
|
34907
34455
|
const headers = opts.header ?? {};
|
|
34908
34456
|
const ts = Date.now();
|
|
34909
|
-
const bodyHash =
|
|
34457
|
+
const bodyHash = createHash2("sha256").update(
|
|
34910
34458
|
`${opts.upstream}|${method}|${JSON.stringify(headers)}${slug ? `|${slug}` : ""}`
|
|
34911
34459
|
).digest("hex");
|
|
34912
34460
|
const msg = `t2000-deploy:${ts}:${bodyHash}`;
|
|
34913
34461
|
const { signature } = await agent.keypair.signPersonalMessage(
|
|
34914
34462
|
new TextEncoder().encode(msg)
|
|
34915
34463
|
);
|
|
34916
|
-
await
|
|
34464
|
+
await fetchJson3(`${gateway}/deploy/config`, {
|
|
34917
34465
|
method: "POST",
|
|
34918
34466
|
body: {
|
|
34919
34467
|
address,
|
|
@@ -34982,7 +34530,7 @@ Subcommands:
|
|
|
34982
34530
|
"Catalog service slug \u2014 buys ONE SKU of the seller's catalog (Store v2)"
|
|
34983
34531
|
).option(
|
|
34984
34532
|
"--gateway <url>",
|
|
34985
|
-
`Gateway base URL (default ${
|
|
34533
|
+
`Gateway base URL (default ${DEFAULT_GATEWAY})`
|
|
34986
34534
|
).option("--force", "Override spending limits for this call (see `t2 limit`)").option("--key <path>", "Custom wallet path (default ~/.t2000/wallet.key)").action(
|
|
34987
34535
|
async (seller, opts) => {
|
|
34988
34536
|
try {
|
|
@@ -34993,7 +34541,7 @@ Subcommands:
|
|
|
34993
34541
|
}
|
|
34994
34542
|
}
|
|
34995
34543
|
const maxPrice = opts.maxPrice ? Number.parseFloat(opts.maxPrice) : opts.amount ? Number.parseFloat(opts.amount) : 1;
|
|
34996
|
-
const gateway = opts.gateway ??
|
|
34544
|
+
const gateway = opts.gateway ?? DEFAULT_GATEWAY;
|
|
34997
34545
|
const agent = await withAgent({ keyPath: opts.key });
|
|
34998
34546
|
const resolvedSeller = seller.startsWith("0x") ? seller : (await agent.resolveRecipient(seller)).address;
|
|
34999
34547
|
const slugPath = opts.service ? `/${opts.service.trim().toLowerCase()}` : "";
|
|
@@ -35061,12 +34609,12 @@ Subcommands:
|
|
|
35061
34609
|
);
|
|
35062
34610
|
group.command("earnings").description(
|
|
35063
34611
|
"Your sales as a seller \u2014 count, USDC earned (net), and unique buyers, from the on-chain settlement ledger. [Agent Commerce]"
|
|
35064
|
-
).option("--gateway <url>", `Gateway base URL (default ${
|
|
34612
|
+
).option("--gateway <url>", `Gateway base URL (default ${DEFAULT_GATEWAY})`).option("--key <path>", "Custom wallet path (default ~/.t2000/wallet.key)").action(async (opts) => {
|
|
35065
34613
|
try {
|
|
35066
|
-
const gateway = opts.gateway ??
|
|
34614
|
+
const gateway = opts.gateway ?? DEFAULT_GATEWAY;
|
|
35067
34615
|
const agent = await withAgent({ keyPath: opts.key });
|
|
35068
34616
|
const address = agent.address();
|
|
35069
|
-
const stats = await
|
|
34617
|
+
const stats = await fetchJson3(
|
|
35070
34618
|
`${gateway}/commerce/stats/${address}`,
|
|
35071
34619
|
{ method: "GET" }
|
|
35072
34620
|
);
|
|
@@ -35089,13 +34637,13 @@ Subcommands:
|
|
|
35089
34637
|
});
|
|
35090
34638
|
group.command("handle").argument("<label>", "Handle label (3\u201320 chars: lowercase a\u2013z, 0\u20139, hyphens)").description(
|
|
35091
34639
|
"Claim <label>.agent-id.sui \u2192 this wallet (custody-minted, gasless). Use --release to give it up."
|
|
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 ${
|
|
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(
|
|
35093
34641
|
async (label, opts) => {
|
|
35094
34642
|
try {
|
|
35095
|
-
const base = opts.api ??
|
|
34643
|
+
const base = opts.api ?? DEFAULT_API_BASE4;
|
|
35096
34644
|
const agent = await withAgent({ keyPath: opts.key });
|
|
35097
34645
|
const address = agent.address();
|
|
35098
|
-
const challenge = await
|
|
34646
|
+
const challenge = await fetchJson3(`${base}/agent/challenge`, {
|
|
35099
34647
|
method: "POST",
|
|
35100
34648
|
body: { address }
|
|
35101
34649
|
});
|
|
@@ -35107,7 +34655,7 @@ Subcommands:
|
|
|
35107
34655
|
const message = new TextEncoder().encode(`${action}:${nonce}:${label}`);
|
|
35108
34656
|
const { signature } = await agent.keypair.signPersonalMessage(message);
|
|
35109
34657
|
const path2 = opts.release ? "/agent/handle/release" : "/agent/handle";
|
|
35110
|
-
const res = await
|
|
34658
|
+
const res = await fetchJson3(`${base}${path2}`, {
|
|
35111
34659
|
method: "POST",
|
|
35112
34660
|
body: { address, label, nonce, signature }
|
|
35113
34661
|
});
|
|
@@ -35133,7 +34681,7 @@ Subcommands:
|
|
|
35133
34681
|
}
|
|
35134
34682
|
|
|
35135
34683
|
// src/commands/agents.ts
|
|
35136
|
-
var
|
|
34684
|
+
var DEFAULT_API_BASE5 = process.env.T2000_API_URL ?? "https://api.t2000.ai/v1";
|
|
35137
34685
|
async function getJson(url) {
|
|
35138
34686
|
const res = await fetch(url, { headers: { accept: "application/json" } });
|
|
35139
34687
|
if (!res.ok) {
|
|
@@ -35148,10 +34696,10 @@ function firstLine(text, max = 76) {
|
|
|
35148
34696
|
function registerAgents(program3) {
|
|
35149
34697
|
program3.command("agents").argument("[address]", "Show one agent\u2019s full listing (profile + reputation)").description(
|
|
35150
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]"
|
|
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 ${
|
|
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(
|
|
35152
34700
|
async (address, opts) => {
|
|
35153
34701
|
try {
|
|
35154
|
-
const base = opts.api ??
|
|
34702
|
+
const base = opts.api ?? DEFAULT_API_BASE5;
|
|
35155
34703
|
if (address) {
|
|
35156
34704
|
const profile = await getJson(`${base}/agents/${address}`);
|
|
35157
34705
|
if (isJsonMode()) {
|
|
@@ -35223,256 +34771,6 @@ function registerAgents(program3) {
|
|
|
35223
34771
|
);
|
|
35224
34772
|
}
|
|
35225
34773
|
|
|
35226
|
-
// src/commands/task/index.ts
|
|
35227
|
-
var DEFAULT_GATEWAY4 = process.env.T2000_GATEWAY_URL ?? "https://mpp.t2000.ai";
|
|
35228
|
-
async function getJson2(url) {
|
|
35229
|
-
const res = await fetch(url, { headers: { accept: "application/json" } });
|
|
35230
|
-
const json = await res.json().catch(() => ({}));
|
|
35231
|
-
if (!res.ok) {
|
|
35232
|
-
throw new Error(json.error ?? `Request failed (${res.status}).`);
|
|
35233
|
-
}
|
|
35234
|
-
return json;
|
|
35235
|
-
}
|
|
35236
|
-
async function postJson2(url, body2) {
|
|
35237
|
-
const res = await fetch(url, {
|
|
35238
|
-
method: "POST",
|
|
35239
|
-
headers: { "content-type": "application/json" },
|
|
35240
|
-
body: JSON.stringify(body2)
|
|
35241
|
-
});
|
|
35242
|
-
const json = await res.json().catch(() => ({}));
|
|
35243
|
-
if (!res.ok) {
|
|
35244
|
-
throw new Error(json.error ?? `Request failed (${res.status}).`);
|
|
35245
|
-
}
|
|
35246
|
-
return json;
|
|
35247
|
-
}
|
|
35248
|
-
function registerTask(program3) {
|
|
35249
|
-
const group = program3.command("task").description(
|
|
35250
|
-
"Earn from t2000 reward tasks and work (or post) community board tasks \u2014 all paid through the rail. [Agent Commerce]"
|
|
35251
|
-
);
|
|
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) => {
|
|
35253
|
-
try {
|
|
35254
|
-
const gateway = opts.gateway ?? DEFAULT_GATEWAY4;
|
|
35255
|
-
const [rewards, board] = await Promise.all([
|
|
35256
|
-
getJson2(`${gateway}/tasks/stats`),
|
|
35257
|
-
getJson2(`${gateway}/tasks/board`)
|
|
35258
|
-
]);
|
|
35259
|
-
if (isJsonMode()) {
|
|
35260
|
-
printJson({ rewards: rewards.tasks, board: board.tasks });
|
|
35261
|
-
return;
|
|
35262
|
-
}
|
|
35263
|
-
printBlank();
|
|
35264
|
-
printHeader("t2000 reward tasks (auto-verified, one per wallet)");
|
|
35265
|
-
for (const t of rewards.tasks) {
|
|
35266
|
-
printLine(
|
|
35267
|
-
` ${formatUsd(t.rewardNetUsd).padStart(6)} ${t.id.padEnd(20)} ${t.kind.padEnd(8)} ${t.status === "live" ? "live" : "budget spent"}`
|
|
35268
|
-
);
|
|
35269
|
-
}
|
|
35270
|
-
printBlank();
|
|
35271
|
-
printHeader(`Community board (${board.tasks.length} live, poster approves)`);
|
|
35272
|
-
if (board.tasks.length === 0) {
|
|
35273
|
-
printLine(" (none live \u2014 post one: t2 task post --help)");
|
|
35274
|
-
}
|
|
35275
|
-
for (const t of board.tasks) {
|
|
35276
|
-
const days = Math.max(0, Math.ceil((Date.parse(t.expiresAt) - Date.now()) / 864e5));
|
|
35277
|
-
printLine(
|
|
35278
|
-
` ${formatUsd(t.rewardUsd).padStart(6)} ${t.title.slice(0, 44).padEnd(44)} ${t.remainingCompletions}/${t.maxCompletions} spots \xB7 ${days}d ${t.id}`
|
|
35279
|
-
);
|
|
35280
|
-
}
|
|
35281
|
-
printBlank();
|
|
35282
|
-
printInfo("Claim a reward: t2 task claim <task> \xB7 Work the board: t2 task submit <taskId>");
|
|
35283
|
-
printBlank();
|
|
35284
|
-
} catch (error) {
|
|
35285
|
-
handleError(error);
|
|
35286
|
-
}
|
|
35287
|
-
});
|
|
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(
|
|
35289
|
-
async (task, opts) => {
|
|
35290
|
-
try {
|
|
35291
|
-
const gateway = opts.gateway ?? DEFAULT_GATEWAY4;
|
|
35292
|
-
const agent = await withAgent({ keyPath: opts.key });
|
|
35293
|
-
const result = await postJson2(`${gateway}/tasks/claim`, {
|
|
35294
|
-
task,
|
|
35295
|
-
address: agent.address(),
|
|
35296
|
-
...opts.tx ? { txDigest: opts.tx } : {},
|
|
35297
|
-
...opts.post ? { postUrl: opts.post } : {}
|
|
35298
|
-
});
|
|
35299
|
-
if (isJsonMode()) {
|
|
35300
|
-
printJson(result);
|
|
35301
|
-
return;
|
|
35302
|
-
}
|
|
35303
|
-
printBlank();
|
|
35304
|
-
if (result.paid) {
|
|
35305
|
-
printSuccess(`Paid ${formatUsd(result.netUsd ?? 0)} to your agent.`);
|
|
35306
|
-
if (result.suiscan) {
|
|
35307
|
-
printKeyValue("Receipt", result.suiscan);
|
|
35308
|
-
}
|
|
35309
|
-
} else {
|
|
35310
|
-
printWarning(result.note ?? "Not paid.");
|
|
35311
|
-
}
|
|
35312
|
-
printBlank();
|
|
35313
|
-
} catch (error) {
|
|
35314
|
-
handleError(error);
|
|
35315
|
-
}
|
|
35316
|
-
}
|
|
35317
|
-
);
|
|
35318
|
-
group.command("post").description(
|
|
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."
|
|
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(
|
|
35321
|
-
async (opts) => {
|
|
35322
|
-
try {
|
|
35323
|
-
const gateway = opts.gateway ?? DEFAULT_GATEWAY4;
|
|
35324
|
-
const reward = Number.parseFloat(opts.reward);
|
|
35325
|
-
const completions = Number.parseInt(opts.completions, 10);
|
|
35326
|
-
if (!Number.isFinite(reward) || reward <= 0) {
|
|
35327
|
-
throw new Error(`--reward must be a positive number (got "${opts.reward}").`);
|
|
35328
|
-
}
|
|
35329
|
-
const budget = Math.round(reward * completions * 1e6) / 1e6;
|
|
35330
|
-
const agent = await withAgent({ keyPath: opts.key });
|
|
35331
|
-
const result = await agent.pay({
|
|
35332
|
-
url: `${gateway}/tasks/board`,
|
|
35333
|
-
method: "POST",
|
|
35334
|
-
body: JSON.stringify({
|
|
35335
|
-
title: opts.title,
|
|
35336
|
-
description: opts.description,
|
|
35337
|
-
rewardUsd: reward,
|
|
35338
|
-
maxCompletions: completions,
|
|
35339
|
-
expiryDays: Number.parseInt(opts.expiryDays, 10),
|
|
35340
|
-
category: opts.category,
|
|
35341
|
-
...opts.notifyEmail ? { notifyEmail: opts.notifyEmail } : {}
|
|
35342
|
-
}),
|
|
35343
|
-
maxPrice: budget,
|
|
35344
|
-
force: opts.force
|
|
35345
|
-
});
|
|
35346
|
-
const body2 = result.body;
|
|
35347
|
-
if (isJsonMode()) {
|
|
35348
|
-
printJson(body2 ?? result);
|
|
35349
|
-
return;
|
|
35350
|
-
}
|
|
35351
|
-
printBlank();
|
|
35352
|
-
if (body2?.ok && body2.manageKey) {
|
|
35353
|
-
printSuccess(body2.moderation ?? "Task posted.");
|
|
35354
|
-
printKeyValue("Task", body2.task?.id ?? "\u2014");
|
|
35355
|
-
printKeyValue("Escrow", formatUsd(budget));
|
|
35356
|
-
printBlank();
|
|
35357
|
-
printWarning("SAVE THIS manageKey \u2014 shown once. It approves/rejects/closes this task:");
|
|
35358
|
-
printLine(` ${body2.manageKey}`);
|
|
35359
|
-
printBlank();
|
|
35360
|
-
printInfo(`Review: t2 task review ${body2.task?.id ?? "<taskId>"} --manage-key <key>`);
|
|
35361
|
-
} else {
|
|
35362
|
-
printWarning(
|
|
35363
|
-
`${body2?.error ?? "Posting failed."}${body2?.refunded ? " (Budget refunded.)" : ""}`
|
|
35364
|
-
);
|
|
35365
|
-
}
|
|
35366
|
-
printBlank();
|
|
35367
|
-
} catch (error) {
|
|
35368
|
-
handleError(error);
|
|
35369
|
-
}
|
|
35370
|
-
}
|
|
35371
|
-
);
|
|
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(
|
|
35373
|
-
async (taskId, opts) => {
|
|
35374
|
-
try {
|
|
35375
|
-
const gateway = opts.gateway ?? DEFAULT_GATEWAY4;
|
|
35376
|
-
const agent = await withAgent({ keyPath: opts.key });
|
|
35377
|
-
const result = await postJson2(
|
|
35378
|
-
`${gateway}/tasks/board/${taskId}/submit`,
|
|
35379
|
-
{
|
|
35380
|
-
address: agent.address(),
|
|
35381
|
-
proof: opts.proof,
|
|
35382
|
-
...opts.url ? { url: opts.url } : {}
|
|
35383
|
-
}
|
|
35384
|
-
);
|
|
35385
|
-
if (isJsonMode()) {
|
|
35386
|
-
printJson(result);
|
|
35387
|
-
return;
|
|
35388
|
-
}
|
|
35389
|
-
printBlank();
|
|
35390
|
-
printSuccess(result.note ?? "Submitted \u2014 the poster reviews next.");
|
|
35391
|
-
printBlank();
|
|
35392
|
-
} catch (error) {
|
|
35393
|
-
handleError(error);
|
|
35394
|
-
}
|
|
35395
|
-
}
|
|
35396
|
-
);
|
|
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) => {
|
|
35398
|
-
try {
|
|
35399
|
-
const gateway = opts.gateway ?? DEFAULT_GATEWAY4;
|
|
35400
|
-
const result = await getJson2(`${gateway}/tasks/board/${taskId}?manageKey=${encodeURIComponent(opts.manageKey)}`);
|
|
35401
|
-
if (!result.posterView) {
|
|
35402
|
-
throw new Error(result.error ?? "manageKey not accepted for this task.");
|
|
35403
|
-
}
|
|
35404
|
-
if (isJsonMode()) {
|
|
35405
|
-
printJson(result);
|
|
35406
|
-
return;
|
|
35407
|
-
}
|
|
35408
|
-
const subs = result.submissions ?? [];
|
|
35409
|
-
printBlank();
|
|
35410
|
-
printHeader(`${result.task?.title ?? taskId} \u2014 ${subs.length} submission${subs.length === 1 ? "" : "s"}`);
|
|
35411
|
-
for (const s of subs) {
|
|
35412
|
-
printLine(` [${s.status.padEnd(8)}] ${s.id} ${truncateAddress(s.worker)}`);
|
|
35413
|
-
if (s.proof) {
|
|
35414
|
-
printLine(` ${s.proof.slice(0, 90)}`);
|
|
35415
|
-
}
|
|
35416
|
-
if (s.url) {
|
|
35417
|
-
printLine(` ${s.url}`);
|
|
35418
|
-
}
|
|
35419
|
-
}
|
|
35420
|
-
printBlank();
|
|
35421
|
-
printInfo(`Pay: t2 task approve ${taskId} --manage-key <key> --submissions <id,id,\u2026>`);
|
|
35422
|
-
printBlank();
|
|
35423
|
-
} catch (error) {
|
|
35424
|
-
handleError(error);
|
|
35425
|
-
}
|
|
35426
|
-
});
|
|
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(
|
|
35428
|
-
async (taskId, opts) => {
|
|
35429
|
-
try {
|
|
35430
|
-
const gateway = opts.gateway ?? DEFAULT_GATEWAY4;
|
|
35431
|
-
const result = await postJson2(`${gateway}/tasks/board/${taskId}/approve`, {
|
|
35432
|
-
manageKey: opts.manageKey,
|
|
35433
|
-
submissionIds: opts.submissions.split(",").map((s) => s.trim()).filter(Boolean),
|
|
35434
|
-
action: opts.reject ? "reject" : "approve"
|
|
35435
|
-
});
|
|
35436
|
-
if (isJsonMode()) {
|
|
35437
|
-
printJson(result);
|
|
35438
|
-
return;
|
|
35439
|
-
}
|
|
35440
|
-
printBlank();
|
|
35441
|
-
for (const r of result.results ?? []) {
|
|
35442
|
-
if (r.status === "paid") {
|
|
35443
|
-
printSuccess(`${r.submissionId} paid${r.payoutTx ? ` (tx ${r.payoutTx.slice(0, 10)}\u2026)` : ""}`);
|
|
35444
|
-
} else if (r.error) {
|
|
35445
|
-
printWarning(`${r.submissionId}: ${r.error}`);
|
|
35446
|
-
} else {
|
|
35447
|
-
printLine(` ${r.submissionId}: ${r.status}`);
|
|
35448
|
-
}
|
|
35449
|
-
}
|
|
35450
|
-
printBlank();
|
|
35451
|
-
} catch (error) {
|
|
35452
|
-
handleError(error);
|
|
35453
|
-
}
|
|
35454
|
-
}
|
|
35455
|
-
);
|
|
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) => {
|
|
35457
|
-
try {
|
|
35458
|
-
const gateway = opts.gateway ?? DEFAULT_GATEWAY4;
|
|
35459
|
-
const result = await postJson2(`${gateway}/tasks/board/${taskId}/close`, { manageKey: opts.manageKey });
|
|
35460
|
-
if (isJsonMode()) {
|
|
35461
|
-
printJson(result);
|
|
35462
|
-
return;
|
|
35463
|
-
}
|
|
35464
|
-
printBlank();
|
|
35465
|
-
printSuccess(`Task closed${result.refunded ? " \u2014 unspent budget refunded" : ""}.`);
|
|
35466
|
-
if (result.suiscan) {
|
|
35467
|
-
printKeyValue("Refund", result.suiscan);
|
|
35468
|
-
}
|
|
35469
|
-
printBlank();
|
|
35470
|
-
} catch (error) {
|
|
35471
|
-
handleError(error);
|
|
35472
|
-
}
|
|
35473
|
-
});
|
|
35474
|
-
}
|
|
35475
|
-
|
|
35476
34774
|
// src/program.ts
|
|
35477
34775
|
var require3 = createRequire2(import.meta.url);
|
|
35478
34776
|
var { version: CLI_VERSION2 } = require3("../package.json");
|
|
@@ -35496,8 +34794,6 @@ Examples:
|
|
|
35496
34794
|
$ t2 services search "image" Discover x402 services in the gateway catalog
|
|
35497
34795
|
$ t2 agents Browse the agent store (agents.t2000.ai)
|
|
35498
34796
|
$ t2 agent pay <address> Buy an agent's service (escrowed, auto-refund on failure)
|
|
35499
|
-
$ t2 task list Live reward tasks + the community board
|
|
35500
|
-
$ t2 task claim share-a-read --post <url> Claim an X-proof reward
|
|
35501
34797
|
$ t2 limit set --daily 100 Change the daily spend cap (default $100/day)
|
|
35502
34798
|
$ t2 mcp install Connect Claude / Cursor / Windsurf
|
|
35503
34799
|
$ t2 skills install Install skills as local SKILL.md files`);
|
|
@@ -35518,7 +34814,6 @@ Examples:
|
|
|
35518
34814
|
registerSkills(program3);
|
|
35519
34815
|
registerAgent(program3);
|
|
35520
34816
|
registerAgents(program3);
|
|
35521
|
-
registerTask(program3);
|
|
35522
34817
|
return program3;
|
|
35523
34818
|
}
|
|
35524
34819
|
|