@lucid-agents/taskmarket 1.7.1 → 1.7.3

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 +51 -12
  2. package/package.json +3 -3
package/dist/index.js CHANGED
@@ -5508,8 +5508,8 @@ function buildReadAuthMessage(address) {
5508
5508
  var READ_AUTH_ADDRESS_HEADER = "X-Taskmarket-Caller-Address";
5509
5509
  var READ_AUTH_SIGNATURE_HEADER = "X-Taskmarket-Caller-Signature";
5510
5510
  var TASK_ACCESS_GRANT_HEADER = "X-Taskmarket-Task-Access-Grant";
5511
- function buildSubmitMessage(taskId) {
5512
- return `taskmarket:submit:${taskId}`;
5511
+ function buildSubmitMessage(taskId, contentBindings) {
5512
+ return contentBindings ? `taskmarket:submit:${taskId}:${contentBindings.join(",")}` : `taskmarket:submit:${taskId}`;
5513
5513
  }
5514
5514
  function buildClaimMessage(taskId) {
5515
5515
  return `taskmarket:claim:${taskId}`;
@@ -6012,7 +6012,8 @@ function decryptPrivateKey(deviceEncryptionKeyHex, encryptedHex) {
6012
6012
  async function saveKeystore(keystore, keystorePath) {
6013
6013
  const p = keystorePath ?? getKeystorePath();
6014
6014
  await fs.mkdir(path.dirname(p), { recursive: true });
6015
- await fs.writeFile(p, JSON.stringify(keystore, null, 2), "utf8");
6015
+ await fs.writeFile(p, JSON.stringify(keystore, null, 2), { encoding: "utf8", mode: 384 });
6016
+ await fs.chmod(p, 384);
6016
6017
  }
6017
6018
  async function loadKeystore(keystorePath) {
6018
6019
  const p = keystorePath ?? getKeystorePath();
@@ -6037,6 +6038,14 @@ async function keystoreExists(keystorePath) {
6037
6038
  // src/lib/api.ts
6038
6039
  var API_URL = process.env.TASKMARKET_API_URL ?? "https://api.taskmarket.dev";
6039
6040
  var API_ORIGIN = new URL(API_URL).origin;
6041
+ var ApiError = class extends Error {
6042
+ status;
6043
+ constructor(status, message) {
6044
+ super(message);
6045
+ this.name = "ApiError";
6046
+ this.status = status;
6047
+ }
6048
+ };
6040
6049
  function legalReceiptHeadersForKeystore(keystore, path4, method) {
6041
6050
  const canSend = keystore.legalAcceptanceApiOrigin === API_ORIGIN && (method === "POST" || path4 === "/api/legal/status");
6042
6051
  return canSend ? buildLegalReceiptHeaders(keystore.legalAcceptanceReceipt) : {};
@@ -6062,7 +6071,7 @@ async function apiGet(path4, options) {
6062
6071
  });
6063
6072
  const body = await res.json();
6064
6073
  if (!res.ok) {
6065
- throw new Error(`GET ${path4} failed (${res.status}): ${JSON.stringify(body)}`);
6074
+ throw new ApiError(res.status, `GET ${path4} failed (${res.status}): ${JSON.stringify(body)}`);
6066
6075
  }
6067
6076
  return body;
6068
6077
  }
@@ -6080,7 +6089,10 @@ async function apiPost(path4, body, options) {
6080
6089
  });
6081
6090
  const result = await res.json();
6082
6091
  if (!res.ok) {
6083
- throw new Error(`POST ${path4} failed (${res.status}): ${JSON.stringify(result)}`);
6092
+ throw new ApiError(
6093
+ res.status,
6094
+ `POST ${path4} failed (${res.status}): ${JSON.stringify(result)}`
6095
+ );
6084
6096
  }
6085
6097
  return result;
6086
6098
  }
@@ -6097,7 +6109,10 @@ async function apiDelete(path4, options) {
6097
6109
  });
6098
6110
  const result = await res.json();
6099
6111
  if (!res.ok) {
6100
- throw new Error(`DELETE ${path4} failed (${res.status}): ${JSON.stringify(result)}`);
6112
+ throw new ApiError(
6113
+ res.status,
6114
+ `DELETE ${path4} failed (${res.status}): ${JSON.stringify(result)}`
6115
+ );
6101
6116
  }
6102
6117
  return result;
6103
6118
  }
@@ -6606,7 +6621,7 @@ async function x402Post(path4, body) {
6606
6621
  return r1.json();
6607
6622
  }
6608
6623
  const text = await r1.text().catch(() => "");
6609
- throw new Error(`POST ${path4} failed (${r1.status}): ${text}`);
6624
+ throw new ApiError(r1.status, `POST ${path4} failed (${r1.status}): ${text}`);
6610
6625
  }
