@ixo/asks-mcp 2.0.0-dev.1 → 2.0.0-dev.2

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/asks-mcp.mjs +378 -196
  2. package/package.json +1 -1
package/dist/asks-mcp.mjs CHANGED
@@ -8093,18 +8093,18 @@ function formAnswersOf(envelope) {
8093
8093
  for (const key of keys) {
8094
8094
  const value = doc[key];
8095
8095
  const isFiles = Array.isArray(value) && value.every((one) => one && typeof one === "object" && typeof one.name === "string");
8096
- const said3 = isFiles ? value.map((one) => one.name).join(", ") : typeof value === "boolean" ? value ? "yes" : "no" : typeof value === "string" || typeof value === "number" ? String(value) : null;
8097
- if (said3 === null) return null;
8098
- let found = deliverable.indexOf(`: ${said3}`, at);
8099
- while (found !== -1 && !(found + 2 + said3.length === deliverable.length || deliverable[found + 2 + said3.length] === "\n")) found = deliverable.indexOf(`: ${said3}`, found + 1);
8096
+ const said4 = isFiles ? value.map((one) => one.name).join(", ") : typeof value === "boolean" ? value ? "yes" : "no" : typeof value === "string" || typeof value === "number" ? String(value) : null;
8097
+ if (said4 === null) return null;
8098
+ let found = deliverable.indexOf(`: ${said4}`, at);
8099
+ while (found !== -1 && !(found + 2 + said4.length === deliverable.length || deliverable[found + 2 + said4.length] === "\n")) found = deliverable.indexOf(`: ${said4}`, found + 1);
8100
8100
  if (found === -1) return null;
8101
8101
  const label = deliverable.slice(at, found).trim();
8102
8102
  if (!label || label.includes("\n")) return null;
8103
- at = found + 2 + said3.length + 1;
8103
+ at = found + 2 + said4.length + 1;
8104
8104
  if (isFiles) {
8105
8105
  const files = value.filter((one) => isStoredFile(one.content)).map((one) => ({ name: one.name.replace(/\s+/g, " ").trim().slice(0, 80) || "file", mediaType: typeof one.type === "string" ? one.type.slice(0, 80) : "application/octet-stream", url: one.content }));
8106
8106
  out.push({ label, files });
8107
- } else out.push({ label, value: said3 });
8107
+ } else out.push({ label, value: said4 });
8108
8108
  }
8109
8109
  return at >= deliverable.length ? out : null;
8110
8110
  }
@@ -8429,24 +8429,24 @@ function blockOf(raw) {
8429
8429
  return null;
8430
8430
  }
