@lucid-agents/taskmarket 1.21.0 → 1.23.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
@@ -14,7 +14,7 @@ import {
14
14
  signReadAuth,
15
15
  submitTaskFiles,
16
16
  taskAccessGrantHeaders
17
- } from "./chunk-5N25NATR.js";
17
+ } from "./chunk-4SZBEOE7.js";
18
18
  import {
19
19
  ComputeCreditError,
20
20
  applyComputeCreditSetup,
@@ -36,7 +36,7 @@ import {
36
36
  refusedPaidWrite,
37
37
  releasePendingComputePurchase,
38
38
  resolvePendingComputePurchases
39
- } from "./chunk-TAMXCFLT.js";
39
+ } from "./chunk-YXCEPGO4.js";
40
40
  import {
41
41
  MPP_TEMPO_DEFAULT_VALIDITY_SECONDS,
42
42
  X402PayError,
@@ -53,36 +53,53 @@ import {
53
53
  loadX402Policy,
54
54
  removeX402PolicyRule,
55
55
  resolveX402PaymentManually,
56
+ selectTaskmarketFeeRequirement,
56
57
  setX402PolicyRuleEnabled,
57
58
  signMessage,
58
59
  signSponsoredTempoTransfer,
59
60
  signTaskmarketFeePayment,
60
61
  signTypedData
61
- } from "./chunk-HE2N4GEO.js";
62
+ } from "./chunk-FSK3D3S5.js";
62
63
  import {
64
+ ActivityFeedInputSchema,
65
+ ActivityHeatmapInputSchema,
66
+ ActorType,
67
+ AgentChainsResponseSchema,
63
68
  AgentMessageEnvelopeSchema,
69
+ AgentTimeSeriesInputSchema,
64
70
  ApiError,
65
71
  BUG_REPORT_SEVERITIES,
66
72
  BUG_REPORT_STATUSES,
67
73
  BUG_REPORT_VISIBILITIES,
68
74
  BugReportMessageBodySchema,
75
+ CrossChainFundingConfigOutputSchema,
69
76
  DEFAULT_EVALUATION_WINDOW_HOURS,
70
77
  DEFAULT_TERMS_BOUNDS,
78
+ EthAddressSchema,
79
+ HookGetInputSchema,
80
+ HookIndexInputSchema,
71
81
  IntentStatusResponseSchema,
82
+ KeystoreExistsError,
72
83
  LegalAcceptanceResponseSchema,
73
84
  LegalBundleSchema,
74
85
  LegalChallengeResponseSchema,
75
86
  LegalStatusResponseSchema,
76
87
  NETWORKS,
77
88
  NETWORK_NAMES,
89
+ NetworkInfoSchema,
78
90
  NetworkRequiredError,
79
91
  PUBLIC_BUG_REPORT_SORTS,
80
92
  PenaltyTo,
93
+ PlatformTimeSeriesInputSchema,
81
94
  PostBugReportMessageInputSchema,
82
95
  READ_AUTH_ADDRESS_HEADER,
83
96
  READ_AUTH_SIGNATURE_HEADER,
84
97
  REDACTED,
98
+ RELAY_BRIDGE_ROUTES,
85
99
  RejectOutcome,
100
+ RelayBridgeFundingConfigOutputSchema,
101
+ RelayBridgeRouteIdSchema,
102
+ STANDARD_X402_ACTION_AMOUNT,
86
103
  SponsoredTaskRewardStateSchema,
87
104
  SponsoredTaskWorkerRewardClaimStatusSchema,
88
105
  SubmissionReviewAssessmentInputSchema,
@@ -103,6 +120,12 @@ import {
103
120
  SubmissionReviewStartPayloadSchema,
104
121
  SubmissionReviewTaskInputSchema,
105
122
  SubmitBugReportInputSchema,
123
+ TaskDropDirectoryInputSchema,
124
+ TaskDropGetInputSchema,
125
+ TaskDropOfficialStatusInputSchema,
126
+ TaskDropOfficialSubscribeInputSchema,
127
+ TaskDropStatusInputSchema,
128
+ TaskDropSubscribeInputSchema,
106
129
  TaskTermsError,
107
130
  TermsPresetName,
108
131
  WALLET_BRIDGE_ORIGIN_CHAIN_ID,
@@ -131,6 +154,7 @@ import {
131
154
  chainInfoFor,
132
155
  claimStakeToPost,
133
156
  clientValidityWindowSeconds,
157
+ createKeystore,
134
158
  decryptPrivateKey,
135
159
  dreamsToUsd,
136
160
  encryptPrivateKey,
@@ -157,6 +181,7 @@ import {
157
181
  readFailureBody,
158
182
  readKeystoreNetwork,
159
183
  redactSecrets,
184
+ relayBridgeRoute,
160
185
  resolveIdempotencyKey,
161
186
  resolveNetwork,
162
187
  resolveTaskTerms,
@@ -172,14 +197,14 @@ import {
172
197
  withChainId,
173
198
  withErrorContext,
174
199
  withIdempotentWrite
175
- } from "./chunk-3IIVNF5F.js";
200
+ } from "./chunk-OGYFQL45.js";
176
201
  import {
177
202
  channelLines
178
203
  } from "./chunk-XJOB4NMV.js";
179
204
  import "./chunk-S7SJMJ2I.js";
180
205
 
181
206
  // src/index.ts
182
- import { Command as Command109 } from "commander";
207
+ import { Command as Command113 } from "commander";
183
208
  import { createRequire } from "module";
184
209
 
185
210
  // src/commands/init.ts
@@ -369,10 +394,32 @@ async function registerDevice(input) {
369
394
  });
370
395
  if (!response.ok) {
371
396
  const text = await response.text().catch(() => "");
397
+ const limited = sponsoredMintRateLimitMessage(
398
+ response.status,
399
+ text,
400
+ response.headers.get("retry-after")
401
+ );
402
+ if (limited) throw new Error(limited);
372
403
  throw new Error(`Device registration failed (${response.status}): ${text}`);
373
404
  }
374
405
  return await response.json();
375
406
  }
407
+ function sponsoredMintRateLimitMessage(status, body, retryAfter) {
408
+ let parsed = body;
409
+ if (typeof body === "string") {
410
+ try {
411
+ parsed = JSON.parse(body);
412
+ } catch {
413
+ parsed = void 0;
414
+ }
415
+ }
416
+ const envelope = parsed;
417
+ if (status !== 429 && envelope?.taskmarket?.reason !== "rate_limited") return void 0;
418
+ const seconds = Number(retryAfter);
419
+ const wait = Number.isFinite(seconds) && seconds > 0 ? `Retry after ${seconds} seconds.` : "Retry later.";
420
+ const detail = envelope?.message ?? envelope?.error?.message;
421
+ return `Sponsored identity registration is rate limited (rate_limited). ${detail ? `${detail} ` : ""}${wait}`.trim();
422
+ }
376
423
 
377
424
  // src/lib/encryption.ts
378
425
  import { createECDH, hkdfSync, createCipheriv, createDecipheriv, randomBytes } from "crypto";
@@ -692,7 +739,7 @@ var initCommand = new Command2("init").description(
692
739
  });
693
740
  const encryptedKey = encryptPrivateKey(deviceEncryptionKey, privateKey);
694
741
  let agentId = initialAgentId;
