@bounty-ai/agent-sdk 0.1.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/LICENSE +21 -0
- package/README.md +107 -0
- package/dist/index.cjs +419 -0
- package/dist/index.cjs.map +1 -0
- package/dist/index.d.cts +177 -0
- package/dist/index.d.ts +177 -0
- package/dist/index.js +375 -0
- package/dist/index.js.map +1 -0
- package/package.json +59 -0
package/dist/index.js
ADDED
|
@@ -0,0 +1,375 @@
|
|
|
1
|
+
// src/errors.ts
|
|
2
|
+
var SdkError = class extends Error {
|
|
3
|
+
constructor(message) {
|
|
4
|
+
super(message);
|
|
5
|
+
this.name = "SdkError";
|
|
6
|
+
}
|
|
7
|
+
};
|
|
8
|
+
var ApiError = class extends SdkError {
|
|
9
|
+
status;
|
|
10
|
+
code;
|
|
11
|
+
body;
|
|
12
|
+
retryable;
|
|
13
|
+
constructor(params) {
|
|
14
|
+
super(params.message);
|
|
15
|
+
this.name = "ApiError";
|
|
16
|
+
this.status = params.status;
|
|
17
|
+
this.code = params.code;
|
|
18
|
+
this.body = params.body;
|
|
19
|
+
this.retryable = params.status === 429 || params.status >= 500;
|
|
20
|
+
}
|
|
21
|
+
};
|
|
22
|
+
|
|
23
|
+
// src/client.ts
|
|
24
|
+
var AgentClient = class {
|
|
25
|
+
baseUrl;
|
|
26
|
+
apiKey;
|
|
27
|
+
fetchImpl;
|
|
28
|
+
constructor(options) {
|
|
29
|
+
this.baseUrl = options.baseUrl.replace(/\/$/, "");
|
|
30
|
+
this.apiKey = options.apiKey;
|
|
31
|
+
this.fetchImpl = options.fetchImpl ?? fetch;
|
|
32
|
+
}
|
|
33
|
+
async ackAssignment(assignmentId, request) {
|
|
34
|
+
await this.post(`/agent/assignments/ack`, {
|
|
35
|
+
assignment_id: assignmentId,
|
|
36
|
+
...request
|
|
37
|
+
});
|
|
38
|
+
}
|
|
39
|
+
async submitResult(input) {
|
|
40
|
+
const payload = {
|
|
41
|
+
status: input.status,
|
|
42
|
+
...input.result ? { result: input.result } : {},
|
|
43
|
+
...input.error ? { error: input.error } : {}
|
|
44
|
+
};
|
|
45
|
+
await this.post(`/agent/assignments/submit`, {
|
|
46
|
+
assignment_id: input.assignmentId,
|
|
47
|
+
...payload
|
|
48
|
+
});
|
|
49
|
+
}
|
|
50
|
+
async submitError(input) {
|
|
51
|
+
await this.submitResult({
|
|
52
|
+
assignmentId: input.assignmentId,
|
|
53
|
+
status: "timed_out",
|
|
54
|
+
error: input.error,
|
|
55
|
+
...input.details ? { result: { details: input.details } } : {}
|
|
56
|
+
});
|
|
57
|
+
}
|
|
58
|
+
async post(path, body) {
|
|
59
|
+
const response = await this.fetchImpl(`${this.baseUrl}${path}`, {
|
|
60
|
+
method: "POST",
|
|
61
|
+
headers: {
|
|
62
|
+
"content-type": "application/json",
|
|
63
|
+
authorization: `Bearer ${this.apiKey}`
|
|
64
|
+
},
|
|
65
|
+
body: JSON.stringify(body)
|
|
66
|
+
});
|
|
67
|
+
if (!response.ok) {
|
|
68
|
+
throw await this.toApiError(response);
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
async toApiError(response) {
|
|
72
|
+
const raw = await response.text();
|
|
73
|
+
let parsed = null;
|
|
74
|
+
if (raw) {
|
|
75
|
+
try {
|
|
76
|
+
parsed = JSON.parse(raw);
|
|
77
|
+
} catch {
|
|
78
|
+
parsed = { message: raw };
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
return new ApiError({
|
|
82
|
+
status: response.status,
|
|
83
|
+
message: parsed?.message ?? `API request failed (${response.status}): ${raw || response.statusText}`,
|
|
84
|
+
code: parsed?.code,
|
|
85
|
+
body: parsed
|
|
86
|
+
});
|
|
87
|
+
}
|
|
88
|
+
};
|
|
89
|
+
|
|
90
|
+
// src/signature.ts
|
|
91
|
+
import { createHmac, timingSafeEqual } from "crypto";
|
|
92
|
+
function computeWebhookSignature(params) {
|
|
93
|
+
const signedPayload = `${params.timestamp}.${params.body}`;
|
|
94
|
+
const digest = createHmac("sha256", params.webhookSecret).update(signedPayload, "utf8").digest("hex");
|
|
95
|
+
return `sha256=${digest}`;
|
|
96
|
+
}
|
|
97
|
+
function verifyWebhookSignature(params) {
|
|
98
|
+
if (!params.timestamp || !params.signature) {
|
|
99
|
+
throw new SdkError("Missing webhook timestamp or signature");
|
|
100
|
+
}
|
|
101
|
+
const expected = computeWebhookSignature({
|
|
102
|
+
webhookSecret: params.webhookSecret,
|
|
103
|
+
timestamp: params.timestamp,
|
|
104
|
+
body: params.body
|
|
105
|
+
});
|
|
106
|
+
const expectedBuffer = Buffer.from(expected, "utf8");
|
|
107
|
+
const actualBuffer = Buffer.from(params.signature, "utf8");
|
|
108
|
+
if (expectedBuffer.length !== actualBuffer.length) {
|
|
109
|
+
throw new SdkError("Invalid webhook signature");
|
|
110
|
+
}
|
|
111
|
+
if (!timingSafeEqual(expectedBuffer, actualBuffer)) {
|
|
112
|
+
throw new SdkError("Invalid webhook signature");
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
// src/contracts.ts
|
|
117
|
+
var CONTRACT_VERSION = "v1";
|
|
118
|
+
function isObject(value) {
|
|
119
|
+
return !!value && typeof value === "object";
|
|
120
|
+
}
|
|
121
|
+
function parseAssignmentRecord(record) {
|
|
122
|
+
if (typeof record.assignment_id !== "string") {
|
|
123
|
+
throw new SdkError("Missing assignment_id");
|
|
124
|
+
}
|
|
125
|
+
if (typeof record.template_slug !== "string") {
|
|
126
|
+
throw new SdkError("Missing template_slug");
|
|
127
|
+
}
|
|
128
|
+
if (!isObject(record.outcome)) {
|
|
129
|
+
throw new SdkError("Missing outcome");
|
|
130
|
+
}
|
|
131
|
+
if (!isObject(record.result_schema)) {
|
|
132
|
+
throw new SdkError("Missing result_schema");
|
|
133
|
+
}
|
|
134
|
+
const outcome = record.outcome;
|
|
135
|
+
if (typeof outcome.title !== "string") {
|
|
136
|
+
throw new SdkError("Missing outcome.title");
|
|
137
|
+
}
|
|
138
|
+
if (!isObject(outcome.payload)) {
|
|
139
|
+
throw new SdkError("Missing outcome.payload");
|
|
140
|
+
}
|
|
141
|
+
const parsedResultSchema = record.result_schema;
|
|
142
|
+
return {
|
|
143
|
+
assignment_id: record.assignment_id,
|
|
144
|
+
template_slug: record.template_slug,
|
|
145
|
+
result_schema: parsedResultSchema,
|
|
146
|
+
outcome: {
|
|
147
|
+
title: outcome.title,
|
|
148
|
+
payload: outcome.payload,
|
|
149
|
+
...typeof outcome.requested_unit_price_value === "number" ? { requested_unit_price_value: outcome.requested_unit_price_value } : {},
|
|
150
|
+
...typeof outcome.requested_total_price_value === "number" ? { requested_total_price_value: outcome.requested_total_price_value } : {},
|
|
151
|
+
...typeof outcome.currency === "string" ? { currency: outcome.currency } : {},
|
|
152
|
+
...typeof outcome.time_window === "string" ? { time_window: outcome.time_window } : {}
|
|
153
|
+
}
|
|
154
|
+
};
|
|
155
|
+
}
|
|
156
|
+
function parseAssignmentV1(body) {
|
|
157
|
+
let payload;
|
|
158
|
+
try {
|
|
159
|
+
payload = JSON.parse(body);
|
|
160
|
+
} catch {
|
|
161
|
+
throw new SdkError("Invalid JSON payload");
|
|
162
|
+
}
|
|
163
|
+
if (!isObject(payload)) {
|
|
164
|
+
throw new SdkError("Invalid assignment payload");
|
|
165
|
+
}
|
|
166
|
+
if (payload.version !== CONTRACT_VERSION) {
|
|
167
|
+
throw new SdkError("Unsupported assignment contract version");
|
|
168
|
+
}
|
|
169
|
+
if (!isObject(payload.assignment)) {
|
|
170
|
+
throw new SdkError("Missing assignment envelope payload");
|
|
171
|
+
}
|
|
172
|
+
return parseAssignmentRecord(payload.assignment);
|
|
173
|
+
}
|
|
174
|
+
function toAssignmentEnvelopeV1(assignment) {
|
|
175
|
+
return {
|
|
176
|
+
version: CONTRACT_VERSION,
|
|
177
|
+
assignment
|
|
178
|
+
};
|
|
179
|
+
}
|
|
180
|
+
function getContractVersion() {
|
|
181
|
+
return CONTRACT_VERSION;
|
|
182
|
+
}
|
|
183
|
+
|
|
184
|
+
// src/webhook.ts
|
|
185
|
+
var DEFAULT_SIGNATURE_HEADER = "x-bounty-signature";
|
|
186
|
+
var DEFAULT_TIMESTAMP_HEADER = "x-bounty-timestamp";
|
|
187
|
+
function createWebhookHandler(options) {
|
|
188
|
+
const shouldVerify = options.verifySignature ?? true;
|
|
189
|
+
return async function handleWebhook(input) {
|
|
190
|
+
if (shouldVerify) {
|
|
191
|
+
verifyWebhookSignature({
|
|
192
|
+
webhookSecret: options.webhookSecret,
|
|
193
|
+
body: input.body,
|
|
194
|
+
...input.signature ? { signature: input.signature } : {},
|
|
195
|
+
...input.timestamp ? { timestamp: input.timestamp } : {}
|
|
196
|
+
});
|
|
197
|
+
}
|
|
198
|
+
const assignment = parseAssignmentV1(input.body);
|
|
199
|
+
return options.onAssignment({ assignment });
|
|
200
|
+
};
|
|
201
|
+
}
|
|
202
|
+
async function executeWebhook(handler, input) {
|
|
203
|
+
try {
|
|
204
|
+
const body = await handler(input);
|
|
205
|
+
return {
|
|
206
|
+
status: 200,
|
|
207
|
+
body
|
|
208
|
+
};
|
|
209
|
+
} catch (error) {
|
|
210
|
+
const message = error instanceof Error ? error.message : "Unexpected webhook error";
|
|
211
|
+
const sdkError = error instanceof SdkError ? error : new SdkError(message);
|
|
212
|
+
return {
|
|
213
|
+
status: 400,
|
|
214
|
+
body: {
|
|
215
|
+
status: "timed_out",
|
|
216
|
+
error: sdkError.message
|
|
217
|
+
}
|
|
218
|
+
};
|
|
219
|
+
}
|
|
220
|
+
}
|
|
221
|
+
|
|
222
|
+
// src/adapters.ts
|
|
223
|
+
function headerValue(headers, key) {
|
|
224
|
+
const value = headers[key] ?? headers[key.toLowerCase()];
|
|
225
|
+
if (Array.isArray(value)) {
|
|
226
|
+
return value[0];
|
|
227
|
+
}
|
|
228
|
+
return value;
|
|
229
|
+
}
|
|
230
|
+
function normalizeBody(body) {
|
|
231
|
+
if (typeof body === "string") {
|
|
232
|
+
return body;
|
|
233
|
+
}
|
|
234
|
+
if (body === void 0 || body === null) {
|
|
235
|
+
return "";
|
|
236
|
+
}
|
|
237
|
+
return JSON.stringify(body);
|
|
238
|
+
}
|
|
239
|
+
function toWebhookInput(params) {
|
|
240
|
+
return {
|
|
241
|
+
body: params.body,
|
|
242
|
+
...params.signature ? { signature: params.signature } : {},
|
|
243
|
+
...params.timestamp ? { timestamp: params.timestamp } : {}
|
|
244
|
+
};
|
|
245
|
+
}
|
|
246
|
+
function createExpressWebhookHandler(options) {
|
|
247
|
+
const handler = createWebhookHandler(options);
|
|
248
|
+
return async function expressWebhook(req, res) {
|
|
249
|
+
const body = req.rawBody ?? normalizeBody(req.body);
|
|
250
|
+
const result = await executeWebhook(
|
|
251
|
+
handler,
|
|
252
|
+
toWebhookInput({
|
|
253
|
+
body,
|
|
254
|
+
signature: headerValue(req.headers, DEFAULT_SIGNATURE_HEADER),
|
|
255
|
+
timestamp: headerValue(req.headers, DEFAULT_TIMESTAMP_HEADER)
|
|
256
|
+
})
|
|
257
|
+
);
|
|
258
|
+
res.status(result.status).json(result.body);
|
|
259
|
+
};
|
|
260
|
+
}
|
|
261
|
+
function createFastifyWebhookHandler(options) {
|
|
262
|
+
const handler = createWebhookHandler(options);
|
|
263
|
+
return async function fastifyWebhook(request, reply) {
|
|
264
|
+
const body = request.rawBody ?? normalizeBody(request.body);
|
|
265
|
+
const result = await executeWebhook(
|
|
266
|
+
handler,
|
|
267
|
+
toWebhookInput({
|
|
268
|
+
body,
|
|
269
|
+
signature: headerValue(request.headers, DEFAULT_SIGNATURE_HEADER),
|
|
270
|
+
timestamp: headerValue(request.headers, DEFAULT_TIMESTAMP_HEADER)
|
|
271
|
+
})
|
|
272
|
+
);
|
|
273
|
+
reply.code(result.status).send(result.body);
|
|
274
|
+
};
|
|
275
|
+
}
|
|
276
|
+
function createNextWebhookHandler(options) {
|
|
277
|
+
const handler = createWebhookHandler(options);
|
|
278
|
+
return async function nextWebhook(request) {
|
|
279
|
+
const body = await request.text();
|
|
280
|
+
const result = await executeWebhook(
|
|
281
|
+
handler,
|
|
282
|
+
toWebhookInput({
|
|
283
|
+
body,
|
|
284
|
+
signature: request.headers.get(DEFAULT_SIGNATURE_HEADER) ?? void 0,
|
|
285
|
+
timestamp: request.headers.get(DEFAULT_TIMESTAMP_HEADER) ?? void 0
|
|
286
|
+
})
|
|
287
|
+
);
|
|
288
|
+
return new Response(JSON.stringify(result.body), {
|
|
289
|
+
status: result.status,
|
|
290
|
+
headers: { "content-type": "application/json" }
|
|
291
|
+
});
|
|
292
|
+
};
|
|
293
|
+
}
|
|
294
|
+
function createHonoWebhookHandler(options) {
|
|
295
|
+
const handler = createWebhookHandler(options);
|
|
296
|
+
return async function honoWebhook(c) {
|
|
297
|
+
const body = await c.req.text();
|
|
298
|
+
const result = await executeWebhook(
|
|
299
|
+
handler,
|
|
300
|
+
toWebhookInput({
|
|
301
|
+
body,
|
|
302
|
+
signature: c.req.header(DEFAULT_SIGNATURE_HEADER),
|
|
303
|
+
timestamp: c.req.header(DEFAULT_TIMESTAMP_HEADER)
|
|
304
|
+
})
|
|
305
|
+
);
|
|
306
|
+
return c.json(result.body, result.status);
|
|
307
|
+
};
|
|
308
|
+
}
|
|
309
|
+
|
|
310
|
+
// src/results.ts
|
|
311
|
+
var DEFAULT_CONTACT_FIELDS = ["email", "phone", "profile_url", "linkedin_url"];
|
|
312
|
+
function hasValue(value) {
|
|
313
|
+
if (typeof value === "string") {
|
|
314
|
+
return value.trim().length > 0;
|
|
315
|
+
}
|
|
316
|
+
return value !== null && value !== void 0;
|
|
317
|
+
}
|
|
318
|
+
function deriveColumns(rows) {
|
|
319
|
+
const ordered = [];
|
|
320
|
+
for (const row of rows) {
|
|
321
|
+
for (const key of Object.keys(row)) {
|
|
322
|
+
if (!ordered.includes(key)) {
|
|
323
|
+
ordered.push(key);
|
|
324
|
+
}
|
|
325
|
+
}
|
|
326
|
+
}
|
|
327
|
+
return ordered;
|
|
328
|
+
}
|
|
329
|
+
function makeRowKey(row, keys) {
|
|
330
|
+
const normalized = keys.map((key) => [key, row[key]]);
|
|
331
|
+
return JSON.stringify(normalized);
|
|
332
|
+
}
|
|
333
|
+
function createTablePayload(rows, options = {}) {
|
|
334
|
+
const columns = options.columns ?? deriveColumns(rows);
|
|
335
|
+
const dedupeKeys = options.dedupeBy && options.dedupeBy.length > 0 ? options.dedupeBy : columns;
|
|
336
|
+
const contactFields = options.contactFields && options.contactFields.length > 0 ? options.contactFields : DEFAULT_CONTACT_FIELDS;
|
|
337
|
+
const uniqueCount = new Set(rows.map((row) => makeRowKey(row, dedupeKeys))).size;
|
|
338
|
+
const hasContactMethod = rows.every((row) => contactFields.some((field) => hasValue(row[field])));
|
|
339
|
+
return {
|
|
340
|
+
table: {
|
|
341
|
+
columns,
|
|
342
|
+
rows
|
|
343
|
+
},
|
|
344
|
+
row_count: rows.length,
|
|
345
|
+
rows_unique: uniqueCount === rows.length,
|
|
346
|
+
has_contact_method: hasContactMethod,
|
|
347
|
+
...options.summary ? { summary: options.summary } : {}
|
|
348
|
+
};
|
|
349
|
+
}
|
|
350
|
+
function createTableResult(rows, options = {}) {
|
|
351
|
+
return {
|
|
352
|
+
result: createTablePayload(rows, options)
|
|
353
|
+
};
|
|
354
|
+
}
|
|
355
|
+
export {
|
|
356
|
+
AgentClient,
|
|
357
|
+
ApiError,
|
|
358
|
+
DEFAULT_SIGNATURE_HEADER,
|
|
359
|
+
DEFAULT_TIMESTAMP_HEADER,
|
|
360
|
+
SdkError,
|
|
361
|
+
computeWebhookSignature,
|
|
362
|
+
createExpressWebhookHandler,
|
|
363
|
+
createFastifyWebhookHandler,
|
|
364
|
+
createHonoWebhookHandler,
|
|
365
|
+
createNextWebhookHandler,
|
|
366
|
+
createTablePayload,
|
|
367
|
+
createTableResult,
|
|
368
|
+
createWebhookHandler,
|
|
369
|
+
executeWebhook,
|
|
370
|
+
getContractVersion,
|
|
371
|
+
parseAssignmentV1,
|
|
372
|
+
toAssignmentEnvelopeV1,
|
|
373
|
+
verifyWebhookSignature
|
|
374
|
+
};
|
|
375
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/errors.ts","../src/client.ts","../src/signature.ts","../src/contracts.ts","../src/webhook.ts","../src/adapters.ts","../src/results.ts"],"sourcesContent":["import type { ApiErrorBody } from \"./types\";\n\nexport class SdkError extends Error {\n constructor(message: string) {\n super(message);\n this.name = \"SdkError\";\n }\n}\n\nexport class ApiError extends SdkError {\n readonly status: number;\n readonly code: string | undefined;\n readonly body: ApiErrorBody | null;\n readonly retryable: boolean;\n\n constructor(params: {\n status: number;\n message: string;\n code: string | undefined;\n body: ApiErrorBody | null;\n }) {\n super(params.message);\n this.name = \"ApiError\";\n this.status = params.status;\n this.code = params.code;\n this.body = params.body;\n this.retryable = params.status === 429 || params.status >= 500;\n }\n}\n","import { ApiError } from \"./errors\";\nimport type {\n ApiErrorBody,\n AssignmentAckRequest,\n AssignmentResult,\n SubmitErrorRequest,\n SubmitResultRequest,\n} from \"./types\";\n\nexport type ClientOptions = {\n baseUrl: string;\n apiKey: string;\n fetchImpl?: typeof fetch;\n};\n\nexport class AgentClient {\n private readonly baseUrl: string;\n private readonly apiKey: string;\n private readonly fetchImpl: typeof fetch;\n\n constructor(options: ClientOptions) {\n this.baseUrl = options.baseUrl.replace(/\\/$/, \"\");\n this.apiKey = options.apiKey;\n this.fetchImpl = options.fetchImpl ?? fetch;\n }\n\n async ackAssignment(assignmentId: string, request: AssignmentAckRequest): Promise<void> {\n await this.post(`/agent/assignments/ack`, {\n assignment_id: assignmentId,\n ...request,\n });\n }\n\n async submitResult(input: SubmitResultRequest): Promise<void> {\n const payload: AssignmentResult = {\n status: input.status,\n ...(input.result ? { result: input.result } : {}),\n ...(input.error ? { error: input.error } : {}),\n };\n\n await this.post(`/agent/assignments/submit`, {\n assignment_id: input.assignmentId,\n ...payload,\n });\n }\n\n async submitError(input: SubmitErrorRequest): Promise<void> {\n await this.submitResult({\n assignmentId: input.assignmentId,\n status: \"timed_out\",\n error: input.error,\n ...(input.details ? { result: { details: input.details } } : {}),\n });\n }\n\n private async post(path: string, body: Record<string, unknown>): Promise<void> {\n const response = await this.fetchImpl(`${this.baseUrl}${path}`, {\n method: \"POST\",\n headers: {\n \"content-type\": \"application/json\",\n authorization: `Bearer ${this.apiKey}`,\n },\n body: JSON.stringify(body),\n });\n\n if (!response.ok) {\n throw await this.toApiError(response);\n }\n }\n\n private async toApiError(response: Response): Promise<ApiError> {\n const raw = await response.text();\n let parsed: ApiErrorBody | null = null;\n\n if (raw) {\n try {\n parsed = JSON.parse(raw) as ApiErrorBody;\n } catch {\n parsed = { message: raw };\n }\n }\n\n return new ApiError({\n status: response.status,\n message:\n parsed?.message ?? `API request failed (${response.status}): ${raw || response.statusText}`,\n code: parsed?.code,\n body: parsed,\n });\n }\n}\n","import { createHmac, timingSafeEqual } from \"node:crypto\";\nimport { SdkError } from \"./errors\";\n\nexport function computeWebhookSignature(params: {\n webhookSecret: string;\n timestamp: string;\n body: string;\n}) {\n const signedPayload = `${params.timestamp}.${params.body}`;\n const digest = createHmac(\"sha256\", params.webhookSecret)\n .update(signedPayload, \"utf8\")\n .digest(\"hex\");\n return `sha256=${digest}`;\n}\n\nexport function verifyWebhookSignature(params: {\n webhookSecret: string;\n timestamp?: string;\n body: string;\n signature?: string;\n}) {\n if (!params.timestamp || !params.signature) {\n throw new SdkError(\"Missing webhook timestamp or signature\");\n }\n\n const expected = computeWebhookSignature({\n webhookSecret: params.webhookSecret,\n timestamp: params.timestamp,\n body: params.body,\n });\n\n const expectedBuffer = Buffer.from(expected, \"utf8\");\n const actualBuffer = Buffer.from(params.signature, \"utf8\");\n\n if (expectedBuffer.length !== actualBuffer.length) {\n throw new SdkError(\"Invalid webhook signature\");\n }\n\n if (!timingSafeEqual(expectedBuffer, actualBuffer)) {\n throw new SdkError(\"Invalid webhook signature\");\n }\n}\n","import { SdkError } from \"./errors\";\nimport type { Assignment, AssignmentEnvelopeV1, AssignmentResultSchema, SdkContractVersion } from \"./types\";\n\nconst CONTRACT_VERSION: SdkContractVersion = \"v1\";\n\nfunction isObject(value: unknown): value is Record<string, unknown> {\n return !!value && typeof value === \"object\";\n}\n\nfunction parseAssignmentRecord(record: Record<string, unknown>): Assignment {\n if (typeof record.assignment_id !== \"string\") {\n throw new SdkError(\"Missing assignment_id\");\n }\n if (typeof record.template_slug !== \"string\") {\n throw new SdkError(\"Missing template_slug\");\n }\n if (!isObject(record.outcome)) {\n throw new SdkError(\"Missing outcome\");\n }\n if (!isObject(record.result_schema)) {\n throw new SdkError(\"Missing result_schema\");\n }\n\n const outcome = record.outcome;\n if (typeof outcome.title !== \"string\") {\n throw new SdkError(\"Missing outcome.title\");\n }\n if (!isObject(outcome.payload)) {\n throw new SdkError(\"Missing outcome.payload\");\n }\n\n const parsedResultSchema = record.result_schema as AssignmentResultSchema;\n\n return {\n assignment_id: record.assignment_id,\n template_slug: record.template_slug,\n result_schema: parsedResultSchema,\n outcome: {\n title: outcome.title,\n payload: outcome.payload,\n ...(typeof outcome.requested_unit_price_value === \"number\"\n ? { requested_unit_price_value: outcome.requested_unit_price_value }\n : {}),\n ...(typeof outcome.requested_total_price_value === \"number\"\n ? { requested_total_price_value: outcome.requested_total_price_value }\n : {}),\n ...(typeof outcome.currency === \"string\" ? { currency: outcome.currency } : {}),\n ...(typeof outcome.time_window === \"string\" ? { time_window: outcome.time_window } : {}),\n },\n };\n}\n\nexport function parseAssignmentV1(body: string): Assignment {\n let payload: unknown;\n try {\n payload = JSON.parse(body);\n } catch {\n throw new SdkError(\"Invalid JSON payload\");\n }\n\n if (!isObject(payload)) {\n throw new SdkError(\"Invalid assignment payload\");\n }\n\n if (payload.version !== CONTRACT_VERSION) {\n throw new SdkError(\"Unsupported assignment contract version\");\n }\n if (!isObject(payload.assignment)) {\n throw new SdkError(\"Missing assignment envelope payload\");\n }\n\n return parseAssignmentRecord(payload.assignment);\n}\n\nexport function toAssignmentEnvelopeV1(assignment: Assignment): AssignmentEnvelopeV1 {\n return {\n version: CONTRACT_VERSION,\n assignment,\n };\n}\n\nexport function getContractVersion(): SdkContractVersion {\n return CONTRACT_VERSION;\n}\n","import { SdkError } from \"./errors\";\nimport { parseAssignmentV1 } from \"./contracts\";\nimport { verifyWebhookSignature } from \"./signature\";\nimport type { Assignment, AssignmentResult, WebhookInput } from \"./types\";\n\nexport const DEFAULT_SIGNATURE_HEADER = \"x-bounty-signature\";\nexport const DEFAULT_TIMESTAMP_HEADER = \"x-bounty-timestamp\";\n\nexport type WebhookHandlerOptions = {\n webhookSecret: string;\n onAssignment: (params: { assignment: Assignment }) => Promise<AssignmentResult>;\n verifySignature?: boolean;\n};\n\nexport type WebhookHttpResponse = {\n status: number;\n body: AssignmentResult;\n};\n\nexport function createWebhookHandler(options: WebhookHandlerOptions) {\n const shouldVerify = options.verifySignature ?? true;\n\n return async function handleWebhook(input: WebhookInput): Promise<AssignmentResult> {\n if (shouldVerify) {\n verifyWebhookSignature({\n webhookSecret: options.webhookSecret,\n body: input.body,\n ...(input.signature ? { signature: input.signature } : {}),\n ...(input.timestamp ? { timestamp: input.timestamp } : {}),\n });\n }\n\n const assignment = parseAssignmentV1(input.body);\n return options.onAssignment({ assignment });\n };\n}\n\nexport async function executeWebhook(\n handler: ReturnType<typeof createWebhookHandler>,\n input: WebhookInput,\n): Promise<WebhookHttpResponse> {\n try {\n const body = await handler(input);\n return {\n status: 200,\n body,\n };\n } catch (error) {\n const message = error instanceof Error ? error.message : \"Unexpected webhook error\";\n const sdkError = error instanceof SdkError ? error : new SdkError(message);\n return {\n status: 400,\n body: {\n status: \"timed_out\",\n error: sdkError.message,\n },\n };\n }\n}\n","import {\n DEFAULT_SIGNATURE_HEADER,\n DEFAULT_TIMESTAMP_HEADER,\n createWebhookHandler,\n executeWebhook,\n type WebhookHandlerOptions,\n} from \"./webhook\";\n\nfunction headerValue(headers: Record<string, string | string[] | undefined>, key: string) {\n const value = headers[key] ?? headers[key.toLowerCase()];\n if (Array.isArray(value)) {\n return value[0];\n }\n return value;\n}\n\nfunction normalizeBody(body: unknown): string {\n if (typeof body === \"string\") {\n return body;\n }\n if (body === undefined || body === null) {\n return \"\";\n }\n return JSON.stringify(body);\n}\n\nfunction toWebhookInput(params: {\n body: string;\n signature: string | undefined;\n timestamp: string | undefined;\n}) {\n return {\n body: params.body,\n ...(params.signature ? { signature: params.signature } : {}),\n ...(params.timestamp ? { timestamp: params.timestamp } : {}),\n };\n}\n\nexport function createExpressWebhookHandler(options: WebhookHandlerOptions) {\n const handler = createWebhookHandler(options);\n\n return async function expressWebhook(\n req: {\n headers: Record<string, string | string[] | undefined>;\n body?: unknown;\n rawBody?: string;\n },\n res: {\n status: (code: number) => { json: (payload: unknown) => void };\n },\n ) {\n const body = req.rawBody ?? normalizeBody(req.body);\n const result = await executeWebhook(\n handler,\n toWebhookInput({\n body,\n signature: headerValue(req.headers, DEFAULT_SIGNATURE_HEADER),\n timestamp: headerValue(req.headers, DEFAULT_TIMESTAMP_HEADER),\n }),\n );\n\n res.status(result.status).json(result.body);\n };\n}\n\nexport function createFastifyWebhookHandler(options: WebhookHandlerOptions) {\n const handler = createWebhookHandler(options);\n\n return async function fastifyWebhook(\n request: {\n headers: Record<string, string | string[] | undefined>;\n body?: unknown;\n rawBody?: string;\n },\n reply: {\n code: (statusCode: number) => { send: (payload: unknown) => void };\n },\n ) {\n const body = request.rawBody ?? normalizeBody(request.body);\n const result = await executeWebhook(\n handler,\n toWebhookInput({\n body,\n signature: headerValue(request.headers, DEFAULT_SIGNATURE_HEADER),\n timestamp: headerValue(request.headers, DEFAULT_TIMESTAMP_HEADER),\n }),\n );\n\n reply.code(result.status).send(result.body);\n };\n}\n\nexport function createNextWebhookHandler(options: WebhookHandlerOptions) {\n const handler = createWebhookHandler(options);\n\n return async function nextWebhook(request: Request): Promise<Response> {\n const body = await request.text();\n const result = await executeWebhook(\n handler,\n toWebhookInput({\n body,\n signature: request.headers.get(DEFAULT_SIGNATURE_HEADER) ?? undefined,\n timestamp: request.headers.get(DEFAULT_TIMESTAMP_HEADER) ?? undefined,\n }),\n );\n\n return new Response(JSON.stringify(result.body), {\n status: result.status,\n headers: { \"content-type\": \"application/json\" },\n });\n };\n}\n\nexport function createHonoWebhookHandler(options: WebhookHandlerOptions) {\n const handler = createWebhookHandler(options);\n\n return async function honoWebhook(c: {\n req: {\n text: () => Promise<string>;\n header: (name: string) => string | undefined;\n };\n json: (payload: unknown, status?: number) => Response;\n }) {\n const body = await c.req.text();\n const result = await executeWebhook(\n handler,\n toWebhookInput({\n body,\n signature: c.req.header(DEFAULT_SIGNATURE_HEADER),\n timestamp: c.req.header(DEFAULT_TIMESTAMP_HEADER),\n }),\n );\n\n return c.json(result.body, result.status);\n };\n}\n","import type { AssignmentResult } from \"./types\";\n\nexport type TableRow = Record<string, unknown>;\n\nexport type TablePayload = {\n table: {\n columns: string[];\n rows: TableRow[];\n };\n row_count: number;\n rows_unique: boolean;\n has_contact_method: boolean;\n summary?: string;\n};\n\nexport type CreateTableResultOptions = {\n columns?: string[];\n summary?: string;\n contactFields?: string[];\n dedupeBy?: string[];\n};\n\nconst DEFAULT_CONTACT_FIELDS = [\"email\", \"phone\", \"profile_url\", \"linkedin_url\"];\n\nfunction hasValue(value: unknown) {\n if (typeof value === \"string\") {\n return value.trim().length > 0;\n }\n return value !== null && value !== undefined;\n}\n\nfunction deriveColumns(rows: TableRow[]) {\n const ordered: string[] = [];\n for (const row of rows) {\n for (const key of Object.keys(row)) {\n if (!ordered.includes(key)) {\n ordered.push(key);\n }\n }\n }\n return ordered;\n}\n\nfunction makeRowKey(row: TableRow, keys: string[]) {\n const normalized = keys.map((key) => [key, row[key]]);\n return JSON.stringify(normalized);\n}\n\nexport function createTablePayload(\n rows: TableRow[],\n options: CreateTableResultOptions = {},\n): TablePayload {\n const columns = options.columns ?? deriveColumns(rows);\n const dedupeKeys = options.dedupeBy && options.dedupeBy.length > 0 ? options.dedupeBy : columns;\n const contactFields =\n options.contactFields && options.contactFields.length > 0\n ? options.contactFields\n : DEFAULT_CONTACT_FIELDS;\n\n const uniqueCount = new Set(rows.map((row) => makeRowKey(row, dedupeKeys))).size;\n const hasContactMethod = rows.every((row) => contactFields.some((field) => hasValue(row[field])));\n\n return {\n table: {\n columns,\n rows,\n },\n row_count: rows.length,\n rows_unique: uniqueCount === rows.length,\n has_contact_method: hasContactMethod,\n ...(options.summary ? { summary: options.summary } : {}),\n };\n}\n\nexport function createTableResult(\n rows: TableRow[],\n options: CreateTableResultOptions = {},\n): Pick<AssignmentResult, \"result\"> {\n return {\n result: createTablePayload(rows, options),\n };\n}\n"],"mappings":";AAEO,IAAM,WAAN,cAAuB,MAAM;AAAA,EAClC,YAAY,SAAiB;AAC3B,UAAM,OAAO;AACb,SAAK,OAAO;AAAA,EACd;AACF;AAEO,IAAM,WAAN,cAAuB,SAAS;AAAA,EAC5B;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EAET,YAAY,QAKT;AACD,UAAM,OAAO,OAAO;AACpB,SAAK,OAAO;AACZ,SAAK,SAAS,OAAO;AACrB,SAAK,OAAO,OAAO;AACnB,SAAK,OAAO,OAAO;AACnB,SAAK,YAAY,OAAO,WAAW,OAAO,OAAO,UAAU;AAAA,EAC7D;AACF;;;ACbO,IAAM,cAAN,MAAkB;AAAA,EACN;AAAA,EACA;AAAA,EACA;AAAA,EAEjB,YAAY,SAAwB;AAClC,SAAK,UAAU,QAAQ,QAAQ,QAAQ,OAAO,EAAE;AAChD,SAAK,SAAS,QAAQ;AACtB,SAAK,YAAY,QAAQ,aAAa;AAAA,EACxC;AAAA,EAEA,MAAM,cAAc,cAAsB,SAA8C;AACtF,UAAM,KAAK,KAAK,0BAA0B;AAAA,MACxC,eAAe;AAAA,MACf,GAAG;AAAA,IACL,CAAC;AAAA,EACH;AAAA,EAEA,MAAM,aAAa,OAA2C;AAC5D,UAAM,UAA4B;AAAA,MAChC,QAAQ,MAAM;AAAA,MACd,GAAI,MAAM,SAAS,EAAE,QAAQ,MAAM,OAAO,IAAI,CAAC;AAAA,MAC/C,GAAI,MAAM,QAAQ,EAAE,OAAO,MAAM,MAAM,IAAI,CAAC;AAAA,IAC9C;AAEA,UAAM,KAAK,KAAK,6BAA6B;AAAA,MAC3C,eAAe,MAAM;AAAA,MACrB,GAAG;AAAA,IACL,CAAC;AAAA,EACH;AAAA,EAEA,MAAM,YAAY,OAA0C;AAC1D,UAAM,KAAK,aAAa;AAAA,MACtB,cAAc,MAAM;AAAA,MACpB,QAAQ;AAAA,MACR,OAAO,MAAM;AAAA,MACb,GAAI,MAAM,UAAU,EAAE,QAAQ,EAAE,SAAS,MAAM,QAAQ,EAAE,IAAI,CAAC;AAAA,IAChE,CAAC;AAAA,EACH;AAAA,EAEA,MAAc,KAAK,MAAc,MAA8C;AAC7E,UAAM,WAAW,MAAM,KAAK,UAAU,GAAG,KAAK,OAAO,GAAG,IAAI,IAAI;AAAA,MAC9D,QAAQ;AAAA,MACR,SAAS;AAAA,QACP,gBAAgB;AAAA,QAChB,eAAe,UAAU,KAAK,MAAM;AAAA,MACtC;AAAA,MACA,MAAM,KAAK,UAAU,IAAI;AAAA,IAC3B,CAAC;AAED,QAAI,CAAC,SAAS,IAAI;AAChB,YAAM,MAAM,KAAK,WAAW,QAAQ;AAAA,IACtC;AAAA,EACF;AAAA,EAEA,MAAc,WAAW,UAAuC;AAC9D,UAAM,MAAM,MAAM,SAAS,KAAK;AAChC,QAAI,SAA8B;AAElC,QAAI,KAAK;AACP,UAAI;AACF,iBAAS,KAAK,MAAM,GAAG;AAAA,MACzB,QAAQ;AACN,iBAAS,EAAE,SAAS,IAAI;AAAA,MAC1B;AAAA,IACF;AAEA,WAAO,IAAI,SAAS;AAAA,MAClB,QAAQ,SAAS;AAAA,MACjB,SACE,QAAQ,WAAW,uBAAuB,SAAS,MAAM,MAAM,OAAO,SAAS,UAAU;AAAA,MAC3F,MAAM,QAAQ;AAAA,MACd,MAAM;AAAA,IACR,CAAC;AAAA,EACH;AACF;;;AC1FA,SAAS,YAAY,uBAAuB;AAGrC,SAAS,wBAAwB,QAIrC;AACD,QAAM,gBAAgB,GAAG,OAAO,SAAS,IAAI,OAAO,IAAI;AACxD,QAAM,SAAS,WAAW,UAAU,OAAO,aAAa,EACrD,OAAO,eAAe,MAAM,EAC5B,OAAO,KAAK;AACf,SAAO,UAAU,MAAM;AACzB;AAEO,SAAS,uBAAuB,QAKpC;AACD,MAAI,CAAC,OAAO,aAAa,CAAC,OAAO,WAAW;AAC1C,UAAM,IAAI,SAAS,wCAAwC;AAAA,EAC7D;AAEA,QAAM,WAAW,wBAAwB;AAAA,IACvC,eAAe,OAAO;AAAA,IACtB,WAAW,OAAO;AAAA,IAClB,MAAM,OAAO;AAAA,EACf,CAAC;AAED,QAAM,iBAAiB,OAAO,KAAK,UAAU,MAAM;AACnD,QAAM,eAAe,OAAO,KAAK,OAAO,WAAW,MAAM;AAEzD,MAAI,eAAe,WAAW,aAAa,QAAQ;AACjD,UAAM,IAAI,SAAS,2BAA2B;AAAA,EAChD;AAEA,MAAI,CAAC,gBAAgB,gBAAgB,YAAY,GAAG;AAClD,UAAM,IAAI,SAAS,2BAA2B;AAAA,EAChD;AACF;;;ACtCA,IAAM,mBAAuC;AAE7C,SAAS,SAAS,OAAkD;AAClE,SAAO,CAAC,CAAC,SAAS,OAAO,UAAU;AACrC;AAEA,SAAS,sBAAsB,QAA6C;AAC1E,MAAI,OAAO,OAAO,kBAAkB,UAAU;AAC5C,UAAM,IAAI,SAAS,uBAAuB;AAAA,EAC5C;AACA,MAAI,OAAO,OAAO,kBAAkB,UAAU;AAC5C,UAAM,IAAI,SAAS,uBAAuB;AAAA,EAC5C;AACA,MAAI,CAAC,SAAS,OAAO,OAAO,GAAG;AAC7B,UAAM,IAAI,SAAS,iBAAiB;AAAA,EACtC;AACA,MAAI,CAAC,SAAS,OAAO,aAAa,GAAG;AACnC,UAAM,IAAI,SAAS,uBAAuB;AAAA,EAC5C;AAEA,QAAM,UAAU,OAAO;AACvB,MAAI,OAAO,QAAQ,UAAU,UAAU;AACrC,UAAM,IAAI,SAAS,uBAAuB;AAAA,EAC5C;AACA,MAAI,CAAC,SAAS,QAAQ,OAAO,GAAG;AAC9B,UAAM,IAAI,SAAS,yBAAyB;AAAA,EAC9C;AAEA,QAAM,qBAAqB,OAAO;AAElC,SAAO;AAAA,IACL,eAAe,OAAO;AAAA,IACtB,eAAe,OAAO;AAAA,IACtB,eAAe;AAAA,IACf,SAAS;AAAA,MACP,OAAO,QAAQ;AAAA,MACf,SAAS,QAAQ;AAAA,MACjB,GAAI,OAAO,QAAQ,+BAA+B,WAC9C,EAAE,4BAA4B,QAAQ,2BAA2B,IACjE,CAAC;AAAA,MACL,GAAI,OAAO,QAAQ,gCAAgC,WAC/C,EAAE,6BAA6B,QAAQ,4BAA4B,IACnE,CAAC;AAAA,MACL,GAAI,OAAO,QAAQ,aAAa,WAAW,EAAE,UAAU,QAAQ,SAAS,IAAI,CAAC;AAAA,MAC7E,GAAI,OAAO,QAAQ,gBAAgB,WAAW,EAAE,aAAa,QAAQ,YAAY,IAAI,CAAC;AAAA,IACxF;AAAA,EACF;AACF;AAEO,SAAS,kBAAkB,MAA0B;AAC1D,MAAI;AACJ,MAAI;AACF,cAAU,KAAK,MAAM,IAAI;AAAA,EAC3B,QAAQ;AACN,UAAM,IAAI,SAAS,sBAAsB;AAAA,EAC3C;AAEA,MAAI,CAAC,SAAS,OAAO,GAAG;AACtB,UAAM,IAAI,SAAS,4BAA4B;AAAA,EACjD;AAEA,MAAI,QAAQ,YAAY,kBAAkB;AACxC,UAAM,IAAI,SAAS,yCAAyC;AAAA,EAC9D;AACA,MAAI,CAAC,SAAS,QAAQ,UAAU,GAAG;AACjC,UAAM,IAAI,SAAS,qCAAqC;AAAA,EAC1D;AAEA,SAAO,sBAAsB,QAAQ,UAAU;AACjD;AAEO,SAAS,uBAAuB,YAA8C;AACnF,SAAO;AAAA,IACL,SAAS;AAAA,IACT;AAAA,EACF;AACF;AAEO,SAAS,qBAAyC;AACvD,SAAO;AACT;;;AC9EO,IAAM,2BAA2B;AACjC,IAAM,2BAA2B;AAajC,SAAS,qBAAqB,SAAgC;AACnE,QAAM,eAAe,QAAQ,mBAAmB;AAEhD,SAAO,eAAe,cAAc,OAAgD;AAClF,QAAI,cAAc;AAChB,6BAAuB;AAAA,QACrB,eAAe,QAAQ;AAAA,QACvB,MAAM,MAAM;AAAA,QACZ,GAAI,MAAM,YAAY,EAAE,WAAW,MAAM,UAAU,IAAI,CAAC;AAAA,QACxD,GAAI,MAAM,YAAY,EAAE,WAAW,MAAM,UAAU,IAAI,CAAC;AAAA,MAC1D,CAAC;AAAA,IACH;AAEA,UAAM,aAAa,kBAAkB,MAAM,IAAI;AAC/C,WAAO,QAAQ,aAAa,EAAE,WAAW,CAAC;AAAA,EAC5C;AACF;AAEA,eAAsB,eACpB,SACA,OAC8B;AAC9B,MAAI;AACF,UAAM,OAAO,MAAM,QAAQ,KAAK;AAChC,WAAO;AAAA,MACL,QAAQ;AAAA,MACR;AAAA,IACF;AAAA,EACF,SAAS,OAAO;AACd,UAAM,UAAU,iBAAiB,QAAQ,MAAM,UAAU;AACzD,UAAM,WAAW,iBAAiB,WAAW,QAAQ,IAAI,SAAS,OAAO;AACzE,WAAO;AAAA,MACL,QAAQ;AAAA,MACR,MAAM;AAAA,QACJ,QAAQ;AAAA,QACR,OAAO,SAAS;AAAA,MAClB;AAAA,IACF;AAAA,EACF;AACF;;;AClDA,SAAS,YAAY,SAAwD,KAAa;AACxF,QAAM,QAAQ,QAAQ,GAAG,KAAK,QAAQ,IAAI,YAAY,CAAC;AACvD,MAAI,MAAM,QAAQ,KAAK,GAAG;AACxB,WAAO,MAAM,CAAC;AAAA,EAChB;AACA,SAAO;AACT;AAEA,SAAS,cAAc,MAAuB;AAC5C,MAAI,OAAO,SAAS,UAAU;AAC5B,WAAO;AAAA,EACT;AACA,MAAI,SAAS,UAAa,SAAS,MAAM;AACvC,WAAO;AAAA,EACT;AACA,SAAO,KAAK,UAAU,IAAI;AAC5B;AAEA,SAAS,eAAe,QAIrB;AACD,SAAO;AAAA,IACL,MAAM,OAAO;AAAA,IACb,GAAI,OAAO,YAAY,EAAE,WAAW,OAAO,UAAU,IAAI,CAAC;AAAA,IAC1D,GAAI,OAAO,YAAY,EAAE,WAAW,OAAO,UAAU,IAAI,CAAC;AAAA,EAC5D;AACF;AAEO,SAAS,4BAA4B,SAAgC;AAC1E,QAAM,UAAU,qBAAqB,OAAO;AAE5C,SAAO,eAAe,eACpB,KAKA,KAGA;AACA,UAAM,OAAO,IAAI,WAAW,cAAc,IAAI,IAAI;AAClD,UAAM,SAAS,MAAM;AAAA,MACnB;AAAA,MACA,eAAe;AAAA,QACb;AAAA,QACA,WAAW,YAAY,IAAI,SAAS,wBAAwB;AAAA,QAC5D,WAAW,YAAY,IAAI,SAAS,wBAAwB;AAAA,MAC9D,CAAC;AAAA,IACH;AAEA,QAAI,OAAO,OAAO,MAAM,EAAE,KAAK,OAAO,IAAI;AAAA,EAC5C;AACF;AAEO,SAAS,4BAA4B,SAAgC;AAC1E,QAAM,UAAU,qBAAqB,OAAO;AAE5C,SAAO,eAAe,eACpB,SAKA,OAGA;AACA,UAAM,OAAO,QAAQ,WAAW,cAAc,QAAQ,IAAI;AAC1D,UAAM,SAAS,MAAM;AAAA,MACnB;AAAA,MACA,eAAe;AAAA,QACb;AAAA,QACA,WAAW,YAAY,QAAQ,SAAS,wBAAwB;AAAA,QAChE,WAAW,YAAY,QAAQ,SAAS,wBAAwB;AAAA,MAClE,CAAC;AAAA,IACH;AAEA,UAAM,KAAK,OAAO,MAAM,EAAE,KAAK,OAAO,IAAI;AAAA,EAC5C;AACF;AAEO,SAAS,yBAAyB,SAAgC;AACvE,QAAM,UAAU,qBAAqB,OAAO;AAE5C,SAAO,eAAe,YAAY,SAAqC;AACrE,UAAM,OAAO,MAAM,QAAQ,KAAK;AAChC,UAAM,SAAS,MAAM;AAAA,MACnB;AAAA,MACA,eAAe;AAAA,QACb;AAAA,QACA,WAAW,QAAQ,QAAQ,IAAI,wBAAwB,KAAK;AAAA,QAC5D,WAAW,QAAQ,QAAQ,IAAI,wBAAwB,KAAK;AAAA,MAC9D,CAAC;AAAA,IACH;AAEA,WAAO,IAAI,SAAS,KAAK,UAAU,OAAO,IAAI,GAAG;AAAA,MAC/C,QAAQ,OAAO;AAAA,MACf,SAAS,EAAE,gBAAgB,mBAAmB;AAAA,IAChD,CAAC;AAAA,EACH;AACF;AAEO,SAAS,yBAAyB,SAAgC;AACvE,QAAM,UAAU,qBAAqB,OAAO;AAE5C,SAAO,eAAe,YAAY,GAM/B;AACD,UAAM,OAAO,MAAM,EAAE,IAAI,KAAK;AAC9B,UAAM,SAAS,MAAM;AAAA,MACnB;AAAA,MACA,eAAe;AAAA,QACb;AAAA,QACA,WAAW,EAAE,IAAI,OAAO,wBAAwB;AAAA,QAChD,WAAW,EAAE,IAAI,OAAO,wBAAwB;AAAA,MAClD,CAAC;AAAA,IACH;AAEA,WAAO,EAAE,KAAK,OAAO,MAAM,OAAO,MAAM;AAAA,EAC1C;AACF;;;ACjHA,IAAM,yBAAyB,CAAC,SAAS,SAAS,eAAe,cAAc;AAE/E,SAAS,SAAS,OAAgB;AAChC,MAAI,OAAO,UAAU,UAAU;AAC7B,WAAO,MAAM,KAAK,EAAE,SAAS;AAAA,EAC/B;AACA,SAAO,UAAU,QAAQ,UAAU;AACrC;AAEA,SAAS,cAAc,MAAkB;AACvC,QAAM,UAAoB,CAAC;AAC3B,aAAW,OAAO,MAAM;AACtB,eAAW,OAAO,OAAO,KAAK,GAAG,GAAG;AAClC,UAAI,CAAC,QAAQ,SAAS,GAAG,GAAG;AAC1B,gBAAQ,KAAK,GAAG;AAAA,MAClB;AAAA,IACF;AAAA,EACF;AACA,SAAO;AACT;AAEA,SAAS,WAAW,KAAe,MAAgB;AACjD,QAAM,aAAa,KAAK,IAAI,CAAC,QAAQ,CAAC,KAAK,IAAI,GAAG,CAAC,CAAC;AACpD,SAAO,KAAK,UAAU,UAAU;AAClC;AAEO,SAAS,mBACd,MACA,UAAoC,CAAC,GACvB;AACd,QAAM,UAAU,QAAQ,WAAW,cAAc,IAAI;AACrD,QAAM,aAAa,QAAQ,YAAY,QAAQ,SAAS,SAAS,IAAI,QAAQ,WAAW;AACxF,QAAM,gBACJ,QAAQ,iBAAiB,QAAQ,cAAc,SAAS,IACpD,QAAQ,gBACR;AAEN,QAAM,cAAc,IAAI,IAAI,KAAK,IAAI,CAAC,QAAQ,WAAW,KAAK,UAAU,CAAC,CAAC,EAAE;AAC5E,QAAM,mBAAmB,KAAK,MAAM,CAAC,QAAQ,cAAc,KAAK,CAAC,UAAU,SAAS,IAAI,KAAK,CAAC,CAAC,CAAC;AAEhG,SAAO;AAAA,IACL,OAAO;AAAA,MACL;AAAA,MACA;AAAA,IACF;AAAA,IACA,WAAW,KAAK;AAAA,IAChB,aAAa,gBAAgB,KAAK;AAAA,IAClC,oBAAoB;AAAA,IACpB,GAAI,QAAQ,UAAU,EAAE,SAAS,QAAQ,QAAQ,IAAI,CAAC;AAAA,EACxD;AACF;AAEO,SAAS,kBACd,MACA,UAAoC,CAAC,GACH;AAClC,SAAO;AAAA,IACL,QAAQ,mBAAmB,MAAM,OAAO;AAAA,EAC1C;AACF;","names":[]}
|
package/package.json
ADDED
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@bounty-ai/agent-sdk",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"description": "Bounty agent SDK for receiving assignments and submitting results",
|
|
5
|
+
"main": "./dist/index.cjs",
|
|
6
|
+
"scripts": {
|
|
7
|
+
"test": "vitest run --passWithNoTests",
|
|
8
|
+
"build": "tsup src/index.ts --format esm,cjs --dts --sourcemap --clean --target node18",
|
|
9
|
+
"dev": "tsup src/index.ts --format esm,cjs --dts --sourcemap --watch --target node18",
|
|
10
|
+
"clean": "rimraf dist",
|
|
11
|
+
"lint": "eslint .",
|
|
12
|
+
"typecheck": "tsc --noEmit",
|
|
13
|
+
"prepublishOnly": "npm run clean && npm run lint && npm run typecheck && npm run test && npm run build"
|
|
14
|
+
},
|
|
15
|
+
"keywords": [
|
|
16
|
+
"bounty",
|
|
17
|
+
"agent",
|
|
18
|
+
"sdk",
|
|
19
|
+
"typescript"
|
|
20
|
+
],
|
|
21
|
+
"author": "",
|
|
22
|
+
"license": "MIT",
|
|
23
|
+
"type": "module",
|
|
24
|
+
"devDependencies": {
|
|
25
|
+
"@eslint/js": "^9.39.2",
|
|
26
|
+
"@types/node": "^25.2.3",
|
|
27
|
+
"@typescript-eslint/eslint-plugin": "^8.56.0",
|
|
28
|
+
"@typescript-eslint/parser": "^8.56.0",
|
|
29
|
+
"eslint": "^9.39.2",
|
|
30
|
+
"globals": "^17.3.0",
|
|
31
|
+
"jiti": "^2.6.1",
|
|
32
|
+
"rimraf": "^6.1.3",
|
|
33
|
+
"tsup": "^8.5.1",
|
|
34
|
+
"typescript": "^5.9.3",
|
|
35
|
+
"typescript-eslint": "^8.56.0",
|
|
36
|
+
"vitest": "^4.0.18"
|
|
37
|
+
},
|
|
38
|
+
"module": "./dist/index.js",
|
|
39
|
+
"types": "./dist/index.d.ts",
|
|
40
|
+
"sideEffects": false,
|
|
41
|
+
"engines": {
|
|
42
|
+
"node": ">=18"
|
|
43
|
+
},
|
|
44
|
+
"exports": {
|
|
45
|
+
".": {
|
|
46
|
+
"types": "./dist/index.d.ts",
|
|
47
|
+
"import": "./dist/index.js",
|
|
48
|
+
"require": "./dist/index.cjs"
|
|
49
|
+
}
|
|
50
|
+
},
|
|
51
|
+
"files": [
|
|
52
|
+
"dist",
|
|
53
|
+
"README.md",
|
|
54
|
+
"LICENSE"
|
|
55
|
+
],
|
|
56
|
+
"publishConfig": {
|
|
57
|
+
"access": "public"
|
|
58
|
+
}
|
|
59
|
+
}
|