@ixo/asks-mcp 2.0.0-dev.3 → 2.0.0-dev.4

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 +74 -70
  2. package/package.json +1 -1
package/dist/asks-mcp.mjs CHANGED
@@ -259536,10 +259536,10 @@ __export(connect_exports, {
259536
259536
  workOf: () => workOf
259537
259537
  });
259538
259538
  function noteIgnored(agent, pinned, others, log) {
259539
- const fresh2 = others.filter((one) => !told.has(`${agent}:${pinned}:${one}`));
259540
- if (!fresh2.length) return;
259541
- for (const one of fresh2) told.add(`${agent}:${pinned}:${one}`);
259542
- log(`asks-mcp: ignoring ${fresh2.length === 1 ? "a connection" : "connections"} to this key from ${fresh2.join(", ")}: it is pinned to ${pinned === SELF ? "itself" : pinned}, and only connect_account changes that.`);
259539
+ const fresh3 = others.filter((one) => !told.has(`${agent}:${pinned}:${one}`));
259540
+ if (!fresh3.length) return;
259541
+ for (const one of fresh3) told.add(`${agent}:${pinned}:${one}`);
259542
+ log(`asks-mcp: ignoring ${fresh3.length === 1 ? "a connection" : "connections"} to this key from ${fresh3.join(", ")}: it is pinned to ${pinned === SELF ? "itself" : pinned}, and only connect_account changes that.`);
259543
259543
  }
