@lucid-agents/taskmarket 0.9.0 → 1.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.
Files changed (2) hide show
  1. package/dist/index.js +896 -149
  2. package/package.json +2 -2
package/dist/index.js CHANGED
@@ -6,7 +6,7 @@ var __export = (target, all) => {
6
6
  };
7
7
 
8
8
  // src/index.ts
9
- import { Command as Command42 } from "commander";
9
+ import { Command as Command52 } from "commander";
10
10
  import { createRequire } from "module";
11
11
 
12
12
  // src/commands/init.ts
@@ -73,7 +73,7 @@ async function keystoreExists(keystorePath) {
73
73
  }
74
74
 
75
75
  // src/lib/api.ts
76
- var API_URL = process.env.TASKMARKET_API_URL ?? "https://api-market.daydreams.systems";
76
+ var API_URL = process.env.TASKMARKET_API_URL ?? "https://api.taskmarket.dev";
77
77
  async function apiGet(path3, options) {
78
78
  const res = await fetch(`${API_URL}${path3}`, {
79
79
  method: "GET",
@@ -198,6 +198,14 @@ function decryptWithPrivateKey(fileBuffer, privateKeyHex) {
198
198
  }
199
199
 
200
200
  // src/commands/init.ts
201
+ function sanitizeEmailUsername(agentId, suffix) {
202
+ const maxBase = 30 - 1 - suffix.length;
203
+ if (maxBase < 2) return null;
204
+ const base = agentId.toLowerCase().replace(/[^a-z0-9]/g, "-").replace(/-+/g, "-").replace(/^-+|-+$/g, "").slice(0, maxBase).replace(/-+$/, "");
205
+ if (base.length < 2) return null;
206
+ const candidate = `${base}-${suffix}`;
207
+ return /^[a-z0-9][a-z0-9-]{1,28}[a-z0-9]$/.test(candidate) ? candidate : null;
208
+ }
201
209
  async function tryRegisterEmail(deviceId, apiToken, username, explicit) {
202
210
  try {
203
211
  const reg = await apiPost("/api/emails/register", {
@@ -253,7 +261,7 @@ var initCommand = new Command("init").description("Create and register a new age
253
261
  } catch {
254
262
  }
255
263
  if (!emailAddress2) {
256
- const username2 = opts.email ?? (agentId2 && networkInfo2 ? `${agentId2}-${networkInfo2.chainId}` : null);
264
+ const username2 = opts.email ?? (agentId2 && networkInfo2 ? sanitizeEmailUsername(agentId2, String(networkInfo2.chainId)) : null);
257
265
  if (username2) {
258
266
  emailAddress2 = await tryRegisterEmail(
259
267
  keystore.deviceId,
@@ -291,7 +299,14 @@ var initCommand = new Command("init").description("Create and register a new age
291
299
  } = await res.json();
292
300
  const encryptedKey = encryptPrivateKey(deviceEncryptionKey, privateKey);
293
301
  let agentId = initialAgentId;
294
- await saveKeystore({ encryptedKey, walletAddress: address, deviceId, apiToken, agentId });
302
+ await saveKeystore({
303
+ encryptedKey,
304
+ walletAddress: address,
305
+ deviceId,
306
+ apiToken,
307
+ agentId,
308
+ keyServerUrl: API_URL
309
+ });
295
310
  if (!agentId) {
296
311
  agentId = await pollAgentId(address);
297
312
  if (agentId) {
@@ -305,7 +320,7 @@ var initCommand = new Command("init").description("Create and register a new age
305
320
  networkInfo = response.result.data;
306
321
  } catch {
307
322
  }
308
- const username = opts.email ?? (agentId && networkInfo ? `${agentId}-${networkInfo.chainId}` : null);
323
+ const username = opts.email ?? (agentId && networkInfo ? sanitizeEmailUsername(agentId, String(networkInfo.chainId)) : null);
309
324
  const emailAddress = username ? await tryRegisterEmail(deviceId, apiToken, username, !!opts.email) : null;
310
325
  printResult({
311
326
  address,
@@ -329,8 +344,9 @@ import { Command as Command3 } from "commander";
329
344
  // src/lib/signer.ts
330
345
  import { privateKeyToAccount as privateKeyToAccount2 } from "viem/accounts";
331
346
  import { toHex } from "viem";
332
- async function fetchDeviceKey(deviceId, apiToken) {
333
- const res = await fetch(`${API_URL}/api/devices/${deviceId}/key`, {
347
+ async function fetchDeviceKey(deviceId, apiToken, keyServerUrl) {
348
+ const base = keyServerUrl ?? API_URL;
349
+ const res = await fetch(`${base}/api/devices/${deviceId}/key`, {
334
350
  method: "POST",
335
351
  headers: { "Content-Type": "application/json" },
336
352
  body: JSON.stringify({ deviceId, apiToken })
@@ -353,7 +369,7 @@ async function signMessage(message, keystore) {
353
369
  return sig;
354
370
  }
355
371
  async function createWalletAccountFromKeystore(keystore) {
356
- const dek = await fetchDeviceKey(keystore.deviceId, keystore.apiToken);
372
+ const dek = await fetchDeviceKey(keystore.deviceId, keystore.apiToken, keystore.keyServerUrl);
357
373
  const privateKey = decryptPrivateKey(dek, keystore.encryptedKey);
358
374
  return privateKeyToAccount2(privateKey);
359
375
  }
@@ -467,6 +483,7 @@ var statsCommand = new Command4("stats").description("View agent statistics").op
467
483
  completedTasks: result.completedTasks,
468
484
  ratedTasks: result.ratedTasks,
469
485
  averageRating: result.averageRating,
486
+ credibility: result.credibility,
470
487
  totalEarnings: result.totalEarnings,
471
488
  skills: result.skills,
472
489
  emailAddress: result.emailAddress,
@@ -475,14 +492,44 @@ var statsCommand = new Command4("stats").description("View agent statistics").op
475
492
  });
476
493
 
477
494
  // src/commands/task/index.ts
478
- import { Command as Command19 } from "commander";
495
+ import { Command as Command29 } from "commander";
479
496
 
480
497
  // src/commands/task/create.ts
481
498
  import { Command as Command5 } from "commander";
482
- var createCmd = new Command5("create").description("Create a new task (costs reward amount in USDC)").requiredOption("--description <text>", "Task description").requiredOption("--reward <usdc>", "Reward in USDC (e.g. 5 for 5 USDC)").requiredOption("--duration <hours>", "Task duration in hours").option("--mode <mode>", "Task mode: bounty, claim, pitch, benchmark, auction", "bounty").option("--tags <tags>", "Comma-separated tags").option("--pitch-deadline <hours>", "Pitch deadline in hours from now (pitch mode only)").option("--bid-deadline <hours>", "Bid deadline in hours from now (auction mode only)").option("--max-price <usdc>", "Maximum bid price in USDC (required for auction mode)").action(
499
+ var createCmd = new Command5("create").description("Create a new task (costs reward amount in USDC)").requiredOption("--description <text>", "Task description").requiredOption("--reward <usdc>", "Reward in USDC (e.g. 5 for 5 USDC)").requiredOption("--duration <hours>", "Task duration in hours").option("--mode <mode>", "Task mode: bounty, claim, pitch, benchmark, auction", "bounty").option("--tags <tags>", "Comma-separated tags").option("--pitch-deadline <hours>", "Pitch deadline in hours from now (pitch mode only)").option("--bid-deadline <hours>", "Bid deadline in hours from now (auction mode only)").option("--max-price <usdc>", "Maximum bid price in USDC (required for auction mode)").option(
500
+ "--auction-type <type>",
501
+ "Auction subtype: dutch, english, reverse_dutch, reverse_english (required for auction mode)"
502
+ ).option(
503
+ "--auction-start-price <usdc>",
504
+ "Starting clock price in USDC for reverse_dutch (required for reverse_dutch)"
505
+ ).option(
506
+ "--auction-floor-price <usdc>",
507
+ "Floor price in USDC for dutch clock (optional, defaults to 0)"
508
+ ).option("--hook <address>", "ITaskHook contract address (optional)").option(
509
+ "--hook-data <hex>",
510
+ "Hook config bytes forwarded to checkFund; encode uint32 as 4 big-endian bytes (e.g. 0x000006b4 for a 1800s TWAP window)"
511
+ ).option("--evaluator <address>", "Evaluator address (optional)").option("--evaluator-fee-bps <bps>", "Evaluator fee in basis points (optional)").option("--evaluation-window <hours>", "Evaluation window in hours (default: 24)").option("--appeal-window <hours>", "Appeal window in hours (default: 24)").option("--dispute-resolver <address>", "Dispute resolver address (optional)").action(
483
512
  async (opts) => {
484
- if (opts.mode === "auction" && !opts.maxPrice) {
485
- printError("--max-price is required for auction mode");
513
+ if (opts.mode === "auction") {
514
+ if (!opts.maxPrice) {
515
+ return void printError("--max-price is required for auction mode");
516
+ }
517
+ if (!opts.auctionType) {
518
+ return void printError(
519
+ "--auction-type is required for auction mode (dutch, english, reverse_dutch, reverse_english)"
520
+ );
521
+ }
522
+ const validTypes = ["dutch", "english", "reverse_dutch", "reverse_english"];
523
+ if (!validTypes.includes(opts.auctionType)) {
524
+ return void printError(
525
+ `--auction-type must be one of: ${validTypes.join(", ")}. Got: ${opts.auctionType}`
526
+ );
527
+ }
528
+ if (opts.auctionType === "reverse_dutch" && !opts.auctionStartPrice) {
529
+ return void printError(
530
+ "--auction-start-price is required for reverse_dutch auction type"
531
+ );
532
+ }
486
533
  }
487
534
  const rewardBaseUnits = String(Math.round(parseFloat(opts.reward) * 1e6));
488
535
  const tags = opts.tags ? opts.tags.split(",").map((t) => t.trim()) : [];
@@ -504,6 +551,52 @@ var createCmd = new Command5("create").description("Create a new task (costs rew
504
551
  if (opts.maxPrice) {
505
552
  body.maxPrice = String(Math.round(parseFloat(opts.maxPrice) * 1e6));
506
553
  }
554
+ if (opts.auctionType) {
555
+ body.auctionType = opts.auctionType;
556
+ }
557
+ if (opts.auctionStartPrice) {
558
+ body.auctionStartPrice = String(Math.round(parseFloat(opts.auctionStartPrice) * 1e6));
559
+ }
560
+ if (opts.auctionFloorPrice) {
561
+ body.auctionFloorPrice = String(Math.round(parseFloat(opts.auctionFloorPrice) * 1e6));
562
+ }
563
+ const ethAddrRe = /^0x[0-9a-fA-F]{40}$/;
564
+ if (opts.hook && !ethAddrRe.test(opts.hook)) {
565
+ return void printError("--hook must be a valid Ethereum address (0x + 40 hex chars)");
566
+ }
567
+ if (opts.hookData && !/^0x(?:[0-9a-fA-F]{2})*$/.test(opts.hookData)) {
568
+ return void printError(
569
+ "--hook-data must be a 0x-prefixed hex string with an even number of hex digits"
570
+ );
571
+ }
572
+ let feeBps;
573
+ if (opts.evaluator) {
574
+ if (!ethAddrRe.test(opts.evaluator)) {
575
+ return void printError(
576
+ "--evaluator must be a valid Ethereum address (0x + 40 hex chars)"
577
+ );
578
+ }
579
+ if (opts.evaluatorFeeBps) {
580
+ feeBps = Number(opts.evaluatorFeeBps);
581
+ if (!Number.isInteger(feeBps) || feeBps < 0 || feeBps > 1e4) {
582
+ return void printError("--evaluator-fee-bps must be an integer between 0 and 10000");
583
+ }
584
+ }
585
+ if (opts.disputeResolver && !ethAddrRe.test(opts.disputeResolver)) {
586
+ return void printError(
587
+ "--dispute-resolver must be a valid Ethereum address (0x + 40 hex chars)"
588
+ );
589
+ }
590
+ }
591
+ if (opts.hook) body.hookContract = opts.hook;
592
+ if (opts.hookData) body.hookData = opts.hookData;
593
+ if (opts.evaluator) {
594
+ body.evaluator = opts.evaluator;
595
+ if (feeBps !== void 0) body.evaluatorFeeBps = feeBps;
596
+ if (opts.evaluationWindow) body.evaluationWindowHours = parseFloat(opts.evaluationWindow);
597
+ if (opts.appealWindow) body.appealWindowHours = parseFloat(opts.appealWindow);
598
+ if (opts.disputeResolver) body.disputeResolver = opts.disputeResolver;
599
+ }
507
600
  const result = await x402Post("/api/tasks", body);
508
601
  printResult({ taskId: result.taskId });
509
602
  }
@@ -511,11 +604,15 @@ var createCmd = new Command5("create").description("Create a new task (costs rew
511
604
 
512
605
  // src/commands/task/search.ts
513
606
  import { Command as Command6 } from "commander";
514
- var listCmd = new Command6("list").alias("search").description("List available tasks").option("--status <status>", "Filter by status (e.g. open)", "open").option("--mode <mode>", "Filter by mode (bounty, claim, pitch, benchmark, auction)").option("--tags <tags>", "Comma-separated tags to filter by").option("--skill <skill>", "Filter by skill tag (comma-separated, alias for --tags)").option("--reward-min <n>", "Minimum reward in USDC").option("--reward-max <n>", "Maximum reward in USDC").option("--deadline-hours <n>", "Only tasks expiring within this many hours").option("--limit <n>", "Maximum results to return", "20").option("--cursor <cursor>", "Cursor from previous page (nextCursor in JSON output)").action(
607
+ var listCmd = new Command6("list").alias("search").description("List available tasks").option("--status <status>", "Filter by status (e.g. open)", "open").option("--mode <mode>", "Filter by mode (bounty, claim, pitch, benchmark, auction)").option(
608
+ "--auction-type <type>",
609
+ "Filter auction tasks by subtype (dutch, english, reverse_dutch, reverse_english)"
610
+ ).option("--tags <tags>", "Comma-separated tags to filter by").option("--skill <skill>", "Filter by skill tag (comma-separated, alias for --tags)").option("--reward-min <n>", "Minimum reward in USDC").option("--reward-max <n>", "Maximum reward in USDC").option("--deadline-hours <n>", "Only tasks expiring within this many hours").option("--limit <n>", "Maximum results to return", "20").option("--cursor <cursor>", "Cursor from previous page (nextCursor in JSON output)").action(
515
611
  async (opts) => {
516
612
  const params = new URLSearchParams();
517
613
  if (opts.status) params.set("status", opts.status);
518
614
  if (opts.mode) params.set("mode", opts.mode);
615
+ if (opts.auctionType) params.set("auctionType", opts.auctionType);
519
616
  const tagsValue = opts.tags ?? opts.skill;
520
617
  if (tagsValue) params.set("tags", tagsValue);
521
618
  if (opts.rewardMin)
@@ -543,48 +640,170 @@ var getCmd = new Command7("get").description("Get task details").argument("<task
543
640
  // src/commands/task/submit.ts
544
641
  import { Command as Command8 } from "commander";
545
642
  import { promises as fs2 } from "fs";
546
- var submitCmd = new Command8("submit").description("Submit work for a task").argument("<taskId>", "Task ID (0x-prefixed hex)").requiredOption("--file <path>", "Path to the submission file").action(async (taskId, opts) => {
547
- const fileContent = await fs2.readFile(opts.file);
548
- const fileBase64 = fileContent.toString("base64");
549
- const keystore = await loadKeystore();
550
- const signature = await signMessage(`taskmarket:submit:${taskId}`, keystore);
551
- const result = await apiPost(`/api/tasks/${taskId}/submissions`, {
552
- workerAddress: keystore.walletAddress,
553
- file: fileBase64,
554
- signature
555
- });
556
- printResult({ submissionId: result.submissionId });
643
+ import { basename, extname } from "path";
644
+ function collectFile(value, previous) {
645
+ return [...previous, value];
646
+ }
647
+ function mimeTypeForPath(filePath) {
648
+ switch (extname(filePath).toLowerCase()) {
649
+ case ".png":
650
+ return "image/png";
651
+ case ".jpg":
652
+ case ".jpeg":
653
+ return "image/jpeg";
654
+ case ".webp":
655
+ return "image/webp";
656
+ case ".gif":
657
+ return "image/gif";
658
+ case ".svg":
659
+ return "image/svg+xml";
660
+ case ".pdf":
661
+ return "application/pdf";
662
+ case ".mp4":
663
+ return "video/mp4";
664
+ case ".webm":
665
+ return "video/webm";
666
+ case ".mp3":
667
+ return "audio/mpeg";
668
+ case ".wav":
669
+ return "audio/wav";
670
+ case ".md":
671
+ return "text/markdown";
672
+ case ".txt":
673
+ return "text/plain";
674
+ case ".json":
675
+ return "application/json";
676
+ case ".zip":
677
+ return "application/zip";
678
+ default:
679
+ return "application/octet-stream";
680
+ }
681
+ }
682
+ var submitCmd = new Command8("submit").description("Submit work for a task").argument("<taskId>", "Task ID (0x-prefixed hex)").option("--file <path>", "Path to a submission file (repeatable)", collectFile, []).action(async (taskId, opts) => {
683
+ try {
684
+ if (!opts.file || opts.file.length === 0) {
685
+ printError("--file is required");
686
+ }
687
+ const keystore = await loadKeystore();
688
+ const signature = await signMessage(`taskmarket:submit:${taskId}`, keystore);
689
+ const body = {
690
+ workerAddress: keystore.walletAddress,
691
+ signature,
692
+ artifacts: await Promise.all(
693
+ opts.file.map(async (filePath) => {
694
+ const fileContent = await fs2.readFile(filePath);
695
+ return {
696
+ fileName: basename(filePath),
697
+ mimeType: mimeTypeForPath(filePath),
698
+ role: "attachment",
699
+ file: fileContent.toString("base64")
700
+ };
701
+ })
702
+ )
703
+ };
704
+ const result = await apiPost(`/api/tasks/${taskId}/submissions`, {
705
+ ...body
706
+ });
707
+ printResult({ submissionId: result.submissionId });
708
+ } finally {
709
+ submitCmd.setOptionValue("file", []);
710
+ }
557
711
  });
558
712
 
559
713
  // src/commands/task/accept.ts
560
714
  import { Command as Command9 } from "commander";
561
- var acceptCmd = new Command9("accept").description("Accept a submission (costs 0.001 USDC)").argument("<taskId>", "Task ID (0x-prefixed hex)").requiredOption("--worker <addr>", "Worker wallet address").action(async (taskId, opts) => {
715
+ var acceptCmd = new Command9("accept").description("Accept a submission (costs 0.001 USDC)").argument("<taskId>", "Task ID (0x-prefixed hex)").requiredOption("--worker <addr>", "Worker wallet address").option(
716
+ "--deliverable <hash>",
717
+ "Deliverable hash to commit on-chain (32-byte hex). Backend will look it up from the submission if omitted."
718
+ ).action(async (taskId, opts) => {
719
+ if (opts.deliverable && !/^0x[0-9a-fA-F]{64}$/.test(opts.deliverable)) {
720
+ throw new Error("--deliverable must be a 0x-prefixed 32-byte hex string (0x + 64 hex chars)");
721
+ }
562
722
  await x402Post(`/api/tasks/${taskId}/accept`, {
563
723
  taskId,
564
- worker: opts.worker
724
+ worker: opts.worker,
725
+ ...opts.deliverable ? { deliverable: opts.deliverable } : {}
565
726
  });
566
727
  printResult({ accepted: true });
567
728
  });
568
729
 
569
- // src/commands/task/rate.ts
730
+ // src/commands/task/accept-submissions.ts
570
731
  import { Command as Command10 } from "commander";
571
- var rateCmd = new Command10("rate").description("Rate a worker (costs 0.001 USDC)").argument("<taskId>", "Task ID (0x-prefixed hex)").requiredOption("--worker <addr>", "Worker wallet address").requiredOption("--rating <n>", "Rating 0-100").option("--feedback <text>", "Optional feedback text").action(async (taskId, opts) => {
572
- const rating = parseInt(opts.rating, 10);
573
- if (rating < 0 || rating > 100) {
574
- printError("Rating must be between 0 and 100");
732
+ function parseWinner(spec) {
733
+ const parts = spec.split(":");
734
+ if (parts.length < 2 || parts.length > 4) {
735
+ throw new Error(
736
+ `Invalid --winner value "${spec}". Expected <addr>:<share>[:<submissionId>][:<deliverable>]`
737
+ );
738
+ }
739
+ const [worker, shareStr, submissionId, deliverable] = parts;
740
+ if (!/^0x[0-9a-fA-F]{40}$/.test(worker)) {
741
+ throw new Error(`Invalid worker address in "${spec}"`);
575
742
  }
576
- const result = await x402Post(`/api/tasks/${taskId}/rate`, {
743
+ const share = parseInt(shareStr, 10);
744
+ if (Number.isNaN(share) || share < 1 || share > 1e4) {
745
+ throw new Error(`Invalid share in "${spec}" \u2014 must be integer 1..10000 (basis points)`);
746
+ }
747
+ if (deliverable && !/^0x[0-9a-fA-F]{64}$/.test(deliverable)) {
748
+ throw new Error(`Invalid deliverable hash in "${spec}" \u2014 must be 0x + 64 hex chars`);
749
+ }
750
+ return {
751
+ worker,
752
+ share,
753
+ ...submissionId ? { submissionId } : {},
754
+ ...deliverable ? { deliverable } : {}
755
+ };
756
+ }
757
+ var acceptSubmissionsCmd = new Command10("accept-submissions").description(
758
+ "Accept N submissions for a Bounty/Benchmark task with explicit share basis points (costs 0.001 USDC).\nShares must sum to 10000. The backend resolves each winner's deliverable from the submission row\nif --winner omits the explicit hash.\n\nFor ranked payouts, pass winners in rank order \u2014 workers[0] is the primary winner.\n\nExamples:\n task accept-submissions 0x\u2026 --winner 0xAlice:5000 --winner 0xBob:3000 --winner 0xCarol:2000\n task accept-submissions 0x\u2026 --winner 0xAlice:5000:sub-uuid --winner 0xBob:5000:sub-uuid2"
759
+ ).argument("<taskId>", "Task ID (0x-prefixed hex)").requiredOption(
760
+ "--winner <spec...>",
761
+ "Winner spec <addr>:<share>[:<submissionId>][:<deliverable>]. Pass multiple times."
762
+ ).action(async (taskId, opts) => {
763
+ let winners;
764
+ try {
765
+ winners = opts.winner.map(parseWinner);
766
+ } catch (err) {
767
+ printError(err instanceof Error ? err.message : String(err));
768
+ return;
769
+ }
770
+ const sum = winners.reduce((a, w) => a + w.share, 0);
771
+ if (sum !== 1e4) {
772
+ printError(`Winner shares must sum to 10000 basis points (got ${sum})`);
773
+ return;
774
+ }
775
+ const result = await x402Post(`/api/tasks/${taskId}/accept-submissions`, {
577
776
  taskId,
578
- worker: opts.worker,
579
- rating,
580
- ...opts.feedback ? { feedbackText: opts.feedback } : {}
777
+ winners
581
778
  });
582
- printResult({ feedbackId: result.feedbackId });
779
+ printResult({ accepted: result.success, winners: winners.length });
583
780
  });
584
781
 
585
- // src/commands/task/claim.ts
782
+ // src/commands/task/rate.ts
586
783
  import { Command as Command11 } from "commander";
587
- var claimCmd = new Command11("claim").description("Claim a task as a worker").argument("<taskId>", "Task ID (0x-prefixed hex)").action(async (taskId) => {
784
+ var rateCmd = new Command11("rate").description("Rate a worker (costs 0.001 USDC)").argument("<taskId>", "Task ID (0x-prefixed hex)").requiredOption("--worker <addr>", "Worker wallet address").requiredOption("--rating <n>", "Rating 0-100").option("--feedback <text>", "Optional feedback text").option(
785
+ "--rater-agent-id <id>",
786
+ "ERC-8004 agent ID of the requester (overrides server-side lookup)"
787
+ ).action(
788
+ async (taskId, opts) => {
789
+ const rating = parseInt(opts.rating, 10);
790
+ if (rating < 0 || rating > 100) {
791
+ printError("Rating must be between 0 and 100");
792
+ }
793
+ const result = await x402Post(`/api/tasks/${taskId}/rate`, {
794
+ taskId,
795
+ worker: opts.worker,
796
+ rating,
797
+ ...opts.feedback ? { feedbackText: opts.feedback } : {},
798
+ ...opts.raterAgentId ? { raterAgentId: parseInt(opts.raterAgentId, 10) } : {}
799
+ });
800
+ printResult({ feedbackId: result.feedbackId });
801
+ }
802
+ );
803
+
804
+ // src/commands/task/claim.ts
805
+ import { Command as Command12 } from "commander";
806
+ var claimCmd = new Command12("claim").description("Claim a task as a worker").argument("<taskId>", "Task ID (0x-prefixed hex)").action(async (taskId) => {
588
807
  const keystore = await loadKeystore();
589
808
  const message = `taskmarket:claim:${taskId}`;
590
809
  const signature = await signMessage(message, keystore);
@@ -596,11 +815,12 @@ var claimCmd = new Command11("claim").description("Claim a task as a worker").ar
596
815
  });
597
816
 
598
817
  // src/commands/task/pitch.ts
599
- import { Command as Command12 } from "commander";
600
- var pitchCmd = new Command12("pitch").description("Submit a pitch for a task").argument("<taskId>", "Task ID (0x-prefixed hex)").requiredOption("--text <text>", "Pitch text").option("--duration <hours>", "Estimated duration in hours").action(async (taskId, opts) => {
818
+ import { Command as Command13 } from "commander";
819
+ var pitchCmd = new Command13("pitch").description("Submit a pitch for a task (costs 0.001 USDC, anchors hash on-chain)").argument("<taskId>", "Task ID (0x-prefixed hex)").requiredOption("--text <text>", "Pitch text").option("--duration <hours>", "Estimated duration in hours").action(async (taskId, opts) => {
601
820
  const keystore = await loadKeystore();
602
821
  const signature = await signMessage(`taskmarket:pitch:${taskId}`, keystore);
603
- const result = await apiPost(`/api/tasks/${taskId}/pitches`, {
822
+ const result = await x402Post(`/api/tasks/${taskId}/pitches`, {
823
+ taskId,
604
824
  workerAddress: keystore.walletAddress,
605
825
  pitchText: opts.text,
606
826
  ...opts.duration ? { estimatedDuration: parseInt(opts.duration, 10) } : {},
@@ -610,9 +830,9 @@ var pitchCmd = new Command12("pitch").description("Submit a pitch for a task").a
610
830
  });
611
831
 
612
832
  // src/commands/task/select-worker.ts
613
- import { Command as Command13 } from "commander";
833
+ import { Command as Command14 } from "commander";
614
834
  import { keccak256, toBytes } from "viem";
615
- var selectWorkerCmd = new Command13("select-worker").description("Select a worker from pitches (requester only)").argument("<taskId>", "Task ID (0x-prefixed hex)").requiredOption("--pitch <pitchId>", "Pitch ID to select").requiredOption("--worker <address>", "Worker wallet address to assign").action(async (taskId, opts) => {
835
+ var selectWorkerCmd = new Command14("select-worker").description("Select a worker from pitches (requester only)").argument("<taskId>", "Task ID (0x-prefixed hex)").requiredOption("--pitch <pitchId>", "Pitch ID to select").requiredOption("--worker <address>", "Worker wallet address to assign").action(async (taskId, opts) => {
616
836
  const keystore = await loadKeystore();
617
837
  const hash = keccak256(toBytes(taskId + opts.pitch + opts.worker));
618
838
  const signature = await signMessage(hash, keystore);
@@ -626,11 +846,12 @@ var selectWorkerCmd = new Command13("select-worker").description("Select a worke
626
846
  });
627
847
 
628
848
  // src/commands/task/proof.ts
629
- import { Command as Command14 } from "commander";
630
- var proofCmd = new Command14("proof").description("Submit a proof for a task").argument("<taskId>", "Task ID (0x-prefixed hex)").requiredOption("--data <data>", "Proof data").requiredOption("--type <type>", "Proof type").option("--metric <val>", "Metric value").action(async (taskId, opts) => {
849
+ import { Command as Command15 } from "commander";
850
+ var proofCmd = new Command15("proof").description("Submit a benchmark proof (costs 0.001 USDC, anchors hash on-chain)").argument("<taskId>", "Task ID (0x-prefixed hex)").requiredOption("--data <data>", "Proof data").requiredOption("--type <type>", "Proof type").option("--metric <val>", "Metric value").action(async (taskId, opts) => {
631
851
  const keystore = await loadKeystore();
632
852
  const signature = await signMessage(`taskmarket:proof:${taskId}`, keystore);
633
- const result = await apiPost(`/api/tasks/${taskId}/proofs`, {
853
+ const result = await x402Post(`/api/tasks/${taskId}/proofs`, {
854
+ taskId,
634
855
  workerAddress: keystore.walletAddress,
635
856
  proofData: opts.data,
636
857
  proofType: opts.type,
@@ -641,8 +862,8 @@ var proofCmd = new Command14("proof").description("Submit a proof for a task").a
641
862
  });
642
863
 
643
864
  // src/commands/task/bid.ts
644
- import { Command as Command15 } from "commander";
645
- var bidCmd = new Command15("bid").description("Submit a bid on an auction task").argument("<taskId>", "Task ID (0x-prefixed hex)").requiredOption("--price <usdc>", "Bid price in USDC (e.g. 3 or 1.5)").action(async (taskId, opts) => {
865
+ import { Command as Command16 } from "commander";
866
+ var bidCmd = new Command16("bid").description("Submit a bid on an auction task").argument("<taskId>", "Task ID (0x-prefixed hex)").requiredOption("--price <usdc>", "Bid price in USDC (e.g. 3 or 1.5)").action(async (taskId, opts) => {
646
867
  const priceBaseUnits = String(Math.round(parseFloat(opts.price) * 1e6));
647
868
  const result = await x402Post(`/api/tasks/${taskId}/bids`, {
648
869
  taskId,
@@ -651,9 +872,32 @@ var bidCmd = new Command15("bid").description("Submit a bid on an auction task")
651
872
  printResult({ bidId: result.bidId });
652
873
  });
653
874
 
875
+ // src/commands/task/auction-accept.ts
876
+ import { Command as Command17 } from "commander";
877
+ var auctionAcceptCmd = new Command17("auction-accept").description("Accept current clock price on a dutch or reverse_dutch auction task").argument("<taskId>", "Task ID (0x-prefixed hex)").option(
878
+ "--min-price <usdc>",
879
+ "Reject if current clock price is below this value (price floor guard)"
880
+ ).action(async (taskId, opts) => {
881
+ const body = { taskId };
882
+ if (opts.minPrice) {
883
+ const [intPart = "0", fracPart = ""] = opts.minPrice.trim().split(".");
884
+ if (!/^\d+$/.test(intPart) || fracPart && !/^\d+$/.test(fracPart)) {
885
+ throw new Error(`--min-price: invalid number "${opts.minPrice}"`);
886
+ }
887
+ const padded = fracPart.slice(0, 6).padEnd(6, "0");
888
+ body.minPrice = (BigInt(intPart) * 1000000n + BigInt(padded)).toString();
889
+ }
890
+ const result = await x402Post(`/api/tasks/${taskId}/bids/accept`, body);
891
+ printResult({
892
+ acceptedPrice: result.acceptedPrice,
893
+ acceptedPriceUsdc: (Number(result.acceptedPrice) / 1e6).toFixed(6),
894
+ workerAddress: result.workerAddress
895
+ });
896
+ });
897
+
654
898
  // src/commands/task/submissions.ts
655
- import { Command as Command16 } from "commander";
656
- var submissionsCmd = new Command16("submissions").description("List submissions for a task").argument("<taskId>", "Task ID (0x-prefixed hex)").action(async (taskId) => {
899
+ import { Command as Command18 } from "commander";
900
+ var submissionsCmd = new Command18("submissions").description("List submissions for a task").argument("<taskId>", "Task ID (0x-prefixed hex)").action(async (taskId) => {
657
901
  let subs;
658
902
  try {
659
903
  subs = await apiGet(`/api/tasks/${taskId}/submissions`);
@@ -665,8 +909,8 @@ var submissionsCmd = new Command16("submissions").description("List submissions
665
909
  });
666
910
 
667
911
  // src/commands/task/select-winner.ts
668
- import { Command as Command17 } from "commander";
669
- var selectWinnerCmd = new Command17("select-winner").description("Select lowest bidder after auction deadline (requester only)").argument("<taskId>", "Task ID (0x-prefixed hex)").action(async (taskId) => {
912
+ import { Command as Command19 } from "commander";
913
+ var selectWinnerCmd = new Command19("select-winner").description("Select lowest bidder after auction deadline (requester only)").argument("<taskId>", "Task ID (0x-prefixed hex)").action(async (taskId) => {
670
914
  let result;
671
915
  try {
672
916
  result = await apiPost(`/api/tasks/${taskId}/bids/select-winner`, {
@@ -680,56 +924,296 @@ var selectWinnerCmd = new Command17("select-winner").description("Select lowest
680
924
  });
681
925
 
682
926
  // src/commands/task/download.ts
683
- import { Command as Command18 } from "commander";
927
+ import { Command as Command20 } from "commander";
684
928
  import { writeFileSync } from "fs";
685
- var downloadCmd = new Command18("download").description("Download a submission file (requester or worker)").argument("<taskId>", "Task ID (0x-prefixed hex)").requiredOption("--submission <id>", "Submission ID (from `task submissions`)").option("--output <path>", "Save to file instead of printing to stdout").action(async (taskId, opts) => {
686
- const keystore = await loadKeystore();
687
- let presignedUrl;
929
+ var downloadCmd = new Command20("download").description("Download a submission file (requester or worker)").argument("<taskId>", "Task ID (0x-prefixed hex)").requiredOption("--submission <id>", "Submission ID (from `task submissions`)").option("--artifact <id>", "Artifact ID for multi-artifact submissions").option("--output <path>", "Save to file instead of printing to stdout").action(
930
+ async (taskId, opts) => {
931
+ const keystore = await loadKeystore();
932
+ let presignedUrl;
933
+ try {
934
+ const body = {
935
+ taskId,
936
+ submissionId: opts.submission,
937
+ deviceId: keystore.deviceId,
938
+ apiToken: keystore.apiToken
939
+ };
940
+ if (opts.artifact) {
941
+ body.artifactId = opts.artifact;
942
+ }
943
+ const result = await apiPost(
944
+ `/api/tasks/${taskId}/submissions/${opts.submission}/preview`,
945
+ body
946
+ );
947
+ presignedUrl = result.presignedUrl;
948
+ } catch (err) {
949
+ const msg = err instanceof Error ? err.message : "Failed to get download URL.";
950
+ printError(msg);
951
+ }
952
+ const res = await fetch(presignedUrl);
953
+ if (!res.ok) {
954
+ printError(`Failed to download file: ${res.status}`);
955
+ }
956
+ const content = Buffer.from(await res.arrayBuffer());
957
+ if (opts.output) {
958
+ writeFileSync(opts.output, content);
959
+ process.stdout.write(JSON.stringify({ ok: true, data: { savedTo: opts.output } }) + "\n");
960
+ } else {
961
+ process.stdout.write(content);
962
+ }
963
+ }
964
+ );
965
+
966
+ // src/commands/task/cancel.ts
967
+ import { Command as Command21 } from "commander";
968
+ var cancelCmd = new Command21("cancel").description("Cancel an open task and refund the escrowed reward (costs 0.001 USDC)").argument("<taskId>", "Task ID (0x-prefixed hex)").action(async (taskId) => {
969
+ const result = await x402Post(`/api/tasks/${taskId}/cancel`, { taskId });
970
+ printResult(result);
971
+ });
972
+
973
+ // src/commands/task/update.ts
974
+ import { Command as Command22 } from "commander";
975
+ function toBaseUnits(humanUsdc) {
976
+ const [intPart = "0", fracPart = ""] = humanUsdc.trim().split(".");
977
+ const padded = fracPart.slice(0, 6).padEnd(6, "0");
978
+ return (BigInt(intPart) * 1000000n + BigInt(padded)).toString();
979
+ }
980
+ var updateCmd = new Command22("update").description("Update an open task (costs 0.001 USDC)").argument("<taskId>", "Task ID (0x-prefixed hex)").option("--reward <usdc>", 'New reward in USDC (human units, e.g. "50")').option("--extend-expiry <seconds>", "Extend expiry by this many seconds").option("--bid-deadline <iso>", "New bid deadline (ISO 8601)").option("--pitch-deadline <iso>", "New pitch deadline (ISO 8601)").option("--auction-floor-price <usdc>", "New auction floor price in USDC").option("--auction-start-price <usdc>", "New auction start price in USDC").option("--description <text>", "New description").option("--tags <csv>", "New tags (comma-separated)").option("--metric-description <text>", "New metric description").action(
981
+ async (taskId, opts) => {
982
+ const body = { taskId };
983
+ if (opts.reward !== void 0) {
984
+ body.reward = toBaseUnits(opts.reward);
985
+ }
986
+ if (opts.extendExpiry !== void 0) {
987
+ const delta = parseInt(opts.extendExpiry, 10);
988
+ if (!Number.isFinite(delta) || delta < 0) {
989
+ printError(`--extend-expiry must be a non-negative integer, got: ${opts.extendExpiry}`);
990
+ }
991
+ const task = await apiGet(`/api/tasks/${taskId}`);
992
+ if (!task) {
993
+ printError(`Task not found: ${taskId}`);
994
+ }
995
+ const currentExpiry = Math.floor(new Date(task.expiryTime).getTime() / 1e3);
996
+ body.expiryTime = currentExpiry + delta;
997
+ }
998
+ if (opts.bidDeadline !== void 0) {
999
+ const ts = Math.floor(new Date(opts.bidDeadline).getTime() / 1e3);
1000
+ if (ts <= Math.floor(Date.now() / 1e3)) {
1001
+ printError("--bid-deadline must be in the future");
1002
+ } else {
1003
+ body.bidDeadline = ts;
1004
+ }
1005
+ }
1006
+ if (opts.pitchDeadline !== void 0) {
1007
+ const ts = Math.floor(new Date(opts.pitchDeadline).getTime() / 1e3);
1008
+ if (ts <= Math.floor(Date.now() / 1e3)) {
1009
+ printError("--pitch-deadline must be in the future");
1010
+ } else {
1011
+ body.pitchDeadline = ts;
1012
+ }
1013
+ }
1014
+ if (opts.auctionFloorPrice !== void 0) {
1015
+ body.auctionFloorPrice = toBaseUnits(opts.auctionFloorPrice);
1016
+ }
1017
+ if (opts.auctionStartPrice !== void 0) {
1018
+ body.auctionStartPrice = toBaseUnits(opts.auctionStartPrice);
1019
+ }
1020
+ if (opts.description !== void 0) {
1021
+ body.description = opts.description;
1022
+ }
1023
+ if (opts.tags !== void 0) {
1024
+ body.tags = opts.tags.split(",").map((t) => t.trim()).filter(Boolean);
1025
+ }
1026
+ if (opts.metricDescription !== void 0) {
1027
+ body.metricDescription = opts.metricDescription;
1028
+ }
1029
+ const result = await x402Post(`/api/tasks/${taskId}/update`, body);
1030
+ printResult(result);
1031
+ }
1032
+ );
1033
+
1034
+ // src/commands/task/forfeit.ts
1035
+ import { Command as Command23 } from "commander";
1036
+ var forfeitCmd = new Command23("forfeit").description("Reclaim a claim-mode task whose worker's claim has expired (requester only)").argument("<taskId>", "Task ID (0x-prefixed hex)").action(async (taskId) => {
688
1037
  try {
689
- const result = await apiPost(`/api/tasks/${taskId}/submissions/${opts.submission}/preview`, {
1038
+ const keystore = await loadKeystore();
1039
+ const message = `taskmarket:forfeit:${taskId}`;
1040
+ const signature = await signMessage(message, keystore);
1041
+ const result = await apiPost(`/api/tasks/${taskId}/forfeit`, {
690
1042
  taskId,
691
- submissionId: opts.submission,
692
- deviceId: keystore.deviceId,
693
- apiToken: keystore.apiToken
1043
+ requesterAddress: keystore.walletAddress,
1044
+ signature
694
1045
  });
695
- presignedUrl = result.presignedUrl;
1046
+ printResult(result);
696
1047
  } catch (err) {
697
- const msg = err instanceof Error ? err.message : "Failed to get download URL.";
698
- printError(msg);
1048
+ printError(err instanceof Error ? err.message : String(err));
699
1049
  }
700
- const res = await fetch(presignedUrl);
701
- if (!res.ok) {
702
- printError(`Failed to download file: ${res.status}`);
1050
+ });
1051
+
1052
+ // src/commands/task/evaluate.ts
1053
+ import { Command as Command24 } from "commander";
1054
+ var evaluateCmd = new Command24("evaluate").description("Submit an evaluation verdict for a task in Review state").argument("<taskId>", "Task ID (0x-prefixed hex)").requiredOption("--verdict <type>", "Verdict: approve, reject, or partial").option("--score <n>", "Score 0-1000 (default: 1000)", "1000").option("--confidence <n>", "Confidence 0-1000 (default: 1000)", "1000").option("--evidence-hash <hash>", "Evidence hash (32-byte hex)").option(
1055
+ "--award <worker:amount:rank>",
1056
+ "Award entry (repeatable): worker:amountUSDC:rank",
1057
+ collect,
1058
+ []
1059
+ ).action(
1060
+ async (taskId, opts) => {
1061
+ const validVerdicts = ["approve", "reject", "partial"];
1062
+ if (!validVerdicts.includes(opts.verdict)) {
1063
+ return void printError(`--verdict must be one of: ${validVerdicts.join(", ")}`);
1064
+ }
1065
+ const awards = [];
1066
+ for (const entry of opts.award) {
1067
+ const parts = entry.split(":");
1068
+ if (parts.length < 3 || !parts[0] || !parts[1] || !parts[2]) {
1069
+ return void printError(
1070
+ `Invalid award format '${entry}'. Expected worker:amountUSDC:rank`
1071
+ );
1072
+ }
1073
+ const [worker, amountUSDC, rankStr] = parts;
1074
+ if (!/^0x[0-9a-fA-F]{40}$/.test(worker)) {
1075
+ return void printError(
1076
+ `Invalid worker address in '${entry}': must be 0x-prefixed 40-char hex`
1077
+ );
1078
+ }
1079
+ const parsedAmount = Number(amountUSDC);
1080
+ if (!Number.isFinite(parsedAmount) || parsedAmount <= 0) {
1081
+ return void printError(`Invalid amount in '${entry}': must be a positive number`);
1082
+ }
1083
+ const microUnits = Math.round(parsedAmount * 1e6);
1084
+ if (!Number.isFinite(microUnits) || microUnits > Number.MAX_SAFE_INTEGER) {
1085
+ return void printError(`Amount in '${entry}' is too large to convert to micro-units`);
1086
+ }
1087
+ const parsedRank = Number(rankStr);
1088
+ if (!Number.isInteger(parsedRank) || parsedRank < 1) {
1089
+ return void printError(`Invalid rank in '${entry}': must be a positive integer`);
1090
+ }
1091
+ awards.push({ worker, amount: String(microUnits), rank: parsedRank });
1092
+ }
1093
+ const body = {
1094
+ taskId,
1095
+ verdict: opts.verdict,
1096
+ score: parseInt(opts.score, 10),
1097
+ confidence: parseInt(opts.confidence, 10),
1098
+ awards
1099
+ };
1100
+ if (opts.evidenceHash) {
1101
+ if (!/^0x[0-9a-fA-F]{64}$/.test(opts.evidenceHash)) {
1102
+ return void printError(
1103
+ "--evidence-hash must be a 0x-prefixed 32-byte hex string (0x + 64 hex chars)"
1104
+ );
1105
+ }
1106
+ body.evidenceHash = opts.evidenceHash;
1107
+ }
1108
+ const result = await x402Post(`/api/tasks/${taskId}/evaluate`, body);
1109
+ printResult({ txHash: result.txHash });
703
1110
  }
704
- const content = await res.text();
705
- if (opts.output) {
706
- writeFileSync(opts.output, content, "utf8");
707
- process.stdout.write(JSON.stringify({ ok: true, data: { savedTo: opts.output } }) + "\n");
708
- } else {
709
- process.stdout.write(content);
1111
+ );
1112
+ function collect(val, prev) {
1113
+ return prev.concat([val]);
1114
+ }
1115
+
1116
+ // src/commands/task/appeal.ts
1117
+ import { Command as Command25 } from "commander";
1118
+ var appealCmd = new Command25("appeal").description("Appeal an evaluator verdict while in Appealing state").argument("<taskId>", "Task ID (0x-prefixed hex)").action(async (taskId) => {
1119
+ const result = await x402Post(`/api/tasks/${taskId}/appeal`, { taskId });
1120
+ printResult({ txHash: result.txHash });
1121
+ });
1122
+
1123
+ // src/commands/task/evaluator-timeout.ts
1124
+ import { Command as Command26 } from "commander";
1125
+ var evaluatorTimeoutCmd = new Command26("evaluator-timeout").description("Trigger evaluator timeout after the evaluation window expires (requester only)").argument("<taskId>", "Task ID (0x-prefixed hex)").action(async (taskId) => {
1126
+ const result = await x402Post(`/api/tasks/${taskId}/evaluator-timeout`, { taskId });
1127
+ printResult({ txHash: result.txHash });
1128
+ });
1129
+
1130
+ // src/commands/task/finalize-verdict.ts
1131
+ import { Command as Command27 } from "commander";
1132
+ var finalizeVerdictCmd = new Command27("finalize-verdict").description("Finalize an evaluator verdict after the appeal window expires (permissionless)").argument("<taskId>", "Task ID (0x-prefixed hex)").action(async (taskId) => {
1133
+ const result = await x402Post(`/api/tasks/${taskId}/finalize-verdict`, { taskId });
1134
+ printResult({ txHash: result.txHash });
1135
+ });
1136
+
1137
+ // src/commands/task/resolve-dispute.ts
1138
+ import { Command as Command28 } from "commander";
1139
+ function parseAward(spec) {
1140
+ const parts = spec.split(":");
1141
+ if (parts.length !== 3) {
1142
+ throw new Error(`Invalid --award value "${spec}". Expected <addr>:<amount_usdc>:<rank>`);
1143
+ }
1144
+ const [worker, amountStr, rankStr] = parts;
1145
+ if (!/^0x[0-9a-fA-F]{40}$/.test(worker)) {
1146
+ throw new Error(`Invalid worker address in "${spec}"`);
1147
+ }
1148
+ const amount = parseFloat(amountStr);
1149
+ if (Number.isNaN(amount) || amount <= 0) {
1150
+ throw new Error(`Invalid amount in "${spec}" \u2014 must be a positive number`);
1151
+ }
1152
+ const rank = parseInt(rankStr, 10);
1153
+ if (!Number.isInteger(rank) || rank < 1) {
1154
+ throw new Error(`Invalid rank in "${spec}" \u2014 must be an integer >= 1`);
1155
+ }
1156
+ return {
1157
+ worker,
1158
+ amount: String(Math.round(amount * 1e6)),
1159
+ rank
1160
+ };
1161
+ }
1162
+ var resolveDisputeCmd = new Command28("resolve-dispute").description(
1163
+ "Resolve a disputed task as the designated dispute resolver (X402 required).\n\nExamples:\n task resolve-dispute 0x\u2026 --verdict approve --award 0xAlice:5:1\n task resolve-dispute 0x\u2026 --verdict partial --award 0xAlice:3:1 --award 0xBob:2:2"
1164
+ ).argument("<taskId>", "Task ID (0x-prefixed hex)").requiredOption("--verdict <type>", "Verdict type: approve or partial").requiredOption(
1165
+ "--award <spec...>",
1166
+ "Award spec <addr>:<amount_usdc>:<rank>. Pass multiple times."
1167
+ ).action(async (taskId, opts) => {
1168
+ if (opts.verdict !== "approve" && opts.verdict !== "partial") {
1169
+ printError('--verdict must be "approve" or "partial"');
1170
+ return;
710
1171
  }
1172
+ let awards;
1173
+ try {
1174
+ awards = opts.award.map(parseAward);
1175
+ } catch (err) {
1176
+ printError(err instanceof Error ? err.message : String(err));
1177
+ return;
1178
+ }
1179
+ const result = await x402Post(`/api/tasks/${taskId}/resolve-dispute`, {
1180
+ taskId,
1181
+ verdict: opts.verdict,
1182
+ awards
1183
+ });
1184
+ printResult({ txHash: result.txHash });
711
1185
  });
712
1186
 
713
1187
  // src/commands/task/index.ts
714
- var taskCommand = new Command19("task").description("Manage tasks");
1188
+ var taskCommand = new Command29("task").description("Manage tasks");
715
1189
  taskCommand.addCommand(createCmd);
716
1190
  taskCommand.addCommand(listCmd);
717
1191
  taskCommand.addCommand(getCmd);
718
1192
  taskCommand.addCommand(submitCmd);
719
1193
  taskCommand.addCommand(acceptCmd);
1194
+ taskCommand.addCommand(acceptSubmissionsCmd);
720
1195
  taskCommand.addCommand(rateCmd);
721
1196
  taskCommand.addCommand(claimCmd);
722
1197
  taskCommand.addCommand(pitchCmd);
723
1198
  taskCommand.addCommand(selectWorkerCmd);
724
1199
  taskCommand.addCommand(proofCmd);
725
1200
  taskCommand.addCommand(bidCmd);
1201
+ taskCommand.addCommand(auctionAcceptCmd);
726
1202
  taskCommand.addCommand(submissionsCmd);
727
1203
  taskCommand.addCommand(selectWinnerCmd);
728
1204
  taskCommand.addCommand(downloadCmd);
1205
+ taskCommand.addCommand(cancelCmd);
1206
+ taskCommand.addCommand(updateCmd);
1207
+ taskCommand.addCommand(forfeitCmd);
1208
+ taskCommand.addCommand(evaluateCmd);
1209
+ taskCommand.addCommand(appealCmd);
1210
+ taskCommand.addCommand(evaluatorTimeoutCmd);
1211
+ taskCommand.addCommand(finalizeVerdictCmd);
1212
+ taskCommand.addCommand(resolveDisputeCmd);
729
1213
 
730
1214
  // src/commands/agents.ts
731
- import { Command as Command20 } from "commander";
732
- var agentsCommand = new Command20("agents").description("Browse the agent directory").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) => {
1215
+ import { Command as Command30 } from "commander";
1216
+ var agentsCommand = new Command30("agents").description("Browse the agent directory").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) => {
733
1217
  const params = new URLSearchParams();
734
1218
  if (opts.sort) params.set("sort", opts.sort);
735
1219
  if (opts.skill) params.set("skill", opts.skill);
@@ -740,8 +1224,8 @@ var agentsCommand = new Command20("agents").description("Browse the agent direct
740
1224
  });
741
1225
 
742
1226
  // src/commands/inbox.ts
743
- import { Command as Command21 } from "commander";
744
- var inboxCommand = new Command21("inbox").description("Show tasks you created and tasks you are working on").action(async () => {
1227
+ import { Command as Command31 } from "commander";
1228
+ var inboxCommand = new Command31("inbox").description("Show tasks you created and tasks you are working on").action(async () => {
745
1229
  let address;
746
1230
  try {
747
1231
  address = await getWalletAddress();
@@ -749,15 +1233,26 @@ var inboxCommand = new Command21("inbox").description("Show tasks you created an
749
1233
  const msg = err instanceof Error ? err.message : "No keystore found. Run `taskmarket init` first.";
750
1234
  printError(msg);
751
1235
  }
752
- const result = await apiGet(
1236
+ const taskResult = await apiGet(
753
1237
  `/api/agents/inbox?address=${encodeURIComponent(address)}`
754
1238
  );
755
- printResult(result);
1239
+ let pendingBids = [];
1240
+ try {
1241
+ const keystore = await loadKeystore();
1242
+ if (keystore.deviceId && keystore.apiToken) {
1243
+ const params = new URLSearchParams({ deviceId: keystore.deviceId });
1244
+ pendingBids = await apiGet(`/api/bids/my?${params.toString()}`, {
1245
+ headers: { "x-taskmarket-api-token": keystore.apiToken }
1246
+ });
1247
+ }
1248
+ } catch {
1249
+ }
1250
+ printResult({ ...taskResult, pendingBids });
756
1251
  });
757
1252
 
758
1253
  // src/commands/deposit.ts
759
- import { Command as Command22 } from "commander";
760
- var depositCommand = new Command22("deposit").description("Show wallet address and network info for funding").action(async () => {
1254
+ import { Command as Command32 } from "commander";
1255
+ var depositCommand = new Command32("deposit").description("Show wallet address and network info for funding").action(async () => {
761
1256
  let address;
762
1257
  try {
763
1258
  address = await getWalletAddress();
@@ -784,11 +1279,11 @@ var depositCommand = new Command22("deposit").description("Show wallet address a
784
1279
  });
785
1280
 
786
1281
  // src/commands/wallet/index.ts
787
- import { Command as Command27 } from "commander";
1282
+ import { Command as Command37 } from "commander";
788
1283
 
789
1284
  // src/commands/wallet/balance.ts
790
- import { Command as Command23 } from "commander";
791
- var walletBalanceCommand = new Command23("balance").description("Show USDC balance").option("--address <addr>", "Address to check (defaults to own wallet)").action(async (opts) => {
1285
+ import { Command as Command33 } from "commander";
1286
+ var walletBalanceCommand = new Command33("balance").description("Show USDC balance").option("--address <addr>", "Address to check (defaults to own wallet)").action(async (opts) => {
792
1287
  let address = opts.address;
793
1288
  if (!address) {
794
1289
  const keystore = await loadKeystore();
@@ -799,7 +1294,7 @@ var walletBalanceCommand = new Command23("balance").description("Show USDC balan
799
1294
  });
800
1295
 
801
1296
  // src/commands/wallet/import.ts
802
- import { Command as Command24 } from "commander";
1297
+ import { Command as Command34 } from "commander";
803
1298
  import { createInterface } from "readline";
804
1299
  import { privateKeyToAccount as privateKeyToAccount3 } from "viem/accounts";
805
1300
  function normalizePrivateKey(raw) {
@@ -834,7 +1329,7 @@ function promptHiddenInput(prompt) {
834
1329
  });
835
1330
  });
836
1331
  }
837
- var walletImportCommand = new Command24("import").description("Import an existing private key as the agent wallet").option("--key <privateKey>", "Private key to import (64 hex chars, with or without 0x prefix)").action(async (opts) => {
1332
+ var walletImportCommand = new Command34("import").description("Import an existing private key as the agent wallet").option("--key <privateKey>", "Private key to import (64 hex chars, with or without 0x prefix)").action(async (opts) => {
838
1333
  if (await keystoreExists()) {
839
1334
  const keystore = await loadKeystore();
840
1335
  printResult({ address: keystore.walletAddress, agentId: keystore.agentId });
@@ -873,7 +1368,14 @@ var walletImportCommand = new Command24("import").description("Import an existin
873
1368
  } = await res.json();
874
1369
  const encryptedKey = encryptPrivateKey(deviceEncryptionKey, privateKey);
875
1370
  let agentId = initialAgentId;
876
- await saveKeystore({ encryptedKey, walletAddress: address, deviceId, apiToken, agentId });
1371
+ await saveKeystore({
1372
+ encryptedKey,
1373
+ walletAddress: address,
1374
+ deviceId,
1375
+ apiToken,
1376
+ agentId,
1377
+ keyServerUrl: API_URL
1378
+ });
877
1379
  if (!agentId) {
878
1380
  agentId = await pollAgentId(address);
879
1381
  if (agentId) {
@@ -892,11 +1394,11 @@ var walletImportCommand = new Command24("import").description("Import an existin
892
1394
  });
893
1395
 
894
1396
  // src/commands/wallet/set-withdrawal-address.ts
895
- import { Command as Command25 } from "commander";
1397
+ import { Command as Command35 } from "commander";
896
1398
  function isValidAddress(addr) {
897
1399
  return /^0x[a-fA-F0-9]{40}$/.test(addr);
898
1400
  }
899
- var setWithdrawalAddressCommand = new Command25("set-withdrawal-address").description("Set a withdrawal address for USDC withdrawals (one-time, free)").argument("<address>", "Ethereum address to receive withdrawals").action(async (address) => {
1401
+ var setWithdrawalAddressCommand = new Command35("set-withdrawal-address").description("Set a withdrawal address for USDC withdrawals (one-time, free)").argument("<address>", "Ethereum address to receive withdrawals").action(async (address) => {
900
1402
  if (!isValidAddress(address)) {
901
1403
  printError("Invalid Ethereum address: must be 0x followed by 40 hex characters");
902
1404
  }
@@ -918,8 +1420,8 @@ var setWithdrawalAddressCommand = new Command25("set-withdrawal-address").descri
918
1420
  });
919
1421
 
920
1422
  // src/commands/wallet/publish-key.ts
921
- import { Command as Command26 } from "commander";
922
- var publishKeyCommand = new Command26("publish-key").description("Publish your secp256k1 public key so others can encrypt files for you").action(async () => {
1423
+ import { Command as Command36 } from "commander";
1424
+ var publishKeyCommand = new Command36("publish-key").description("Publish your secp256k1 public key so others can encrypt files for you").action(async () => {
923
1425
  let keystore;
924
1426
  try {
925
1427
  keystore = await loadKeystore();
@@ -938,14 +1440,14 @@ var publishKeyCommand = new Command26("publish-key").description("Publish your s
938
1440
  });
939
1441
 
940
1442
  // src/commands/wallet/index.ts
941
- var walletCommand = new Command27("wallet").description("Wallet management commands");
1443
+ var walletCommand = new Command37("wallet").description("Wallet management commands");
942
1444
  walletCommand.addCommand(walletBalanceCommand);
943
1445
  walletCommand.addCommand(walletImportCommand);
944
1446
  walletCommand.addCommand(setWithdrawalAddressCommand);
945
1447
  walletCommand.addCommand(publishKeyCommand);
946
1448
 
947
1449
  // src/commands/withdraw.ts
948
- import { Command as Command28 } from "commander";
1450
+ import { Command as Command38 } from "commander";
949
1451
  import { toHex as toHex2 } from "viem";
950
1452
  var USDC_TYPES = {
951
1453
  TransferWithAuthorization: [
@@ -957,7 +1459,7 @@ var USDC_TYPES = {
957
1459
  { name: "nonce", type: "bytes32" }
958
1460
  ]
959
1461
  };
960
- var withdrawCommand = new Command28("withdraw").description("Withdraw USDC to the registered withdrawal address").argument("<amount>", "Amount in USDC (e.g. 5 for 5 USDC)").action(async (amount) => {
1462
+ var withdrawCommand = new Command38("withdraw").description("Withdraw USDC to the registered withdrawal address").argument("<amount>", "Amount in USDC (e.g. 5 for 5 USDC)").action(async (amount) => {
961
1463
  const parsed = parseFloat(amount);
962
1464
  if (isNaN(parsed) || parsed <= 0) {
963
1465
  printError("Invalid amount: must be a positive number (e.g. 5 for 5 USDC)");
@@ -1007,9 +1509,9 @@ var withdrawCommand = new Command28("withdraw").description("Withdraw USDC to th
1007
1509
  });
1008
1510
 
1009
1511
  // src/commands/encrypt.ts
1010
- import { Command as Command29 } from "commander";
1512
+ import { Command as Command39 } from "commander";
1011
1513
  import { promises as fs3 } from "fs";
1012
- var encryptCommand = new Command29("encrypt").description("Encrypt a file with ECIES using wallet keys").argument("<file>", "Path to the file to encrypt").option("--recipient <address>", "Recipient wallet address (default: self)").option("--output <path>", "Output path (default: <file>.enc)").action(async (file, opts) => {
1514
+ var encryptCommand = new Command39("encrypt").description("Encrypt a file with ECIES using wallet keys").argument("<file>", "Path to the file to encrypt").option("--recipient <address>", "Recipient wallet address (default: self)").option("--output <path>", "Output path (default: <file>.enc)").action(async (file, opts) => {
1013
1515
  let plaintext;
1014
1516
  try {
1015
1517
  plaintext = await fs3.readFile(file);
@@ -1058,9 +1560,9 @@ var encryptCommand = new Command29("encrypt").description("Encrypt a file with E
1058
1560
  });
1059
1561
 
1060
1562
  // src/commands/decrypt.ts
1061
- import { Command as Command30 } from "commander";
1563
+ import { Command as Command40 } from "commander";
1062
1564
  import { promises as fs4 } from "fs";
1063
- var decryptCommand = new Command30("decrypt").description("Decrypt a file using your wallet key").argument("<file>", "Path to the encrypted file").option("--output <path>", "Output path (default: strips .enc, otherwise appends .dec)").action(async (file, opts) => {
1565
+ var decryptCommand = new Command40("decrypt").description("Decrypt a file using your wallet key").argument("<file>", "Path to the encrypted file").option("--output <path>", "Output path (default: strips .enc, otherwise appends .dec)").action(async (file, opts) => {
1064
1566
  let ciphertext;
1065
1567
  try {
1066
1568
  ciphertext = await fs4.readFile(file);
@@ -1098,7 +1600,7 @@ var decryptCommand = new Command30("decrypt").description("Decrypt a file using
1098
1600
  });
1099
1601
 
1100
1602
  // src/commands/xmtp.ts
1101
- import { Command as Command31 } from "commander";
1603
+ import { Command as Command41 } from "commander";
1102
1604
 
1103
1605
  // src/lib/xmtp-client.ts
1104
1606
  import os2 from "os";
@@ -5157,11 +5659,14 @@ var TaskStatus = external_exports.enum([
5157
5659
  "claimed",
5158
5660
  "worker_selected",
5159
5661
  "pending_approval",
5160
- "accepted",
5662
+ "review",
5663
+ "appealing",
5664
+ "disputed",
5161
5665
  "completed",
5162
5666
  "expired",
5163
- "disputed"
5667
+ "cancelled"
5164
5668
  ]);
5669
+ var AuctionType = external_exports.enum(["dutch", "english", "reverse_dutch", "reverse_english"]);
5165
5670
  var TaskCreateSchema = external_exports.object({
5166
5671
  description: external_exports.string().min(1, "Description is required").max(2e3, "Description is too long"),
5167
5672
  reward: external_exports.string().min(1, "Reward is required"),
@@ -5174,7 +5679,17 @@ var TaskCreateSchema = external_exports.object({
5174
5679
  bidDeadline: external_exports.number().positive().optional(),
5175
5680
  maxPrice: external_exports.string().optional(),
5176
5681
  metricDescription: external_exports.string().max(500).optional(),
5177
- metricTarget: external_exports.string().max(200).optional()
5682
+ metricTarget: external_exports.string().max(200).optional(),
5683
+ auctionType: AuctionType.optional(),
5684
+ auctionStartPrice: external_exports.string().optional(),
5685
+ auctionFloorPrice: external_exports.string().optional(),
5686
+ hookContract: external_exports.string().optional(),
5687
+ hookData: external_exports.string().regex(/^0x(?:[0-9a-fA-F]{2})*$/, "hookData must be hex-encoded bytes (0x followed by pairs of hex digits)").optional(),
5688
+ evaluator: external_exports.string().optional(),
5689
+ evaluatorFeeBps: external_exports.number().min(0).max(1e4).optional(),
5690
+ evaluationWindowHours: external_exports.number().positive().optional(),
5691
+ appealWindowHours: external_exports.number().positive().optional(),
5692
+ disputeResolver: external_exports.string().optional()
5178
5693
  });
5179
5694
  var TaskResponseSchema = external_exports.object({
5180
5695
  id: external_exports.string(),
@@ -5203,23 +5718,38 @@ var TaskResponseSchema = external_exports.object({
5203
5718
  submissionCount: external_exports.number().optional().default(0),
5204
5719
  pitchCount: external_exports.number().optional().default(0),
5205
5720
  requesterAgentId: external_exports.string().nullable().optional(),
5206
- workerAgentId: external_exports.string().nullable().optional()
5721
+ requesterActorType: external_exports.enum(["agent", "human"]).optional(),
5722
+ workerAgentId: external_exports.string().nullable().optional(),
5723
+ workerActorType: external_exports.enum(["agent", "human"]).optional(),
5724
+ auctionType: AuctionType.nullable().optional(),
5725
+ auctionStartPrice: external_exports.string().nullable().optional(),
5726
+ auctionFloorPrice: external_exports.string().nullable().optional(),
5727
+ currentAuctionPrice: external_exports.string().nullable().optional(),
5728
+ auctionBidCount: external_exports.number().nullable().optional(),
5729
+ auctionPriceReachesFloorAt: external_exports.string().nullable().optional(),
5730
+ auctionPriceReachesMaxAt: external_exports.string().nullable().optional(),
5731
+ currentLowestBid: external_exports.string().nullable().optional(),
5732
+ hookContract: external_exports.string().nullable().optional(),
5733
+ evaluator: external_exports.string().nullable().optional(),
5734
+ evaluatorStake: external_exports.string().nullable().optional(),
5735
+ evaluatorFeeBps: external_exports.number().nullable().optional(),
5736
+ evaluationWindow: external_exports.number().nullable().optional(),
5737
+ appealWindow: external_exports.number().nullable().optional(),
5738
+ disputeResolver: external_exports.string().nullable().optional(),
5739
+ appealDeadline: external_exports.string().nullable().optional(),
5740
+ evaluatorDeadline: external_exports.string().nullable().optional(),
5741
+ verdictType: external_exports.enum(["APPROVE", "REJECT", "PARTIAL"]).nullable().optional(),
5742
+ verdictScore: external_exports.number().nullable().optional(),
5743
+ verdictConfidence: external_exports.number().nullable().optional(),
5744
+ verdictEvidenceHash: external_exports.string().nullable().optional()
5207
5745
  });
5208
5746
  var TaskListInputSchema = external_exports.object({
5209
5747
  limit: external_exports.number().min(1).max(100).optional().default(20),
5210
5748
  cursor: external_exports.string().optional(),
5211
- status: external_exports.enum([
5212
- "ALL",
5213
- "open",
5214
- "claimed",
5215
- "worker_selected",
5216
- "pending_approval",
5217
- "accepted",
5218
- "completed",
5219
- "expired",
5220
- "disputed"
5221
- ]).optional().default("ALL"),
5749
+ status: external_exports.union([TaskStatus, external_exports.literal("ALL")]).optional().default("ALL"),
5222
5750
  mode: external_exports.enum(["ALL", "bounty", "claim", "pitch", "benchmark", "auction"]).optional().default("ALL"),
5751
+ auctionType: AuctionType.optional(),
5752
+ requesterActorType: external_exports.enum(["agent", "human"]).optional(),
5223
5753
  tags: external_exports.array(external_exports.string()).optional(),
5224
5754
  minReward: external_exports.string().optional(),
5225
5755
  maxReward: external_exports.string().optional(),
@@ -5237,20 +5767,88 @@ var TaskInboxResponseSchema = external_exports.object({
5237
5767
  asRequester: external_exports.array(TaskResponseSchema),
5238
5768
  asWorker: external_exports.array(TaskResponseSchema)
5239
5769
  });
5770
+ var PendingActionName = external_exports.enum([
5771
+ "accept",
5772
+ "appeal",
5773
+ "auction_accept",
5774
+ "bid",
5775
+ "cancel",
5776
+ "claim",
5777
+ "evaluate",
5778
+ "evaluator_timeout",
5779
+ "finalize_verdict",
5780
+ "forfeit",
5781
+ "pitch",
5782
+ "rate",
5783
+ "resolve_dispute",
5784
+ "select_winner",
5785
+ "select_worker",
5786
+ "submit",
5787
+ "submit_proof",
5788
+ "update"
5789
+ ]);
5240
5790
  var PendingActionSchema = external_exports.object({
5241
- role: external_exports.enum(["requester", "worker"]),
5242
- action: external_exports.string(),
5791
+ role: external_exports.enum(["requester", "worker", "evaluator", "dispute_resolver", "anyone"]),
5792
+ action: PendingActionName,
5243
5793
  command: external_exports.string()
5244
5794
  });
5245
5795
  var TaskDetailResponseSchema = TaskResponseSchema.extend({
5246
5796
  pendingActions: PendingActionSchema.array()
5247
5797
  });
5798
+ var CancelTaskInputSchema = external_exports.object({
5799
+ taskId: external_exports.string()
5800
+ });
5801
+ var UpdateTaskInputSchema = external_exports.object({
5802
+ taskId: external_exports.string(),
5803
+ reward: external_exports.string().optional(),
5804
+ expiryTime: external_exports.number().optional(),
5805
+ bidDeadline: external_exports.number().optional(),
5806
+ pitchDeadline: external_exports.number().optional(),
5807
+ auctionFloorPrice: external_exports.string().optional(),
5808
+ auctionStartPrice: external_exports.string().optional(),
5809
+ description: external_exports.string().optional(),
5810
+ tags: external_exports.array(external_exports.string()).optional(),
5811
+ metricDescription: external_exports.string().optional()
5812
+ });
5248
5813
 
5249
5814
  // ../../packages/shared/dist/schemas/submission.schemas.js
5815
+ var ArtifactRole = external_exports.enum(["preview", "source", "final", "attachment"]);
5816
+ var ArtifactMediaKind = external_exports.enum([
5817
+ "image",
5818
+ "video",
5819
+ "audio",
5820
+ "pdf",
5821
+ "text",
5822
+ "archive",
5823
+ "unknown"
5824
+ ]);
5825
+ var ArtifactCreateSchema = external_exports.object({
5826
+ fileName: external_exports.string().min(1, "File name is required").max(255, "File name is too long"),
5827
+ mimeType: external_exports.string().min(1, "MIME type is required").max(120, "MIME type is too long"),
5828
+ role: ArtifactRole.optional().default("attachment"),
5829
+ file: external_exports.string().min(1, "File is required")
5830
+ });
5831
+ var ArtifactResponseSchema = external_exports.object({
5832
+ id: external_exports.string(),
5833
+ taskId: external_exports.string(),
5834
+ submissionId: external_exports.string(),
5835
+ workerAddress: external_exports.string(),
5836
+ workerAgentId: external_exports.string().nullable(),
5837
+ role: ArtifactRole,
5838
+ fileName: external_exports.string(),
5839
+ mimeType: external_exports.string(),
5840
+ mediaKind: ArtifactMediaKind,
5841
+ storageUri: external_exports.string(),
5842
+ sizeBytes: external_exports.number(),
5843
+ sha256Hash: external_exports.string(),
5844
+ keccak256Hash: external_exports.string(),
5845
+ displayOrder: external_exports.number(),
5846
+ textPreview: external_exports.string().optional()
5847
+ });
5250
5848
  var SubmissionCreateSchema = external_exports.object({
5251
5849
  taskId: external_exports.string(),
5252
5850
  workerAddress: external_exports.string(),
5253
- file: external_exports.string().min(1, "File is required"),
5851
+ artifacts: external_exports.array(ArtifactCreateSchema).min(1).max(20),
5254
5852
  signature: external_exports.string()
5255
5853
  });
5256
5854
  var SubmissionResponseSchema = external_exports.object({
@@ -5261,6 +5859,9 @@ var SubmissionResponseSchema = external_exports.object({
5261
5859
  signature: external_exports.string(),
5262
5860
  submittedAt: external_exports.string(),
5263
5861
  workerAgentId: external_exports.string().nullable().optional(),
5862
+ deliverableHash: external_exports.string().nullable().optional(),
5863
+ submitTxHash: external_exports.string().nullable().optional(),
5864
+ artifacts: external_exports.array(ArtifactResponseSchema).optional().default([]),
5264
5865
  workerStats: external_exports.object({
5265
5866
  completedTasks: external_exports.number(),
5266
5867
  ratedTasks: external_exports.number(),
@@ -5269,7 +5870,8 @@ var SubmissionResponseSchema = external_exports.object({
5269
5870
  }).nullable().optional()
5270
5871
  });
5271
5872
  var DownloadRequestSchema = external_exports.object({
5272
- acceptanceTxHash: external_exports.string()
5873
+ acceptanceTxHash: external_exports.string(),
5874
+ artifactId: external_exports.string().optional()
5273
5875
  });
5274
5876
  var DownloadResponseSchema = external_exports.object({
5275
5877
  fileUrl: external_exports.string(),
@@ -5278,9 +5880,12 @@ var DownloadResponseSchema = external_exports.object({
5278
5880
  });
5279
5881
 
5280
5882
  // ../../packages/shared/dist/schemas/agent.schemas.js
5883
+ var ActorType = external_exports.enum(["agent", "human"]);
5884
+ var RegistrationSource = external_exports.enum(["cli", "web"]);
5281
5885
  var AgentStatsSchema = external_exports.object({
5282
5886
  address: external_exports.string(),
5283
5887
  agentId: external_exports.string().nullable().optional(),
5888
+ actorType: ActorType.optional(),
5284
5889
  completedTasks: external_exports.number(),
5285
5890
  ratedTasks: external_exports.number(),
5286
5891
  totalStars: external_exports.number(),
@@ -5288,12 +5893,18 @@ var AgentStatsSchema = external_exports.object({
5288
5893
  totalEarnings: external_exports.string(),
5289
5894
  skills: external_exports.array(external_exports.string()).optional(),
5290
5895
  emailAddress: external_exports.string().nullable().optional(),
5896
+ credibility: external_exports.number().int().min(0).max(1e3).optional(),
5291
5897
  recentRatings: external_exports.array(external_exports.object({
5292
5898
  taskId: external_exports.string(),
5293
5899
  rating: external_exports.number(),
5294
- createdAt: external_exports.string()
5900
+ createdAt: external_exports.string(),
5901
+ taskTitle: external_exports.string().nullable().optional(),
5902
+ feedbackText: external_exports.string().nullable().optional()
5295
5903
  })).optional()
5296
5904
  });
5905
+ var AgentRegistrationInputSchema = external_exports.object({
5906
+ source: RegistrationSource.optional().default("cli")
5907
+ });
5297
5908
  var LeaderboardInputSchema = external_exports.object({
5298
5909
  limit: external_exports.number().optional().default(20),
5299
5910
  offset: external_exports.number().optional().default(0),
@@ -5301,17 +5912,20 @@ var LeaderboardInputSchema = external_exports.object({
5301
5912
  skill: external_exports.string().optional(),
5302
5913
  search: external_exports.string().optional(),
5303
5914
  minRating: external_exports.number().min(0).max(5).optional(),
5304
- minTasks: external_exports.number().int().min(0).optional()
5915
+ minTasks: external_exports.number().int().min(0).optional(),
5916
+ actorType: ActorType.optional()
5305
5917
  });
5306
5918
  var LeaderboardEntrySchema = external_exports.object({
5307
5919
  rank: external_exports.number(),
5308
5920
  address: external_exports.string(),
5309
5921
  agentId: external_exports.string().nullable(),
5922
+ actorType: ActorType.optional(),
5310
5923
  completedTasks: external_exports.number(),
5311
5924
  averageRating: external_exports.number(),
5312
5925
  totalEarnings: external_exports.string(),
5313
5926
  skills: external_exports.array(external_exports.string()),
5314
- emailAddress: external_exports.string().nullable().optional()
5927
+ emailAddress: external_exports.string().nullable().optional(),
5928
+ credibility: external_exports.number().int().min(0).max(1e3).optional()
5315
5929
  });
5316
5930
  var LeaderboardResponseSchema = external_exports.array(LeaderboardEntrySchema);
5317
5931
 
@@ -5320,7 +5934,8 @@ var RatingInputSchema = external_exports.object({
5320
5934
  taskId: external_exports.string(),
5321
5935
  worker: external_exports.string(),
5322
5936
  rating: external_exports.number().int().min(0).max(100),
5323
- feedbackText: external_exports.string().max(500).optional()
5937
+ feedbackText: external_exports.string().max(500).optional(),
5938
+ raterAgentId: external_exports.number().int().nonnegative().optional()
5324
5939
  });
5325
5940
  var FeedbackSchema = external_exports.object({
5326
5941
  id: external_exports.string(),
@@ -5390,7 +6005,16 @@ var ClaimResponseSchema = external_exports.object({
5390
6005
  });
5391
6006
 
5392
6007
  // ../../packages/shared/dist/schemas/proof.schemas.js
5393
- var ProofType = external_exports.enum(["url", "screenshot", "api_data", "manual"]);
6008
+ var ProofType = external_exports.enum([
6009
+ "url",
6010
+ "screenshot",
6011
+ "api_data",
6012
+ "manual",
6013
+ "custom",
6014
+ "eval",
6015
+ "tlsn",
6016
+ "zk"
6017
+ ]);
5394
6018
  var ProofStatus = external_exports.enum(["pending", "verified", "rejected"]);
5395
6019
  var ProofSubmitSchema = external_exports.object({
5396
6020
  taskId: external_exports.string().min(1, "Task ID is required"),
@@ -5417,13 +6041,18 @@ var BidCreateSchema = external_exports.object({
5417
6041
  taskId: external_exports.string().min(1, "Task ID is required"),
5418
6042
  price: external_exports.string().min(1, "Price is required")
5419
6043
  });
6044
+ var AuctionAcceptSchema = external_exports.object({
6045
+ taskId: external_exports.string().min(1, "Task ID is required"),
6046
+ minPrice: external_exports.string().optional()
6047
+ });
5420
6048
  var BidResponseSchema = external_exports.object({
5421
6049
  id: external_exports.string(),
5422
6050
  taskId: external_exports.string(),
5423
- workerAddress: external_exports.string(),
5424
- price: external_exports.string(),
6051
+ workerAddress: external_exports.string().nullable(),
6052
+ price: external_exports.string().nullable(),
5425
6053
  createdAt: external_exports.string(),
5426
- workerAgentId: external_exports.string().nullable().optional()
6054
+ workerAgentId: external_exports.string().nullable().optional(),
6055
+ isMyBid: external_exports.boolean().optional()
5427
6056
  });
5428
6057
 
5429
6058
  // ../../packages/shared/dist/schemas/wallet.schemas.js
@@ -5571,6 +6200,20 @@ var EmailInboundHeadersSchema = external_exports.object({
5571
6200
  "x-email-from": external_exports.string(),
5572
6201
  "x-email-to": external_exports.string().email()
5573
6202
  });
6203
+ var BroadcastInputSchema = external_exports.object({
6204
+ subject: external_exports.string().min(1).max(200),
6205
+ body: external_exports.string().min(1).max(5e4),
6206
+ filters: external_exports.object({
6207
+ skills: external_exports.array(external_exports.string()).max(20).optional(),
6208
+ minTasks: external_exports.number().int().min(0).optional(),
6209
+ actorType: external_exports.enum(["agent", "human", "all"]).optional()
6210
+ }).optional()
6211
+ });
6212
+ var BroadcastResultSchema = external_exports.object({
6213
+ sent: external_exports.number(),
6214
+ failed: external_exports.number(),
6215
+ total: external_exports.number()
6216
+ });
5574
6217
 
5575
6218
  // ../../packages/shared/dist/lib/agentName.js
5576
6219
  var MODIFIERS = [
@@ -6595,7 +7238,7 @@ function getDefaultQueryTimeoutMs() {
6595
7238
  }
6596
7239
  return Math.floor(parsed);
6597
7240
  }
6598
- var xmtpCommand = new Command31("xmtp").description("Manage XMTP messaging for this agent");
7241
+ var xmtpCommand = new Command41("xmtp").description("Manage XMTP messaging for this agent");
6599
7242
  xmtpCommand.command("init").description("Initialize XMTP client and register installation metadata with backend").action(async () => {
6600
7243
  const keystore = await loadKeystore();
6601
7244
  const client = await createXmtpClient({
@@ -6823,7 +7466,7 @@ xmtpCommand.command("purge").description("Revoke stale XMTP installations that h
6823
7466
  });
6824
7467
 
6825
7468
  // src/commands/daemon.ts
6826
- import { Command as Command32 } from "commander";
7469
+ import { Command as Command42 } from "commander";
6827
7470
  function diffTaskStatuses(prev, next) {
6828
7471
  const changes = [];
6829
7472
  for (const [taskId, newStatus] of next) {
@@ -6851,11 +7494,17 @@ function sleepOrAbort(ms, signal) {
6851
7494
  });
6852
7495
  }
6853
7496
  var MAX_SEEN_TASK_IDS = 2e3;
6854
- var daemonCommand = new Command32("daemon").description("Long-running agent daemon: XMTP stream, heartbeats, and task polling").option("--heartbeat-interval <ms>", "Heartbeat interval in milliseconds", "1800000").option("--inbox-interval <ms>", "Inbox poll interval in milliseconds", "15000").option("--task-interval <ms>", "New task poll interval in milliseconds", "60000").option("--task-filters <json>", "JSON filter object for new-task discovery").option("--no-xmtp", "Disable XMTP stream and heartbeat").action(
7497
+ var daemonCommand = new Command42("daemon").description("Long-running agent daemon: XMTP stream, heartbeats, and task polling").option("--heartbeat-interval <ms>", "Heartbeat interval in milliseconds", "1800000").option("--inbox-interval <ms>", "Inbox poll interval in milliseconds", "15000").option("--task-interval <ms>", "New task poll interval in milliseconds", "60000").option(
7498
+ "--auction-poll-interval <ms>",
7499
+ "Poll interval for clock-based auction tasks (dutch/reverse_dutch) in milliseconds",
7500
+ "15000"
7501
+ ).option("--email-poll-interval <ms>", "Email inbox poll interval in milliseconds", "60000").option("--task-filters <json>", "JSON filter object for new-task discovery").option("--no-xmtp", "Disable XMTP stream and heartbeat").action(
6855
7502
  async (opts) => {
6856
7503
  const heartbeatIntervalMs = Number(opts.heartbeatInterval);
6857
7504
  const inboxIntervalMs = Number(opts.inboxInterval);
6858
7505
  const taskIntervalMs = Number(opts.taskInterval);
7506
+ const auctionPollIntervalMs = Number(opts.auctionPollInterval);
7507
+ const emailPollIntervalMs = Number(opts.emailPollInterval);
6859
7508
  if (!Number.isFinite(heartbeatIntervalMs) || heartbeatIntervalMs <= 0) {
6860
7509
  throw new Error("--heartbeat-interval must be a positive number");
6861
7510
  }
@@ -6865,6 +7514,12 @@ var daemonCommand = new Command32("daemon").description("Long-running agent daem
6865
7514
  if (!Number.isFinite(taskIntervalMs) || taskIntervalMs <= 0) {
6866
7515
  throw new Error("--task-interval must be a positive number");
6867
7516
  }
7517
+ if (!Number.isFinite(auctionPollIntervalMs) || auctionPollIntervalMs <= 0) {
7518
+ throw new Error("--auction-poll-interval must be a positive number");
7519
+ }
7520
+ if (!Number.isFinite(emailPollIntervalMs) || emailPollIntervalMs <= 0) {
7521
+ throw new Error("--email-poll-interval must be a positive number");
7522
+ }
6868
7523
  let taskFilters = {};
6869
7524
  if (opts.taskFilters) {
6870
7525
  try {
@@ -7057,7 +7712,99 @@ var daemonCommand = new Command32("daemon").description("Long-running agent daem
7057
7712
  }
7058
7713
  }
7059
7714
  };
7060
- await Promise.allSettled([inboxPollLoop(), newTaskPollLoop()]);
7715
+ const auctionPollLoop = async () => {
7716
+ while (!stopped) {
7717
+ await sleepOrAbort(auctionPollIntervalMs, abortController.signal);
7718
+ if (stopped) break;
7719
+ try {
7720
+ let cursor;
7721
+ let hasMore = true;
7722
+ while (hasMore) {
7723
+ const params = new URLSearchParams({
7724
+ mode: "auction",
7725
+ status: "open",
7726
+ limit: "50"
7727
+ });
7728
+ if (cursor) params.set("cursor", cursor);
7729
+ const result = await apiGet(`/api/tasks?${params.toString()}`);
7730
+ for (const task of result.tasks) {
7731
+ if (task.auctionType === "dutch" || task.auctionType === "reverse_dutch") {
7732
+ printResult({
7733
+ event: "task.auction_clock",
7734
+ taskId: task.id,
7735
+ auctionType: task.auctionType,
7736
+ currentAuctionPrice: task.currentAuctionPrice ?? null,
7737
+ bidDeadline: task.bidDeadline ?? null
7738
+ });
7739
+ }
7740
+ }
7741
+ cursor = result.nextCursor ?? void 0;
7742
+ hasMore = result.hasMore && cursor !== void 0;
7743
+ }
7744
+ } catch (err) {
7745
+ process.stderr.write(
7746
+ `Auction poll failed: ${err instanceof Error ? err.message : String(err)}
7747
+ `
7748
+ );
7749
+ }
7750
+ }
7751
+ };
7752
+ const emailPollLoop = async () => {
7753
+ const PAGE_SIZE = 50;
7754
+ while (!stopped) {
7755
+ await sleepOrAbort(emailPollIntervalMs, abortController.signal);
7756
+ if (stopped) break;
7757
+ try {
7758
+ let hasMore = true;
7759
+ while (hasMore) {
7760
+ const params = new URLSearchParams({
7761
+ deviceId: keystore.deviceId,
7762
+ apiToken: keystore.apiToken,
7763
+ limit: String(PAGE_SIZE),
7764
+ unread: "true"
7765
+ });
7766
+ const result = await apiGet(
7767
+ `/api/emails/list?${params.toString()}`
7768
+ );
7769
+ for (const email of result.emails) {
7770
+ printResult({
7771
+ event: "email.new",
7772
+ id: email.id,
7773
+ fromAddress: email.fromAddress,
7774
+ subject: email.subject,
7775
+ bodyText: email.bodyText,
7776
+ receivedAt: email.receivedAt
7777
+ });
7778
+ try {
7779
+ await apiPost("/api/emails/mark-read", {
7780
+ deviceId: keystore.deviceId,
7781
+ apiToken: keystore.apiToken,
7782
+ id: email.id,
7783
+ read: true
7784
+ });
7785
+ } catch (markErr) {
7786
+ process.stderr.write(
7787
+ `Email mark-read failed for ${email.id}: ${markErr instanceof Error ? markErr.message : String(markErr)}
7788
+ `
7789
+ );
7790
+ }
7791
+ }
7792
+ hasMore = result.emails.length === PAGE_SIZE;
7793
+ }
7794
+ } catch (err) {
7795
+ process.stderr.write(
7796
+ `Email poll failed: ${err instanceof Error ? err.message : String(err)}
7797
+ `
7798
+ );
7799
+ }
7800
+ }
7801
+ };
7802
+ await Promise.allSettled([
7803
+ inboxPollLoop(),
7804
+ newTaskPollLoop(),
7805
+ auctionPollLoop(),
7806
+ emailPollLoop()
7807
+ ]);
7061
7808
  };
7062
7809
  await Promise.allSettled([xmtpLoop(), heartbeatLoop(), taskPollLoop()]);
7063
7810
  } finally {
@@ -7068,11 +7815,11 @@ var daemonCommand = new Command32("daemon").description("Long-running agent daem
7068
7815
  );
7069
7816
 
7070
7817
  // src/commands/email/index.ts
7071
- import { Command as Command41 } from "commander";
7818
+ import { Command as Command51 } from "commander";
7072
7819
 
7073
7820
  // src/commands/email/register.ts
7074
- import { Command as Command33 } from "commander";
7075
- var registerCommand = new Command33("register").description("Register an email address for this agent").requiredOption("--username <name>", "Desired username (e.g. myagent)").action(async (opts) => {
7821
+ import { Command as Command43 } from "commander";
7822
+ var registerCommand = new Command43("register").description("Register an email address for this agent").requiredOption("--username <name>", "Desired username (e.g. myagent)").action(async (opts) => {
7076
7823
  const check = await apiGet(
7077
7824
  `/api/emails/check-username?username=${encodeURIComponent(opts.username)}`
7078
7825
  );
@@ -7089,8 +7836,8 @@ var registerCommand = new Command33("register").description("Register an email a
7089
7836
  });
7090
7837
 
7091
7838
  // src/commands/email/inbox.ts
7092
- import { Command as Command34 } from "commander";
7093
- var inboxCommand2 = new Command34("inbox").description("List emails in your inbox").option("--limit <n>", "Number of emails to return", "20").option("--unread", "Show only unread emails").action(async (opts) => {
7839
+ import { Command as Command44 } from "commander";
7840
+ var inboxCommand2 = new Command44("inbox").description("List emails in your inbox").option("--limit <n>", "Number of emails to return", "20").option("--unread", "Show only unread emails").action(async (opts) => {
7094
7841
  const keystore = await loadKeystore();
7095
7842
  const params = new URLSearchParams({
7096
7843
  deviceId: keystore.deviceId,
@@ -7105,8 +7852,8 @@ var inboxCommand2 = new Command34("inbox").description("List emails in your inbo
7105
7852
  });
7106
7853
 
7107
7854
  // src/commands/email/read.ts
7108
- import { Command as Command35 } from "commander";
7109
- var readCommand = new Command35("read").description("Read an email by ID (marks it as read)").argument("<id>", "Email ID").action(async (id) => {
7855
+ import { Command as Command45 } from "commander";
7856
+ var readCommand = new Command45("read").description("Read an email by ID (marks it as read)").argument("<id>", "Email ID").action(async (id) => {
7110
7857
  const keystore = await loadKeystore();
7111
7858
  const params = new URLSearchParams({
7112
7859
  deviceId: keystore.deviceId,
@@ -7118,8 +7865,8 @@ var readCommand = new Command35("read").description("Read an email by ID (marks
7118
7865
  });
7119
7866
 
7120
7867
  // src/commands/email/send.ts
7121
- import { Command as Command36 } from "commander";
7122
- var sendCommand = new Command36("send").description("Send an email").requiredOption("--to <address>", "Recipient email address").requiredOption("--subject <subject>", "Email subject").requiredOption("--body <text>", "Email body text").action(async (opts) => {
7868
+ import { Command as Command46 } from "commander";
7869
+ var sendCommand = new Command46("send").description("Send an email").requiredOption("--to <address>", "Recipient email address").requiredOption("--subject <subject>", "Email subject").requiredOption("--body <text>", "Email body text").action(async (opts) => {
7123
7870
  const keystore = await loadKeystore();
7124
7871
  const result = await apiPost("/api/emails/send", {
7125
7872
  deviceId: keystore.deviceId,
@@ -7132,8 +7879,8 @@ var sendCommand = new Command36("send").description("Send an email").requiredOpt
7132
7879
  });
7133
7880
 
7134
7881
  // src/commands/email/reply.ts
7135
- import { Command as Command37 } from "commander";
7136
- var replyCommand = new Command37("reply").description("Reply to an email").argument("<id>", "Email ID to reply to").requiredOption("--body <text>", "Reply body text").action(async (id, opts) => {
7882
+ import { Command as Command47 } from "commander";
7883
+ var replyCommand = new Command47("reply").description("Reply to an email").argument("<id>", "Email ID to reply to").requiredOption("--body <text>", "Reply body text").action(async (id, opts) => {
7137
7884
  const keystore = await loadKeystore();
7138
7885
  const params = new URLSearchParams({
7139
7886
  deviceId: keystore.deviceId,
@@ -7155,8 +7902,8 @@ var replyCommand = new Command37("reply").description("Reply to an email").argum
7155
7902
  });
7156
7903
 
7157
7904
  // src/commands/email/delete.ts
7158
- import { Command as Command38 } from "commander";
7159
- var deleteCommand = new Command38("delete").description("Delete an email by ID").argument("<id>", "Email ID").action(async (id) => {
7905
+ import { Command as Command48 } from "commander";
7906
+ var deleteCommand = new Command48("delete").description("Delete an email by ID").argument("<id>", "Email ID").action(async (id) => {
7160
7907
  const keystore = await loadKeystore();
7161
7908
  const result = await apiPost("/api/emails/delete", {
7162
7909
  deviceId: keystore.deviceId,
@@ -7167,15 +7914,15 @@ var deleteCommand = new Command38("delete").description("Delete an email by ID")
7167
7914
  });
7168
7915
 
7169
7916
  // src/commands/email/address.ts
7170
- import { Command as Command39 } from "commander";
7171
- var addressCommand2 = new Command39("address").description("Show your registered email address").action(async () => {
7917
+ import { Command as Command49 } from "commander";
7918
+ var addressCommand2 = new Command49("address").description("Show your registered email address").action(async () => {
7172
7919
  const keystore = await loadKeystore();
7173
7920
  const result = await apiGet(`/api/agents/stats?address=${keystore.walletAddress}`);
7174
7921
  printResult({ emailAddress: result.emailAddress ?? null });
7175
7922
  });
7176
7923
 
7177
7924
  // src/commands/email/mark-read.ts
7178
- import { Command as Command40 } from "commander";
7925
+ import { Command as Command50 } from "commander";
7179
7926
  async function setReadStatus(id, read) {
7180
7927
  const keystore = await loadKeystore();
7181
7928
  const result = await apiPost("/api/emails/mark-read", {
@@ -7186,12 +7933,12 @@ async function setReadStatus(id, read) {
7186
7933
  });
7187
7934
  printResult({ id: result.id, isRead: result.isRead });
7188
7935
  }
7189
- var markReadCommand = new Command40("mark-read").description("Mark an email as read or unread").argument("<id>", "Email ID").option("--unread", "Mark as unread instead of read").action(async (id, opts) => {
7936
+ var markReadCommand = new Command50("mark-read").description("Mark an email as read or unread").argument("<id>", "Email ID").option("--unread", "Mark as unread instead of read").action(async (id, opts) => {
7190
7937
  await setReadStatus(id, !opts.unread);
7191
7938
  });
7192
7939
 
7193
7940
  // src/commands/email/index.ts
7194
- var emailCommand = new Command41("email").description("Email management commands");
7941
+ var emailCommand = new Command51("email").description("Email management commands");
7195
7942
  emailCommand.addCommand(registerCommand);
7196
7943
  emailCommand.addCommand(inboxCommand2);
7197
7944
  emailCommand.addCommand(readCommand);
@@ -7204,7 +7951,7 @@ emailCommand.addCommand(markReadCommand);
7204
7951
  // src/index.ts
7205
7952
  var require2 = createRequire(import.meta.url);
7206
7953
  var { version } = require2("../package.json");
7207
- var program = new Command42();
7954
+ var program = new Command52();
7208
7955
  program.name("taskmarket").description("Taskmarket CLI for AI agents").version(version);
7209
7956
  program.addCommand(initCommand);
7210
7957
  program.addCommand(walletCommand);