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

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 +420 -634
  2. package/package.json +1 -1
package/dist/asks-mcp.mjs CHANGED
@@ -7520,14 +7520,13 @@ function answerPage(site, collectionId, claimId, facts) {
7520
7520
  function inviteLink(site, token, review) {
7521
7521
  return review ? `${site.replace(/\/+$/, "")}/pro/i/${token}` : `${site.replace(/\/+$/, "")}/opencall/i/${token}`;
7522
7522
  }
7523
- var isReviewTitle, proPage, marketplacePage, roomPage;
7523
+ var isReviewTitle, proPage, roomPage;
7524
7524
  var init_world = __esm({
7525
7525
  "src/world.ts"() {
7526
7526
  "use strict";
7527
7527
  init_callTag();
7528
7528
  isReviewTitle = (title) => /^Expert review:/.test(title ?? "");
7529
7529
  proPage = (site, handle2) => `${site.replace(/\/+$/, "")}/pro/pros/${handle2}`;
7530
- marketplacePage = (site, slug) => `${site.replace(/\/+$/, "")}/pro/marketplaces/${slug}`;
7531
7530
  roomPage = (site, collectionId, pro) => `${site.replace(/\/+$/, "")}/pro/reviews/${collectionId}/with/${encodeURIComponent(pro.replace(/^@/, ""))}`;
7532
7531
  }
7533
7532
  });
@@ -8159,12 +8158,12 @@ var init_report = __esm({
8159
8158
 
8160
8159
  // ../../packages/openhands-sdk/src/rubric/survey.ts
8161
8160
  function surveyOptionsProblem(options) {
8162
- const L5 = SURVEY_LIMITS;
8161
+ const L4 = SURVEY_LIMITS;
8163
8162
  if (!Array.isArray(options)) return "A survey needs its options.";
8164
- if (options.length < L5.optionsMin || options.length > L5.optionsMax) return `A survey has ${L5.optionsMin} to ${L5.optionsMax} options.`;
8163
+ if (options.length < L4.optionsMin || options.length > L4.optionsMax) return `A survey has ${L4.optionsMin} to ${L4.optionsMax} options.`;
8165
8164
  const seen2 = /* @__PURE__ */ new Set();
8166
8165
  for (const option of options) {
8167
- if (typeof option !== "string" || !option.trim() || option.trim().length > L5.optionMax) return `Every option is 1 to ${L5.optionMax} characters.`;
8166
+ if (typeof option !== "string" || !option.trim() || option.trim().length > L4.optionMax) return `Every option is 1 to ${L4.optionMax} characters.`;
8168
8167
  if (/[\n\r]/.test(option)) return "An option is one line.";
8169
8168
  const key = option.trim().toLowerCase();
8170
8169
  if (seen2.has(key)) return `"${option.trim()}" is listed twice.`;
@@ -8389,31 +8388,31 @@ function chainOf(raw) {
8389
8388
  function blockOf(raw) {
8390
8389
  const block2 = raw;
8391
8390
  if (!block2 || typeof block2 !== "object") return null;
8392
- const L5 = CALL_LIMITS;
8391
+ const L4 = CALL_LIMITS;
8393
8392
  const picture2 = (one) => {
8394
8393
  const it2 = one;
8395
- return Boolean(it2) && https(it2.url) && line(it2.alt, L5.alt) && maybe(it2.caption, L5.caption);
8394
+ return Boolean(it2) && https(it2.url) && line(it2.alt, L4.alt) && maybe(it2.caption, L4.caption);
8396
8395
  };
8397
8396
  const file3 = (one) => {
8398
8397
  const it2 = one;
8399
- return Boolean(it2) && https(it2.url) && line(it2.name, L5.name) && maybe(it2.note, L5.note);
8398
+ return Boolean(it2) && https(it2.url) && line(it2.name, L4.name) && maybe(it2.note, L4.note);
8400
8399
  };
8401
8400
  const step = (one) => {
8402
8401
  const it2 = one;
8403
- return Boolean(it2) && line(it2.title, L5.stepTitle) && maybe(it2.text, L5.stepText);
8402
+ return Boolean(it2) && line(it2.title, L4.stepTitle) && maybe(it2.text, L4.stepText);
8404
8403
  };
8405
- const paragraph = (one) => line(one, L5.paragraph);
8404
+ const paragraph = (one) => line(one, L4.paragraph);
8406
8405
  const withCaption = (value, caption) => caption === void 0 ? value : { ...value, caption };
8407
8406
  const withNote = (value, note) => note === void 0 ? value : { ...value, note };
8408
8407
  switch (block2.kind) {
8409
8408
  case "story":
8410
- return someOf(block2.paragraphs, L5.paragraphs, paragraph) ? { kind: "story", paragraphs: [...block2.paragraphs] } : null;
8409
+ return someOf(block2.paragraphs, L4.paragraphs, paragraph) ? { kind: "story", paragraphs: [...block2.paragraphs] } : null;
8411
8410
  case "cover":
8412
- return https(block2.url) && line(block2.alt, L5.alt) && maybe(block2.caption, L5.caption) ? withCaption({ kind: "cover", url: block2.url, alt: block2.alt }, block2.caption) : null;
8411
+ return https(block2.url) && line(block2.alt, L4.alt) && maybe(block2.caption, L4.caption) ? withCaption({ kind: "cover", url: block2.url, alt: block2.alt }, block2.caption) : null;
8413
8412
  case "pictures":
8414
- return someOf(block2.items, L5.items, picture2) ? { kind: "pictures", items: block2.items.map((one) => withCaption({ url: one.url, alt: one.alt }, one.caption)) } : null;
8413
+ return someOf(block2.items, L4.items, picture2) ? { kind: "pictures", items: block2.items.map((one) => withCaption({ url: one.url, alt: one.alt }, one.caption)) } : null;
8415
8414
  case "diagram":
8416
- if (!line(block2.title, L5.title) || !someOf(block2.steps, L5.steps, step) || !(block2.source === void 0 || lines(block2.source, L5.source))) return null;
8415
+ if (!line(block2.title, L4.title) || !someOf(block2.steps, L4.steps, step) || !(block2.source === void 0 || lines(block2.source, L4.source))) return null;
8417
8416
  return {
8418
8417
  kind: "diagram",
8419
8418
  title: block2.title,
@@ -8421,29 +8420,29 @@ function blockOf(raw) {
8421
8420
  ...block2.source === void 0 ? {} : { source: block2.source }
8422
8421
  };
8423
8422
  case "data":
8424
- return line(block2.title, L5.title) && lines(block2.csv, L5.csv) && maybe(block2.note, L5.note) ? withNote({ kind: "data", title: block2.title, csv: block2.csv }, block2.note) : null;
8423
+ return line(block2.title, L4.title) && lines(block2.csv, L4.csv) && maybe(block2.note, L4.note) ? withNote({ kind: "data", title: block2.title, csv: block2.csv }, block2.note) : null;
8425
8424
  case "files":
8426
- return someOf(block2.items, L5.items, file3) ? { kind: "files", items: block2.items.map((one) => withNote({ url: one.url, name: one.name }, one.note)) } : null;
8425
+ return someOf(block2.items, L4.items, file3) ? { kind: "files", items: block2.items.map((one) => withNote({ url: one.url, name: one.name }, one.note)) } : null;
8427
8426
  case "start":
8428
- return lines(block2.prompt, L5.start) ? { kind: "start", prompt: block2.prompt } : null;
8427
+ return lines(block2.prompt, L4.start) ? { kind: "start", prompt: block2.prompt } : null;
8429
8428
  }
8430
8429
  return null;
8431
8430
  }
8432
8431
  function callOf(raw) {
8433
8432
  const call2 = raw;
8434
8433
  if (!call2 || typeof call2 !== "object") return null;
8435
- const L5 = CALL_LIMITS;
8434
+ const L4 = CALL_LIMITS;
8436
8435
  if (typeof call2.slug !== "string" || !CALL_SLUG.test(call2.slug)) return null;
8437
8436
  if (!CALL_LEGS.includes(call2.leg)) return null;
8438
- if (!line(call2.title, L5.title) || !line(call2.lede, L5.lede) || !line(call2.poster, L5.poster)) return null;
8439
- if (!Array.isArray(call2.points) || call2.points.length === 0 || call2.points.length > L5.lines || !call2.points.every((one) => finite(one) && one >= 0 && one <= 100)) 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;
8440
8439
  const money2 = call2.money;
8441
8440
  if (!money2 || typeof money2 !== "object") return null;
8442
8441
  if (!amount(money2.prize) || !whole(money2.runnersN, 0, 5) || !amount(money2.runnersEach) || !amount(money2.entryEach) || !whole(money2.entryUpTo, 1, 1e4)) return null;
8443
8442
  const share = call2.share;
8444
8443
  if (share !== void 0 && (!share || typeof share !== "object" || !nonNegative(share.network) || !nonNegative(share.node) || share.network + share.node >= 100)) return null;
8445
- const sponsor = call2.sponsor;
8446
- if (sponsor !== void 0 && (!sponsor || typeof sponsor !== "object" || typeof sponsor.slug !== "string" || !CALL_SLUG.test(sponsor.slug) || !line(sponsor.name, L5.sponsorName) || typeof sponsor.node !== "string" || !ENTITY_DID.test(sponsor.node))) return null;
8444
+ const named = call2.sponsor;
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;
8447
8446
  if (!date5(call2.closes) || !date5(call2.drop) || !date5(call2.pick)) return null;
8448
8447
  let legs;
8449
8448
  if (call2.legs !== void 0) {
@@ -8457,7 +8456,7 @@ function callOf(raw) {
8457
8456
  legs[name8] = id;
8458
8457
  }
8459
8458
  }
8460
- if (!Array.isArray(call2.blocks) || call2.blocks.length > L5.blocks) return null;
8459
+ if (!Array.isArray(call2.blocks) || call2.blocks.length > L4.blocks) return null;
8461
8460
  const blocks = call2.blocks.map(blockOf);
8462
8461
  if (blocks.some((block2) => block2 === null)) return null;
8463
8462
  let review = null;
@@ -8465,11 +8464,11 @@ function callOf(raw) {
8465
8464
  if (call2.kind !== "review" || call2.mode !== "hire") return null;
8466
8465
  const subject = call2.subject;
8467
8466
  if (subject !== void 0) {
8468
- if (!subject || typeof subject !== "object" || !line(subject.name, L5.subjectName)) return null;
8469
- if (subject.version !== void 0 && !line(subject.version, L5.version)) return null;
8470
- if (subject.where !== void 0 && !line(subject.where, L5.where)) return null;
8467
+ if (!subject || typeof subject !== "object" || !line(subject.name, L4.subjectName)) return null;
8468
+ if (subject.version !== void 0 && !line(subject.version, L4.version)) return null;
8469
+ if (subject.where !== void 0 && !line(subject.where, L4.where)) return null;
8471
8470
  }
8472
- if (call2.scenarios !== void 0 && (!Array.isArray(call2.scenarios) || call2.scenarios.length === 0 || call2.scenarios.length > L5.scenarios || !call2.scenarios.every((one) => line(one, L5.scenario)))) return null;
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;
8473
8472
  review = {
8474
8473
  kind: "review",
8475
8474
  ...subject ? { subject: { name: subject.name, ...subject.version !== void 0 ? { version: subject.version } : {}, ...subject.where !== void 0 ? { where: subject.where } : {} } } : {},
@@ -27772,7 +27771,7 @@ function bech32Polymod(pre) {
27772
27771
  }
27773
27772
  return chk;
27774
27773
  }
27775
- function bechChecksum(prefix, words5, encodingConst = 1) {
27774
+ function bechChecksum(prefix, words4, encodingConst = 1) {
27776
27775
  const len = prefix.length;
27777
27776
  let chk = 1;
27778
27777
  for (let i = 0; i < len; i++) {
@@ -27784,7 +27783,7 @@ function bechChecksum(prefix, words5, encodingConst = 1) {
27784
27783
  chk = bech32Polymod(chk);
27785
27784
  for (let i = 0; i < len; i++)
27786
27785
  chk = bech32Polymod(chk) ^ prefix.charCodeAt(i) & 31;
27787
- for (let v of words5)
27786
+ for (let v of words4)
27788
27787
  chk = bech32Polymod(chk) ^ v;
27789
27788
  for (let i = 0; i < 6; i++)
27790
27789
  chk = bech32Polymod(chk);
@@ -27798,20 +27797,20 @@ function genBech32(encoding) {
27798
27797
  const fromWords = _words.decode;
27799
27798
  const toWords = _words.encode;
27800
27799
  const fromWordsUnsafe = unsafeWrapper(fromWords);
27801
- function encode29(prefix, words5, limit = 90) {
27800
+ function encode29(prefix, words4, limit = 90) {
27802
27801
  astr("bech32.encode prefix", prefix);
27803
- if (isBytes2(words5))
27804
- words5 = Array.from(words5);
27805
- anumArr("bech32.encode", words5);
27802
+ if (isBytes2(words4))
27803
+ words4 = Array.from(words4);
27804
+ anumArr("bech32.encode", words4);
27806
27805
  const plen = prefix.length;
27807
27806
  if (plen === 0)
27808
27807
  throw new TypeError(`Invalid prefix length ${plen}`);
27809
- const actualLength = plen + 7 + words5.length;
27808
+ const actualLength = plen + 7 + words4.length;
27810
27809
  if (limit !== false && actualLength > limit)
27811
27810
  throw new TypeError(`Length ${actualLength} exceeds limit ${limit}`);
27812
27811
  const lowered = prefix.toLowerCase();
27813
- const sum2 = bechChecksum(lowered, words5, ENCODING_CONST);
27814
- return `${lowered}1${BECH_ALPHABET.encode(words5)}${sum2}`;
27812
+ const sum2 = bechChecksum(lowered, words4, ENCODING_CONST);
27813
+ return `${lowered}1${BECH_ALPHABET.encode(words4)}${sum2}`;
27815
27814
  }
27816
27815
  function decode33(str6, limit = 90) {
27817
27816
  astr("bech32.decode input", str6);
@@ -27828,19 +27827,19 @@ function genBech32(encoding) {
27828
27827
  const data = lowered.slice(sepIndex + 1);
27829
27828
  if (data.length < 6)
27830
27829
  throw new Error("Data must be at least 6 characters long");
27831
- const words5 = BECH_ALPHABET.decode(data).slice(0, -6);
27832
- const sum2 = bechChecksum(prefix, words5, ENCODING_CONST);
27830
+ const words4 = BECH_ALPHABET.decode(data).slice(0, -6);
27831
+ const sum2 = bechChecksum(prefix, words4, ENCODING_CONST);
27833
27832
  if (!data.endsWith(sum2))
27834
27833
  throw new Error(`Invalid checksum in ${str6}: expected "${sum2}"`);
27835
- return { prefix, words: words5 };
27834
+ return { prefix, words: words4 };
27836
27835
  }
27837
27836
  const decodeUnsafe = unsafeWrapper(decode33);
27838
27837
  function decodeToBytes(str6) {
27839
- const { prefix, words: words5 } = decode33(str6, false);
27838
+ const { prefix, words: words4 } = decode33(str6, false);
27840
27839
  return {
27841
27840
  prefix,
27842
- words: words5,
27843
- bytes: fromWords(words5)
27841
+ words: words4,
27842
+ bytes: fromWords(words4)
27844
27843
  };
27845
27844
  }
27846
27845
  function encodeFromBytes(prefix, bytes3) {
@@ -35612,10 +35611,10 @@ function nfkd(str6) {
35612
35611
  }
35613
35612
  function normalize2(str6) {
35614
35613
  const norm = nfkd(str6);
35615
- const words5 = norm.split(" ");
35616
- if (![12, 15, 18, 21, 24].includes(words5.length))
35614
+ const words4 = norm.split(" ");
35615
+ if (![12, 15, 18, 21, 24].includes(words4.length))
35617
35616
  throw new Error("Invalid mnemonic");
35618
- return { nfkd: norm, words: words5 };
35617
+ return { nfkd: norm, words: words4 };
35619
35618
  }
35620
35619
  function aentropy(ent) {
35621
35620
  abytes4(ent);
@@ -35638,15 +35637,15 @@ function getCoder(wordlist2) {
35638
35637
  return utils2.chain(utils2.checksum(1, calcChecksum), utils2.radix2(11, true), utils2.alphabet(wordlist2));
35639
35638
  }
35640
35639
  function mnemonicToEntropy(mnemonic, wordlist2) {
35641
- const { words: words5 } = normalize2(mnemonic);
35642
- const entropy = getCoder(wordlist2).decode(words5);
35640
+ const { words: words4 } = normalize2(mnemonic);
35641
+ const entropy = getCoder(wordlist2).decode(words4);
35643
35642
  aentropy(entropy);
35644
35643
  return entropy;
35645
35644
  }
35646
35645
  function entropyToMnemonic(entropy, wordlist2) {
35647
35646
  aentropy(entropy);
35648
- const words5 = getCoder(wordlist2).encode(entropy);
35649
- return words5.join(isJapanese(wordlist2) ? "\u3000" : " ");
35647
+ const words4 = getCoder(wordlist2).encode(entropy);
35648
+ return words4.join(isJapanese(wordlist2) ? "\u3000" : " ");
35650
35649
  }
35651
35650
  function validateMnemonic(mnemonic, wordlist2) {
35652
35651
  try {
@@ -39961,15 +39960,15 @@ function poly(field2, roots, create11, fft, length3) {
39961
39960
  };
39962
39961
  const checkLength = (a, b) => {
39963
39962
  checkPoly("a", a);
39964
- const L5 = a.length;
39963
+ const L4 = a.length;
39965
39964
  if (b !== void 0) {
39966
39965
  checkPoly("b", b);
39967
- if (b.length !== L5)
39968
- throw new Error(`poly: mismatched lengths ${L5} vs ${b.length}`);
39966
+ if (b.length !== L4)
39967
+ throw new Error(`poly: mismatched lengths ${L4} vs ${b.length}`);
39969
39968
  }
39970
- if (length3 !== void 0 && L5 !== length3)
39971
- throw new Error(`poly: expected fixed length ${length3}, got ${L5}`);
39972
- return L5;
39969
+ if (length3 !== void 0 && L4 !== length3)
39970
+ throw new Error(`poly: expected fixed length ${length3}, got ${L4}`);
39971
+ return L4;
39973
39972
  };
39974
39973
  function findOmegaIndex(x, n, brp = false, weights) {
39975
39974
  if (!isPowerOfTwo(n))
@@ -40124,11 +40123,11 @@ function poly(field2, roots, create11, fft, length3) {
40124
40123
  const idx = findOmegaIndex(x, a.length, brp);
40125
40124
  if (idx !== -1)
40126
40125
  return a[idx];
40127
- const L5 = this.basis(x, a.length, brp);
40126
+ const L4 = this.basis(x, a.length, brp);
40128
40127
  let acc = F.ZERO;
40129
40128
  for (let i = 0; i < a.length; i++)
40130
40129
  if (!F.is0(a[i]))
40131
- acc = F.add(acc, F.mul(a[i], L5[i]));
40130
+ acc = F.add(acc, F.mul(a[i], L4[i]));
40132
40131
  return acc;
40133
40132
  }
40134
40133
  },
@@ -40254,8 +40253,8 @@ function hash_to_field(msg, count2, options) {
40254
40253
  if (k < 0)
40255
40254
  throw new Error("hash_to_field: invalid k");
40256
40255
  const log2p = p.toString(2).length;
40257
- const L5 = Math.ceil((log2p + k) / 8);
40258
- const len_in_bytes = count2 * m * L5;
40256
+ const L4 = Math.ceil((log2p + k) / 8);
40257
+ const len_in_bytes = count2 * m * L4;
40259
40258
  let prb;
40260
40259
  if (expand2 === "xmd") {
40261
40260
  prb = expand_message_xmd(msg, DST, len_in_bytes, hash2);
@@ -40270,8 +40269,8 @@ function hash_to_field(msg, count2, options) {
40270
40269
  for (let i = 0; i < count2; i++) {
40271
40270
  const e = new Array(m);
40272
40271
  for (let j = 0; j < m; j++) {
40273
- const elm_offset = L5 * (j + i * m);
40274
- const tv = prb.subarray(elm_offset, elm_offset + L5);
40272
+ const elm_offset = L4 * (j + i * m);
40273
+ const tv = prb.subarray(elm_offset, elm_offset + L4);
40275
40274
  e[j] = mod2(os2ip(tv), p);
40276
40275
  }
40277
40276
  u[i] = e;
@@ -40613,18 +40612,18 @@ function createFROST(opts) {
40613
40612
  throw new Error("empty coefficients");
40614
40613
  return Poly.monomial.eval(coeffs, x);
40615
40614
  };
40616
- const deriveInterpolatingValue = (L5, xi) => {
40615
+ const deriveInterpolatingValue = (L4, xi) => {
40617
40616
  const err = "invalid parameters";
40618
- if (!L5.some((x) => Fn2.eql(x, xi)))
40617
+ if (!L4.some((x) => Fn2.eql(x, xi)))
40619
40618
  throw new Error(err);
40620
- const Lset = new Set(L5);
40621
- if (Lset.size !== L5.length)
40619
+ const Lset = new Set(L4);
40620
+ if (Lset.size !== L4.length)
40622
40621
  throw new Error(err);
40623
40622
  if (!Lset.has(xi))
40624
40623
  throw new Error(err);
40625
40624
  let num5 = Fn2.ONE;
40626
40625
  let den = Fn2.ONE;
40627
- for (const x of L5) {
40626
+ for (const x of L4) {
40628
40627
  if (Fn2.eql(x, xi))
40629
40628
  continue;
40630
40629
  num5 = Fn2.mul(num5, x);
@@ -42707,9 +42706,9 @@ var init_legacy = __esm({
42707
42706
  Id160 = /* @__PURE__ */ (() => Uint8Array.from(new Array(16).fill(0).map((_, i) => i)))();
42708
42707
  Pi160 = /* @__PURE__ */ (() => Id160.map((i) => (9 * i + 5) % 16))();
42709
42708
  idxLR = /* @__PURE__ */ (() => {
42710
- const L5 = [Id160];
42709
+ const L4 = [Id160];
42711
42710
  const R = [Pi160];
42712
- const res = [L5, R];
42711
+ const res = [L4, R];
42713
42712
  for (let i = 0; i < 4; i++)
42714
42713
  for (let j of res)
42715
42714
  j.push(j[i].map((k) => Rho160[k]));
@@ -43145,9 +43144,9 @@ function weierstrass(params, extraOpts = {}) {
43145
43144
  y = Fp2.neg(y);
43146
43145
  return { x, y };
43147
43146
  } else if (length3 === uncomp && head === 4) {
43148
- const L5 = Fp2.BYTES;
43149
- const x = Fp2.fromBytes(tail.subarray(0, L5));
43150
- const y = Fp2.fromBytes(tail.subarray(L5, L5 * 2));
43147
+ const L4 = Fp2.BYTES;
43148
+ const x = Fp2.fromBytes(tail.subarray(0, L4));
43149
+ const y = Fp2.fromBytes(tail.subarray(L4, L4 * 2));
43151
43150
  if (!isValidXY(x, y))
43152
43151
  throw new Error("bad point: is not on curve");
43153
43152
  return { x, y };
@@ -43672,9 +43671,9 @@ function ecdsa(Point2, hash2, ecdsaOpts = {}) {
43672
43671
  format11 = "compact";
43673
43672
  bytes3 = bytes3.subarray(1);
43674
43673
  }
43675
- const L5 = lengths.signature / 2;
43676
- const r = bytes3.subarray(0, L5);
43677
- const s = bytes3.subarray(L5, L5 * 2);
43674
+ const L4 = lengths.signature / 2;
43675
+ const r = bytes3.subarray(0, L4);
43676
+ const s = bytes3.subarray(L4, L4 * 2);
43678
43677
  return new Signature3(Fn2.fromBytes(r), Fn2.fromBytes(s), recid);
43679
43678
  }
43680
43679
  static fromHex(hex5, format11) {
@@ -51744,7 +51743,7 @@ var require_minimal = __commonJS({
51744
51743
  configurable: true
51745
51744
  },
51746
51745
  name: {
51747
- get: function get3() {
51746
+ get: function get2() {
51748
51747
  return name8;
51749
51748
  },
51750
51749
  set: void 0,
@@ -112985,15 +112984,15 @@ var require_xstream = __commonJS({
112985
112984
  Merge2.prototype._start = function(out) {
112986
112985
  this.out = out;
112987
112986
  var s = this.insArr;
112988
- var L5 = s.length;
112989
- this.ac = L5;
112990
- for (var i = 0; i < L5; i++)
112987
+ var L4 = s.length;
112988
+ this.ac = L4;
112989
+ for (var i = 0; i < L4; i++)
112991
112990
  s[i]._add(this);
112992
112991
  };
112993
112992
  Merge2.prototype._stop = function() {
112994
112993
  var s = this.insArr;
112995
- var L5 = s.length;
112996
- for (var i = 0; i < L5; i++)
112994
+ var L4 = s.length;
112995
+ for (var i = 0; i < L4; i++)
112997
112996
  s[i]._remove(this);
112998
112997
  this.out = NO;
112999
112998
  };
@@ -113726,16 +113725,16 @@ var require_xstream = __commonJS({
113726
113725
  }
113727
113726
  Stream2.prototype._n = function(t) {
113728
113727
  var a = this._ils;
113729
- var L5 = a.length;
113728
+ var L4 = a.length;
113730
113729
  if (this._d)
113731
113730
  this._dl._n(t);
113732
- if (L5 == 1)
113731
+ if (L4 == 1)
113733
113732
  a[0]._n(t);
113734
- else if (L5 == 0)
113733
+ else if (L4 == 0)
113735
113734
  return;
113736
113735
  else {
113737
113736
  var b = cp(a);
113738
- for (var i = 0; i < L5; i++)
113737
+ for (var i = 0; i < L4; i++)
113739
113738
  b[i]._n(t);
113740
113739
  }
113741
113740
  };
@@ -113744,35 +113743,35 @@ var require_xstream = __commonJS({
113744
113743
  return;
113745
113744
  this._err = err;
113746
113745
  var a = this._ils;
113747
- var L5 = a.length;
113746
+ var L4 = a.length;
113748
113747
  this._x();
113749
113748
  if (this._d)
113750
113749
  this._dl._e(err);
113751
- if (L5 == 1)
113750
+ if (L4 == 1)
113752
113751
  a[0]._e(err);
113753
- else if (L5 == 0)
113752
+ else if (L4 == 0)
113754
113753
  return;
113755
113754
  else {
113756
113755
  var b = cp(a);
113757
- for (var i = 0; i < L5; i++)
113756
+ for (var i = 0; i < L4; i++)
113758
113757
  b[i]._e(err);
113759
113758
  }
113760
- if (!this._d && L5 == 0)
113759
+ if (!this._d && L4 == 0)
113761
113760
  throw this._err;
113762
113761
  };
113763
113762
  Stream2.prototype._c = function() {
113764
113763
  var a = this._ils;
113765
- var L5 = a.length;
113764
+ var L4 = a.length;
113766
113765
  this._x();
113767
113766
  if (this._d)
113768
113767
  this._dl._c();
113769
- if (L5 == 1)
113768
+ if (L4 == 1)
113770
113769
  a[0]._c();
113771
- else if (L5 == 0)
113770
+ else if (L4 == 0)
113772
113771
  return;
113773
113772
  else {
113774
113773
  var b = cp(a);
113775
- for (var i = 0; i < L5; i++)
113774
+ for (var i = 0; i < L4; i++)
113776
113775
  b[i]._c();
113777
113776
  }
113778
113777
  };
@@ -114764,7 +114763,7 @@ var require_http = __commonJS({
114764
114763
  }
114765
114764
  return res;
114766
114765
  }
114767
- async function http3(method, url4, headers, request, timeout3) {
114766
+ async function http3(method, url4, headers, request, timeout2) {
114768
114767
  const settings = {
114769
114768
  method,
114770
114769
  body: request ? JSON.stringify(request) : void 0,
@@ -114772,7 +114771,7 @@ var require_http = __commonJS({
114772
114771
  "Content-Type": "application/json",
114773
114772
  ...headers
114774
114773
  },
114775
- signal: timeout3 ? AbortSignal.timeout(timeout3) : void 0
114774
+ signal: timeout2 ? AbortSignal.timeout(timeout2) : void 0
114776
114775
  };
114777
114776
  return fetch(url4, settings).then(filterBadStatus).then((res) => res.json());
114778
114777
  }
@@ -114903,7 +114902,7 @@ var require_httpclient = __commonJS({
114903
114902
  url;
114904
114903
  headers;
114905
114904
  timeout;
114906
- constructor(endpoint, timeout3) {
114905
+ constructor(endpoint, timeout2) {
114907
114906
  if (typeof endpoint === "string") {
114908
114907
  if (!(0, rpcclient_1.hasProtocol)(endpoint)) {
114909
114908
  throw new Error("Endpoint URL is missing a protocol. Expected 'https://' or 'http://'.");
@@ -114913,7 +114912,7 @@ var require_httpclient = __commonJS({
114913
114912
  this.url = endpoint.url;
114914
114913
  this.headers = endpoint.headers;
114915
114914
  }
114916
- this.timeout = timeout3;
114915
+ this.timeout = timeout2;
114917
114916
  }
114918
114917
  disconnect() {
114919
114918
  }
@@ -117309,7 +117308,7 @@ var require_websocket = __commonJS({
117309
117308
  const isSecure = parsedUrl.protocol === "wss:" || parsedUrl.protocol === "https:";
117310
117309
  const defaultPort = isSecure ? 443 : 80;
117311
117310
  const key = randomBytes8(16).toString("base64");
117312
- const get3 = isSecure ? https4.get : http3.get;
117311
+ const get2 = isSecure ? https4.get : http3.get;
117313
117312
  let perMessageDeflate;
117314
117313
  opts.createConnection = isSecure ? tlsConnect : netConnect;
117315
117314
  opts.defaultPort = opts.defaultPort || defaultPort;
@@ -117377,7 +117376,7 @@ var require_websocket = __commonJS({
117377
117376
  options.headers.authorization = "Basic " + Buffer.from(opts.auth).toString("base64");
117378
117377
  }
117379
117378
  }
117380
- let req = websocket._req = get3(opts);
117379
+ let req = websocket._req = get2(opts);
117381
117380
  if (opts.timeout) {
117382
117381
  req.on("timeout", () => {
117383
117382
  abortHandshake(websocket, req, "Opening handshake has timed out");
@@ -118095,7 +118094,7 @@ var require_socketwrapper = __commonJS({
118095
118094
  openHandler;
118096
118095
  closeHandler;
118097
118096
  timeout;
118098
- constructor(url4, messageHandler, errorHandler, openHandler, closeHandler, timeout3 = 1e4) {
118097
+ constructor(url4, messageHandler, errorHandler, openHandler, closeHandler, timeout2 = 1e4) {
118099
118098
  this.connected = new Promise((resolve2, reject) => {
118100
118099
  this.connectedResolver = resolve2;
118101
118100
  this.connectedRejecter = reject;
@@ -118105,7 +118104,7 @@ var require_socketwrapper = __commonJS({
118105
118104
  this.errorHandler = errorHandler;
118106
118105
  this.openHandler = openHandler;
118107
118106
  this.closeHandler = closeHandler;
118108
- this.timeout = timeout3;
118107
+ this.timeout = timeout2;
118109
118108
  }
118110
118109
  /**
118111
118110
  * returns a promise that resolves when connection is open
@@ -118238,7 +118237,7 @@ var require_streamingsocket = __commonJS({
118238
118237
  events;
118239
118238
  eventProducerListener;
118240
118239
  socket;
118241
- constructor(url4, timeout3 = 1e4) {
118240
+ constructor(url4, timeout2 = 1e4) {
118242
118241
  this.socket = new socketwrapper_1.SocketWrapper(url4, (event) => {
118243
118242
  if (this.eventProducerListener) {
118244
118243
  this.eventProducerListener.next(event);
@@ -118256,7 +118255,7 @@ var require_streamingsocket = __commonJS({
118256
118255
  this.eventProducerListener.error("Socket was closed unclean");
118257
118256
  }
118258
118257
  }
118259
- }, timeout3);
118258
+ }, timeout2);
118260
118259
  this.connected = this.socket.connected;
118261
118260
  const eventProducer = {
118262
118261
  start: (listener) => this.eventProducerListener = listener,
@@ -118305,9 +118304,9 @@ var require_queueingstreamingsocket = __commonJS({
118305
118304
  eventProducerListener;
118306
118305
  connectionStatusProducer;
118307
118306
  reconnectedHandler;
118308
- constructor(url4, timeout3 = 1e4, reconnectedHandler) {
118307
+ constructor(url4, timeout2 = 1e4, reconnectedHandler) {
118309
118308
  this.url = url4;
118310
- this.timeout = timeout3;
118309
+ this.timeout = timeout2;
118311
118310
  this.reconnectedHandler = reconnectedHandler;
118312
118311
  const eventProducer = {
118313
118312
  start: (listener) => this.eventProducerListener = listener,
@@ -118411,13 +118410,13 @@ var require_reconnectingsocket = __commonJS({
118411
118410
  disconnected = false;
118412
118411
  timeoutIndex = 0;
118413
118412
  reconnectTimeout = null;
118414
- constructor(url4, timeout3 = 1e4, reconnectedHandler) {
118413
+ constructor(url4, timeout2 = 1e4, reconnectedHandler) {
118415
118414
  const eventProducer = {
118416
118415
  start: (listener) => this.eventProducerListener = listener,
118417
118416
  stop: () => this.eventProducerListener = void 0
118418
118417
  };
118419
118418
  this.events = xstream_1.Stream.create(eventProducer);
118420
- this.socket = new queueingstreamingsocket_1.QueueingStreamingSocket(url4, timeout3, reconnectedHandler);
118419
+ this.socket = new queueingstreamingsocket_1.QueueingStreamingSocket(url4, timeout2, reconnectedHandler);
118421
118420
  this.socket.events.subscribe({
118422
118421
  next: (event) => {
118423
118422
  if (this.eventProducerListener) {
@@ -236883,10 +236882,10 @@ var init_fromMm = __esm({
236883
236882
  if (!_EnglishMnemonic.mnemonicMatcher.test(mnemonic)) {
236884
236883
  throw new Error("Invalid mnemonic format");
236885
236884
  }
236886
- const words5 = mnemonic.split(" ");
236885
+ const words4 = mnemonic.split(" ");
236887
236886
  const allowedWordsLengths = [12, 15, 18, 21, 24];
236888
- if (allowedWordsLengths.indexOf(words5.length) === -1) {
236889
- throw new Error(`Invalid word count in mnemonic (allowed: ${allowedWordsLengths} got: ${words5.length})`);
236887
+ if (allowedWordsLengths.indexOf(words4.length) === -1) {
236888
+ throw new Error(`Invalid word count in mnemonic (allowed: ${allowedWordsLengths} got: ${words4.length})`);
236890
236889
  }
236891
236890
  if (!validateMnemonic(mnemonic, wordlist)) {
236892
236891
  throw new Error("Mnemonic is invalid.");
@@ -253861,14 +253860,14 @@ var require_follow_redirects = __commonJS({
253861
253860
  debug("options", options);
253862
253861
  return new RedirectableRequest(options, callback);
253863
253862
  }
253864
- function get3(input, options, callback) {
253863
+ function get2(input, options, callback) {
253865
253864
  var wrappedRequest = wrappedProtocol.request(input, options, callback);
253866
253865
  wrappedRequest.end();
253867
253866
  return wrappedRequest;
253868
253867
  }
253869
253868
  Object.defineProperties(wrappedProtocol, {
253870
253869
  request: { value: request, configurable: true, enumerable: true, writable: true },
253871
- get: { value: get3, configurable: true, enumerable: true, writable: true }
253870
+ get: { value: get2, configurable: true, enumerable: true, writable: true }
253872
253871
  });
253873
253872
  });
253874
253873
  return exports2;
@@ -255712,8 +255711,8 @@ var init_http2 = __esm({
255712
255711
  boundSockets.clear();
255713
255712
  });
255714
255713
  if (own2("timeout")) {
255715
- const timeout3 = parseInt(own2("timeout"), 10);
255716
- if (Number.isNaN(timeout3)) {
255714
+ const timeout2 = parseInt(own2("timeout"), 10);
255715
+ if (Number.isNaN(timeout2)) {
255717
255716
  abort(
255718
255717
  new AxiosError_default(
255719
255718
  "error trying to parse `config.timeout` to int",
@@ -255728,10 +255727,10 @@ var init_http2 = __esm({
255728
255727
  if (isDone) return;
255729
255728
  abort(createTimeoutError());
255730
255729
  };
255731
- if (isNativeTransport && timeout3 > 0) {
255732
- connectPhaseTimer = setTimeout(handleTimeout, timeout3);
255730
+ if (isNativeTransport && timeout2 > 0) {
255731
+ connectPhaseTimer = setTimeout(handleTimeout, timeout2);
255733
255732
  }
255734
- req.setTimeout(timeout3, handleTimeout);
255733
+ req.setTimeout(timeout2, handleTimeout);
255735
255734
  } else {
255736
255735
  req.setTimeout(0);
255737
255736
  }
@@ -256249,9 +256248,9 @@ var init_composeSignals = __esm({
256249
256248
  init_CanceledError();
256250
256249
  init_AxiosError();
256251
256250
  init_utils7();
256252
- composeSignals = (signals, timeout3) => {
256251
+ composeSignals = (signals, timeout2) => {
256253
256252
  signals = signals ? signals.filter(Boolean) : [];
256254
- if (!timeout3 && !signals.length) {
256253
+ if (!timeout2 && !signals.length) {
256255
256254
  return;
256256
256255
  }
256257
256256
  const controller = new AbortController();
@@ -256266,10 +256265,10 @@ var init_composeSignals = __esm({
256266
256265
  );
256267
256266
  }
256268
256267
  };
256269
- let timer = timeout3 && setTimeout(() => {
256268
+ let timer = timeout2 && setTimeout(() => {
256270
256269
  timer = null;
256271
- onabort(new AxiosError_default(`timeout of ${timeout3}ms exceeded`, AxiosError_default.ETIMEDOUT));
256272
- }, timeout3);
256270
+ onabort(new AxiosError_default(`timeout of ${timeout2}ms exceeded`, AxiosError_default.ETIMEDOUT));
256271
+ }, timeout2);
256273
256272
  const unsubscribe = () => {
256274
256273
  if (!signals) {
256275
256274
  return;
@@ -256514,7 +256513,7 @@ var init_fetch = __esm({
256514
256513
  data,
256515
256514
  signal,
256516
256515
  cancelToken,
256517
- timeout: timeout3,
256516
+ timeout: timeout2,
256518
256517
  onDownloadProgress,
256519
256518
  onUploadProgress,
256520
256519
  responseType,
@@ -256531,7 +256530,7 @@ var init_fetch = __esm({
256531
256530
  responseType = responseType ? (responseType + "").toLowerCase() : "text";
256532
256531
  let composedSignal = composeSignals_default(
256533
256532
  [signal, cancelToken && cancelToken.toAbortSignal()],
256534
- timeout3
256533
+ timeout2
256535
256534
  );
256536
256535
  let request = null;
256537
256536
  const unsubscribe = composedSignal && composedSignal.unsubscribe && (() => {
@@ -258586,6 +258585,10 @@ function loadSession() {
258586
258585
  if (!raw) return null;
258587
258586
  const parsed = JSON.parse(raw);
258588
258587
  if (!parsed.address) return null;
258588
+ if (parsed.matrix && "mnemonic" in parsed.matrix) {
258589
+ delete parsed.matrix.mnemonic;
258590
+ window.localStorage.setItem(KEY, JSON.stringify(parsed));
258591
+ }
258589
258592
  return kindOf2(parsed) === "passkey" ? parsed.credentialId && parsed.authenticatorId ? parsed : null : parsed;
258590
258593
  } catch {
258591
258594
  return null;
@@ -260227,8 +260230,8 @@ async function readPrivateAnswer(args) {
260227
260230
  try {
260228
260231
  const envelope = JSON.parse(new TextDecoder().decode(bytes3));
260229
260232
  const names = (Array.isArray(envelope.files) ? envelope.files : []).map((one) => one?.name).filter((name8) => typeof name8 === "string");
260230
- const words5 = typeof envelope.deliverable === "string" ? envelope.deliverable : "";
260231
- return [words5, names.length ? `Files kept privately: ${names.join(", ")}` : ""].filter(Boolean).join("\n\n") || "failed";
260233
+ const words4 = typeof envelope.deliverable === "string" ? envelope.deliverable : "";
260234
+ return [words4, names.length ? `Files kept privately: ${names.join(", ")}` : ""].filter(Boolean).join("\n\n") || "failed";
260232
260235
  } catch {
260233
260236
  return "failed";
260234
260237
  }
@@ -260686,11 +260689,11 @@ async function publishJson(doc, label = "document") {
260686
260689
  }
260687
260690
  async function withinDeadline(task, ms2, label) {
260688
260691
  let deadline;
260689
- const timeout3 = new Promise((_, reject) => {
260692
+ const timeout2 = new Promise((_, reject) => {
260690
260693
  deadline = setTimeout(() => reject(new Error(`${label} timed out after ${ms2} ms`)), ms2);
260691
260694
  });
260692
260695
  try {
260693
- return await Promise.race([task, timeout3]);
260696
+ return await Promise.race([task, timeout2]);
260694
260697
  } finally {
260695
260698
  clearTimeout(deadline);
260696
260699
  }
@@ -260760,9 +260763,9 @@ function wastesOf(assessment) {
260760
260763
  return kept;
260761
260764
  }
260762
260765
  function listSays(wastes) {
260763
- const words5 = wastes.map((key) => WASTE[key].says);
260764
- if (words5.length <= 1) return words5[0] ?? "";
260765
- return `${words5.slice(0, -1).join(", ")} and ${words5[words5.length - 1]}`;
260766
+ const words4 = wastes.map((key) => WASTE[key].says);
260767
+ if (words4.length <= 1) return words4[0] ?? "";
260768
+ return `${words4.slice(0, -1).join(", ")} and ${words4[words4.length - 1]}`;
260766
260769
  }
260767
260770
  function isAssessment(value) {
260768
260771
  const doc = value;
@@ -262920,11 +262923,11 @@ async function readAllowanceBase(granter, agent, denom = askDenom()) {
262920
262923
  return 0;
262921
262924
  })();
262922
262925
  let deadline;
262923
- const timeout3 = new Promise((_, reject) => {
262926
+ const timeout2 = new Promise((_, reject) => {
262924
262927
  deadline = setTimeout(() => reject(new Error(`allowance read for ${granter.slice(0, 12)}\u2026 timed out`)), 8e3);
262925
262928
  });
262926
262929
  try {
262927
- return await Promise.race([asked, timeout3]);
262930
+ return await Promise.race([asked, timeout2]);
262928
262931
  } finally {
262929
262932
  clearTimeout(deadline);
262930
262933
  }
@@ -263500,12 +263503,6 @@ function callChecker(network2, review, deployment2) {
263500
263503
  function missingOf(fields, ctx) {
263501
263504
  const out = [];
263502
263505
  const review = fields.kind === "review";
263503
- if (review && !fields.sponsor)
263504
- out.push({
263505
- field: "sponsor",
263506
- question: `Which Zone is this pro ask through? ${ctx.marketplaces ? `On asks.world today: ${ctx.marketplaces}.` : "list_marketplaces names them."} The pros you invite are LinkedIn verified, and it earns the Zone's share of each approved report. Ask the person, even when there is one.`,
263507
- example: '"ixo"'
263508
- });
263509
263506
  if (!fields.title) out.push({ field: "title", question: review ? "What is being reviewed, as one sentence a pro reads first?" : "What is the call, in one sentence?", example: review ? "Try Qi Portal 2.3 as a first-time project owner and tell us where it fails" : "How should a city pay strangers to fix what they find?" });
263510
263507
  if (review && !fields.subject) out.push({ field: "subject", question: "What is reviewed: its name, the version to test, and where a pro finds it (a public address). Put test accounts and anything private in the invitation, not here: the pro ask is readable by everyone on its list.", example: '{ "name": "Qi Portal", "version": "2.3.0", "where": "https://staging.qi.space" }' });
263511
263508
  if (review && !fields.scenarios?.length) out.push({ field: "scenarios", question: "The scenarios to try, one line each, up to eight: the tasks a real user comes to do. Every report must cover each with a step.", example: '["Sign up with the invite link on a phone that has never seen the app", "Create a project and add two members", "Export the project and open it on a laptop"]' });
@@ -263583,7 +263580,7 @@ function blocksOf(fields) {
263583
263580
  else if (fields.kind === "review") blocks.push({ kind: "start", prompt: reviewStart(fields.title) });
263584
263581
  return blocks;
263585
263582
  }
263586
- function callOfDraft(draft, poster, dates, legs, share, sponsor) {
263583
+ function callOfDraft(draft, poster, dates, legs, share) {
263587
263584
  const f = draft.fields;
263588
263585
  if (!isReady(f) || !f.money) throw new Error("the draft is not ready to post");
263589
263586
  return {
@@ -263596,7 +263593,6 @@ function callOfDraft(draft, poster, dates, legs, share, sponsor) {
263596
263593
  points: linesOf(f).map(() => 100 / L2.lines),
263597
263594
  money: f.mode === "hire" ? { ...f.money, prize: 0, runnersN: 0, runnersEach: 0 } : f.money,
263598
263595
  ...share ? { share: { network: share.network, node: share.node } } : {},
263599
- ...sponsor ? { sponsor: { slug: sponsor.slug, name: sponsor.name, node: sponsor.node } } : {},
263600
263596
  ...dates,
263601
263597
  ...legs && Object.keys(legs).length ? { legs } : {},
263602
263598
  blocks: blocksOf(f)
@@ -263628,7 +263624,7 @@ function legTerms(draft, leg, ctx) {
263628
263624
  const review = draft.fields.kind === "review";
263629
263625
  return {
263630
263626
  ...callEntriesTerms({
263631
- call: callOfDraft(draft, ctx.poster, ctx.dates, legs, ctx.share, ctx.sponsor),
263627
+ call: callOfDraft(draft, ctx.poster, ctx.dates, legs, ctx.share),
263632
263628
  lines: linesOf(draft.fields),
263633
263629
  judge: ctx.oracle,
263634
263630
  access: access2,
@@ -263638,12 +263634,12 @@ function legTerms(draft, leg, ctx) {
263638
263634
  via: "mcp"
263639
263635
  };
263640
263636
  }
263641
- return { ...callPickTerms({ call: callOfDraft(draft, ctx.poster, ctx.dates, void 0, ctx.share, ctx.sponsor), leg, access: access2 }), via: "mcp" };
263637
+ return { ...callPickTerms({ call: callOfDraft(draft, ctx.poster, ctx.dates, void 0, ctx.share), leg, access: access2 }), via: "mcp" };
263642
263638
  }
263643
263639
  function callPlan(draft, ctx, now3 = Date.now()) {
263644
263640
  if (callShares(draft.fields) !== Boolean(ctx.share)) throw new Error(ctx.share ? "only a private call carries the network's share" : "a private call is priced with the network's share: read the split first (callShare)");
263645
263641
  const dates = draft.dates ?? callDates(draft.fields.openDays, now3, draft.fields.mode === "hire" ? "hire" : void 0);
263646
- const entries2 = legTerms(draft, "entries", { poster: ctx.poster, dates, oracle: { kind: "oracle", address: ctx.oracle }, share: ctx.share, sponsor: ctx.sponsor });
263642
+ const entries2 = legTerms(draft, "entries", { poster: ctx.poster, dates, oracle: { kind: "oracle", address: ctx.oracle }, share: ctx.share });
263647
263643
  const checkBase = ctx.checkerLegBase(entries2);
263648
263644
  const legs = legOrder(draft.fields).map((leg) => legPlan(draft.fields, leg, checkBase, ctx.share, ctx.feeInReward));
263649
263645
  return { legs, totalBase: legs.reduce((sum2, one) => sum2 + one.escrowBase, 0), dates, share: ctx.share };
@@ -263683,7 +263679,7 @@ __export(feeLine_exports, {
263683
263679
  feeLine: () => feeLine
263684
263680
  });
263685
263681
  function feeLine(args) {
263686
- const { split: split3, sponsorName, symbol: symbol2 } = args;
263682
+ const { split: split3, symbol: symbol2 } = args;
263687
263683
  const leg = grossFor(Math.round(args.net * 1e6), split3);
263688
263684
  const receives = `Each pro receives ${amountWords(args.net, symbol2)}.`;
263689
263685
  const locked2 = `${amountWords(leg / 1e6, symbol2)} is locked per report`;
@@ -263691,8 +263687,7 @@ function feeLine(args) {
263691
263687
  if (args.network === "mainnet") return `${receives} Nothing is taken on top: ${locked2}.`;
263692
263688
  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.`;
263693
263689
  }
263694
- const part = (value) => value > 0 ? percentWords(value) : "nothing";
263695
- return `${receives} On top, the network takes ${part(split3.network)} and ${sponsorName}, the Zone, ${part(split3.node)}: ${locked2}.`;
263690
+ return `${receives} ${locked2}: ${percentWords(split3.network + split3.node)} on top of what the pro receives.`;
263696
263691
  }
263697
263692
  var MAINNET_SPLIT, percentWords, amountWords;
263698
263693
  var init_feeLine = __esm({
@@ -263769,11 +263764,10 @@ function callReadout(terms, ctx) {
263769
263764
  const review = call2.kind === "review";
263770
263765
  const shared = call2.share ? sharedPay(m.entryEach, call2.share) : null;
263771
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"}` : "";
263772
- const proMoney = call2.sponsor && call2.share && hire ? `Money: ${feeLine({ split: call2.share, sponsorName: call2.sponsor.name, 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;
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;
263773
263768
  const out = [
263774
263769
  `${review ? "Pro ask" : hire ? "Hiring call" : "Open call"} "${call2.slug}" \xB7 posted by ${call2.poster} \xB7 ${stageWords(call2, ctx.now)}`,
263775
263770
  ...review && ctx.site ? [`Its page: ${ctx.site.replace(/\/+$/, "")}/pro/reviews/${ctx.id}`] : [],
263776
- ...call2.sponsor ? [`Zone: ${call2.sponsor.name} (sponsor "${call2.sponsor.slug}"), which hosts this pro ask; its pros are LinkedIn verified.`] : [],
263777
263771
  call2.title,
263778
263772
  call2.lede,
263779
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.`] : [],
@@ -263814,7 +263808,6 @@ __export(call_exports2, {
263814
263808
  INVITES_MAX: () => INVITES_MAX,
263815
263809
  InFlightError: () => InFlightError,
263816
263810
  PRO_ASK_INVITE_ONLY: () => PRO_ASK_INVITE_ONLY,
263817
- PRO_ASK_NEEDS_MARKETPLACE: () => PRO_ASK_NEEDS_MARKETPLACE,
263818
263811
  PostRefused: () => PostRefused,
263819
263812
  SETTLE_MS: () => SETTLE_MS,
263820
263813
  SHARE_UNREAD: () => SHARE_UNREAD,
@@ -264013,10 +264006,6 @@ function mergeDraft(draft, input, now3 = /* @__PURE__ */ new Date()) {
264013
264006
  if (fields.kind === "review" && fields.mode === void 0) fields.mode = "hire";
264014
264007
  if (fields.kind === "review" && fields.access === void 0) fields.access = "invite";
264015
264008
  }
264016
- if (input.sponsor !== void 0) {
264017
- const slug = input.sponsor.trim().toLowerCase();
264018
- take("sponsor", slug, fields.kind !== "review" ? 'sponsor names the Zone of a pro ask (kind "review"); an open call has none' : CALL_SLUG.test(slug) ? null : `"${slug.slice(0, 40)}" is not a Zone's name: list_marketplaces gives each one's`);
264019
- }
264020
264009
  if (input.subject !== void 0) {
264021
264010
  const subject = { name: oneLine(input.subject.name), ...input.subject.version?.trim() ? { version: oneLine(input.subject.version) } : {}, ...input.subject.where?.trim() ? { where: oneLine(input.subject.where) } : {} };
264022
264011
  take("subject", subject, within(subject.name, L3.subjectName, "What is reviewed") ?? (subject.version ? within(subject.version, L3.version, "The version") : null) ?? (subject.where ? within(subject.where, L3.where, "Where it is") : null));
@@ -264162,9 +264151,9 @@ async function settleInFlight(slug, lookup, now3 = Date.now(), txs = chainCheck)
264162
264151
  const draft = readDraft(slug);
264163
264152
  const inFlight2 = draft?.inFlight;
264164
264153
  if (!draft || !inFlight2) return null;
264165
- const words5 = `checking whether the earlier post of the ${inFlight2.leg === "runnersUp" ? "runners-up" : inFlight2.leg} leg (started ${inFlight2.startedAt}) landed`;
264154
+ const words4 = `checking whether the earlier post of the ${inFlight2.leg === "runnersUp" ? "runners-up" : inFlight2.leg} leg (started ${inFlight2.startedAt}) landed`;
264166
264155
  const seen2 = await settleMarker(inFlight2, lookup, now3, txs);
264167
- if (seen2.state === "pending") return { state: "pending", words: `Still ${words5}: ${seen2.why}. Nothing new was posted. Call post_call again in a minute.` };
264156
+ if (seen2.state === "pending") return { state: "pending", words: `Still ${words4}: ${seen2.why}. Nothing new was posted. Call post_call again in a minute.` };
264168
264157
  const at = new Date(now3).toISOString();
264169
264158
  if (seen2.state === "landed") {
264170
264159
  const next2 = { ...draft, updatedAt: at, inFlight: null, posted: { ...draft.posted, [inFlight2.leg]: { id: seen2.id, at, ...inFlight2.txHash ? { tx: inFlight2.txHash } : {} } } };
@@ -264241,8 +264230,6 @@ async function postNextLeg(slug, ctx) {
264241
264230
  async function postNextLegNow(slug, ctx) {
264242
264231
  const found = readDraft(slug);
264243
264232
  if (!found) throw new Error(`no draft called "${slug}"`);
264244
- if (found.fields.kind === "review" && nextLeg(found) && (!found.fields.sponsor || !ctx.sponsor)) throw new PostRefused(`${PRO_ASK_NEEDS_MARKETPLACE} Nothing was posted.`);
264245
- if (ctx.sponsor && ctx.sponsor.slug !== found.fields.sponsor) throw new PostRefused(`Refused: the Zone resolved ("${ctx.sponsor.slug}") is not the one the draft names. Nothing was posted.`);
264246
264233
  if (!isReady(found.fields)) throw new Error("the draft is not ready to post");
264247
264234
  const settled = found.inFlight ? await settleInFlight(slug, ctx.lookup ?? indexLookup, ctx.now, ctx.txs) : null;
264248
264235
  if (settled?.state === "pending") throw new InFlightError(settled.words);
@@ -264258,7 +264245,7 @@ async function postNextLegNow(slug, ctx) {
264258
264245
  const priced = callShare(draft.fields, split3);
264259
264246
  if ("unread" in priced) throw new PostRefused(SHARE_UNREAD);
264260
264247
  const feeDenom = checkerFeeDenom2(network2());
264261
- const { legs, dates } = callPlan(draft, { poster: shortPoster, checkerLegBase: (terms2) => ctx.fee ? ctx.fee.base : ctx.perCheck ? 0 : checkerLegBase2(feeDenom, terms2, ctx.checkReward), oracle: ctx.checker, share: priced.share, feeInReward: Boolean(ctx.fee) || ctx.askDenom === feeDenom, sponsor: ctx.sponsor }, ctx.now);
264248
+ const { legs, dates } = callPlan(draft, { poster: shortPoster, checkerLegBase: (terms2) => ctx.fee ? ctx.fee.base : ctx.perCheck ? 0 : checkerLegBase2(feeDenom, terms2, ctx.checkReward), oracle: ctx.checker, share: priced.share, feeInReward: Boolean(ctx.fee) || ctx.askDenom === feeDenom }, ctx.now);
264262
264249
  if (settled?.state === "landed") {
264263
264250
  ctx.nudge?.("hire", settled.id);
264264
264251
  return { leg: settled.leg, id: settled.id, tx: null, plan: legs.find((one) => one.leg === settled.leg), terms: null, draft, resumed: true };
@@ -264270,7 +264257,7 @@ async function postNextLegNow(slug, ctx) {
264270
264257
  if (ctx.acting && legs.some((one) => one.feeBase > 0)) throw new Error(callTwoCoins);
264271
264258
  const plan = legs.find((one) => one.leg === leg);
264272
264259
  const oracle = { kind: "oracle", address: ctx.checker, rewardUixo: plan.checkBase || legs.find((one) => one.leg === "entries").checkBase };
264273
- const terms = legTerms(draft, leg, { poster: shortPoster, dates, oracle, approver: ctx.approver ?? null, share: priced.share, sponsor: ctx.sponsor });
264260
+ const terms = legTerms(draft, leg, { poster: shortPoster, dates, oracle, approver: ctx.approver ?? null, share: priced.share });
264274
264261
  const screen = await steps.screen(ctx.site, terms.task, terms);
264275
264262
  if (screen?.verdict === "refuse") throw new Error(refusedWords(screen.reason));
264276
264263
  await steps.fund(actor.address, ctx.site, ctx.acting?.principal);
@@ -264332,8 +264319,6 @@ async function postNextLegNow(slug, ctx) {
264332
264319
  doneMeans: published,
264333
264320
  /* The leg, not the quote: on a private call it is grossed up, and the approval leg carries the chain's split (openAskMessages). */
264334
264321
  amountUixo: plan.legBase,
264335
- /* A pro ask's entities are relayed by its marketplace's node, so the chain pays the marketplace the node share. */
264336
- ...ctx.sponsor ? { relayerNode: ctx.sponsor.node } : {},
264337
264322
  quota: plan.quota,
264338
264323
  days: legDays(dates, leg, ctx.now),
264339
264324
  denom: ctx.askDenom,
@@ -264383,7 +264368,7 @@ function confirms(said3, totalBase, symbol2) {
264383
264368
  const figure = said3.replace(/[$,\s]|USDC|PAY|IXO/gi, "");
264384
264369
  return /^\d+(\.\d+)?$/.test(figure) && Math.round(Number(figure) * MICRO5) === totalBase;
264385
264370
  }
264386
- var MICRO5, callsDir, fileOf, askInvitesFile, freshDraft, L3, ENTRIES_MAX, INVITES_MAX, INVITE_NOTE_MAX, ADDRESS2, HANDLE_ITEM, isInviteItem, PRO_ASK_INVITE_ONLY, PRO_ASK_NEEDS_MARKETPLACE, manyLines, overCap, callTwoCoins, SETTLE_MS, chainCheck, InFlightError, PostRefused, feeUnpaid, said2, indexLookupWith, indexLookup, posting, isAskPending, isTxFailed, tagOf, TESTNET_CALL_DEFAULTS, payWords;
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;
264387
264372
  var init_call2 = __esm({
264388
264373
  "src/call.ts"() {
264389
264374
  "use strict";
@@ -264418,8 +264403,7 @@ var init_call2 = __esm({
264418
264403
  ADDRESS2 = /^ixo1[a-z0-9]{38}$/;
264419
264404
  HANDLE_ITEM = /^@?[a-z][a-z0-9-]{2,29}$/;
264420
264405
  isInviteItem = (one) => one === "link" || ADDRESS2.test(one) || HANDLE_ITEM.test(one);
264421
- PRO_ASK_INVITE_ONLY = `A pro ask is by invitation only (access "invite"): its pros come from its Zone's roster`;
264422
- PRO_ASK_NEEDS_MARKETPLACE = "A pro ask names its Zone: call draft_call with sponsor.";
264406
+ PRO_ASK_INVITE_ONLY = 'A pro ask is by invitation only (access "invite").';
264423
264407
  manyLines = (value) => value.replace(/\r\n?/g, "\n").replace(/\t/g, ",").trim();
264424
264408
  overCap = (leg, capBase) => leg.escrowBase > capBase;
264425
264409
  callTwoCoins = "this call's reviews are held in review credit beside its rewards, and the connection's allowance covers the rewards only. Use a verifier that bills per check (Pay for reviews)";
@@ -264800,6 +264784,7 @@ __export(inviteProof_exports, {
264800
264784
  linkedinMessage: () => linkedinMessage,
264801
264785
  linkedinWords: () => linkedinWords,
264802
264786
  noticesMessage: () => noticesMessage,
264787
+ openToWork: () => openToWork,
264803
264788
  readAcceptMessage: () => readAcceptMessage,
264804
264789
  readAnswersMessage: () => readAnswersMessage,
264805
264790
  readApplyMessage: () => readApplyMessage,
@@ -264836,8 +264821,13 @@ __export(inviteProof_exports, {
264836
264821
  vetRequestWords: () => vetRequestWords,
264837
264822
  vetWords: () => vetWords,
264838
264823
  vettingMineMessage: () => vettingMineMessage,
264839
- vettingQueueMessage: () => vettingQueueMessage
264824
+ vettingQueueMessage: () => vettingQueueMessage,
264825
+ withListed: () => withListed
264840
264826
  });
264827
+ function withListed(profile, listed) {
264828
+ const { listed: _was, ...rest } = profile;
264829
+ return listed ? rest : { ...rest, listed: false };
264830
+ }
264841
264831
  function readHandProfile(raw) {
264842
264832
  const it2 = raw;
264843
264833
  if (!it2 || typeof it2 !== "object") return { problem: "a page is an object" };
@@ -264873,37 +264863,37 @@ function readHandProfile(raw) {
264873
264863
  const invitable = it2.invitable === void 0 ? true : it2.invitable;
264874
264864
  if (typeof invitable !== "boolean") return { problem: "invitable is true or false" };
264875
264865
  if (it2.listed !== void 0 && typeof it2.listed !== "boolean") return { problem: "listed is true or false" };
264876
- const L5 = HAND_LIMITS;
264866
+ const L4 = HAND_LIMITS;
264877
264867
  const pictureUrl = (value, what) => value === void 0 || value === null || value === "" ? void 0 : https3(value) ? value : { problem: `${what} is an https address` };
264878
264868
  const avatar = pictureUrl(it2.avatar, "avatar");
264879
264869
  if (avatar && typeof avatar === "object") return avatar;
264880
264870
  const banner = pictureUrl(it2.banner, "banner");
264881
264871
  if (banner && typeof banner === "object") return banner;
264882
- const location = it2.location === void 0 || it2.location === null || it2.location === "" ? void 0 : oneLine2(it2.location, L5.location);
264883
- if (location === null) return { problem: `location is one line, up to ${L5.location} characters` };
264884
- const timezone = it2.timezone === void 0 || it2.timezone === null || it2.timezone === "" ? void 0 : oneLine2(it2.timezone, L5.timezone);
264872
+ const location = it2.location === void 0 || it2.location === null || it2.location === "" ? void 0 : oneLine2(it2.location, L4.location);
264873
+ if (location === null) return { problem: `location is one line, up to ${L4.location} characters` };
264874
+ const timezone = it2.timezone === void 0 || it2.timezone === null || it2.timezone === "" ? void 0 : oneLine2(it2.timezone, L4.timezone);
264885
264875
  if (timezone === null || timezone && !/^[A-Za-z_+\-\/0-9: ]{1,64}$/.test(timezone)) return { problem: "timezone is an IANA name, e.g. Europe/Ljubljana, or UTC+2" };
264886
264876
  const when3 = (value) => typeof value === "string" && /^\d{4}(-(0[1-9]|1[0-2]))?$/.test(value);
264887
264877
  const experience = [];
264888
264878
  if (it2.experience !== void 0 && it2.experience !== null) {
264889
- if (!Array.isArray(it2.experience) || it2.experience.length > L5.experience) return { problem: `experience is up to ${L5.experience} rows` };
264879
+ if (!Array.isArray(it2.experience) || it2.experience.length > L4.experience) return { problem: `experience is up to ${L4.experience} rows` };
264890
264880
  for (const [at, raw2] of it2.experience.entries()) {
264891
- const title = oneLine2(raw2?.title, L5.title);
264892
- const org = oneLine2(raw2?.org, L5.org);
264881
+ const title = oneLine2(raw2?.title, L4.title);
264882
+ const org = oneLine2(raw2?.org, L4.org);
264893
264883
  if (!title || !org) return { problem: `experience row ${at + 1} needs a title and an org` };
264894
264884
  if (!when3(raw2?.from)) return { problem: `experience row ${at + 1}: from is "YYYY" or "YYYY-MM"` };
264895
264885
  if (!(raw2?.to === null || raw2?.to === void 0 || raw2?.to === "" || when3(raw2?.to))) return { problem: `experience row ${at + 1}: to is "YYYY", "YYYY-MM", or null for now` };
264896
- const where2 = raw2?.where === void 0 || raw2?.where === null || raw2?.where === "" ? void 0 : oneLine2(raw2.where, L5.where);
264886
+ const where2 = raw2?.where === void 0 || raw2?.where === null || raw2?.where === "" ? void 0 : oneLine2(raw2.where, L4.where);
264897
264887
  if (where2 === null) return { problem: `experience row ${at + 1}: where is one line` };
264898
264888
  let what;
264899
264889
  if (raw2?.what !== void 0 && raw2?.what !== null && raw2?.what !== "") {
264900
- if (typeof raw2.what !== "string" || raw2.what.length > L5.what) return { problem: `experience row ${at + 1}: what is up to ${L5.what} characters` };
264890
+ if (typeof raw2.what !== "string" || raw2.what.length > L4.what) return { problem: `experience row ${at + 1}: what is up to ${L4.what} characters` };
264901
264891
  what = raw2.what.replace(/\s+/g, " ").trim();
264902
264892
  }
264903
264893
  experience.push({ title, org, from: raw2.from, to: when3(raw2?.to) ? raw2.to : null, ...where2 ? { where: where2 } : {}, ...what ? { what } : {} });
264904
264894
  }
264905
264895
  }
264906
- const words5 = (value, max, each, what) => {
264896
+ const words4 = (value, max, each, what) => {
264907
264897
  if (value === void 0 || value === null) return [];
264908
264898
  if (!Array.isArray(value) || value.length > max) return { problem: `${what} is up to ${max} entries` };
264909
264899
  const out = [];
@@ -264914,16 +264904,16 @@ function readHandProfile(raw) {
264914
264904
  }
264915
264905
  return [...new Set(out)];
264916
264906
  };
264917
- const skills = words5(it2.skills, L5.skills, L5.skill, "skills");
264907
+ const skills = words4(it2.skills, L4.skills, L4.skill, "skills");
264918
264908
  if (!Array.isArray(skills)) return skills;
264919
- const languages = words5(it2.languages, L5.languages, L5.language, "languages");
264909
+ const languages = words4(it2.languages, L4.languages, L4.language, "languages");
264920
264910
  if (!Array.isArray(languages)) return languages;
264921
264911
  const education = [];
264922
264912
  if (it2.education !== void 0 && it2.education !== null) {
264923
- if (!Array.isArray(it2.education) || it2.education.length > L5.education) return { problem: `education is up to ${L5.education} rows` };
264913
+ if (!Array.isArray(it2.education) || it2.education.length > L4.education) return { problem: `education is up to ${L4.education} rows` };
264924
264914
  for (const [at, raw2] of it2.education.entries()) {
264925
- const title = oneLine2(raw2?.title, L5.title);
264926
- const org = oneLine2(raw2?.org, L5.org);
264915
+ const title = oneLine2(raw2?.title, L4.title);
264916
+ const org = oneLine2(raw2?.org, L4.org);
264927
264917
  if (!title || !org) return { problem: `education row ${at + 1} needs a title and an org` };
264928
264918
  if (!(raw2?.year === void 0 || raw2?.year === null || raw2?.year === "" || typeof raw2?.year === "string" && /^\d{4}$/.test(raw2.year))) return { problem: `education row ${at + 1}: year is "YYYY"` };
264929
264919
  education.push({ title, org, ...typeof raw2?.year === "string" && raw2.year ? { year: raw2.year } : {} });
@@ -264931,7 +264921,7 @@ function readHandProfile(raw) {
264931
264921
  }
264932
264922
  const blocks = [];
264933
264923
  if (it2.blocks !== void 0 && it2.blocks !== null) {
264934
- if (!Array.isArray(it2.blocks) || it2.blocks.length > L5.blocks) return { problem: `blocks is up to ${L5.blocks}` };
264924
+ if (!Array.isArray(it2.blocks) || it2.blocks.length > L4.blocks) return { problem: `blocks is up to ${L4.blocks}` };
264935
264925
  for (const [at, raw2] of it2.blocks.entries()) {
264936
264926
  const block2 = readHandBlock(raw2);
264937
264927
  if ("problem" in block2) return { problem: `block ${at + 1}: ${block2.problem}` };
@@ -264968,39 +264958,39 @@ function readHandProfile(raw) {
264968
264958
  function readHandBlock(raw) {
264969
264959
  const it2 = raw;
264970
264960
  if (!it2 || typeof it2 !== "object") return { problem: "a block is an object" };
264971
- const L5 = HAND_LIMITS;
264961
+ const L4 = HAND_LIMITS;
264972
264962
  switch (it2.kind) {
264973
264963
  case "story": {
264974
- if (!Array.isArray(it2.paragraphs) || it2.paragraphs.length === 0 || it2.paragraphs.length > L5.paragraphs) return { problem: `a story is 1 to ${L5.paragraphs} paragraphs` };
264964
+ if (!Array.isArray(it2.paragraphs) || it2.paragraphs.length === 0 || it2.paragraphs.length > L4.paragraphs) return { problem: `a story is 1 to ${L4.paragraphs} paragraphs` };
264975
264965
  const paragraphs = [];
264976
264966
  for (const one of it2.paragraphs) {
264977
- const line2 = oneLine2(one, L5.paragraph);
264978
- if (!line2) return { problem: `a paragraph is one line, up to ${L5.paragraph} characters` };
264967
+ const line2 = oneLine2(one, L4.paragraph);
264968
+ if (!line2) return { problem: `a paragraph is one line, up to ${L4.paragraph} characters` };
264979
264969
  paragraphs.push(line2);
264980
264970
  }
264981
264971
  return { block: { kind: "story", paragraphs } };
264982
264972
  }
264983
264973
  case "pictures": {
264984
- if (!Array.isArray(it2.items) || it2.items.length === 0 || it2.items.length > L5.items) return { problem: `pictures are 1 to ${L5.items}` };
264974
+ if (!Array.isArray(it2.items) || it2.items.length === 0 || it2.items.length > L4.items) return { problem: `pictures are 1 to ${L4.items}` };
264985
264975
  const items = [];
264986
264976
  for (const one of it2.items) {
264987
264977
  if (!https3(one?.url)) return { problem: "a picture's url is an https address" };
264988
- const alt = oneLine2(one?.alt, L5.alt);
264978
+ const alt = oneLine2(one?.alt, L4.alt);
264989
264979
  if (!alt) return { problem: "a picture needs words (alt)" };
264990
- const caption = one?.caption === void 0 || one?.caption === null || one?.caption === "" ? void 0 : oneLine2(one.caption, L5.caption);
264980
+ const caption = one?.caption === void 0 || one?.caption === null || one?.caption === "" ? void 0 : oneLine2(one.caption, L4.caption);
264991
264981
  if (caption === null) return { problem: "a caption is one line" };
264992
264982
  items.push({ url: one.url, alt, ...caption ? { caption } : {} });
264993
264983
  }
264994
264984
  return { block: { kind: "pictures", items } };
264995
264985
  }
264996
264986
  case "files": {
264997
- if (!Array.isArray(it2.items) || it2.items.length === 0 || it2.items.length > L5.items) return { problem: `files are 1 to ${L5.items}` };
264987
+ if (!Array.isArray(it2.items) || it2.items.length === 0 || it2.items.length > L4.items) return { problem: `files are 1 to ${L4.items}` };
264998
264988
  const items = [];
264999
264989
  for (const one of it2.items) {
265000
264990
  if (!https3(one?.url)) return { problem: "a file's url is an https address" };
265001
- const name8 = oneLine2(one?.name, L5.fileName);
264991
+ const name8 = oneLine2(one?.name, L4.fileName);
265002
264992
  if (!name8) return { problem: "a file needs a name" };
265003
- const note = one?.note === void 0 || one?.note === null || one?.note === "" ? void 0 : oneLine2(one.note, L5.note);
264993
+ const note = one?.note === void 0 || one?.note === null || one?.note === "" ? void 0 : oneLine2(one.note, L4.note);
265004
264994
  if (note === null) return { problem: "a file's note is one line" };
265005
264995
  items.push({ url: one.url, name: name8, ...note ? { note } : {} });
265006
264996
  }
@@ -265010,7 +265000,7 @@ function readHandBlock(raw) {
265010
265000
  return { problem: 'kind is "story", "pictures" or "files"' };
265011
265001
  }
265012
265002
  }
265013
- var HANDLE, RESERVED_HANDLES, HAND_LIMITS, DOES, RATE_UNITS, RATE_COINS, AVAILABILITY, oneLine2, https3;
265003
+ var HANDLE, RESERVED_HANDLES, HAND_LIMITS, DOES, RATE_UNITS, RATE_COINS, AVAILABILITY, oneLine2, https3, openToWork;
265014
265004
  var init_inviteProof = __esm({
265015
265005
  "../../packages/openhands-sdk/src/chain/inviteProof.ts"() {
265016
265006
  "use strict";
@@ -265098,6 +265088,7 @@ var init_inviteProof = __esm({
265098
265088
  return false;
265099
265089
  }
265100
265090
  };
265091
+ openToWork = (profile) => profile.invitable !== false && profile.availability === "open";
265101
265092
  }
265102
265093
  });
265103
265094
 
@@ -265105,6 +265096,7 @@ var init_inviteProof = __esm({
265105
265096
  var invites_exports = {};
265106
265097
  __export(invites_exports, {
265107
265098
  NOT_KNOWN_YET: () => NOT_KNOWN_YET,
265099
+ NOT_VERIFIED: () => NOT_VERIFIED,
265108
265100
  OFF_ROSTER: () => OFF_ROSTER,
265109
265101
  TERMS_UNREAD: () => TERMS_UNREAD,
265110
265102
  acceptInvitation: () => acceptInvitation,
@@ -265135,7 +265127,6 @@ __export(invites_exports, {
265135
265127
  removePage: () => removePage,
265136
265128
  revokeInvite: () => revokeInvite,
265137
265129
  rowAnswerWords: () => rowAnswerWords,
265138
- setMarketplacePage: () => setMarketplacePage,
265139
265130
  setPage: () => setPage,
265140
265131
  sharePage: () => sharePage,
265141
265132
  standingWords: () => standingWords,
@@ -265143,10 +265134,10 @@ __export(invites_exports, {
265143
265134
  writeInvites: () => writeInvites,
265144
265135
  writeInvitesPatiently: () => writeInvitesPatiently
265145
265136
  });
265146
- function inviteItemsOf(words5) {
265137
+ function inviteItemsOf(words4) {
265147
265138
  const items = [];
265148
265139
  const problems = [];
265149
- for (const raw of words5) {
265140
+ for (const raw of words4) {
265150
265141
  const one = raw.trim();
265151
265142
  if (one === "link") items.push({ link: true });
265152
265143
  else if (/^ixo1[a-z0-9]{38}$/.test(one)) items.push({ address: one });
@@ -265337,8 +265328,8 @@ function standingWords(standing, context) {
265337
265328
  function doorLine(collectionId, sources) {
265338
265329
  const door2 = sources.worker ?? sources.draft ?? sources.terms ?? null;
265339
265330
  if (!door2) return `#${collectionId} \xB7 who may enter is not known yet: the board has not read this ask's terms (it does within a minute of posting). The list below already gates; call again shortly.`;
265340
- const words5 = door2 === "invite" ? "by invitation" : door2 === "apply" ? "by application" : "open to anyone";
265341
- return `#${collectionId} \xB7 ${words5}${!sources.worker && door2 !== "public" ? " (the board reads the terms within a minute; the list already gates)" : ""}`;
265331
+ const words4 = door2 === "invite" ? "by invitation" : door2 === "apply" ? "by application" : "open to anyone";
265332
+ return `#${collectionId} \xB7 ${words4}${!sources.worker && door2 !== "public" ? " (the board reads the terms within a minute; the list already gates)" : ""}`;
265342
265333
  }
265343
265334
  async function setPage(site, signer2, profile, fetchImpl) {
265344
265335
  const owner = signer2.principal ?? signer2.address;
@@ -265352,14 +265343,6 @@ async function setPage(site, signer2, profile, fetchImpl) {
265352
265343
  );
265353
265344
  return answer.ok ? { handle: String(answer.body.handle), address: String(answer.body.address) } : { refused: refusalOf(answer) };
265354
265345
  }
265355
- async function setMarketplacePage(site, signer2, page, fetchImpl) {
265356
- const body = { ...signer2.principal ? { onBehalfOf: signer2.principal } : {}, page };
265357
- const message = await sponsorWords("page", signer2.address, body);
265358
- const answer = await post(site, "/api/marketplaces/page", { address: signer2.address, ...body, proof: { kind: "adr36", message, ...await signWords(signer2.mnemonic, message) } }, fetchImpl);
265359
- if (answer.ok && typeof answer.body.slug === "string") return { slug: answer.body.slug };
265360
- if (answer.status === 404 && !answer.body.code) return { refused: "this site does not take Zone pages yet" };
265361
- return { refused: refusalOf(answer), ...codeOf2(answer) ? { code: codeOf2(answer) } : {} };
265362
- }
265363
265346
  async function removePage(site, signer2, fetchImpl) {
265364
265347
  const owner = signer2.principal ?? signer2.address;
265365
265348
  const prefAt = Date.now();
@@ -265408,7 +265391,7 @@ function pageWords(page, site) {
265408
265391
  page.linkedin ? `LinkedIn verified since ${page.linkedin.verifiedAt.slice(0, 10)}${page.linkedin.profileUrl ? ` \xB7 ${page.linkedin.profileUrl}` : ""}` : "Not LinkedIn verified yet",
265409
265392
  page.linkedin?.credentialUrl ? `LinkedIn credential (it shows this account logged in to this LinkedIn account; any app can check it): ${page.linkedin.credentialUrl}${page.linkedin.verifyUrl ? ` \xB7 check it: ${page.linkedin.verifyUrl}` : ""}` : "",
265410
265393
  `Address: ${page.address}${p.location ? ` \xB7 ${p.location}` : ""}${p.timezone ? ` (${p.timezone})` : ""}`,
265411
- `Does: ${p.does.length ? p.does.join(", ") : "not said"} \xB7 Rate: ${rate} \xB7 Availability: ${p.availability} \xB7 Invitable by handle: ${p.invitable ? "yes" : "no"}`,
265394
+ `Does: ${p.does.length ? p.does.join(", ") : "not said"} \xB7 Rate: ${rate} \xB7 Availability: ${p.availability} \xB7 Can be invited: ${openToWork(p) ? "yes" : "no, not taking work right now"}`,
265412
265395
  p.listed === false ? "Private: not shown on asks.world or in search; only someone who types the exact handle or address can invite them." : "Public: shown on asks.world, anyone can find it.",
265413
265396
  "Profile claims are supplied by the owner. Check what independent providers signed against your own requirements.",
265414
265397
  ...(p.verificationCredentials ?? []).map((one) => `Signed record cited (not verified): ${one.title} \xB7 ${one.issuerDid} \xB7 ${one.url}`),
@@ -265445,7 +265428,7 @@ async function linkedinStatus(site, id, fetchImpl = fetch) {
265445
265428
  if (response.ok && typeof body.state === "string") return body;
265446
265429
  return { refused: refusalOf({ status: response.status, body }) };
265447
265430
  }
265448
- var refusalOf, codeOf2, NOT_KNOWN_YET, TERMS_UNREAD, OFF_ROSTER, NO_ANSWER_MS, dayOf, acceptInvitation, declineInvitation, utc, rateWords;
265431
+ var refusalOf, codeOf2, NOT_KNOWN_YET, TERMS_UNREAD, OFF_ROSTER, NOT_VERIFIED, NO_ANSWER_MS, dayOf, acceptInvitation, declineInvitation, utc, rateWords;
265449
265432
  var init_invites = __esm({
265450
265433
  "src/invites.ts"() {
265451
265434
  "use strict";
@@ -265457,7 +265440,8 @@ var init_invites = __esm({
265457
265440
  codeOf2 = (answer) => typeof answer.body.code === "string" && answer.body.code ? answer.body.code : void 0;
265458
265441
  NOT_KNOWN_YET = "unknown-collection";
265459
265442
  TERMS_UNREAD = "terms-unread";
265460
- OFF_ROSTER = /Only LinkedIn-verified pros can be invited to this pro ask/;
265443
+ OFF_ROSTER = /Only (?:LinkedIn-)?verified pros can be invited to (?:a|this) pro ask/;
265444
+ NOT_VERIFIED = "Only verified pros can be invited to a pro ask.";
265461
265445
  NO_ANSWER_MS = 7 * 864e5;
265462
265446
  dayOf = (iso) => {
265463
265447
  const at = iso ? new Date(iso) : null;
@@ -266955,6 +266939,51 @@ var init_onAsks = __esm({
266955
266939
  }
266956
266940
  });
266957
266941
 
266942
+ // ../../app/lib/meRooms.ts
266943
+ var meRooms_exports = {};
266944
+ __export(meRooms_exports, {
266945
+ ROOMS: () => ROOMS,
266946
+ roomLines: () => roomLines,
266947
+ roomRows: () => roomRows
266948
+ });
266949
+ function roomRows(counts) {
266950
+ return ROOMS.map((room) => {
266951
+ switch (room.key) {
266952
+ case "page":
266953
+ return { ...room, figure: null, after: null, ...counts.page === "listed" ? { chip: "Listed" } : counts.page === "private" ? { chip: "Private" } : counts.page === "verify" ? { verify: true } : {} };
266954
+ case "work":
266955
+ return { ...room, ...counted(counts.work, "waiting") };
266956
+ case "messages":
266957
+ return { ...room, ...counted(counts.unread, "unread") };
266958
+ case "inbox":
266959
+ return { ...room, ...counted(counts.inbox, null) };
266960
+ case "money":
266961
+ return { ...room, figure: counts.money.available, money: true, after: counts.money.onAsks ? `${counts.money.onAsks} on asks` : null };
266962
+ case "agents":
266963
+ return { ...room, ...counted(counts.agents, null) };
266964
+ default:
266965
+ return { ...room, figure: null, after: null };
266966
+ }
266967
+ });
266968
+ }
266969
+ var ROOMS, counted, roomLines;
266970
+ var init_meRooms = __esm({
266971
+ "../../app/lib/meRooms.ts"() {
266972
+ "use strict";
266973
+ ROOMS = [
266974
+ { key: "page", word: "Your page", href: "/me/page" },
266975
+ { key: "work", word: "Work", href: "/me/work" },
266976
+ { key: "messages", word: "Messages", href: "/me/messages" },
266977
+ { key: "inbox", word: "Inbox", href: "/me/check" },
266978
+ { key: "money", word: "Money", href: "/me/money" },
266979
+ { key: "agents", word: "Agents", href: "/me/agents" },
266980
+ { key: "settings", word: "Settings", href: "/me/settings" }
266981
+ ];
266982
+ counted = (value, after) => value ? { figure: String(value), after } : { figure: null, after: null };
266983
+ 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"))}`);
266984
+ }
266985
+ });
266986
+
266958
266987
  // src/verdictSource.ts
266959
266988
  var verdictSource_exports = {};
266960
266989
  __export(verdictSource_exports, {
@@ -267172,96 +267201,6 @@ var init_spot = __esm({
267172
267201
  }
267173
267202
  });
267174
267203
 
267175
- // ../../packages/openhands-sdk/src/data/sponsors.ts
267176
- var sponsors_exports = {};
267177
- __export(sponsors_exports, {
267178
- SPONSOR_METHOD_MAX: () => SPONSOR_METHOD_MAX,
267179
- SPONSOR_PAGE_LIMITS: () => SPONSOR_PAGE_LIMITS,
267180
- SPONSOR_SLUG: () => SPONSOR_SLUG,
267181
- checkSponsorPage: () => checkSponsorPage,
267182
- slugOf: () => slugOf,
267183
- sponsorAccounts: () => sponsorAccounts,
267184
- sponsorBlocks: () => sponsorBlocks,
267185
- sponsorBySlug: () => sponsorBySlug,
267186
- sponsorNode: () => sponsorNode,
267187
- tidySponsorPage: () => tidySponsorPage
267188
- });
267189
- function checkSponsorPage(page) {
267190
- if (!record2(page)) return "A page is its deck line, logo, cover, story, steps, pictures and links";
267191
- const stray = Object.keys(page).find((key) => !PAGE_FIELDS.has(key));
267192
- if (stray) return `A page has no "${stray.slice(0, 40)}"; it carries a deck line, logo, cover, story, steps, pictures and links`;
267193
- return maybeWords(page.deck, SPONSOR_PAGE_LIMITS.deck, "The deck line") ?? (page.logo === void 0 ? null : typeof page.logo === "string" && isHttps2(page.logo) ? null : `The logo: "${String(page.logo).slice(0, 80)}" is not an https address`) ?? (page.cover === void 0 ? null : pictureOf(page.cover, "The cover")) ?? many(page.story, L4.paragraphs, "paragraphs", (one, index) => typeof one === "string" ? within(one, L4.paragraph, `Paragraph ${index + 1}`, true) : `Paragraph ${index + 1} is not words`) ?? many(page.steps, L4.steps, "steps", (one, index) => record2(one) ? words4(one.title, L4.stepTitle, `Step ${index + 1}'s title`) ?? maybeWords(one.text, L4.stepText, `Step ${index + 1}'s words`) : `Step ${index + 1} needs a title`) ?? many(page.pictures, L4.items, "pictures", (one, index) => pictureOf(one, `Picture ${index + 1}`)) ?? many(page.links, SPONSOR_PAGE_LIMITS.links, "links", (one, index) => {
267194
- if (!record2(one) || typeof one.url !== "string") return `Link ${index + 1} needs an address and a name`;
267195
- if (!isHttps2(one.url)) return `Link ${index + 1}: "${one.url.slice(0, 80)}" is not an https address`;
267196
- return words4(one.name, L4.name, `Link ${index + 1}'s name`) ?? maybeWords(one.note, L4.note, `Link ${index + 1}'s note`);
267197
- });
267198
- }
267199
- function tidySponsorPage(page) {
267200
- const out = {};
267201
- if (page.deck?.trim()) out.deck = oneLine(page.deck);
267202
- if (page.logo?.trim()) out.logo = page.logo.trim();
267203
- if (page.cover && (page.cover.url.trim() || page.cover.alt.trim())) out.cover = tidyPicture(page.cover);
267204
- const story = (page.story ?? []).map((one) => one.trim()).filter(Boolean);
267205
- if (story.length) out.story = story;
267206
- const steps = (page.steps ?? []).filter((one) => one.title.trim() || one.text?.trim()).map((one) => ({ title: oneLine(one.title), ...one.text?.trim() ? { text: oneLine(one.text) } : {} }));
267207
- if (steps.length) out.steps = steps;
267208
- const pictures = (page.pictures ?? []).filter((one) => one.url.trim() || one.alt.trim()).map(tidyPicture);
267209
- if (pictures.length) out.pictures = pictures;
267210
- const links = (page.links ?? []).filter((one) => one.url.trim() || one.name.trim()).map((one) => ({ url: one.url.trim(), name: oneLine(one.name), ...one.note?.trim() ? { note: oneLine(one.note) } : {} }));
267211
- if (links.length) out.links = links;
267212
- return out;
267213
- }
267214
- function sponsorBlocks(page, name8) {
267215
- const blocks = [];
267216
- if (page.cover) blocks.push({ kind: "cover", ...tidyPicture(page.cover) });
267217
- if (page.story?.length) blocks.push({ kind: "story", paragraphs: page.story });
267218
- if (page.steps?.length) blocks.push({ kind: "diagram", title: `How ${name8} verifies`, steps: page.steps.map((one) => ({ title: oneLine(one.title), ...one.text ? { text: oneLine(one.text) } : {} })) });
267219
- if (page.pictures?.length) blocks.push({ kind: "pictures", items: page.pictures.map(tidyPicture) });
267220
- if (page.links?.length) blocks.push({ kind: "files", items: page.links.map((one) => ({ url: one.url, name: oneLine(one.name), ...one.note ? { note: oneLine(one.note) } : {} })) });
267221
- return blocks;
267222
- }
267223
- var SPONSOR_METHOD_MAX, sponsorBySlug, SPONSOR_SLUG, slugOf, sponsorNode, sponsorAccounts, SPONSOR_PAGE_LIMITS, PAGE_FIELDS, L4, words4, maybeWords, record2, many, pictureOf, tidyPicture;
267224
- var init_sponsors = __esm({
267225
- "../../packages/openhands-sdk/src/data/sponsors.ts"() {
267226
- "use strict";
267227
- init_entityShape();
267228
- init_env();
267229
- init_callChecks();
267230
- init_callLimits();
267231
- SPONSOR_METHOD_MAX = 600;
267232
- sponsorBySlug = (list7, slug) => list7.find((s) => s.slug === slug) ?? null;
267233
- SPONSOR_SLUG = /^[a-z][a-z0-9-]{2,39}$/;
267234
- slugOf = (org) => org.normalize("NFKD").replace(/[\u0300-\u036f]/g, "").toLowerCase().replace(/[^a-z0-9]+/g, "-").replace(/^-+|-+$/g, "").slice(0, 40).replace(/-+$/, "");
267235
- sponsorNode = (sponsor, network2) => {
267236
- if (sponsor.state !== "approved") return null;
267237
- const own2 = sponsor.node[network2];
267238
- return isEntityDid(own2) ? own2 : chainEndpointsFor(network2)?.relayerNodeDid ?? null;
267239
- };
267240
- sponsorAccounts = (list7) => new Set(list7.filter((s) => s.state === "approved").map((s) => s.account));
267241
- SPONSOR_PAGE_LIMITS = { deck: 120, links: 6 };
267242
- PAGE_FIELDS = /* @__PURE__ */ new Set(["deck", "logo", "cover", "story", "steps", "pictures", "links"]);
267243
- L4 = CALL_LIMITS;
267244
- words4 = (value, max, what) => typeof value === "string" ? within(oneLine(value), max, what) : `${what} is not words`;
267245
- maybeWords = (value, max, what) => value === void 0 ? null : words4(value, max, what);
267246
- record2 = (value) => Boolean(value) && typeof value === "object" && !Array.isArray(value);
267247
- many = (value, max, what, each) => {
267248
- if (value === void 0) return null;
267249
- if (!Array.isArray(value)) return `The ${what} are not a list`;
267250
- if (value.length > max) return `${value.length} ${what}; the most is ${max}`;
267251
- for (const [index, one] of value.entries()) {
267252
- const problem = each(one, index);
267253
- if (problem) return problem;
267254
- }
267255
- return null;
267256
- };
267257
- pictureOf = (one, what) => {
267258
- if (!record2(one) || typeof one.url !== "string" || typeof one.alt !== "string" || one.caption !== void 0 && typeof one.caption !== "string") return `${what} needs an address and words for it`;
267259
- return picture({ url: one.url, alt: one.alt, ...one.caption === void 0 ? {} : { caption: one.caption } }, what);
267260
- };
267261
- tidyPicture = (one) => ({ url: one.url.trim(), alt: oneLine(one.alt), ...one.caption?.trim() ? { caption: oneLine(one.caption) } : {} });
267262
- }
267263
- });
267264
-
267265
267204
  // ../../app/lib/floor.ts
267266
267205
  var TRACE_URL, MONTHS, dayOf2;
267267
267206
  var init_floor = __esm({
@@ -267273,64 +267212,26 @@ var init_floor = __esm({
267273
267212
  }
267274
267213
  });
267275
267214
 
267276
- // src/marketplaces.ts
267277
- var marketplaces_exports = {};
267278
- __export(marketplaces_exports, {
267215
+ // src/pros.ts
267216
+ var pros_exports = {};
267217
+ __export(pros_exports, {
267279
267218
  FIND_PRO_MAX: () => FIND_PRO_MAX,
267280
- REGISTRY_DOWN: () => REGISTRY_DOWN,
267219
+ PRIVATE_LINE: () => PRIVATE_LINE,
267281
267220
  linkedinWords: () => linkedinWords2,
267282
- marketplaceChoices: () => marketplaceChoices,
267283
- marketplacePageWords: () => marketplacePageWords,
267284
- marketplacesWords: () => marketplacesWords,
267285
- notAMarketplace: () => notAMarketplace,
267286
267221
  proWords: () => proWords,
267222
+ prosWords: () => prosWords,
267287
267223
  readDirectory: () => readDirectory,
267288
- readMarketplace: () => readMarketplace,
267289
- readMarketplacePage: () => readMarketplacePage,
267290
- readMarketplaces: () => readMarketplaces,
267291
- resolveMarketplace: () => resolveMarketplace,
267292
- rosterOf: () => rosterOf,
267293
- rosterWords: () => rosterWords
267294
- });
267295
- async function readMarketplaces(site, fetchImpl = fetch) {
267296
- const response = await get2(site, "/api/marketplaces", fetchImpl);
267297
- if (!response?.ok) return { unavailable: REGISTRY_DOWN };
267298
- const body = await response.json().catch(() => null);
267299
- return Array.isArray(body?.sponsors) ? { sponsors: body.sponsors.filter(isSponsor) } : { unavailable: REGISTRY_DOWN };
267300
- }
267301
- async function readMarketplace(site, slug, fetchImpl = fetch) {
267302
- const response = await get2(site, `/api/marketplaces/${encodeURIComponent(slug)}`, fetchImpl);
267303
- const body = await response?.json().catch(() => null);
267304
- if (response?.ok && isSponsor(body?.sponsor)) return { sponsor: body.sponsor, counts: typeof body.counts?.checked === "number" ? { checked: body.counts.checked } : null };
267305
- if (response?.status === 404 && body?.code === "no-sponsor") return { missing: true };
267306
- return { unavailable: REGISTRY_DOWN };
267307
- }
267308
- async function readMarketplacePage(site, slug, fetchImpl = fetch) {
267309
- const response = await get2(site, `/api/marketplaces/${encodeURIComponent(slug)}`, fetchImpl);
267310
- if (!response?.ok) return null;
267311
- const body = await response.json().catch(() => null);
267312
- const page = body?.page?.page;
267313
- return page && typeof page === "object" && !Array.isArray(page) ? page : null;
267314
- }
267315
- async function resolveMarketplace(site, slug, network2, fetchImpl = fetch) {
267316
- const one = await readMarketplace(site, slug, fetchImpl);
267317
- if ("unavailable" in one) return { refused: `${REGISTRY_DOWN}, so the Zone "${slug}" cannot be confirmed. Try again in a minute.`, unavailable: true };
267318
- if ("missing" in one) return { refused: notAMarketplace(slug) };
267319
- const { sponsor } = one;
267320
- if (sponsor.state !== "approved") return { refused: `${sponsor.name} is paused: it takes no new pro Asks right now.` };
267321
- const node = sponsorNode(sponsor, network2);
267322
- if (!node) return { refused: `${sponsor.name} cannot take pro Asks here yet: it has not set up where its share is paid on this network.` };
267323
- return { sponsor: { slug: sponsor.slug, name: sponsor.name, node }, account: sponsor.account };
267324
- }
267224
+ verifiedOf: () => verifiedOf
267225
+ });
267325
267226
  async function readDirectory(site, q, fetchImpl = fetch) {
267326
267227
  const query = new URLSearchParams({ limit: "100" });
267327
267228
  if (q?.trim()) query.set("q", q.trim().slice(0, 60));
267328
- const response = await get2(site, `/api/hands?${query}`, fetchImpl);
267229
+ const response = await fetchImpl(`${base5(site)}/api/hands?${query}`, { headers: { accept: "application/json" }, signal: AbortSignal.timeout(15e3) }).catch(() => null);
267329
267230
  if (!response?.ok) return null;
267330
267231
  const body = await response.json().catch(() => null);
267331
267232
  return Array.isArray(body?.hands) ? body.hands.filter((one) => typeof one?.address === "string" && typeof one?.profile?.handle === "string") : null;
267332
267233
  }
267333
- function rosterOf(rows2, options = {}) {
267234
+ function verifiedOf(rows2, options = {}) {
267334
267235
  const out = [];
267335
267236
  for (const row of rows2) {
267336
267237
  if (!row.linkedin?.verifiedAt) continue;
@@ -267348,81 +267249,34 @@ function proWords(one, site, index) {
267348
267249
  ` Page and record: ${proPage(site, p.handle)}`
267349
267250
  ].join("\n");
267350
267251
  }
267351
- function rosterWords(found, ctx) {
267352
- const whose2 = ctx.marketplace ? `${ctx.marketplace}'s roster` : "a Zone's roster";
267252
+ function prosWords(found, ctx) {
267353
267253
  const narrowed = [ctx.q ? `for "${ctx.q}"` : "", ctx.available ? "open to work now" : ""].filter(Boolean).join(", ");
267354
267254
  const shown2 = found.slice(0, FIND_PRO_MAX);
267355
267255
  if (shown2.length === 0)
267356
- return `No pro on ${whose2}${narrowed ? ` ${narrowed}` : ""} matches. ${ctx.q || ctx.available ? "Widen q, or leave available out, and ask again." : "Nobody is on it yet."} Nothing ranks pros here; the roster is every LinkedIn-verified pro.`;
267256
+ return `${narrowed ? `Nobody matches ${narrowed}. Widen q, or leave available out, and ask again.` : "No pros listed yet."} Nothing ranks pros here. ${PRIVATE_LINE}`;
267357
267257
  const lines2 = [
267358
- `Pros on ${whose2}${narrowed ? `, ${narrowed}` : ""}: ${shown2.length} of ${found.length}, newest LinkedIn verification first. Nothing ranks them: the order is the date each was verified, and the person chooses.`,
267258
+ `Verified pros${narrowed ? `, ${narrowed}` : ""}: ${shown2.length} of ${found.length}, newest verification first. Nothing ranks them: the order is the date each was verified, and the person chooses.`,
267359
267259
  "",
267360
267260
  asData("pros", shown2.map((one, index) => proWords(one, ctx.site, index)).join("\n\n")),
267361
267261
  ""
267362
267262
  ];
267363
267263
  if (shown2.length < 3) lines2.push(`Only ${shown2.length} ${shown2.length === 1 ? "matches" : "match"}; wider words find more.`);
267264
+ lines2.push(PRIVATE_LINE);
267364
267265
  lines2.push(`Show these to the person and let them choose. Then invite_to_call with the pro ask's slug (or its number) and invite: ["@handle", \u2026]; each one invited reads the pro ask with read_ask.`);
267365
267266
  return lines2.join("\n");
267366
267267
  }
267367
- function marketplacesWords(rows2, site) {
267368
- if (rows2.length === 0) return "No Zone is approved on asks.world yet, so no pro ask can be posted here. Open calls still can (draft_call without kind).";
267369
- return [
267370
- `Zones on asks.world: ${rows2.length}. A pro ask names one: the pros invited are LinkedIn verified, and it earns the Zone's share of each approved report. The order is when each was approved; nothing ranks them.`,
267371
- "",
267372
- ...rows2.flatMap((one, index) => [
267373
- `${index + 1}. ${one.sponsor.name} \xB7 sponsor: "${one.sponsor.slug}" \xB7 since ${dayOf2(new Date(one.sponsor.since))}`,
267374
- ` Pros on its roster: ${one.roster === null ? "not answering right now" : `${one.roster}, LinkedIn verified`}`,
267375
- ` Its page: ${marketplacePage(site, one.sponsor.slug)}`,
267376
- asData("marketplace", `What ${one.sponsor.name} verifies, in its words: ${one.sponsor.method}`),
267377
- ""
267378
- ]),
267379
- 'Draft a pro ask through one: draft_call with kind: "review" and sponsor: "<slug>". Suggest pros from its roster: find_pro with sponsor: "<slug>". A pro gets on every roster with connect_linkedin.'
267380
- ].join("\n");
267381
- }
267382
- function marketplacePageWords(sponsor, page, site, before = null) {
267383
- const picture2 = (one) => `${one.url} \u2014 ${one.alt}${one.caption ? ` (${one.caption})` : ""}`;
267384
- const theirs = [
267385
- page.deck ? `Under it: ${page.deck}` : "",
267386
- page.logo ? `Logo: ${page.logo}` : "",
267387
- page.cover ? `Cover: ${picture2(page.cover)}` : "",
267388
- ...page.story?.length ? ["Story:", ...page.story.map((one, index) => ` ${index + 1}. ${one}`)] : [],
267389
- ...page.steps?.length ? [`How ${sponsor.name} verifies:`, ...page.steps.map((one, index) => ` ${index + 1}. ${one.title}${one.text ? ` \u2014 ${one.text}` : ""}`)] : [],
267390
- ...page.pictures?.length ? ["Pictures:", ...page.pictures.map((one, index) => ` ${index + 1}. ${picture2(one)}`)] : [],
267391
- ...page.links?.length ? ["Links:", ...page.links.map((one, index) => ` ${index + 1}. ${one.name} \u2014 ${one.url}${one.note ? ` (${one.note})` : ""}`)] : []
267392
- ].filter(Boolean);
267393
- const gone = before ? Object.keys(PAGE_PARTS).filter((key) => before[key] !== void 0 && page[key] === void 0).map((key) => PAGE_PARTS[key]) : [];
267394
- return [
267395
- `${sponsor.name}'s page, as ${marketplacePage(site, sponsor.slug)} will show it:`,
267396
- "",
267397
- `${sponsor.name} stands behind these professionals. (ours: every Zone's page opens with it)`,
267398
- ...theirs.length ? theirs : ["(nothing of its own: the page draws from the list of Zones alone)"],
267399
- "Around it, the same on every Zone's page and not changed here: the pros it verified, its numbers and the deal.",
267400
- "",
267401
- `This replaces the page whole.${gone.length ? ` Taken off: ${gone.join(", ")}.` : ""} Pictures and the logo are read from their addresses each time the page is read, so a changed file changes the page.`
267402
- ].join("\n");
267403
- }
267404
- var REGISTRY_DOWN, FIND_PRO_MAX, base5, timeout2, get2, isSponsor, notAMarketplace, marketplaceChoices, linkedinWords2, PAGE_PARTS;
267405
- var init_marketplaces = __esm({
267406
- "src/marketplaces.ts"() {
267268
+ var FIND_PRO_MAX, base5, linkedinWords2, PRIVATE_LINE;
267269
+ var init_pros = __esm({
267270
+ "src/pros.ts"() {
267407
267271
  "use strict";
267408
- init_sponsors();
267409
267272
  init_floor();
267410
267273
  init_invites();
267411
267274
  init_safety();
267412
267275
  init_world();
267413
- REGISTRY_DOWN = "The Zones list is not answering right now";
267414
267276
  FIND_PRO_MAX = 5;
267415
267277
  base5 = (site) => site.replace(/\/+$/, "");
267416
- timeout2 = () => AbortSignal.timeout(15e3);
267417
- get2 = (site, path, fetchImpl) => fetchImpl(`${base5(site)}${path}`, { headers: { accept: "application/json" }, signal: timeout2() }).catch(() => null);
267418
- isSponsor = (one) => {
267419
- const row = one;
267420
- return Boolean(row) && typeof row.slug === "string" && typeof row.name === "string" && typeof row.account === "string" && typeof row.state === "string" && typeof row.node === "object" && row.node !== null;
267421
- };
267422
- notAMarketplace = (slug) => `"${slug}" is not a Zone on asks.world: list_marketplaces names them.`;
267423
- marketplaceChoices = (list7) => list7.map((one) => `${one.name} (sponsor: "${one.slug}")`).join("; ");
267424
267278
  linkedinWords2 = (badge) => `LinkedIn verified \xB7 ${dayOf2(new Date(badge.verifiedAt))}${badge.profileUrl ? ` \xB7 ${badge.profileUrl}` : ""}`;
267425
- PAGE_PARTS = { deck: "the line under ours", logo: "the logo", cover: "the cover", story: "the story", steps: "the steps", pictures: "the pictures", links: "the links" };
267279
+ PRIVATE_LINE = "A private pro is in no list: any verified pro can be invited by their exact @handle or ixo1 address.";
267426
267280
  }
267427
267281
  });
267428
267282
 
@@ -267458,8 +267312,8 @@ var init_marketPlan = __esm({
267458
267312
  return match6 ? match6[1] : null;
267459
267313
  };
267460
267314
  planSlug = (text4, suffix = "") => {
267461
- const words5 = text4.toLowerCase().normalize("NFKD").replace(/[̀-ͯ]/g, "").replace(/[^a-z0-9]+/g, "-").replace(/^-+|-+$/g, "");
267462
- const start = words5.replace(/^[^a-z]+/, "") || "plan";
267315
+ const words4 = text4.toLowerCase().normalize("NFKD").replace(/[̀-ͯ]/g, "").replace(/[^a-z0-9]+/g, "-").replace(/^-+|-+$/g, "");
267316
+ const start = words4.replace(/^[^a-z]+/, "") || "plan";
267463
267317
  const tail = suffix ? `-${suffix}` : "";
267464
267318
  const room = 40 - tail.length;
267465
267319
  const body = start.slice(0, room).replace(/-+$/, "");
@@ -267652,43 +267506,43 @@ ${where2}`)) {
267652
267506
  askAt = (place) => ` At ${place.name}.`;
267653
267507
  askOverrun = (check2, place) => Math.max(0, askWords(check2).length + askAt(place).length - PLAN_LIMITS.textMax);
267654
267508
  shapeOfCheck = (check2) => {
267655
- const L5 = PLAN_LIMITS;
267509
+ const L4 = PLAN_LIMITS;
267656
267510
  const out = [];
267657
267511
  const bad = (why) => out.push({ rule: "shape", check: check2.id, why });
267658
267512
  if (!PLAN_ACTS.includes(check2.act)) bad(`The act must be one of ${PLAN_ACTS.join(", ")}.`);
267659
267513
  const text4 = check2.text.trim();
267660
- if (text4.length < L5.textMin || text4.length > L5.textMax) bad(`The check's words must be ${L5.textMin} to ${L5.textMax} characters.`);
267514
+ if (text4.length < L4.textMin || text4.length > L4.textMax) bad(`The check's words must be ${L4.textMin} to ${L4.textMax} characters.`);
267661
267515
  else {
267662
267516
  const named = check2.places.filter((place) => place.name?.trim());
267663
267517
  const worst = named.reduce((most2, place) => !most2 || askOverrun(check2, place) > askOverrun(check2, most2) ? place : most2, null);
267664
267518
  const over = worst ? askOverrun(check2, worst) : 0;
267665
267519
  if (worst && over > 0) {
267666
- bad(`Each ask adds "${askAt(worst).trim()}" after the words, which takes them ${over} characters past the ${L5.textMax} an ask carries. Cut ${over} characters from the words, or shorten that place's name.`);
267520
+ bad(`Each ask adds "${askAt(worst).trim()}" after the words, which takes them ${over} characters past the ${L4.textMax} an ask carries. Cut ${over} characters from the words, or shorten that place's name.`);
267667
267521
  }
267668
267522
  }
267669
267523
  if (!check2.places.length) bad("A check needs at least one place.");
267670
- if (check2.places.length > L5.placesPerCheck) bad(`A check holds at most ${L5.placesPerCheck} places.`);
267524
+ if (check2.places.length > L4.placesPerCheck) bad(`A check holds at most ${L4.placesPerCheck} places.`);
267671
267525
  for (const place of check2.places) {
267672
267526
  if (!place.name?.trim()) bad("Every place needs a name a person recognises.");
267673
267527
  if (!(Math.abs(place.lat) <= 90) || !(Math.abs(place.lon) <= 180) || place.lat === 0 && place.lon === 0) bad(`"${place.name}" has no usable coordinates.`);
267674
- if (!(place.withinM >= L5.withinMin && place.withinM <= L5.withinMax)) bad(`"${place.name}": the distance must be ${L5.withinMin} to ${L5.withinMax} m.`);
267528
+ if (!(place.withinM >= L4.withinMin && place.withinM <= L4.withinMax)) bad(`"${place.name}": the distance must be ${L4.withinMin} to ${L4.withinMax} m.`);
267675
267529
  }
267676
- const most = check2.act === "survey" ? L5.surveyPerPlace : L5.perPlace;
267530
+ const most = check2.act === "survey" ? L4.surveyPerPlace : L4.perPlace;
267677
267531
  if (!Number.isInteger(check2.perPlace) || check2.perPlace < 1 || check2.perPlace > most) bad(`Answers per place must be a whole number from 1 to ${most}.`);
267678
267532
  if (check2.act === "survey") {
267679
267533
  const problem = surveyOptionsProblem(check2.options);
267680
267534
  if (problem) bad(problem);
267681
267535
  } else if (check2.options !== void 0) bad("Only a survey has options.");
267682
267536
  for (const [name8, line2] of [["why", check2.why], ["how it is read", check2.readAs]]) {
267683
- if (line2 !== void 0 && (line2.trim().length < L5.lineMin || line2.trim().length > L5.lineMax)) bad(`The check's ${name8} line is ${L5.lineMin} to ${L5.lineMax} characters.`);
267537
+ if (line2 !== void 0 && (line2.trim().length < L4.lineMin || line2.trim().length > L4.lineMax)) bad(`The check's ${name8} line is ${L4.lineMin} to ${L4.lineMax} characters.`);
267684
267538
  }
267685
- if (!(check2.payUsd >= L5.payFloorUsd)) bad(`The pay must be at least $${L5.payFloorUsd.toFixed(2)} an answer.`);
267686
- if (!(check2.hours >= L5.hoursMin && check2.hours <= L5.hoursMax)) bad(`A check stays open ${L5.hoursMin} to ${L5.hoursMax} hours.`);
267687
- if (check2.beats.trim().length > L5.lineMax) bad(`What the check beats fits in ${L5.lineMax} characters.`);
267539
+ if (!(check2.payUsd >= L4.payFloorUsd)) bad(`The pay must be at least $${L4.payFloorUsd.toFixed(2)} an answer.`);
267540
+ if (!(check2.hours >= L4.hoursMin && check2.hours <= L4.hoursMax)) bad(`A check stays open ${L4.hoursMin} to ${L4.hoursMax} hours.`);
267541
+ if (check2.beats.trim().length > L4.lineMax) bad(`What the check beats fits in ${L4.lineMax} characters.`);
267688
267542
  return out;
267689
267543
  };
267690
267544
  validatePlan = (plan) => {
267691
- const L5 = PLAN_LIMITS;
267545
+ const L4 = PLAN_LIMITS;
267692
267546
  const refusals = [...screenMarket(plan.market)];
267693
267547
  const shape = (why) => refusals.push({ rule: "shape", check: null, why });
267694
267548
  if (plan.kind !== MARKET_PLAN_KIND || plan.v !== 1) shape("This is not a version 1 plan.");
@@ -267696,15 +267550,15 @@ ${where2}`)) {
267696
267550
  if (!/^https?:\/\//.test(plan.market.url)) shape("The market needs its link.");
267697
267551
  if (plan.market.question.trim().length < 8) shape("The market needs its question.");
267698
267552
  if (!plan.checks.length) shape("A plan needs at least one check.");
267699
- if (plan.checks.length > L5.checks) shape(`A plan holds at most ${L5.checks} checks.`);
267700
- if (planAskCount(plan) > L5.asksPerPlan) shape(`A plan posts at most ${L5.asksPerPlan} Asks (one per place per check).`);
267553
+ if (plan.checks.length > L4.checks) shape(`A plan holds at most ${L4.checks} checks.`);
267554
+ if (planAskCount(plan) > L4.asksPerPlan) shape(`A plan posts at most ${L4.asksPerPlan} Asks (one per place per check).`);
267701
267555
  const ids = /* @__PURE__ */ new Set();
267702
267556
  for (const check2 of plan.checks) {
267703
267557
  if (ids.has(check2.id)) shape(`Two checks share the id ${check2.id}.`);
267704
267558
  ids.add(check2.id);
267705
267559
  }
267706
- if (plan.thesis !== void 0 && (plan.thesis.trim().length < L5.lineMin || plan.thesis.trim().length > L5.thesisMax)) shape(`The thesis is ${L5.lineMin} to ${L5.thesisMax} characters.`);
267707
- if (plan.cannotTell.trim().length < L5.lineMin) {
267560
+ if (plan.thesis !== void 0 && (plan.thesis.trim().length < L4.lineMin || plan.thesis.trim().length > L4.thesisMax)) shape(`The thesis is ${L4.lineMin} to ${L4.thesisMax} characters.`);
267561
+ if (plan.cannotTell.trim().length < L4.lineMin) {
267708
267562
  refusals.push({ rule: "no-cannot-tell", check: null, why: "Say what this plan cannot tell the trader. A plan without its limit reads as a promise." });
267709
267563
  }
267710
267564
  for (const check2 of plan.checks) refusals.push(...shapeOfCheck(check2), ...screenCheck(check2));
@@ -272809,12 +272663,12 @@ function az_default() {
272809
272663
  }
272810
272664
 
272811
272665
  // ../../node_modules/.pnpm/zod@4.4.3/node_modules/zod/v4/locales/be.js
272812
- function getBelarusianPlural(count2, one, few, many2) {
272666
+ function getBelarusianPlural(count2, one, few, many) {
272813
272667
  const absCount = Math.abs(count2);
272814
272668
  const lastDigit = absCount % 10;
272815
272669
  const lastTwoDigits = absCount % 100;
272816
272670
  if (lastTwoDigits >= 11 && lastTwoDigits <= 19) {
272817
- return many2;
272671
+ return many;
272818
272672
  }
272819
272673
  if (lastDigit === 1) {
272820
272674
  return one;
@@ -272822,7 +272676,7 @@ function getBelarusianPlural(count2, one, few, many2) {
272822
272676
  if (lastDigit >= 2 && lastDigit <= 4) {
272823
272677
  return few;
272824
272678
  }
272825
- return many2;
272679
+ return many;
272826
272680
  }
272827
272681
  var error3 = () => {
272828
272682
  const Sizable = {
@@ -274888,8 +274742,8 @@ function hu_default() {
274888
274742
  }
274889
274743
 
274890
274744
  // ../../node_modules/.pnpm/zod@4.4.3/node_modules/zod/v4/locales/hy.js
274891
- function getArmenianPlural(count2, one, many2) {
274892
- return Math.abs(count2) === 1 ? one : many2;
274745
+ function getArmenianPlural(count2, one, many) {
274746
+ return Math.abs(count2) === 1 ? one : many;
274893
274747
  }
274894
274748
  function withDefiniteArticle(word) {
274895
274749
  if (!word)
@@ -277017,12 +276871,12 @@ function ro_default() {
277017
276871
  }
277018
276872
 
277019
276873
  // ../../node_modules/.pnpm/zod@4.4.3/node_modules/zod/v4/locales/ru.js
277020
- function getRussianPlural(count2, one, few, many2) {
276874
+ function getRussianPlural(count2, one, few, many) {
277021
276875
  const absCount = Math.abs(count2);
277022
276876
  const lastDigit = absCount % 10;
277023
276877
  const lastTwoDigits = absCount % 100;
277024
276878
  if (lastTwoDigits >= 11 && lastTwoDigits <= 19) {
277025
- return many2;
276879
+ return many;
277026
276880
  }
277027
276881
  if (lastDigit === 1) {
277028
276882
  return one;
@@ -277030,7 +276884,7 @@ function getRussianPlural(count2, one, few, many2) {
277030
276884
  if (lastDigit >= 2 && lastDigit <= 4) {
277031
276885
  return few;
277032
276886
  }
277033
- return many2;
276887
+ return many;
277034
276888
  }
277035
276889
  var error38 = () => {
277036
276890
  const Sizable = {
@@ -289873,11 +289727,11 @@ var Protocol = class {
289873
289727
  const controller = this._requestHandlerAbortControllers.get(notification.params.requestId);
289874
289728
  controller?.abort(notification.params.reason);
289875
289729
  }
289876
- _setupTimeout(messageId, timeout3, maxTotalTimeout, onTimeout, resetTimeoutOnProgress = false) {
289730
+ _setupTimeout(messageId, timeout2, maxTotalTimeout, onTimeout, resetTimeoutOnProgress = false) {
289877
289731
  this._timeoutInfo.set(messageId, {
289878
- timeoutId: setTimeout(onTimeout, timeout3),
289732
+ timeoutId: setTimeout(onTimeout, timeout2),
289879
289733
  startTime: Date.now(),
289880
- timeout: timeout3,
289734
+ timeout: timeout2,
289881
289735
  maxTotalTimeout,
289882
289736
  resetTimeoutOnProgress,
289883
289737
  onTimeout
@@ -290339,9 +290193,9 @@ var Protocol = class {
290339
290193
  options?.signal?.addEventListener("abort", () => {
290340
290194
  cancel(options?.signal?.reason);
290341
290195
  });
290342
- const timeout3 = options?.timeout ?? DEFAULT_REQUEST_TIMEOUT_MSEC;
290343
- const timeoutHandler = () => cancel(McpError.fromError(ErrorCode.RequestTimeout, "Request timed out", { timeout: timeout3 }));
290344
- this._setupTimeout(messageId, timeout3, options?.maxTotalTimeout, timeoutHandler, options?.resetTimeoutOnProgress ?? false);
290196
+ const timeout2 = options?.timeout ?? DEFAULT_REQUEST_TIMEOUT_MSEC;
290197
+ const timeoutHandler = () => cancel(McpError.fromError(ErrorCode.RequestTimeout, "Request timed out", { timeout: timeout2 }));
290198
+ this._setupTimeout(messageId, timeout2, options?.maxTotalTimeout, timeoutHandler, options?.resetTimeoutOnProgress ?? false);
290345
290199
  const relatedTaskId = relatedTask?.taskId;
290346
290200
  if (relatedTaskId) {
290347
290201
  const responseResolver = (response) => {
@@ -292290,7 +292144,7 @@ import { randomBytes as randomBytes7 } from "node:crypto";
292290
292144
  // package.json
292291
292145
  var package_default = {
292292
292146
  name: "@ixo/asks-mcp",
292293
- version: "1.12.2-dev.1",
292147
+ version: "2.0.0-dev.1",
292294
292148
  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.",
292295
292149
  license: "Apache-2.0",
292296
292150
  repository: {
@@ -292514,7 +292368,7 @@ var TOOLS = {
292514
292368
  },
292515
292369
  my_status: {
292516
292370
  title: "This participant's standing",
292517
- description: "Address, what is available and what is on your asks, answers sent, and rewards still owed.",
292371
+ 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.",
292518
292372
  spends: false,
292519
292373
  hosted: false,
292520
292374
  annotations: reads
@@ -292566,7 +292420,7 @@ var TOOLS = {
292566
292420
  },
292567
292421
  draft_call: {
292568
292422
  title: "Set up an open call or a pro ask",
292569
- 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: Pros qualified by the organisation you name (`sponsor`, from list_marketplaces) try the scenarios and send reports; always a hire, by invitation only; Asky Pro Checker, the verifier, checks each report, and the Zone earns its share. 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, the shares on top, what is held per report) and the clock, for the person to approve. Spends nothing.',
292423
+ 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.',
292570
292424
  spends: false,
292571
292425
  hosted: false,
292572
292426
  /* It writes the draft file, and nothing else anywhere. */
@@ -292574,7 +292428,7 @@ var TOOLS = {
292574
292428
  },
292575
292429
  post_call: {
292576
292430
  title: "Post an open call or a pro ask (spends money)",
292577
- description: `Post a drafted open call or pro ask as the account you act for: a competition is three Asks under one tag (the prize, the runners-up, the entries), a hire (every pro ask is one) is the entries alone; each holds its money until approval. One leg per call; call again until it says everything is posted. A pro ask confirms its Zone (\`sponsor\`) with the registry first: the Zone is written into its terms and earns its share of each approved report; a pro ask that names none, or one whose Zone is paused or not set up here, is refused before anything moves. A call by invitation writes its list the moment the entries post, and prints the invite links. Pays in this network's own coin, said in dollars. With \`pay_by: "card"\` nothing is spent here: the whole call is saved and you get a link where the person pays by card and posts it. Requires \`confirm\` to restate the exact total from the preview. ${ASK_RULES}`,
292431
+ description: `Post a drafted open call or pro ask as the account you act for: a competition is three Asks under one tag (the prize, the runners-up, the entries), a hire (every pro ask is one) is the entries alone; each holds its money until approval. One leg per call; call again until it says everything is posted. A call by invitation writes its list the moment the entries post, and prints the invite links. Pays in this network's own coin, said in dollars. With \`pay_by: "card"\` nothing is spent here: the whole call is saved and you get a link where the person pays by card and posts it. Requires \`confirm\` to restate the exact total from the preview. ${ASK_RULES}`,
292578
292432
  spends: true,
292579
292433
  hosted: false,
292580
292434
  annotations: acts
@@ -292589,7 +292443,7 @@ var TOOLS = {
292589
292443
  },
292590
292444
  invite_to_call: {
292591
292445
  title: "Invite pros or people to an ask",
292592
- description: `Put people on the list of an ask after it is posted (one by invitation or by application): ixo1 addresses, @handles of people with a page, and "link" once per single-use link to mint. Each link admits one new person, whoever opens it first. For a pro ask, invite pros from its Zone's roster: find_pro suggests them. For an ask posted with post_ask, pass its number as collectionId. Answers with the links to hand out and what was written. Only the poster, or the agent they connected, can. Spends nothing.`,
292446
+ description: 'Put people on the list of an ask after it is posted (one by invitation or by application): ixo1 addresses, @handles of people with a page, and "link" once per single-use link to mint. Each link admits one new person, whoever opens it first. A pro ask takes only verified pros: find_pro suggests them. For an ask posted with post_ask, pass its number as collectionId. Answers with the links to hand out and what was written. Only the poster, or the agent they connected, can. Spends nothing.',
292593
292447
  spends: false,
292594
292448
  hosted: false,
292595
292449
  annotations: acts
@@ -292624,7 +292478,7 @@ var TOOLS = {
292624
292478
  },
292625
292479
  accept_invitation: {
292626
292480
  title: "Accept an invitation to a pro ask",
292627
- description: "Accept an invitation to a pro ask: a link or the ask's number. As the account you act for when connected, else as this key. The builder hears you accepted, and your room with them opens with their note first; a link becomes yours, so nobody else can use it. A pro off the Zone's roster is refused, and the link stays open. Previews; `confirm: true` accepts, once the person says yes. Spends nothing.",
292481
+ description: "Accept an invitation to a pro ask: a link or the ask's number. As the account you act for when connected, else as this key. The builder hears you accepted, and your room with them opens with their note first; a link becomes yours, so nobody else can use it. Someone who is not a verified pro is refused, and the link stays open. Previews; `confirm: true` accepts, once the person says yes. Spends nothing.",
292628
292482
  spends: false,
292629
292483
  hosted: false,
292630
292484
  annotations: { ...acts, idempotentHint: true }
@@ -292653,7 +292507,7 @@ var TOOLS = {
292653
292507
  },
292654
292508
  set_my_page: {
292655
292509
  title: "Write your pro page",
292656
- description: "Make or change the pro page of the person you act for (or this key's own): the page posters find and invite them by, on Pro Asks and across asks.world. A handle, a name, a headline, what they do, a rate, links, availability, whether posters may invite them by handle, and `listed`: public (the default, anyone can find the page) or private (off asks.world and search; only someone who types the exact handle or address can invite them). Ask once, plainly, which they want. A private page can have a secret link (`share_link`: create, or replace to switch the old one off), said once on confirm. Previews by default; call again with confirm: true to sign. For guided setup, follow /pro/mcp.md#create-your-pro-profile on the matching Pro Asks host. Start with connect_linkedin: its verified profile pre-fills the name, headline, LinkedIn link and handle; ask only for what LinkedIn lacks (the work they take, rate, availability, a line about them). This tool reads no site itself, so build the rest from what the person tells you or pastes. Spends nothing.",
292510
+ description: "Make or change the pro page of the person you act for (or this key's own): the page posters find and invite them by, on Pro Asks and across asks.world. A handle, a name, a headline, what they do, a rate, links, availability (open means they can be invited to a pro ask; busy or closed, they are shown but not invited), and `listed`: public (the default, anyone can find the page) or private (off asks.world and search; only someone who types the exact handle or address can invite them). Ask once, plainly, which they want. A private page can have a secret link (`share_link`: create, or replace to switch the old one off), said once on confirm. Previews by default; call again with confirm: true to sign. For guided setup, follow /pro/mcp.md#create-your-pro-profile on the matching Pro Asks host. Start with connect_linkedin: its verified profile pre-fills the name, headline, LinkedIn link and handle; ask only for what LinkedIn lacks (the work they take, rate, availability, a line about them). This tool reads no site itself, so build the rest from what the person tells you or pastes. Spends nothing.",
292657
292511
  spends: false,
292658
292512
  hosted: false,
292659
292513
  annotations: { ...acts, idempotentHint: true }
@@ -292672,34 +292526,20 @@ var TOOLS = {
292672
292526
  hosted: false,
292673
292527
  annotations: { ...acts, destructiveHint: true, idempotentHint: true }
292674
292528
  },
292675
- list_marketplaces: {
292676
- title: "List Zones",
292677
- description: "The Zones of Pro Asks: a pro ask names one (draft_call's `sponsor`): the pros invited are LinkedIn verified, and it earns the Zone's share of each approved report. For each: its name and slug, what it does, since when, and how many LinkedIn-verified pros are on its roster. A pro gets on every roster with connect_linkedin. Nothing ranks them. Spends nothing.",
292678
- spends: false,
292679
- hosted: false,
292680
- annotations: reads
292681
- },
292682
292529
  connect_linkedin: {
292683
292530
  title: "Verify your pro page with LinkedIn",
292684
- description: "Give the person you act for (or this key's own page) a link to log in to LinkedIn. Logging in puts a LinkedIn-verified tick on their pro page (it means: this person logged in to this LinkedIn account), and that is what lets them be invited to any Zone's pro ask. Show the link and say: open it and log in to LinkedIn. asks.world reads their LinkedIn profile once and keeps no access. Then call again with the `id` it gave: it says whether they are verified and, once they are, gives the name, headline, LinkedIn link and a handle to pre-fill set_my_page. One LinkedIn account verifies one asks.world account. Spends nothing.",
292531
+ description: "Give the person you act for (or this key's own page) a link to log in to LinkedIn. Logging in puts a LinkedIn-verified tick on their pro page (it means: this person logged in to this LinkedIn account), and that is what lets them be invited to a pro ask. Show the link and say: open it and log in to LinkedIn. asks.world reads their LinkedIn profile once and keeps no access. Then call again with the `id` it gave: it says whether they are verified and, once they are, gives the name, headline, LinkedIn link and a handle to pre-fill set_my_page. One LinkedIn account verifies one asks.world account. Spends nothing.",
292685
292532
  spends: false,
292686
292533
  hosted: false,
292687
292534
  annotations: acts
292688
292535
  },
292689
292536
  find_pro: {
292690
292537
  title: "Find pros, or one person's page",
292691
- description: "Suggest three to five pros who can be invited to a Zone's pro asks (`sponsor`, from list_marketplaces; left out, any Zone's): LinkedIn-verified pros. Narrow by `q` (what the pro ask needs, or any words: Android, payments, a name) and `available` (open to work now). Each row: who they are, \"LinkedIn verified \xB7 date\" with their LinkedIn, their rate, their page with their record, and how to invite them. Newest verification first; nothing ranks them, and the person chooses. Then invite_to_call. With `handle` (an @handle or an ixo1 address) it reads that one person's page instead: who they are, what they do, their rate, and the address to invite. Spends nothing.",
292538
+ description: 'Suggest three to five verified pros to invite to a pro ask: the listed ones, by field. Narrow by `q` (what the pro ask needs, or any words: Android, payments, a name) and `available` (open to work now). Each row: who they are, "LinkedIn verified \xB7 date" with their LinkedIn, their rate, their page with their record, and how to invite them. Newest verification first; nothing ranks them, and the person chooses. Then invite_to_call. A private page is in no list, yet any verified pro can be invited by their exact @handle or ixo1 address. With `handle` (an exact @handle or an ixo1 address) it reads that one person\'s public page instead: who they are, what they do, their rate, and the address to invite. Spends nothing.',
292692
292539
  spends: false,
292693
292540
  hosted: true,
292694
292541
  annotations: reads
292695
292542
  },
292696
- set_marketplace_page: {
292697
- title: "Write your Zone's page",
292698
- description: "Write the page of the Zone the person you act for hosts (or this key's own, when it is the Zone's account) on Pro Asks: its own words, under the line every Zone's page opens with. A deck line, a logo, a cover, its story in paragraphs, how it verifies pros as steps, pictures and links; every picture, logo and link is an https address on its own site, and nothing is uploaded. It replaces the page whole. Previews the page as text by default: show it to the person, and call again with confirm: true to sign and publish it only once they say yes. Only an approved Zone's account, or the agent it connected, can. Answers with the page's address. Spends nothing.",
292699
- spends: false,
292700
- hosted: false,
292701
- annotations: { ...acts, idempotentHint: true }
292702
- },
292703
292543
  create_campaign: {
292704
292544
  title: "Create a campaign with its own requirements",
292705
292545
  description: "Mint a campaign: a campaign protocol plus its shared claim protocol carrying the requirements every answer in it is checked against. Minted and owned by the connected person (the organisation's owner or admin, via connect_account), never by this server's key. Previews by default; call again with the same values and confirm: true to mint. Then post its Asks with `post_ask campaign: <the campaign's id>`. Spends only network fees.",
@@ -293166,8 +293006,8 @@ var FACT_LABELS = {
293166
293006
  };
293167
293007
  var humanise = (s) => s.replace(/^\$/, "").replace(/([a-z])([A-Z])/g, "$1 $2").replace(/[._-]+/g, " ").trim().replace(/^./, (c) => c.toUpperCase()).replace(/(?<=\s)([A-Z])(?=[a-z])/g, (c) => c.toLowerCase());
293168
293008
  function codeLabel(code10) {
293169
- const words5 = /^[A-Z0-9]+-\d+-([A-Z0-9-]+)$/.exec(code10)?.[1];
293170
- return words5 ? humanise(words5.toLowerCase()) : humanise(code10);
293009
+ const words4 = /^[A-Z0-9]+-\d+-([A-Z0-9-]+)$/.exec(code10)?.[1];
293010
+ return words4 ? humanise(words4.toLowerCase()) : humanise(code10);
293171
293011
  }
293172
293012
  function leaves(node, out = []) {
293173
293013
  if (Array.isArray(node)) for (const n of node) leaves(n, out);
@@ -293871,10 +293711,10 @@ ${problems.map((one) => `- ${one}`).join("\n")}`;
293871
293711
  async function sendOnce(send, world, report, files, manifest, digest2) {
293872
293712
  const prior = await priorSend(world, digest2, send.collectionId, "report");
293873
293713
  if ("said" in prior) return prior.said;
293874
- let record3 = prior.record;
293875
- const words5 = storeWords(world.private);
293714
+ let record2 = prior.record;
293715
+ const words4 = storeWords(world.private);
293876
293716
  let prepared = false;
293877
- if (!record3) {
293717
+ if (!record2) {
293878
293718
  await world.put(digest2, { state: "previewed" });
293879
293719
  return [
293880
293720
  `Not sent yet. Show the person this whole report and these files, then call submit_work again with exactly the same report and files: they approve it in a dialog before anything is sent.`,
@@ -293882,7 +293722,7 @@ async function sendOnce(send, world, report, files, manifest, digest2) {
293882
293722
  JSON.stringify(report, null, 2),
293883
293723
  "",
293884
293724
  ...summaryOf2(report, manifest, digest2).slice(7),
293885
- words5.preview
293725
+ words4.preview
293886
293726
  ].join("\n");
293887
293727
  }
293888
293728
  const stopped = stoppedWords(world.site, send.collectionId, "report");
@@ -293890,12 +293730,12 @@ async function sendOnce(send, world, report, files, manifest, digest2) {
293890
293730
  const no2 = stopped(
293891
293731
  await world.ask(`Use what I remember about you in this report?
293892
293732
 
293893
- Parts of this report for ask #${send.collectionId} came from what Claude remembers about you or from earlier chats. ${words5.memory}`, "memory"),
293733
+ Parts of this report for ask #${send.collectionId} came from what Claude remembers about you or from earlier chats. ${words4.memory}`, "memory"),
293894
293734
  "Nothing was sent: leave out what came from memory, then call again with uses_memory: false."
293895
293735
  );
293896
293736
  if (no2) return no2;
293897
293737
  }
293898
- let stored = record3?.files;
293738
+ let stored = record2?.files;
293899
293739
  if (!stored && files.length) {
293900
293740
  const no2 = stopped(
293901
293741
  await world.ask(
@@ -293903,7 +293743,7 @@ Parts of this report for ask #${send.collectionId} came from what Claude remembe
293903
293743
  `Upload these ${files.length} ${files.length === 1 ? "file" : "files"} for ask #${send.collectionId}?`,
293904
293744
  ...manifest.map((one) => `- ${one.path} (${one.mediaType}, ${Math.ceil(one.bytes / 1024)} KB) sha256 ${one.sha256}`),
293905
293745
  "",
293906
- `${words5.upload} The report itself is asked about next.`,
293746
+ `${words4.upload} The report itself is asked about next.`,
293907
293747
  `Digest: ${digest2}`
293908
293748
  ].join("\n"),
293909
293749
  "upload"
@@ -293919,8 +293759,8 @@ Parts of this report for ask #${send.collectionId} came from what Claude remembe
293919
293759
  const up = await uploadAll(world, files);
293920
293760
  if (typeof up === "string") return up;
293921
293761
  stored = up;
293922
- record3 = { state: "uploaded", files: stored };
293923
- await world.put(digest2, record3);
293762
+ record2 = { state: "uploaded", files: stored };
293763
+ await world.put(digest2, record2);
293924
293764
  }
293925
293765
  stored ??= [];
293926
293766
  const no = stopped(
@@ -293929,11 +293769,11 @@ Parts of this report for ask #${send.collectionId} came from what Claude remembe
293929
293769
  `Send this review report to ask #${send.collectionId}, as ${send.submitter}?`,
293930
293770
  "",
293931
293771
  ...summaryOf2(report, manifest, digest2),
293932
- `The full report was shown in the conversation before this. ${words5.sent}`
293772
+ `The full report was shown in the conversation before this. ${words4.sent}`
293933
293773
  ].join("\n"),
293934
293774
  "publish"
293935
293775
  ),
293936
- files.length ? `Nothing was sent (${words5.filesKept}).` : "Nothing was sent."
293776
+ files.length ? `Nothing was sent (${words4.filesKept}).` : "Nothing was sent."
293937
293777
  );
293938
293778
  if (no) return no;
293939
293779
  const unprepared = prepared ? null : await world.prepare();
@@ -293941,7 +293781,7 @@ Parts of this report for ask #${send.collectionId} came from what Claude remembe
293941
293781
  const primary = files.find((one) => one.mediaType === "application/pdf") ?? files[0];
293942
293782
  const primaryAt = primary ? stored.find((one) => one.id === primary.id) : void 0;
293943
293783
  const primaryCid = primaryAt ? primaryAt.url.split("/").pop() ?? null : null;
293944
- const envelope = record3?.envelope ?? await sealText(world, {
293784
+ const envelope = record2?.envelope ?? await sealText(world, {
293945
293785
  collectionId: send.collectionId,
293946
293786
  ts: world.now(),
293947
293787
  submitter: send.submitter,
@@ -293954,34 +293794,34 @@ Parts of this report for ask #${send.collectionId} came from what Claude remembe
293954
293794
  ...reportEnvelope(report, stored)
293955
293795
  });
293956
293796
  if (typeof envelope !== "string") return envelope.refused;
293957
- const sealed = await publishOnce(world, digest2, { ...record3 ?? { state: "uploaded" }, files: stored }, envelope);
293797
+ const sealed = await publishOnce(world, digest2, { ...record2 ?? { state: "uploaded" }, files: stored }, envelope);
293958
293798
  if (typeof sealed === "string") return sealed;
293959
293799
  return broadcastOnce(world, digest2, sealed, send.collectionId, "report", `Answered #${send.collectionId} with a review report as ${send.submitter}.`);
293960
293800
  }
293961
293801
  async function priorSend(world, digest2, collectionId, what) {
293962
- let record3;
293802
+ let record2;
293963
293803
  try {
293964
- record3 = await world.get(digest2);
293804
+ record2 = await world.get(digest2);
293965
293805
  } catch {
293966
293806
  return { said: `Refused: the record of an earlier send of this exact ${what} (digest ${digest2}, in the answers folder under OPENHANDS_HOME) cannot be read. Nothing was sent. Look at the ask's receipt page first; remove the record only if you are sure it never went.` };
293967
293807
  }
293968
- if (record3?.claimId && (record3.state === "submitting" || record3.state === "submitted")) {
293969
- const seen2 = await world.onChain(record3.claimId);
293808
+ if (record2?.claimId && (record2.state === "submitting" || record2.state === "submitted")) {
293809
+ const seen2 = await world.onChain(record2.claimId);
293970
293810
  if (seen2) {
293971
- await world.put(digest2, { ...record3, state: "submitted" });
293811
+ await world.put(digest2, { ...record2, state: "submitted" });
293972
293812
  return { said: `Already sent: this exact ${what} is recorded for #${collectionId}.
293973
- answer ${record3.claimId}${record3.tx ? `
293974
- transaction ${record3.tx}` : ""}
293975
- ${receiptLine(world.site, collectionId, record3.claimId, world.reviewSlug)}` };
293813
+ answer ${record2.claimId}${record2.tx ? `
293814
+ transaction ${record2.tx}` : ""}
293815
+ ${receiptLine(world.site, collectionId, record2.claimId, world.reviewSlug)}` };
293976
293816
  }
293977
293817
  return {
293978
293818
  said: [
293979
293819
  `Not sent again: an earlier send of this exact ${what} (digest ${digest2}) may already be recorded, and ${seen2 === null ? "the ledger could not be read just now" : "the index has not shown it yet"}.`,
293980
- `Look at ${receiptLine(world.site, collectionId, record3.claimId, world.reviewSlug).slice("Receipt: ".length)} in a few minutes. This tool never sends the same ${what} twice.`
293820
+ `Look at ${receiptLine(world.site, collectionId, record2.claimId, world.reviewSlug).slice("Receipt: ".length)} in a few minutes. This tool never sends the same ${what} twice.`
293981
293821
  ].join("\n")
293982
293822
  };
293983
293823
  }
293984
- return { record: record3 };
293824
+ return { record: record2 };
293985
293825
  }
293986
293826
  var stoppedWords = (site, collectionId, what) => (approval, tail) => approval.answer === "approved" ? null : approval.answer === "unsupported" ? `Refused: sending ${what === "report" ? "a report" : "an answer"} needs your OK in a dialog, and this client cannot show one. Use Claude Code in a terminal, or answer on the website: ${site}/submit/${collectionId}. Nothing was sent.` : `${tail} ${approval.answer === "declined" ? "The person said no" : approval.answer === "cancelled" ? "The client closed the dialog without the person's answer" : "No answer came back from the person"}. Change the ${what} and call again, or answer on the website: ${site}/submit/${collectionId}.`;
293987
293827
  var sealText = async (world, envelope) => world.private && world.fit ? world.fit(envelope) : JSON.stringify(envelope);
@@ -293998,18 +293838,18 @@ async function uploadAll(world, files) {
293998
293838
  }
293999
293839
  return stored;
294000
293840
  }
294001
- async function publishOnce(world, digest2, record3, envelope) {
294002
- if (record3.envelope && record3.claimId) return record3;
293841
+ async function publishOnce(world, digest2, record2, envelope) {
293842
+ if (record2.envelope && record2.claimId) return record2;
294003
293843
  const published = await world.publish(envelope);
294004
293844
  if (!published) return storeWords(world.private).refusedEnvelope;
294005
293845
  if (published.cid !== cidOfText2(envelope)) return "The store gave it another address than its own bytes. Nothing was sent.";
294006
- const next = { ...record3, state: "published", envelope, claimId: published.cid };
293846
+ const next = { ...record2, state: "published", envelope, claimId: published.cid };
294007
293847
  await world.put(digest2, next);
294008
293848
  return next;
294009
293849
  }
294010
- async function broadcastOnce(world, digest2, record3, collectionId, what, done) {
294011
- const claimId = record3.claimId;
294012
- await world.put(digest2, { ...record3, state: "submitting" });
293850
+ async function broadcastOnce(world, digest2, record2, collectionId, what, done) {
293851
+ const claimId = record2.claimId;
293852
+ await world.put(digest2, { ...record2, state: "submitting" });
294013
293853
  let tx;
294014
293854
  try {
294015
293855
  tx = await world.submit(claimId);
@@ -294021,10 +293861,10 @@ async function broadcastOnce(world, digest2, record3, collectionId, what, done)
294021
293861
  ].filter(Boolean).join("\n");
294022
293862
  }
294023
293863
  if (typeof tx !== "string") {
294024
- await world.put(digest2, { ...record3, state: "published" });
293864
+ await world.put(digest2, { ...record2, state: "published" });
294025
293865
  return [`The network refused the answer, so nothing was sent: ${tx.failed}. Fix what it says, then call submit_work again with the same ${what}.`, storeWords(world.private).kept].filter(Boolean).join(" ");
294026
293866
  }
294027
- await world.put(digest2, { ...record3, state: "submitted", tx });
293867
+ await world.put(digest2, { ...record2, state: "submitted", tx });
294028
293868
  return [`${done}
294029
293869
  answer ${claimId}
294030
293870
  transaction ${tx}
@@ -294042,11 +293882,11 @@ function answersStore(dir) {
294042
293882
  const text4 = await (await fs2()).readFile(path(digest2), "utf8").catch((error54) => error54.code === "ENOENT" ? null : Promise.reject(error54));
294043
293883
  return text4 === null ? null : JSON.parse(text4);
294044
293884
  },
294045
- async put(digest2, record3) {
293885
+ async put(digest2, record2) {
294046
293886
  const { mkdir, rename, writeFile } = await fs2();
294047
293887
  await mkdir(dir, { recursive: true, mode: 448 });
294048
293888
  const tmp = `${path(digest2)}.${process.pid}.tmp`;
294049
- await writeFile(tmp, JSON.stringify(record3), { mode: 384 });
293889
+ await writeFile(tmp, JSON.stringify(record2), { mode: 384 });
294050
293890
  await rename(tmp, path(digest2));
294051
293891
  }
294052
293892
  };
@@ -294066,7 +293906,7 @@ init_checkers();
294066
293906
  init_format();
294067
293907
  import { basename as basename2, isAbsolute as isAbsolute2 } from "node:path";
294068
293908
  var questionsLine = (fields) => fields.map((field2) => `${field2.name} (${field2.label}${field2.required ? ", needed" : ""}${field2.type === "file" ? ", a file path" : field2.enum ? `: ${field2.enum.join(" | ")}` : field2.type === "string" ? "" : `, ${field2.type}`})`).join("; ");
294069
- var sentence2 = (words5) => `${words5.trim().replace(/[.\s]+$/, "")}.`;
293909
+ var sentence2 = (words4) => `${words4.trim().replace(/[.\s]+$/, "")}.`;
294070
293910
  function checkersListing(experts, network2) {
294071
293911
  const priceWords = (base6, denom) => base6 === null || !denom ? "no published fee" : `${coinWords(base6, denom, network2 !== "mainnet")} per check`;
294072
293912
  return [
@@ -294122,8 +293962,8 @@ async function sendFields(send, world) {
294122
293962
  try {
294123
293963
  const prior = await priorSend(world, digest2, send.collectionId, "answer");
294124
293964
  if ("said" in prior) return prior.said;
294125
- let record3 = prior.record;
294126
- if (!record3) {
293965
+ let record2 = prior.record;
293966
+ if (!record2) {
294127
293967
  await world.put(digest2, { state: "previewed" });
294128
293968
  return [
294129
293969
  "Not sent yet. Show the person these answers and files, then call submit_work again with exactly the same fields: they approve the files and then the answer in dialogs before anything is sent.",
@@ -294138,9 +293978,9 @@ async function sendFields(send, world) {
294138
293978
  ].join("\n");
294139
293979
  }
294140
293980
  const stopped = stoppedWords(world.site, send.collectionId, "answer");
294141
- const words5 = storeWords(world.private);
293981
+ const words4 = storeWords(world.private);
294142
293982
  let prepared = false;
294143
- let stored = record3.files;
293983
+ let stored = record2.files;
294144
293984
  if (!stored && files.length) {
294145
293985
  const no2 = stopped(
294146
293986
  await world.ask(
@@ -294148,7 +293988,7 @@ async function sendFields(send, world) {
294148
293988
  `Upload these ${files.length} ${files.length === 1 ? "file" : "files"} for ask #${send.collectionId}?`,
294149
293989
  ...fileLines,
294150
293990
  "",
294151
- `${words5.upload} The answer itself is asked about next.`,
293991
+ `${words4.upload} The answer itself is asked about next.`,
294152
293992
  `Digest: ${digest2}`
294153
293993
  ].join("\n"),
294154
293994
  "upload"
@@ -294164,25 +294004,25 @@ async function sendFields(send, world) {
294164
294004
  const up = await uploadAll(world, files);
294165
294005
  if (typeof up === "string") return up;
294166
294006
  stored = up;
294167
- record3 = { state: "uploaded", files: stored };
294168
- await world.put(digest2, record3);
294007
+ record2 = { state: "uploaded", files: stored };
294008
+ await world.put(digest2, record2);
294169
294009
  }
294170
294010
  stored ??= [];
294171
294011
  const no = stopped(
294172
294012
  await world.ask(
294173
- [`Send this answer to ask #${send.collectionId}, as ${send.submitter}?`, "", ...answerLines, "", files.length ? "Files:" : "Files: none", ...fileLines, "", `Digest: ${digest2}`, words5.sent].join("\n"),
294013
+ [`Send this answer to ask #${send.collectionId}, as ${send.submitter}?`, "", ...answerLines, "", files.length ? "Files:" : "Files: none", ...fileLines, "", `Digest: ${digest2}`, words4.sent].join("\n"),
294174
294014
  "answer"
294175
294015
  ),
294176
- files.length ? `Nothing was sent (${words5.filesKept}).` : "Nothing was sent."
294016
+ files.length ? `Nothing was sent (${words4.filesKept}).` : "Nothing was sent."
294177
294017
  );
294178
294018
  if (no) return no;
294179
294019
  const unprepared = prepared ? null : await world.prepare();
294180
294020
  if (unprepared) return unprepared;
294181
294021
  const values = { ...send.values };
294182
294022
  for (const field2 of fileFields) values[field2.name] = stored.filter((one) => one.id === field2.name).map((one) => ({ name: one.name, type: one.mediaType, url: one.url }));
294183
- const envelope = record3.envelope ?? await sealText(world, checkEnvelope({ fields: send.fields, values, collectionId: send.collectionId, submitter: send.submitter, ts: world.now(), ...send.delegate ? { delegate: send.delegate } : {}, ...send.alias ? { alias: send.alias } : {}, via: "mcp" }));
294023
+ const envelope = record2.envelope ?? await sealText(world, checkEnvelope({ fields: send.fields, values, collectionId: send.collectionId, submitter: send.submitter, ts: world.now(), ...send.delegate ? { delegate: send.delegate } : {}, ...send.alias ? { alias: send.alias } : {}, via: "mcp" }));
294184
294024
  if (typeof envelope !== "string") return envelope.refused;
294185
- const sealed = await publishOnce(world, digest2, { ...record3, files: stored }, envelope);
294025
+ const sealed = await publishOnce(world, digest2, { ...record2, files: stored }, envelope);
294186
294026
  if (typeof sealed === "string") return sealed;
294187
294027
  return broadcastOnce(world, digest2, sealed, send.collectionId, "answer", `Answered #${send.collectionId} as ${send.submitter}.`);
294188
294028
  } finally {
@@ -294711,7 +294551,7 @@ Each is its own ask and pays on its own. Read one with read_ask before deciding.
294711
294551
  return [
294712
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`,
294713
294553
  title ? asData("ask-title", title) : "",
294714
- `${review ? "A specialist's report on the review's scenarios, assessed against its requirements. A report that meets them qualifies for payment, after the builder's final approval when they give one." : "A written entry assessed against five requirements. Entries that meet all five qualify for payment. 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}`}`
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}`}`
294715
294555
  ].filter(Boolean).join("\n");
294716
294556
  };
294717
294557
  const lines2 = board.rows.filter(within2).map((row) => {
@@ -294797,7 +294637,7 @@ ${notes.join("\n")}${notes.length ? "\n\n" : ""}Read one with read_ask before de
294797
294637
  const { callReadout: callReadout2 } = await Promise.resolve().then(() => (init_call2(), call_exports2));
294798
294638
  terms = callReadout2(read9, { id: collectionId, symbol: shown2?.symbol ?? ASK_SYMBOL, site: SITE, network: NETWORK2 });
294799
294639
  postedShare = read9.call.share ?? null;
294800
- proAsk = Boolean(read9.call.sponsor);
294640
+ proAsk = read9.call.kind === "review";
294801
294641
  }
294802
294642
  }
294803
294643
  }
@@ -294951,7 +294791,7 @@ You cannot complete it, and trying would spend the gate's network fee to be reje
294951
294791
  lane = opened;
294952
294792
  }
294953
294793
  let acceptedFirst = "";
294954
- const withAccepted = (words5) => [acceptedFirst, words5].filter(Boolean).join("\n");
294794
+ const withAccepted = (words4) => [acceptedFirst, words4].filter(Boolean).join("\n");
294955
294795
  const answerFirst = async () => {
294956
294796
  const invitesModule = await Promise.resolve().then(() => (init_invites(), invites_exports));
294957
294797
  const signer3 = await inviteSigner(acting);
@@ -295678,7 +295518,7 @@ ${SITE}/t/${earlier.id}`);
295678
295518
  const image = work?.image ? work.image.startsWith("/") ? `${SITE}${work.image}` : work.image : void 0;
295679
295519
  if (work?.text || image) artifact = work?.text ? { kind: image ? "submission" : "text", body: work.text, url: image } : { kind: "image", url: image };
295680
295520
  }
295681
- const record3 = await fetch2(`${SITE}/api/waiting?address=${encodeURIComponent(approved.agentAddress)}`, { signal: AbortSignal.timeout(15e3) }).then((response) => response.ok ? response.json() : null).catch(() => null);
295521
+ const record2 = await fetch2(`${SITE}/api/waiting?address=${encodeURIComponent(approved.agentAddress)}`, { signal: AbortSignal.timeout(15e3) }).then((response) => response.ok ? response.json() : null).catch(() => null);
295682
295522
  const terms = receipt.doneMeansCid ? await participant.readDocJson(receipt.doneMeansCid, { timeoutMs: 15e3, fetchImpl: fetch2, at: receipt.doneMeansUrl }) : null;
295683
295523
  const { isPrivateTerms: isPrivateTerms2 } = await Promise.resolve().then(() => (init_lane(), lane_exports));
295684
295524
  if (receipt.access || isPrivateTerms2(terms)) {
@@ -295721,7 +295561,7 @@ ${SITE}/t/${earlier.id}`);
295721
295561
  if (!where2 && mode !== "url-check") mode = mode === "photo" ? "photo-anywhere" : "written";
295722
295562
  const followsUp = Boolean(terms?.followUp);
295723
295563
  const { evidenceFrom: evidenceFrom2, evidenceLines: evidenceLines2, WORTH: WORTH2 } = await Promise.resolve().then(() => (init_confidence(), confidence_exports));
295724
- const verifiedHere = record3?.record?.approved ?? 0;
295564
+ const verifiedHere = record2?.record?.approved ?? 0;
295725
295565
  const evidence = evidenceFrom2(
295726
295566
  [
295727
295567
  {
@@ -296332,12 +296172,41 @@ ${pending.link}`);
296332
296172
  return [];
296333
296173
  }
296334
296174
  })();
296175
+ const rooms = await (async () => {
296176
+ try {
296177
+ const [{ roomLines: roomLines2 }, invitesModule, roomsModule] = await Promise.all([Promise.resolve().then(() => (init_meRooms(), meRooms_exports)), Promise.resolve().then(() => (init_invites(), invites_exports)), Promise.resolve().then(() => (init_rooms(), rooms_exports))]);
296178
+ const signer3 = await inviteSigner(await principal2());
296179
+ const [page, invited, mineRooms, waiting, agents] = await Promise.all([
296180
+ invitesModule.readMyPage(SITE, signer3).catch(() => void 0),
296181
+ invitesModule.myInvitations(SITE, signer3).catch(() => null),
296182
+ roomsModule.myRooms(SITE, signer3).catch(() => null),
296183
+ fetch2(`${SITE}/api/waiting?address=${encodeURIComponent(signer3.address)}`, { signal: AbortSignal.timeout(2e4) }).then((r) => r.ok ? r.json() : null).catch(() => null),
296184
+ fetch2(`${SITE}/api/connect?principal=${encodeURIComponent(signer3.address)}`, { signal: AbortSignal.timeout(2e4) }).then((r) => r.ok ? r.json() : null).catch(() => null)
296185
+ ]);
296186
+ const verified = page?.linkedin?.verifiedAt;
296187
+ return [
296188
+ "You, as the account area says it:",
296189
+ ...roomLines2({
296190
+ page: page === void 0 ? null : page === null ? "none" : !verified ? "verify" : page.profile.listed === false ? "private" : "listed",
296191
+ work: invited && "invited" in invited ? invited.invited.filter((one) => one.answer === "sent").length : null,
296192
+ unread: mineRooms && "rooms" in mineRooms ? mineRooms.rooms.reduce((sum2, one) => sum2 + one.unread, 0) : null,
296193
+ inbox: Array.isArray(waiting?.waiting) ? waiting.waiting.length : null,
296194
+ money: { available: pays(Number(held[ASK_DENOM] ?? 0), ASK_DENOM), onAsks: onAsks ? pays(onAsks, "upay") : null },
296195
+ agents: Array.isArray(agents?.delegations) ? agents.delegations.length : null
296196
+ }).map((line2) => ` ${line2}`),
296197
+ ""
296198
+ ];
296199
+ } catch {
296200
+ return [];
296201
+ }
296202
+ })();
296335
296203
  return text4(
296336
296204
  [
296337
296205
  `Address: ${mine}`,
296338
296206
  actingNote(connection.acting) ?? connection.problem ?? "",
296339
296207
  candidateWords2(connection.candidates) ?? "",
296340
296208
  ...news,
296209
+ ...rooms,
296341
296210
  /* The two places money lives, as the site says them: Available is this key's own, On your asks what its asks hold.
296342
296211
  The review fee's coin, where it is not the reward's (mainnet: USDC rewards, PAY fees), is what covers the next
296343
296212
  ask's checks, so it is said when there is any. In dollars, as every amount. The network fee is the gate's to
@@ -296462,7 +296331,7 @@ claude mcp add ${MCP_SERVER} ${Object.entries(callEnv).map(([name8, value]) => `
296462
296331
  ...npxCacheLines(),
296463
296332
  ...plugin,
296464
296333
  ...blocks,
296465
- `Each agent makes its own key on first run and earns to its own address. This board (${SITE}) pays every reward in this network's own coin, said in dollars. The server reads the default, the deployment's addresses, the Zone its Asks name and the claim form their rules bind to, from ${SITE}/api/config at boot (and again on a later call if that read failed), so nothing else needs setting.`,
296334
+ `Each agent makes its own key on first run and earns to its own address. This board (${SITE}) pays every reward in this network's own coin, said in dollars. The server reads the default, the deployment's addresses and the claim form every ask's rules bind to, from ${SITE}/api/config at boot (and again on a later call if that read failed), so nothing else needs setting.`,
296466
296335
  /* A server that cannot post says so here, with what to set, before anyone tries. */
296467
296336
  CLAIM_FORM ? bindingDetail() : `${bindingDetail()}
296468
296337
  Set all three, ${CLAIM_FORM_ENV.join(", ")}, in this server's environment, to the values the deployment published (scripts/publish-vct.ts prints them).${callLine ? " The open-call line below carries the sandbox's." : ""}`,
@@ -296574,8 +296443,7 @@ Mapping pays for the report. What happens to a mapped pin afterwards is a separa
296574
296443
  brief: external_exports.array(external_exports.string().max(1500)).max(8).optional().describe("The story, up to eight short paragraphs, in the person's words."),
296575
296444
  lines: external_exports.array(external_exports.object({ text: external_exports.string().max(300), fail: external_exports.string().max(300).optional() })).max(5).optional().describe('The five requirements the jury reviews. For each, write the requirement in `text` and the condition that fails it in `fail`. Write `fail` as a clause completing "Fail this only if \u2026", for example "it names no page". Include all five.'),
296576
296445
  mode: external_exports.enum(["competition", "hire"]).optional().describe("competition: a pick and runners-up beside the paid entries. hire: every entry that passes is paid the same, up to a number, and nobody is picked."),
296577
- kind: external_exports.literal("review").optional().describe("review: a pro ask on Pro Asks, a review of an app or an agent. LinkedIn-verified pros, invited through the Zone you name (sponsor), try the scenarios and hand in review reports; every report that passes the lines is paid the same (a hire); by invitation only; the five lines default to the review's own unless given. Asky Pro Checker, the verifier, checks each report for its own fee per check, held with the reward."),
296578
- sponsor: external_exports.string().max(40).optional().describe("A pro ask: the Zone's slug, as list_marketplaces gives it. The pros you invite come from its roster; it earns the Zone's share."),
296446
+ kind: external_exports.literal("review").optional().describe("review: a pro ask on Pro Asks, a review of an app or an agent. Verified pros you invite try the scenarios and hand in review reports; every report that passes the lines is paid the same (a hire); by invitation only; the five lines default to the review's own unless given. Asky Pro Checker, the verifier, checks each report for its own fee per check, held with the reward."),
296579
296447
  subject: external_exports.object({ name: external_exports.string().max(120), version: external_exports.string().max(40).optional(), where: external_exports.string().max(2048).optional() }).optional().describe("A review: what is reviewed, the version to test, and where a specialist finds it (a public address). Private access goes in the invitation note, never here."),
296580
296448
  scenarios: external_exports.array(external_exports.string().max(300)).max(8).optional().describe("A review: the scenarios to try, one line each; every report must cover each with a step."),
296581
296449
  report: external_exports.array(external_exports.string().max(60)).max(5).optional().describe("A review: extra section headings every report must have, besides the standard summary, steps, findings, recommendations and limitations. Empty is fine."),
@@ -296610,29 +296478,17 @@ Mapping pays for the report. What happens to a mapped pin afterwards is a separa
296610
296478
  const changing = clear || Object.values(input).some((value) => value !== void 0);
296611
296479
  if (posted && changing) return text4(`Call "${slug}" is already posted: its terms were frozen with the money. Start a new call with another slug.`);
296612
296480
  const start = clear || !existing ? call2.freshDraft(slug) : existing;
296613
- const marketplaces = await Promise.resolve().then(() => (init_marketplaces(), marketplaces_exports));
296614
- let given2 = input;
296615
- const notTaken = [];
296616
- const namedSponsor = input.sponsor?.trim().toLowerCase();
296617
- if (namedSponsor && CALL_SLUG2.test(namedSponsor)) {
296618
- const checked = await marketplaces.resolveMarketplace(SITE, namedSponsor, NETWORK2, fetch2);
296619
- if ("refused" in checked && !checked.unavailable) {
296620
- notTaken.push(checked.refused);
296621
- given2 = { ...input, sponsor: void 0 };
296622
- }
296623
- }
296624
- const merged = call2.mergeDraft(start, given2);
296481
+ const merged = call2.mergeDraft(start, input);
296625
296482
  const coin = call2.callCoin(merged.draft, NETWORK2, ASK_DENOM);
296626
296483
  if (typeof coin !== "string") return text4(`Refused: ${coin.refused}. Nothing was saved.`);
296627
- const refused2 = [...notTaken, ...merged.refused];
296484
+ const refused2 = merged.refused;
296628
296485
  const draft = coin !== ASK_DENOM ? { ...merged.draft, coin } : merged.draft;
296629
296486
  call2.writeDraft(draft);
296630
296487
  const coinSymbol = symbolOf(coin);
296631
296488
  const acting = await principal2();
296632
296489
  const held = await heldBy(acting, coin);
296633
296490
  const holds = held === null ? null : pays(held.reward, coinSymbol);
296634
- const choices = draft.fields.kind === "review" && !draft.fields.sponsor ? await marketplaces.readMarketplaces(SITE, fetch2) : null;
296635
- const missing2 = call2.missingOf(draft.fields, { symbol: coinSymbol, holds, marketplaces: choices && "sponsors" in choices ? marketplaces.marketplaceChoices(choices.sponsors) : null });
296491
+ const missing2 = call2.missingOf(draft.fields, { symbol: coinSymbol, holds });
296636
296492
  const out = [`Draft "${slug}" saved${posted ? " (posted)" : ""}.`];
296637
296493
  if (refused2.length) out.push("", "Not taken:", ...refused2.map((one) => ` - ${one}`));
296638
296494
  if (missing2.length) {
@@ -296657,22 +296513,19 @@ Mapping pays for the report. What happens to a mapped pin afterwards is a separa
296657
296513
  return text4(out.join("\n"));
296658
296514
  }
296659
296515
  const proAsk = draft.fields.kind === "review";
296660
- const resolved = proAsk && draft.fields.sponsor ? await marketplaces.resolveMarketplace(SITE, draft.fields.sponsor, NETWORK2, fetch2) : null;
296661
- const sponsor = resolved && "sponsor" in resolved ? resolved.sponsor : null;
296662
- const sponsorProblem = resolved && "refused" in resolved ? resolved : null;
296663
- 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, sponsor });
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 });
296664
296517
  const feeTotal = plan.legs.reduce((sum2, one) => sum2 + one.feeBase, 0);
296665
296518
  const finalOk = draft.fields.kind === "review" ? acting?.principal ?? null : null;
296666
- const preview = call2.legTerms(draft, "entries", { poster: shortPoster, dates: plan.dates, oracle: { kind: "oracle", address: checker.address || "the verifier" }, approver: finalOk, share: plan.share, sponsor });
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 });
296667
296520
  const twoCoins = acting && feeTotal > 0 ? `Can't post as ${acting.principal}: ${call2.callTwoCoins}.` : null;
296668
296521
  const { capCoinRefusal: capCoinRefusal2, capIn: capIn2 } = await Promise.resolve().then(() => (init_hq(), hq_exports));
296669
296522
  const otherCoin = capCoinRefusal2(acting, coin, checker.fee ? `${SITE}/connect` : void 0);
296670
296523
  const capped4 = call2.capWords(plan.legs, CAP_BASE, coinSymbol, NETWORK2);
296671
296524
  const keyOnly = !acting && feeTotal > 0;
296672
- const blocked = capped4.length > 0 || Boolean(otherCoin) || Boolean(twoCoins) && draft.fields.kind !== "review" || Boolean(sponsorProblem && !sponsorProblem.unavailable);
296525
+ const blocked = capped4.length > 0 || Boolean(otherCoin) || Boolean(twoCoins) && draft.fields.kind !== "review";
296673
296526
  const m = draft.fields.money;
296674
296527
  const { shareWords: shareWords2 } = await Promise.resolve().then(() => (init_callRead(), callRead_exports));
296675
- const proMoney = Boolean(sponsor && plan.share);
296528
+ const proMoney = proAsk && Boolean(plan.share);
296676
296529
  const who = draft.fields.kind === "review" ? "pro" : "hired person";
296677
296530
  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)}` : "";
296678
296531
  const legRows = plan.legs.map(
@@ -296685,8 +296538,7 @@ Mapping pays for the report. What happens to a mapped pin afterwards is a separa
296685
296538
  twoCoins ?? "",
296686
296539
  otherCoin ? `Can't post as it stands: ${otherCoin}.` : "",
296687
296540
  !hire && m.prize < m.entryEach ? `The prize (${face(m.prize, coinSymbol)}) is less than one entry earns (${face(m.entryEach, coinSymbol)}).` : "",
296688
- sponsorProblem ? sponsorProblem.unavailable ? `${sponsorProblem.refused} post_call confirms the Zone again before anything moves.` : `Can't post as it stands: ${sponsorProblem.refused}` : "",
296689
- draft.fields.access === "invite" && !draft.fields.invite?.length ? proAsk ? `Nobody invited yet: find_pro${draft.fields.sponsor ? ` with sponsor: "${draft.fields.sponsor}"` : ""} suggests pros from ${sponsor ? `${sponsor.name}'s` : "the Zone's"} roster; 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.' : "",
296541
+ 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.' : "",
296690
296542
  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." : "",
296691
296543
  ...call2.balanceWarnings(held, { totalBase: plan.totalBase, feeTotal, symbol: coinSymbol, network: NETWORK2, feeWords }),
296692
296544
  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.` : "",
@@ -296759,14 +296611,10 @@ Mapping pays for the report. What happens to a mapped pin afterwards is a separa
296759
296611
  const ids = ["prize", "runnersUp", "entries"].flatMap((leg2) => draft.posted[leg2] ? [`${LEG_WORDS[leg2]} #${draft.posted[leg2].id}`] : []);
296760
296612
  if (!next) return text4(`Everything is posted: ${ids.join(", ")}.
296761
296613
  The call: ${linkOf(draft.posted)}`);
296762
- if (review && !draft.fields.sponsor) return text4(`${call2.PRO_ASK_NEEDS_MARKETPLACE} Nothing was posted.`);
296763
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.`);
296764
296615
  const cannot = await unjudged();
296765
296616
  if (cannot) return text4(cannot);
296766
296617
  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.");
296767
- const marketplace = review ? await (await Promise.resolve().then(() => (init_marketplaces(), marketplaces_exports))).resolveMarketplace(SITE, draft.fields.sponsor, NETWORK2, fetch2) : null;
296768
- if (marketplace && "refused" in marketplace) return text4(`Refused: ${marketplace.refused} Nothing was posted.`);
296769
- const sponsor = marketplace?.sponsor ?? null;
296770
296618
  const acting = card || plain_key && review ? null : await principal2();
296771
296619
  const pick2 = acting || card || confirm ? null : await unchosen();
296772
296620
  if (!acting && !plain_key && !card) {
@@ -296781,11 +296629,11 @@ Then call post_call again. Nothing was posted.`);
296781
296629
  const split3 = call2.callShares(draft.fields) ? await callSplit() : null;
296782
296630
  const priced = call2.callShare(draft.fields, split3);
296783
296631
  if ("unread" in priced) return text4(call2.SHARE_UNREAD);
296784
- 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, sponsor });
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 });
296785
296633
  const feeTotal = plan.legs.reduce((sum2, one) => sum2 + one.feeBase, 0);
296786
296634
  const total = pays(plan.totalBase, coinSymbol);
296787
296635
  const { feeLine: feeLine2 } = await Promise.resolve().then(() => (init_feeLine(), feeLine_exports));
296788
- const moneySentence = sponsor && plan.share ? feeLine2({ split: plan.share, sponsorName: sponsor.name, net: draft.fields.money.entryEach, symbol: coinSymbol, network: NETWORK2 }) : null;
296636
+ const moneySentence = review && plan.share ? feeLine2({ split: plan.share, net: draft.fields.money.entryEach, symbol: coinSymbol, network: NETWORK2 }) : null;
296789
296637
  if (acting && feeTotal > 0) return text4(`Refused: ${call2.callTwoCoins}.${review ? ` ${PLAIN_REVIEW}` : ""} Nothing was posted.`);
296790
296638
  const approver = review && acting ? acting.principal : null;
296791
296639
  if (approver) {
@@ -296800,11 +296648,11 @@ Then call post_call again. Nothing was posted.`);
296800
296648
  const payDraft = await Promise.resolve().then(() => (init_payDraft(), payDraft_exports));
296801
296649
  const rewardBase = plan.legs.reduce((sum2, one) => sum2 + one.payBase * one.escrowSpots, 0);
296802
296650
  const quote = payDraft.quoteOf(rewardBase, plan.totalBase + feeTotal - rewardBase);
296803
- const words5 = payDraft.cardPreview(quote);
296804
- if (typeof words5 !== "string") return text4(`${words5.refused} Nothing was posted.`);
296805
- if (!confirm) return text4([`Call "${slug}" is ${order2.length} Asks: ${order2.map((one) => LEG_WORDS[one]).join(", then ")}.`, ...moneySentence ? [moneySentence] : [], words5].join("\n"));
296651
+ const words4 = payDraft.cardPreview(quote);
296652
+ if (typeof words4 !== "string") return text4(`${words4.refused} Nothing was posted.`);
296653
+ if (!confirm) return text4([`Call "${slug}" is ${order2.length} Asks: ${order2.map((one) => LEG_WORDS[one]).join(", then ")}.`, ...moneySentence ? [moneySentence] : [], words4].join("\n"));
296806
296654
  if (confirm.trim() !== payDraft.confirmToken(quote)) return text4(`Refused: confirm said "${confirm}" but the person pays ${payDraft.confirmToken(quote)}. Preview it again.`);
296807
- const terms = { slug, fields: draft.fields, dates: plan.dates, legs: plan.legs, checker: checker.address, perCheck, ...checker.fee ? { fee: checker.fee } : {}, ...plan.share ? { share: plan.share } : {}, ...sponsor ? { sponsor } : {} };
296655
+ const terms = { slug, fields: draft.fields, dates: plan.dates, legs: plan.legs, checker: checker.address, perCheck, ...checker.fee ? { fee: checker.fee } : {}, ...plan.share ? { share: plan.share } : {} };
296808
296656
  return text4(await payDraft.saveDraft(SITE, { kind: "call", terms, quote, network: NETWORK2 }, fetch2));
296809
296657
  }
296810
296658
  if (!confirm) {
@@ -296864,8 +296712,7 @@ Then call post_call again. Nothing was posted.`);
296864
296712
  mnemonic: key.mnemonic,
296865
296713
  nudge: (event, id) => nudge(event, id, checker.at),
296866
296714
  charge: (escrowBase) => chargeDay("call", escrowBase / MICRO6),
296867
- feeSplit: split3,
296868
- sponsor
296715
+ feeSplit: split3
296869
296716
  });
296870
296717
  } catch (error54) {
296871
296718
  if (error54 instanceof call2.InFlightError || error54 instanceof call2.PostRefused) return text4(error54.message);
@@ -296888,7 +296735,7 @@ The call: ${linkOf(posted.draft.posted)}`);
296888
296735
  return text4(
296889
296736
  [
296890
296737
  `${done} of ${order2.length} posted: ${LEG_WORDS[posted.leg]}, #${posted.id}${acting ? `, as ${acting.principal}` : ""}, locking ${pays(posted.plan.escrowBase, coinSymbol)}.`,
296891
- sponsor ? `A pro ask through ${sponsor.name}, the Zone. ${moneySentence ?? ""}`.trim() : "",
296738
+ moneySentence ?? "",
296892
296739
  held ?? "",
296893
296740
  after ? `Call post_call again for ${LEG_WORDS[after]}.` : [
296894
296741
  held ? `The call is posted but not yet open: ${linkOf(posted.draft.posted)} says so until a person clears the entries. Once it is open:` : await liveLine(posted.id, linkOf(posted.draft.posted)),
@@ -296912,15 +296759,15 @@ ${allowLine(SITE, posted.id, approver, acting?.principal ?? null)}` : `Every rep
296912
296759
  async function writeDraftInvites(draft, entriesId, acting) {
296913
296760
  const invitesModule = await Promise.resolve().then(() => (init_invites(), invites_exports));
296914
296761
  const callModule = await Promise.resolve().then(() => (init_call2(), call_exports2));
296915
- const words5 = draft.fields.invite ?? [];
296916
- if (words5.length === 0)
296762
+ const words4 = draft.fields.invite ?? [];
296763
+ if (words4.length === 0)
296917
296764
  return [
296918
- draft.fields.kind === "review" && draft.fields.sponsor ? `Nobody is on the list yet: find_pro with sponsor: "${draft.fields.sponsor}" suggests pros from the Zone's roster; then invite_to_call slug "${draft.slug}" with the @handles the person chooses.` : draft.fields.access === "invite" ? `Nobody is on the list yet: invite_to_call slug "${draft.slug}" with addresses, @handles, or "link" for each single-use link.` : ""
296765
+ draft.fields.kind === "review" ? `Nobody is on the list yet: find_pro suggests verified pros; then invite_to_call slug "${draft.slug}" with the @handles the person chooses.` : draft.fields.access === "invite" ? `Nobody is on the list yet: invite_to_call slug "${draft.slug}" with addresses, @handles, or "link" for each single-use link.` : ""
296919
296766
  ].filter(Boolean);
296920
- const { items, problems } = invitesModule.inviteItemsOf(words5);
296767
+ const { items, problems } = invitesModule.inviteItemsOf(words4);
296921
296768
  const answer = items.length ? await invitesModule.writeInvitesPatiently(SITE, await inviteSigner(acting), entriesId, items, draft.fields.inviteNote ? { note: draft.fields.inviteNote } : {}) : { written: [], problems: [], tries: 0 };
296922
296769
  if ("refused" in answer) {
296923
- const again = `invite_to_call slug "${draft.slug}" invite ${JSON.stringify(words5)}${draft.fields.inviteNote ? ` note ${JSON.stringify(draft.fields.inviteNote)}` : ""}`;
296770
+ const again = `invite_to_call slug "${draft.slug}" invite ${JSON.stringify(words4)}${draft.fields.inviteNote ? ` note ${JSON.stringify(draft.fields.inviteNote)}` : ""}`;
296924
296771
  return [
296925
296772
  answer.code === invitesModule.NOT_KNOWN_YET ? `Nobody is on the list yet: asked ${answer.tries} times, the board could not name #${entriesId}'s poster (${answer.refused}). The names are kept in the draft. In a minute, run ${again}; until then nobody can enter.` : `The list could not be written: ${answer.refused}. Nobody is on it yet; run ${again}.`
296926
296773
  ];
@@ -296945,12 +296792,12 @@ ${allowLine(SITE, posted.id, approver, acting?.principal ?? null)}` : `Every rep
296945
296792
  return " Copy the links now: they could not be kept on this machine, and only you have them. You can always make a new link with invite_to_call.";
296946
296793
  }
296947
296794
  }
296948
- async function writeAskInvites(askId, words5, acting) {
296949
- if (words5.length === 0) return ['Nobody is on the list yet: invite_to_call with addresses, @handles, or "link" for each single-use link.'];
296795
+ async function writeAskInvites(askId, words4, acting) {
296796
+ if (words4.length === 0) return ['Nobody is on the list yet: invite_to_call with addresses, @handles, or "link" for each single-use link.'];
296950
296797
  const invitesModule = await Promise.resolve().then(() => (init_invites(), invites_exports));
296951
- const { items, problems } = invitesModule.inviteItemsOf(words5);
296798
+ const { items, problems } = invitesModule.inviteItemsOf(words4);
296952
296799
  const answer = await invitesModule.writeInvitesPatiently(SITE, await inviteSigner(acting), askId, items);
296953
- if ("refused" in answer) return [`The list could not be written: ${answer.refused}. Nobody is on it yet; in a minute run invite_to_call collectionId "${askId}" invite ${JSON.stringify(words5)}.`];
296800
+ if ("refused" in answer) return [`The list could not be written: ${answer.refused}. Nobody is on it yet; in a minute run invite_to_call collectionId "${askId}" invite ${JSON.stringify(words4)}.`];
296954
296801
  const at = (/* @__PURE__ */ new Date()).toISOString();
296955
296802
  const kept = answer.written.map((one) => ({ via: one.via, collectionId: askId, at, ...one.id !== void 0 ? { id: one.id } : {}, ...one.token ? { token: one.token } : {}, ...one.address ? { address: one.address } : {}, ...one.handle ? { handle: one.handle } : {} }));
296956
296803
  const saved = kept.length ? await keptOnMachine(askId, kept) : "";
@@ -297011,8 +296858,8 @@ ${allowLine(SITE, posted.id, approver, acting?.principal ?? null)}` : `Every rep
297011
296858
  `Invited on #${entriesId} (${kept.length}):`,
297012
296859
  ...inviteLines(kept, await isReview(draft, entriesId)),
297013
296860
  ...[...problems, ...answer.problems].map((one) => ` not invited: ${one}`),
297014
- /* A pro ask takes only its marketplace's pros; say where they are found. */
297015
- answer.problems.some((one) => invitesModule.OFF_ROSTER.test(one)) ? `A pro ask takes only LinkedIn-verified pros: find_pro${draft?.fields.sponsor ? ` with sponsor: "${draft.fields.sponsor}"` : ""} suggests them.` : "",
296861
+ /* A pro ask takes only verified pros; say so once, and where they are found. */
296862
+ answer.problems.some((one) => invitesModule.OFF_ROSTER.test(one)) ? `${invitesModule.NOT_VERIFIED} find_pro suggests them; connect_linkedin verifies a pro.` : "",
297016
296863
  kept.some((one) => one.via === "link") ? `Hand each link to one person.${saved}` : ""
297017
296864
  ].filter(Boolean).join("\n")
297018
296865
  );
@@ -297231,14 +297078,14 @@ ${allowLine(SITE, posted.id, approver, acting?.principal ?? null)}` : `Every rep
297231
297078
  confirm: external_exports.boolean().optional().describe("false (the default) previews what would be sent; true sends it, once the person has said yes to the preview.")
297232
297079
  }
297233
297080
  },
297234
- async ({ collectionId, with: who, text: words5, confirm }) => {
297081
+ async ({ collectionId, with: who, text: words4, confirm }) => {
297235
297082
  if (!confirm)
297236
297083
  return text4(
297237
297084
  [
297238
297085
  `This is what would happen in the room on pro ask #${collectionId}${who ? ` with ${who.startsWith("ixo1") ? who : `@${who.replace(/^@/, "").toLowerCase()}`}` : ""}:`,
297239
297086
  "- This message is sent, and the other side of the room gets a notice:",
297240
297087
  "",
297241
- words5,
297088
+ words4,
297242
297089
  "",
297243
297090
  "Show this to the person. Then call again with the same values and confirm: true. Nothing was sent."
297244
297091
  ].join("\n")
@@ -297246,7 +297093,7 @@ ${allowLine(SITE, posted.id, approver, acting?.principal ?? null)}` : `Every rep
297246
297093
  const roomsModule = await Promise.resolve().then(() => (init_rooms(), rooms_exports));
297247
297094
  const invitesModule = await Promise.resolve().then(() => (init_invites(), invites_exports));
297248
297095
  const signer3 = await inviteSigner(await principal2());
297249
- const sent = await roomsModule.sendToRoom(SITE, signer3, collectionId, words5, who ? { with: who } : {});
297096
+ const sent = await roomsModule.sendToRoom(SITE, signer3, collectionId, words4, who ? { with: who } : {});
297250
297097
  if ("refused" in sent) return text4(await roomRefusal(sent, collectionId, who, "send_message", signer3));
297251
297098
  const toPoster = sent.pro === roomsModule.actorOf(signer3);
297252
297099
  const page = await invitesModule.readPage(SITE, { address: sent.pro }).catch(() => null);
@@ -297266,7 +297113,6 @@ The room's page: ${roomPage(SITE, collectionId, page?.profile.handle ?? sent.pro
297266
297113
  rate: external_exports.object({ amount: external_exports.number().positive(), unit: external_exports.enum(["hour", "day", "deliverable"]), coin: external_exports.enum(["USDC", "IXO"]) }).nullable().optional(),
297267
297114
  links: external_exports.array(external_exports.string().url().max(2048)).max(6).optional(),
297268
297115
  availability: external_exports.enum(["open", "busy", "closed"]).optional(),
297269
- invitable: external_exports.boolean().optional().describe("May posters invite them by handle? Default true."),
297270
297116
  listed: external_exports.boolean().optional().describe("Public (true) or private (false): a private page is off asks.world, the directory and search, and only someone who types the exact handle or address can invite them. Left out, the page keeps what it says now (public for a new page)."),
297271
297117
  avatar: external_exports.string().max(2048).optional().describe("Their picture: a file on this machine (png, jpg or webp, up to 5 MB) or an https address. Uploaded for them; square works best."),
297272
297118
  banner: external_exports.string().max(2048).optional().describe("A wide picture across the top of the page: a file on this machine or an https address. About 3:1."),
@@ -297325,7 +297171,8 @@ The room's page: ${roomPage(SITE, collectionId, page?.profile.handle ?? sent.pro
297325
297171
  does: page.does ?? [],
297326
297172
  links: page.links ?? [],
297327
297173
  availability: page.availability ?? "open",
297328
- invitable: page.invitable ?? true,
297174
+ /* D3: "may posters invite them" is Open to work, said once: the signed field follows availability. */
297175
+ invitable: (page.availability ?? "open") === "open",
297329
297176
  rate: page.rate ?? null,
297330
297177
  ...avatar ? { avatar: /^https:\/\//.test(avatar) ? avatar : void 0 } : {},
297331
297178
  ...banner ? { banner: /^https:\/\//.test(banner) ? banner : void 0 } : {},
@@ -297369,93 +297216,32 @@ ${page.linkedin?.credentialUrl || page.linkedin?.credential ? `${credentialWords
297369
297216
 
297370
297217
  ` : ""}Edit the profile at ${EXPERT_SITE}/pro/profile.${page.linkedin ? "" : " Next: connect_linkedin verifies it, so you can be invited to pro asks."}`);
297371
297218
  });
297372
- if (offered("list_marketplaces")) server2.registerTool("list_marketplaces", { ...meta3("list_marketplaces"), inputSchema: {} }, async () => {
297373
- const marketplaces = await Promise.resolve().then(() => (init_marketplaces(), marketplaces_exports));
297374
- const list7 = await marketplaces.readMarketplaces(SITE, fetch2);
297375
- if ("unavailable" in list7) return text4(`${list7.unavailable}. Try again in a minute; nothing about the Zones is known until it answers.`);
297376
- const rows2 = await Promise.all(list7.sponsors.map(async (sponsor) => {
297377
- const one = await marketplaces.readMarketplace(SITE, sponsor.slug, fetch2);
297378
- return { sponsor, roster: "sponsor" in one && one.counts ? one.counts.checked : null };
297379
- }));
297380
- return text4(marketplaces.marketplacesWords(rows2, SITE));
297381
- });
297382
297219
  if (offered("find_pro")) server2.registerTool(
297383
297220
  "find_pro",
297384
297221
  {
297385
297222
  ...meta3("find_pro"),
297386
297223
  inputSchema: {
297387
- sponsor: external_exports.string().max(40).optional().describe("The Zone's slug, as list_marketplaces gives it: only pros it verified. Left out, any Zone's."),
297388
- q: external_exports.string().max(60).optional().describe("What the pro ask needs, or any words (Android, payments, a name): searched across each pro's page, as the directory's search box does."),
297224
+ q: external_exports.string().max(60).optional().describe("What the pro ask needs, or any words (Android, payments, a name): searched across each listed pro's page, as the directory's search box does."),
297389
297225
  available: external_exports.boolean().optional().describe("true: only pros open to work now."),
297390
- handle: external_exports.string().max(64).optional().describe("One person's page instead: their @handle or ixo1 address.")
297226
+ handle: external_exports.string().max(64).optional().describe("One person's public page instead: their exact @handle or ixo1 address.")
297391
297227
  }
297392
297228
  },
297393
- async ({ sponsor: slug, q, available, handle: handle2 }) => {
297394
- const marketplaces = await Promise.resolve().then(() => (init_marketplaces(), marketplaces_exports));
297229
+ async ({ q, available, handle: handle2 }) => {
297395
297230
  if (handle2) {
297396
297231
  const invitesModule = await Promise.resolve().then(() => (init_invites(), invites_exports));
297397
297232
  const who = handle2.trim();
297233
+ const named = who.startsWith("ixo1") ? who : `@${who.replace(/^@/, "")}`;
297398
297234
  const page = await invitesModule.readPage(SITE, who.startsWith("ixo1") ? { address: who } : { handle: who });
297399
- if (!page) return text4(`${who.startsWith("ixo1") ? who : `@${who.replace(/^@/, "")}`} binds to nobody here.`);
297235
+ if (!page) return text4(`No public page for ${named}. A private page is not shown; if ${named} is a verified pro, invite_to_call with "${named}" still reaches them.`);
297400
297236
  taint2(page.profile.about ?? "");
297401
297237
  return text4(asData("page", invitesModule.pageWords(page, SITE)));
297402
297238
  }
297403
- const named = slug?.trim().toLowerCase();
297404
- const read9 = named ? await marketplaces.readMarketplace(SITE, named, fetch2) : await marketplaces.readMarketplaces(SITE, fetch2);
297405
- if ("unavailable" in read9) return text4(`${read9.unavailable}, so no roster can be read. Try again in a minute.`);
297406
- if ("missing" in read9) return text4(marketplaces.notAMarketplace(slug));
297407
- const chosen2 = "sponsor" in read9 ? read9.sponsor : null;
297408
- const open = ("sponsors" in read9 ? read9.sponsors : [read9.sponsor]).some((one) => one.state === "approved");
297409
- const rows2 = await marketplaces.readDirectory(SITE, q, fetch2);
297239
+ const pros = await Promise.resolve().then(() => (init_pros(), pros_exports));
297240
+ const rows2 = await pros.readDirectory(SITE, q, fetch2);
297410
297241
  if (!rows2) return text4("The directory could not be read just now. Try again shortly.");
297411
- const found = open ? marketplaces.rosterOf(rows2, { available }) : [];
297412
- for (const pro of found.slice(0, marketplaces.FIND_PRO_MAX)) taint2([pro.row.profile.headline, pro.row.profile.about].filter(Boolean).join("\n"));
297413
- return text4(marketplaces.rosterWords(found, { site: SITE, marketplace: chosen2?.name ?? null, q, available }));
297414
- }
297415
- );
297416
- const sitePicture = external_exports.object({ url: external_exports.string().max(2048).describe("An https address on the Zone's own site."), alt: external_exports.string().max(400).describe("What the picture shows, for someone who cannot see it."), caption: external_exports.string().max(400).optional() });
297417
- const marketplacePageInput = external_exports.object({
297418
- deck: external_exports.string().max(400).optional().describe("One line under the line every Zone's page opens with: what it is, in its words (up to 120 characters)."),
297419
- logo: external_exports.string().max(2048).optional().describe("Its mark: an https address of a square picture on its own site. Left out, its account's mark."),
297420
- cover: sitePicture.optional().describe("A wide picture across the top."),
297421
- story: external_exports.array(external_exports.string().max(4e3)).max(20).optional().describe("Who it is and why it verifies pros, in paragraphs."),
297422
- steps: external_exports.array(external_exports.object({ title: external_exports.string().max(400), text: external_exports.string().max(1e3).optional() })).max(20).optional().describe('How it verifies a pro, as steps: drawn as "How <name> verifies".'),
297423
- pictures: external_exports.array(sitePicture).max(20).optional().describe("Pictures of its work and its people, with captions that say what is shown. No stock or generated photographs."),
297424
- links: external_exports.array(external_exports.object({ url: external_exports.string().max(2048), name: external_exports.string().max(400), note: external_exports.string().max(400).optional() })).max(20).optional().describe("Its site, its published method, press: https addresses.")
297425
- });
297426
- if (offered("set_marketplace_page")) server2.registerTool(
297427
- "set_marketplace_page",
297428
- {
297429
- ...meta3("set_marketplace_page"),
297430
- inputSchema: { page: marketplacePageInput, confirm: external_exports.boolean().optional().describe("false (the default) previews; true signs and publishes, once the person has said yes to the preview.") }
297431
- },
297432
- async ({ page, confirm }) => {
297433
- const { checkSponsorPage: checkSponsorPage2, tidySponsorPage: tidySponsorPage2 } = await Promise.resolve().then(() => (init_sponsors(), sponsors_exports));
297434
- const marketplaces = await Promise.resolve().then(() => (init_marketplaces(), marketplaces_exports));
297435
- const words5 = [page.deck, ...page.story ?? [], ...(page.steps ?? []).flatMap((one) => [one.title, one.text]), ...[page.cover, ...page.pictures ?? []].flatMap((one) => [one?.alt, one?.caption]), ...(page.links ?? []).flatMap((one) => [one.name, one.note])];
297436
- if (words5.some((one) => one && isTainted(one))) return text4(TAINT_REFUSAL);
297437
- const acting = await principal2();
297438
- const owner = acting?.principal ?? await address2();
297439
- const list7 = await marketplaces.readMarketplaces(SITE, fetch2);
297440
- if ("unavailable" in list7) return text4(`${list7.unavailable}, so whose page this is cannot be confirmed. Try again in a minute. Nothing was published.`);
297441
- const mine = list7.sponsors.find((one) => one.account === owner);
297442
- if (!mine)
297443
- return text4(
297444
- `${owner} hosts no Zone on asks.world, so it has no page to write. A Zone's page is written by its own account, or by the agent that account connected${acting ? "" : " (connect_account with the Zone's account first)"}. To host one: ${EXPERT_SITE}/pro/marketplaces/host. Nothing was published.`
297445
- );
297446
- const tidy = tidySponsorPage2(page);
297447
- const problem = checkSponsorPage2(tidy);
297448
- if (problem) return text4(`Not a page yet: ${problem}. Nothing was published.`);
297449
- if (!confirm) {
297450
- const before = await marketplaces.readMarketplacePage(SITE, mine.slug, fetch2);
297451
- return text4(`${marketplaces.marketplacePageWords(mine, tidy, SITE, before)}
297452
-
297453
- Show it to the person. Then call again with the same page and confirm: true to sign and publish it as ${mine.name}'s page${acting ? `, for ${owner}` : ""}.`);
297454
- }
297455
- const invitesModule = await Promise.resolve().then(() => (init_invites(), invites_exports));
297456
- const answer = await invitesModule.setMarketplacePage(SITE, await inviteSigner(acting), tidy);
297457
- if ("refused" in answer) return text4(`Refused: ${answer.refused}. Nothing changed.`);
297458
- return text4(`Published ${mine.name}'s page: ${marketplacePage(SITE, answer.slug)}. Signed ${acting ? `for ${owner} by this agent` : `by ${owner}`}. Pages refresh within five minutes.`);
297242
+ const found = pros.verifiedOf(rows2, { available });
297243
+ for (const pro of found.slice(0, pros.FIND_PRO_MAX)) taint2([pro.row.profile.headline, pro.row.profile.about].filter(Boolean).join("\n"));
297244
+ return text4(pros.prosWords(found, { site: SITE, q, available }));
297459
297245
  }
297460
297246
  );
297461
297247
  const credentialWords = (linkedin, listed) => linkedin?.credentialUrl && listed ? `You also have a LinkedIn credential: it shows you logged in to this LinkedIn account, and any app can check it. Its public link: ${linkedin.credentialUrl}. Download it at ${EXPERT_SITE}/pro/profile.` : `You also have a LinkedIn credential: it shows you logged in to this LinkedIn account, and any app can check it. ${listed && !linkedin?.credential && !linkedin?.credentialUrl ? "It appears on your page once the page is published." : "Only you can see it while your page is private; it goes public when the page does."} Download it at ${EXPERT_SITE}/pro/profile.`;