@lucid-agents/taskmarket 1.20.3 → 1.21.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-H2XTB3NF.js";
17
+ } from "./chunk-5N25NATR.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-4EN2RUZ3.js";
39
+ } from "./chunk-TAMXCFLT.js";
40
40
  import {
41
41
  MPP_TEMPO_DEFAULT_VALIDITY_SECONDS,
42
42
  X402PayError,
@@ -58,7 +58,7 @@ import {
58
58
  signSponsoredTempoTransfer,
59
59
  signTaskmarketFeePayment,
60
60
  signTypedData
61
- } from "./chunk-EMIVR2MT.js";
61
+ } from "./chunk-HE2N4GEO.js";
62
62
  import {
63
63
  AgentMessageEnvelopeSchema,
64
64
  ApiError,
@@ -75,6 +75,7 @@ import {
75
75
  LegalStatusResponseSchema,
76
76
  NETWORKS,
77
77
  NETWORK_NAMES,
78
+ NetworkRequiredError,
78
79
  PUBLIC_BUG_REPORT_SORTS,
79
80
  PenaltyTo,
80
81
  PostBugReportMessageInputSchema,
@@ -138,14 +139,17 @@ import {
138
139
  formatPaymentAmount,
139
140
  formatUsdcBaseUnits,
140
141
  generateKeypair,
142
+ getNetwork,
141
143
  getTaskmarketHome,
142
144
  idempotencyKeyForError,
143
145
  isInFlightApiError,
146
+ isNetworkName,
144
147
  isPendingApiError,
145
148
  isRecordingPendingResponse,
146
149
  isTaskmarketChainId,
147
150
  isTerminalWalletBridgeStatus,
148
151
  keystoreExists,
152
+ liveNetworkNames,
149
153
  loadKeystore,
150
154
  networkToStamp,
151
155
  paymentProtocolOf,
@@ -158,6 +162,7 @@ import {
158
162
  resolveTaskTerms,
159
163
  saveKeystore,
160
164
  selectedNetwork,
165
+ selectedNetworkOrUndefined,
161
166
  setSelectedNetwork,
162
167
  settlementActionExpiresAt,
163
168
  settlementActionRequiresExpiry,
@@ -167,7 +172,7 @@ import {
167
172
  withChainId,
168
173
  withErrorContext,
169
174
  withIdempotentWrite
170
- } from "./chunk-4SG3R5IH.js";
175
+ } from "./chunk-3IIVNF5F.js";
171
176
  import {
172
177
  channelLines
173
178
  } from "./chunk-XJOB4NMV.js";
@@ -180,6 +185,7 @@ import { createRequire } from "module";
180
185
  // src/commands/init.ts
181
186
  import { Command as Command2 } from "commander";
182
187
  import { privateKeyToAccount } from "viem/accounts";
188
+ import { createInterface as createInterface2 } from "readline";
183
189
 
184
190
  // src/lib/last-error.ts
185
191
  import fs from "fs";
@@ -308,21 +314,38 @@ function printWarning(message) {
308
314
  }
309
315
 
310
316
  // src/lib/agent.ts
317
+ function legacyAgentIdChain(keystore) {
318
+ const network = keystore.network;
319
+ return network && isNetworkName(network) ? NETWORKS[network].chainId : void 0;
320
+ }
321
+ function agentIdForChain(keystore, chainId) {
322
+ const stored = keystore.agentIds?.[String(chainId)];
323
+ if (stored) return stored;
324
+ if (keystore.agentId && legacyAgentIdChain(keystore) === chainId) return keystore.agentId;
325
+ return null;
326
+ }
327
+ function withAgentIdForChain(keystore, chainId, agentId) {
328
+ return { ...keystore, agentIds: { ...keystore.agentIds, [String(chainId)]: agentId } };
329
+ }
330
+ async function lookupAgentId(address, chainId = selectedNetwork().chainId) {
331
+ try {
332
+ const res = await fetch(
333
+ `${apiUrl()}/api/identity/status?address=${address}&chainId=${chainId}`
334
+ );
335
+ if (!res.ok) return null;
336
+ const data = await res.json();
337
+ return data.agentId ?? null;
338
+ } catch {
339
+ return null;
340
+ }
341
+ }
311
342
  async function pollAgentId(address, maxWaitMs = 6e4) {
312
343
  const interval = 3e3;
313
344
  const deadline = Date.now() + maxWaitMs;
314
345
  while (Date.now() < deadline) {
315
346
  await new Promise((r) => setTimeout(r, interval));
316
- try {
317
- const res = await fetch(
318
- `${apiUrl()}/api/identity/status?address=${address}&chainId=${selectedNetwork().chainId}`
319
- );
320
- if (res.ok) {
321
- const data = await res.json();
322
- if (data.agentId) return data.agentId;
323
- }
324
- } catch {
325
- }
347
+ const agentId = await lookupAgentId(address);
348
+ if (agentId) return agentId;
326
349
  }
327
350
  return null;
328
351
  }
@@ -599,13 +622,42 @@ async function tryRegisterEmail(deviceId, apiToken, username, explicit) {
599
622
  return null;
600
623
  }
601
624
  }
602
- var initCommand = new Command2("init").description("Create and register a new agent wallet (safe to re-run)").option(
625
+ function terminalIo() {
626
+ return {
627
+ interactive: Boolean(process.stdin.isTTY && process.stderr.isTTY),
628
+ ask: (question) => new Promise((resolve) => {
629
+ const rl = createInterface2({ input: process.stdin, output: process.stderr });
630
+ rl.question(question, (answer) => {
631
+ rl.close();
632
+ resolve(answer);
633
+ });
634
+ })
635
+ };
636
+ }
637
+ async function ensureInitNetwork(io = terminalIo()) {
638
+ if (selectedNetworkOrUndefined()) return;
639
+ if (!io.interactive) throw new NetworkRequiredError();
640
+ const answer = (await io.ask(`Network to use (${liveNetworkNames().join(", ")}): `)).trim();
641
+ if (!answer) throw new NetworkRequiredError();
642
+ setSelectedNetwork(getNetwork(answer));
643
+ }
644
+ function existingWalletMessage() {
645
+ return "This machine already has a Taskmarket wallet; init runs once and never replaces saved credentials. The same wallet and device credentials work on every network. To register its agent identity on another network, run: taskmarket --network <name> identity register";
646
+ }
647
+ var initCommand = new Command2("init").description(
648
+ "Create and register this machine's agent wallet (one-time; refuses when a wallet exists)"
649
+ ).option(
603
650
  "--email <username>",
604
651
  "Claim a custom email username (default: auto-generated from agent ID)"
605
652
  ).option(
606
653
  "--yes",
607
654
  "Confirm legal acceptance non-interactively after reviewing every current policy"
608
655
  ).action(async (opts) => {
656
+ if (await keystoreExists()) {
657
+ printError(existingWalletMessage());
658
+ return;
659
+ }
660
+ await ensureInitNetwork();
609
661
  if (opts.email) {
610
662
  const check = await apiGet(
611
663
  `/api/emails/check-username?username=${encodeURIComponent(opts.email)}`
@@ -615,56 +667,6 @@ var initCommand = new Command2("init").description("Create and register a new ag
615
667
  return;
616
668
  }
617
669
  }
618
- if (await keystoreExists()) {
619
- const keystore = await loadKeystore();
620
- let agentId2 = keystore.agentId;
621
- if (!agentId2) {
622
- agentId2 = await pollAgentId(keystore.walletAddress);
623
- if (agentId2) {
624
- await saveKeystore({ ...keystore, agentId: agentId2 });
625
- }
626
- }
627
- let networkInfo2;
628
- try {
629
- const response = await apiGet("/trpc/network.info");
630
- networkInfo2 = response.result.data;
631
- } catch {
632
- }
633
- let emailAddress2 = null;
634
- try {
635
- const existing = await apiGet(`/api/agents/stats?address=${keystore.walletAddress}`);
636
- emailAddress2 = existing.emailAddress ?? null;
637
- } catch {
638
- }
639
- if (!emailAddress2) {
640
- const username2 = opts.email ?? (agentId2 && networkInfo2 ? sanitizeEmailUsername(agentId2, String(selectedNetwork().chainId)) : null);
641
- if (username2) {
642
- emailAddress2 = await tryRegisterEmail(
643
- keystore.deviceId,
644
- keystore.apiToken,
645
- username2,
646
- !!opts.email
647
- );
648
- }
649
- }
650
- let chain2;
651
- try {
652
- chain2 = chainInfoFor(networkInfo2, selectedNetwork().chainId);
653
- } catch (err) {
654
- renderFailure(err);
655
- return;
656
- }
657
- printResult({
658
- address: keystore.walletAddress,
659
- agentId: agentId2,
660
- network: chain2?.networkName ?? networkInfo2?.networkName,
661
- chainId: chain2?.chainId ?? networkInfo2?.chainId,
662
- paymentMethod: chain2?.paymentMethod,
663
- feeModel: chain2?.feeModel,
664
- emailAddress: emailAddress2
665
- });
666
- return;
667
- }
668
670
  const { privateKey, address } = generateKeypair();
669
671
  const publicKey = deriveCompressedPublicKey(privateKey);
670
672
  const legalBundle = LegalBundleSchema.parse(await apiGet("/api/legal/current"));
@@ -696,6 +698,7 @@ var initCommand = new Command2("init").description("Create and register a new ag
696
698
  deviceId,
697
699
  apiToken,
698
700
  agentId,
701
+ ...agentId ? { agentIds: { [String(selectedNetwork().chainId)]: agentId } } : {},
699
702
  keyServerUrl: apiUrl(),
700
703
  network: networkToStamp(),
701
704
  ...legalAcceptance ? {
@@ -708,7 +711,9 @@ var initCommand = new Command2("init").description("Create and register a new ag
708
711
  agentId = await pollAgentId(address);
709
712
  if (agentId) {
710
713
  const keystore = await loadKeystore();
711
- await saveKeystore({ ...keystore, agentId });
714
+ await saveKeystore(
715
+ withAgentIdForChain({ ...keystore, agentId }, selectedNetwork().chainId, agentId)
716
+ );
712
717
  }
713
718
  }
714
719
  let networkInfo;
@@ -746,72 +751,35 @@ var addressCommand = new Command3("address").description("Print the wallet addre
746
751
 
747
752
  // src/commands/identity.ts
748
753
  import { Command as Command4 } from "commander";
749
-
750
- // src/lib/x402.ts
751
- var FACILITATOR_RETRIES = 2;
752
- var MAX_RETRY_AFTER_SECONDS = 60;
753
- var DEFAULT_RETRY_AFTER_SECONDS = 30;
754
- function retryAfterMs(res) {
755
- const header = res.headers?.get?.("retry-after");
756
- const seconds = header ? Number(header) : NaN;
757
- const wait = Number.isFinite(seconds) && seconds >= 0 ? seconds : DEFAULT_RETRY_AFTER_SECONDS;
758
- return Math.min(wait, MAX_RETRY_AFTER_SECONDS) * 1e3;
759
- }
760
- async function x402Post(path3, body, options) {
761
- const sleep4 = options?.sleep ?? ((ms) => new Promise((resolve) => setTimeout(resolve, ms)));
762
- if (paymentProtocolOf(selectedNetwork().chainId) === "mpp")
763
- return mppPost(path3, body, options);
754
+ var identityCommand = new Command4("identity").description("Manage agent identity");
755
+ identityCommand.command("register").description(
756
+ "Register this wallet's ERC-8004 agent identity on the selected network (free; uses this machine's existing credentials)"
757
+ ).action(async () => {
764
758
  const keystore = await loadKeystore();
765
- const idempotencyKey = resolveIdempotencyKey(options?.idempotencyKey);
766
- const request = paidWriteRequest(keystore, path3, body, idempotencyKey);
767
- return withIdempotentWrite(idempotencyKey, async () => {
768
- const r1 = await fetch(request.url, {
769
- method: "POST",
770
- redirect: "error",
771
- headers: request.headers,
772
- body: request.body
773
- });
774
- if (r1.status !== 402) {
775
- if (r1.ok) {
776
- return { data: await r1.json(), idempotencyKey };
777
- }
778
- throw refusedPaidWrite(path3, r1.status, await readFailureBody(r1), idempotencyKey);
779
- }
780
- const requirements = await r1.json();
781
- if (!requirements.accepts || requirements.accepts.length === 0) {
782
- throw new Error("No payment methods accepted by server");
783
- }
784
- const accept = requirements.accepts[0];
785
- const { header } = await signTaskmarketFeePayment({
786
- resource: requirements.resource,
787
- requirement: accept,
788
- typedData: accept.extra.eip712,
789
- from: keystore.walletAddress,
790
- signTypedData: (typedData) => signTypedData(typedData, keystore)
791
- });
792
- for (let attempt = 0; ; attempt++) {
793
- const r2 = await fetch(request.url, {
794
- method: "POST",
795
- redirect: "error",
796
- headers: { ...request.headers, "PAYMENT-SIGNATURE": header },
797
- body: request.body
798
- });
799
- if (r2.ok) return { data: await r2.json(), idempotencyKey };
800
- const read = await readFailureBody(r2);
801
- if (r2.status === 503 && apiErrorEnvelopeOf(read.body)?.reason === "facilitator_unavailable" && attempt < FACILITATOR_RETRIES) {
802
- await sleep4(retryAfterMs(r2));
803
- continue;
804
- }
805
- throw failedAfterPayment(path3, r2.status, read, idempotencyKey);
806
- }
759
+ const chainId = selectedNetwork().chainId;
760
+ const stored = agentIdForChain(keystore, chainId);
761
+ if (stored) {
762
+ printResult({ agentId: stored, alreadyRegistered: true, chainId });
763
+ return;
764
+ }
765
+ const { data, idempotencyKey } = await apiPost(`/api/devices/${encodeURIComponent(keystore.deviceId)}/identity`, {
766
+ deviceId: keystore.deviceId,
767
+ apiToken: keystore.apiToken,
768
+ chainId
807
769
  });
808
- }
809
-
810
- // src/commands/identity.ts
811
- var identityCommand = new Command4("identity").description("Manage agent identity");
812
- identityCommand.command("register").description("Register ERC-8004 agent identity (costs 0.001 in the payment token)").action(async () => {
813
- const { data: result, idempotencyKey } = await x402Post("/api/identity/register", { chainId: selectedNetwork().chainId });
814
- printResult({ agentId: result.agentId }, { idempotencyKey });
770
+ const agentId = data.agentId ?? await pollAgentId(keystore.walletAddress);
771
+ if (agentId) {
772
+ await saveKeystore(withAgentIdForChain(await loadKeystore(), chainId, agentId));
773
+ printResult(
774
+ { agentId, alreadyRegistered: data.alreadyRegistered, chainId },
775
+ { idempotencyKey }
776
+ );
777
+ return;
778
+ }
779
+ printError(
780
+ `The sponsored identity mint on chain ${chainId} has started but has not landed yet. Re-run this command to pick it up: ${taskmarketCommandFor(chainId)} identity register`,
781
+ { idempotencyKey }
782
+ );
815
783
  });
816
784
  identityCommand.command("status").description("Check identity registration status").action(async () => {
817
785
  const keystore = await loadKeystore();
@@ -845,7 +813,9 @@ function describeReputationLink(link) {
845
813
  return `unavailable: ${link.linkUnavailableReason ?? LINK_READ_FAILED_REASON}`;
846
814
  return link.linkedAgentId ? `linked to agent #${link.linkedAgentId}` : NOT_LINKED_YET;
847
815
  }
848
- var whoamiCommand = new Command5("whoami").description("Show this wallet, its agent ID on each chain and its requester reputation link").action(async () => {
816
+ var whoamiCommand = new Command5("whoami").description(
817
+ "Show this wallet, its agent ID on each chain and its requester reputation link on the selected --network"
818
+ ).action(async () => {
849
819
  const keystore = await loadKeystore();
850
820
  const selected = selectedNetwork();
851
821
  const chains = await Promise.all(
@@ -870,7 +840,7 @@ var whoamiCommand = new Command5("whoami").description("Show this wallet, its ag
870
840
 
871
841
  // src/commands/stats.ts
872
842
  import { Command as Command6 } from "commander";
873
- var statsCommand = new Command6("stats").description("View agent statistics").option("--address <addr>", "Wallet address (defaults to own wallet)").option("--agent <agentId>", "Agent ID (alternative to --address)").action(async (opts) => {
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) => {
874
844
  let address = opts.address;
875
845
  if (!address) {
876
846
  const keystore = await loadKeystore();
@@ -1342,6 +1312,66 @@ var reviewCmd = createReviewCommand();
1342
1312
  import { Command as Command8 } from "commander";
1343
1313
  import { parseUnits } from "viem";
1344
1314
 
1315
+ // src/lib/x402.ts
1316
+ var FACILITATOR_RETRIES = 2;
1317
+ var MAX_RETRY_AFTER_SECONDS = 60;
1318
+ var DEFAULT_RETRY_AFTER_SECONDS = 30;
1319
+ function retryAfterMs(res) {
1320
+ const header = res.headers?.get?.("retry-after");
1321
+ const seconds = header ? Number(header) : NaN;
1322
+ const wait = Number.isFinite(seconds) && seconds >= 0 ? seconds : DEFAULT_RETRY_AFTER_SECONDS;
1323
+ return Math.min(wait, MAX_RETRY_AFTER_SECONDS) * 1e3;
1324
+ }
1325
+ async function x402Post(path3, body, options) {
1326
+ const sleep4 = options?.sleep ?? ((ms) => new Promise((resolve) => setTimeout(resolve, ms)));
1327
+ if (paymentProtocolOf(selectedNetwork().chainId) === "mpp")
1328
+ return mppPost(path3, body, options);
1329
+ const keystore = await loadKeystore();
1330
+ const idempotencyKey = resolveIdempotencyKey(options?.idempotencyKey);
1331
+ const request = paidWriteRequest(keystore, path3, body, idempotencyKey);
1332
+ return withIdempotentWrite(idempotencyKey, async () => {
1333
+ const r1 = await fetch(request.url, {
1334
+ method: "POST",
1335
+ redirect: "error",
1336
+ headers: request.headers,
1337
+ body: request.body
1338
+ });
1339
+ if (r1.status !== 402) {
1340
+ if (r1.ok) {
1341
+ return { data: await r1.json(), idempotencyKey };
1342
+ }
1343
+ throw refusedPaidWrite(path3, r1.status, await readFailureBody(r1), idempotencyKey);
1344
+ }
1345
+ 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];
1350
+ const { header } = await signTaskmarketFeePayment({
1351
+ resource: requirements.resource,
1352
+ requirement: accept,
1353
+ typedData: accept.extra.eip712,
1354
+ from: keystore.walletAddress,
1355
+ signTypedData: (typedData) => signTypedData(typedData, keystore)
1356
+ });
1357
+ for (let attempt = 0; ; attempt++) {
1358
+ const r2 = await fetch(request.url, {
1359
+ method: "POST",
1360
+ redirect: "error",
1361
+ headers: { ...request.headers, "PAYMENT-SIGNATURE": header },
1362
+ body: request.body
1363
+ });
1364
+ if (r2.ok) return { data: await r2.json(), idempotencyKey };
1365
+ const read = await readFailureBody(r2);
1366
+ if (r2.status === 503 && apiErrorEnvelopeOf(read.body)?.reason === "facilitator_unavailable" && attempt < FACILITATOR_RETRIES) {
1367
+ await sleep4(retryAfterMs(r2));
1368
+ continue;
1369
+ }
1370
+ throw failedAfterPayment(path3, r2.status, read, idempotencyKey);
1371
+ }
1372
+ });
1373
+ }
1374
+
1345
1375
  // src/lib/settlement-terms.ts
1346
1376
  var TERM_FLAGS = {
1347
1377
  stakeRequired: "--stake-required",
@@ -3258,14 +3288,14 @@ import { Command as Command49, Option as Option3 } from "commander";
3258
3288
  import { Command as Command47 } from "commander";
3259
3289
 
3260
3290
  // src/lib/tty-confirm.ts
3261
- import { createInterface as createInterface2 } from "readline";
3291
+ import { createInterface as createInterface3 } from "readline";
3262
3292
  async function confirmAtTerminal(lines, unattended) {
3263
3293
  if (!process.stdin.isTTY) {
3264
3294
  throw new Error(`Interactive confirmation requires a TTY; ${unattended}`);
3265
3295
  }
3266
3296
  process.stderr.write(`${lines.join("\n")}
3267
3297
  `);
3268
- const readline = createInterface2({ input: process.stdin, output: process.stderr });
3298
+ const readline = createInterface3({ input: process.stdin, output: process.stderr });
3269
3299
  const answer = await new Promise(
3270
3300
  (resolve) => readline.question("Type yes to approve: ", resolve)
3271
3301
  );
@@ -3457,7 +3487,7 @@ async function runAgentCommand(options) {
3457
3487
  try {
3458
3488
  const { assertAgentCompatibility } = await import("./compatibility-636WJOEX.js");
3459
3489
  const pi = assertAgentCompatibility();
3460
- const { runAgent } = await import("./launch-MX3RJWL7.js");
3490
+ const { runAgent } = await import("./launch-QDCWAIKE.js");
3461
3491
  result = await runAgent({
3462
3492
  model: options.model,
3463
3493
  pi,
@@ -3516,13 +3546,13 @@ function agentManagementCommands() {
3516
3546
  const status = new Command48("status").description(
3517
3547
  "Show the agent channels (locked, charged, refundable), purchases with an unknown outcome, the sandbox and compute credit. Reads only."
3518
3548
  ).option("--json", "Print the versioned JSON envelope").action(async (options) => {
3519
- const { collectAgentStatus, statusLines } = await import("./status-JCOPIQ7O.js");
3549
+ const { collectAgentStatus, statusLines } = await import("./status-FTTQWS5P.js");
3520
3550
  await run(options, () => collectAgentStatus(), statusLines);
3521
3551
  });
3522
3552
  const doctor = new Command48("doctor").description(
3523
3553
  "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."
3524
3554
  ).option("--json", "Print the versioned JSON envelope").action(async (options) => {
3525
- const { runDoctor, doctorLines } = await import("./doctor-Z5O2VY62.js");
3555
+ const { runDoctor, doctorLines } = await import("./doctor-26YOWQOH.js");
3526
3556
  const report = await run(options, () => runDoctor(), doctorLines);
3527
3557
  if (report && !report.ok) process.exitCode = 1;
3528
3558
  });
@@ -3533,7 +3563,7 @@ function agentManagementCommands() {
3533
3563
  "Reconcile the open purchases of this channel, as status lists it; also reaches retired channels"
3534
3564
  ).option("--json", "Print the versioned JSON envelope").action(
3535
3565
  async (invocationId, options) => {
3536
- const { reconcileChannelPurchases, reconcileInvocation } = await import("./reconcile-OAT32H4B.js");
3566
+ const { reconcileChannelPurchases, reconcileInvocation } = await import("./reconcile-MALCM3NB.js");
3537
3567
  const choice = { rail: options.rail, channel: options.channel };
3538
3568
  if (invocationId !== void 0) {
3539
3569
  await run(
@@ -3591,7 +3621,7 @@ function agentManagementCommands() {
3591
3621
  `Not a USDC amount: ${options.amount} (digits, at most 6 decimals)`
3592
3622
  );
3593
3623
  }
3594
- const { openAgentChannels, requestTopUp, selectRail, withdrawalHatch } = await import("./channels-B4HKYLKV.js");
3624
+ const { openAgentChannels, requestTopUp, selectRail, withdrawalHatch } = await import("./channels-OBJUNCZX.js");
3595
3625
  const { rails } = await openAgentChannels();
3596
3626
  const result = await requestTopUp(selectRail(rails, options.rail), amount);
3597
3627
  return {
@@ -3615,8 +3645,8 @@ function agentManagementCommands() {
3615
3645
  async () => {
3616
3646
  await requireExperimental();
3617
3647
  const { AGENT_VIEW_VERSION } = await import("./budget-view-J6L7X6EY.js");
3618
- const { closeChannel, openAgentChannels, selectChannel } = await import("./channels-B4HKYLKV.js");
3619
- const { reconcileLeasedPurchase } = await import("./reconcile-OAT32H4B.js");
3648
+ const { closeChannel, openAgentChannels, selectChannel } = await import("./channels-OBJUNCZX.js");
3649
+ const { reconcileLeasedPurchase } = await import("./reconcile-MALCM3NB.js");
3620
3650
  const opened = await openAgentChannels();
3621
3651
  const { rail, retired } = selectChannel(opened, options);
3622
3652
  const result = await closeChannel(
@@ -3687,7 +3717,7 @@ function agentManagementCommands() {
3687
3717
  options,
3688
3718
  async () => {
3689
3719
  await requireExperimental();
3690
- const { runPull } = await import("./sync-pull-D4DZ2LYX.js");
3720
+ const { runPull } = await import("./sync-pull-N6OTHBWR.js");
3691
3721
  const { terminalPrompter } = await import("./prompter-LSICEYSQ.js");
3692
3722
  return runPull(options, {
3693
3723
  interactive: Boolean(process.stdin.isTTY && process.stdout.isTTY) && !options.json,
@@ -3750,7 +3780,7 @@ for (const command of agentManagementCommands()) {
3750
3780
 
3751
3781
  // src/commands/agents.ts
3752
3782
  import { Command as Command50 } from "commander";
3753
- var agentsCommand = new Command50("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) => {
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) => {
3754
3784
  const params = new URLSearchParams();
3755
3785
  if (opts.sort) params.set("sort", opts.sort);
3756
3786
  if (opts.skill) params.set("skill", opts.skill);
@@ -3862,7 +3892,7 @@ var walletBalanceCommand = new Command54("balance").description("Show the wallet
3862
3892
 
3863
3893
  // src/commands/wallet/import.ts
3864
3894
  import { Command as Command55 } from "commander";
3865
- import { createInterface as createInterface3 } from "readline";
3895
+ import { createInterface as createInterface4 } from "readline";
3866
3896
  import { privateKeyToAccount as privateKeyToAccount2 } from "viem/accounts";
3867
3897
  function normalizePrivateKey(raw) {
3868
3898
  const hex = raw.startsWith("0x") ? raw.slice(2) : raw;
@@ -3873,7 +3903,7 @@ function normalizePrivateKey(raw) {
3873
3903
  }
3874
3904
  function promptHiddenInput(prompt) {
3875
3905
  return new Promise((resolve) => {
3876
- const rl = createInterface3({
3906
+ const rl = createInterface4({
3877
3907
  input: process.stdin,
3878
3908
  output: process.stdout,
3879
3909
  terminal: true
@@ -3902,7 +3932,10 @@ var walletImportCommand = new Command55("import").description("Import an existin
3902
3932
  ).action(async (opts) => {
3903
3933
  if (await keystoreExists()) {
3904
3934
  const keystore = await loadKeystore();
3905
- printResult({ address: keystore.walletAddress, agentId: keystore.agentId });
3935
+ printResult({
3936
+ address: keystore.walletAddress,
3937
+ agentId: agentIdForChain(keystore, selectedNetwork().chainId)
3938
+ });
3906
3939
  return;
3907
3940
  }
3908
3941
  let rawKey;
@@ -3950,6 +3983,7 @@ var walletImportCommand = new Command55("import").description("Import an existin
3950
3983
  deviceId,
3951
3984
  apiToken,
3952
3985
  agentId,
3986
+ ...agentId ? { agentIds: { [String(selectedNetwork().chainId)]: agentId } } : {},
3953
3987
  keyServerUrl: apiUrl(),
3954
3988
  network: networkToStamp(),
3955
3989
  ...legalAcceptance ? {
@@ -3962,7 +3996,9 @@ var walletImportCommand = new Command55("import").description("Import an existin
3962
3996
  agentId = await pollAgentId(address);
3963
3997
  if (agentId) {
3964
3998
  const keystore = await loadKeystore();
3965
- await saveKeystore({ ...keystore, agentId });
3999
+ await saveKeystore(
4000
+ withAgentIdForChain({ ...keystore, agentId }, selectedNetwork().chainId, agentId)
4001
+ );
3966
4002
  }
3967
4003
  }
3968
4004
  if (keySource === "flag") {
@@ -4282,7 +4318,11 @@ var withdrawDreamsCommand = new Command62("withdraw-dreams").description("Withdr
4282
4318
  withChainId(`/api/wallet/dreams-balance?address=${workerAddress}`)
4283
4319
  );
4284
4320
  if (!balance.hookAddress || balance.chainId === void 0) {
4285
- printError("DREAMS rewards are not configured on this server");
4321
+ const chainId = selectedNetwork().chainId;
4322
+ const chain = isTaskmarketChainId(chainId) ? taskmarketChain(chainId) : void 0;
4323
+ printError(
4324
+ chain && !chain.features.dreamsRewards ? `${chain.name} has no DREAMS rewards` : "DREAMS rewards are not configured on this server"
4325
+ );
4286
4326
  return;
4287
4327
  }
4288
4328
  if (!isTaskmarketChainId(balance.chainId)) {
@@ -5796,6 +5836,33 @@ function sleepOrAbort(ms, signal) {
5796
5836
  });
5797
5837
  }
5798
5838
  var MAX_SEEN_TASK_IDS = 2e3;
5839
+ function buildDaemonTaskParams(filters, chainId) {
5840
+ const params = new URLSearchParams();
5841
+ params.set("status", "open");
5842
+ params.set("limit", "50");
5843
+ params.set("chainId", String(chainId));
5844
+ if (typeof filters.mode === "string") {
5845
+ params.set("mode", filters.mode);
5846
+ }
5847
+ const tagsValue = filters.tags;
5848
+ if (typeof tagsValue === "string") {
5849
+ params.set("tags", tagsValue);
5850
+ } else if (Array.isArray(tagsValue)) {
5851
+ params.set("tags", tagsValue.join(","));
5852
+ }
5853
+ return params;
5854
+ }
5855
+ function buildDaemonAuctionParams(chainId) {
5856
+ return new URLSearchParams({
5857
+ mode: "auction",
5858
+ status: "open",
5859
+ limit: "50",
5860
+ chainId: String(chainId)
5861
+ });
5862
+ }
5863
+ function daemonInboxPath(address, chainId) {
5864
+ return `/api/agents/inbox?address=${encodeURIComponent(address)}&chainId=${chainId}`;
5865
+ }
5799
5866
  var daemonCommand = new Command69("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", "15000").option(
5800
5867
  "--auction-poll-interval <ms>",
5801
5868
  "Poll interval for clock-based auction tasks (dutch/reverse_dutch) in milliseconds",
@@ -5900,24 +5967,10 @@ var daemonCommand = new Command69("daemon").description("Long-running agent daem
5900
5967
  const taskPollLoop = async () => {
5901
5968
  const knownStatuses = /* @__PURE__ */ new Map();
5902
5969
  const seenTaskIds = /* @__PURE__ */ new Set();
5903
- const buildTaskParams = () => {
5904
- const params = new URLSearchParams();
5905
- params.set("status", "open");
5906
- params.set("limit", "50");
5907
- if (typeof taskFilters.mode === "string") {
5908
- params.set("mode", taskFilters.mode);
5909
- }
5910
- const tagsValue = taskFilters.tags;
5911
- if (typeof tagsValue === "string") {
5912
- params.set("tags", tagsValue);
5913
- } else if (Array.isArray(tagsValue)) {
5914
- params.set("tags", tagsValue.join(","));
5915
- }
5916
- return params;
5917
- };
5970
+ const buildTaskParams = () => buildDaemonTaskParams(taskFilters, selectedNetwork().chainId);
5918
5971
  try {
5919
5972
  const inbox = await apiGet(
5920
- `/api/agents/inbox?address=${encodeURIComponent(address)}`
5973
+ daemonInboxPath(address, selectedNetwork().chainId)
5921
5974
  );
5922
5975
  for (const task of [...inbox.asRequester, ...inbox.asWorker]) {
5923
5976
  knownStatuses.set(task.id, task.status);
@@ -5937,7 +5990,7 @@ var daemonCommand = new Command69("daemon").description("Long-running agent daem
5937
5990
  if (stopped) break;
5938
5991
  try {
5939
5992
  const inbox = await apiGet(
5940
- `/api/agents/inbox?address=${encodeURIComponent(address)}`
5993
+ daemonInboxPath(address, selectedNetwork().chainId)
5941
5994
  );
5942
5995
  const allTasks = [...inbox.asRequester, ...inbox.asWorker];
5943
5996
  const nextStatuses = /* @__PURE__ */ new Map();
@@ -5950,7 +6003,9 @@ var daemonCommand = new Command69("daemon").description("Long-running agent daem
5950
6003
  const role = isRequester ? "requester" : "worker";
5951
6004
  let pendingActions = [];
5952
6005
  try {
5953
- const detail = await apiGet(`/api/tasks/${change.taskId}`);
6006
+ const detail = await apiGet(
6007
+ `/api/tasks/${change.taskId}?chainId=${selectedNetwork().chainId}`
6008
+ );
5954
6009
  pendingActions = detail.pendingActions ?? [];
5955
6010
  } catch {
5956
6011
  }
@@ -6025,11 +6080,7 @@ var daemonCommand = new Command69("daemon").description("Long-running agent daem
6025
6080
  let cursor;
6026
6081
  let hasMore = true;
6027
6082
  while (hasMore) {
6028
- const params = new URLSearchParams({
6029
- mode: "auction",
6030
- status: "open",
6031
- limit: "50"
6032
- });
6083
+ const params = buildDaemonAuctionParams(selectedNetwork().chainId);
6033
6084
  if (cursor) params.set("cursor", cursor);
6034
6085
  const result = await apiGet(`/api/tasks?${params.toString()}`);
6035
6086
  for (const task of result.tasks) {
@@ -6700,7 +6751,7 @@ import { Command as Command93 } from "commander";
6700
6751
 
6701
6752
  // src/commands/x402/payments.ts
6702
6753
  import { Command as Command90, Option as Option4 } from "commander";
6703
- import { createInterface as createInterface4 } from "readline";
6754
+ import { createInterface as createInterface5 } from "readline";
6704
6755
  var PAYMENT_STATES = [
6705
6756
  "reserved",
6706
6757
  "approval_pending",
@@ -6715,7 +6766,7 @@ var PAYMENT_STATES = [
6715
6766
  ];
6716
6767
  async function confirmManualResolution() {
6717
6768
  if (!process.stdin.isTTY) throw new Error("Manual resolution requires an interactive TTY");
6718
- const readline = createInterface4({ input: process.stdin, output: process.stderr });
6769
+ const readline = createInterface5({ input: process.stdin, output: process.stderr });
6719
6770
  const answer = await new Promise(
6720
6771
  (resolve) => readline.question(
6721
6772
  "Manual resolution changes local spending accounting. Type resolve to continue: ",
@@ -6755,7 +6806,7 @@ x402PaymentsCommand.command("resolve").description("Manually record an externall
6755
6806
  // src/commands/x402/policy.ts
6756
6807
  import { promises as fs4 } from "fs";
6757
6808
  import { Command as Command91 } from "commander";
6758
- import { createInterface as createInterface5 } from "readline";
6809
+ import { createInterface as createInterface6 } from "readline";
6759
6810
  async function confirmUnattendedRule(rule) {
6760
6811
  if (!process.stdin.isTTY) {
6761
6812
  throw new Error("Authorizing an unattended policy rule requires an interactive TTY");
@@ -6773,7 +6824,7 @@ async function confirmUnattendedRule(rule) {
6773
6824
  ].join("\n")}
6774
6825
  `
6775
6826
  );
6776
- const readline = createInterface5({ input: process.stdin, output: process.stderr });
6827
+ const readline = createInterface6({ input: process.stdin, output: process.stderr });
6777
6828
  const answer = await new Promise(
6778
6829
  (resolve) => readline.question("Type authorize to grant unattended spending: ", resolve)
6779
6830
  );
@@ -10738,7 +10789,7 @@ setLastErrorCliVersion(version);
10738
10789
  program.name("taskmarket").description("Taskmarket CLI for AI agents").version(version);
10739
10790
  program.option(
10740
10791
  "--network <name>",
10741
- `Network to use: ${NETWORK_NAMES.join(", ")} (default: TASKMARKET_NETWORK, then the keystore's network, then base)`
10792
+ `Network to use: ${NETWORK_NAMES.join(", ")} (else TASKMARKET_NETWORK, then the keystore's network; there is no default)`
10742
10793
  ).hook("preAction", async (thisCommand) => {
10743
10794
  const { network } = thisCommand.opts();
10744
10795
  setSelectedNetwork(