259544
259544
  async function actingFor(agent, reads2 = chainReads, pins2 = keyPins) {
259545
259545
  const pinned = pinOf(agent, pins2);
@@ -260189,17 +260189,17 @@ function laneStore(deps) {
260189
260189
  const bearer = (can) => laneInvocation({ agent: deps.agent, pass: deps.pass, entityDid: deps.entityDid, collectionId: deps.collectionId, can });
260190
260190
  async function put(bytes3, mediaType, name8) {
260191
260191
  const deadline = Date.now() + (deps.settleMs ?? 6e4);
260192
- let fresh2 = false;
260192
+ let fresh3 = false;
260193
260193
  for (let pause2 = 2e3; ; pause2 = Math.min(pause2 * 2, 8e3)) {
260194
260194
  try {
260195
- return await uploadToLane(bytes3, mediaType, { bearer: await bearer("fs/write"), entityDid: deps.entityDid, collectionId: deps.collectionId, name: laneName(deps.person, bytes3, name8, fresh2) });
260195
+ return await uploadToLane(bytes3, mediaType, { bearer: await bearer("fs/write"), entityDid: deps.entityDid, collectionId: deps.collectionId, name: laneName(deps.person, bytes3, name8, fresh3) });
260196
260196
  } catch (error54) {
260197
- if (error54 instanceof LaneRefused && error54.status === 409 && !fresh2) {
260197
+ if (error54 instanceof LaneRefused && error54.status === 409 && !fresh3) {
260198
260198
  if (bytes3.byteLength <= RAW_CID_MAX) {
260199
260199
  const cid = cidOfBytes(bytes3);
260200
260200
  return { cid, url: laneCidUrl(cid) };
260201
260201
  }
260202
- fresh2 = true;
260202
+ fresh3 = true;
260203
260203
  continue;
260204
260204
  }
260205
260205
  if (!passing(error54) || Date.now() + pause2 > deadline) return null;
@@ -260276,7 +260276,7 @@ ${shareLink(site, collectionId, approver)}` : "";
260276
260276
  BOX_TTL_MS = 10 * 6e4;
260277
260277
  newBoxId = () => randomBytes5(16).toString("hex");
260278
260278
  safeName = (name8) => name8.replace(/[^A-Za-z0-9._-]+/g, "-").replace(/^[.-]+/, "").slice(-80) || "file";
260279
- laneName = (person, bytes3, name8, fresh2 = false) => `${person}/${createHash5("sha256").update(bytes3).digest("hex").slice(0, 24)}${fresh2 ? `-${randomBytes5(3).toString("hex")}` : ""}-${safeName(name8)}`;
260279
+ laneName = (person, bytes3, name8, fresh3 = false) => `${person}/${createHash5("sha256").update(bytes3).digest("hex").slice(0, 24)}${fresh3 ? `-${randomBytes5(3).toString("hex")}` : ""}-${safeName(name8)}`;
260280
260280
  RAW_CID_MAX = 1024 * 1024;
260281
260281
  passing = (error54) => !(error54 instanceof LaneRefused) || error54.status === 403 || error54.status === 429 || error54.status >= 500;
260282
260282
  ENVELOPE_LIMIT = 200 * 1024;
@@ -261831,8 +261831,8 @@ function senderFor(deps) {
261831
261831
  let signerData = deps.signerData ? await deps.signerData() : void 0;
261832
261832
  let fee = "auto";
261833
261833
  try {
261834
- const simulated = await simulateWithChainSequence({ client: client2, address: address2, messages, memo, signerData, warn, onCorrected: (fresh2) => {
261835
- signerData = fresh2;
261834
+ const simulated = await simulateWithChainSequence({ client: client2, address: address2, messages, memo, signerData, warn, onCorrected: (fresh3) => {
261835
+ signerData = fresh3;
261836
261836
  } });
261837
261837
  const priced = (0, import_stargate7.calculateFee)(Math.round(simulated.gas * 1.8), GAS_PRICE2);
261838
261838
  const granter = await deps.granterFor(messages.map((one) => one.typeUrl), Number(priced.amount[0]?.amount ?? 0));
@@ -263686,7 +263686,9 @@ var init_callTerms = __esm({
263686
263686
  var feeLine_exports = {};
263687
263687
  __export(feeLine_exports, {
263688
263688
  MAINNET_SPLIT: () => MAINNET_SPLIT,
263689
- feeLine: () => feeLine
263689
+ feeLine: () => feeLine,
263690
+ feeSentence: () => feeSentence,
263691
+ feeWords: () => feeWords
263690
263692
  });
263691
263693
  function feeLine(args) {
263692
263694
  const { split: split3, symbol: symbol2 } = args;
@@ -263694,12 +263696,12 @@ function feeLine(args) {
263694
263696
  const receives = `Each pro receives ${amountWords(args.net, symbol2)}.`;
263695
263697
  const locked2 = `${amountWords(leg / 1e6, symbol2)} is locked per report`;
263696
263698
  if (split3.network + split3.node === 0) {
263697
- if (args.network === "mainnet") return `${receives} Nothing is taken on top: ${locked2}.`;
263698
- return `${receives} In the sandbox nothing is added: ${amountWords(leg / 1e6, symbol2)} is held per report; on the real network the fee is ${percentWords(MAINNET_SPLIT.network + MAINNET_SPLIT.node)} on top.`;
263699
+ if (args.network === "mainnet") return `${receives} Nothing is taken: ${locked2}.`;
263700
+ return `${receives} In the sandbox nothing is added: ${amountWords(leg / 1e6, symbol2)} is held per report. On the real network, ${feeWords(MAINNET_SPLIT)}`;
263699
263701
  }
263700
- return `${receives} ${locked2}: ${percentWords(split3.network + split3.node)} on top of what the pro receives.`;
263702
+ return `${receives} ${locked2}. ${feeWords(split3)}`;
263701
263703
  }
263702
- var MAINNET_SPLIT, percentWords, amountWords;
263704
+ var MAINNET_SPLIT, percentWords, feeWords, feeSentence, amountWords;
263703
263705
  var init_feeLine = __esm({
263704
263706
  "../../packages/openhands-sdk/src/rubric/feeLine.ts"() {
263705
263707
  "use strict";
@@ -263707,6 +263709,8 @@ var init_feeLine = __esm({
263707
263709
  init_share();
263708
263710
  MAINNET_SPLIT = { network: 10, node: 10 };
263709
263711
  percentWords = (value) => `${Number(value.toFixed(6))} %`;
263712
+ feeWords = (split3, who = "The pro") => `${percentWords(split3.network + split3.node)} of what you pay runs asks.world. ${who} gets the rest.`;
263713
+ feeSentence = (split3, network2, who = "The pro") => split3.network + split3.node === 0 && network2 !== "mainnet" ? `In the sandbox nothing is added. On the real network, ${feeWords(MAINNET_SPLIT, who)}` : feeWords(split3, who);
263710
263714
  amountWords = (value, symbol2) => ["USDC", "USD", "PAY", "$"].includes(symbol2) ? dollars(value) : `${Number(value.toFixed(6))} ${symbol2}`;
263711
263715
  }
263712
263716
  });
@@ -263773,7 +263777,7 @@ function callReadout(terms, ctx) {
263773
263777
  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.";
263774
263778
  const review = call3.kind === "review";
263775
263779
  const shared = call3.share ? sharedPay(m.entryEach, call3.share) : null;
263776
- 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"}` : "";
263780
+ 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"}` : "";
263777
263781
  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;
263778
263782
  const out = [
263779
263783
  `${review ? "Pro ask" : hire ? "Hiring call" : "Open call"} "${call3.slug}" \xB7 posted by ${call3.poster} \xB7 ${stageWords(call3, ctx.now)}`,
@@ -267120,11 +267124,11 @@ function roomRows(counts) {
267120
267124
  case "proAsks":
267121
267125
  return { ...room, ...counted(counts.proAsks ?? null, null) };
267122
267126
  case "work":
267123
- return { ...room, ...counted(counts.work, "waiting") };
267127
+ return { ...room, ...fresh2(counts.work, "waiting") };
267124
267128
  case "messages":
267125
- return { ...room, ...counted(counts.unread, "unread") };
267129
+ return { ...room, ...fresh2(counts.unread, "unread") };
267126
267130
  case "inbox":
267127
- return { ...room, ...counted(counts.inbox, null) };
267131
+ return { ...room, ...fresh2(counts.inbox, "new") };
267128
267132
  case "money":
267129
267133
  return { ...room, figure: counts.money.available, money: true, after: counts.money.onAsks ? `${counts.money.onAsks} on asks` : null };
267130
267134
  case "agents":
@@ -267134,7 +267138,7 @@ function roomRows(counts) {
267134
267138
  }
267135
267139
  });
267136
267140
  }
267137
- var ROOMS, counted, roomLines;
267141
+ var ROOMS, counted, fresh2, roomLines;
267138
267142
  var init_meRooms = __esm({
267139
267143
  "../../app/lib/meRooms.ts"() {
267140
267144
  "use strict";
@@ -267149,6 +267153,7 @@ var init_meRooms = __esm({
267149
267153
  { key: "settings", word: "Settings", href: "/me/settings" }
267150
267154
  ];
267151
267155
  counted = (value, after) => value ? { figure: String(value), after } : { figure: null, after: null };
267156
+ fresh2 = (value, after) => ({ ...counted(value, after), ...value ? { fresh: true } : {} });
267152
267157
  roomLines = (counts) => roomRows(counts).map((row) => `${row.word}: ${row.chip ?? (row.verify ? "not verified yet" : [row.figure, row.after].filter(Boolean).join(row.money ? " \xB7 " : " ") || (row.key === "settings" ? "sign-in, recovery, currency, identity" : "nothing waiting"))}`);
267153
267158
  }
267154
267159
  });
@@ -292360,7 +292365,7 @@ import { randomBytes as randomBytes7 } from "node:crypto";
292360
292365
  // package.json
292361
292366
  var package_default = {
292362
292367
  name: "@ixo/asks-mcp",
292363
- version: "2.0.0-dev.3",
292368
+ version: "2.0.0-dev.4",
292364
292369
  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.",
292365
292370
  license: "Apache-2.0",
292366
292371
  repository: {
@@ -292650,7 +292655,7 @@ var TOOLS = {
292650
292655
  },
292651
292656
  draft_call: {
292652
292657
  title: "Set up an open call or a pro ask",
292653
- description: 'Draft an open call or a pro ask. An open call is a brief people answer with their own AI, checked against five requirements: a competition picks a winner; a hire pays every entry that passes, up to a number, and picks nobody; open to anyone, by application (you say yes to each), or by invitation (your list: addresses, @handles, single-use links). A software-review Ask (`kind: "review"`) is one specialised work type on Pro Asks: verified pros you invite try the scenarios and send reports; always a hire, by invitation only; Asky Pro Checker, the verifier, checks each report. Interviews in order: give what the person said, and the answer lists what is still missing, each with the question to ask them. Kept on disk between calls, so never re-send what was already taken. When nothing is missing it shows the whole call, what each leg holds (a pro ask\'s money in one sentence: what each pro receives, what is held per report, and the fee: 20 % on top of what the pro receives) and the clock, for the person to approve. Spends nothing.',
292658
+ description: 'Draft an open call or a pro ask. An open call is a brief people answer with their own AI, checked against five requirements: a competition picks a winner; a hire pays every entry that passes, up to a number, and picks nobody; open to anyone, by application (you say yes to each), or by invitation (your list: addresses, @handles, single-use links). A software-review Ask (`kind: "review"`) is one specialised work type on Pro Asks: verified pros you invite try the scenarios and send reports; always a hire, by invitation only; Asky Pro Checker, the verifier, checks each report. Interviews in order: give what the person said, and the answer lists what is still missing, each with the question to ask them. Kept on disk between calls, so never re-send what was already taken. When nothing is missing it shows the whole call, what each leg holds (a pro ask\'s money in one sentence: what each pro receives, what is held per report, and the fee: 20 % of what you pay runs asks.world, the pro gets the rest) and the clock, for the person to approve. Spends nothing.',
292654
292659
  spends: false,
292655
292660
  hosted: false,
292656
292661
  /* It writes the draft file, and nothing else anywhere. */
@@ -294493,18 +294498,18 @@ async function build2(options, server2, parts) {
294493
294498
  const refreshDeployment = async () => {
294494
294499
  if (!local || options.deployment || Date.now() - siteReadAt < (CLAIM_FORM && !DEPLOYMENT.note ? SITE_REREAD_MS : 1e4)) return;
294495
294500
  siteReadAt = Date.now();
294496
- const fresh2 = await deployment().catch(() => null);
294497
- if (!fresh2 || fresh2.note) return;
294498
- DEPLOYMENT = fresh2;
294499
- adoptRelayer(fresh2);
294500
- adoptAskProtocol(fresh2);
294501
- adoptReviewBilling(fresh2);
294502
- adoptOracleUrl(fresh2);
294503
- adoptFeeSplit(fresh2);
294504
- adoptAskDenom(fresh2);
294505
- adoptClaimForm(fresh2);
294506
- CLAIM_FORM = fresh2.claimForm;
294507
- applyDeployment(fresh2);
294501
+ const fresh3 = await deployment().catch(() => null);
294502
+ if (!fresh3 || fresh3.note) return;
294503
+ DEPLOYMENT = fresh3;
294504
+ adoptRelayer(fresh3);
294505
+ adoptAskProtocol(fresh3);
294506
+ adoptReviewBilling(fresh3);
294507
+ adoptOracleUrl(fresh3);
294508
+ adoptFeeSplit(fresh3);
294509
+ adoptAskDenom(fresh3);
294510
+ adoptClaimForm(fresh3);
294511
+ CLAIM_FORM = fresh3.claimForm;
294512
+ applyDeployment(fresh3);
294508
294513
  };
294509
294514
  const unjudged = async () => {
294510
294515
  await refreshDeployment();
@@ -294535,7 +294540,7 @@ async function build2(options, server2, parts) {
294535
294540
  const cap = capCoinRefusal2(acting, coin);
294536
294541
  return cap ? { refused: cap } : coin;
294537
294542
  };
294538
- const feeWords = (base6, symbol2 = FEE_SYMBOL) => dollarsOf(base6, symbol2, NETWORK2);
294543
+ const feeWords2 = (base6, symbol2 = FEE_SYMBOL) => dollarsOf(base6, symbol2, NETWORK2);
294539
294544
  const FUNDER = ownEnv().OPENHANDS_FUNDER?.trim() || void 0;
294540
294545
  const FOLLOW_PAY_MAX = 10;
294541
294546
  const MAX_PER_ASK = CAPS.perAsk;
@@ -294791,7 +294796,7 @@ Each is its own ask and pays on its own. Read one with read_ask before deciding.
294791
294796
  if (title) taint2(title);
294792
294797
  const facts = row.callSummary;
294793
294798
  const shares = call3.shared;
294794
- 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;
294799
+ const entryPays = shares && facts?.entryEach !== void 0 && call3.entries?.pays ? faceOf2({ value: facts.entryEach, symbol: call3.entries.pays.symbol }, SANDBOX)?.text : call3.entries?.pays ? `${faceOf2(call3.entries.pays, SANDBOX)?.text}${shares ? ", less the network's share" : ""}` : void 0;
294795
294800
  return [
294796
294801
  `${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`,
294797
294802
  title ? asData("ask-title", title) : "",
@@ -295398,15 +295403,15 @@ Never open it yourself.`);
295398
295403
  amount: offChain ? `${offChain.amount} ${offChain.currency}` : face(pay, symbol2),
295399
295404
  quota: spots,
295400
295405
  total: offChain ? `${(Number(offChain.amount) * spots).toFixed(2)} ${offChain.currency}` : rewardsFace,
295401
- fee: feeWords(perCheck ? perCheck.price : legBase),
295402
- feeTotal: feeWords(legBase * spots),
295406
+ fee: feeWords2(perCheck ? perCheck.price : legBase),
295407
+ feeTotal: feeWords2(legBase * spots),
295403
295408
  perReview: Boolean(perCheck),
295404
295409
  own: !perCheck && legBase === 0 && !orgAsk.oracle.url,
295405
295410
  free: !perCheck && legBase === 0 && Boolean(orgAsk.oracle.url)
295406
295411
  }).map((line2) => `- ${line2.label}: ${line2.text}`).join("\n") : "";
295407
295412
  const { total, what: preview, details: costDetails } = orgAsk ? { total: 0, what: `nothing from this key (${orgName} pays)`, details: `What this costs ${orgName}:
295408
- ${orgCosts}` } : { total: onChain.total, what: perCheck ? `${onChain.what}. Review fee: ${billing.creditsCopy(null, feeWords(perCheck.price))}` : onChain.what, details: "" };
295409
- const orgToken = orgAsk ? (await Promise.resolve().then(() => (init_hq(), hq_exports))).orgConfirmToken({ offChainTotal: offChain ? `${(Number(offChain.amount) * spots).toFixed(2)} ${offChain.currency}` : null, rewards: rewardsFace, feesSetAside: !perCheck && legBase > 0 ? feeWords(legBase * spots) : null }) : void 0;
295413
+ ${orgCosts}` } : { total: onChain.total, what: perCheck ? `${onChain.what}. Review fee: ${billing.creditsCopy(null, feeWords2(perCheck.price))}` : onChain.what, details: "" };
295414
+ const orgToken = orgAsk ? (await Promise.resolve().then(() => (init_hq(), hq_exports))).orgConfirmToken({ offChainTotal: offChain ? `${(Number(offChain.amount) * spots).toFixed(2)} ${offChain.currency}` : null, rewards: rewardsFace, feesSetAside: !perCheck && legBase > 0 ? feeWords2(legBase * spots) : null }) : void 0;
295410
295415
  const payDraft = card ? await Promise.resolve().then(() => (init_payDraft(), payDraft_exports)) : null;
295411
295416
  const quote = payDraft?.quoteOf(Number(baseFromPay2(pay)) * spots, legBase * spots);
295412
295417
  const cardWords = payDraft && quote ? payDraft.cardPreview(quote) : null;
@@ -295435,7 +295440,7 @@ ${orgCosts}` } : { total: onChain.total, what: perCheck ? `${onChain.what}. Revi
295435
295440
  card ? null : actingNote(acting),
295436
295441
  pick2,
295437
295442
  expert ? expertNote(expert) : checkingNote(terms, acting?.principal ?? null),
295438
- expert ? null : orgAsk ? `Reviewed by ${await oracleWordsFor({ did: orgAsk.oracle.did, address: orgAsk.oracle.address })}.` : reviewer && reviewer !== CHECKER ? `Reviewed by ${await oracleWordsFor({ address: reviewer })}.` : reviewer ? `Checked by asks.world verifier, ${feeWords(perCheck ? perCheck.price : legBase)} per check.` : null,
295443
+ expert ? null : orgAsk ? `Reviewed by ${await oracleWordsFor({ did: orgAsk.oracle.did, address: orgAsk.oracle.address })}.` : reviewer && reviewer !== CHECKER ? `Reviewed by ${await oracleWordsFor({ address: reviewer })}.` : reviewer ? `Checked by asks.world verifier, ${feeWords2(perCheck ? perCheck.price : legBase)} per check.` : null,
295439
295444
  doorWords(door2.access, door2.invite.length),
295440
295445
  inCampaign ? `In campaign ${inCampaign.protocolDid}, checked by its shared rules (${inCampaign.claimProtocolDid}).` : null,
295441
295446
  picture2 && !("refused" in picture2) ? `Picture: ${picture2.contentType.slice(6)}, ${Math.ceil(picture2.bytes.byteLength / 1024)} KB, uploaded through your account connection with the ask.` : null,
@@ -295535,12 +295540,12 @@ ${SITE}/t/${earlier.id}`);
295535
295540
  if (bare2) return said4(receives);
295536
295541
  return `${said4(receives)} (the leg is ${said4(Number(amount3))}; the network keeps ${said4(Number(amount3) - receives)}: ${shareWords2(split3, posted ? "as posted" : "today")})`;
295537
295542
  }
295538
- const callLocks = (rewardBase, feeBase, symbol2 = ASK_SYMBOL) => `${pays(rewardBase, symbol2)}${feeBase > 0 ? ` and ${feeWords(feeBase)} for reviews` : ""}`;
295543
+ const callLocks = (rewardBase, feeBase, symbol2 = ASK_SYMBOL) => `${pays(rewardBase, symbol2)}${feeBase > 0 ? ` and ${feeWords2(feeBase)} for reviews` : ""}`;
295539
295544
  function escrowTotal(pay, spots, legBase, symbol2 = ASK_SYMBOL, sameCoin = true, feeSymbol = FEE_SYMBOL) {
295540
295545
  const leg = legBase / MICRO6;
295541
295546
  if (!sameCoin && leg > 0) {
295542
295547
  const total2 = pay * spots;
295543
- return { total: total2, what: `${face(total2, symbol2)} and ${feeWords(legBase * spots, feeSymbol)}. A ${face(pay, symbol2)} reward for each of ${spots} ${spots === 1 ? "answer" : "answers"}, plus ${feeWords(legBase, feeSymbol)} for each review. Held now` };
295548
+ return { total: total2, what: `${face(total2, symbol2)} and ${feeWords2(legBase * spots, feeSymbol)}. A ${face(pay, symbol2)} reward for each of ${spots} ${spots === 1 ? "answer" : "answers"}, plus ${feeWords2(legBase, feeSymbol)} for each review. Held now` };
295544
295549
  }
295545
295550
  const total = (pay + leg) * spots;
295546
295551
  return {
@@ -295647,7 +295652,7 @@ ${SITE}/t/${earlier.id}`);
295647
295652
  const billing = await Promise.resolve().then(() => (init_reviewBilling(), reviewBilling_exports));
295648
295653
  const escrowed = escrowTotal(pay, spots, legBase, coinSymbol, coin === (expert?.feeDenom ?? FEE_DENOM), symbolOf(expert?.feeDenom ?? FEE_DENOM));
295649
295654
  const total = escrowed.total;
295650
- const what = perCheck ? `${escrowed.what}. Review fee: ${billing.creditsCopy(null, feeWords(perCheck.price))}` : escrowed.what;
295655
+ const what = perCheck ? `${escrowed.what}. Review fee: ${billing.creditsCopy(null, feeWords2(perCheck.price))}` : escrowed.what;
295651
295656
  const guard = spendGuard({
295652
295657
  bucket: "world",
295653
295658
  task: question,
@@ -296488,7 +296493,7 @@ ${pending.link}`);
296488
296493
  The review fee's coin, where it is not the reward's (mainnet: USDC rewards, PAY fees), is what covers the next
296489
296494
  ask's checks, so it is said when there is any. In dollars, as every amount. The network fee is the gate's to
296490
296495
  cover for an account that holds money, so it is not a line here. */
296491
- `Available: ${pays(Number(held[ASK_DENOM] ?? 0), ASK_DENOM)} \xB7 On your asks ${onAsks === null ? "(could not be read just now)" : pays(onAsks, "upay")}${ASK_DENOM !== FEE_DENOM && Number(held[FEE_DENOM] ?? 0) > 0 ? ` \xB7 ${feeWords(Number(held[FEE_DENOM]))} set aside for checks` : ""}`,
296496
+ `Available: ${pays(Number(held[ASK_DENOM] ?? 0), ASK_DENOM)} \xB7 On your asks ${onAsks === null ? "(could not be read just now)" : pays(onAsks, "upay")}${ASK_DENOM !== FEE_DENOM && Number(held[FEE_DENOM] ?? 0) > 0 ? ` \xB7 ${feeWords2(Number(held[FEE_DENOM]))} set aside for checks` : ""}`,
296492
296497
  done ? `Work: ${done.submitted ?? 0} answers \xB7 ${done.approved ?? 0} approved${done.earned ? ` \xB7 ${face(done.earned.value, done.earned.symbol)} earned` : ""}` : "",
296493
296498
  /* Whose money this would spend, and how much of it is left. An agent
296494
296499
  funded by somebody's allowance should be able to say so — and an
@@ -296654,7 +296659,7 @@ ${settings}`
296654
296659
  const unread = await unreadable(terms);
296655
296660
  if (unread) return text4(unread);
296656
296661
  const { total } = escrowTotal(pin_pay, pins2, legBase, coinSymbol, coin === FEE_DENOM);
296657
- const preview = `${face(total, coinSymbol)} to open "${name8}". ${pins2} ${pins2 === 1 ? "report" : "reports"} at ${face(pin_pay, coinSymbol)} each, plus ${feeWords(legBase)} to whoever checks each one. Mapping stays open ${open} days, and two pins closer than ${apart} m are the same mess`;
296662
+ const preview = `${face(total, coinSymbol)} to open "${name8}". ${pins2} ${pins2 === 1 ? "report" : "reports"} at ${face(pin_pay, coinSymbol)} each, plus ${feeWords2(legBase)} to whoever checks each one. Mapping stays open ${open} days, and two pins closer than ${apart} m are the same mess`;
296658
296663
  const guard = spendGuard({ bucket: "organise", task: `campaign ${tag}`, total, ...confirm ? { confirm } : {}, what: preview, symbol: coinSymbol });
296659
296664
  if (guard) {
296660
296665
  return text4(
@@ -296801,12 +296806,12 @@ Mapping pays for the report. What happens to a mapped pin afterwards is a separa
296801
296806
  const keyOnly = !acting && feeTotal > 0;
296802
296807
  const blocked = capped4.length > 0 || Boolean(otherCoin) || Boolean(twoCoins) && draft.fields.kind !== "review";
296803
296808
  const m = draft.fields.money;
296804
- const { shareWords: shareWords2 } = await Promise.resolve().then(() => (init_callRead(), callRead_exports));
296809
+ const { feeSentence: feeSentence2 } = await Promise.resolve().then(() => (init_feeLine(), feeLine_exports));
296805
296810
  const proMoney = proAsk && Boolean(plan.share);
296806
296811
  const who = draft.fields.kind === "review" ? "pro" : "hired person";
296807
- const onTop = (leg) => plan.share && !proMoney ? `; the network's share (${shareWords2(plan.share, "today")}) is added on top, so the leg pays ${pays(leg.legBase, coinSymbol)}` : "";
296812
+ const legPays = (leg) => plan.share && !proMoney ? `, so the leg pays ${pays(leg.legBase, coinSymbol)}` : "";
296808
296813
  const legRows = plan.legs.map(
296809
- (leg) => leg.leg === "prize" ? ` The pick ${pays(leg.payBase, coinSymbol)} to one entry${onTop(leg)}; its ask takes ${leg.quota} claims (the pick and two spare) \xB7 locks ${pays(leg.escrowBase, coinSymbol)}` : leg.leg === "runnersUp" ? ` Runners-up ${pays(leg.payBase, coinSymbol)} to each of ${m.runnersN}${onTop(leg)} \xB7 locks ${pays(leg.escrowBase, coinSymbol)}` : plan.share ? ` Entries each ${who} receives ${pays(leg.payBase, coinSymbol)} for an entry that passes all ${draft.fields.kind === "review" ? "six" : "five"} lines${onTop(leg)} \xB7 up to ${leg.quota}${checker.fee ? `, plus ${pays(leg.checkBase, coinSymbol)} per check to ${checker.name}` : leg.checkBase > 0 ? `, plus the verifier's ${feeWords(leg.checkBase)} per ruling` : ", the verifier billed per check from credits"} \xB7 locks ${callLocks(leg.escrowBase, leg.feeBase, coinSymbol)}` : ` Entries ${pays(leg.payBase, coinSymbol)} to each entry that passes all ${draft.fields.kind === "review" ? "six" : "five"} lines, up to ${leg.quota}${checker.fee ? `, plus ${pays(leg.checkBase, coinSymbol)} per check to ${checker.name}` : leg.checkBase > 0 ? `, plus the verifier's ${feeWords(leg.checkBase)} per ruling` : ", the verifier billed per check from credits"} \xB7 locks ${callLocks(leg.escrowBase, leg.feeBase, coinSymbol)}`
296814
+ (leg) => leg.leg === "prize" ? ` The pick ${pays(leg.payBase, coinSymbol)} to one entry${legPays(leg)}; its ask takes ${leg.quota} claims (the pick and two spare) \xB7 locks ${pays(leg.escrowBase, coinSymbol)}` : leg.leg === "runnersUp" ? ` Runners-up ${pays(leg.payBase, coinSymbol)} to each of ${m.runnersN}${legPays(leg)} \xB7 locks ${pays(leg.escrowBase, coinSymbol)}` : plan.share ? ` Entries each ${who} receives ${pays(leg.payBase, coinSymbol)} for an entry that passes all ${draft.fields.kind === "review" ? "six" : "five"} lines${legPays(leg)} \xB7 up to ${leg.quota}${checker.fee ? `, plus ${pays(leg.checkBase, coinSymbol)} per check to ${checker.name}` : leg.checkBase > 0 ? `, plus the verifier's ${feeWords2(leg.checkBase)} per ruling` : ", the verifier billed per check from credits"} \xB7 locks ${callLocks(leg.escrowBase, leg.feeBase, coinSymbol)}` : ` Entries ${pays(leg.payBase, coinSymbol)} to each entry that passes all ${draft.fields.kind === "review" ? "six" : "five"} lines, up to ${leg.quota}${checker.fee ? `, plus ${pays(leg.checkBase, coinSymbol)} per check to ${checker.name}` : leg.checkBase > 0 ? `, plus the verifier's ${feeWords2(leg.checkBase)} per ruling` : ", the verifier billed per check from credits"} \xB7 locks ${callLocks(leg.escrowBase, leg.feeBase, coinSymbol)}`
296810
296815
  );
296811
296816
  const shareTotal = plan.legs.reduce((sum2, one) => sum2 + one.shareBase * one.escrowSpots, 0);
296812
296817
  const hire = draft.fields.mode === "hire";
@@ -296817,7 +296822,7 @@ Mapping pays for the report. What happens to a mapped pin afterwards is a separa
296817
296822
  !hire && m.prize < m.entryEach ? `The prize (${face(m.prize, coinSymbol)}) is less than one entry earns (${face(m.entryEach, coinSymbol)}).` : "",
296818
296823
  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.' : "",
296819
296824
  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." : "",
296820
- ...call3.balanceWarnings(held, { totalBase: plan.totalBase, feeTotal, symbol: coinSymbol, network: NETWORK2, feeWords }),
296825
+ ...call3.balanceWarnings(held, { totalBase: plan.totalBase, feeTotal, symbol: coinSymbol, network: NETWORK2, feeWords: feeWords2 }),
296821
296826
  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.` : "",
296822
296827
  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.` : ""
296823
296828
  ].filter(Boolean);
@@ -296831,10 +296836,10 @@ Mapping pays for the report. What happens to a mapped pin afterwards is a separa
296831
296836
  ...legRows,
296832
296837
  ` Total ${callLocks(plan.totalBase, feeTotal, coinSymbol)}`,
296833
296838
  ...plan.share && !proMoney ? [
296834
- ` Network's share ${pays(shareTotal, coinSymbol)} of that, if every spot is paid (${shareWords2(plan.share, "today")}): the network splits it off each approval and pays the rest to the person. Asks and public calls carry no share.`
296839
+ ` Network's share ${pays(shareTotal, coinSymbol)} of that, if every spot is paid. ${feeSentence2(plan.share, NETWORK2, "Each hired person")} Asks and public calls carry no share.`
296835
296840
  ] : [],
296836
296841
  "",
296837
- `${actingNote(acting) ?? `Not connected; with plain_key this key posts as itself, ${await address2()}.`} The account holds ${holds ?? "an amount nobody could read"}${held !== null && feeTotal > 0 ? ` and ${feeWords(held.fee)}` : ""}; this call locks ${callLocks(plan.totalBase, feeTotal, coinSymbol)}.`,
296842
+ `${actingNote(acting) ?? `Not connected; with plain_key this key posts as itself, ${await address2()}.`} The account holds ${holds ?? "an amount nobody could read"}${held !== null && feeTotal > 0 ? ` and ${feeWords2(held.fee)}` : ""}; this call locks ${callLocks(plan.totalBase, feeTotal, coinSymbol)}.`,
296838
296843
  hire ? `The clock: entries close ${new Date(plan.dates.closes).toUTCString()}; ${finalOk ? `every passing report is paid once ${finalOk} gives the final OK` : "every passing entry is paid as it is judged"}, and nothing waits for a pick.` : `The clock: entries close ${new Date(plan.dates.closes).toUTCString()}; the shortlist shows ${new Date(plan.dates.drop).toUTCString()}; the pick by ${new Date(plan.dates.pick).toUTCString()}.`,
296839
296844
  `Who may enter: ${draft.fields.access === "invite" ? `by invitation only${draft.fields.invite?.length ? `. ${draft.fields.invite.length} people will be invited when the Ask is posted${draft.fields.inviteNote ? ", each with your private note" : ""}` : ""}` : draft.fields.access === "apply" ? "by application, listed on the board" : "anyone, listed on the board"}.`,
296840
296845
  ...draft.fields.kind === "review" ? [
@@ -296933,20 +296938,19 @@ Then call post_call again. Nothing was posted.`);
296933
296938
  return text4(await payDraft.saveDraft(SITE, { kind: "call", terms, quote, network: NETWORK2 }, fetch2));
296934
296939
  }
296935
296940
  if (!confirm) {
296936
- const { shareWords: shareWords2 } = await Promise.resolve().then(() => (init_callRead(), callRead_exports));
296937
- const shareTotal = plan.legs.reduce((sum2, one) => sum2 + one.shareBase * one.escrowSpots, 0);
296941
+ const { feeSentence: feeSentence2 } = await Promise.resolve().then(() => (init_feeLine(), feeLine_exports));
296938
296942
  const held2 = await heldBy(acting, coin);
296939
296943
  return text4(
296940
296944
  [
296941
296945
  `Call "${slug}" locks ${callLocks(plan.totalBase, feeTotal, coinSymbol)} in ${order2.length} ${order2.length === 1 ? "Ask" : "Asks"}, posted one per call: ${order2.map((one) => LEG_WORDS[one]).join(", then ")}.${ids.length ? ` Posted already: ${ids.join(", ")}.` : ""}`,
296942
- /* A private call: the share is in that total, on top of what each person receives, and said before the yes; a pro ask says it in its one sentence. */
296943
- ...moneySentence ? [moneySentence] : plan.share ? [`Of that, the network's share is ${pays(shareTotal, coinSymbol)} if every spot is paid (${shareWords2(plan.share, "today")}), on top of what each person receives: ${pays(plan.legs.find((one) => one.leg === "entries").payBase, coinSymbol)} for each passing entry.`] : [],
296946
+ /* A private call: the fee is in that total, said before the yes in one figure of what the poster pays; a pro ask says it in its one sentence. */
296947
+ ...moneySentence ? [moneySentence] : plan.share ? [`Each hired person receives ${pays(plan.legs.find((one) => one.leg === "entries").payBase, coinSymbol)} for each passing entry. ${feeSentence2(plan.share, NETWORK2, "Each hired person")}`] : [],
296944
296948
  `Next: ${LEG_WORDS[next]}, locking ${callLocks(leg.escrowBase, leg.feeBase, coinSymbol)}, plus a small network fee.`,
296945
296949
  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}.`),
296946
296950
  ...pick2 ? [pick2] : [],
296947
296951
  `Spent today (call): ${spentWords("call", coinSymbol)}. Every tool together: ${spentAllWords()}.`,
296948
296952
  ...call3.capWords(plan.legs.filter((one) => !draft.posted[one.leg]), CAP_BASE, coinSymbol, NETWORK2),
296949
- ...call3.balanceWarnings(held2, { totalBase: plan.totalBase, feeTotal, symbol: coinSymbol, network: NETWORK2, feeWords }),
296953
+ ...call3.balanceWarnings(held2, { totalBase: plan.totalBase, feeTotal, symbol: coinSymbol, network: NETWORK2, feeWords: feeWords2 }),
296950
296954
  "",
296951
296955
  `To go ahead, call again with confirm: "${total}".`
296952
296956
  ].join("\n")
@@ -296966,7 +296970,7 @@ Then call post_call again. Nothing was posted.`);
296966
296970
  feeDenom: FEE_DENOM,
296967
296971
  balanceBase: async (who, denom) => Number((await balancesOfStrict2(who))[denom] ?? 0),
296968
296972
  face: (base6) => pays(base6, coinSymbol),
296969
- feeFace: feeWords,
296973
+ feeFace: feeWords2,
296970
296974
  coinFixed: Boolean(checker.fee),
296971
296975
  site: SITE
296972
296976
  });
@@ -297677,15 +297681,15 @@ ${asData("linkedin", JSON.stringify(prefill, null, 2))}`
297677
297681
  }
297678
297682
  };
297679
297683
  let PLANS = DEPLOYMENT.plans;
297680
- function applyDeployment(fresh2) {
297681
- ASK_DENOM = fresh2.askDenom;
297684
+ function applyDeployment(fresh3) {
297685
+ ASK_DENOM = fresh3.askDenom;
297682
297686
  ASK_SYMBOL = symbolOf(ASK_DENOM);
297683
- CHECKER = fresh2.checker;
297684
- GATE = fresh2.gate;
297685
- CHECK_REWARD = fresh2.checkRewardBase;
297686
- ENGINE_ORACLE = fresh2.engine.oracle;
297687
- ENGINE_MODE = fresh2.engine.live;
297688
- PLANS = fresh2.plans;
297687
+ CHECKER = fresh3.checker;
297688
+ GATE = fresh3.gate;
297689
+ CHECK_REWARD = fresh3.checkRewardBase;
297690
+ ENGINE_ORACLE = fresh3.engine.oracle;
297691
+ ENGINE_MODE = fresh3.engine.live;
297692
+ PLANS = fresh3.plans;
297689
297693
  }
297690
297694
  const MAX_PER_PLAN = CAPS.perPlan;
297691
297695
  const PLAN_CAPS = { perAsk: MAX_PER_ASK, perPlan: MAX_PER_PLAN, perDayTotal: MAX_PER_DAY_TOTAL };
@@ -297696,8 +297700,8 @@ ${asData("linkedin", JSON.stringify(prefill, null, 2))}`
297696
297700
  return { cost: planCost2(plan, { reviewUsd: sameCoin ? world.leg / MICRO6 : 0, feeRate: 0 }), reviewsBase: sameCoin ? 0 : world.leg * planAnswerCount2(plan) };
297697
297701
  }
297698
297702
  async function reviewWords(world, reviewsBase) {
297699
- if (world.perCheck) return `Review fee: ${(await Promise.resolve().then(() => (init_reviewBilling(), reviewBilling_exports))).creditsCopy(null, feeWords(world.perCheck.price))}`;
297700
- return reviewsBase > 0 ? `Reviews: ${feeWords(reviewsBase)} on top, ${feeWords(world.leg)} for each answer, escrowed beside the rewards.` : "";
297703
+ if (world.perCheck) return `Review fee: ${(await Promise.resolve().then(() => (init_reviewBilling(), reviewBilling_exports))).creditsCopy(null, feeWords2(world.perCheck.price))}`;
297704
+ return reviewsBase > 0 ? `Reviews: ${feeWords2(reviewsBase)} on top, ${feeWords2(world.leg)} for each answer, escrowed beside the rewards.` : "";
297701
297705
  }
297702
297706
  const UNPRICED = "The verifier could not be priced just now, so no plan can be bought. Try again shortly. Nothing was posted.";
297703
297707
  async function registerPlan(cid, poster) {
@@ -297895,7 +297899,7 @@ ${asData("linkedin", JSON.stringify(prefill, null, 2))}`
297895
297899
  }
297896
297900
  if (confirm.trim() !== money3(cost.totalUsd)) return text4(`Refused: confirm said "${confirm}" but the total is ${money3(cost.totalUsd)}. Preview it again.`);
297897
297901
  if (!resuming) {
297898
- if (acting && reviewsBase > 0) return text4(`Refused: this plan's reviews escrow ${feeWords(reviewsBase)} beside its ${coinSymbol} rewards, and ${acting.principal}'s allowance covers ${coinSymbol} only. Use a verifier that bills per check (Pay for reviews), or post from this key. Nothing was posted.`);
297902
+ if (acting && reviewsBase > 0) return text4(`Refused: this plan's reviews escrow ${feeWords2(reviewsBase)} beside its ${coinSymbol} rewards, and ${acting.principal}'s allowance covers ${coinSymbol} only. Use a verifier that bills per check (Pay for reviews), or post from this key. Nothing was posted.`);
297899
297903
  const otherCoin = (await Promise.resolve().then(() => (init_hq(), hq_exports))).capCoinRefusal(acting, coin);
297900
297904
  if (otherCoin) return text4(`Refused: ${otherCoin}. Draft the plan again with draft_plan in that coin. Nothing was posted.`);
297901
297905
  if (acting) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ixo/asks-mcp",
3
- "version": "2.0.0-dev.3",
3
+ "version": "2.0.0-dev.4",
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": {