6611
6626
  const requirements = await r1.json();
6612
6627
  if (!requirements.accepts || requirements.accepts.length === 0) {
@@ -6640,7 +6655,10 @@ async function x402Post(path4, body) {
6640
6655
  });
6641
6656
  const result = await r2.json();
6642
6657
  if (!r2.ok) {
6643
- throw new Error(`POST ${path4} failed after payment (${r2.status}): ${JSON.stringify(result)}`);
6658
+ throw new ApiError(
6659
+ r2.status,
6660
+ `POST ${path4} failed after payment (${r2.status}): ${JSON.stringify(result)}`
6661
+ );
6644
6662
  }
6645
6663
  return result;
6646
6664
  }
@@ -7156,11 +7174,18 @@ var submitCmd = new Command9("submit").description("Submit work for a task").arg
7156
7174
  };
7157
7175
  })
7158
7176
  );
7159
- const result = await apiPost(`/api/tasks/${taskId}/submissions/from-keys`, {
7177
+ const submitSignature = await signMessage(
7178
+ buildSubmitMessage(
7179
+ taskId,
7180
+ artifactInputs.map((artifact) => artifact.artifactKey)
7181
+ ),
7182
+ keystore
7183
+ );
7184
+ const result = await x402Post(`/api/tasks/${taskId}/submissions/from-keys`, {
7160
7185
  taskId,
7161
7186
  workerAddress: keystore.walletAddress,
7162
7187
  artifacts: artifactInputs,
7163
- signature
7188
+ signature: submitSignature
7164
7189
  });
7165
7190
  printResult({ submissionId: result.submissionId });
7166
7191
  } finally {
@@ -7415,6 +7440,9 @@ var selectWinnerCmd = new Command22("select-winner").description("Permissionless
7415
7440
  // src/commands/task/download.ts
7416
7441
  import { Command as Command23 } from "commander";
7417
7442
  import { writeFileSync } from "fs";
7443
+ function sanitizeForTerminal(text) {
7444
+ return text.replace(/[\x00-\x08\x0b\x0c\x0e-\x1f\x7f]/g, "");
7445
+ }
7418
7446
  var downloadCmd = new Command23("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(
7419
7447
  async (taskId, opts) => {
7420
7448
  const keystore = await loadKeystore();
@@ -7447,7 +7475,15 @@ var downloadCmd = new Command23("download").description("Download a submission f
7447
7475
  writeFileSync(opts.output, content);
7448
7476
  process.stdout.write(JSON.stringify({ ok: true, data: { savedTo: opts.output } }) + "\n");
7449
7477
  } else {
7450
- process.stdout.write(content);
7478
+ let decoded;
7479
+ try {
7480
+ decoded = new TextDecoder("utf-8", { fatal: true }).decode(content);
7481
+ } catch {
7482
+ printError(
7483
+ "Downloaded content is not valid UTF-8 text and cannot be safely printed to the terminal. Use --output <path> to save it to a file instead."
7484
+ );
7485
+ }
7486
+ process.stdout.write(sanitizeForTerminal(decoded));
7451
7487
  }
7452
7488
  }
7453
7489
  );
@@ -9882,6 +9918,9 @@ program.addCommand(emailCommand);
9882
9918
  program.addCommand(requesterCmd);
9883
9919
  program.addCommand(legalCommand);
9884
9920
  program.parseAsync(process.argv).catch((err) => {
9885
- process.stderr.write(JSON.stringify({ ok: false, error: err.message }) + "\n");
9921
+ const status = err instanceof ApiError ? err.status : void 0;
9922
+ process.stderr.write(
9923
+ JSON.stringify({ ok: false, error: err.message, ...status !== void 0 ? { status } : {} }) + "\n"
9924
+ );
9886
9925
  process.exit(1);
9887
9926
  });
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@lucid-agents/taskmarket",
3
- "version": "1.7.1",
3
+ "version": "1.7.3",
4
4
  "type": "module",
5
5
  "bin": {
6
6
  "taskmarket": "./dist/index.js"
@@ -17,9 +17,9 @@
17
17
  "tsx": "^4.7.0",
18
18
  "typescript": "^5.3.3",
19
19
  "vitest": "^2.0.0",
20
- "@taskmarket/eslint-config": "0.0.0",
21
20
  "@taskmarket/prettier-config": "0.0.0",
22
- "@taskmarket/shared": "2.0.0"
21
+ "@taskmarket/shared": "2.0.0",
22
+ "@taskmarket/eslint-config": "0.0.0"
23
23
  },
24
24
  "files": [
25
25
  "dist"