@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.
- package/dist/index.js +51 -12
- 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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
-
|
|
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
|
-
|
|
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.
|
|
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"
|