8431
8431
  function callOf(raw) {
8432
- const call2 = raw;
8433
- if (!call2 || typeof call2 !== "object") return null;
8432
+ const call3 = raw;
8433
+ if (!call3 || typeof call3 !== "object") return null;
8434
8434
  const L4 = CALL_LIMITS;
8435
- if (typeof call2.slug !== "string" || !CALL_SLUG.test(call2.slug)) return null;
8436
- if (!CALL_LEGS.includes(call2.leg)) return null;
8437
- if (!line(call2.title, L4.title) || !line(call2.lede, L4.lede) || !line(call2.poster, L4.poster)) return null;
8438
- if (!Array.isArray(call2.points) || call2.points.length === 0 || call2.points.length > L4.lines || !call2.points.every((one) => finite(one) && one >= 0 && one <= 100)) return null;
8439
- const money2 = call2.money;
8435
+ if (typeof call3.slug !== "string" || !CALL_SLUG.test(call3.slug)) return null;
8436
+ if (!CALL_LEGS.includes(call3.leg)) return null;
8437
+ if (!line(call3.title, L4.title) || !line(call3.lede, L4.lede) || !line(call3.poster, L4.poster)) return null;
8438
+ if (!Array.isArray(call3.points) || call3.points.length === 0 || call3.points.length > L4.lines || !call3.points.every((one) => finite(one) && one >= 0 && one <= 100)) return null;
8439
+ const money2 = call3.money;
8440
8440
  if (!money2 || typeof money2 !== "object") return null;
8441
8441
  if (!amount(money2.prize) || !whole(money2.runnersN, 0, 5) || !amount(money2.runnersEach) || !amount(money2.entryEach) || !whole(money2.entryUpTo, 1, 1e4)) return null;
8442
- const share = call2.share;
8442
+ const share = call3.share;
8443
8443
  if (share !== void 0 && (!share || typeof share !== "object" || !nonNegative(share.network) || !nonNegative(share.node) || share.network + share.node >= 100)) return null;
8444
- const named = call2.sponsor;
8444
+ const named = call3.sponsor;
8445
8445
  const sponsor = named && typeof named === "object" && typeof named.slug === "string" && CALL_SLUG.test(named.slug) && line(named.name, L4.sponsorName) && typeof named.node === "string" && ENTITY_DID.test(named.node) ? named : void 0;
8446
- if (!date5(call2.closes) || !date5(call2.drop) || !date5(call2.pick)) return null;
8446
+ if (!date5(call3.closes) || !date5(call3.drop) || !date5(call3.pick)) return null;
8447
8447
  let legs;
8448
- if (call2.legs !== void 0) {
8449
- const raw2 = call2.legs;
8448
+ if (call3.legs !== void 0) {
8449
+ const raw2 = call3.legs;
8450
8450
  if (!raw2 || typeof raw2 !== "object") return null;
8451
8451
  legs = {};
8452
8452
  for (const name8 of CALL_LEGS) {
@@ -8456,42 +8456,42 @@ function callOf(raw) {
8456
8456
  legs[name8] = id;
8457
8457
  }
8458
8458
  }
8459
- if (!Array.isArray(call2.blocks) || call2.blocks.length > L4.blocks) return null;
8460
- const blocks = call2.blocks.map(blockOf);
8459
+ if (!Array.isArray(call3.blocks) || call3.blocks.length > L4.blocks) return null;
8460
+ const blocks = call3.blocks.map(blockOf);
8461
8461
  if (blocks.some((block2) => block2 === null)) return null;
8462
8462
  let review = null;
8463
- if (call2.kind !== void 0) {
8464
- if (call2.kind !== "review" || call2.mode !== "hire") return null;
8465
- const subject = call2.subject;
8463
+ if (call3.kind !== void 0) {
8464
+ if (call3.kind !== "review" || call3.mode !== "hire") return null;
8465
+ const subject = call3.subject;
8466
8466
  if (subject !== void 0) {
8467
8467
  if (!subject || typeof subject !== "object" || !line(subject.name, L4.subjectName)) return null;
8468
8468
  if (subject.version !== void 0 && !line(subject.version, L4.version)) return null;
8469
8469
  if (subject.where !== void 0 && !line(subject.where, L4.where)) return null;
8470
8470
  }
8471
- if (call2.scenarios !== void 0 && (!Array.isArray(call2.scenarios) || call2.scenarios.length === 0 || call2.scenarios.length > L4.scenarios || !call2.scenarios.every((one) => line(one, L4.scenario)))) return null;
8471
+ if (call3.scenarios !== void 0 && (!Array.isArray(call3.scenarios) || call3.scenarios.length === 0 || call3.scenarios.length > L4.scenarios || !call3.scenarios.every((one) => line(one, L4.scenario)))) return null;
8472
8472
  review = {
8473
8473
  kind: "review",
8474
8474
  ...subject ? { subject: { name: subject.name, ...subject.version !== void 0 ? { version: subject.version } : {}, ...subject.where !== void 0 ? { where: subject.where } : {} } } : {},
8475
- ...call2.scenarios !== void 0 ? { scenarios: [...call2.scenarios] } : {}
8475
+ ...call3.scenarios !== void 0 ? { scenarios: [...call3.scenarios] } : {}
8476
8476
  };
8477
8477
  }
8478
8478
  return {
8479
8479
  call: {
8480
- slug: call2.slug,
8481
- leg: call2.leg,
8480
+ slug: call3.slug,
8481
+ leg: call3.leg,
8482
8482
  /* The one literal: anything else is a competition, as every call before it was. */
8483
- ...call2.mode === "hire" ? { mode: "hire" } : {},
8483
+ ...call3.mode === "hire" ? { mode: "hire" } : {},
8484
8484
  ...review ?? {},
8485
- title: call2.title,
8486
- lede: call2.lede,
8487
- poster: call2.poster,
8488
- points: [...call2.points],
8485
+ title: call3.title,
8486
+ lede: call3.lede,
8487
+ poster: call3.poster,
8488
+ points: [...call3.points],
8489
8489
  money: { prize: money2.prize, runnersN: money2.runnersN, runnersEach: money2.runnersEach, entryEach: money2.entryEach, entryUpTo: money2.entryUpTo },
8490
8490
  ...share ? { share: { network: share.network, node: share.node } } : {},
8491
8491
  ...sponsor ? { sponsor: { slug: sponsor.slug, name: sponsor.name, node: sponsor.node } } : {},
8492
- closes: call2.closes,
8493
- drop: call2.drop,
8494
- pick: call2.pick,
8492
+ closes: call3.closes,
8493
+ drop: call3.drop,
8494
+ pick: call3.pick,
8495
8495
  ...legs ? { legs } : {},
8496
8496
  blocks
8497
8497
  }
@@ -9080,7 +9080,7 @@ function toEngineRubric(terms, binding, options = {}) {
9080
9080
  const screens = [];
9081
9081
  if (PHOTOGRAPH.has(normalized.deliverable.type)) {
9082
9082
  const photos = pair && !normalized.site ? [PHOTO, BEFORE_PHOTO] : [PHOTO];
9083
- const said3 = (photo) => photos.length === 1 ? "The photograph" : photo === BEFORE_PHOTO ? "The before photograph" : "The after photograph";
9083
+ const said4 = (photo) => photos.length === 1 ? "The photograph" : photo === BEFORE_PHOTO ? "The before photograph" : "The after photograph";
9084
9084
  const screened2 = (sourced) => {
9085
9085
  pending.push(sourced);
9086
9086
  screens.push({ ...sourced.gate, when: extRef(sourced.name) });
@@ -9090,7 +9090,7 @@ function toEngineRubric(terms, binding, options = {}) {
9090
9090
  screened2({
9091
9091
  name: PHOTO_CHECKS.notMarkedGenerated,
9092
9092
  send: { photo },
9093
- gate: { "@type": "Gate", code: codeFor(extra, "not-generated"), reason: `${said3(photo)} says of itself that an AI generator made it`, onFail: "reject", class: "invalid_evidence" }
9093
+ gate: { "@type": "Gate", code: codeFor(extra, "not-generated"), reason: `${said4(photo)} says of itself that an AI generator made it`, onFail: "reject", class: "invalid_evidence" }
9094
9094
  });
9095
9095
  }
9096
9096
  const judged = normalized.criteria.filter((criterion) => criterion.kind === "judge").length;
@@ -9117,7 +9117,7 @@ function toEngineRubric(terms, binding, options = {}) {
9117
9117
  gate: {
9118
9118
  "@type": "Gate",
9119
9119
  code: codeFor(extra, "not-elsewhere"),
9120
- reason: `${said3(photo)}'s own GPS puts it far from the place reported. Take the photograph at the place you are reporting`,
9120
+ reason: `${said4(photo)}'s own GPS puts it far from the place reported. Take the photograph at the place you are reporting`,
9121
9121
  onFail: "reject",
9122
9122
  class: "invalid_evidence"
9123
9123
  }
@@ -10087,8 +10087,8 @@ var init_engine = __esm({
10087
10087
  num = (value) => typeof value === "number" && Number.isFinite(value) ? value : null;
10088
10088
  obj2 = (value) => value !== null && typeof value === "object" && !Array.isArray(value) ? value : null;
10089
10089
  withPerson = (gate, verdict, reasonCodes) => {
10090
- const said3 = personGate(gate.code, verdict, reasonCodes);
10091
- return said3 ? { ...gate, ...said3, joined: true } : gate;
10090
+ const said4 = personGate(gate.code, verdict, reasonCodes);
10091
+ return said4 ? { ...gate, ...said4, joined: true } : gate;
10092
10092
  };
10093
10093
  codesOf = (raw) => Array.isArray(raw) ? raw.filter((one) => typeof one === "string") : [];
10094
10094
  engineStatusOf = (decision) => decision.outcome ?? (decision.verdict === "approve" || decision.verdict === "partial" ? 1 : decision.verdict === "reject" ? 2 : 5);
@@ -28345,18 +28345,18 @@ function waysIn(org, oracle, sourceId) {
28345
28345
  `In Claude Code: eval-oracle api review-billing enable --source ${sourceId ?? "<source id>"} --kit ${oracle.url.replace(/\/$/, "")} --cap <dollars> (it previews first; add --yes to sign).`
28346
28346
  ];
28347
28347
  }
28348
- async function sourceCall(oracleUrl2, audience, mint, call2, options = {}) {
28348
+ async function sourceCall(oracleUrl2, audience, mint, call3, options = {}) {
28349
28349
  try {
28350
- const response = await (options.fetch ?? fetch)(`${base3(oracleUrl2)}${call2.path}`, {
28351
- method: call2.method ?? "GET",
28350
+ const response = await (options.fetch ?? fetch)(`${base3(oracleUrl2)}${call3.path}`, {
28351
+ method: call3.method ?? "GET",
28352
28352
  headers: {
28353
28353
  accept: "application/json",
28354
- authorization: `Bearer ${await mint(audience, call2.can, call2.sourceId)}`,
28354
+ authorization: `Bearer ${await mint(audience, call3.can, call3.sourceId)}`,
28355
28355
  "x-auth-type": "ucan",
28356
- ...call2.sourceId ? { "x-source-id": call2.sourceId } : {},
28357
- ...call2.body !== void 0 ? { "content-type": "application/json" } : {}
28356
+ ...call3.sourceId ? { "x-source-id": call3.sourceId } : {},
28357
+ ...call3.body !== void 0 ? { "content-type": "application/json" } : {}
28358
28358
  },
28359
- ...call2.body !== void 0 ? { body: JSON.stringify(call2.body) } : {},
28359
+ ...call3.body !== void 0 ? { body: JSON.stringify(call3.body) } : {},
28360
28360
  signal: AbortSignal.timeout(TIMEOUT2)
28361
28361
  });
28362
28362
  const body = await response.json().catch(() => null);
@@ -28554,8 +28554,8 @@ function parseChecks(raw) {
28554
28554
  return raw.flatMap((one) => {
28555
28555
  const c = one;
28556
28556
  if (!c || typeof c.name !== "string" || c.status !== "ok" && c.status !== "error") return [];
28557
- const said3 = typeof c.reason === "string" ? c.reason.trim() : "";
28558
- return [{ name: c.name, status: c.status, value: c.value ?? null, reason: said3 ? said3.length > REASON_MAX ? `${said3.slice(0, REASON_MAX).trimEnd()}\u2026` : said3 : null }];
28557
+ const said4 = typeof c.reason === "string" ? c.reason.trim() : "";
28558
+ return [{ name: c.name, status: c.status, value: c.value ?? null, reason: said4 ? said4.length > REASON_MAX ? `${said4.slice(0, REASON_MAX).trimEnd()}\u2026` : said4 : null }];
28559
28559
  });
28560
28560
  }
28561
28561
  function parseReviewerNote(raw) {
@@ -29696,14 +29696,14 @@ function rulesOf(rubric, manifest) {
29696
29696
  const work = manifest && typeof manifest === "object" ? manifest : {};
29697
29697
  const ai = listOf(rub.aiChecks).length ? listOf(rub.aiChecks) : listOf(work.ai && typeof work.ai === "object" ? Object.values(work.ai) : []);
29698
29698
  const tasks = listOf(rub.review?.tasks).length ? listOf(rub.review?.tasks) : listOf(work.review?.taskDetails);
29699
- const said3 = (kind) => (raw) => {
29699
+ const said4 = (kind) => (raw) => {
29700
29700
  const text4 = clampText(raw, 300);
29701
29701
  return text4 ? [{ text: text4, kind }] : [];
29702
29702
  };
29703
29703
  return [
29704
- ...listOf(rub.gates).flatMap((gate) => said3("measure")(gate.reason)),
29705
- ...ai.flatMap((check2) => (Array.isArray(check2.instructions) ? check2.instructions : []).flatMap(said3("judge"))),
29706
- ...tasks.flatMap((task) => said3("attest")(task.prompt))
29704
+ ...listOf(rub.gates).flatMap((gate) => said4("measure")(gate.reason)),
29705
+ ...ai.flatMap((check2) => (Array.isArray(check2.instructions) ? check2.instructions : []).flatMap(said4("judge"))),
29706
+ ...tasks.flatMap((task) => said4("attest")(task.prompt))
29707
29707
  ].slice(0, RULES_MAX);
29708
29708
  }
29709
29709
  async function readProven(resource2, fetchImpl) {
@@ -30053,7 +30053,7 @@ function checkEnvelope(input) {
30053
30053
  if (problems.length) throw new Error(problems.join(" "));
30054
30054
  const answered = input.fields.filter((field2) => !isEmpty2(input.values[field2.name]));
30055
30055
  const answers = Object.fromEntries(answered.map((field2) => [field2.name, answerOf(field2, input.values[field2.name])]));
30056
- const said3 = (field2) => {
30056
+ const said4 = (field2) => {
30057
30057
  const value = input.values[field2.name];
30058
30058
  if (field2.type === "file") return filesOf(value).map((file3) => file3.name).join(", ");
30059
30059
  if (field2.type === "boolean") return value ? "yes" : "no";
@@ -30067,7 +30067,7 @@ function checkEnvelope(input) {
30067
30067
  ...input.delegate ? { delegate: input.delegate } : {},
30068
30068
  ...input.alias ? { alias: input.alias } : {},
30069
30069
  ...input.via ? { via: input.via } : {},
30070
- deliverable: answered.map((field2) => `${field2.label}: ${said3(field2)}`).join("\n"),
30070
+ deliverable: answered.map((field2) => `${field2.label}: ${said4(field2)}`).join("\n"),
30071
30071
  /* Last: a form question that shares an envelope field's name keeps the person's answer, which is what the checker reads. */
30072
30072
  ...answers
30073
30073
  };
@@ -250658,10 +250658,10 @@ var require_get_proto = __commonJS({
250658
250658
  var require_hasown = __commonJS({
250659
250659
  "../../node_modules/.pnpm/hasown@2.0.4/node_modules/hasown/index.js"(exports, module) {
250660
250660
  "use strict";
250661
- var call2 = Function.prototype.call;
250661
+ var call3 = Function.prototype.call;
250662
250662
  var $hasOwn = Object.prototype.hasOwnProperty;
250663
250663
  var bind2 = require_function_bind();
250664
- module.exports = bind2.call(call2, $hasOwn);
250664
+ module.exports = bind2.call(call3, $hasOwn);
250665
250665
  }
250666
250666
  });
250667
250667
 
@@ -260049,8 +260049,8 @@ async function uploadToLane(bytes3, contentType3, args) {
260049
260049
  signal: args.signal ?? AbortSignal.timeout(6e4)
260050
260050
  });
260051
260051
  if (!response.ok) {
260052
- const said3 = await response.text().catch(() => "");
260053
- throw new LaneRefused(response.status, `the private store refused the file (${response.status}${said3 ? `: ${said3.slice(0, 160)}` : ""})`);
260052
+ const said4 = await response.text().catch(() => "");
260053
+ throw new LaneRefused(response.status, `the private store refused the file (${response.status}${said4 ? `: ${said4.slice(0, 160)}` : ""})`);
260054
260054
  }
260055
260055
  const meta4 = await response.json();
260056
260056
  if (typeof meta4.cid !== "string" || !meta4.cid) throw new LaneRefused(502, "the private store gave no address for the file");
@@ -260327,8 +260327,8 @@ async function allowOperatorAmounts(collectionId, owner, options) {
260327
260327
  signal: AbortSignal.timeout(1e4)
260328
260328
  });
260329
260329
  if (response.ok) return { ok: true };
260330
- const said3 = await response.json().catch(() => null) ?? null;
260331
- const message = typeof said3?.error === "string" ? said3.error : said3?.error?.message ?? said3?.message ?? "";
260330
+ const said4 = await response.json().catch(() => null) ?? null;
260331
+ const message = typeof said4?.error === "string" ? said4.error : said4?.error?.message ?? said4?.message ?? "";
260332
260332
  why = `the oracle answered ${response.status}${message ? ` (${String(message).slice(0, 160)})` : ""}`;
260333
260333
  if (response.status === 401 || response.status === 403 || response.status === 400) break;
260334
260334
  } catch (error54) {
@@ -260757,9 +260757,9 @@ function dominantWaste(wastes) {
260757
260757
  }
260758
260758
  function wastesOf(assessment) {
260759
260759
  if (!assessment) return [];
260760
- const said3 = Array.isArray(assessment.wastes) && assessment.wastes.length > 0 ? assessment.wastes : [assessment.waste];
260760
+ const said4 = Array.isArray(assessment.wastes) && assessment.wastes.length > 0 ? assessment.wastes : [assessment.waste];
260761
260761
  const kept = [];
260762
- for (const key of ORDERED_WASTE) if (said3.includes(key) && !kept.includes(key)) kept.push(key);
260762
+ for (const key of ORDERED_WASTE) if (said4.includes(key) && !kept.includes(key)) kept.push(key);
260763
260763
  return kept;
260764
260764
  }
260765
260765
  function listSays(wastes) {
@@ -261565,8 +261565,8 @@ function broadcastTimeoutId(error54) {
261565
261565
  const txId = error54.txId;
261566
261566
  if (typeof txId !== "string" || !txId) return null;
261567
261567
  const named = error54.name === "TimeoutError";
261568
- const said3 = /was submitted but was not yet found on the chain/i.test(String(error54.message ?? ""));
261569
- return named || said3 ? txId : null;
261568
+ const said4 = /was submitted but was not yet found on the chain/i.test(String(error54.message ?? ""));
261569
+ return named || said4 ? txId : null;
261570
261570
  }
261571
261571
  function refusedAtCheckTx(error54) {
261572
261572
  if (!error54 || typeof error54 !== "object") return false;
@@ -263205,7 +263205,7 @@ function ledeOf(trace) {
263205
263205
  }
263206
263206
  function gatheredDetail(checks) {
263207
263207
  const ext = checks.filter((check2) => check2.kind === "ext");
263208
- const named = [...new Set(ext.map((check2) => words3(check2.name)).filter((said3) => Boolean(said3)))];
263208
+ const named = [...new Set(ext.map((check2) => words3(check2.name)).filter((said4) => Boolean(said4)))];
263209
263209
  const unknown3 = ext.filter((check2) => !words3(check2.name)).length;
263210
263210
  const measured = unknown3 ? [...named, unknown3 === 1 ? "one other thing" : `${unknown3} other things`] : named;
263211
263211
  const duplicates = checks.some((check2) => check2.kind === "unique");
@@ -263241,8 +263241,8 @@ function rulesSummary(rules, verdict) {
263241
263241
  const unreached = total - met - failed;
263242
263242
  if (!total) return verdict === "approve" ? "Approved against rules fixed before the work began." : "Decided against rules fixed before the work began.";
263243
263243
  if (!failed && !unreached) return `${met} of ${total} ${total === 1 ? "rule" : "rules"} met, against rules fixed before the work began.`;
263244
- const said3 = [`${met} met`, `${failed} not met`, ...unreached ? [`${unreached} not reached`] : []];
263245
- return `Of ${total} rules, ${list6(said3)}.`;
263244
+ const said4 = [`${met} met`, `${failed} not met`, ...unreached ? [`${unreached} not reached`] : []];
263245
+ return `Of ${total} rules, ${list6(said4)}.`;
263246
263246
  }
263247
263247
  function signedDetail(step) {
263248
263248
  const host = issuerHost(step.issuer);
@@ -263314,8 +263314,8 @@ function sentence3(step) {
263314
263314
  return `${face ? `${face.text} released` : "released"} to ${step.to}. ${paidDetail(step)}${fee}`;
263315
263315
  }
263316
263316
  case "recorded": {
263317
- const said3 = recordedLine(step.status);
263318
- return `${said3.line}. ${said3.detail}`;
263317
+ const said4 = recordedLine(step.status);
263318
+ return `${said4.line}. ${said4.detail}`;
263319
263319
  }
263320
263320
  }
263321
263321
  }
@@ -263362,23 +263362,23 @@ function lineSentence(line2) {
263362
263362
  if (sentence4.length > 300) throw new Error(`a judged line is ${sentence4.length} characters with its failure; the jury reads 300 at most`);
263363
263363
  return sentence4;
263364
263364
  }
263365
- function legCall(call2, leg) {
263366
- const read9 = callOf({ ...call2, leg });
263365
+ function legCall(call3, leg) {
263366
+ const read9 = callOf({ ...call3, leg });
263367
263367
  if (!read9) throw new Error("the call does not read back: a field is missing, too long, or not an https address");
263368
263368
  return read9.call;
263369
263369
  }
263370
263370
  function taskFor(title, leg, kind) {
263371
263371
  const named = title.replace(/\s+/g, " ").trim();
263372
- const said3 = leg === "entries" ? `${kind === "review" ? "Expert review" : "Open call"}: ${named}` : leg === "prize" ? `The pick of the open call: ${named}` : `A runner-up of the open call: ${named}`;
263373
- return said3.length <= 140 ? said3 : `${said3.slice(0, 139)}\u2026`;
263372
+ const said4 = leg === "entries" ? `${kind === "review" ? "Expert review" : "Open call"}: ${named}` : leg === "prize" ? `The pick of the open call: ${named}` : `A runner-up of the open call: ${named}`;
263373
+ return said4.length <= 140 ? said4 : `${said4.slice(0, 139)}\u2026`;
263374
263374
  }
263375
263375
  function callEntriesTerms(input) {
263376
263376
  if (input.lines.length !== CALL_LIMITS.lines) throw new Error(`a call is judged on exactly ${CALL_LIMITS.lines} lines`);
263377
263377
  if (input.judge.kind !== "oracle" || !input.judge.address) throw new Error("the entries are judged by the oracle, and it has to be named");
263378
- const call2 = legCall(input.call, "entries");
263379
- if (call2.points.length !== CALL_LIMITS.lines) throw new Error("one score per judged line");
263380
- if (call2.kind === "review" && !input.report) throw new Error("a review call's entries are reports: say report (the extra sections, or none)");
263381
- if (call2.kind !== "review" && input.report) throw new Error("only a review call is answered as a report");
263378
+ const call3 = legCall(input.call, "entries");
263379
+ if (call3.points.length !== CALL_LIMITS.lines) throw new Error("one score per judged line");
263380
+ if (call3.kind === "review" && !input.report) throw new Error("a review call's entries are reports: say report (the extra sections, or none)");
263381
+ if (call3.kind !== "review" && input.report) throw new Error("only a review call is answered as a report");
263382
263382
  if (input.approver !== void 0 && !/^ixo1[a-z0-9]{38,64}$/.test(input.approver)) throw new Error("approver is an ixo1 address");
263383
263383
  const criteria = [
263384
263384
  { id: "present", kind: "measure", gate: { id: "non-empty" } },
@@ -263387,11 +263387,11 @@ function callEntriesTerms(input) {
263387
263387
  ];
263388
263388
  const terms = {
263389
263389
  v: 2,
263390
- task: taskFor(call2.title, "entries", call2.kind),
263390
+ task: taskFor(call3.title, "entries", call3.kind),
263391
263391
  deliverable: { type: "text", prompt: input.report ? REVIEW_DELIVERABLE_PROMPT : "One page, in your own words, covering all five requirements" },
263392
- campaign: callTag(call2.slug),
263392
+ campaign: callTag(call3.slug),
263393
263393
  ...input.access ? { access: input.access } : {},
263394
- call: call2,
263394
+ call: call3,
263395
263395
  criteria,
263396
263396
  judge: input.judge,
263397
263397
  ...input.approver ? { approver: input.approver } : {}
@@ -263399,17 +263399,17 @@ function callEntriesTerms(input) {
263399
263399
  return input.report ? withReport(terms, input.report, input.approver ? { v: 2 } : void 0) : terms;
263400
263400
  }
263401
263401
  function callPickTerms(input) {
263402
- const call2 = legCall(input.call, input.leg);
263403
- if (call2.mode === "hire") throw new Error("a hiring call has no pick: the entries are the whole call");
263402
+ const call3 = legCall(input.call, input.leg);
263403
+ if (call3.mode === "hire") throw new Error("a hiring call has no pick: the entries are the whole call");
263404
263404
  const which = input.leg === "prize" ? "the pick" : "a runner-up";
263405
263405
  return {
263406
263406
  v: 2,
263407
- task: taskFor(call2.title, input.leg),
263407
+ task: taskFor(call3.title, input.leg),
263408
263408
  deliverable: { type: "text", prompt: "Quote the number of your entry, nothing else" },
263409
- campaign: callTag(call2.slug),
263409
+ campaign: callTag(call3.slug),
263410
263410
  ...input.access ? { access: input.access } : {},
263411
- call: call2,
263412
- criteria: [{ id: "picked", kind: "attest", text: `The poster chose this entry as ${which} of call ${call2.slug}` }],
263411
+ call: call3,
263412
+ criteria: [{ id: "picked", kind: "attest", text: `The poster chose this entry as ${which} of call ${call3.slug}` }],
263413
263413
  judge: { kind: "poster" }
263414
263414
  };
263415
263415
  }
@@ -263421,8 +263421,8 @@ function callDates(openDays, now3 = Date.now(), mode) {
263421
263421
  }
263422
263422
  return { closes: new Date(closes).toISOString(), drop: new Date(closes + DAY_MS2).toISOString(), pick: new Date(closes + 4 * DAY_MS2).toISOString() };
263423
263423
  }
263424
- function legDays(call2, leg, now3 = Date.now()) {
263425
- const until = leg === "entries" ? Date.parse(call2.closes) : Date.parse(call2.pick) + 7 * DAY_MS2;
263424
+ function legDays(call3, leg, now3 = Date.now()) {
263425
+ const until = leg === "entries" ? Date.parse(call3.closes) : Date.parse(call3.pick) + 7 * DAY_MS2;
263426
263426
  return Math.max(1, Math.ceil((until - now3) / DAY_MS2));
263427
263427
  }
263428
263428
  var ENTRY_MIN_CHARS, REVIEW_LINES, REVIEW_DELIVERABLE_PROMPT, DAY_MS2, legsOf, pickQuota;
@@ -263442,7 +263442,7 @@ var init_call = __esm({
263442
263442
  ];
263443
263443
  REVIEW_DELIVERABLE_PROMPT = "A review report: what you tested, your steps per scenario, each finding with its evidence, how to reproduce it and its severity, what to change, and the limitations";
263444
263444
  DAY_MS2 = 24 * 3600 * 1e3;
263445
- legsOf = (call2) => call2.mode === "hire" ? ["entries"] : ["prize", ...call2.money.runnersN > 0 ? ["runnersUp"] : [], "entries"];
263445
+ legsOf = (call3) => call3.mode === "hire" ? ["entries"] : ["prize", ...call3.money.runnersN > 0 ? ["runnersUp"] : [], "entries"];
263446
263446
  pickQuota = (winners) => winners + 2;
263447
263447
  }
263448
263448
  });
@@ -263711,12 +263711,12 @@ __export(callRead_exports, {
263711
263711
  sharedPay: () => sharedPay,
263712
263712
  stageWords: () => stageWords
263713
263713
  });
263714
- function stageWords(call2, now3 = Date.now()) {
263715
- if (now3 < Date.parse(call2.closes)) return `open until ${day(call2.closes)}`;
263716
- if (call2.mode === "hire") return `closed ${day(call2.closes)}; every entry that passed is paid as it is judged`;
263717
- if (now3 < Date.parse(call2.drop)) return `closed ${day(call2.closes)}; the shortlist shows ${day(call2.drop)}`;
263718
- if (now3 < Date.parse(call2.pick)) return `closed; the shortlist is out; the pick by ${day(call2.pick)}`;
263719
- return `closed; the pick was due ${day(call2.pick)}`;
263714
+ function stageWords(call3, now3 = Date.now()) {
263715
+ if (now3 < Date.parse(call3.closes)) return `open until ${day(call3.closes)}`;
263716
+ if (call3.mode === "hire") return `closed ${day(call3.closes)}; every entry that passed is paid as it is judged`;
263717
+ if (now3 < Date.parse(call3.drop)) return `closed ${day(call3.closes)}; the shortlist shows ${day(call3.drop)}`;
263718
+ if (now3 < Date.parse(call3.pick)) return `closed; the shortlist is out; the pick by ${day(call3.pick)}`;
263719
+ return `closed; the pick was due ${day(call3.pick)}`;
263720
263720
  }
263721
263721
  function sharedPay(quote, share) {
263722
263722
  const leg = grossFor(Math.round(quote * 1e6), share);
@@ -263749,35 +263749,35 @@ ${block2.prompt}`;
263749
263749
  }
263750
263750
  function callReadout(terms, ctx) {
263751
263751
  const amount3 = (value, symbol2) => dollarsOfValue(value, symbol2, ctx.network ?? "mainnet");
263752
- const call2 = terms.call;
263753
- const m = call2.money;
263754
- const hire = call2.mode === "hire";
263752
+ const call3 = terms.call;
263753
+ const m = call3.money;
263754
+ const hire = call3.mode === "hire";
263755
263755
  const lines2 = terms.criteria.filter((one) => one.kind === "judge").map((one) => one.text);
263756
263756
  const n = countWords(lines2.length || 5);
263757
- const entriesId = call2.leg === "entries" ? ctx.id : call2.legs?.entries;
263757
+ const entriesId = call3.leg === "entries" ? ctx.id : call3.legs?.entries;
263758
263758
  const money2 = hire ? [`every entry that passes all ${n} lines is paid ${amount3(m.entryEach, ctx.symbol)}, up to ${m.entryUpTo} ${m.entryUpTo === 1 ? "entry" : "entries"}; there is no pick`] : [
263759
263759
  `the pick gets ${amount3(m.prize, ctx.symbol)}`,
263760
263760
  m.runnersN > 0 ? `${m.runnersN} runner${m.runnersN === 1 ? "-up gets" : "s-up get"} ${amount3(m.runnersEach, ctx.symbol)} each` : "",
263761
263761
  `every entry that passes all ${n} lines is paid ${amount3(m.entryEach, ctx.symbol)}, up to ${m.entryUpTo}`
263762
263762
  ].filter(Boolean);
263763
263763
  const who = terms.access === "invite" ? "By invitation: only the people the poster put on the list can enter. If you were sent a link, pass it as submit_work's `invite`; if your address or page was named, nothing more is needed." : terms.access === "apply" ? "By application: apply_to_call first, with a short note; when the poster says yes, submit_work is admitted." : "Open to anyone.";
263764
- const review = call2.kind === "review";
263765
- const shared = call2.share ? sharedPay(m.entryEach, call2.share) : null;
263766
- const shareLine2 = shared && call2.share ? `each ${review ? "pro" : hire ? "hired person" : "entry paid"} receives ${amount3(shared.receives, ctx.symbol)} (the leg is ${amount3(shared.leg, ctx.symbol)}; the network keeps ${amount3(shared.keeps, ctx.symbol)}: ${shareWords(call2.share, "as posted")})${hire ? "" : "; the pick's and the runners-up's legs carry the same share on top of theirs"}` : "";
263767
- const proMoney = review && call2.share && hire ? `Money: ${feeLine({ split: call2.share, net: m.entryEach, symbol: ctx.symbol, network: ctx.network ?? "mainnet" })} Up to ${m.entryUpTo} ${m.entryUpTo === 1 ? "report is" : "reports are"} paid, each one that passes all ${n} lines; there is no pick. Held on the ask's own account before anyone enters.` : null;
263764
+ const review = call3.kind === "review";
263765
+ const shared = call3.share ? sharedPay(m.entryEach, call3.share) : null;
263766
+ const shareLine2 = shared && call3.share ? `each ${review ? "pro" : hire ? "hired person" : "entry paid"} receives ${amount3(shared.receives, ctx.symbol)} (the leg is ${amount3(shared.leg, ctx.symbol)}; the network keeps ${amount3(shared.keeps, ctx.symbol)}: ${shareWords(call3.share, "as posted")})${hire ? "" : "; the pick's and the runners-up's legs carry the same share on top of theirs"}` : "";
263767
+ const proMoney = review && call3.share && hire ? `Money: ${feeLine({ split: call3.share, net: m.entryEach, symbol: ctx.symbol, network: ctx.network ?? "mainnet" })} Up to ${m.entryUpTo} ${m.entryUpTo === 1 ? "report is" : "reports are"} paid, each one that passes all ${n} lines; there is no pick. Held on the ask's own account before anyone enters.` : null;
263768
263768
  const out = [
263769
- `${review ? "Pro ask" : hire ? "Hiring call" : "Open call"} "${call2.slug}" \xB7 posted by ${call2.poster} \xB7 ${stageWords(call2, ctx.now)}`,
263769
+ `${review ? "Pro ask" : hire ? "Hiring call" : "Open call"} "${call3.slug}" \xB7 posted by ${call3.poster} \xB7 ${stageWords(call3, ctx.now)}`,
263770
263770
  ...review && ctx.site ? [`Its page: ${ctx.site.replace(/\/+$/, "")}/pro/reviews/${ctx.id}`] : [],
263771
- call2.title,
263772
- call2.lede,
263773
- ...review && call2.subject ? [`Reviewing: ${call2.subject.name}${call2.subject.version ? ` ${call2.subject.version}` : ""}${call2.subject.where ? ` \xB7 ${call2.subject.where}` : ""}. Access details, if any, are in your invitation.`] : [],
263774
- ...review && call2.scenarios?.length ? ["Scenarios, each one a step in your report:", ...call2.scenarios.map((one, index) => ` S${index + 1}. ${one}`)] : [],
263771
+ call3.title,
263772
+ call3.lede,
263773
+ ...review && call3.subject ? [`Reviewing: ${call3.subject.name}${call3.subject.version ? ` ${call3.subject.version}` : ""}${call3.subject.where ? ` \xB7 ${call3.subject.where}` : ""}. Access details, if any, are in your invitation.`] : [],
263774
+ ...review && call3.scenarios?.length ? ["Scenarios, each one a step in your report:", ...call3.scenarios.map((one, index) => ` S${index + 1}. ${one}`)] : [],
263775
263775
  proMoney ?? `Money: ${[...money2, shareLine2].filter(Boolean).join("; ")}. Locked in ${hire ? "the ask's own account" : "each leg's own account"} before anyone enters.`,
263776
263776
  who,
263777
- call2.leg === "entries" ? review ? `Enter: a review report with screenshots, as submit_work's report and files, collectionId "${ctx.id}"${terms.approver ? `; the AI checks it against the requirements, then ${terms.approver} gives final approval to release payment` : "; the AI checks it against the requirements and a passing report is paid"}. One report per account.` : `Enter: one page of text, in your own words: submit_work collectionId "${ctx.id}". One entry per account.` : `The pick's leg: only the entry the poster picked may claim here, with one line naming it. ${entriesId ? `The entries are ask ${entriesId}.` : "The entries are the call's own ask."}`,
263777
+ call3.leg === "entries" ? review ? `Enter: a review report with screenshots, as submit_work's report and files, collectionId "${ctx.id}"${terms.approver ? `; the AI checks it against the requirements, then ${terms.approver} gives final approval to release payment` : "; the AI checks it against the requirements and a passing report is paid"}. One report per account.` : `Enter: one page of text, in your own words: submit_work collectionId "${ctx.id}". One entry per account.` : `The pick's leg: only the entry the poster picked may claim here, with one line naming it. ${entriesId ? `The entries are ask ${entriesId}.` : "The entries are the call's own ask."}`,
263778
263778
  hire ? `Judged: ${n} requirements that every entry must meet. Pass all ${n} and the entry is paid on approval; nobody is picked.` : `Judged: ${n} requirements that every entry must meet. Pass all ${n} and the entry is paid; how clearly it meets each requirement ranks the entries for the pick.`,
263779
263779
  "",
263780
- ...call2.blocks.map(blockText).flatMap((text4) => [text4, ""]),
263780
+ ...call3.blocks.map(blockText).flatMap((text4) => [text4, ""]),
263781
263781
  `The ${n} requirements:`,
263782
263782
  ...lines2.length ? lines2.map((text4, index) => `${index + 1}. ${text4}`) : ["(on the entries ask)"]
263783
263783
  ];
@@ -264362,10 +264362,10 @@ function callServerEnv(site, env) {
264362
264362
  OPENHANDS_MAX_PER_DAY_USD: env.OPENHANDS_MAX_PER_DAY_USD?.trim() || "100"
264363
264363
  };
264364
264364
  }
264365
- function confirms(said3, totalBase, symbol2) {
264366
- const named = /USDC|PAY|IXO/i.exec(said3)?.[0]?.toUpperCase();
264365
+ function confirms(said4, totalBase, symbol2) {
264366
+ const named = /USDC|PAY|IXO/i.exec(said4)?.[0]?.toUpperCase();
264367
264367
  if (symbol2 && named && named !== symbol2.toUpperCase()) return false;
264368
- const figure = said3.replace(/[$,\s]|USDC|PAY|IXO/gi, "");
264368
+ const figure = said4.replace(/[$,\s]|USDC|PAY|IXO/gi, "");
264369
264369
  return /^\d+(\.\d+)?$/.test(figure) && Math.round(Number(figure) * MICRO5) === totalBase;
264370
264370
  }
264371
264371
  var MICRO5, callsDir, fileOf, askInvitesFile, freshDraft, L3, ENTRIES_MAX, INVITES_MAX, INVITE_NOTE_MAX, ADDRESS2, HANDLE_ITEM, isInviteItem, PRO_ASK_INVITE_ONLY, manyLines, overCap, callTwoCoins, SETTLE_MS, chainCheck, InFlightError, PostRefused, feeUnpaid, said2, indexLookupWith, indexLookup, posting, isAskPending, isTxFailed, tagOf, TESTNET_CALL_DEFAULTS, payWords;
@@ -264545,6 +264545,14 @@ function readLinkedinMessage(message, expected, now3 = Date.now(), maxAgeMs = ST
264545
264545
  if (parts.length !== 5 || parts[0] !== "linkedin" || parts[1] !== expected.act || parts[2] !== expected.signer || parts[4] !== expected.digest) return "mismatch";
264546
264546
  return fresh(parts[3], now3, maxAgeMs);
264547
264547
  }
264548
+ async function cashoutWords(act, signer2, body, now3 = Date.now()) {
264549
+ return cashoutMessage(act, signer2, now3, await digestOf(linkedinBody(body)));
264550
+ }
264551
+ function readCashoutMessage(message, expected, now3 = Date.now(), maxAgeMs = STAFF_PROOF_MAX_AGE_MS) {
264552
+ const parts = message.split(":");
264553
+ if (parts.length !== 5 || parts[0] !== "cashout" || parts[1] !== expected.act || parts[2] !== expected.signer || parts[4] !== expected.digest) return "mismatch";
264554
+ return fresh(parts[3], now3, maxAgeMs);
264555
+ }
264548
264556
  async function roomWords(act, signer2, body, now3 = Date.now()) {
264549
264557
  return roomMessage(act, signer2, now3, await digestOf(roomBody(body)));
264550
264558
  }
@@ -264641,8 +264649,8 @@ function readHandsRemoveMessage(message, expected) {
264641
264649
  if (parts.length !== 3 || parts[0] !== "hands-remove" || parts[1] !== expected.address) return "mismatch";
264642
264650
  return Number(parts[2]) === expected.prefAt ? "ok" : "mismatch";
264643
264651
  }
264644
- function fresh(said3, now3, maxAgeMs) {
264645
- const at = Number(said3);
264652
+ function fresh(said4, now3, maxAgeMs) {
264653
+ const at = Number(said4);
264646
264654
  if (!Number.isFinite(at)) return "mismatch";
264647
264655
  return Math.abs(now3 - at) <= maxAgeMs ? "ok" : "stale";
264648
264656
  }
@@ -264662,7 +264670,7 @@ async function digestOf(value) {
264662
264670
  const bytes3 = new Uint8Array(await crypto.subtle.digest("SHA-256", new TextEncoder().encode(canonicalJson2(value))));
264663
264671
  return Array.from(bytes3, (byte) => byte.toString(16).padStart(2, "0")).join("");
264664
264672
  }
264665
- var PROOF_MAX_AGE_MS2, INVITE_OPS, INVITE_WRITES, inviteOpBody, inviteOpMessage, applyMessage, invitedMessage, answersMessage, READ_PROOF_MAX_AGE_MS, FUTURE_SKEW_MS, LEGACY_WORDS_UNTIL, callsMessage, noticesMessage, tellMessage, NOTICE_KINDS, handsMessage, vettingMineMessage, vettingQueueMessage, STAFF_PROOF_MAX_AGE_MS, vetRequestBody, vetRequestMessage, vetBody, vetMessage, handsRemoveMessage, handsMineMessage, LINKEDIN_ACTS, linkedinBody, linkedinMessage, ROOM_ACTS, roomBody, roomMessage, ROOM_SEND_MAX_AGE_MS, SPONSOR_ACTS, sponsorBody, sponsorMessage, HANDS_SHARE_ACTS, handsShareMessage;
264673
+ var PROOF_MAX_AGE_MS2, INVITE_OPS, INVITE_WRITES, inviteOpBody, inviteOpMessage, applyMessage, invitedMessage, answersMessage, READ_PROOF_MAX_AGE_MS, FUTURE_SKEW_MS, LEGACY_WORDS_UNTIL, callsMessage, noticesMessage, tellMessage, NOTICE_KINDS, handsMessage, vettingMineMessage, vettingQueueMessage, STAFF_PROOF_MAX_AGE_MS, vetRequestBody, vetRequestMessage, vetBody, vetMessage, handsRemoveMessage, handsMineMessage, LINKEDIN_ACTS, linkedinBody, linkedinMessage, CASHOUT_ACTS, cashoutMessage, ROOM_ACTS, roomBody, roomMessage, ROOM_SEND_MAX_AGE_MS, SPONSOR_ACTS, sponsorBody, sponsorMessage, HANDS_SHARE_ACTS, handsShareMessage;
264666
264674
  var init_inviteMessages = __esm({
264667
264675
  "../../packages/openhands-sdk/src/chain/inviteMessages.ts"() {
264668
264676
  "use strict";
@@ -264697,6 +264705,8 @@ var init_inviteMessages = __esm({
264697
264705
  return rest;
264698
264706
  };
264699
264707
  linkedinMessage = (act, signer2, now3 = Date.now(), digest2 = "") => `linkedin:${act}:${signer2}:${now3}:${digest2}`;
264708
+ CASHOUT_ACTS = ["quote", "draft", "status"];
264709
+ cashoutMessage = (act, signer2, now3 = Date.now(), digest2 = "") => `cashout:${act}:${signer2}:${now3}:${digest2}`;
264700
264710
  ROOM_ACTS = ["mine", "read", "send", "bring", "export"];
264701
264711
  roomBody = (body) => {
264702
264712
  const { address: _address, proof: _proof, ...rest } = body;
@@ -264743,6 +264753,7 @@ var init_inviteAnswer = __esm({
264743
264753
  var inviteProof_exports = {};
264744
264754
  __export(inviteProof_exports, {
264745
264755
  AVAILABILITY: () => AVAILABILITY,
264756
+ CASHOUT_ACTS: () => CASHOUT_ACTS,
264746
264757
  DOES: () => DOES,
264747
264758
  FUTURE_SKEW_MS: () => FUTURE_SKEW_MS,
264748
264759
  HANDLE: () => HANDLE,
@@ -264770,6 +264781,8 @@ __export(inviteProof_exports, {
264770
264781
  applyMessage: () => applyMessage,
264771
264782
  callsMessage: () => callsMessage,
264772
264783
  canonicalJson: () => canonicalJson2,
264784
+ cashoutMessage: () => cashoutMessage,
264785
+ cashoutWords: () => cashoutWords,
264773
264786
  digestOf: () => digestOf,
264774
264787
  fresh: () => fresh,
264775
264788
  handsMessage: () => handsMessage,
@@ -264789,6 +264802,7 @@ __export(inviteProof_exports, {
264789
264802
  readAnswersMessage: () => readAnswersMessage,
264790
264803
  readApplyMessage: () => readApplyMessage,
264791
264804
  readCallsMessage: () => readCallsMessage,
264805
+ readCashoutMessage: () => readCashoutMessage,
264792
264806
  readHandBlock: () => readHandBlock,
264793
264807
  readHandProfile: () => readHandProfile,
264794
264808
  readHandsMessage: () => readHandsMessage,
@@ -266191,13 +266205,13 @@ function shortTitle(task, max = TITLE_MAX) {
266191
266205
  return `${(space > max / 2 ? cut.slice(0, space) : cut).replace(/[\s,;:.-]+$/, "")}\u2026`;
266192
266206
  }
266193
266207
  function askHead(name8, task) {
266194
- const said3 = placeJoined((task ?? "").trim());
266208
+ const said4 = placeJoined((task ?? "").trim());
266195
266209
  const named = (name8 ?? "").trim();
266196
- if (!said3 || said3 === named) return { title: null, task: null };
266210
+ if (!said4 || said4 === named) return { title: null, task: null };
266197
266211
  const stem = named.replace(/…$/, "").trimEnd();
266198
- const cut = (named.endsWith("\u2026") || named.length >= 140) && said3.startsWith(stem);
266199
- const heading = cut ? shortTitle(said3) : named;
266200
- const rest = /[.?!]$/.test(heading) && said3.startsWith(heading) ? said3.slice(heading.length).trim() : said3;
266212
+ const cut = (named.endsWith("\u2026") || named.length >= 140) && said4.startsWith(stem);
266213
+ const heading = cut ? shortTitle(said4) : named;
266214
+ const rest = /[.?!]$/.test(heading) && said4.startsWith(heading) ? said4.slice(heading.length).trim() : said4;
266201
266215
  return { title: cut ? heading : null, task: rest || null };
266202
266216
  }
266203
266217
  var TITLE_MAX, placeJoined;
@@ -266432,10 +266446,10 @@ function clean5(raw) {
266432
266446
  return text4.length <= MAX_LENGTH ? text4 : `${text4.slice(0, MAX_LENGTH - 1).trimEnd()}\u2026`;
266433
266447
  }
266434
266448
  async function placeName(point, zoom, reach = {}) {
266435
- const call2 = reach.fetch ?? globalThis.fetch;
266449
+ const call3 = reach.fetch ?? globalThis.fetch;
266436
266450
  const url4 = `${ENDPOINT}?lat=${encodeURIComponent(point.lat)}&lon=${encodeURIComponent(point.lon)}&format=jsonv2&zoom=${encodeURIComponent(zoom)}`;
266437
266451
  try {
266438
- const response = await call2(url4, {
266452
+ const response = await call3(url4, {
266439
266453
  headers: { "user-agent": USER_AGENT, accept: "application/json" },
266440
266454
  signal: AbortSignal.timeout(TIMEOUT_MS6)
266441
266455
  });
@@ -266832,6 +266846,129 @@ var init_takeBack = __esm({
266832
266846
  }
266833
266847
  });
266834
266848
 
266849
+ // src/cashout.ts
266850
+ var cashout_exports = {};
266851
+ __export(cashout_exports, {
266852
+ cashOut: () => cashOut,
266853
+ cashOutStatus: () => cashOutStatus
266854
+ });
266855
+ async function call2(deps, path, body) {
266856
+ try {
266857
+ const response = await deps.fetch(`${deps.site.replace(/\/+$/, "")}${path}`, {
266858
+ method: body === void 0 ? "GET" : "POST",
266859
+ headers: { accept: "application/json", ...body === void 0 ? {} : { "content-type": "application/json" } },
266860
+ ...body === void 0 ? {} : { body: JSON.stringify(body) },
266861
+ signal: AbortSignal.timeout(2e4)
266862
+ });
266863
+ return { status: response.status, body: await response.json().catch(() => ({})) ?? {} };
266864
+ } catch {
266865
+ return { status: 0, body: { error: "asks.world did not answer. Try again shortly." } };
266866
+ }
266867
+ }
266868
+ async function signedCall(deps, act, fields) {
266869
+ const full = { ...fields, ...deps.signer.principal ? { onBehalfOf: deps.signer.principal } : {} };
266870
+ const message = await cashoutWords(act, deps.signer.address, full);
266871
+ return call2(deps, `/api/cashout/${act}`, { address: deps.signer.address, ...full, proof: { kind: "adr36", message, ...await signWords(deps.signer.mnemonic, message) } });
266872
+ }
266873
+ async function cashOut(deps, input) {
266874
+ const person = deps.signer.principal ?? deps.signer.address;
266875
+ const [ready, payBase] = await Promise.all([signedCall(deps, "status", {}), deps.payBase(person)]);
266876
+ if (ready.status !== 200) return said3(ready);
266877
+ const kyc = ready.body.kyc;
266878
+ if (!ready.body.linkedin) return "Cash-out needs your LinkedIn connected first. Next: connect_linkedin (about a minute), then cash_out again.";
266879
+ const available = payBase / 1e6;
266880
+ if (available <= 0) return "You have no PAY to cash out yet.";
266881
+ const kycLine = kyc?.status === "verified" ? "" : kyc?.status === "expired" ? `Your identity check has expired. Renew it first: ${deps.site.replace(/\/+$/, "")}/me/identity` : `Cash-out needs an identity check. If you haven't done it yet, do it first: ${deps.site.replace(/\/+$/, "")}/me/identity`;
266882
+ if (kyc?.status === "expired") return kycLine;
266883
+ const country = input.country?.trim().toUpperCase();
266884
+ if (!country || !/^[A-Z]{2}$/.test(country)) return [`You have $${available.toFixed(2)} in PAY to cash out.`, kycLine, 'Which country are you in? (Ask the person; then call cash_out with country, like "NG" or "DE".)'].filter(Boolean).join("\n");
266885
+ const info = await call2(deps, `/api/cashout/info?country=${country}`);
266886
+ if (info.status !== 200) return said3(info);
266887
+ const methods = info.body.methods ?? [];
266888
+ const fee = info.body.fee;
266889
+ if (!methods.length) return `There's no way to cash out in ${country} yet.`;
266890
+ const chosen2 = methods.find((one) => one.method === input.method);
266891
+ if (!chosen2)
266892
+ return [
266893
+ `You have $${available.toFixed(2)} in PAY. Ways to get paid in ${country}:`,
266894
+ ...methods.map((one) => `- ${WAYS[one.method] ?? one.method} (method "${one.method}"): $${one.minUsd} to $${one.maxUsd}`),
266895
+ `Fee: ${fee?.bps ? `${fee.bps / 100}%` : "none"}${fee?.minUsd && Number(fee.minUsd) > 0 ? `, at least $${fee.minUsd}` : ""}.`,
266896
+ kycLine,
266897
+ "(Ask which way and how much; then call cash_out with method and amount_usd.)"
266898
+ ].filter(Boolean).join("\n");
266899
+ const amount3 = input.amount_usd?.trim().replace(/^\$/, "");
266900
+ if (!amount3 || !/^\d+(\.\d{1,2})?$/.test(amount3)) return `How much do you want to cash out? You have $${available.toFixed(2)}; this way takes $${chosen2.minUsd} to $${chosen2.maxUsd}. (Then call cash_out with amount_usd, like "25".)`;
266901
+ if (Number(amount3) > available) return `You have $${available.toFixed(2)} in PAY, less than $${amount3}. Pick a smaller amount.`;
266902
+ if (Number(amount3) < Number(chosen2.minUsd)) return `The smallest you can cash out this way is $${chosen2.minUsd}.`;
266903
+ if (Number(amount3) > Number(chosen2.maxUsd)) return `The largest you can cash out this way is $${chosen2.maxUsd}.`;
266904
+ const to = input.to?.trim();
266905
+ if (chosen2.fields.includes("address") && !(to && BASE_ADDRESS.test(to))) return "Which Base address should receive the USDC? (An 0x\u2026 address on Base; then call cash_out with to.)";
266906
+ const quote = await signedCall(deps, "quote", { method: chosen2.method, country, amountUsd: amount3 });
266907
+ if (quote.status !== 201) return said3(quote);
266908
+ const q = quote.body;
266909
+ const receive = `You'll receive $${q.receive?.amount ?? q.amountUsd}${q.receive?.currency && q.receive.currency !== "USD" ? ` in ${q.receive.currency}` : ""} (fee $${q.feeUsd ?? "0.00"}).`;
266910
+ const named = chosen2.fields.includes("accountHolder") ? NAME_LINE : "";
266911
+ if (!input.confirm) return [`Cash out $${q.amountUsd} by ${WAYS[chosen2.method] ?? chosen2.method}${to ? ` to ${to}` : ""}.`, receive, named, kycLine, "Nothing is sent yet. To go ahead, call cash_out again with the same answers and confirm: true."].filter(Boolean).join("\n");
266912
+ const link5 = new URL(`${deps.site.replace(/\/+$/, "")}/me/cash-out`);
266913
+ link5.searchParams.set("quote", String(q.quoteId));
266914
+ link5.searchParams.set("method", chosen2.method);
266915
+ link5.searchParams.set("amount", amount3);
266916
+ link5.searchParams.set("country", country);
266917
+ if (to) link5.searchParams.set("to", to);
266918
+ return [receive, named, `Open this and confirm with one tap: ${link5.toString()}`, "Your money leaves only when you confirm there. I signed nothing. (Later, cash_out_status with the id that page shows says where it stands.)"].filter(Boolean).join("\n");
266919
+ }
266920
+ async function cashOutStatus(deps, id) {
266921
+ const answer = await signedCall(deps, "status", { id });
266922
+ if (answer.status === 404) return `No cash-out "${id}" for you on this network.`;
266923
+ if (answer.status !== 200) return said3(answer);
266924
+ const v = answer.body;
266925
+ const lapsed = id.startsWith("cd_") && (v.state === "open" || v.state === "signing") && Date.parse(v.expiresAt ?? "") <= Date.now();
266926
+ const money2 = v.receive?.amount ? `$${v.receive.amount}${v.receive.currency && v.receive.currency !== "USD" ? ` ${v.receive.currency}` : ""}` : v.quote?.amountUsd ? `$${v.quote.amountUsd}` : "your cash-out";
266927
+ switch (lapsed ? "expired" : v.state) {
266928
+ case "open":
266929
+ case "signing":
266930
+ return `Not confirmed yet: open the confirm link and tap confirm (${money2}).`;
266931
+ case "sent":
266932
+ return "Confirmed. The payout is starting.";
266933
+ case "expired":
266934
+ case "failed":
266935
+ return "This cash-out expired before it was confirmed. Nothing was taken. Start a new one with cash_out.";
266936
+ case "converting":
266937
+ case "taking":
266938
+ case "paying":
266939
+ return `On its way: ${money2}.`;
266940
+ case "paid":
266941
+ return `Paid: ${money2}.`;
266942
+ case "needs_attention":
266943
+ return `Your payout didn't go through: ${v.reason ?? "the payout failed"}. Check your details or pick another way: ${v.fixUrl ?? ""}
266944
+ ${NAME_LINE}`;
266945
+ case "not_converted":
266946
+ case "cancelled":
266947
+ return "This cash-out didn't go through, and nothing was taken.";
266948
+ case "refunded":
266949
+ return "Your PAY was sent back to you.";
266950
+ default:
266951
+ return `State: ${v.state ?? "unknown"}.`;
266952
+ }
266953
+ }
266954
+ var WAYS, BASE_ADDRESS, NAME_LINE, said3;
266955
+ var init_cashout = __esm({
266956
+ "src/cashout.ts"() {
266957
+ "use strict";
266958
+ init_accountProof();
266959
+ init_inviteProof();
266960
+ WAYS = {
266961
+ usdc_base: "USDC on Base (any country)",
266962
+ stripe_bank: "Bank account, through Stripe",
266963
+ yellowcard_bank: "Bank account, through Yellow Card",
266964
+ yellowcard_momo: "Mobile money, through Yellow Card"
266965
+ };
266966
+ BASE_ADDRESS = /^0x[0-9a-fA-F]{40}$/;
266967
+ NAME_LINE = "The payout account name must match the name on your ID.";
266968
+ said3 = (answer) => answer.status === 503 && answer.body.code === "not-open" ? "Cash-out isn't open on this network yet." : String(answer.body.error ?? `Cash-out refused this (${answer.status}).`);
266969
+ }
266970
+ });
266971
+
266835
266972
  // src/pairing.ts
266836
266973
  var pairing_exports = {};
266837
266974
  __export(pairing_exports, {
@@ -292144,7 +292281,7 @@ import { randomBytes as randomBytes7 } from "node:crypto";
292144
292281
  // package.json
292145
292282
  var package_default = {
292146
292283
  name: "@ixo/asks-mcp",
292147
- version: "2.0.0-dev.1",
292284
+ version: "2.0.0-dev.2",
292148
292285
  description: "The Openhands Network MCP server: read the board, answer asks, post work and get paid on the ixo chain, with a key of its own on your machine.",
292149
292286
  license: "Apache-2.0",
292150
292287
  repository: {
@@ -292366,6 +292503,20 @@ var TOOLS = {
292366
292503
  /* A second sweep finds nothing to send: the first one emptied the key. */
292367
292504
  annotations: { ...acts, idempotentHint: true }
292368
292505
  },
292506
+ cash_out: {
292507
+ title: "Cash out your PAY",
292508
+ description: `Turn the PAY the person earned into money: USDC on Base, or a bank account where offered. One step per call: it reads their PAY, their LinkedIn and identity check, then asks the country, the way to get paid, the amount and (for USDC) the Base address, and shows the quote in plain words ("You'll receive $X (fee $0)"). With confirm: true it gives ONE link: the person opens it and confirms with one tap; that page checks their identity and they sign there. Limits and fees come from IXO's cash-out service, never from here. No LinkedIn: say connect_linkedin first. Signs no money and holds no key of theirs.`,
292509
+ spends: false,
292510
+ hosted: false,
292511
+ annotations: acts
292512
+ },
292513
+ cash_out_status: {
292514
+ title: "Where a cash-out stands",
292515
+ description: "Given a cash-out's id (cd_\u2026 or wd_\u2026, from the confirm page), says where it stands in plain words: waiting for the tap, on its way, paid, or that it didn't go through and where to fix it. Spends nothing.",
292516
+ spends: false,
292517
+ hosted: false,
292518
+ annotations: reads
292519
+ },
292369
292520
  my_status: {
292370
292521
  title: "This participant's standing",
292371
292522
  description: "Address, the account area as seven lines (Your page, Work waiting, Messages unread, Inbox, Money, Agents, Settings, as asks.world/me draws them), what is available and what is on your asks, answers sent, and rewards still owed.",
@@ -292949,17 +293100,17 @@ function measureOf(reason) {
292949
293100
  function reasonText(reason) {
292950
293101
  const rest = reason.detail.startsWith(`${reason.label}: `) ? reason.detail.slice(reason.label.length + 2) : reason.detail;
292951
293102
  const measure = measureOf(reason);
292952
- const said3 = rest === reason.label || rest === RESULT_WORD[reason.result] || rest === "Did not pass" ? "" : rest;
292953
- const sayMeasured = reason.value !== void 0 && said3.startsWith(num2(reason.value, reason.unit));
292954
- return [sayMeasured ? "" : measure, said3].filter(Boolean).join(". ");
293103
+ const said4 = rest === reason.label || rest === RESULT_WORD[reason.result] || rest === "Did not pass" ? "" : rest;
293104
+ const sayMeasured = reason.value !== void 0 && said4.startsWith(num2(reason.value, reason.unit));
293105
+ return [sayMeasured ? "" : measure, said4].filter(Boolean).join(". ");
292955
293106
  }
292956
293107
  var evidenceLine = (why) => why.evidenceGrade ? `Time/place: ${why.evidenceGrade}` : null;
292957
293108
  function whyLines(why, indent3 = "") {
292958
293109
  if (!why) return [`${indent3}${WHY_UNREADABLE}.`];
292959
293110
  const lines2 = [`${indent3}${why.summary}`];
292960
293111
  for (const reason of why.reasons) {
292961
- const said3 = reasonText(reason);
292962
- lines2.push(`${indent3} ${RESULT_WORD[reason.result]}: ${reason.label}${said3 ? ` \u2014 ${said3}` : ""}`);
293112
+ const said4 = reasonText(reason);
293113
+ lines2.push(`${indent3} ${RESULT_WORD[reason.result]}: ${reason.label}${said4 ? ` \u2014 ${said4}` : ""}`);
292963
293114
  }
292964
293115
  const evidence = evidenceLine(why);
292965
293116
  if (evidence) lines2.push(`${indent3}${evidence}`);
@@ -294368,10 +294519,10 @@ To go ahead, call again with confirm: "${token}".`;
294368
294519
  return chargeDay(args.bucket, args.total);
294369
294520
  }
294370
294521
  const withNotes = (guard, notes) => {
294371
- const said3 = notes.filter((note) => Boolean(note));
294372
- return guard.startsWith("Refused") || said3.length === 0 ? guard : `${guard}
294522
+ const said4 = notes.filter((note) => Boolean(note));
294523
+ return guard.startsWith("Refused") || said4.length === 0 ? guard : `${guard}
294373
294524
 
294374
- ${said3.join("\n")}`;
294525
+ ${said4.join("\n")}`;
294375
294526
  };
294376
294527
  const principal2 = async () => actingFor2(await address2());
294377
294528
  const unchosen = async () => {
@@ -294540,18 +294691,18 @@ Each is its own ask and pays on its own. Read one with read_ask before deciding.
294540
294691
  calls.set(tag, { slug, entries: entries2, shared });
294541
294692
  })
294542
294693
  );
294543
- const callLine = (row, call2) => {
294694
+ const callLine = (row, call3) => {
294544
294695
  const summary = row.campaignSummary;
294545
- const review = isReviewTitle(call2.entries?.title);
294546
- const title = call2.entries?.title.replace(/^(Open call|Expert review): /, "") ?? null;
294696
+ const review = isReviewTitle(call3.entries?.title);
294697
+ const title = call3.entries?.title.replace(/^(Open call|Expert review): /, "") ?? null;
294547
294698
  if (title) taint2(title);
294548
294699
  const facts = row.callSummary;
294549
- const shares = call2.shared;
294550
- const entryPays = shares && facts?.entryEach !== void 0 && call2.entries?.pays ? `${faceOf2({ value: facts.entryEach, symbol: call2.entries.pays.symbol }, SANDBOX)?.text} (the network's share is on top of it)` : call2.entries?.pays ? `${faceOf2(call2.entries.pays, SANDBOX)?.text}${shares ? ", less the network's share" : ""}` : void 0;
294700
+ const shares = call3.shared;
294701
+ const entryPays = shares && facts?.entryEach !== void 0 && call3.entries?.pays ? `${faceOf2({ value: facts.entryEach, symbol: call3.entries.pays.symbol }, SANDBOX)?.text} (the network's share is on top of it)` : call3.entries?.pays ? `${faceOf2(call3.entries.pays, SANDBOX)?.text}${shares ? ", less the network's share" : ""}` : void 0;
294551
294702
  return [
294552
- `${review ? "Expert review" : "Open call"} "${call2.slug}" \xB7 ${summary.open} of ${summary.places} legs open${entryPays ? ` \xB7 every ${review ? "report" : "entry"} that meets the bar is paid ${entryPays}` : ""} \xB7 needs-a-human`,
294703
+ `${review ? "Expert review" : "Open call"} "${call3.slug}" \xB7 ${summary.open} of ${summary.places} legs open${entryPays ? ` \xB7 every ${review ? "report" : "entry"} that meets the bar is paid ${entryPays}` : ""} \xB7 needs-a-human`,
294553
294704
  title ? asData("ask-title", title) : "",
294554
- `${review ? "A specialist's report on the review's scenarios, assessed against its requirements. A report that meets them is paid, after the builder's final approval when they give one." : "A written entry assessed against five requirements. Entries that meet all five are paid. For competitions, the poster also chooses a prize winner."} ${call2.entries ? `Read it with read_ask "${call2.entries.id}"; the page is` : "Read its legs on the page:"} ${review ? `${EXPERT_SITE}/pro/reviews/${call2.entries?.id ?? call2.slug}` : `${SITE}/opencall/${call2.slug}`}`
294705
+ `${review ? "A specialist's report on the review's scenarios, assessed against its requirements. A report that meets them is paid, after the builder's final approval when they give one." : "A written entry assessed against five requirements. Entries that meet all five are paid. For competitions, the poster also chooses a prize winner."} ${call3.entries ? `Read it with read_ask "${call3.entries.id}"; the page is` : "Read its legs on the page:"} ${review ? `${EXPERT_SITE}/pro/reviews/${call3.entries?.id ?? call3.slug}` : `${SITE}/opencall/${call3.slug}`}`
294555
294706
  ].filter(Boolean).join("\n");
294556
294707
  };
294557
294708
  const lines2 = board.rows.filter(within2).map((row) => {
@@ -294569,8 +294720,8 @@ Each is its own ask and pays on its own. Read one with read_ask before deciding.
294569
294720
  }
294570
294721
  if ((row.card === "campaign" || row.card === "call") && row.campaignSummary) {
294571
294722
  const summary = row.campaignSummary;
294572
- const call2 = calls.get(summary.tag);
294573
- if (call2) return callLine(row, call2);
294723
+ const call3 = calls.get(summary.tag);
294724
+ if (call3) return callLine(row, call3);
294574
294725
  const low = summary.low ? faceOf2(summary.low, SANDBOX)?.text : void 0;
294575
294726
  const high = summary.high ? faceOf2(summary.high, SANDBOX)?.text : void 0;
294576
294727
  const range = summary.pool || !low ? "paid from pools" : high && high !== low ? `${low} to ${high} a place` : `${low} a place`;
@@ -294821,13 +294972,13 @@ You cannot complete it, and trying would spend the gate's network fee to be reje
294821
294972
  });
294822
294973
  if (!granted.ok) {
294823
294974
  const body = await granted.text();
294824
- let said3 = body.slice(0, 200);
294975
+ let said4 = body.slice(0, 200);
294825
294976
  try {
294826
294977
  const parsed = JSON.parse(body);
294827
- if (typeof parsed.error === "string" && parsed.error) said3 = parsed.error.replace(/\.?$/, ".");
294978
+ if (typeof parsed.error === "string" && parsed.error) said4 = parsed.error.replace(/\.?$/, ".");
294828
294979
  } catch {
294829
294980
  }
294830
- return `The gate refused: ${said3}`;
294981
+ return `The gate refused: ${said4}`;
294831
294982
  }
294832
294983
  return null;
294833
294984
  };
@@ -294872,9 +295023,9 @@ You cannot complete it, and trying would spend the gate's network fee to be reje
294872
295023
  ...lane ? { private: true, fit: lane.fit, upload: lane.store.upload, fetchBack: lane.store.fetchBack, publish: lane.store.publish } : {}
294873
295024
  };
294874
295025
  const who = { submitter, ...acting ? { delegate: actor.address } : {}, ...alias ? { alias } : {} };
294875
- const said3 = report ? await sendReport({ collectionId, report, paths: files ?? [], requirement, ...uses_memory ? { usesMemory: true } : {}, ...who }, world) : await sendFields({ fields: expertAsk.check.fields, values: fields, collectionId, ...who }, world);
294876
- if (said3.startsWith("Answered")) nudge("scan", collectionId, expertAsk?.checker ?? (await Promise.resolve().then(() => (init_call2(), call_exports2))).nudgeAtFor(NETWORK2, judgeAddress));
294877
- return text4(withAccepted(expertAsk && said3.startsWith("Answered") ? said3.replace(/^(Answered #\d+ as \S+)\./, `$1, for ${expertAsk.checker.name} to check.`) : said3));
295026
+ const said4 = report ? await sendReport({ collectionId, report, paths: files ?? [], requirement, ...uses_memory ? { usesMemory: true } : {}, ...who }, world) : await sendFields({ fields: expertAsk.check.fields, values: fields, collectionId, ...who }, world);
295027
+ if (said4.startsWith("Answered")) nudge("scan", collectionId, expertAsk?.checker ?? (await Promise.resolve().then(() => (init_call2(), call_exports2))).nudgeAtFor(NETWORK2, judgeAddress));
295028
+ return text4(withAccepted(expertAsk && said4.startsWith("Answered") ? said4.replace(/^(Answered #\d+ as \S+)\./, `$1, for ${expertAsk.checker.name} to check.`) : said4));
294878
295029
  }
294879
295030
  const refusedToPrepare = await prepare2();
294880
295031
  if (refusedToPrepare) return text4(withAccepted(refusedToPrepare));
@@ -295284,12 +295435,12 @@ ${SITE}/t/${earlier.id}`);
295284
295435
  const { netOf: netOf2 } = await Promise.resolve().then(() => (init_share(), share_exports));
295285
295436
  const { shareWords: shareWords2 } = await Promise.resolve().then(() => (init_callRead(), callRead_exports));
295286
295437
  const { denom, amount: amount3 } = leg.amount[0];
295287
- const said3 = (base6) => faceOf2(coinDisplay2([{ denom, amount: String(base6) }]), SANDBOX)?.text ?? "see the record";
295438
+ const said4 = (base6) => faceOf2(coinDisplay2([{ denom, amount: String(base6) }]), SANDBOX)?.text ?? "see the record";
295288
295439
  const split3 = posted ?? await callSplit();
295289
- if (!split3) return `${said3(Number(amount3))} less the network's share (the fee split could not be read just now)`;
295440
+ if (!split3) return `${said4(Number(amount3))} less the network's share (the fee split could not be read just now)`;
295290
295441
  const receives = netOf2(Number(amount3), split3);
295291
- if (bare) return said3(receives);
295292
- return `${said3(receives)} (the leg is ${said3(Number(amount3))}; the network keeps ${said3(Number(amount3) - receives)}: ${shareWords2(split3, posted ? "as posted" : "today")})`;
295442
+ if (bare) return said4(receives);
295443
+ return `${said4(receives)} (the leg is ${said4(Number(amount3))}; the network keeps ${said4(Number(amount3) - receives)}: ${shareWords2(split3, posted ? "as posted" : "today")})`;
295293
295444
  }
295294
295445
  const callLocks = (rewardBase, feeBase, symbol2 = ASK_SYMBOL) => `${pays(rewardBase, symbol2)}${feeBase > 0 ? ` and ${feeWords(feeBase)} for reviews` : ""}`;
295295
295446
  function escrowTotal(pay, spots, legBase, symbol2 = ASK_SYMBOL, sameCoin = true, feeSymbol = FEE_SYMBOL) {
@@ -295897,11 +296048,42 @@ Left on this key: ${skipped.length === 1 ? "a coin" : `${skipped.length} coins`}
295897
296048
  ],
295898
296049
  "earnings home"
295899
296050
  );
295900
- const said3 = coinsSaid(moving);
295901
- return text4(`Sent ${said3} to ${home}.
296051
+ const said4 = coinsSaid(moving);
296052
+ return text4(`Sent ${said4} to ${home}.
295902
296053
  tx ${result.transactionHash}${leftWords}`);
295903
296054
  }
295904
296055
  );
296056
+ const cashoutDeps = async () => {
296057
+ const acting = await principal2();
296058
+ const key = await loadKey2();
296059
+ return { site: SITE, signer: { address: await address2(), mnemonic: key.mnemonic, principal: acting?.principal ?? null }, fetch: fetch2 };
296060
+ };
296061
+ if (offered("cash_out")) server2.registerTool(
296062
+ "cash_out",
296063
+ {
296064
+ ...meta3("cash_out"),
296065
+ inputSchema: {
296066
+ country: external_exports.string().max(2).optional().describe("Where the person lives: two letters, like NG or DE."),
296067
+ method: external_exports.string().max(40).optional().describe("The way to get paid, as cash_out listed it (like usdc_base)."),
296068
+ amount_usd: external_exports.string().max(12).optional().describe('How much, in dollars, like "25" or "25.50".'),
296069
+ to: external_exports.string().max(64).optional().describe("USDC on Base only: the 0x\u2026 address that receives it."),
296070
+ confirm: external_exports.boolean().optional().describe("true, after the person said yes to the quote: gives the one link to confirm.")
296071
+ }
296072
+ },
296073
+ async (args) => {
296074
+ const { cashOut: cashOut2 } = await Promise.resolve().then(() => (init_cashout(), cashout_exports));
296075
+ const participant = await Promise.resolve().then(() => (init_src5(), src_exports4));
296076
+ return text4(await cashOut2({ ...await cashoutDeps(), payBase: async (who) => Number((await participant.balancesOf(who)).upay ?? 0) }, args));
296077
+ }
296078
+ );
296079
+ if (offered("cash_out_status")) server2.registerTool(
296080
+ "cash_out_status",
296081
+ { ...meta3("cash_out_status"), inputSchema: { id: external_exports.string().regex(/^(cd|wd)_[a-z2-7]{24}$/).describe("The cash-out's id, cd_\u2026 or wd_\u2026.") } },
296082
+ async ({ id }) => {
296083
+ const { cashOutStatus: cashOutStatus2 } = await Promise.resolve().then(() => (init_cashout(), cashout_exports));
296084
+ return text4(await cashOutStatus2(await cashoutDeps(), id));
296085
+ }
296086
+ );
295905
296087
  if (offered("set_payout_settings")) {
295906
296088
  server2.registerTool("set_payout_settings", { ...meta3("set_payout_settings"), inputSchema: settingsInput }, async (args) => {
295907
296089
  const { readOrgPayouts: readOrgPayouts2, facilitatorHealth: facilitatorHealth2, oracleResolves: oracleResolves2 } = await Promise.resolve().then(() => (init_orgPayouts(), orgPayouts_exports));
@@ -296259,7 +296441,7 @@ ${pending.link}`);
296259
296441
  const { needsChain: needsChain2, verdictFacts: verdictFacts2 } = await Promise.resolve().then(() => (init_verdictSource(), verdictSource_exports));
296260
296442
  const onChain = needsChain2(ours.evaluationByClaimId) ? await (await Promise.resolve().then(() => (init_claimVerdict(), claimVerdict_exports))).claimVerdictOnChain(ours.claimId) : null;
296261
296443
  const facts = verdictFacts2(ours.evaluationByClaimId, onChain);
296262
- const said3 = verdictSays2(facts.status);
296444
+ const said4 = verdictSays2(facts.status);
296263
296445
  const paid = faceOf2(coinDisplay2(facts.amount ?? void 0), SANDBOX);
296264
296446
  const arrived = paid && facts.amount?.length ? await sharedPays({ amount: facts.amount, is_oracle_payment: receipt.payments?.["approval"]?.is_oracle_payment }, null) : null;
296265
296447
  const proofRaw = facts.verificationProof;
@@ -296276,7 +296458,7 @@ ${pending.link}`);
296276
296458
  return checkFailed2(await readHeldClaim2(ask.oracle.url, key, ours.claimId));
296277
296459
  } : void 0;
296278
296460
  const why = await whyBlock(ours.claimId, proofRaw, ours.agentAddress === mine ? mint : void 0, failed ? { failed } : {});
296279
- return text4([`#${collectionId}: ${said3}.${paid ? ` Paid ${arrived ?? paid.text}.` : ""}`, `answer ${ours.claimId}`, `${SITE}/r/${collectionId}/trace/${encodeURIComponent(ours.claimId)}`, ...why, ...steps, ...tail].join("\n"));
296461
+ return text4([`#${collectionId}: ${said4}.${paid ? ` Paid ${arrived ?? paid.text}.` : ""}`, `answer ${ours.claimId}`, `${SITE}/r/${collectionId}/trace/${encodeURIComponent(ours.claimId)}`, ...why, ...steps, ...tail].join("\n"));
296280
296462
  }
296281
296463
  if (local) {
296282
296464
  server2.registerTool(
@@ -296468,27 +296650,27 @@ Mapping pays for the report. What happens to a mapped pin afterwards is a separa
296468
296650
  }
296469
296651
  },
296470
296652
  async ({ slug: named, clear, ...input }) => {
296471
- const call2 = await Promise.resolve().then(() => (init_call2(), call_exports2));
296653
+ const call3 = await Promise.resolve().then(() => (init_call2(), call_exports2));
296472
296654
  const { CALL_SLUG: CALL_SLUG2 } = await Promise.resolve().then(() => (init_terms(), terms_exports));
296473
- if (call2.typedText(input).some((one) => isTainted(one))) return text4(TAINT_REFUSAL);
296474
- const slug = named?.trim() || call2.nextSlug();
296655
+ if (call3.typedText(input).some((one) => isTainted(one))) return text4(TAINT_REFUSAL);
296656
+ const slug = named?.trim() || call3.nextSlug();
296475
296657
  if (!CALL_SLUG2.test(slug)) return text4(`"${slug}" cannot name a call: lowercase letters, digits and dashes, starting with a letter, 3 to 40 long. Nothing was saved.`);
296476
- const existing = call2.readDraft(slug);
296658
+ const existing = call3.readDraft(slug);
296477
296659
  const posted = existing ? Object.values(existing.posted).some(Boolean) || Boolean(existing.inFlight) : false;
296478
296660
  const changing = clear || Object.values(input).some((value) => value !== void 0);
296479
296661
  if (posted && changing) return text4(`Call "${slug}" is already posted: its terms were frozen with the money. Start a new call with another slug.`);
296480
- const start = clear || !existing ? call2.freshDraft(slug) : existing;
296481
- const merged = call2.mergeDraft(start, input);
296482
- const coin = call2.callCoin(merged.draft, NETWORK2, ASK_DENOM);
296662
+ const start = clear || !existing ? call3.freshDraft(slug) : existing;
296663
+ const merged = call3.mergeDraft(start, input);
296664
+ const coin = call3.callCoin(merged.draft, NETWORK2, ASK_DENOM);
296483
296665
  if (typeof coin !== "string") return text4(`Refused: ${coin.refused}. Nothing was saved.`);
296484
296666
  const refused2 = merged.refused;
296485
296667
  const draft = coin !== ASK_DENOM ? { ...merged.draft, coin } : merged.draft;
296486
- call2.writeDraft(draft);
296668
+ call3.writeDraft(draft);
296487
296669
  const coinSymbol = symbolOf(coin);
296488
296670
  const acting = await principal2();
296489
296671
  const held = await heldBy(acting, coin);
296490
296672
  const holds = held === null ? null : pays(held.reward, coinSymbol);
296491
- const missing2 = call2.missingOf(draft.fields, { symbol: coinSymbol, holds });
296673
+ const missing2 = call3.missingOf(draft.fields, { symbol: coinSymbol, holds });
296492
296674
  const out = [`Draft "${slug}" saved${posted ? " (posted)" : ""}.`];
296493
296675
  if (refused2.length) out.push("", "Not taken:", ...refused2.map((one) => ` - ${one}`));
296494
296676
  if (missing2.length) {
@@ -296497,7 +296679,7 @@ Mapping pays for the report. What happens to a mapped pin afterwards is a separa
296497
296679
  "Still needed, in this order. Ask the person, a group at a time, in their words; never write the brief for them:",
296498
296680
  ...missing2.flatMap((one, index) => [` ${index + 1}. ${one.field}: ${one.question}`, ` e.g. ${one.example}`])
296499
296681
  );
296500
- const optional5 = call2.optionalOf(draft.fields, originOf(NETWORK2));
296682
+ const optional5 = call3.optionalOf(draft.fields, originOf(NETWORK2));
296501
296683
  if (optional5.length) out.push("", "Optional, not given yet:", ...optional5.map((one) => ` - ${one}`));
296502
296684
  return text4(out.join("\n"));
296503
296685
  }
@@ -296507,20 +296689,20 @@ Mapping pays for the report. What happens to a mapped pin afterwards is a separa
296507
296689
  const checker = await callChecker2(draft.fields.kind === "review");
296508
296690
  if (checker.fee && checker.fee.denom !== coin) return text4(`Refused: ${checker.name} is paid in another coin than this call pays in, and a review pays in its verifier's coin. Start a new review.`);
296509
296691
  const perCheck = checker.fee ? false : await callPerCheck(checker.address);
296510
- const priced = call2.callShare(draft.fields, call2.callShares(draft.fields) ? await callSplit() : null);
296692
+ const priced = call3.callShare(draft.fields, call3.callShares(draft.fields) ? await callSplit() : null);
296511
296693
  if ("unread" in priced) {
296512
296694
  out.push("", "Not priced yet: this call is a hire by invitation or application, which carries the network's share, and the fee split could not be read just now. The draft is saved; call draft_call again in a minute.");
296513
296695
  return text4(out.join("\n"));
296514
296696
  }
296515
296697
  const proAsk = draft.fields.kind === "review";
296516
- const plan = call2.callPlan(draft, { poster: shortPoster, checkerLegBase: (terms) => checker.fee ? checker.fee.base : perCheck ? 0 : checkerLegBase2(FEE_DENOM, terms, CHECK_REWARD), oracle: checker.address || "the verifier", share: priced.share, feeInReward: Boolean(checker.fee) || coin === FEE_DENOM });
296698
+ const plan = call3.callPlan(draft, { poster: shortPoster, checkerLegBase: (terms) => checker.fee ? checker.fee.base : perCheck ? 0 : checkerLegBase2(FEE_DENOM, terms, CHECK_REWARD), oracle: checker.address || "the verifier", share: priced.share, feeInReward: Boolean(checker.fee) || coin === FEE_DENOM });
296517
296699
  const feeTotal = plan.legs.reduce((sum2, one) => sum2 + one.feeBase, 0);
296518
296700
  const finalOk = draft.fields.kind === "review" ? acting?.principal ?? null : null;
296519
- const preview = call2.legTerms(draft, "entries", { poster: shortPoster, dates: plan.dates, oracle: { kind: "oracle", address: checker.address || "the verifier" }, approver: finalOk, share: plan.share });
296520
- const twoCoins = acting && feeTotal > 0 ? `Can't post as ${acting.principal}: ${call2.callTwoCoins}.` : null;
296701
+ const preview = call3.legTerms(draft, "entries", { poster: shortPoster, dates: plan.dates, oracle: { kind: "oracle", address: checker.address || "the verifier" }, approver: finalOk, share: plan.share });
296702
+ const twoCoins = acting && feeTotal > 0 ? `Can't post as ${acting.principal}: ${call3.callTwoCoins}.` : null;
296521
296703
  const { capCoinRefusal: capCoinRefusal2, capIn: capIn2 } = await Promise.resolve().then(() => (init_hq(), hq_exports));
296522
296704
  const otherCoin = capCoinRefusal2(acting, coin, checker.fee ? `${SITE}/connect` : void 0);
296523
- const capped4 = call2.capWords(plan.legs, CAP_BASE, coinSymbol, NETWORK2);
296705
+ const capped4 = call3.capWords(plan.legs, CAP_BASE, coinSymbol, NETWORK2);
296524
296706
  const keyOnly = !acting && feeTotal > 0;
296525
296707
  const blocked = capped4.length > 0 || Boolean(otherCoin) || Boolean(twoCoins) && draft.fields.kind !== "review";
296526
296708
  const m = draft.fields.money;
@@ -296540,15 +296722,15 @@ Mapping pays for the report. What happens to a mapped pin afterwards is a separa
296540
296722
  !hire && m.prize < m.entryEach ? `The prize (${face(m.prize, coinSymbol)}) is less than one entry earns (${face(m.entryEach, coinSymbol)}).` : "",
296541
296723
  draft.fields.access === "invite" && !draft.fields.invite?.length ? proAsk ? "Nobody invited yet: find_pro suggests verified pros; add them with invite now, or invite_to_call after it posts." : 'By invitation, and nobody invited yet: add invite (addresses, @handles, "link") now, or invite_to_call after it posts.' : "",
296542
296724
  draft.fields.access === "apply" ? "By application: people apply on the call's page or with apply_to_call; you say yes with decide_application before they can enter." : "",
296543
- ...call2.balanceWarnings(held, { totalBase: plan.totalBase, feeTotal, symbol: coinSymbol, network: NETWORK2, feeWords }),
296725
+ ...call3.balanceWarnings(held, { totalBase: plan.totalBase, feeTotal, symbol: coinSymbol, network: NETWORK2, feeWords }),
296544
296726
  acting?.cap && !otherCoin && Number(capIn2(acting, coin)?.remainingBase ?? 0) < plan.totalBase ? `Their cap has ${pays(Number(capIn2(acting, coin)?.remainingBase ?? 0), coinSymbol)} left; the call locks ${pays(plan.totalBase, coinSymbol)}. They raise it at ${SITE}/connect.` : "",
296545
- keyOnly ? `Not connected, and a connection would not carry this call: ${call2.callTwoCoins}. With plain_key: true it posts as this key itself, ${await address2()}, from its own money.` : !acting ? `Not connected: post_call refuses until the person connects this key (connect_account gives them the link). For a rehearsal, plain_key: true posts as this key itself, ${await address2()}, from its own money.` : ""
296727
+ keyOnly ? `Not connected, and a connection would not carry this call: ${call3.callTwoCoins}. With plain_key: true it posts as this key itself, ${await address2()}, from its own money.` : !acting ? `Not connected: post_call refuses until the person connects this key (connect_account gives them the link). For a rehearsal, plain_key: true posts as this key itself, ${await address2()}, from its own money.` : ""
296546
296728
  ].filter(Boolean);
296547
296729
  out.push(
296548
296730
  "",
296549
296731
  blocked ? "Drafted, but post_call would refuse it as it stands (the warnings say why). This is the call as an entrant's AI will read it:" : "Ready. This is the call as an entrant's AI will read it:",
296550
296732
  "",
296551
- call2.callReadout(preview, { id: "(the entries ask, once posted)", symbol: coinSymbol, network: NETWORK2 }),
296733
+ call3.callReadout(preview, { id: "(the entries ask, once posted)", symbol: coinSymbol, network: NETWORK2 }),
296552
296734
  "",
296553
296735
  "What each leg locks:",
296554
296736
  ...legRows,
@@ -296585,17 +296767,17 @@ Mapping pays for the report. What happens to a mapped pin afterwards is a separa
296585
296767
  },
296586
296768
  async ({ slug, confirm, plain_key, pay_by }) => {
296587
296769
  const card = pay_by === "card";
296588
- const call2 = await Promise.resolve().then(() => (init_call2(), call_exports2));
296589
- const found = call2.readDraft(slug);
296770
+ const call3 = await Promise.resolve().then(() => (init_call2(), call_exports2));
296771
+ const found = call3.readDraft(slug);
296590
296772
  if (!found) return text4(`No draft called "${slug}". Start one with draft_call.`);
296591
296773
  const review = found.fields.kind === "review";
296592
296774
  const checker = await callChecker2(review);
296593
296775
  const linkOf = (posted2) => review ? `${EXPERT_SITE}/pro/reviews/${posted2.entries?.id ?? slug}` : `${SITE}/opencall/${slug}`;
296594
- const settled = found.inFlight ? await call2.settleInFlight(slug, call2.indexLookup) : null;
296776
+ const settled = found.inFlight ? await call3.settleInFlight(slug, call3.indexLookup) : null;
296595
296777
  if (settled?.state === "pending") return text4(settled.words);
296596
296778
  if (settled?.state === "landed") {
296597
296779
  nudge("hire", settled.id, checker.at);
296598
- const after2 = call2.nextLeg(settled.draft);
296780
+ const after2 = call3.nextLeg(settled.draft);
296599
296781
  return text4(
296600
296782
  [
296601
296783
  `The earlier post landed: ${LEG_WORDS[settled.leg]} is #${settled.id}. It is recorded, and nothing was posted twice.`,
@@ -296604,14 +296786,14 @@ Mapping pays for the report. What happens to a mapped pin afterwards is a separa
296604
296786
  );
296605
296787
  }
296606
296788
  const draft = settled?.draft ?? found;
296607
- const coin = call2.callCoin(draft, NETWORK2, ASK_DENOM);
296789
+ const coin = call3.callCoin(draft, NETWORK2, ASK_DENOM);
296608
296790
  if (typeof coin !== "string") return text4(`Refused: ${coin.refused}. Nothing was posted.`);
296609
296791
  const coinSymbol = symbolOf(coin);
296610
- const next = call2.nextLeg(draft);
296792
+ const next = call3.nextLeg(draft);
296611
296793
  const ids = ["prize", "runnersUp", "entries"].flatMap((leg2) => draft.posted[leg2] ? [`${LEG_WORDS[leg2]} #${draft.posted[leg2].id}`] : []);
296612
296794
  if (!next) return text4(`Everything is posted: ${ids.join(", ")}.
296613
296795
  The call: ${linkOf(draft.posted)}`);
296614
- if (!call2.isReady(draft.fields)) return text4(`"${slug}" is not ready: ${call2.missingOf(draft.fields, { symbol: coinSymbol, holds: null }).map((one) => one.field).join(", ")} still missing. Finish it with draft_call.`);
296796
+ if (!call3.isReady(draft.fields)) return text4(`"${slug}" is not ready: ${call3.missingOf(draft.fields, { symbol: coinSymbol, holds: null }).map((one) => one.field).join(", ")} still missing. Finish it with draft_call.`);
296615
296797
  const cannot = await unjudged();
296616
296798
  if (cannot) return text4(cannot);
296617
296799
  if (!checker.address) return text4("No verifier is configured on this deployment, so nothing could judge the entries. Refusing rather than posting a call nobody can settle.");
@@ -296626,15 +296808,15 @@ Then call post_call again. Nothing was posted.`);
296626
296808
  const poster = acting?.principal ?? await address2();
296627
296809
  if (checker.fee && checker.fee.denom !== coin) return text4(`Refused: ${checker.name} is paid in another coin than this call pays in, and a review pays in its verifier's coin. Start a new review. Nothing was posted.`);
296628
296810
  const perCheck = checker.fee ? false : await callPerCheck(checker.address);
296629
- const split3 = call2.callShares(draft.fields) ? await callSplit() : null;
296630
- const priced = call2.callShare(draft.fields, split3);
296631
- if ("unread" in priced) return text4(call2.SHARE_UNREAD);
296632
- const plan = call2.callPlan(draft, { poster: `${poster.slice(0, 10)}\u2026${poster.slice(-4)}`, checkerLegBase: (terms) => checker.fee ? checker.fee.base : perCheck ? 0 : checkerLegBase2(FEE_DENOM, terms, CHECK_REWARD), oracle: checker.address, share: priced.share, feeInReward: Boolean(checker.fee) || coin === FEE_DENOM });
296811
+ const split3 = call3.callShares(draft.fields) ? await callSplit() : null;
296812
+ const priced = call3.callShare(draft.fields, split3);
296813
+ if ("unread" in priced) return text4(call3.SHARE_UNREAD);
296814
+ const plan = call3.callPlan(draft, { poster: `${poster.slice(0, 10)}\u2026${poster.slice(-4)}`, checkerLegBase: (terms) => checker.fee ? checker.fee.base : perCheck ? 0 : checkerLegBase2(FEE_DENOM, terms, CHECK_REWARD), oracle: checker.address, share: priced.share, feeInReward: Boolean(checker.fee) || coin === FEE_DENOM });
296633
296815
  const feeTotal = plan.legs.reduce((sum2, one) => sum2 + one.feeBase, 0);
296634
296816
  const total = pays(plan.totalBase, coinSymbol);
296635
296817
  const { feeLine: feeLine2 } = await Promise.resolve().then(() => (init_feeLine(), feeLine_exports));
296636
296818
  const moneySentence = review && plan.share ? feeLine2({ split: plan.share, net: draft.fields.money.entryEach, symbol: coinSymbol, network: NETWORK2 }) : null;
296637
- if (acting && feeTotal > 0) return text4(`Refused: ${call2.callTwoCoins}.${review ? ` ${PLAIN_REVIEW}` : ""} Nothing was posted.`);
296819
+ if (acting && feeTotal > 0) return text4(`Refused: ${call3.callTwoCoins}.${review ? ` ${PLAIN_REVIEW}` : ""} Nothing was posted.`);
296638
296820
  const approver = review && acting ? acting.principal : null;
296639
296821
  if (approver) {
296640
296822
  const notReady = await approverRefusal(approver, async (who) => (await Promise.resolve().then(() => (init_personReview(), personReview_exports))).approverReady(who, { self: true }));
@@ -296668,21 +296850,21 @@ Then call post_call again. Nothing was posted.`);
296668
296850
  actingNote(acting) ?? (review ? "Posting from your own account (this key), not the person's account; the AI decides each report alone, with no final OK from the person." : `Posting as this key, ${poster}.`),
296669
296851
  ...pick2 ? [pick2] : [],
296670
296852
  `Spent today (call): ${spentWords("call", coinSymbol)}. Every tool together: ${spentAllWords()}.`,
296671
- ...call2.capWords(plan.legs.filter((one) => !draft.posted[one.leg]), CAP_BASE, coinSymbol, NETWORK2),
296672
- ...call2.balanceWarnings(held2, { totalBase: plan.totalBase, feeTotal, symbol: coinSymbol, network: NETWORK2, feeWords }),
296853
+ ...call3.capWords(plan.legs.filter((one) => !draft.posted[one.leg]), CAP_BASE, coinSymbol, NETWORK2),
296854
+ ...call3.balanceWarnings(held2, { totalBase: plan.totalBase, feeTotal, symbol: coinSymbol, network: NETWORK2, feeWords }),
296673
296855
  "",
296674
296856
  `To go ahead, call again with confirm: "${total}".`
296675
296857
  ].join("\n")
296676
296858
  );
296677
296859
  }
296678
- if (!call2.confirms(confirm, plan.totalBase, coinSymbol)) return text4(`Refused: confirm said "${confirm}" but the call locks ${total}. Preview it again.`);
296679
- if (call2.overCap(leg, CAP_BASE)) return text4(`Refused: this leg locks ${pays(leg.escrowBase, coinSymbol)}, over your own ${face(MAX_PER_ASK, coinSymbol)} per-ask cap (OPENHANDS_MAX_PER_ASK_USD, which you set: raise or remove it where you set it). Paying by card (pay_by "card") is not capped.`);
296860
+ if (!call3.confirms(confirm, plan.totalBase, coinSymbol)) return text4(`Refused: confirm said "${confirm}" but the call locks ${total}. Preview it again.`);
296861
+ if (call3.overCap(leg, CAP_BASE)) return text4(`Refused: this leg locks ${pays(leg.escrowBase, coinSymbol)}, over your own ${face(MAX_PER_ASK, coinSymbol)} per-ask cap (OPENHANDS_MAX_PER_ASK_USD, which you set: raise or remove it where you set it). Paying by card (pay_by "card") is not capped.`);
296680
296862
  if (ids.length === 0) {
296681
- const taken = await fetch2(`${SITE}/api/board?campaign=${encodeURIComponent(call2.tagOf(draft))}&size=5`, { signal: AbortSignal.timeout(15e3) }).then((response) => response.ok ? response.json() : null).catch(() => null);
296863
+ const taken = await fetch2(`${SITE}/api/board?campaign=${encodeURIComponent(call3.tagOf(draft))}&size=5`, { signal: AbortSignal.timeout(15e3) }).then((response) => response.ok ? response.json() : null).catch(() => null);
296682
296864
  if (taken?.rows?.length) return text4(`Refused: "${slug}" already names a call with open Asks on this board. Draft it under another slug with draft_call. Nothing was posted.`);
296683
296865
  }
296684
296866
  const { balancesOfStrict: balancesOfStrict2 } = await Promise.resolve().then(() => (init_balance(), balance_exports));
296685
- const refusedBefore = await call2.preCheck(leg, {
296867
+ const refusedBefore = await call3.preCheck(leg, {
296686
296868
  acting,
296687
296869
  poster,
296688
296870
  askDenom: coin,
@@ -296699,7 +296881,7 @@ Then call post_call again. Nothing was posted.`);
296699
296881
  const key = await loadKey2();
296700
296882
  let posted;
296701
296883
  try {
296702
- posted = await call2.postNextLeg(slug, {
296884
+ posted = await call3.postNextLeg(slug, {
296703
296885
  site: SITE,
296704
296886
  askDenom: coin,
296705
296887
  checker: checker.address,
@@ -296715,10 +296897,10 @@ Then call post_call again. Nothing was posted.`);
296715
296897
  feeSplit: split3
296716
296898
  });
296717
296899
  } catch (error54) {
296718
- if (error54 instanceof call2.InFlightError || error54 instanceof call2.PostRefused) return text4(error54.message);
296900
+ if (error54 instanceof call3.InFlightError || error54 instanceof call3.PostRefused) return text4(error54.message);
296719
296901
  if (isUnanchored(error54)) return text4(unanchoredWords(error54));
296720
296902
  if (error54 instanceof Error && error54.name === "TxFailed") {
296721
- if (call2.feeUnpaid(error54, coin)) return text4(`Nothing moved: this agent's key could not pay the network fee for ${LEG_WORDS[next]}. Call post_call again in a minute; it arranges the fee before it signs anything. If it is refused again, tell the person the network fee could not be arranged just now.`);
296903
+ if (call3.feeUnpaid(error54, coin)) return text4(`Nothing moved: this agent's key could not pay the network fee for ${LEG_WORDS[next]}. Call post_call again in a minute; it arranges the fee before it signs anything. If it is refused again, tell the person the network fee could not be arranged just now.`);
296722
296904
  return text4(`The network refused ${LEG_WORDS[next]}: ${error54.message}. Nothing moved. Fix that (often what the account holds, or its cap) and call post_call again.`);
296723
296905
  }
296724
296906
  return text4(
@@ -296728,7 +296910,7 @@ Then call post_call again. Nothing was posted.`);
296728
296910
  if ("done" in posted) return text4(`Everything is posted.
296729
296911
  The call: ${linkOf(posted.draft.posted)}`);
296730
296912
  const done = order2.filter((one) => posted.draft.posted[one]).length;
296731
- const after = call2.nextLeg(posted.draft);
296913
+ const after = call3.nextLeg(posted.draft);
296732
296914
  const hire = posted.draft.fields.mode === "hire";
296733
296915
  const held = posted.screen?.verdict === "hold" ? heldWords(posted.screen.reason) : null;
296734
296916
  const invited = !after && posted.draft.fields.access && posted.draft.fields.access !== "public" ? await writeDraftInvites(posted.draft, posted.id, acting) : null;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ixo/asks-mcp",
3
- "version": "2.0.0-dev.1",
3
+ "version": "2.0.0-dev.2",
4
4
  "description": "The Openhands Network MCP server: read the board, answer asks, post work and get paid on the ixo chain, with a key of its own on your machine.",
5
5
  "license": "Apache-2.0",
6
6
  "repository": {