695
- await saveKeystore({
742
+ const newKeystore = {
696
743
  encryptedKey,
697
744
  walletAddress: address,
698
745
  deviceId,
@@ -706,7 +753,18 @@ var initCommand = new Command2("init").description(
706
753
  legalAcceptanceBundleVersion: legalAcceptance.bundleVersion,
707
754
  legalAcceptanceReceipt: legalAcceptance.receipt
708
755
  } : {}
709
- });
756
+ };
757
+ const created = await createKeystore(newKeystore).then(
758
+ () => true,
759
+ (error) => {
760
+ if (error instanceof KeystoreExistsError) return false;
761
+ throw error;
762
+ }
763
+ );
764
+ if (!created) {
765
+ printError(existingWalletMessage());
766
+ return;
767
+ }
710
768
  if (!agentId) {
711
769
  agentId = await pollAgentId(address);
712
770
  if (agentId) {
@@ -762,11 +820,26 @@ identityCommand.command("register").description(
762
820
  printResult({ agentId: stored, alreadyRegistered: true, chainId });
763
821
  return;
764
822
  }
765
- const { data, idempotencyKey } = await apiPost(`/api/devices/${encodeURIComponent(keystore.deviceId)}/identity`, {
766
- deviceId: keystore.deviceId,
767
- apiToken: keystore.apiToken,
768
- chainId
769
- });
823
+ let posted;
824
+ try {
825
+ posted = await apiPost(
826
+ `/api/devices/${encodeURIComponent(keystore.deviceId)}/identity`,
827
+ { deviceId: keystore.deviceId, apiToken: keystore.apiToken, chainId }
828
+ );
829
+ } catch (error) {
830
+ if (error instanceof ApiError) {
831
+ const limited = sponsoredMintRateLimitMessage(
832
+ error.status,
833
+ error.envelope ?? error.message
834
+ );
835
+ if (limited) {
836
+ renderFailure(new ApiError(error.status, limited, error.idempotencyKey, error.envelope));
837
+ return;
838
+ }
839
+ }
840
+ throw error;
841
+ }
842
+ const { data, idempotencyKey } = posted;
770
843
  const agentId = data.agentId ?? await pollAgentId(keystore.walletAddress);
771
844
  if (agentId) {
772
845
  await saveKeystore(withAgentIdForChain(await loadKeystore(), chainId, agentId));
@@ -840,7 +913,91 @@ var whoamiCommand = new Command5("whoami").description(
840
913
 
841
914
  // src/commands/stats.ts
842
915
  import { Command as Command6 } from "commander";
843
- var statsCommand = new Command6("stats").description("View agent statistics on the selected --network").option("--address <addr>", "Wallet address (defaults to own wallet)").option("--agent <agentId>", "Agent ID (alternative to --address)").action(async (opts) => {
916
+
917
+ // src/lib/parse-input.ts
918
+ function parseInput(schema, input) {
919
+ const result = schema.safeParse(input);
920
+ if (!result.success) {
921
+ const detail = result.error.issues.map((issue) => (issue.path.length > 0 ? `${issue.path.join(".")}: ` : "") + issue.message).join("; ");
922
+ throw new Error(`Invalid input: ${detail}`);
923
+ }
924
+ return result.data;
925
+ }
926
+ function optionalInt(value) {
927
+ if (value === void 0) return void 0;
928
+ const parsed = Number(value);
929
+ return Number.isInteger(parsed) ? parsed : Number.NaN;
930
+ }
931
+
932
+ // src/commands/stats.ts
933
+ function query(values) {
934
+ const params = new URLSearchParams();
935
+ for (const [key, value] of Object.entries(values)) {
936
+ if (value !== void 0) params.set(key, String(value));
937
+ }
938
+ return params.toString();
939
+ }
940
+ async function platformView(opts) {
941
+ const views = [opts.platform, opts.activity, opts.heatmap, opts.series].filter(Boolean).length;
942
+ if (views === 0) return false;
943
+ if (views > 1) {
944
+ throw new Error("Pass only one of --platform, --activity, --heatmap or --series");
945
+ }
946
+ if (opts.platform) {
947
+ const input2 = parseInput(PlatformTimeSeriesInputSchema, {
948
+ range: opts.range,
949
+ bucket: opts.bucket
950
+ });
951
+ const [market, breakdowns, timeSeries] = await Promise.all([
952
+ apiGet(withChainId("/api/market/stats")),
953
+ apiGet(withChainId("/api/stats/breakdowns")),
954
+ apiGet(withChainId(`/api/stats/platform-time-series?${query(input2)}`))
955
+ ]);
956
+ printResult({ chainId: selectedNetwork().chainId, market, breakdowns, timeSeries });
957
+ return true;
958
+ }
959
+ if (opts.activity) {
960
+ const input2 = parseInput(ActivityFeedInputSchema, {
961
+ limit: optionalInt(opts.limit),
962
+ cursor: opts.cursor
963
+ });
964
+ printResult(
965
+ await apiGet(
966
+ withChainId(
967
+ `/api/stats/activity-feed?${query({ limit: input2.limit, cursor: input2.cursor })}`
968
+ )
969
+ )
970
+ );
971
+ return true;
972
+ }
973
+ if (opts.heatmap) {
974
+ const input2 = parseInput(ActivityHeatmapInputSchema, {
975
+ range: opts.range,
976
+ dimension: opts.dimension
977
+ });
978
+ printResult(await apiGet(withChainId(`/api/stats/activity-heatmap?${query(input2)}`)));
979
+ return true;
980
+ }
981
+ let address = opts.address;
982
+ if (!address && !opts.agent) {
983
+ address = (await loadKeystore()).walletAddress;
984
+ }
985
+ const input = parseInput(AgentTimeSeriesInputSchema, {
986
+ address: opts.agent ? void 0 : address,
987
+ agentId: opts.agent,
988
+ range: opts.range,
989
+ bucket: opts.bucket
990
+ });
991
+ printResult(await apiGet(withChainId(`/api/stats/agent-time-series?${query(input)}`)));
992
+ return true;
993
+ }
994
+ var statsCommand = new Command6("stats").description("View agent or platform-wide statistics on the selected --network").option("--address <addr>", "Wallet address (defaults to own wallet)").option("--agent <agentId>", "Agent ID (alternative to --address)").option("--platform", "Platform-wide market stats, breakdowns and time series").option("--activity", "Recent platform activity feed").option("--heatmap", "Market activity heat map").option("--series", "An agent's earnings, ratings and activity time series").option("--range <range>", "Time range for --platform, --heatmap, --series: 7d, 30d, 90d or all").option("--bucket <bucket>", "Bucket for --platform and --series: day or week").option("--dimension <dimension>", "Heat map dimension for --heatmap: mode or hourOfWeek").option("--limit <n>", "Items for --activity (1-50)").option("--cursor <cursor>", "nextCursor from a previous --activity page").action(async (opts) => {
995
+ try {
996
+ if (await platformView(opts)) return;
997
+ } catch (err) {
998
+ renderFailure(err);
999
+ return;
1000
+ }
844
1001
  let address = opts.address;
845
1002
  if (!address) {
846
1003
  const keystore = await loadKeystore();
@@ -883,7 +1040,12 @@ var statsCommand = new Command6("stats").description("View agent statistics on t
883
1040
  ratedTasks: result.ratedTasks,
884
1041
  averageRating: result.averageRating,
885
1042
  credibility: result.credibility,
1043
+ // Paid on the selected chain, in its token; earningsByChain lists every chain where the
1044
+ // wallet earned, each in its own token, never summed.
886
1045
  totalEarnings: result.totalEarnings,
1046
+ earningsChainId: selectedNetwork().chainId,
1047
+ earningsToken: paymentTokenSymbol(selectedNetwork().chainId),
1048
+ earningsByChain: result.earningsByChain ?? [],
887
1049
  skills: result.skills,
888
1050
  emailAddress: result.emailAddress,
889
1051
  recentRatings: result.recentRatings
@@ -908,7 +1070,7 @@ var correctionOutput = z.object({
908
1070
  correctionId: z.string().uuid(),
909
1071
  createdAt: z.string().datetime()
910
1072
  });
911
- var query = (values) => {
1073
+ var query2 = (values) => {
912
1074
  const params = new URLSearchParams();
913
1075
  for (const [key, value] of Object.entries(values))
914
1076
  if (value !== void 0) params.set(key, String(value));
@@ -968,7 +1130,7 @@ function createSubmissionReviewClient(options) {
968
1130
  async profile(input) {
969
1131
  const { taskId, ...params } = SubmissionReviewTaskInputSchema.parse(input);
970
1132
  return get(
971
- `${taskPath(taskId)}/submission-review-profile${query(params)}`,
1133
+ `${taskPath(taskId)}/submission-review-profile${query2(params)}`,
972
1134
  SubmissionReviewProfileOutputSchema
973
1135
  );
974
1136
  },
@@ -1011,12 +1173,12 @@ function createSubmissionReviewClient(options) {
1011
1173
  },
1012
1174
  async status(input) {
1013
1175
  const { runId, ...params } = SubmissionReviewRunInputSchema.parse(input);
1014
- return get(`${runPath(runId)}${query(params)}`, SubmissionReviewRunSummarySchema);
1176
+ return get(`${runPath(runId)}${query2(params)}`, SubmissionReviewRunSummarySchema);
1015
1177
  },
1016
1178
  async lookup(input) {
1017
1179
  const { idempotencyKey, ...params } = SubmissionReviewLookupInputSchema.parse(input);
1018
1180
  return get(
1019
- `/api/submission-review-requests/${idempotencyKey}${query(params)}`,
1181
+ `/api/submission-review-requests/${idempotencyKey}${query2(params)}`,
1020
1182
  SubmissionReviewRunSummarySchema
1021
1183
  );
1022
1184
  },
@@ -1035,7 +1197,7 @@ function createSubmissionReviewClient(options) {
1035
1197
  async results(input) {
1036
1198
  const { taskId, ...params } = SubmissionReviewResultsInputSchema.parse(input);
1037
1199
  return get(
1038
- `${taskPath(taskId)}/submission-review-results${query(params)}`,
1200
+ `${taskPath(taskId)}/submission-review-results${query2(params)}`,
1039
1201
  SubmissionReviewResultsOutputSchema
1040
1202
  );
1041
1203
  },
@@ -1067,14 +1229,14 @@ function createSubmissionReviewClient(options) {
1067
1229
  async history(input) {
1068
1230
  const { taskId, ...params } = SubmissionReviewHistoryInputSchema.parse(input);
1069
1231
  return get(
1070
- `${taskPath(taskId)}/submission-reviews${query(params)}`,
1232
+ `${taskPath(taskId)}/submission-reviews${query2(params)}`,
1071
1233
  SubmissionReviewHistoryOutputSchema
1072
1234
  );
1073
1235
  },
1074
1236
  async assessment(input) {
1075
1237
  const { runId, submissionId, ...params } = SubmissionReviewAssessmentInputSchema.parse(input);
1076
1238
  return get(
1077
- `${runPath(runId)}/assessments/${encodeURIComponent(submissionId)}${query(params)}`,
1239
+ `${runPath(runId)}/assessments/${encodeURIComponent(submissionId)}${query2(params)}`,
1078
1240
  SubmissionReviewAssessmentOutputSchema
1079
1241
  );
1080
1242
  },
@@ -1312,6 +1474,9 @@ var reviewCmd = createReviewCommand();
1312
1474
  import { Command as Command8 } from "commander";
1313
1475
  import { parseUnits } from "viem";
1314
1476
 
1477
+ // src/lib/fee-ceiling.ts
1478
+ var TASKMARKET_FEE_DEFAULT_CEILING = (BigInt(STANDARD_X402_ACTION_AMOUNT) * 2n).toString();
1479
+
1315
1480
  // src/lib/x402.ts
1316
1481
  var FACILITATOR_RETRIES = 2;
1317
1482
  var MAX_RETRY_AFTER_SECONDS = 60;
@@ -1343,10 +1508,12 @@ async function x402Post(path3, body, options) {
1343
1508
  throw refusedPaidWrite(path3, r1.status, await readFailureBody(r1), idempotencyKey);
1344
1509
  }
1345
1510
  const requirements = await r1.json();
1346
- if (!requirements.accepts || requirements.accepts.length === 0) {
1347
- throw new Error("No payment methods accepted by server");
1348
- }
1349
- const accept = requirements.accepts[0];
1511
+ const chain = taskmarketChain(selectedNetwork().chainId);
1512
+ const accept = selectTaskmarketFeeRequirement(requirements.accepts, {
1513
+ network: chain.caip2,
1514
+ asset: chain.payment.token,
1515
+ maxAmount: options?.maxAmount ?? TASKMARKET_FEE_DEFAULT_CEILING
1516
+ });
1350
1517
  const { header } = await signTaskmarketFeePayment({
1351
1518
  resource: requirements.resource,
1352
1519
  requirement: accept,
@@ -1956,7 +2123,10 @@ var createCmd = new Command8("create").description("Create a new task (costs the
1956
2123
  if (opts.appealWindow) body.appealWindowHours = parseFloat(opts.appealWindow);
1957
2124
  if (opts.disputeResolver) body.disputeResolver = opts.disputeResolver;
1958
2125
  }
1959
- const { data: result, idempotencyKey } = await x402Post("/api/tasks", body);
2126
+ const { data: result, idempotencyKey } = await x402Post("/api/tasks", body, {
2127
+ // Creating a task pays the reward plus any evaluator stake, exactly; never more.
2128
+ maxAmount: (BigInt(String(body.reward)) + BigInt(String(body.evaluatorStake ?? "0"))).toString()
2129
+ });
1960
2130
  const terms = result.terms ?? resolvedTerms;
1961
2131
  printResult(
1962
2132
  {
@@ -1972,6 +2142,29 @@ var createCmd = new Command8("create").description("Create a new task (costs the
1972
2142
 
1973
2143
  // src/commands/task/search.ts
1974
2144
  import { Command as Command9 } from "commander";
2145
+
2146
+ // src/lib/chain-name.ts
2147
+ function chainDisplayName(chainId) {
2148
+ return isTaskmarketChainId(chainId) ? taskmarketChain(chainId).name : `Chain ${chainId}`;
2149
+ }
2150
+ function withChainNames(value) {
2151
+ if (Array.isArray(value)) return value.map((item) => withChainNames(item));
2152
+ if (value === null || typeof value !== "object") return value;
2153
+ const proto = Object.getPrototypeOf(value);
2154
+ if (proto !== Object.prototype && proto !== null) return value;
2155
+ const record = value;
2156
+ const chainId = record.chainId;
2157
+ const named = typeof chainId === "number" && Number.isInteger(chainId);
2158
+ const out = {};
2159
+ for (const [key, field] of Object.entries(record)) {
2160
+ if (key === "chainName" && named) continue;
2161
+ out[key] = withChainNames(field);
2162
+ if (key === "chainId" && named) out.chainName = chainDisplayName(chainId);
2163
+ }
2164
+ return out;
2165
+ }
2166
+
2167
+ // src/commands/task/search.ts
1975
2168
  var listCmd = new Command9("list").alias("search").description("List available tasks").option("--status <status>", "Filter by status (e.g. open)", "open").option(
1976
2169
  "--phase <phase>",
1977
2170
  "Filter by derived lifecycle phase (active, in_review, awaiting_settlement, resolved) -- independent of --status, e.g. --phase awaiting_settlement finds tasks whose deadline has passed but are still open/claimed/worker_selected"
@@ -1993,7 +2186,11 @@ var listCmd = new Command9("list").alias("search").description("List available t
1993
2186
  limit: opts.limit,
1994
2187
  cursor: opts.cursor
1995
2188
  });
1996
- printResult({ tasks: result.tasks, hasMore: result.hasMore, nextCursor: result.nextCursor });
2189
+ printResult({
2190
+ tasks: withChainNames(result.tasks),
2191
+ hasMore: result.hasMore,
2192
+ nextCursor: result.nextCursor
2193
+ });
1997
2194
  }
1998
2195
  );
1999
2196
 
@@ -2007,7 +2204,7 @@ var getCmd = new Command10("get").description("Get task details").argument("<tas
2007
2204
  );
2008
2205
  return;
2009
2206
  }
2010
- printResult({ ...task, ...await termsAmountsAndDeadlines(taskId) });
2207
+ printResult(withChainNames({ ...task, ...await termsAmountsAndDeadlines(taskId) }));
2011
2208
  });
2012
2209
  async function termsAmountsAndDeadlines(taskId) {
2013
2210
  try {
@@ -2410,7 +2607,7 @@ var submissionsCmd = new Command23("submissions").description("List submissions
2410
2607
  renderFailure(err, { fallback: "Failed to fetch submissions." });
2411
2608
  return;
2412
2609
  }
2413
- printResult(subs);
2610
+ printResult(withChainNames(subs));
2414
2611
  });
2415
2612
 
2416
2613
  // src/commands/task/select-winner.ts
@@ -2697,7 +2894,7 @@ import { Command as Command31 } from "commander";
2697
2894
  var mySubmissionsCmd = new Command31("my-submissions").description("List all submissions made by your wallet across all tasks.").option("--address <address>", "Wallet address to query (defaults to own wallet from keystore)").action(async (opts) => {
2698
2895
  try {
2699
2896
  const result = await listWorkerSubmissions(cliTaskReadContext(), { address: opts.address });
2700
- printResult(result);
2897
+ printResult(withChainNames(result));
2701
2898
  } catch (err) {
2702
2899
  renderFailure(
2703
2900
  err instanceof TaskOperationError && err.code === "no_address" ? new Error("No address provided and no keystore found -- pass --address <address>.") : err
@@ -2788,7 +2985,12 @@ var updateCmd = new Command32("update").description("Update an open task (costs
2788
2985
  }
2789
2986
  const { data: result, idempotencyKey } = await x402Post(
2790
2987
  `/api/tasks/${taskId}/update`,
2791
- body
2988
+ body,
2989
+ ...body.reward === void 0 ? [] : [
2990
+ {
2991
+ maxAmount: (BigInt(TASKMARKET_FEE_DEFAULT_CEILING) + BigInt(String(body.reward))).toString()
2992
+ }
2993
+ ]
2792
2994
  );
2793
2995
  printResult(result, { idempotencyKey });
2794
2996
  }
@@ -2884,7 +3086,11 @@ var assignEvaluatorCmd = new Command34("assign-evaluator").description(
2884
3086
  }
2885
3087
  const { data: result, idempotencyKey } = await x402Post(
2886
3088
  `/api/tasks/${taskId}/evaluator`,
2887
- body
3089
+ body,
3090
+ // The action fee plus the stake this command just confirmed.
3091
+ {
3092
+ maxAmount: (BigInt(TASKMARKET_FEE_DEFAULT_CEILING) + BigInt(evaluatorStake)).toString()
3093
+ }
2888
3094
  );
2889
3095
  printResult(
2890
3096
  { ...result, ...await settleRecording(result, idempotencyKey) },
@@ -3487,7 +3693,7 @@ async function runAgentCommand(options) {
3487
3693
  try {
3488
3694
  const { assertAgentCompatibility } = await import("./compatibility-636WJOEX.js");
3489
3695
  const pi = assertAgentCompatibility();
3490
- const { runAgent } = await import("./launch-QDCWAIKE.js");
3696
+ const { runAgent } = await import("./launch-VZ5JBM5R.js");
3491
3697
  result = await runAgent({
3492
3698
  model: options.model,
3493
3699
  pi,
@@ -3546,13 +3752,13 @@ function agentManagementCommands() {
3546
3752
  const status = new Command48("status").description(
3547
3753
  "Show the agent channels (locked, charged, refundable), purchases with an unknown outcome, the sandbox and compute credit. Reads only."
3548
3754
  ).option("--json", "Print the versioned JSON envelope").action(async (options) => {
3549
- const { collectAgentStatus, statusLines } = await import("./status-FTTQWS5P.js");
3755
+ const { collectAgentStatus, statusLines } = await import("./status-RHVQJID5.js");
3550
3756
  await run(options, () => collectAgentStatus(), statusLines);
3551
3757
  });
3552
3758
  const doctor = new Command48("doctor").description(
3553
3759
  "Check that the agent can start: Node and the bundled runtime, wallet and policy, channels, API, sandbox broker, host keys, xgate and RPC. Reads only."
3554
3760
  ).option("--json", "Print the versioned JSON envelope").action(async (options) => {
3555
- const { runDoctor, doctorLines } = await import("./doctor-26YOWQOH.js");
3761
+ const { runDoctor, doctorLines } = await import("./doctor-YP2Z6WNE.js");
3556
3762
  const report = await run(options, () => runDoctor(), doctorLines);
3557
3763
  if (report && !report.ok) process.exitCode = 1;
3558
3764
  });
@@ -3563,7 +3769,7 @@ function agentManagementCommands() {
3563
3769
  "Reconcile the open purchases of this channel, as status lists it; also reaches retired channels"
3564
3770
  ).option("--json", "Print the versioned JSON envelope").action(
3565
3771
  async (invocationId, options) => {
3566
- const { reconcileChannelPurchases, reconcileInvocation } = await import("./reconcile-MALCM3NB.js");
3772
+ const { reconcileChannelPurchases, reconcileInvocation } = await import("./reconcile-VVNBTJRJ.js");
3567
3773
  const choice = { rail: options.rail, channel: options.channel };
3568
3774
  if (invocationId !== void 0) {
3569
3775
  await run(
@@ -3621,7 +3827,7 @@ function agentManagementCommands() {
3621
3827
  `Not a USDC amount: ${options.amount} (digits, at most 6 decimals)`
3622
3828
  );
3623
3829
  }
3624
- const { openAgentChannels, requestTopUp, selectRail, withdrawalHatch } = await import("./channels-OBJUNCZX.js");
3830
+ const { openAgentChannels, requestTopUp, selectRail, withdrawalHatch } = await import("./channels-Z52MJ5YT.js");
3625
3831
  const { rails } = await openAgentChannels();
3626
3832
  const result = await requestTopUp(selectRail(rails, options.rail), amount);
3627
3833
  return {
@@ -3645,8 +3851,8 @@ function agentManagementCommands() {
3645
3851
  async () => {
3646
3852
  await requireExperimental();
3647
3853
  const { AGENT_VIEW_VERSION } = await import("./budget-view-J6L7X6EY.js");
3648
- const { closeChannel, openAgentChannels, selectChannel } = await import("./channels-OBJUNCZX.js");
3649
- const { reconcileLeasedPurchase } = await import("./reconcile-MALCM3NB.js");
3854
+ const { closeChannel, openAgentChannels, selectChannel } = await import("./channels-Z52MJ5YT.js");
3855
+ const { reconcileLeasedPurchase } = await import("./reconcile-VVNBTJRJ.js");
3650
3856
  const opened = await openAgentChannels();
3651
3857
  const { rail, retired } = selectChannel(opened, options);
3652
3858
  const result = await closeChannel(
@@ -3717,7 +3923,7 @@ function agentManagementCommands() {
3717
3923
  options,
3718
3924
  async () => {
3719
3925
  await requireExperimental();
3720
- const { runPull } = await import("./sync-pull-N6OTHBWR.js");
3926
+ const { runPull } = await import("./sync-pull-C3VA3C26.js");
3721
3927
  const { terminalPrompter } = await import("./prompter-LSICEYSQ.js");
3722
3928
  return runPull(options, {
3723
3929
  interactive: Boolean(process.stdin.isTTY && process.stdout.isTTY) && !options.json,
@@ -3780,15 +3986,65 @@ for (const command of agentManagementCommands()) {
3780
3986
 
3781
3987
  // src/commands/agents.ts
3782
3988
  import { Command as Command50 } from "commander";
3783
- var agentsCommand = new Command50("agents").description("Browse the agent directory on the selected --network").option("--sort <order>", "Sort order: reputation or tasks", "reputation").option("--skill <tag>", "Filter by skill tag").option("--search <query>", "Search by agentId or wallet address").option("--limit <n>", "Maximum results to return", "20").action(async (opts) => {
3784
- const params = new URLSearchParams();
3785
- if (opts.sort) params.set("sort", opts.sort);
3786
- if (opts.skill) params.set("skill", opts.skill);
3787
- if (opts.search) params.set("search", opts.search);
3788
- if (opts.limit) params.set("limit", opts.limit);
3789
- params.set("chainId", String(selectedNetwork().chainId));
3790
- const result = await apiGet(`/api/agents/leaderboard?${params.toString()}`);
3791
- printResult(result);
3989
+ var agentsCommand = new Command50("agents").description("Browse the agent directory on the selected --network").option("--sort <order>", "Sort order: reputation or tasks", "reputation").option("--skill <tag>", "Filter by skill tag").option("--search <query>", "Search by agentId or wallet address").option("--limit <n>", "Maximum results to return", "20").option(
3990
+ "--kind <kind>",
3991
+ "Filter by actor kind: agent, human (the web humans directory) or hosted"
3992
+ ).action(
3993
+ async (opts) => {
3994
+ let kind;
3995
+ try {
3996
+ kind = opts.kind === void 0 ? void 0 : parseInput(ActorType, opts.kind);
3997
+ } catch (err) {
3998
+ renderFailure(err);
3999
+ return;
4000
+ }
4001
+ const params = new URLSearchParams();
4002
+ if (opts.sort) params.set("sort", opts.sort);
4003
+ if (opts.skill) params.set("skill", opts.skill);
4004
+ if (opts.search) params.set("search", opts.search);
4005
+ if (opts.limit) params.set("limit", opts.limit);
4006
+ if (kind) params.set("actorType", kind);
4007
+ const { chainId } = selectedNetwork();
4008
+ params.set("chainId", String(chainId));
4009
+ const result = await apiGet(`/api/agents/leaderboard?${params.toString()}`);
4010
+ printResult(
4011
+ Array.isArray(result) ? result.map((entry) => ({
4012
+ ...entry,
4013
+ earningsChainId: chainId,
4014
+ earningsToken: paymentTokenSymbol(chainId)
4015
+ })) : result
4016
+ );
4017
+ }
4018
+ );
4019
+ agentsCommand.command("get").description("Show an agent's record on the selected --network, or on every chain").argument("<address>", "Wallet address of the agent").option("--all-chains", "List the agent's records on every served chain").action(async (address, opts) => {
4020
+ let wallet;
4021
+ try {
4022
+ wallet = parseInput(EthAddressSchema, address);
4023
+ } catch (err) {
4024
+ renderFailure(err);
4025
+ return;
4026
+ }
4027
+ if (opts.allChains) {
4028
+ const result = await apiGet(
4029
+ `/api/agents/chains?${new URLSearchParams({ address: wallet }).toString()}`
4030
+ );
4031
+ const parsed = AgentChainsResponseSchema.safeParse(result);
4032
+ if (!parsed.success) {
4033
+ printResult(result);
4034
+ return;
4035
+ }
4036
+ printResult({
4037
+ ...parsed.data,
4038
+ chains: parsed.data.chains.map((entry) => ({
4039
+ ...entry,
4040
+ earningsToken: paymentTokenSymbol(entry.chainId)
4041
+ }))
4042
+ });
4043
+ return;
4044
+ }
4045
+ const { chainId } = selectedNetwork();
4046
+ const params = new URLSearchParams({ address: wallet, chainId: String(chainId) });
4047
+ printResult(await apiGet(`/api/agents/stats?${params.toString()}`));
3792
4048
  });
3793
4049
 
3794
4050
  // src/commands/inbox.ts
@@ -3810,7 +4066,7 @@ var inboxCommand = new Command51("inbox").description("Show tasks you created an
3810
4066
  () => []
3811
4067
  ) : Promise.resolve([])
3812
4068
  ]);
3813
- printResult({ ...taskResult, pendingBids });
4069
+ printResult(withChainNames({ ...taskResult, pendingBids }));
3814
4070
  });
3815
4071
 
3816
4072
  // src/commands/actions.ts
@@ -3830,7 +4086,94 @@ var actionsCommand = new Command52("actions").description("Show lifecycle action
3830
4086
 
3831
4087
  // src/commands/deposit.ts
3832
4088
  import { Command as Command53 } from "commander";
3833
- var depositCommand = new Command53("deposit").description("Show wallet address and network info for funding").action(async () => {
4089
+
4090
+ // src/lib/relay-bridge.ts
4091
+ import { z as z3 } from "zod";
4092
+ var RELAY_API_BASE_URL = "https://api.relay.link";
4093
+ var RelayQuoteResponseSchema = z3.object({
4094
+ requestId: z3.string().min(1),
4095
+ steps: z3.array(
4096
+ z3.object({
4097
+ depositAddress: z3.string().regex(/^0x[a-fA-F0-9]{40}$/).optional()
4098
+ })
4099
+ ).optional(),
4100
+ details: z3.object({
4101
+ currencyOut: z3.object({
4102
+ amount: z3.string().regex(/^[0-9]+$/).optional()
4103
+ }).optional()
4104
+ }).optional()
4105
+ });
4106
+ async function requestRelayBridgeDepositAddress(request, fetchImpl = fetch) {
4107
+ const route = relayBridgeRoute(request.routeId);
4108
+ const res = await fetchImpl(`${RELAY_API_BASE_URL}/quote`, {
4109
+ method: "POST",
4110
+ headers: { "Content-Type": "application/json" },
4111
+ body: JSON.stringify({
4112
+ user: request.recipient,
4113
+ recipient: request.recipient,
4114
+ originChainId: route.origin.chainId,
4115
+ originCurrency: route.origin.currency,
4116
+ destinationChainId: route.destination.chainId,
4117
+ destinationCurrency: route.destination.currency,
4118
+ amount: request.amountBaseUnits,
4119
+ tradeType: "EXACT_INPUT",
4120
+ useDepositAddress: true
4121
+ })
4122
+ });
4123
+ if (!res.ok) {
4124
+ throw new Error(`Relay quote request failed: ${res.status}`);
4125
+ }
4126
+ const parsed = RelayQuoteResponseSchema.safeParse(await res.json());
4127
+ const depositAddress = parsed.success ? parsed.data.steps?.[0]?.depositAddress : void 0;
4128
+ const quotedOut = parsed.success ? parsed.data.details?.currencyOut?.amount : void 0;
4129
+ if (!parsed.success || !depositAddress || !quotedOut) {
4130
+ throw new Error("Relay quote response missing or malformed requestId/depositAddress/amount");
4131
+ }
4132
+ return {
4133
+ requestId: parsed.data.requestId,
4134
+ depositAddress,
4135
+ amountInBaseUnits: request.amountBaseUnits,
4136
+ quotedOutBaseUnits: quotedOut
4137
+ };
4138
+ }
4139
+
4140
+ // src/commands/deposit.ts
4141
+ async function fundingOptionsFor(chainId) {
4142
+ const [cctpRaw, relayRaw] = await Promise.all([
4143
+ apiGet("/api/wallet/cross-chain-funding-config").catch(() => null),
4144
+ apiGet("/api/wallet/relay-bridge-funding-config").catch(() => null)
4145
+ ]);
4146
+ const cctp = CrossChainFundingConfigOutputSchema.safeParse(cctpRaw);
4147
+ const relay = RelayBridgeFundingConfigOutputSchema.safeParse(relayRaw);
4148
+ return {
4149
+ cctp: cctp.success && cctp.data.enabled && cctp.data.destination.chainId === chainId && cctp.data.sourceChains.length > 0 ? {
4150
+ environment: cctp.data.environment,
4151
+ destinationChainId: cctp.data.destination.chainId,
4152
+ sourceChains: cctp.data.sourceChains
4153
+ } : null,
4154
+ relayRoutes: relay.success ? relay.data.routes.map((id) => RELAY_BRIDGE_ROUTES[id]).filter((route) => route.destination.chainId === chainId).map((route) => ({
4155
+ routeId: route.id,
4156
+ from: {
4157
+ chainId: route.origin.chainId,
4158
+ chainName: route.origin.chainName,
4159
+ symbol: route.origin.symbol,
4160
+ currency: route.origin.currency
4161
+ },
4162
+ to: {
4163
+ chainId: route.destination.chainId,
4164
+ chainName: route.destination.chainName,
4165
+ symbol: route.destination.symbol
4166
+ }
4167
+ })) : [],
4168
+ note: "Run `taskmarket deposit --relay-route <routeId> --amount <n>` for a Relay deposit address. Fiat funding: see issue #2720."
4169
+ };
4170
+ }
4171
+ var depositCommand = new Command53("deposit").description(
4172
+ "Show wallet address, network info and cross-chain funding options for the selected --network"
4173
+ ).option(
4174
+ "--relay-route <routeId>",
4175
+ "Request a Relay deposit address for this wallet on an offered route (see fundingOptions.relayRoutes)"
4176
+ ).option("--amount <amount>", "Amount of the route origin stablecoin to send, for --relay-route").action(async (opts) => {
3834
4177
  let address;
3835
4178
  try {
3836
4179
  address = await getWalletAddress();
@@ -3870,7 +4213,48 @@ var depositCommand = new Command53("deposit").description("Show wallet address a
3870
4213
  /** Kept for scripts that read it; the same address as `tokenAddress`. */
3871
4214
  usdcContract: tokenAddress
3872
4215
  };
3873
- printResult(data);
4216
+ const fundingOptions = await fundingOptionsFor(chainId);
4217
+ if (opts.relayRoute === void 0) {
4218
+ if (opts.amount !== void 0) {
4219
+ renderFailure(new Error("--amount needs --relay-route"));
4220
+ return;
4221
+ }
4222
+ printResult({ ...data, fundingOptions });
4223
+ return;
4224
+ }
4225
+ try {
4226
+ const routeId = RelayBridgeRouteIdSchema.parse(opts.relayRoute);
4227
+ if (!fundingOptions.relayRoutes.some((route2) => route2.routeId === routeId)) {
4228
+ throw new Error(
4229
+ `Relay route ${routeId} is not offered for ${chain.networkName}; offered: ${fundingOptions.relayRoutes.map((route2) => route2.routeId).join(", ") || "none"}`
4230
+ );
4231
+ }
4232
+ if (opts.amount === void 0) throw new Error("--relay-route needs --amount");
4233
+ let amountBaseUnits;
4234
+ try {
4235
+ amountBaseUnits = usdcToBaseUnits(opts.amount).toString();
4236
+ } catch {
4237
+ throw new Error("Enter a valid amount.");
4238
+ }
4239
+ if (BigInt(amountBaseUnits) <= 0n) throw new Error("Enter a valid amount.");
4240
+ const deposit = await requestRelayBridgeDepositAddress({
4241
+ routeId,
4242
+ recipient: address,
4243
+ amountBaseUnits
4244
+ });
4245
+ const route = RELAY_BRIDGE_ROUTES[routeId];
4246
+ printResult({
4247
+ ...data,
4248
+ relayDeposit: {
4249
+ routeId,
4250
+ ...deposit,
4251
+ send: `${opts.amount} ${route.origin.symbol} on ${route.origin.chainName} to ${deposit.depositAddress}`,
4252
+ credits: `${route.destination.symbol} on ${route.destination.chainName} to ${address}`
4253
+ }
4254
+ });
4255
+ } catch (err) {
4256
+ renderFailure(err);
4257
+ }
3874
4258
  });
3875
4259
 
3876
4260
  // src/commands/wallet/index.ts
@@ -3878,14 +4262,58 @@ import { Command as Command64 } from "commander";
3878
4262
 
3879
4263
  // src/commands/wallet/balance.ts
3880
4264
  import { Command as Command54 } from "commander";
3881
- var walletBalanceCommand = new Command54("balance").description("Show the wallet's payment-token balance on the selected network").option("--address <addr>", "Address to check (defaults to own wallet)").action(async (opts) => {
4265
+ function balancePath(address, chainId) {
4266
+ return `/api/wallet/balance?address=${address}&chainId=${chainId}`;
4267
+ }
4268
+ async function allChainBalances(address) {
4269
+ const raw = await apiGet("/trpc/network.info");
4270
+ const info = NetworkInfoSchema.safeParse(raw?.result?.data);
4271
+ if (!info.success) {
4272
+ throw new Error(
4273
+ "The API returned network info this CLI cannot read; upgrade the CLI or the API."
4274
+ );
4275
+ }
4276
+ const chains = await Promise.all(
4277
+ info.data.chains.map(async (chain) => {
4278
+ const base = {
4279
+ chainId: chain.chainId,
4280
+ networkName: chain.networkName,
4281
+ tokenSymbol: chain.tokenSymbol
4282
+ };
4283
+ try {
4284
+ const result = await apiGet(balancePath(address, chain.chainId));
4285
+ return {
4286
+ ...base,
4287
+ tokenSymbol: result.tokenSymbol ?? chain.tokenSymbol,
4288
+ balanceBaseUnits: result.balanceBaseUnits,
4289
+ balanceUsdc: result.balanceUsdc
4290
+ };
4291
+ } catch (err) {
4292
+ return { ...base, error: err instanceof Error ? err.message : String(err) };
4293
+ }
4294
+ })
4295
+ );
4296
+ return { address, chains };
4297
+ }
4298
+ var walletBalanceCommand = new Command54("balance").description("Show the wallet's payment-token balance on the selected network").option("--address <addr>", "Address to check (defaults to own wallet)").option(
4299
+ "--all-chains",
4300
+ "Show the balance on every chain the selected deployment serves, one entry per chain"
4301
+ ).action(async (opts) => {
3882
4302
  let address = opts.address;
3883
4303
  if (!address) {
3884
4304
  const keystore = await loadKeystore();
3885
4305
  address = keystore.walletAddress;
3886
4306
  }
4307
+ if (opts.allChains) {
4308
+ try {
4309
+ printResult(await allChainBalances(address));
4310
+ } catch (err) {
4311
+ renderFailure(err, { fallback: "Failed to fetch network info from backend." });
4312
+ }
4313
+ return;
4314
+ }
3887
4315
  const result = await apiGet(
3888
- `/api/wallet/balance?address=${address}&chainId=${selectedNetwork().chainId}`
4316
+ balancePath(address, selectedNetwork().chainId)
3889
4317
  );
3890
4318
  printResult(result);
3891
4319
  });
@@ -3930,6 +4358,7 @@ var walletImportCommand = new Command55("import").description("Import an existin
3930
4358
  "--yes",
3931
4359
  "Confirm legal acceptance non-interactively after reviewing every current policy"
3932
4360
  ).action(async (opts) => {
4361
+ selectedNetwork();
3933
4362
  if (await keystoreExists()) {
3934
4363
  const keystore = await loadKeystore();
3935
4364
  printResult({
@@ -6350,8 +6779,8 @@ var browseCommand = new Command79("browse").description(
6350
6779
  printError("--offset must be a whole number");
6351
6780
  return;
6352
6781
  }
6353
- const query2 = opts.query?.trim();
6354
- if (query2 !== void 0 && (query2.length === 0 || query2.length > 200)) {
6782
+ const query3 = opts.query?.trim();
6783
+ if (query3 !== void 0 && (query3.length === 0 || query3.length > 200)) {
6355
6784
  printError("--query must be 1 to 200 characters");
6356
6785
  return;
6357
6786
  }
@@ -6361,7 +6790,7 @@ var browseCommand = new Command79("browse").description(
6361
6790
  offset: String(offset)
6362
6791
  });
6363
6792
  if (opts.status) params.set("status", opts.status);
6364
- if (query2) params.set("query", query2);
6793
+ if (query3) params.set("query", query3);
6365
6794
  try {
6366
6795
  printResult(await apiGet(`/api/bug-tracker?${params.toString()}`));
6367
6796
  } catch (error) {
@@ -6725,12 +7154,173 @@ bugCommand.addCommand(meTooCommand);
6725
7154
  bugCommand.addCommand(commentCommand);
6726
7155
  bugCommand.addCommand(visibilityCommand);
6727
7156
 
6728
- // src/commands/requester/index.ts
7157
+ // src/commands/bookmark/index.ts
6729
7158
  import { Command as Command89 } from "commander";
6730
7159
 
6731
- // src/commands/requester/stats.ts
7160
+ // src/commands/bookmark/auth.ts
7161
+ async function bookmarkAuth(action) {
7162
+ const auth = await signReadAuth();
7163
+ if (!auth || Object.keys(auth.headers).length === 0) {
7164
+ printError(`${action} needs a wallet. Run \`taskmarket init\` first.`);
7165
+ return null;
7166
+ }
7167
+ return auth;
7168
+ }
7169
+
7170
+ // src/commands/bookmark/collection.ts
6732
7171
  import { Command as Command88 } from "commander";
6733
- var requesterStatsCmd = new Command88("stats").description("Get requester reputation stats for an address").argument("<address>", "Wallet address of the requester").action(async (address) => {
7172
+ var createCommand = new Command88("create").description("Create a private collection").argument("<name>", "Collection name, up to 120 characters").action(async (name) => {
7173
+ const trimmed = name.trim();
7174
+ if (trimmed.length === 0 || trimmed.length > 120) {
7175
+ printError("Collection name must be 1 to 120 characters");
7176
+ return;
7177
+ }
7178
+ const auth = await bookmarkAuth("Creating a collection");
7179
+ if (!auth) return;
7180
+ try {
7181
+ const { data, idempotencyKey } = await apiPost(
7182
+ "/api/bookmarks/collections",
7183
+ { name: trimmed },
7184
+ { headers: auth.headers }
7185
+ );
7186
+ printResult(data, { idempotencyKey });
7187
+ } catch (error) {
7188
+ return renderFailure(error);
7189
+ }
7190
+ });
7191
+ var listCommand2 = new Command88("list").description("List your collections; a published one carries its publishedSlug (/c/<slug>)").action(async () => {
7192
+ const auth = await bookmarkAuth("Listing collections");
7193
+ if (!auth) return;
7194
+ try {
7195
+ printResult(await apiGet("/api/bookmarks/collections", { headers: auth.headers }));
7196
+ } catch (error) {
7197
+ return renderFailure(error);
7198
+ }
7199
+ });
7200
+ function publishToggle(name, description, action) {
7201
+ return new Command88(name).description(description).argument("<collection-id>", "Collection id (from `taskmarket bookmark collection list`)").action(async (collectionId) => {
7202
+ const auth = await bookmarkAuth(action);
7203
+ if (!auth) return;
7204
+ try {
7205
+ const { data, idempotencyKey } = await apiPost(
7206
+ `/api/bookmarks/collections/${encodeURIComponent(collectionId)}/${name}`,
7207
+ {},
7208
+ { headers: auth.headers }
7209
+ );
7210
+ printResult(data, { idempotencyKey });
7211
+ } catch (error) {
7212
+ return renderFailure(error);
7213
+ }
7214
+ });
7215
+ }
7216
+ var collectionCommand = new Command88("collection").description(
7217
+ "Create, list, publish and unpublish bookmark collections"
7218
+ );
7219
+ collectionCommand.addCommand(createCommand);
7220
+ collectionCommand.addCommand(listCommand2);
7221
+ collectionCommand.addCommand(
7222
+ publishToggle(
7223
+ "publish",
7224
+ "Publish a collection at a random /c/<slug> link; viewers see only what they may see",
7225
+ "Publishing a collection"
7226
+ )
7227
+ );
7228
+ collectionCommand.addCommand(
7229
+ publishToggle(
7230
+ "unpublish",
7231
+ "Unpublish a collection; its link stops working and is never reissued",
7232
+ "Unpublishing a collection"
7233
+ )
7234
+ );
7235
+
7236
+ // src/commands/bookmark/index.ts
7237
+ var ENTITY_TYPES = ["task", "submission", "agent"];
7238
+ function parseEntityType(value, flag) {
7239
+ if (value === void 0) return null;
7240
+ if (ENTITY_TYPES.includes(value)) return value;
7241
+ printError(`${flag} must be one of ${ENTITY_TYPES.join(", ")}`);
7242
+ return null;
7243
+ }
7244
+ function chainFor(entityType) {
7245
+ return entityType === "agent" ? { chainId: selectedNetwork().chainId } : {};
7246
+ }
7247
+ var addCommand = new Command89("add").description(
7248
+ "Bookmark a task, submission or agent; an agent is saved on the selected network (--network)"
7249
+ ).argument("<type>", `What to bookmark: ${ENTITY_TYPES.join(", ")}`).argument("<id>", "Task id, submission id or agent id").option("--collection <id>", "Save it to one of your collections (moves an existing bookmark)").option("--note <text>", "A private note, up to 500 characters").action(async (type, id, opts) => {
7250
+ const entityType = parseEntityType(type, "<type>");
7251
+ if (!entityType) return;
7252
+ if (opts.note !== void 0 && opts.note.length > 500) {
7253
+ printError("--note must be at most 500 characters");
7254
+ return;
7255
+ }
7256
+ const auth = await bookmarkAuth("Bookmarking");
7257
+ if (!auth) return;
7258
+ try {
7259
+ const { data, idempotencyKey } = await apiPost(
7260
+ "/api/bookmarks",
7261
+ {
7262
+ entityType,
7263
+ entityId: id,
7264
+ ...chainFor(entityType),
7265
+ ...opts.collection !== void 0 ? { collectionId: opts.collection } : {},
7266
+ ...opts.note !== void 0 ? { note: opts.note } : {}
7267
+ },
7268
+ { headers: auth.headers }
7269
+ );
7270
+ printResult(data, { idempotencyKey });
7271
+ } catch (error) {
7272
+ return renderFailure(error);
7273
+ }
7274
+ });
7275
+ var removeCommand = new Command89("remove").description("Remove a bookmark; an agent bookmark is matched on the selected network").argument("<type>", `What was bookmarked: ${ENTITY_TYPES.join(", ")}`).argument("<id>", "Task id, submission id or agent id").action(async (type, id) => {
7276
+ const entityType = parseEntityType(type, "<type>");
7277
+ if (!entityType) return;
7278
+ const auth = await bookmarkAuth("Removing a bookmark");
7279
+ if (!auth) return;
7280
+ try {
7281
+ const { data, idempotencyKey } = await apiPost(
7282
+ "/api/bookmarks/remove",
7283
+ { entityType, entityId: id, ...chainFor(entityType) },
7284
+ { headers: auth.headers }
7285
+ );
7286
+ printResult(data, { idempotencyKey });
7287
+ } catch (error) {
7288
+ return renderFailure(error);
7289
+ }
7290
+ });
7291
+ var listCommand3 = new Command89("list").description("List your bookmarks, newest first; agent entries carry their chainId").option("--type <type>", `Only one kind: ${ENTITY_TYPES.join(", ")}`).option("--collection <id>", "Only bookmarks in this collection").option("--limit <n>", "Maximum bookmarks to return (1-100)", "50").action(async (opts) => {
7292
+ const entityType = opts.type === void 0 ? void 0 : parseEntityType(opts.type, "--type");
7293
+ if (entityType === null) return;
7294
+ const limit = Number(opts.limit);
7295
+ if (!Number.isInteger(limit) || limit < 1 || limit > 100) {
7296
+ printError("--limit must be an integer from 1 to 100");
7297
+ return;
7298
+ }
7299
+ const auth = await bookmarkAuth("Listing bookmarks");
7300
+ if (!auth) return;
7301
+ const params = new URLSearchParams({ limit: String(limit) });
7302
+ if (entityType) params.set("entityType", entityType);
7303
+ if (opts.collection) params.set("collectionId", opts.collection);
7304
+ try {
7305
+ printResult(await apiGet(`/api/bookmarks?${params.toString()}`, { headers: auth.headers }));
7306
+ } catch (error) {
7307
+ return renderFailure(error);
7308
+ }
7309
+ });
7310
+ var bookmarkCommand = new Command89("bookmark").description(
7311
+ "Save tasks, submissions and agents to your private list, and share collections of them"
7312
+ );
7313
+ bookmarkCommand.addCommand(addCommand);
7314
+ bookmarkCommand.addCommand(removeCommand);
7315
+ bookmarkCommand.addCommand(listCommand3);
7316
+ bookmarkCommand.addCommand(collectionCommand);
7317
+
7318
+ // src/commands/requester/index.ts
7319
+ import { Command as Command91 } from "commander";
7320
+
7321
+ // src/commands/requester/stats.ts
7322
+ import { Command as Command90 } from "commander";
7323
+ var requesterStatsCmd = new Command90("stats").description("Get requester reputation stats for an address").argument("<address>", "Wallet address of the requester").action(async (address) => {
6734
7324
  if (!/^0x[0-9a-fA-F]{40}$/.test(address)) {
6735
7325
  printError("Address must be a 0x-prefixed 20-byte hex string");
6736
7326
  return;
@@ -6744,13 +7334,13 @@ var requesterStatsCmd = new Command88("stats").description("Get requester reputa
6744
7334
  });
6745
7335
 
6746
7336
  // src/commands/requester/index.ts
6747
- var requesterCmd = new Command89("requester").description("Requester reputation commands").addCommand(requesterStatsCmd);
7337
+ var requesterCmd = new Command91("requester").description("Requester reputation commands").addCommand(requesterStatsCmd);
6748
7338
 
6749
7339
  // src/commands/x402/index.ts
6750
- import { Command as Command93 } from "commander";
7340
+ import { Command as Command95 } from "commander";
6751
7341
 
6752
7342
  // src/commands/x402/payments.ts
6753
- import { Command as Command90, Option as Option4 } from "commander";
7343
+ import { Command as Command92, Option as Option4 } from "commander";
6754
7344
  import { createInterface as createInterface5 } from "readline";
6755
7345
  var PAYMENT_STATES = [
6756
7346
  "reserved",
@@ -6776,7 +7366,7 @@ async function confirmManualResolution() {
6776
7366
  readline.close();
6777
7367
  return answer.trim().toLowerCase() === "resolve";
6778
7368
  }
6779
- var x402PaymentsCommand = new Command90("payments").description(
7369
+ var x402PaymentsCommand = new Command92("payments").description(
6780
7370
  "Inspect and reconcile X402 Pay payment records"
6781
7371
  );
6782
7372
  x402PaymentsCommand.command("list").description("List current payment records").addOption(new Option4("--state <state>", "Filter by state").choices(PAYMENT_STATES)).action(async (options) => {
@@ -6805,7 +7395,7 @@ x402PaymentsCommand.command("resolve").description("Manually record an externall
6805
7395
 
6806
7396
  // src/commands/x402/policy.ts
6807
7397
  import { promises as fs4 } from "fs";
6808
- import { Command as Command91 } from "commander";
7398
+ import { Command as Command93 } from "commander";
6809
7399
  import { createInterface as createInterface6 } from "readline";
6810
7400
  async function confirmUnattendedRule(rule) {
6811
7401
  if (!process.stdin.isTTY) {
@@ -6831,7 +7421,7 @@ async function confirmUnattendedRule(rule) {
6831
7421
  readline.close();
6832
7422
  return answer.trim().toLowerCase() === "authorize";
6833
7423
  }
6834
- var x402PolicyCommand = new Command91("policy").description(
7424
+ var x402PolicyCommand = new Command93("policy").description(
6835
7425
  "Manage local X402 Pay spending policy"
6836
7426
  );
6837
7427
  x402PolicyCommand.command("init").description("Create a deny-all policy file").action(async () => {
@@ -6867,14 +7457,14 @@ for (const enabled of [true, false]) {
6867
7457
  }
6868
7458
 
6869
7459
  // src/commands/x402/request.ts
6870
- import { Command as Command92, Option as Option5 } from "commander";
7460
+ import { Command as Command94, Option as Option5 } from "commander";
6871
7461
  function collect3(value, previous) {
6872
7462
  return [...previous, value];
6873
7463
  }
6874
7464
  function confirm(lines) {
6875
7465
  return confirmAtTerminal(lines, "use --non-interactive with policy");
6876
7466
  }
6877
- var x402RequestCommand = new Command92("request").description("Request and pay for a direct x402 HTTP resource (X402 Pay)").argument("<url>", "HTTPS resource URL").addOption(new Option5("--method <method>", "HTTP method").choices(["GET", "POST"]).default("GET")).option("--json <json>", "Inline JSON POST body").option("--body-file <path>", "Read JSON POST body from a file").option("--headers-file <path>", "Read request headers from an owner-only JSON file").option(
7467
+ var x402RequestCommand = new Command94("request").description("Request and pay for a direct x402 HTTP resource (X402 Pay)").argument("<url>", "HTTPS resource URL").addOption(new Option5("--method <method>", "HTTP method").choices(["GET", "POST"]).default("GET")).option("--json <json>", "Inline JSON POST body").option("--body-file <path>", "Read JSON POST body from a file").option("--headers-file <path>", "Read request headers from an owner-only JSON file").option(
6878
7468
  "--header-env <header=ENV_VAR>",
6879
7469
  "Read one request header from an environment variable (repeatable)",
6880
7470
  collect3,
@@ -6922,7 +7512,7 @@ var x402RequestCommand = new Command92("request").description("Request and pay f
6922
7512
  );
6923
7513
 
6924
7514
  // src/commands/x402/index.ts
6925
- var x402Command = new Command93("x402").description(
7515
+ var x402Command = new Command95("x402").description(
6926
7516
  "Pay x402 services with local spending policies (X402 Pay)"
6927
7517
  );
6928
7518
  x402Command.addCommand(x402RequestCommand);
@@ -6930,10 +7520,10 @@ x402Command.addCommand(x402PolicyCommand);
6930
7520
  x402Command.addCommand(x402PaymentsCommand);
6931
7521
 
6932
7522
  // src/commands/sponsored-task/index.ts
6933
- import { Command as Command108 } from "commander";
7523
+ import { Command as Command110 } from "commander";
6934
7524
 
6935
7525
  // src/commands/sponsored-task/create.ts
6936
- import { Command as Command94 } from "commander";
7526
+ import { Command as Command96 } from "commander";
6937
7527
  import { toHex as toHex4 } from "viem";
6938
7528
 
6939
7529
  // ../../packages/contracts/abi/generated/SponsoredTasksVault.ts
@@ -10155,7 +10745,7 @@ async function approveSponsoredTaskSpend(input) {
10155
10745
  function isValidAddress4(addr) {
10156
10746
  return /^0x[a-fA-F0-9]{40}$/.test(addr);
10157
10747
  }
10158
- var sponsoredTaskCreateCommand = new Command94("create").description("Create a new Sponsored Task vault for a project token").requiredOption("--factory <address>", "SponsoredTaskFactory contract address").requiredOption("--chain-id <id>", "Chain id the factory is deployed on").requiredOption("--token <address>", "Project ERC-20 token address to fund the vault with").option("--owner <address>", "Vault owner (defaults to your own wallet)").action(async (opts) => {
10748
+ var sponsoredTaskCreateCommand = new Command96("create").description("Create a new Sponsored Task vault for a project token").requiredOption("--factory <address>", "SponsoredTaskFactory contract address").requiredOption("--chain-id <id>", "Chain id the factory is deployed on").requiredOption("--token <address>", "Project ERC-20 token address to fund the vault with").option("--owner <address>", "Vault owner (defaults to your own wallet)").action(async (opts) => {
10159
10749
  if (!isValidAddress4(opts.factory) || !isValidAddress4(opts.token)) {
10160
10750
  printError("Invalid Ethereum address for --factory or --token");
10161
10751
  return;
@@ -10192,11 +10782,11 @@ var sponsoredTaskCreateCommand = new Command94("create").description("Create a n
10192
10782
  });
10193
10783
 
10194
10784
  // src/commands/sponsored-task/fund.ts
10195
- import { Command as Command95 } from "commander";
10785
+ import { Command as Command97 } from "commander";
10196
10786
  function isValidAddress5(addr) {
10197
10787
  return /^0x[a-fA-F0-9]{40}$/.test(addr);
10198
10788
  }
10199
- var sponsoredTaskFundCommand = new Command95("fund").description("Fund a Sponsored Task vault with its project token (base units)").requiredOption("--vault <address>", "Vault address").requiredOption("--token <address>", "Project ERC-20 token address").requiredOption("--chain-id <id>", "Chain id the vault is deployed on").requiredOption("--amount <baseUnits>", "Amount to fund, in the token base units").action(async (opts) => {
10789
+ var sponsoredTaskFundCommand = new Command97("fund").description("Fund a Sponsored Task vault with its project token (base units)").requiredOption("--vault <address>", "Vault address").requiredOption("--token <address>", "Project ERC-20 token address").requiredOption("--chain-id <id>", "Chain id the vault is deployed on").requiredOption("--amount <baseUnits>", "Amount to fund, in the token base units").action(async (opts) => {
10200
10790
  if (!isValidAddress5(opts.vault) || !isValidAddress5(opts.token)) {
10201
10791
  printError("Invalid Ethereum address for --vault or --token");
10202
10792
  return;
@@ -10235,7 +10825,7 @@ var sponsoredTaskFundCommand = new Command95("fund").description("Fund a Sponsor
10235
10825
  });
10236
10826
 
10237
10827
  // src/commands/sponsored-task/managers.ts
10238
- import { Command as Command96 } from "commander";
10828
+ import { Command as Command98 } from "commander";
10239
10829
  function isValidAddress6(addr) {
10240
10830
  return /^0x[a-fA-F0-9]{40}$/.test(addr);
10241
10831
  }
@@ -10281,7 +10871,7 @@ async function configure(opts) {
10281
10871
  });
10282
10872
  printResult({ txHash, manager: opts.manager, spendCap: cap.toString(), active: opts.active });
10283
10873
  }
10284
- var sponsoredTaskManagersCommand = new Command96("managers").description(
10874
+ var sponsoredTaskManagersCommand = new Command98("managers").description(
10285
10875
  "Manage authorized managers for a Sponsored Task vault"
10286
10876
  );
10287
10877
  sponsoredTaskManagersCommand.command("add").description("Authorize a manager with a token-denominated spend cap").requiredOption("--vault <address>", "Vault address").requiredOption("--chain-id <id>", "Chain id the vault is deployed on").requiredOption("--manager <address>", "Manager address to authorize").requiredOption("--cap <baseUnits>", "Spend cap, in the project token base units").action((opts) => configure({ ...opts, active: true }));
@@ -10292,8 +10882,8 @@ sponsoredTaskManagersCommand.command("list").description("List a vault authorize
10292
10882
  });
10293
10883
 
10294
10884
  // src/commands/sponsored-task/managed.ts
10295
- import { Command as Command97 } from "commander";
10296
- var sponsoredTaskManagedCommand = new Command97("managed").description(
10885
+ import { Command as Command99 } from "commander";
10886
+ var sponsoredTaskManagedCommand = new Command99("managed").description(
10297
10887
  "List the active Sponsored Task vaults an address can fund tasks from as an active manager (defaults to your wallet)"
10298
10888
  ).option("--address <address>", "Manager address (defaults to your wallet)").option("--limit <n>", "Max vaults to return (1-100)", "50").option("--cursor <vaultId>", "Pagination cursor from a previous nextCursor").action(async (opts) => {
10299
10889
  let address = opts.address;
@@ -10323,7 +10913,7 @@ var sponsoredTaskManagedCommand = new Command97("managed").description(
10323
10913
  });
10324
10914
 
10325
10915
  // src/commands/sponsored-task/fee-bank.ts
10326
- import { Command as Command98 } from "commander";
10916
+ import { Command as Command100 } from "commander";
10327
10917
  function isValidAddress7(addr) {
10328
10918
  return /^0x[a-fA-F0-9]{40}$/.test(addr);
10329
10919
  }
@@ -10335,7 +10925,7 @@ async function requireKeystore2() {
10335
10925
  return null;
10336
10926
  }
10337
10927
  }
10338
- var sponsoredTaskFeeBankCommand = new Command98("fee-bank").description(
10928
+ var sponsoredTaskFeeBankCommand = new Command100("fee-bank").description(
10339
10929
  "Manage a manager USDC credit balance, charged by the Sponsored Task hook at task creation"
10340
10930
  );
10341
10931
  sponsoredTaskFeeBankCommand.command("deposit").description("Deposit USDC credit for creating sponsored tasks").requiredOption("--fee-bank <address>", "SponsoredTaskFeeBank contract address").requiredOption("--usdc <address>", "USDC token address").requiredOption("--chain-id <id>", "Chain id the fee bank is deployed on").requiredOption("--amount <baseUnits>", "Amount to deposit, in USDC base units (6 decimals)").action(async (opts) => {
@@ -10419,8 +11009,8 @@ sponsoredTaskFeeBankCommand.command("withdraw").description("Withdraw unused USD
10419
11009
  );
10420
11010
 
10421
11011
  // src/commands/sponsored-task/list.ts
10422
- import { Command as Command99 } from "commander";
10423
- var sponsoredTaskListCommand = new Command99("list").description("List Sponsored Task vaults").option("--limit <n>", "Max vaults to return", "50").option("--cursor <vaultId>", "Pagination cursor").option("--include-unverified", "Include vaults not yet curator-approved", false).action(async (opts) => {
11012
+ import { Command as Command101 } from "commander";
11013
+ var sponsoredTaskListCommand = new Command101("list").description("List Sponsored Task vaults").option("--limit <n>", "Max vaults to return", "50").option("--cursor <vaultId>", "Pagination cursor").option("--include-unverified", "Include vaults not yet curator-approved", false).action(async (opts) => {
10424
11014
  const params = new URLSearchParams({ limit: opts.limit });
10425
11015
  if (opts.cursor) params.set("cursor", opts.cursor);
10426
11016
  if (opts.includeUnverified) params.set("includeUnverified", "true");
@@ -10429,8 +11019,8 @@ var sponsoredTaskListCommand = new Command99("list").description("List Sponsored
10429
11019
  });
10430
11020
 
10431
11021
  // src/commands/sponsored-task/settlements.ts
10432
- import { Command as Command100 } from "commander";
10433
- var sponsoredTaskSettlementsCommand = new Command100("settlements").description("List the settlements a Sponsored Task vault has installed, newest first").argument("<vaultId>", "Vault id").option("--limit <n>", "Max settlements to return (1-100)", "25").option("--cursor <cursor>", "Pagination cursor from a previous nextCursor").action(async (vaultId, opts) => {
11022
+ import { Command as Command102 } from "commander";
11023
+ var sponsoredTaskSettlementsCommand = new Command102("settlements").description("List the settlements a Sponsored Task vault has installed, newest first").argument("<vaultId>", "Vault id").option("--limit <n>", "Max settlements to return (1-100)", "25").option("--cursor <cursor>", "Pagination cursor from a previous nextCursor").action(async (vaultId, opts) => {
10434
11024
  const limit = Number(opts.limit);
10435
11025
  if (!Number.isInteger(limit) || limit < 1 || limit > 100) {
10436
11026
  printError("--limit must be an integer from 1 to 100");
@@ -10441,21 +11031,21 @@ var sponsoredTaskSettlementsCommand = new Command100("settlements").description(
10441
11031
  const result = await apiGet(
10442
11032
  `/api/sponsored-task-vaults/${vaultId}/settlements?${params.toString()}`
10443
11033
  );
10444
- printResult(result);
11034
+ printResult(withChainNames(result));
10445
11035
  });
10446
11036
 
10447
11037
  // src/commands/sponsored-task/show.ts
10448
- import { Command as Command101 } from "commander";
10449
- var sponsoredTaskShowCommand = new Command101("show").description("Show a Sponsored Task vault by id").argument("<vaultId>", "Vault id").action(async (vaultId) => {
11038
+ import { Command as Command103 } from "commander";
11039
+ var sponsoredTaskShowCommand = new Command103("show").description("Show a Sponsored Task vault by id").argument("<vaultId>", "Vault id").action(async (vaultId) => {
10450
11040
  const result = await apiGet(`/api/sponsored-task-vaults/${vaultId}`);
10451
11041
  printResult(result);
10452
11042
  });
10453
11043
 
10454
11044
  // src/commands/sponsored-task/request-review.ts
10455
11045
  import { randomBytes as randomBytes3 } from "crypto";
10456
- import { Command as Command102 } from "commander";
11046
+ import { Command as Command104 } from "commander";
10457
11047
  var REQUEST_TTL_SECONDS = 5 * 60;
10458
- var sponsoredTaskRequestReviewCommand = new Command102("request-review").description("Ask Taskmarket curators to review a Sponsored Task vault (vault owner only)").argument("<vaultId>", "Vault id").action(async (vaultId) => {
11048
+ var sponsoredTaskRequestReviewCommand = new Command104("request-review").description("Ask Taskmarket curators to review a Sponsored Task vault (vault owner only)").argument("<vaultId>", "Vault id").action(async (vaultId) => {
10459
11049
  let keystore;
10460
11050
  try {
10461
11051
  keystore = await loadKeystore();
@@ -10512,18 +11102,18 @@ var sponsoredTaskRequestReviewCommand = new Command102("request-review").descrip
10512
11102
  });
10513
11103
 
10514
11104
  // src/commands/sponsored-task/balance.ts
10515
- import { Command as Command103 } from "commander";
10516
- var sponsoredTaskBalanceCommand = new Command103("balance").description("Show a Sponsored Task vault funded/available/reserved balances").argument("<vaultId>", "Vault id").action(async (vaultId) => {
11105
+ import { Command as Command105 } from "commander";
11106
+ var sponsoredTaskBalanceCommand = new Command105("balance").description("Show a Sponsored Task vault funded/available/reserved balances").argument("<vaultId>", "Vault id").action(async (vaultId) => {
10517
11107
  const result = await apiGet(`/api/sponsored-task-vaults/${vaultId}/balance`);
10518
11108
  printResult(result);
10519
11109
  });
10520
11110
 
10521
11111
  // src/commands/sponsored-task/withdraw.ts
10522
- import { Command as Command104 } from "commander";
11112
+ import { Command as Command106 } from "commander";
10523
11113
  function isValidAddress8(addr) {
10524
11114
  return /^0x[a-fA-F0-9]{40}$/.test(addr);
10525
11115
  }
10526
- var sponsoredTaskWithdrawCommand = new Command104("withdraw").description("Withdraw unreserved project tokens from a vault (owner only)").requiredOption("--vault <address>", "Vault address").requiredOption("--chain-id <id>", "Chain id the vault is deployed on").requiredOption("--amount <baseUnits>", "Amount to withdraw, in the project token base units").option("--recipient <address>", "Recipient (defaults to your own wallet)").action(async (opts) => {
11116
+ var sponsoredTaskWithdrawCommand = new Command106("withdraw").description("Withdraw unreserved project tokens from a vault (owner only)").requiredOption("--vault <address>", "Vault address").requiredOption("--chain-id <id>", "Chain id the vault is deployed on").requiredOption("--amount <baseUnits>", "Amount to withdraw, in the project token base units").option("--recipient <address>", "Recipient (defaults to your own wallet)").action(async (opts) => {
10527
11117
  if (!isValidAddress8(opts.vault) || opts.recipient && !isValidAddress8(opts.recipient)) {
10528
11118
  printError("Invalid Ethereum address for --vault or --recipient");
10529
11119
  return;
@@ -10553,11 +11143,11 @@ var sponsoredTaskWithdrawCommand = new Command104("withdraw").description("Withd
10553
11143
  });
10554
11144
 
10555
11145
  // src/commands/sponsored-task/exit.ts
10556
- import { Command as Command105 } from "commander";
11146
+ import { Command as Command107 } from "commander";
10557
11147
  function isValidAddress9(addr) {
10558
11148
  return /^0x[a-fA-F0-9]{40}$/.test(addr);
10559
11149
  }
10560
- var sponsoredTaskExitCommand = new Command105("exit").description(
11150
+ var sponsoredTaskExitCommand = new Command107("exit").description(
10561
11151
  "Terminally exit a vault: sweeps every reserved and unclaimed token back to you, invalidating every outstanding reservation, claim signature, and Merkle proof at once. There is no undo and no per-allocation revoke -- a worker with a pending but unclaimed entitlement gets nothing once this runs."
10562
11152
  ).requiredOption("--vault <address>", "Vault address").requiredOption("--chain-id <id>", "Chain id the vault is deployed on").option("--recipient <address>", "Recipient (defaults to your own wallet)").option("--yes", "Skip the confirmation prompt", false).action(async (opts) => {
10563
11153
  if (!isValidAddress9(opts.vault) || opts.recipient && !isValidAddress9(opts.recipient)) {
@@ -10593,7 +11183,7 @@ var sponsoredTaskExitCommand = new Command105("exit").description(
10593
11183
  });
10594
11184
 
10595
11185
  // src/commands/sponsored-task/claim.ts
10596
- import { Command as Command106 } from "commander";
11186
+ import { Command as Command108 } from "commander";
10597
11187
  var CLAIM_TO_TYPES = {
10598
11188
  ClaimTo: [
10599
11189
  { name: "vaultId", type: "bytes32" },
@@ -10628,7 +11218,7 @@ async function postClaimWithRetry(path3, body, options = {}) {
10628
11218
  }
10629
11219
  }
10630
11220
  }
10631
- var sponsoredTaskClaimCommand = new Command106("claim").description("Claim your unclaimed Sponsored Task reward for a vault task").argument("<vaultId>", "Vault id").option(
11221
+ var sponsoredTaskClaimCommand = new Command108("claim").description("Claim your unclaimed Sponsored Task reward for a vault task").argument("<vaultId>", "Vault id").option(
10632
11222
  "--task-id <id>",
10633
11223
  "Claim the entitlement for a specific task (defaults to the first unclaimed one)"
10634
11224
  ).action(async (vaultId, opts) => {
@@ -10720,10 +11310,10 @@ var sponsoredTaskClaimCommand = new Command106("claim").description("Claim your
10720
11310
  });
10721
11311
 
10722
11312
  // src/commands/sponsored-task/rewards.ts
10723
- import { Command as Command107 } from "commander";
11313
+ import { Command as Command109 } from "commander";
10724
11314
  var REWARD_STATES = SponsoredTaskRewardStateSchema.options;
10725
11315
  var CLAIM_STATUSES = SponsoredTaskWorkerRewardClaimStatusSchema.options;
10726
- var sponsoredTaskRewardsCommand = new Command107("rewards").description("List Sponsored Task rewards across every vault (defaults to your wallet)").option("--address <address>", "Worker address (defaults to your wallet)").option("--state <state>", `Reward state: ${REWARD_STATES.join(", ")}`).option("--claim-status <status>", `Claim status: ${CLAIM_STATUSES.join(", ")}`).option("--limit <n>", "Max rewards to return (1-100)", "50").option("--cursor <cursor>", "Pagination cursor from a previous nextCursor").action(
11316
+ var sponsoredTaskRewardsCommand = new Command109("rewards").description("List Sponsored Task rewards across every vault (defaults to your wallet)").option("--address <address>", "Worker address (defaults to your wallet)").option("--state <state>", `Reward state: ${REWARD_STATES.join(", ")}`).option("--claim-status <status>", `Claim status: ${CLAIM_STATUSES.join(", ")}`).option("--limit <n>", "Max rewards to return (1-100)", "50").option("--cursor <cursor>", "Pagination cursor from a previous nextCursor").action(
10727
11317
  async (opts) => {
10728
11318
  let address = opts.address;
10729
11319
  if (address === void 0) {
@@ -10758,12 +11348,12 @@ var sponsoredTaskRewardsCommand = new Command107("rewards").description("List Sp
10758
11348
  const result = await apiGet(
10759
11349
  `/api/sponsored-task-rewards/workers/${address.toLowerCase()}?${params.toString()}`
10760
11350
  );
10761
- printResult(result);
11351
+ printResult(withChainNames(result));
10762
11352
  }
10763
11353
  );
10764
11354
 
10765
11355
  // src/commands/sponsored-task/index.ts
10766
- var sponsoredTaskCommand = new Command108("sponsored-task").description(
11356
+ var sponsoredTaskCommand = new Command110("sponsored-task").description(
10767
11357
  "Sponsored Task vault administration and reward claims"
10768
11358
  );
10769
11359
  sponsoredTaskCommand.addCommand(sponsoredTaskCreateCommand);
@@ -10781,10 +11371,117 @@ sponsoredTaskCommand.addCommand(sponsoredTaskExitCommand);
10781
11371
  sponsoredTaskCommand.addCommand(sponsoredTaskClaimCommand);
10782
11372
  sponsoredTaskCommand.addCommand(sponsoredTaskRewardsCommand);
10783
11373
 
11374
+ // src/commands/drops.ts
11375
+ import { Command as Command111 } from "commander";
11376
+ var listCommand4 = new Command111("list").description("List public Task Drops, ones accepting work first").option("--limit <n>", "Maximum drops to return (1-48)", "24").option("--cursor <cursor>", "nextCursor from a previous page").action(async (opts) => {
11377
+ try {
11378
+ const input = parseInput(TaskDropDirectoryInputSchema, {
11379
+ limit: optionalInt(opts.limit),
11380
+ cursor: opts.cursor
11381
+ });
11382
+ const params = new URLSearchParams({ limit: String(input.limit) });
11383
+ if (input.cursor) params.set("cursor", input.cursor);
11384
+ printResult(await apiGet(`/api/task-drops/directory?${params.toString()}`));
11385
+ } catch (err) {
11386
+ renderFailure(err);
11387
+ }
11388
+ });
11389
+ var showCommand2 = new Command111("show").description("Show a Task Drop and its discoverable tasks").argument("<taskDropId>", "Task Drop ID").action(async (taskDropId) => {
11390
+ try {
11391
+ const input = parseInput(TaskDropGetInputSchema, { taskDropId });
11392
+ const result = await apiGet(`/api/task-drops/${encodeURIComponent(input.taskDropId)}`);
11393
+ if (result === null || result === void 0) {
11394
+ throw new Error(`Task Drop ${input.taskDropId} not found`);
11395
+ }
11396
+ printResult(result);
11397
+ } catch (err) {
11398
+ renderFailure(err);
11399
+ }
11400
+ });
11401
+ var subscribeCommand = new Command111("subscribe").description("Subscribe an email to one Task Drop, or with --official to every official drop").argument("[taskDropId]", "Task Drop ID (omit with --official)").requiredOption("--email <email>", "Email address to notify").option("--official", "Subscribe to all official Task Drops").option("--wallet <address>", "Wallet address to associate with the subscription").action(
11402
+ async (taskDropId, opts) => {
11403
+ try {
11404
+ if (opts.official) {
11405
+ if (taskDropId) throw new Error("Pass either a Task Drop ID or --official, not both");
11406
+ const body2 = parseInput(TaskDropOfficialSubscribeInputSchema, {
11407
+ email: opts.email,
11408
+ walletAddress: opts.wallet,
11409
+ source: "cli"
11410
+ });
11411
+ const outcome2 = await apiPost("/api/task-drops/official/subscribe", body2);
11412
+ printResult(outcome2.data, { idempotencyKey: outcome2.idempotencyKey });
11413
+ return;
11414
+ }
11415
+ if (!taskDropId) throw new Error("Pass a Task Drop ID, or --official");
11416
+ const body = parseInput(TaskDropSubscribeInputSchema, {
11417
+ taskDropId,
11418
+ email: opts.email,
11419
+ walletAddress: opts.wallet,
11420
+ source: "cli"
11421
+ });
11422
+ const outcome = await apiPost("/api/task-drops/subscribe", body);
11423
+ printResult(outcome.data, { idempotencyKey: outcome.idempotencyKey });
11424
+ } catch (err) {
11425
+ renderFailure(err);
11426
+ }
11427
+ }
11428
+ );
11429
+ var statusCommand3 = new Command111("status").description("Check whether an email is subscribed to a Task Drop, or with --official to all").argument("[taskDropId]", "Task Drop ID (omit with --official)").requiredOption("--email <email>", "Email address to check").option("--official", "Check the all-official-drops subscription").action(async (taskDropId, opts) => {
11430
+ try {
11431
+ if (opts.official) {
11432
+ if (taskDropId) throw new Error("Pass either a Task Drop ID or --official, not both");
11433
+ const input2 = parseInput(TaskDropOfficialStatusInputSchema, { email: opts.email });
11434
+ const params2 = new URLSearchParams({ email: input2.email });
11435
+ printResult(await apiGet(`/api/task-drops/official/status?${params2.toString()}`));
11436
+ return;
11437
+ }
11438
+ if (!taskDropId) throw new Error("Pass a Task Drop ID, or --official");
11439
+ const input = parseInput(TaskDropStatusInputSchema, { taskDropId, email: opts.email });
11440
+ const params = new URLSearchParams({ taskDropId: input.taskDropId, email: input.email });
11441
+ printResult(await apiGet(`/api/task-drops/status?${params.toString()}`));
11442
+ } catch (err) {
11443
+ renderFailure(err);
11444
+ }
11445
+ });
11446
+ var dropsCommand = new Command111("drops").description("Browse Task Drops and manage email subscriptions to them").addCommand(listCommand4).addCommand(showCommand2).addCommand(subscribeCommand).addCommand(statusCommand3);
11447
+
11448
+ // src/commands/hooks.ts
11449
+ import { Command as Command112 } from "commander";
11450
+ var listCommand5 = new Command112("list").description("List observed hooks and their active-phase task counts on the selected --network").option("--limit <n>", "Maximum hooks to return (1-100)", "50").action(async (opts) => {
11451
+ try {
11452
+ const input = parseInput(HookIndexInputSchema, { limit: optionalInt(opts.limit) });
11453
+ printResult(await apiGet(withChainId(`/api/hooks?limit=${input.limit}`)));
11454
+ } catch (err) {
11455
+ renderFailure(err);
11456
+ }
11457
+ });
11458
+ var showCommand3 = new Command112("show").description("Show one observed hook by address on the selected --network").argument("<address>", "Hook contract address").action(async (address) => {
11459
+ try {
11460
+ const input = parseInput(HookGetInputSchema, { address });
11461
+ const result = await apiGet(withChainId(`/api/hooks/${input.address}`));
11462
+ if (result === null || result === void 0) {
11463
+ throw new Error(`Hook ${input.address} has not been observed on this network`);
11464
+ }
11465
+ printResult(result);
11466
+ } catch (err) {
11467
+ renderFailure(err);
11468
+ }
11469
+ });
11470
+ var attachmentConfigCommand = new Command112("attachment-config").description(
11471
+ "Show the protocol-default hook order and maximum hooks per task on the selected --network"
11472
+ ).action(async () => {
11473
+ try {
11474
+ printResult(await apiGet(withChainId("/api/hooks/attachment-configuration")));
11475
+ } catch (err) {
11476
+ renderFailure(err);
11477
+ }
11478
+ });
11479
+ var hooksCommand = new Command112("hooks").description("Browse the hook registry on the selected --network").addCommand(listCommand5).addCommand(showCommand3).addCommand(attachmentConfigCommand);
11480
+
10784
11481
  // src/index.ts
10785
11482
  var require2 = createRequire(import.meta.url);
10786
11483
  var { version } = require2("../package.json");
10787
- var program = new Command109();
11484
+ var program = new Command113();
10788
11485
  setLastErrorCliVersion(version);
10789
11486
  program.name("taskmarket").description("Taskmarket CLI for AI agents").version(version);
10790
11487
  program.option(
@@ -10822,7 +11519,10 @@ program.addCommand(requesterCmd);
10822
11519
  program.addCommand(legalCommand);
10823
11520
  program.addCommand(x402Command);
10824
11521
  program.addCommand(sponsoredTaskCommand);
11522
+ program.addCommand(dropsCommand);
11523
+ program.addCommand(hooksCommand);
10825
11524
  program.addCommand(bugCommand);
11525
+ program.addCommand(bookmarkCommand);
10826
11526
  void (async () => {
10827
11527
  try {
10828
11528
  await program.parseAsync(process.argv);