@bolloon/bolloon-agent 0.4.33 → 0.5.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (143) hide show
  1. package/dist/agents/contacts/chain.js +27 -7
  2. package/dist/agents/execution-supervisor.js +493 -35
  3. package/dist/agents/external-events.js +35 -6
  4. package/dist/agents/gateway-group.js +100 -12
  5. package/dist/agents/goal-criteria.js +10 -3
  6. package/dist/agents/goal-flywheel/block-executor.js +346 -0
  7. package/dist/agents/goal-flywheel/continuation-decision.js +592 -0
  8. package/dist/agents/goal-flywheel/goal-change.js +754 -0
  9. package/dist/agents/goal-flywheel/index.js +26 -0
  10. package/dist/agents/goal-flywheel/memory-layers.js +227 -0
  11. package/dist/agents/goal-flywheel/run-closure.js +809 -0
  12. package/dist/agents/goal-flywheel/skill-candidate.js +628 -0
  13. package/dist/agents/goal-flywheel/types.js +329 -0
  14. package/dist/agents/goal-flywheel/wiring/change.js +288 -0
  15. package/dist/agents/goal-flywheel/wiring/closure.js +697 -0
  16. package/dist/agents/goal-flywheel/wiring/continuation.js +432 -0
  17. package/dist/agents/goal-flywheel/wiring/contract.js +270 -0
  18. package/dist/agents/goal-flywheel/wiring/index.js +26 -0
  19. package/dist/agents/goal-flywheel/wiring/monitor.js +254 -0
  20. package/dist/agents/goal-flywheel/wiring/seams.js +592 -0
  21. package/dist/agents/goal-flywheel/work-contract.js +478 -0
  22. package/dist/agents/goal-flywheel/work-monitor.js +488 -0
  23. package/dist/agents/goal-flywheel-wiring.js +1870 -0
  24. package/dist/agents/goal-state-reducer.js +406 -0
  25. package/dist/agents/goal-store.js +35 -1
  26. package/dist/agents/mobile-flywheel-view.js +144 -0
  27. package/dist/agents/mobile-task-actions-verify.js +74 -0
  28. package/dist/agents/mobile-task-actions.js +178 -0
  29. package/dist/agents/mobile-task-views.js +199 -0
  30. package/dist/agents/network-pulse.js +304 -18
  31. package/dist/agents/pi-sdk.js +75 -20
  32. package/dist/agents/run-store.js +18 -5
  33. package/dist/agents/skill-readiness.js +52 -10
  34. package/dist/agents/subagent-manager.js +209 -3
  35. package/dist/agents/task/task-runner.js +9 -3
  36. package/dist/agents/task-group.js +8 -51
  37. package/dist/agents/task-public-text.js +89 -0
  38. package/dist/cli/commands/index.js +1 -0
  39. package/dist/cli/commands/tasks.js +350 -2
  40. package/dist/cli/identity-command.js +177 -0
  41. package/dist/cli/setup-wizard.js +71 -0
  42. package/dist/cli/update-commands.js +150 -24
  43. package/dist/cli-entry.js +12 -2
  44. package/dist/electron-build/agents/contacts/chain.js +26 -6
  45. package/dist/electron-build/agents/contacts/chain.js.map +1 -1
  46. package/dist/electron-build/agents/execution-supervisor.js +492 -34
  47. package/dist/electron-build/agents/execution-supervisor.js.map +1 -1
  48. package/dist/electron-build/agents/external-events.js +34 -5
  49. package/dist/electron-build/agents/external-events.js.map +1 -1
  50. package/dist/electron-build/agents/goal-criteria.js +10 -3
  51. package/dist/electron-build/agents/goal-criteria.js.map +1 -1
  52. package/dist/electron-build/agents/goal-flywheel/continuation-decision.js +598 -0
  53. package/dist/electron-build/agents/goal-flywheel/continuation-decision.js.map +1 -0
  54. package/dist/electron-build/agents/goal-flywheel/goal-change.js +773 -0
  55. package/dist/electron-build/agents/goal-flywheel/goal-change.js.map +1 -0
  56. package/dist/electron-build/agents/goal-flywheel/memory-layers.js +269 -0
  57. package/dist/electron-build/agents/goal-flywheel/memory-layers.js.map +1 -0
  58. package/dist/electron-build/agents/goal-flywheel/run-closure.js +818 -0
  59. package/dist/electron-build/agents/goal-flywheel/run-closure.js.map +1 -0
  60. package/dist/electron-build/agents/goal-flywheel/skill-candidate.js +642 -0
  61. package/dist/electron-build/agents/goal-flywheel/skill-candidate.js.map +1 -0
  62. package/dist/electron-build/agents/goal-flywheel/types.js +333 -0
  63. package/dist/electron-build/agents/goal-flywheel/types.js.map +1 -0
  64. package/dist/electron-build/agents/goal-flywheel/wiring/change.js +294 -0
  65. package/dist/electron-build/agents/goal-flywheel/wiring/change.js.map +1 -0
  66. package/dist/electron-build/agents/goal-flywheel/wiring/closure.js +742 -0
  67. package/dist/electron-build/agents/goal-flywheel/wiring/closure.js.map +1 -0
  68. package/dist/electron-build/agents/goal-flywheel/wiring/continuation.js +444 -0
  69. package/dist/electron-build/agents/goal-flywheel/wiring/continuation.js.map +1 -0
  70. package/dist/electron-build/agents/goal-flywheel/wiring/contract.js +279 -0
  71. package/dist/electron-build/agents/goal-flywheel/wiring/contract.js.map +1 -0
  72. package/dist/electron-build/agents/goal-flywheel/wiring/index.js +111 -0
  73. package/dist/electron-build/agents/goal-flywheel/wiring/index.js.map +1 -0
  74. package/dist/electron-build/agents/goal-flywheel/wiring/monitor.js +264 -0
  75. package/dist/electron-build/agents/goal-flywheel/wiring/monitor.js.map +1 -0
  76. package/dist/electron-build/agents/goal-flywheel/wiring/seams.js +612 -0
  77. package/dist/electron-build/agents/goal-flywheel/wiring/seams.js.map +1 -0
  78. package/dist/electron-build/agents/goal-flywheel/work-contract.js +488 -0
  79. package/dist/electron-build/agents/goal-flywheel/work-contract.js.map +1 -0
  80. package/dist/electron-build/agents/goal-flywheel/work-monitor.js +501 -0
  81. package/dist/electron-build/agents/goal-flywheel/work-monitor.js.map +1 -0
  82. package/dist/electron-build/agents/goal-flywheel-wiring.js +1962 -0
  83. package/dist/electron-build/agents/goal-flywheel-wiring.js.map +1 -0
  84. package/dist/electron-build/agents/goal-state-reducer.js +414 -0
  85. package/dist/electron-build/agents/goal-state-reducer.js.map +1 -0
  86. package/dist/electron-build/agents/goal-store.js +35 -1
  87. package/dist/electron-build/agents/goal-store.js.map +1 -1
  88. package/dist/electron-build/agents/network-pulse.js +307 -19
  89. package/dist/electron-build/agents/network-pulse.js.map +1 -1
  90. package/dist/electron-build/agents/pi-sdk.js +74 -19
  91. package/dist/electron-build/agents/pi-sdk.js.map +1 -1
  92. package/dist/electron-build/agents/run-store.js +20 -5
  93. package/dist/electron-build/agents/run-store.js.map +1 -1
  94. package/dist/electron-build/agents/skill-readiness.js +52 -9
  95. package/dist/electron-build/agents/skill-readiness.js.map +1 -1
  96. package/dist/electron-build/agents/task/task-runner.js +8 -2
  97. package/dist/electron-build/agents/task/task-runner.js.map +1 -1
  98. package/dist/electron-build/orbitdb/cid-database.js +83 -17
  99. package/dist/electron-build/orbitdb/cid-database.js.map +1 -1
  100. package/dist/electron-build/orbitdb/ipfs-node.js +31 -2
  101. package/dist/electron-build/orbitdb/ipfs-node.js.map +1 -1
  102. package/dist/electron-build/utils/dual-source.js +471 -0
  103. package/dist/electron-build/utils/dual-source.js.map +1 -0
  104. package/dist/electron-build/utils/update-manager.js +331 -57
  105. package/dist/electron-build/utils/update-manager.js.map +1 -1
  106. package/dist/electron-build/utils/update-state.js +16 -1
  107. package/dist/electron-build/utils/update-state.js.map +1 -1
  108. package/dist/electron-build/utils/version-info.js +82 -2
  109. package/dist/electron-build/utils/version-info.js.map +1 -1
  110. package/dist/index.js +103 -12
  111. package/dist/ios/chain-explorer.js +617 -0
  112. package/dist/ios/explorer.html +163 -0
  113. package/dist/ios/index.html +96 -0
  114. package/dist/ios/mobile-agent.js +2 -2
  115. package/dist/ios/mobile-contacts.js +329 -0
  116. package/dist/ios/mobile-core.js +1379 -226
  117. package/dist/ios/mobile-privacy.js +185 -0
  118. package/dist/ios/mobile.css +19 -0
  119. package/dist/ios/mobile.html +96 -0
  120. package/dist/ios/mobile.js +706 -7
  121. package/dist/ios/routes-chain-index.js +108 -0
  122. package/dist/ios/routes-contacts.js +420 -0
  123. package/dist/ios/routes-onchain-trade.js +99 -0
  124. package/dist/ios/routes-x402-info.js +1 -0
  125. package/dist/ios/server.js +762 -0
  126. package/dist/ios/task-frame-server.js +211 -0
  127. package/dist/orbitdb/cid-database.js +81 -16
  128. package/dist/orbitdb/ipfs-node.js +31 -2
  129. package/dist/utils/dual-source.js +426 -0
  130. package/dist/utils/update-cli.js +16 -21
  131. package/dist/utils/update-health.js +35 -5
  132. package/dist/utils/update-manager.js +329 -57
  133. package/dist/utils/update-state.js +16 -1
  134. package/dist/utils/version-info.js +75 -1
  135. package/dist/web/mobile-contacts.js +44 -11
  136. package/dist/web/mobile-core.js +1197 -513
  137. package/dist/web/mobile-tasks.js +339 -0
  138. package/dist/web/mobile.css +19 -0
  139. package/dist/web/mobile.html +64 -0
  140. package/dist/web/mobile.js +531 -1
  141. package/dist/web/routes-mobile-tasks.js +353 -0
  142. package/dist/web/server.js +163 -4
  143. package/package.json +3 -1
@@ -1374,7 +1374,7 @@
1374
1374
  }
1375
1375
  function encode(data, alphabet4, bitsPerChar) {
1376
1376
  const pad2 = alphabet4[alphabet4.length - 1] === "=";
1377
- const mask = (1 << bitsPerChar) - 1;
1377
+ const mask2 = (1 << bitsPerChar) - 1;
1378
1378
  let out = "";
1379
1379
  let bits = 0;
1380
1380
  let buffer6 = 0;
@@ -1383,11 +1383,11 @@
1383
1383
  bits += 8;
1384
1384
  while (bits > bitsPerChar) {
1385
1385
  bits -= bitsPerChar;
1386
- out += alphabet4[mask & buffer6 >> bits];
1386
+ out += alphabet4[mask2 & buffer6 >> bits];
1387
1387
  }
1388
1388
  }
1389
1389
  if (bits !== 0) {
1390
- out += alphabet4[mask & buffer6 << bitsPerChar - bits];
1390
+ out += alphabet4[mask2 & buffer6 << bitsPerChar - bits];
1391
1391
  }
1392
1392
  if (pad2) {
1393
1393
  while ((out.length * bitsPerChar & 7) !== 0) {
@@ -3361,8 +3361,8 @@
3361
3361
  }
3362
3362
  function encodeInteger(value2) {
3363
3363
  const contents = new Uint8ArrayList();
3364
- const mask = 128;
3365
- const positive2 = (value2.subarray()[0] & mask) === mask;
3364
+ const mask2 = 128;
3365
+ const positive2 = (value2.subarray()[0] & mask2) === mask2;
3366
3366
  if (positive2) {
3367
3367
  contents.append(Uint8Array.from([0]));
3368
3368
  }
@@ -4974,13 +4974,13 @@
4974
4974
  const windows = Math.ceil(scalarBits2 / W2) + 1;
4975
4975
  const windowSize = 2 ** (W2 - 1);
4976
4976
  const maxNumber = 2 ** W2;
4977
- const mask = bitMask(W2);
4977
+ const mask2 = bitMask(W2);
4978
4978
  const shiftBy = BigInt(W2);
4979
- return { windows, windowSize, mask, maxNumber, shiftBy };
4979
+ return { windows, windowSize, mask: mask2, maxNumber, shiftBy };
4980
4980
  }
4981
4981
  function calcOffsets(n, window2, wOpts) {
4982
- const { windowSize, mask, maxNumber, shiftBy } = wOpts;
4983
- let wbits = Number(n & mask);
4982
+ const { windowSize, mask: mask2, maxNumber, shiftBy } = wOpts;
4983
+ let wbits = Number(n & mask2);
4984
4984
  let nextN = n >> shiftBy;
4985
4985
  if (wbits > windowSize) {
4986
4986
  wbits -= maxNumber;
@@ -6801,18 +6801,18 @@
6801
6801
  * Zig-zag encodes this long bits
6802
6802
  */
6803
6803
  zzEncode() {
6804
- const mask = this.hi >> 31;
6805
- this.hi = ((this.hi << 1 | this.lo >>> 31) ^ mask) >>> 0;
6806
- this.lo = (this.lo << 1 ^ mask) >>> 0;
6804
+ const mask2 = this.hi >> 31;
6805
+ this.hi = ((this.hi << 1 | this.lo >>> 31) ^ mask2) >>> 0;
6806
+ this.lo = (this.lo << 1 ^ mask2) >>> 0;
6807
6807
  return this;
6808
6808
  }
6809
6809
  /**
6810
6810
  * Zig-zag decodes this long bits
6811
6811
  */
6812
6812
  zzDecode() {
6813
- const mask = -(this.lo & 1);
6814
- this.lo = ((this.lo >>> 1 | this.hi << 31) ^ mask) >>> 0;
6815
- this.hi = (this.hi >>> 1 ^ mask) >>> 0;
6813
+ const mask2 = -(this.lo & 1);
6814
+ this.lo = ((this.lo >>> 1 | this.hi << 31) ^ mask2) >>> 0;
6815
+ this.hi = (this.hi >>> 1 ^ mask2) >>> 0;
6816
6816
  return this;
6817
6817
  }
6818
6818
  /**
@@ -12897,9 +12897,9 @@ ${indent}[Error list was empty]`;
12897
12897
  }
12898
12898
  }
12899
12899
  }
12900
- function simpleMaskLength(mask) {
12900
+ function simpleMaskLength(mask2) {
12901
12901
  let ones = 0;
12902
- for (let [index, byte] of mask.entries()) {
12902
+ for (let [index, byte] of mask2.entries()) {
12903
12903
  if (byte === 255) {
12904
12904
  ones += 8;
12905
12905
  continue;
@@ -12911,8 +12911,8 @@ ${indent}[Error list was empty]`;
12911
12911
  if ((byte & 128) != 0) {
12912
12912
  return -1;
12913
12913
  }
12914
- for (let i = index + 1; i < mask.length; i++) {
12915
- if (mask[i] != 0) {
12914
+ for (let i = index + 1; i < mask2.length; i++) {
12915
+ if (mask2[i] != 0) {
12916
12916
  return -1;
12917
12917
  }
12918
12918
  }
@@ -12920,9 +12920,9 @@ ${indent}[Error list was empty]`;
12920
12920
  }
12921
12921
  return ones;
12922
12922
  }
12923
- function maskToHex(mask) {
12923
+ function maskToHex(mask2) {
12924
12924
  let hex = "0x";
12925
- for (const byte of mask) {
12925
+ for (const byte of mask2) {
12926
12926
  hex += (byte >> 4).toString(16) + (byte & 15).toString(16);
12927
12927
  }
12928
12928
  return hex;
@@ -12934,20 +12934,20 @@ ${indent}[Error list was empty]`;
12934
12934
  });
12935
12935
 
12936
12936
  // node_modules/@chainsafe/netmask/dist/src/ip.js
12937
- function maskIp(ip, mask) {
12938
- if (mask.length === IPv6Len && ip.length === IPv4Len && allFF(mask, 0, 11)) {
12939
- mask = mask.slice(12);
12937
+ function maskIp(ip, mask2) {
12938
+ if (mask2.length === IPv6Len && ip.length === IPv4Len && allFF(mask2, 0, 11)) {
12939
+ mask2 = mask2.slice(12);
12940
12940
  }
12941
- if (mask.length === IPv4Len && ip.length === IPv6Len && deepEqual(ip, ipv4Prefix, 0, 11)) {
12941
+ if (mask2.length === IPv4Len && ip.length === IPv6Len && deepEqual(ip, ipv4Prefix, 0, 11)) {
12942
12942
  ip = ip.slice(12);
12943
12943
  }
12944
12944
  const n = ip.length;
12945
- if (n != mask.length) {
12945
+ if (n != mask2.length) {
12946
12946
  throw new Error("Failed to mask ip");
12947
12947
  }
12948
12948
  const out = new Uint8Array(n);
12949
12949
  for (let i = 0; i < n; i++) {
12950
- out[i] = ip[i] & mask[i];
12950
+ out[i] = ip[i] & mask2[i];
12951
12951
  }
12952
12952
  return out;
12953
12953
  }
@@ -13009,10 +13009,10 @@ ${indent}[Error list was empty]`;
13009
13009
  if (Number.isNaN(m2) || String(m2).length !== maskString.length || m2 < 0 || m2 > ipLength * 8) {
13010
13010
  throw new Error("Failed to parse given CIDR: " + s2);
13011
13011
  }
13012
- const mask = cidrMask(m2, 8 * ipLength);
13012
+ const mask2 = cidrMask(m2, 8 * ipLength);
13013
13013
  return {
13014
- network: maskIp(ip, mask),
13015
- mask
13014
+ network: maskIp(ip, mask2),
13015
+ mask: mask2
13016
13016
  };
13017
13017
  }
13018
13018
  function cidrMask(ones, bits) {
@@ -13054,18 +13054,18 @@ ${indent}[Error list was empty]`;
13054
13054
  * @param ipOrCidr either network ip or full cidr address
13055
13055
  * @param mask in case ipOrCidr is network this can be either mask in decimal format or as ip address
13056
13056
  */
13057
- constructor(ipOrCidr, mask) {
13058
- if (mask == null) {
13057
+ constructor(ipOrCidr, mask2) {
13058
+ if (mask2 == null) {
13059
13059
  ({ network: this.network, mask: this.mask } = parseCidr(ipOrCidr));
13060
13060
  } else {
13061
13061
  const ipResult = parseIP(ipOrCidr);
13062
13062
  if (ipResult == null) {
13063
13063
  throw new Error("Failed to parse network");
13064
13064
  }
13065
- mask = String(mask);
13066
- const m2 = parseInt(mask, 10);
13067
- if (Number.isNaN(m2) || String(m2).length !== mask.length || m2 < 0 || m2 > ipResult.length * 8) {
13068
- const maskResult = parseIP(mask);
13065
+ mask2 = String(mask2);
13066
+ const m2 = parseInt(mask2, 10);
13067
+ if (Number.isNaN(m2) || String(m2).length !== mask2.length || m2 < 0 || m2 > ipResult.length * 8) {
13068
+ const maskResult = parseIP(mask2);
13069
13069
  if (maskResult == null) {
13070
13070
  throw new Error("Failed to parse mask");
13071
13071
  }
@@ -13087,8 +13087,8 @@ ${indent}[Error list was empty]`;
13087
13087
  /**Serializes back to string format */
13088
13088
  toString() {
13089
13089
  const l = simpleMaskLength(this.mask);
13090
- const mask = l !== -1 ? String(l) : maskToHex(this.mask);
13091
- return ipToString(this.network) + "/" + mask;
13090
+ const mask2 = l !== -1 ? String(l) : maskToHex(this.mask);
13091
+ return ipToString(this.network) + "/" + mask2;
13092
13092
  }
13093
13093
  };
13094
13094
  }
@@ -13309,11 +13309,11 @@ ${indent}[Error list was empty]`;
13309
13309
  }
13310
13310
  }
13311
13311
  var Netmask4Impl = class _Netmask4Impl {
13312
- constructor(net, mask) {
13312
+ constructor(net, mask2) {
13313
13313
  if (typeof net !== "string") {
13314
13314
  throw new Error("Missing `net' parameter");
13315
13315
  }
13316
- let maskStr = mask;
13316
+ let maskStr = mask2;
13317
13317
  if (!maskStr) {
13318
13318
  const parts = net.split("/", 2);
13319
13319
  net = parts[0];
@@ -13498,11 +13498,11 @@ ${indent}[Error list was empty]`;
13498
13498
  }
13499
13499
  }
13500
13500
  var Netmask6Impl = class _Netmask6Impl {
13501
- constructor(net, mask) {
13501
+ constructor(net, mask2) {
13502
13502
  if (typeof net !== "string") {
13503
13503
  throw new Error("Missing `net' parameter");
13504
13504
  }
13505
- let prefixLen = mask;
13505
+ let prefixLen = mask2;
13506
13506
  if (prefixLen === void 0 || prefixLen === null) {
13507
13507
  const slashIdx = net.indexOf("/");
13508
13508
  if (slashIdx !== -1) {
@@ -13585,15 +13585,15 @@ ${indent}[Error list was empty]`;
13585
13585
  } });
13586
13586
  var netmask6_1 = require_netmask6();
13587
13587
  var Netmask2 = class _Netmask {
13588
- constructor(net, mask) {
13588
+ constructor(net, mask2) {
13589
13589
  if (typeof net !== "string") {
13590
13590
  throw new Error("Missing `net' parameter");
13591
13591
  }
13592
13592
  const addrPart = net.indexOf("/") !== -1 ? net.substring(0, net.indexOf("/")) : net;
13593
13593
  if (addrPart.indexOf(":") !== -1) {
13594
- this._impl = new netmask6_1.Netmask6Impl(net, mask);
13594
+ this._impl = new netmask6_1.Netmask6Impl(net, mask2);
13595
13595
  } else {
13596
- this._impl = new netmask4_1.Netmask4Impl(net, mask);
13596
+ this._impl = new netmask4_1.Netmask4Impl(net, mask2);
13597
13597
  }
13598
13598
  this.base = this._impl.base;
13599
13599
  this.mask = this._impl.mask;
@@ -18414,11 +18414,11 @@ ${indent}[Error list was empty]`;
18414
18414
  function toToken2(data, pos, prefix, length20, options2) {
18415
18415
  const totLength = prefix + length20;
18416
18416
  assertEnoughData(data, pos, totLength);
18417
- const tok = new Token(Type.string, toStr(data, pos + prefix, pos + totLength), totLength);
18417
+ const tok2 = new Token(Type.string, toStr(data, pos + prefix, pos + totLength), totLength);
18418
18418
  if (options2.retainStringBytes === true) {
18419
- tok.byteValue = data.slice(pos + prefix, pos + totLength);
18419
+ tok2.byteValue = data.slice(pos + prefix, pos + totLength);
18420
18420
  }
18421
- return tok;
18421
+ return tok2;
18422
18422
  }
18423
18423
  function decodeStringCompact(data, pos, minor, options2) {
18424
18424
  return toToken2(data, pos, 1, minor, options2);
@@ -21481,18 +21481,18 @@ ${indent}[Error list was empty]`;
21481
21481
  * Zig-zag encodes this long bits
21482
21482
  */
21483
21483
  zzEncode() {
21484
- const mask = this.hi >> 31;
21485
- this.hi = ((this.hi << 1 | this.lo >>> 31) ^ mask) >>> 0;
21486
- this.lo = (this.lo << 1 ^ mask) >>> 0;
21484
+ const mask2 = this.hi >> 31;
21485
+ this.hi = ((this.hi << 1 | this.lo >>> 31) ^ mask2) >>> 0;
21486
+ this.lo = (this.lo << 1 ^ mask2) >>> 0;
21487
21487
  return this;
21488
21488
  }
21489
21489
  /**
21490
21490
  * Zig-zag decodes this long bits
21491
21491
  */
21492
21492
  zzDecode() {
21493
- const mask = -(this.lo & 1);
21494
- this.lo = ((this.lo >>> 1 | this.hi << 31) ^ mask) >>> 0;
21495
- this.hi = (this.hi >>> 1 ^ mask) >>> 0;
21493
+ const mask2 = -(this.lo & 1);
21494
+ this.lo = ((this.lo >>> 1 | this.hi << 31) ^ mask2) >>> 0;
21495
+ this.hi = (this.hi >>> 1 ^ mask2) >>> 0;
21496
21496
  return this;
21497
21497
  }
21498
21498
  /**
@@ -24141,18 +24141,18 @@ ${indent}[Error list was empty]`;
24141
24141
  * Zig-zag encodes this long bits
24142
24142
  */
24143
24143
  zzEncode() {
24144
- const mask = this.hi >> 31;
24145
- this.hi = ((this.hi << 1 | this.lo >>> 31) ^ mask) >>> 0;
24146
- this.lo = (this.lo << 1 ^ mask) >>> 0;
24144
+ const mask2 = this.hi >> 31;
24145
+ this.hi = ((this.hi << 1 | this.lo >>> 31) ^ mask2) >>> 0;
24146
+ this.lo = (this.lo << 1 ^ mask2) >>> 0;
24147
24147
  return this;
24148
24148
  }
24149
24149
  /**
24150
24150
  * Zig-zag decodes this long bits
24151
24151
  */
24152
24152
  zzDecode() {
24153
- const mask = -(this.lo & 1);
24154
- this.lo = ((this.lo >>> 1 | this.hi << 31) ^ mask) >>> 0;
24155
- this.hi = (this.hi >>> 1 ^ mask) >>> 0;
24153
+ const mask2 = -(this.lo & 1);
24154
+ this.lo = ((this.lo >>> 1 | this.hi << 31) ^ mask2) >>> 0;
24155
+ this.hi = (this.hi >>> 1 ^ mask2) >>> 0;
24156
24156
  return this;
24157
24157
  }
24158
24158
  /**
@@ -28712,18 +28712,18 @@ ${indent}[Error list was empty]`;
28712
28712
  }
28713
28713
  function multiaddrToIpNet(ma) {
28714
28714
  const config = getNetConfig(ma);
28715
- let mask = config.cidr;
28715
+ let mask2 = config.cidr;
28716
28716
  if (config.type !== "ip4" && config.type !== "ip6") {
28717
28717
  throw new InvalidParametersError(`Multiaddr ${ma} was not an IPv4 or IPv6 address`);
28718
28718
  }
28719
- if (mask == null) {
28719
+ if (mask2 == null) {
28720
28720
  switch (config.type) {
28721
28721
  case "ip4": {
28722
- mask = 32;
28722
+ mask2 = 32;
28723
28723
  break;
28724
28724
  }
28725
28725
  case "ip6": {
28726
- mask = 128;
28726
+ mask2 = 128;
28727
28727
  break;
28728
28728
  }
28729
28729
  default: {
@@ -28731,7 +28731,7 @@ ${indent}[Error list was empty]`;
28731
28731
  }
28732
28732
  }
28733
28733
  }
28734
- return new IpNet(config.host, mask);
28734
+ return new IpNet(config.host, mask2);
28735
28735
  }
28736
28736
  function isDirect(ma) {
28737
28737
  return !Circuit.exactMatch(ma);
@@ -35926,12 +35926,12 @@ ${[...listenStats.errors.entries()].map(([addr, err2]) => {
35926
35926
  g[i] &= 8191;
35927
35927
  }
35928
35928
  g[9] -= 1 << 13;
35929
- let mask = (c ^ 1) - 1;
35929
+ let mask2 = (c ^ 1) - 1;
35930
35930
  for (let i = 0; i < 10; i++)
35931
- g[i] &= mask;
35932
- mask = ~mask;
35931
+ g[i] &= mask2;
35932
+ mask2 = ~mask2;
35933
35933
  for (let i = 0; i < 10; i++)
35934
- h3[i] = h3[i] & mask | g[i];
35934
+ h3[i] = h3[i] & mask2 | g[i];
35935
35935
  h3[0] = (h3[0] | h3[1] << 13) & 65535;
35936
35936
  h3[1] = (h3[1] >>> 3 | h3[2] << 10) & 65535;
35937
35937
  h3[2] = (h3[2] >>> 6 | h3[3] << 7) & 65535;
@@ -36669,7 +36669,7 @@ ${[...listenStats.errors.entries()].map(([addr, err2]) => {
36669
36669
  }
36670
36670
  function encode10(data, alphabet4, bitsPerChar) {
36671
36671
  const pad2 = alphabet4[alphabet4.length - 1] === "=";
36672
- const mask = (1 << bitsPerChar) - 1;
36672
+ const mask2 = (1 << bitsPerChar) - 1;
36673
36673
  let out = "";
36674
36674
  let bits = 0;
36675
36675
  let buffer6 = 0;
@@ -36678,11 +36678,11 @@ ${[...listenStats.errors.entries()].map(([addr, err2]) => {
36678
36678
  bits += 8;
36679
36679
  while (bits > bitsPerChar) {
36680
36680
  bits -= bitsPerChar;
36681
- out += alphabet4[mask & buffer6 >> bits];
36681
+ out += alphabet4[mask2 & buffer6 >> bits];
36682
36682
  }
36683
36683
  }
36684
36684
  if (bits !== 0) {
36685
- out += alphabet4[mask & buffer6 << bitsPerChar - bits];
36685
+ out += alphabet4[mask2 & buffer6 << bitsPerChar - bits];
36686
36686
  }
36687
36687
  if (pad2) {
36688
36688
  while ((out.length * bitsPerChar & 7) !== 0) {
@@ -38978,18 +38978,18 @@ ${[...listenStats.errors.entries()].map(([addr, err2]) => {
38978
38978
  * Zig-zag encodes this long bits
38979
38979
  */
38980
38980
  zzEncode() {
38981
- const mask = this.hi >> 31;
38982
- this.hi = ((this.hi << 1 | this.lo >>> 31) ^ mask) >>> 0;
38983
- this.lo = (this.lo << 1 ^ mask) >>> 0;
38981
+ const mask2 = this.hi >> 31;
38982
+ this.hi = ((this.hi << 1 | this.lo >>> 31) ^ mask2) >>> 0;
38983
+ this.lo = (this.lo << 1 ^ mask2) >>> 0;
38984
38984
  return this;
38985
38985
  }
38986
38986
  /**
38987
38987
  * Zig-zag decodes this long bits
38988
38988
  */
38989
38989
  zzDecode() {
38990
- const mask = -(this.lo & 1);
38991
- this.lo = ((this.lo >>> 1 | this.hi << 31) ^ mask) >>> 0;
38992
- this.hi = (this.hi >>> 1 ^ mask) >>> 0;
38990
+ const mask2 = -(this.lo & 1);
38991
+ this.lo = ((this.lo >>> 1 | this.hi << 31) ^ mask2) >>> 0;
38992
+ this.hi = (this.hi >>> 1 ^ mask2) >>> 0;
38993
38993
  return this;
38994
38994
  }
38995
38995
  /**
@@ -41706,18 +41706,18 @@ ${[...listenStats.errors.entries()].map(([addr, err2]) => {
41706
41706
  * Zig-zag encodes this long bits
41707
41707
  */
41708
41708
  zzEncode() {
41709
- const mask = this.hi >> 31;
41710
- this.hi = ((this.hi << 1 | this.lo >>> 31) ^ mask) >>> 0;
41711
- this.lo = (this.lo << 1 ^ mask) >>> 0;
41709
+ const mask2 = this.hi >> 31;
41710
+ this.hi = ((this.hi << 1 | this.lo >>> 31) ^ mask2) >>> 0;
41711
+ this.lo = (this.lo << 1 ^ mask2) >>> 0;
41712
41712
  return this;
41713
41713
  }
41714
41714
  /**
41715
41715
  * Zig-zag decodes this long bits
41716
41716
  */
41717
41717
  zzDecode() {
41718
- const mask = -(this.lo & 1);
41719
- this.lo = ((this.lo >>> 1 | this.hi << 31) ^ mask) >>> 0;
41720
- this.hi = (this.hi >>> 1 ^ mask) >>> 0;
41718
+ const mask2 = -(this.lo & 1);
41719
+ this.lo = ((this.lo >>> 1 | this.hi << 31) ^ mask2) >>> 0;
41720
+ this.hi = (this.hi >>> 1 ^ mask2) >>> 0;
41721
41721
  return this;
41722
41722
  }
41723
41723
  /**
@@ -43635,18 +43635,18 @@ ${[...listenStats.errors.entries()].map(([addr, err2]) => {
43635
43635
  * Zig-zag encodes this long bits
43636
43636
  */
43637
43637
  zzEncode() {
43638
- const mask = this.hi >> 31;
43639
- this.hi = ((this.hi << 1 | this.lo >>> 31) ^ mask) >>> 0;
43640
- this.lo = (this.lo << 1 ^ mask) >>> 0;
43638
+ const mask2 = this.hi >> 31;
43639
+ this.hi = ((this.hi << 1 | this.lo >>> 31) ^ mask2) >>> 0;
43640
+ this.lo = (this.lo << 1 ^ mask2) >>> 0;
43641
43641
  return this;
43642
43642
  }
43643
43643
  /**
43644
43644
  * Zig-zag decodes this long bits
43645
43645
  */
43646
43646
  zzDecode() {
43647
- const mask = -(this.lo & 1);
43648
- this.lo = ((this.lo >>> 1 | this.hi << 31) ^ mask) >>> 0;
43649
- this.hi = (this.hi >>> 1 ^ mask) >>> 0;
43647
+ const mask2 = -(this.lo & 1);
43648
+ this.lo = ((this.lo >>> 1 | this.hi << 31) ^ mask2) >>> 0;
43649
+ this.hi = (this.hi >>> 1 ^ mask2) >>> 0;
43650
43650
  return this;
43651
43651
  }
43652
43652
  /**
@@ -45169,18 +45169,18 @@ ${[...listenStats.errors.entries()].map(([addr, err2]) => {
45169
45169
  * Zig-zag encodes this long bits
45170
45170
  */
45171
45171
  zzEncode() {
45172
- const mask = this.hi >> 31;
45173
- this.hi = ((this.hi << 1 | this.lo >>> 31) ^ mask) >>> 0;
45174
- this.lo = (this.lo << 1 ^ mask) >>> 0;
45172
+ const mask2 = this.hi >> 31;
45173
+ this.hi = ((this.hi << 1 | this.lo >>> 31) ^ mask2) >>> 0;
45174
+ this.lo = (this.lo << 1 ^ mask2) >>> 0;
45175
45175
  return this;
45176
45176
  }
45177
45177
  /**
45178
45178
  * Zig-zag decodes this long bits
45179
45179
  */
45180
45180
  zzDecode() {
45181
- const mask = -(this.lo & 1);
45182
- this.lo = ((this.lo >>> 1 | this.hi << 31) ^ mask) >>> 0;
45183
- this.hi = (this.hi >>> 1 ^ mask) >>> 0;
45181
+ const mask2 = -(this.lo & 1);
45182
+ this.lo = ((this.lo >>> 1 | this.hi << 31) ^ mask2) >>> 0;
45183
+ this.hi = (this.hi >>> 1 ^ mask2) >>> 0;
45184
45184
  return this;
45185
45185
  }
45186
45186
  /**
@@ -66360,8 +66360,8 @@ ${[...listenStats.errors.entries()].map(([addr, err2]) => {
66360
66360
  const view = new DataView(localKadId.buffer, localKadId.byteOffset, localKadId.byteLength);
66361
66361
  const localPrefix = view.getUint16(0, false);
66362
66362
  const toggledLocalPrefix = localPrefix ^ 32768 >> targetCommonPrefixLength;
66363
- const mask = 65535 << 16 - (targetCommonPrefixLength + 1);
66364
- const targetPrefix = toggledLocalPrefix & mask | randomPrefix & ~mask;
66363
+ const mask2 = 65535 << 16 - (targetCommonPrefixLength + 1);
66364
+ const targetPrefix = toggledLocalPrefix & mask2 | randomPrefix & ~mask2;
66365
66365
  const keyPrefix3 = generated_prefix_list_browser_default[targetPrefix];
66366
66366
  const keyBuffer = new ArrayBuffer(34);
66367
66367
  const keyView = new DataView(keyBuffer, 0, keyBuffer.byteLength);
@@ -67641,18 +67641,18 @@ ${[...listenStats.errors.entries()].map(([addr, err2]) => {
67641
67641
  * Zig-zag encodes this long bits
67642
67642
  */
67643
67643
  zzEncode() {
67644
- const mask = this.hi >> 31;
67645
- this.hi = ((this.hi << 1 | this.lo >>> 31) ^ mask) >>> 0;
67646
- this.lo = (this.lo << 1 ^ mask) >>> 0;
67644
+ const mask2 = this.hi >> 31;
67645
+ this.hi = ((this.hi << 1 | this.lo >>> 31) ^ mask2) >>> 0;
67646
+ this.lo = (this.lo << 1 ^ mask2) >>> 0;
67647
67647
  return this;
67648
67648
  }
67649
67649
  /**
67650
67650
  * Zig-zag decodes this long bits
67651
67651
  */
67652
67652
  zzDecode() {
67653
- const mask = -(this.lo & 1);
67654
- this.lo = ((this.lo >>> 1 | this.hi << 31) ^ mask) >>> 0;
67655
- this.hi = (this.hi >>> 1 ^ mask) >>> 0;
67653
+ const mask2 = -(this.lo & 1);
67654
+ this.lo = ((this.lo >>> 1 | this.hi << 31) ^ mask2) >>> 0;
67655
+ this.hi = (this.hi >>> 1 ^ mask2) >>> 0;
67656
67656
  return this;
67657
67657
  }
67658
67658
  /**
@@ -71270,7 +71270,7 @@ ${[...listenStats.errors.entries()].map(([addr, err2]) => {
71270
71270
  i = this._head + i & this._capacityMask;
71271
71271
  return this._list[i];
71272
71272
  };
71273
- Denque2.prototype.get = function get2(i) {
71273
+ Denque2.prototype.get = function get3(i) {
71274
71274
  return this.peekAt(i);
71275
71275
  };
71276
71276
  Denque2.prototype.peek = function peek() {
@@ -75209,18 +75209,18 @@ ${[...listenStats.errors.entries()].map(([addr, err2]) => {
75209
75209
  * Zig-zag encodes this long bits
75210
75210
  */
75211
75211
  zzEncode() {
75212
- const mask = this.hi >> 31;
75213
- this.hi = ((this.hi << 1 | this.lo >>> 31) ^ mask) >>> 0;
75214
- this.lo = (this.lo << 1 ^ mask) >>> 0;
75212
+ const mask2 = this.hi >> 31;
75213
+ this.hi = ((this.hi << 1 | this.lo >>> 31) ^ mask2) >>> 0;
75214
+ this.lo = (this.lo << 1 ^ mask2) >>> 0;
75215
75215
  return this;
75216
75216
  }
75217
75217
  /**
75218
75218
  * Zig-zag decodes this long bits
75219
75219
  */
75220
75220
  zzDecode() {
75221
- const mask = -(this.lo & 1);
75222
- this.lo = ((this.lo >>> 1 | this.hi << 31) ^ mask) >>> 0;
75223
- this.hi = (this.hi >>> 1 ^ mask) >>> 0;
75221
+ const mask2 = -(this.lo & 1);
75222
+ this.lo = ((this.lo >>> 1 | this.hi << 31) ^ mask2) >>> 0;
75223
+ this.hi = (this.hi >>> 1 ^ mask2) >>> 0;
75224
75224
  return this;
75225
75225
  }
75226
75226
  /**
@@ -81244,7 +81244,7 @@ ${[...listenStats.errors.entries()].map(([addr, err2]) => {
81244
81244
  let carry = 0;
81245
81245
  let pos = 0;
81246
81246
  const max = powers[from6];
81247
- const mask = powers[to] - 1;
81247
+ const mask2 = powers[to] - 1;
81248
81248
  const res = [];
81249
81249
  for (const n of data) {
81250
81250
  anumber6(n);
@@ -81255,13 +81255,13 @@ ${[...listenStats.errors.entries()].map(([addr, err2]) => {
81255
81255
  throw new Error(`convertRadix2: carry overflow pos=${pos} from=${from6}`);
81256
81256
  pos += from6;
81257
81257
  for (; pos >= to; pos -= to)
81258
- res.push((carry >> pos - to & mask) >>> 0);
81258
+ res.push((carry >> pos - to & mask2) >>> 0);
81259
81259
  const pow = powers[pos];
81260
81260
  if (pow === void 0)
81261
81261
  throw new Error("invalid carry");
81262
81262
  carry &= pow - 1;
81263
81263
  }
81264
- carry = carry << to - pos & mask;
81264
+ carry = carry << to - pos & mask2;
81265
81265
  if (!padding2 && pos >= from6)
81266
81266
  throw new Error("Excess padding");
81267
81267
  if (!padding2 && carry > 0)
@@ -84769,13 +84769,13 @@ zoo`.split("\n");
84769
84769
  const windows = Math.ceil(scalarBits2 / W2) + 1;
84770
84770
  const windowSize = 2 ** (W2 - 1);
84771
84771
  const maxNumber = 2 ** W2;
84772
- const mask = bitMask2(W2);
84772
+ const mask2 = bitMask2(W2);
84773
84773
  const shiftBy = BigInt(W2);
84774
- return { windows, windowSize, mask, maxNumber, shiftBy };
84774
+ return { windows, windowSize, mask: mask2, maxNumber, shiftBy };
84775
84775
  }
84776
84776
  function calcOffsets2(n, window2, wOpts) {
84777
- const { windowSize, mask, maxNumber, shiftBy } = wOpts;
84778
- let wbits = Number(n & mask);
84777
+ const { windowSize, mask: mask2, maxNumber, shiftBy } = wOpts;
84778
+ let wbits = Number(n & mask2);
84779
84779
  let nextN = n >> shiftBy;
84780
84780
  if (wbits > windowSize) {
84781
84781
  wbits -= maxNumber;
@@ -87477,7 +87477,7 @@ ${r.steps.map((s3) => `${s3.ok ? "\u2713" : "\u2717"} ${s3.step}: ${s3.note}`).j
87477
87477
  result: reply,
87478
87478
  did: id.did,
87479
87479
  mode: "fallback",
87480
- hint: "\u5F53\u524D\u662F\u300C\u624B\u673A\u672C\u5730\u89C4\u5219\u300D\u6A21\u5F0F\uFF1A\u8FD9\u53F0\u624B\u673A\u4E0A\u8FD8\u6CA1\u63A5\u539F\u751F\u6267\u884C\u80FD\u529B (iOS \u6682\u4E0D\u652F\u6301\u539F\u751F\u64CD\u63A7 App; Android \u9700\u5F00\u65E0\u969C\u788D\u670D\u52A1)\uFF0C\u6240\u4EE5\u53EA\u80FD\u7528\u5185\u7F6E\u89C4\u5219\u56DE\u590D\u3002\u8FDE\u4E0A\u7535\u8111\u7AEF\u540E\uFF0C\u4EFB\u52A1\u53EF\u4EE5\u4EA4\u7ED9\u7535\u8111\u7AEF Agent \u771F\u6B63\u6267\u884C\u3002"
87480
+ hint: "\u5F53\u524D\u662F\u300C\u624B\u673A\u672C\u5730\u89C4\u5219\u300D\u6A21\u5F0F\uFF1A\u8FD9\u53F0\u624B\u673A\u4E0A\u8FD8\u6CA1\u63A5\u539F\u751F\u6267\u884C\u80FD\u529B\uFF0C\u6240\u4EE5\u53EA\u80FD\u7528\u5185\u7F6E\u89C4\u5219\u56DE\u590D\u3002\u8FDE\u4E0A\u7535\u8111\u7AEF\u540E\uFF0C\u4EFB\u52A1\u53EF\u4EE5\u4EA4\u7ED9\u7535\u8111\u7AEF Agent \u771F\u6B63\u6267\u884C\u3002"
87481
87481
  };
87482
87482
  } catch (e) {
87483
87483
  return {
@@ -87486,7 +87486,7 @@ ${r.steps.map((s3) => `${s3.ok ? "\u2713" : "\u2717"} ${s3.step}: ${s3.note}`).j
87486
87486
  error: String(e?.message || e).slice(0, 100),
87487
87487
  did: id.did,
87488
87488
  mode: native ? "native" : "fallback",
87489
- hint: "\u4EFB\u52A1\u6CA1\u8DD1\u8D77\u6765\u3002\u5E38\u89C1\u539F\u56E0\uFF1A\u2460 \u7535\u8111\u7AEF\u6CA1\u5728\u8FD0\u884C\u6216\u4E0D\u540C\u7F51\u6BB5 (\u8BBE\u7F6E \u2192 \u7535\u8111\u7AEF\u540C\u6B65 \u91CC\u914D\u7F6E/\u6D4B\u8BD5) \u2461 \u6CA1\u914D LLM API (\u8BBE\u7F6E \u2192 API \u914D\u7F6E) \u2462 \u8FD9\u53F0\u624B\u673A\u6CA1\u63A5\u539F\u751F\u6267\u884C\u80FD\u529B (iOS \u4E0D\u652F\u6301\u539F\u751F\u64CD\u63A7, Android \u9700\u65E0\u969C\u788D\u670D\u52A1)\u3002"
87489
+ hint: "\u4EFB\u52A1\u6CA1\u8DD1\u8D77\u6765\u3002\u5E38\u89C1\u539F\u56E0\uFF1A\u2460 \u7535\u8111\u7AEF\u6CA1\u5728\u8FD0\u884C\u6216\u4E0D\u540C\u7F51\u6BB5 (\u8BBE\u7F6E \u2192 \u7535\u8111\u7AEF\u540C\u6B65 \u91CC\u914D\u7F6E/\u6D4B\u8BD5) \u2461 \u6CA1\u914D LLM API (\u8BBE\u7F6E \u2192 API \u914D\u7F6E) \u2462 \u8FD9\u53F0\u624B\u673A\u6CA1\u63A5\u539F\u751F\u6267\u884C\u80FD\u529B\u3002"
87490
87490
  };
87491
87491
  }
87492
87492
  }
@@ -87666,6 +87666,406 @@ ${r.steps.map((s3) => `${s3.ok ? "\u2713" : "\u2717"} ${s3.step}: ${s3.note}`).j
87666
87666
  }
87667
87667
  });
87668
87668
 
87669
+ // src/agents/contacts/grant-payload.ts
87670
+ function canonicalGrantPayload(g) {
87671
+ return JSON.stringify({
87672
+ grantId: g.grantId,
87673
+ identityId: g.identityId,
87674
+ ownerDid: g.ownerDid,
87675
+ level: g.level,
87676
+ channels: g.channels,
87677
+ contactScope: g.contactScope,
87678
+ taskScope: g.taskScope,
87679
+ contentScope: g.contentScope,
87680
+ replyWakeAllowed: g.replyWakeAllowed,
87681
+ autoSend: g.autoSend,
87682
+ sensitiveContentAllowed: g.sensitiveContentAllowed,
87683
+ newRecipientAllowed: g.newRecipientAllowed,
87684
+ grantedAt: g.grantedAt,
87685
+ grantedBy: g.grantedBy,
87686
+ grantedVia: g.grantedVia,
87687
+ deviceIds: [...g.deviceIds].sort(),
87688
+ status: g.status,
87689
+ revokedAt: g.revokedAt || "",
87690
+ grantVersion: g.grantVersion
87691
+ });
87692
+ }
87693
+ function canonicalRevocationPayload(r) {
87694
+ return JSON.stringify({ grantId: r.grantId, grantVersion: r.grantVersion, revokedAt: r.revokedAt, by: r.by });
87695
+ }
87696
+ function presetForChoice(choice) {
87697
+ const base6 = { channels: "both", replyWakeAllowed: true, autoSend: true, newRecipientAllowed: false };
87698
+ switch (choice) {
87699
+ case "task_once":
87700
+ return { ...base6, level: "task_once", contactScope: "verified_contacts", taskScope: "current_goal", contentScope: "normal", autoSend: false, sensitiveContentAllowed: false };
87701
+ case "persistent":
87702
+ return { ...base6, level: "persistent", contactScope: "verified_contacts", taskScope: "all_future_goals", contentScope: "normal", sensitiveContentAllowed: false };
87703
+ case "full_contact_access":
87704
+ return { ...base6, level: "full_contact_access", contactScope: "all_contacts", taskScope: "all_future_goals", contentScope: "sensitive", sensitiveContentAllowed: true };
87705
+ }
87706
+ }
87707
+ var init_grant_payload = __esm({
87708
+ "src/agents/contacts/grant-payload.ts"() {
87709
+ "use strict";
87710
+ }
87711
+ });
87712
+
87713
+ // src/web/mobile-contacts.ts
87714
+ var mobile_contacts_exports = {};
87715
+ __export(mobile_contacts_exports, {
87716
+ authorizeFromPhone: () => authorizeFromPhone,
87717
+ bindFromPhone: () => bindFromPhone,
87718
+ buildPhoneCard: () => buildPhoneCard,
87719
+ decideApprovalFromPhone: () => decideApprovalFromPhone,
87720
+ ed25519Available: () => ed25519Available,
87721
+ flushQueuedGrants: () => flushQueuedGrants,
87722
+ loadCapabilityCopy: () => loadCapabilityCopy,
87723
+ loadFromDesktop: () => loadFromDesktop,
87724
+ loadOrCreateDeviceKey: () => loadOrCreateDeviceKey,
87725
+ pendingQueue: () => pendingQueue,
87726
+ registerDeviceOnDesktop: () => registerDeviceOnDesktop,
87727
+ revokeFromPhone: () => revokeFromPhone,
87728
+ saveCapabilityCopy: () => saveCapabilityCopy,
87729
+ sha256HexOf: () => sha256HexOf,
87730
+ signGrantOnDevice: () => signGrantOnDevice,
87731
+ signPayloadOnDevice: () => signPayloadOnDevice,
87732
+ signPayloadWithMaterial: () => signPayloadWithMaterial,
87733
+ signRevocationOnDevice: () => signRevocationOnDevice,
87734
+ verifyFromPhone: () => verifyFromPhone
87735
+ });
87736
+ function ed25519Available(c) {
87737
+ const cobj = cryptoOf(c);
87738
+ if (!cobj?.subtle) return false;
87739
+ try {
87740
+ const alg = { name: "Ed25519" };
87741
+ return typeof cobj.subtle.importKey === "function" && !!alg;
87742
+ } catch {
87743
+ return false;
87744
+ }
87745
+ }
87746
+ function bytesOf(s2) {
87747
+ const src4 = new TextEncoder().encode(s2);
87748
+ const out = new Uint8Array(new ArrayBuffer(src4.byteLength));
87749
+ out.set(src4);
87750
+ return out;
87751
+ }
87752
+ function b64(buf) {
87753
+ const arr = new Uint8Array(buf);
87754
+ let out = "";
87755
+ for (let i = 0; i < arr.length; i++) out += String.fromCharCode(arr[i]);
87756
+ return btoa(out);
87757
+ }
87758
+ function pemFromSpki(spki) {
87759
+ const b = b64(spki).replace(/(.{64})/g, "$1\n").trim();
87760
+ return `-----BEGIN PUBLIC KEY-----
87761
+ ${b}
87762
+ -----END PUBLIC KEY-----
87763
+ `;
87764
+ }
87765
+ async function sha256Hex(c, text) {
87766
+ const d2 = await c.subtle.digest("SHA-256", bytesOf(text));
87767
+ return [...new Uint8Array(d2)].map((x) => x.toString(16).padStart(2, "0")).join("");
87768
+ }
87769
+ async function loadOrCreateDeviceKey(storage2, c) {
87770
+ const cobj = cryptoOf(c);
87771
+ if (!cobj?.subtle) throw new Error("device_signing_unavailable: \u672C\u673A\u6CA1\u6709 WebCrypto");
87772
+ const raw = storage2.getItem(K_DEVICE);
87773
+ if (raw) {
87774
+ try {
87775
+ const parsed = JSON.parse(raw);
87776
+ if (parsed?.privateKeyJwk && parsed?.publicKeyPem && parsed?.deviceId) return parsed;
87777
+ } catch {
87778
+ }
87779
+ }
87780
+ let pair;
87781
+ try {
87782
+ pair = await cobj.subtle.generateKey({ name: "Ed25519" }, true, ["sign", "verify"]);
87783
+ } catch (err2) {
87784
+ throw new Error(`device_signing_unavailable: ${String(err2?.message || err2)}`);
87785
+ }
87786
+ const publicKeyPem = pemFromSpki(await cobj.subtle.exportKey("spki", pair.publicKey));
87787
+ const privateKeyJwk = await cobj.subtle.exportKey("jwk", pair.privateKey);
87788
+ const deviceId = `dev-${(await sha256Hex(cobj, publicKeyPem)).slice(0, 12)}`;
87789
+ const material = { deviceId, publicKeyPem, privateKeyJwk };
87790
+ storage2.setItem(K_DEVICE, JSON.stringify(material));
87791
+ return material;
87792
+ }
87793
+ async function signGrantOnDevice(grant, storage2, c) {
87794
+ return signPayloadOnDevice(canonicalGrantPayload(grant), storage2, c);
87795
+ }
87796
+ async function signRevocationOnDevice(rev, storage2, c) {
87797
+ return signPayloadOnDevice(canonicalRevocationPayload(rev), storage2, c);
87798
+ }
87799
+ async function signPayloadOnDevice(payload, storage2, c) {
87800
+ const cobj = cryptoOf(c);
87801
+ if (!cobj?.subtle) throw new Error("device_signing_unavailable: \u672C\u673A\u6CA1\u6709 WebCrypto");
87802
+ const material = await loadOrCreateDeviceKey(storage2, cobj);
87803
+ const key = await cobj.subtle.importKey("jwk", material.privateKeyJwk, { name: "Ed25519" }, false, ["sign"]);
87804
+ const bytes = bytesOf(String(payload ?? ""));
87805
+ const sig = await cobj.subtle.sign({ name: "Ed25519" }, key, bytes);
87806
+ return { deviceId: material.deviceId, alg: "ed25519", payloadHash: await sha256Hex(cobj, String(payload ?? "")), sig: b64(sig) };
87807
+ }
87808
+ async function sha256HexOf(text, c) {
87809
+ const cobj = cryptoOf(c);
87810
+ if (!cobj?.subtle) throw new Error("device_signing_unavailable: \u672C\u673A\u6CA1\u6709 WebCrypto");
87811
+ return sha256Hex(cobj, String(text ?? ""));
87812
+ }
87813
+ async function signPayloadWithMaterial(payload, material, c) {
87814
+ const cobj = cryptoOf(c);
87815
+ if (!cobj?.subtle) throw new Error("device_signing_unavailable: \u672C\u673A\u6CA1\u6709 WebCrypto");
87816
+ const key = await cobj.subtle.importKey("jwk", material.privateKeyJwk, { name: "Ed25519" }, false, ["sign"]);
87817
+ const sig = await cobj.subtle.sign({ name: "Ed25519" }, key, bytesOf(String(payload ?? "")));
87818
+ return { deviceId: material.deviceId, alg: "ed25519", payloadHash: await sha256Hex(cobj, String(payload ?? "")), sig: b64(sig) };
87819
+ }
87820
+ async function post(base6, path, body, f) {
87821
+ const res = await f(`${String(base6).replace(/\/+$/, "")}${path}`, {
87822
+ method: "POST",
87823
+ headers: { "Content-Type": "application/json" },
87824
+ body: JSON.stringify(body ?? {})
87825
+ });
87826
+ let json = null;
87827
+ try {
87828
+ json = await res.json();
87829
+ } catch {
87830
+ }
87831
+ return { status: res.status, json };
87832
+ }
87833
+ async function get(base6, path, f) {
87834
+ const res = await f(`${String(base6).replace(/\/+$/, "")}${path}`);
87835
+ let json = null;
87836
+ try {
87837
+ json = await res.json();
87838
+ } catch {
87839
+ }
87840
+ return { status: res.status, json };
87841
+ }
87842
+ async function registerDeviceOnDesktop(base6, storage2, opts = {}) {
87843
+ const f = opts.fetchImpl || fetch;
87844
+ const dev = await loadOrCreateDeviceKey(storage2, opts.cryptoObj);
87845
+ const r = await post(base6, "/api/contacts/devices", { deviceId: dev.deviceId, publicKeyPem: dev.publicKeyPem, label: opts.label || "\u624B\u673A" }, f);
87846
+ if (r.status !== 200 || !r.json?.ok) return { ok: false, error: `\u684C\u9762\u672A\u63A5\u53D7\u8BBE\u5907\u767B\u8BB0: ${r.json?.error || r.status}`, data: dev };
87847
+ return { ok: true, data: dev };
87848
+ }
87849
+ function saveCapabilityCopy(storage2, items) {
87850
+ const clean8 = (items || []).map((c) => ({
87851
+ contactId: String(c.contactId || ""),
87852
+ kind: c.kind,
87853
+ displayValue: String(c.displayValue || ""),
87854
+ verificationStatus: String(c.verificationStatus || ""),
87855
+ capabilities: [...c.capabilities || []],
87856
+ provider: c.provider ? String(c.provider) : void 0,
87857
+ state: c.state ? String(c.state) : void 0
87858
+ }));
87859
+ storage2.setItem(K_CAPS, JSON.stringify(clean8));
87860
+ }
87861
+ function loadCapabilityCopy(storage2) {
87862
+ try {
87863
+ const v = JSON.parse(storage2.getItem(K_CAPS) || "[]");
87864
+ return Array.isArray(v) ? v : [];
87865
+ } catch {
87866
+ return [];
87867
+ }
87868
+ }
87869
+ function pendingQueue(storage2) {
87870
+ try {
87871
+ const v = JSON.parse(storage2.getItem(K_QUEUE) || "[]");
87872
+ return Array.isArray(v) ? v : [];
87873
+ } catch {
87874
+ return [];
87875
+ }
87876
+ }
87877
+ function setQueue(storage2, q) {
87878
+ storage2.setItem(K_QUEUE, JSON.stringify(q.slice(-20)));
87879
+ }
87880
+ async function flushQueuedGrants(base6, storage2, opts = {}) {
87881
+ const f = opts.fetchImpl || fetch;
87882
+ const q = pendingQueue(storage2);
87883
+ const keep = [];
87884
+ const results = [];
87885
+ let sent = 0, failed = 0;
87886
+ for (const item of q) {
87887
+ try {
87888
+ const r = await post(base6, "/api/contacts/grants/sync", { grant: { ...item.grant, signature: item.signature } }, f);
87889
+ if (r.status === 200 && r.json?.ok) {
87890
+ sent++;
87891
+ results.push({ grantId: item.grant.grantId, ok: true });
87892
+ continue;
87893
+ }
87894
+ failed++;
87895
+ keep.push(item);
87896
+ results.push({ grantId: item.grant.grantId, ok: false, error: r.json?.code || r.status });
87897
+ } catch {
87898
+ failed++;
87899
+ keep.push(item);
87900
+ results.push({ grantId: item.grant.grantId, ok: false, error: "network" });
87901
+ }
87902
+ }
87903
+ setQueue(storage2, keep);
87904
+ return { sent, failed, results };
87905
+ }
87906
+ async function authorizeFromPhone(input) {
87907
+ const c = cryptoOf(input.cryptoObj);
87908
+ if (!ed25519Available(c || void 0)) {
87909
+ return { ok: false, error: "device_signing_unavailable: \u672C\u673A WebView \u4E0D\u652F\u6301 Ed25519 \u8BBE\u5907\u7B7E\u540D \u2014\u2014 \u8BF7\u5728\u684C\u9762\u7AEF\u6388\u6743 (\u6216\u5347\u7EA7\u7CFB\u7EDF WebView)" };
87910
+ }
87911
+ const dev = await loadOrCreateDeviceKey(input.storage, c);
87912
+ const preset = presetForChoice(input.choice);
87913
+ const grant = {
87914
+ grantId: `gr-${Date.now().toString(36)}-${Math.random().toString(36).slice(2, 8)}`,
87915
+ identityId: input.identityId || `sid-phone-${dev.deviceId.slice(-6)}`,
87916
+ ownerDid: input.ownerDid,
87917
+ ...preset,
87918
+ grantedAt: (/* @__PURE__ */ new Date()).toISOString(),
87919
+ grantedBy: input.grantedBy || "leo",
87920
+ grantedVia: "mobile",
87921
+ deviceIds: [dev.deviceId],
87922
+ status: "active",
87923
+ grantVersion: 1
87924
+ };
87925
+ const signature = await signGrantOnDevice(grant, input.storage, c);
87926
+ const f = input.fetchImpl || fetch;
87927
+ const reg = await registerDeviceOnDesktop(input.base, input.storage, { fetchImpl: f, cryptoObj: c }).catch(() => ({ ok: false }));
87928
+ if (!reg.ok) {
87929
+ const q2 = pendingQueue(input.storage);
87930
+ q2.push({ grant, signature, queuedAt: (/* @__PURE__ */ new Date()).toISOString() });
87931
+ setQueue(input.storage, q2);
87932
+ return {
87933
+ ok: false,
87934
+ queued: true,
87935
+ error: `\u684C\u9762\u6682\u4E0D\u53EF\u8FBE \u2192 \u6388\u6743\u5DF2\u5B58\u5728\u624B\u673A, \u5F85\u684C\u9762\u5728\u7EBF\u65F6\u81EA\u52A8\u540C\u6B65 (${reg.error || "offline"})`,
87936
+ data: { grantId: grant.grantId, level: grant.level, signature },
87937
+ note: "\u684C\u9762\u4E0D\u5728\u7EBF\u65F6\u4E0D\u5047\u88C5\u5DF2\u751F\u6548: \u6388\u6743\u5728\u672C\u5730\u961F\u5217\u91CC, \u684C\u9762\u4E00\u4E0A\u7EBF\u5C31\u8865\u540C\u6B65"
87938
+ };
87939
+ }
87940
+ const r = await post(input.base, "/api/contacts/grants/sync", { grant: { ...grant, signature } }, f);
87941
+ if (r.status === 200 && r.json?.ok) {
87942
+ return { ok: true, data: { grantId: grant.grantId, level: grant.level, signature }, note: "\u684C\u9762\u5DF2\u9A8C\u7B7E\u63A5\u53D7" };
87943
+ }
87944
+ const q = pendingQueue(input.storage);
87945
+ q.push({ grant, signature, queuedAt: (/* @__PURE__ */ new Date()).toISOString() });
87946
+ setQueue(input.storage, q);
87947
+ return {
87948
+ ok: false,
87949
+ queued: true,
87950
+ error: `\u684C\u9762\u62D2\u7EDD/\u672A\u63A5\u53D7: ${r.json?.code || r.json?.reason || r.status}`,
87951
+ data: { grantId: grant.grantId, level: grant.level, signature },
87952
+ note: "\u5DF2\u4FDD\u5B58\u5728\u624B\u673A\u672C\u5730\u961F\u5217 (\u4E0D\u4F1A\u56E0\u4E3A\u5931\u8D25\u5C31\u5F53\u6210\u5DF2\u6388\u6743)"
87953
+ };
87954
+ }
87955
+ async function revokeFromPhone(opts) {
87956
+ const c = cryptoOf(opts.cryptoObj);
87957
+ if (!ed25519Available(c || void 0)) return { ok: false, error: "device_signing_unavailable: \u672C\u673A\u4E0D\u652F\u6301\u8BBE\u5907\u7B7E\u540D, \u64A4\u9500\u9700\u5728\u684C\u9762\u7AEF\u8FDB\u884C" };
87958
+ const revokedAt = (/* @__PURE__ */ new Date()).toISOString();
87959
+ const payload = { grantId: opts.grantId, grantVersion: opts.version || 1, revokedAt, by: "mobile" };
87960
+ const signature = await signRevocationOnDevice(payload, opts.storage, c);
87961
+ const f = opts.fetchImpl || fetch;
87962
+ const r = await post(opts.base, "/api/contacts/grants/revoke-sync", { grantId: opts.grantId, by: "mobile", reason: opts.reason, version: payload.grantVersion, revokedAt, signature }, f);
87963
+ if (r.status === 200 && r.json?.ok) return { ok: true, data: { grantId: opts.grantId }, note: "\u684C\u9762\u5DF2\u9A8C\u7B7E\u5E76\u7ACB\u5373\u5931\u6548" };
87964
+ return { ok: false, error: `\u64A4\u9500\u672A\u9001\u8FBE: ${r.json?.code || r.json?.error || r.status}`, note: "\u684C\u9762\u4E0D\u5728\u7EBF\u65F6\u64A4\u9500**\u4E0D\u4F1A**\u88AB\u5F53\u4F5C\u5DF2\u5B8C\u6210 \u2014\u2014 \u8BF7\u5728\u684C\u9762\u5728\u7EBF\u540E\u91CD\u8BD5 (\u6216\u684C\u9762\u7AEF\u64A4\u9500)" };
87965
+ }
87966
+ async function loadFromDesktop(base6, storage2, opts = {}) {
87967
+ const f = opts.fetchImpl || fetch;
87968
+ if (!base6) {
87969
+ const caps = loadCapabilityCopy(storage2);
87970
+ return {
87971
+ ok: false,
87972
+ error: "desktop_offline",
87973
+ data: { contacts: caps, grants: [], effective: "\u684C\u9762\u4E0D\u5728\u7EBF (\u663E\u793A\u624B\u673A\u672C\u5730\u526F\u672C)", approvals: [], waiting: [] },
87974
+ note: "\u4EE5\u4E0B\u662F\u4F60\u624B\u673A\u4E0A\u4FDD\u5B58\u7684\u80FD\u529B\u526F\u672C (\u4E0D\u662F\u684C\u9762\u5B9E\u65F6\u72B6\u6001)"
87975
+ };
87976
+ }
87977
+ try {
87978
+ const a = await get(base6, "/api/contacts", f);
87979
+ const b = await get(base6, "/api/contacts/grants", f);
87980
+ if (a.status !== 200 && b.status !== 200) return { ok: false, error: `desktop_http_${a.status || b.status}` };
87981
+ const view = {
87982
+ contacts: a.json?.contacts || [],
87983
+ grants: b.json?.grants || [],
87984
+ effective: b.json?.effective || "",
87985
+ approvals: a.json?.approvals || [],
87986
+ waiting: a.json?.waiting || []
87987
+ };
87988
+ saveCapabilityCopy(storage2, (view.contacts || []).filter((c) => c.capabilities?.includes("send")).map((c) => ({
87989
+ contactId: c.contactId,
87990
+ kind: c.kind,
87991
+ displayValue: c.displayValue,
87992
+ verificationStatus: c.status,
87993
+ capabilities: c.capabilities,
87994
+ provider: c.provider,
87995
+ state: c.status
87996
+ })));
87997
+ return { ok: true, data: view };
87998
+ } catch (err2) {
87999
+ const caps = loadCapabilityCopy(storage2);
88000
+ return {
88001
+ ok: false,
88002
+ error: "desktop_offline",
88003
+ data: { contacts: caps, grants: [], effective: "\u684C\u9762\u4E0D\u5728\u7EBF (\u663E\u793A\u624B\u673A\u672C\u5730\u526F\u672C)", approvals: [], waiting: [] },
88004
+ note: `\u8FDE\u4E0D\u4E0A\u684C\u9762 (${String(err2?.message || err2).slice(0, 60)}) \u2014\u2014 \u663E\u793A\u672C\u5730\u526F\u672C`
88005
+ };
88006
+ }
88007
+ }
88008
+ async function bindFromPhone(base6, opts, storage2, f) {
88009
+ const impl = f || fetch;
88010
+ if (!base6) return { ok: false, error: "desktop_offline: \u7ED1\u5B9A\u9700\u8981\u684C\u9762\u7AEF\u5728\u7EBF (\u684C\u9762\u8D1F\u8D23\u843D\u76D8\u4E0E\u9A8C\u8BC1\u7801\u901A\u9053)" };
88011
+ const r = await post(base6, "/api/contacts/bind", { kind: opts.kind, value: opts.value, region: opts.region }, impl);
88012
+ if (r.status === 200 && r.json?.ok) return { ok: true, data: r.json };
88013
+ return { ok: false, error: r.json?.error || `HTTP ${r.status}` };
88014
+ }
88015
+ async function verifyFromPhone(base6, opts, storage2, f) {
88016
+ const impl = f || fetch;
88017
+ if (!base6) return { ok: false, error: "desktop_offline: \u9A8C\u8BC1\u9700\u8981\u684C\u9762\u7AEF\u5728\u7EBF" };
88018
+ const r = await post(base6, "/api/contacts/verify", { contactId: opts.contactId, challengeId: opts.challengeId, code: opts.code }, impl);
88019
+ if (r.status === 200 && r.json?.ok) return { ok: true, data: r.json };
88020
+ return { ok: false, error: r.json?.error || `HTTP ${r.status}` };
88021
+ }
88022
+ async function decideApprovalFromPhone(base6, opts, f) {
88023
+ const impl = f || fetch;
88024
+ if (!base6) return { ok: false, error: "desktop_offline: \u6279\u51C6\u9700\u8981\u684C\u9762\u7AEF\u5728\u7EBF (\u624B\u673A\u4E0D\u5728\u7EBF\u65F6\u4E0D\u4F1A\u5047\u88C5\u5DF2\u6279\u51C6)" };
88025
+ const r = await post(base6, `/api/contacts/approvals/${encodeURIComponent(opts.consentId)}/${opts.action}`, { by: "leo", via: "mobile", body: opts.body, reason: opts.reason }, impl);
88026
+ if (r.status === 200 && r.json?.ok) return { ok: true, data: r.json };
88027
+ return { ok: false, error: r.json?.error || `HTTP ${r.status}` };
88028
+ }
88029
+ function buildPhoneCard(view, opts) {
88030
+ return {
88031
+ title: "\u8BA9 Bolloon \u4EE3\u8868\u4F60\u8054\u7CFB\u5916\u90E8\u7684\u4EBA",
88032
+ effective: view?.effective || opts.offline || "\u672A\u77E5",
88033
+ contacts: (view?.contacts || []).map((c) => ({
88034
+ displayValue: c.displayValue || "",
88035
+ kind: c.kind || "",
88036
+ state: c.status || c.verificationStatus || "",
88037
+ label: c.capabilities?.includes("send") ? "\u53EF\u8054\u7CFB" : "\u4E0D\u53EF\u8054\u7CFB"
88038
+ })),
88039
+ approvals: (view?.approvals || []).map((a) => ({
88040
+ consentId: a.consentId,
88041
+ contactName: a.contactName,
88042
+ channel: a.channel,
88043
+ subject: a.subject,
88044
+ bodyPreview: a.bodyPreview || "",
88045
+ reason: a.reason,
88046
+ reallySent: !!a.reallySent
88047
+ })),
88048
+ choices: [
88049
+ { id: "task_once", label: "\u4EC5\u672C\u6B21\u4EFB\u52A1" },
88050
+ { id: "persistent", label: "\u957F\u671F\u4F7F\u7528 (\u63A8\u8350)" },
88051
+ { id: "full_contact_access", label: "\u5B8C\u5168\u6388\u6743\u8054\u7CFB\u65B9\u5F0F\u80FD\u529B" }
88052
+ ],
88053
+ willNotGet: ["\u8BFB\u53D6\u5168\u90E8\u90AE\u7BB1", "\u8BFB\u53D6\u901A\u8BAF\u5F55", "\u7FA4\u53D1\u6D88\u606F", "\u81EA\u52A8\u652F\u4ED8/\u8F6C\u8D26", "\u4EE3\u8868\u4F60\u7B7E\u7F72\u5408\u540C", "\u62FF\u5230\u624B\u673A\u53F7/\u90AE\u7BB1\u660E\u6587"],
88054
+ deviceSigning: opts.deviceSigning
88055
+ };
88056
+ }
88057
+ var K_DEVICE, K_QUEUE, K_CAPS, cryptoOf;
88058
+ var init_mobile_contacts = __esm({
88059
+ "src/web/mobile-contacts.ts"() {
88060
+ "use strict";
88061
+ init_grant_payload();
88062
+ K_DEVICE = "bolloon.contacts.device.v1";
88063
+ K_QUEUE = "bolloon.contacts.queue.v1";
88064
+ K_CAPS = "bolloon.contacts.capabilities.v1";
88065
+ cryptoOf = (c) => c || globalThis.crypto || null;
88066
+ }
88067
+ });
88068
+
87669
88069
  // src/web/mobile-social.ts
87670
88070
  var mobile_social_exports = {};
87671
88071
  __export(mobile_social_exports, {
@@ -90103,13 +90503,13 @@ ${r.steps.map((s3) => `${s3.ok ? "\u2713" : "\u2717"} ${s3.step}: ${s3.note}`).j
90103
90503
  const windows = Math.ceil(scalarBits2 / W2) + 1;
90104
90504
  const windowSize = 2 ** (W2 - 1);
90105
90505
  const maxNumber = 2 ** W2;
90106
- const mask = bitMask3(W2);
90506
+ const mask2 = bitMask3(W2);
90107
90507
  const shiftBy = BigInt(W2);
90108
- return { windows, windowSize, mask, maxNumber, shiftBy };
90508
+ return { windows, windowSize, mask: mask2, maxNumber, shiftBy };
90109
90509
  }
90110
90510
  function calcOffsets3(n, window2, wOpts) {
90111
- const { windowSize, mask, maxNumber, shiftBy } = wOpts;
90112
- let wbits = Number(n & mask);
90511
+ const { windowSize, mask: mask2, maxNumber, shiftBy } = wOpts;
90512
+ let wbits = Number(n & mask2);
90113
90513
  let nextN = n >> shiftBy;
90114
90514
  if (wbits > windowSize) {
90115
90515
  wbits -= maxNumber;
@@ -95154,10 +95554,10 @@ ${r.steps.map((s3) => `${s3.ok ? "\u2713" : "\u2717"} ${s3.step}: ${s3.note}`).j
95154
95554
  let f = G;
95155
95555
  const pow_2_w = 2 ** W;
95156
95556
  const maxNum = pow_2_w;
95157
- const mask = big(pow_2_w - 1);
95557
+ const mask2 = big(pow_2_w - 1);
95158
95558
  const shiftBy = big(W);
95159
95559
  for (let w2 = 0; w2 < pwindows; w2++) {
95160
- let wbits = Number(n & mask);
95560
+ let wbits = Number(n & mask2);
95161
95561
  n >>= shiftBy;
95162
95562
  if (wbits > pwindowSize) {
95163
95563
  wbits -= maxNum;
@@ -96895,11 +97295,11 @@ ${r.steps.map((s3) => `${s3.ok ? "\u2713" : "\u2717"} ${s3.step}: ${s3.note}`).j
96895
97295
  function toToken6(data, pos, prefix, length20, options2) {
96896
97296
  const totLength = prefix + length20;
96897
97297
  assertEnoughData2(data, pos, totLength);
96898
- const tok = new Token2(Type2.string, toStr2(data, pos + prefix, pos + totLength), totLength);
97298
+ const tok2 = new Token2(Type2.string, toStr2(data, pos + prefix, pos + totLength), totLength);
96899
97299
  if (options2.retainStringBytes === true) {
96900
- tok.byteValue = data.slice(pos + prefix, pos + totLength);
97300
+ tok2.byteValue = data.slice(pos + prefix, pos + totLength);
96901
97301
  }
96902
- return tok;
97302
+ return tok2;
96903
97303
  }
96904
97304
  function decodeStringCompact2(data, pos, minor, options2) {
96905
97305
  return toToken6(data, pos, 1, minor, options2);
@@ -98382,7 +98782,7 @@ ${r.steps.map((s3) => `${s3.ok ? "\u2713" : "\u2717"} ${s3.step}: ${s3.note}`).j
98382
98782
  }
98383
98783
  function encode15(data, alphabet4, bitsPerChar) {
98384
98784
  const pad2 = alphabet4[alphabet4.length - 1] === "=";
98385
- const mask = (1 << bitsPerChar) - 1;
98785
+ const mask2 = (1 << bitsPerChar) - 1;
98386
98786
  let out = "";
98387
98787
  let bits = 0;
98388
98788
  let buffer6 = 0;
@@ -98391,11 +98791,11 @@ ${r.steps.map((s3) => `${s3.ok ? "\u2713" : "\u2717"} ${s3.step}: ${s3.note}`).j
98391
98791
  bits += 8;
98392
98792
  while (bits > bitsPerChar) {
98393
98793
  bits -= bitsPerChar;
98394
- out += alphabet4[mask & buffer6 >> bits];
98794
+ out += alphabet4[mask2 & buffer6 >> bits];
98395
98795
  }
98396
98796
  }
98397
98797
  if (bits !== 0) {
98398
- out += alphabet4[mask & buffer6 << bitsPerChar - bits];
98798
+ out += alphabet4[mask2 & buffer6 << bitsPerChar - bits];
98399
98799
  }
98400
98800
  if (pad2) {
98401
98801
  while ((out.length * bitsPerChar & 7) !== 0) {
@@ -99216,7 +99616,7 @@ ${r.steps.map((s3) => `${s3.ok ? "\u2713" : "\u2717"} ${s3.step}: ${s3.note}`).j
99216
99616
  computeCid: () => computeCid,
99217
99617
  createIpfsClient: () => createIpfsClient,
99218
99618
  createMemoryStorage: () => createMemoryStorage,
99219
- defaultStorage: () => defaultStorage2,
99619
+ defaultStorage: () => defaultStorage3,
99220
99620
  getIpfsConfig: () => getIpfsConfig,
99221
99621
  ipfsCacheGet: () => ipfsCacheGet,
99222
99622
  ipfsCacheSet: () => ipfsCacheSet,
@@ -99247,7 +99647,7 @@ ${r.steps.map((s3) => `${s3.ok ? "\u2713" : "\u2717"} ${s3.step}: ${s3.note}`).j
99247
99647
  }
99248
99648
  };
99249
99649
  }
99250
- function defaultStorage2() {
99650
+ function defaultStorage3() {
99251
99651
  try {
99252
99652
  if (typeof localStorage !== "undefined" && localStorage) {
99253
99653
  const probe = "__bolloon_ipfs_probe__";
@@ -99317,7 +99717,7 @@ ${r.steps.map((s3) => `${s3.ok ? "\u2713" : "\u2717"} ${s3.step}: ${s3.note}`).j
99317
99717
  }
99318
99718
  }
99319
99719
  }
99320
- function getIpfsConfig(storage2 = defaultStorage2()) {
99720
+ function getIpfsConfig(storage2 = defaultStorage3()) {
99321
99721
  const base6 = { mode: "public", gateways: [...DEFAULT_GATEWAYS] };
99322
99722
  try {
99323
99723
  const raw = storage2.getItem(IPFS_CONFIG_KEY);
@@ -99336,7 +99736,7 @@ ${r.steps.map((s3) => `${s3.ok ? "\u2713" : "\u2717"} ${s3.step}: ${s3.note}`).j
99336
99736
  return base6;
99337
99737
  }
99338
99738
  }
99339
- function setIpfsConfig(cfg, storage2 = defaultStorage2()) {
99739
+ function setIpfsConfig(cfg, storage2 = defaultStorage3()) {
99340
99740
  try {
99341
99741
  if (cfg.mode !== void 0 && !VALID_MODES.includes(cfg.mode)) {
99342
99742
  return { ok: false, error: `\u975E\u6CD5 mode: ${String(cfg.mode)} (\u5E94\u4E3A public|remote|pinata)` };
@@ -99384,7 +99784,7 @@ ${r.steps.map((s3) => `${s3.ok ? "\u2713" : "\u2717"} ${s3.step}: ${s3.note}`).j
99384
99784
  }
99385
99785
  return kept;
99386
99786
  }
99387
- function ipfsCacheGet(cid, storage2 = defaultStorage2()) {
99787
+ function ipfsCacheGet(cid, storage2 = defaultStorage3()) {
99388
99788
  try {
99389
99789
  const key = normalizeCid(cid);
99390
99790
  if (!key) return null;
@@ -99404,7 +99804,7 @@ ${r.steps.map((s3) => `${s3.ok ? "\u2713" : "\u2717"} ${s3.step}: ${s3.note}`).j
99404
99804
  return null;
99405
99805
  }
99406
99806
  }
99407
- function ipfsCacheSet(cid, text, storage2 = defaultStorage2()) {
99807
+ function ipfsCacheSet(cid, text, storage2 = defaultStorage3()) {
99408
99808
  try {
99409
99809
  const key = normalizeCid(cid);
99410
99810
  if (!key) return { ok: false, error: "cid \u4E0D\u80FD\u4E3A\u7A7A" };
@@ -99488,7 +99888,7 @@ ${r.steps.map((s3) => `${s3.ok ? "\u2713" : "\u2717"} ${s3.step}: ${s3.note}`).j
99488
99888
  async function ipfsFetch(cid, opts = {}) {
99489
99889
  const key = normalizeCid(cid);
99490
99890
  if (!key) return { ok: false, error: "cid \u4E0D\u80FD\u4E3A\u7A7A" };
99491
- const storage2 = opts.storage ?? defaultStorage2();
99891
+ const storage2 = opts.storage ?? defaultStorage3();
99492
99892
  const useCache = opts.useCache !== false;
99493
99893
  if (useCache) {
99494
99894
  const cached = ipfsCacheGet(key, storage2);
@@ -100794,8 +101194,8 @@ ${r.steps.map((s3) => `${s3.ok ? "\u2713" : "\u2717"} ${s3.step}: ${s3.note}`).j
100794
101194
  }
100795
101195
  function encodeInteger2(value2) {
100796
101196
  const contents = new Uint8ArrayList10();
100797
- const mask = 128;
100798
- const positive2 = (value2.subarray()[0] & mask) === mask;
101197
+ const mask2 = 128;
101198
+ const positive2 = (value2.subarray()[0] & mask2) === mask2;
100799
101199
  if (positive2) {
100800
101200
  contents.append(Uint8Array.from([0]));
100801
101201
  }
@@ -100952,18 +101352,18 @@ ${r.steps.map((s3) => `${s3.ok ? "\u2713" : "\u2717"} ${s3.step}: ${s3.note}`).j
100952
101352
  * Zig-zag encodes this long bits
100953
101353
  */
100954
101354
  zzEncode() {
100955
- const mask = this.hi >> 31;
100956
- this.hi = ((this.hi << 1 | this.lo >>> 31) ^ mask) >>> 0;
100957
- this.lo = (this.lo << 1 ^ mask) >>> 0;
101355
+ const mask2 = this.hi >> 31;
101356
+ this.hi = ((this.hi << 1 | this.lo >>> 31) ^ mask2) >>> 0;
101357
+ this.lo = (this.lo << 1 ^ mask2) >>> 0;
100958
101358
  return this;
100959
101359
  }
100960
101360
  /**
100961
101361
  * Zig-zag decodes this long bits
100962
101362
  */
100963
101363
  zzDecode() {
100964
- const mask = -(this.lo & 1);
100965
- this.lo = ((this.lo >>> 1 | this.hi << 31) ^ mask) >>> 0;
100966
- this.hi = (this.hi >>> 1 ^ mask) >>> 0;
101364
+ const mask2 = -(this.lo & 1);
101365
+ this.lo = ((this.lo >>> 1 | this.hi << 31) ^ mask2) >>> 0;
101366
+ this.hi = (this.hi >>> 1 ^ mask2) >>> 0;
100967
101367
  return this;
100968
101368
  }
100969
101369
  /**
@@ -103541,7 +103941,7 @@ ${r.steps.map((s3) => `${s3.ok ? "\u2713" : "\u2717"} ${s3.step}: ${s3.note}`).j
103541
103941
  }
103542
103942
  }
103543
103943
  }
103544
- function get(source, path) {
103944
+ function get2(source, path) {
103545
103945
  let node2 = source;
103546
103946
  for (const [index, key] of path.entries()) {
103547
103947
  node2 = node2[key];
@@ -103597,7 +103997,7 @@ ${r.steps.map((s3) => `${s3.ok ? "\u2713" : "\u2717"} ${s3.step}: ${s3.note}`).j
103597
103997
  return tree(this.value, []);
103598
103998
  }
103599
103999
  get(path = "/") {
103600
- return get(this.value, path.split("/").filter(Boolean));
104000
+ return get2(this.value, path.split("/").filter(Boolean));
103601
104001
  }
103602
104002
  };
103603
104003
  }
@@ -103864,18 +104264,18 @@ ${r.steps.map((s3) => `${s3.ok ? "\u2713" : "\u2717"} ${s3.step}: ${s3.note}`).j
103864
104264
  * Zig-zag encodes this long bits
103865
104265
  */
103866
104266
  zzEncode() {
103867
- const mask = this.hi >> 31;
103868
- this.hi = ((this.hi << 1 | this.lo >>> 31) ^ mask) >>> 0;
103869
- this.lo = (this.lo << 1 ^ mask) >>> 0;
104267
+ const mask2 = this.hi >> 31;
104268
+ this.hi = ((this.hi << 1 | this.lo >>> 31) ^ mask2) >>> 0;
104269
+ this.lo = (this.lo << 1 ^ mask2) >>> 0;
103870
104270
  return this;
103871
104271
  }
103872
104272
  /**
103873
104273
  * Zig-zag decodes this long bits
103874
104274
  */
103875
104275
  zzDecode() {
103876
- const mask = -(this.lo & 1);
103877
- this.lo = ((this.lo >>> 1 | this.hi << 31) ^ mask) >>> 0;
103878
- this.hi = (this.hi >>> 1 ^ mask) >>> 0;
104276
+ const mask2 = -(this.lo & 1);
104277
+ this.lo = ((this.lo >>> 1 | this.hi << 31) ^ mask2) >>> 0;
104278
+ this.hi = (this.hi >>> 1 ^ mask2) >>> 0;
103879
104279
  return this;
103880
104280
  }
103881
104281
  /**
@@ -114756,18 +115156,18 @@ ${values.join("\n")}` : `${blockName} :`;
114756
115156
  * Zig-zag encodes this long bits
114757
115157
  */
114758
115158
  zzEncode() {
114759
- const mask = this.hi >> 31;
114760
- this.hi = ((this.hi << 1 | this.lo >>> 31) ^ mask) >>> 0;
114761
- this.lo = (this.lo << 1 ^ mask) >>> 0;
115159
+ const mask2 = this.hi >> 31;
115160
+ this.hi = ((this.hi << 1 | this.lo >>> 31) ^ mask2) >>> 0;
115161
+ this.lo = (this.lo << 1 ^ mask2) >>> 0;
114762
115162
  return this;
114763
115163
  }
114764
115164
  /**
114765
115165
  * Zig-zag decodes this long bits
114766
115166
  */
114767
115167
  zzDecode() {
114768
- const mask = -(this.lo & 1);
114769
- this.lo = ((this.lo >>> 1 | this.hi << 31) ^ mask) >>> 0;
114770
- this.hi = (this.hi >>> 1 ^ mask) >>> 0;
115168
+ const mask2 = -(this.lo & 1);
115169
+ this.lo = ((this.lo >>> 1 | this.hi << 31) ^ mask2) >>> 0;
115170
+ this.hi = (this.hi >>> 1 ^ mask2) >>> 0;
114771
115171
  return this;
114772
115172
  }
114773
115173
  /**
@@ -117096,18 +117496,18 @@ ${values.join("\n")}` : `${blockName} :`;
117096
117496
  * Zig-zag encodes this long bits
117097
117497
  */
117098
117498
  zzEncode() {
117099
- const mask = this.hi >> 31;
117100
- this.hi = ((this.hi << 1 | this.lo >>> 31) ^ mask) >>> 0;
117101
- this.lo = (this.lo << 1 ^ mask) >>> 0;
117499
+ const mask2 = this.hi >> 31;
117500
+ this.hi = ((this.hi << 1 | this.lo >>> 31) ^ mask2) >>> 0;
117501
+ this.lo = (this.lo << 1 ^ mask2) >>> 0;
117102
117502
  return this;
117103
117503
  }
117104
117504
  /**
117105
117505
  * Zig-zag decodes this long bits
117106
117506
  */
117107
117507
  zzDecode() {
117108
- const mask = -(this.lo & 1);
117109
- this.lo = ((this.lo >>> 1 | this.hi << 31) ^ mask) >>> 0;
117110
- this.hi = (this.hi >>> 1 ^ mask) >>> 0;
117508
+ const mask2 = -(this.lo & 1);
117509
+ this.lo = ((this.lo >>> 1 | this.hi << 31) ^ mask2) >>> 0;
117510
+ this.hi = (this.hi >>> 1 ^ mask2) >>> 0;
117111
117511
  return this;
117112
117512
  }
117113
117513
  /**
@@ -119947,46 +120347,46 @@ ${values.join("\n")}` : `${blockName} :`;
119947
120347
  var len;
119948
120348
  revLookup["-".charCodeAt(0)] = 62;
119949
120349
  revLookup["_".charCodeAt(0)] = 63;
119950
- function getLens(b64) {
119951
- var len2 = b64.length;
120350
+ function getLens(b642) {
120351
+ var len2 = b642.length;
119952
120352
  if (len2 % 4 > 0) {
119953
120353
  throw new Error("Invalid string. Length must be a multiple of 4");
119954
120354
  }
119955
- var validLen = b64.indexOf("=");
120355
+ var validLen = b642.indexOf("=");
119956
120356
  if (validLen === -1) validLen = len2;
119957
120357
  var placeHoldersLen = validLen === len2 ? 0 : 4 - validLen % 4;
119958
120358
  return [validLen, placeHoldersLen];
119959
120359
  }
119960
- function byteLength2(b64) {
119961
- var lens = getLens(b64);
120360
+ function byteLength2(b642) {
120361
+ var lens = getLens(b642);
119962
120362
  var validLen = lens[0];
119963
120363
  var placeHoldersLen = lens[1];
119964
120364
  return (validLen + placeHoldersLen) * 3 / 4 - placeHoldersLen;
119965
120365
  }
119966
- function _byteLength(b64, validLen, placeHoldersLen) {
120366
+ function _byteLength(b642, validLen, placeHoldersLen) {
119967
120367
  return (validLen + placeHoldersLen) * 3 / 4 - placeHoldersLen;
119968
120368
  }
119969
- function toByteArray(b64) {
120369
+ function toByteArray(b642) {
119970
120370
  var tmp;
119971
- var lens = getLens(b64);
120371
+ var lens = getLens(b642);
119972
120372
  var validLen = lens[0];
119973
120373
  var placeHoldersLen = lens[1];
119974
- var arr = new Arr(_byteLength(b64, validLen, placeHoldersLen));
120374
+ var arr = new Arr(_byteLength(b642, validLen, placeHoldersLen));
119975
120375
  var curByte = 0;
119976
120376
  var len2 = placeHoldersLen > 0 ? validLen - 4 : validLen;
119977
120377
  var i2;
119978
120378
  for (i2 = 0; i2 < len2; i2 += 4) {
119979
- tmp = revLookup[b64.charCodeAt(i2)] << 18 | revLookup[b64.charCodeAt(i2 + 1)] << 12 | revLookup[b64.charCodeAt(i2 + 2)] << 6 | revLookup[b64.charCodeAt(i2 + 3)];
120379
+ tmp = revLookup[b642.charCodeAt(i2)] << 18 | revLookup[b642.charCodeAt(i2 + 1)] << 12 | revLookup[b642.charCodeAt(i2 + 2)] << 6 | revLookup[b642.charCodeAt(i2 + 3)];
119980
120380
  arr[curByte++] = tmp >> 16 & 255;
119981
120381
  arr[curByte++] = tmp >> 8 & 255;
119982
120382
  arr[curByte++] = tmp & 255;
119983
120383
  }
119984
120384
  if (placeHoldersLen === 2) {
119985
- tmp = revLookup[b64.charCodeAt(i2)] << 2 | revLookup[b64.charCodeAt(i2 + 1)] >> 4;
120385
+ tmp = revLookup[b642.charCodeAt(i2)] << 2 | revLookup[b642.charCodeAt(i2 + 1)] >> 4;
119986
120386
  arr[curByte++] = tmp & 255;
119987
120387
  }
119988
120388
  if (placeHoldersLen === 1) {
119989
- tmp = revLookup[b64.charCodeAt(i2)] << 10 | revLookup[b64.charCodeAt(i2 + 1)] << 4 | revLookup[b64.charCodeAt(i2 + 2)] >> 2;
120389
+ tmp = revLookup[b642.charCodeAt(i2)] << 10 | revLookup[b642.charCodeAt(i2 + 1)] << 4 | revLookup[b642.charCodeAt(i2 + 2)] >> 2;
119990
120390
  arr[curByte++] = tmp >> 8 & 255;
119991
120391
  arr[curByte++] = tmp & 255;
119992
120392
  }
@@ -129350,12 +129750,12 @@ ${values.join("\n")}` : `${blockName} :`;
129350
129750
  type: MESSAGE_TYPES[opcode]
129351
129751
  };
129352
129752
  }
129353
- let mask;
129753
+ let mask2;
129354
129754
  if (isMasked) {
129355
129755
  if (buf.byteLength < offset + 4) {
129356
129756
  return;
129357
129757
  }
129358
- mask = buf.subarray(offset, offset + 4);
129758
+ mask2 = buf.subarray(offset, offset + 4);
129359
129759
  offset += 4;
129360
129760
  }
129361
129761
  if (buf.byteLength < offset + length20) {
@@ -129363,8 +129763,8 @@ ${values.join("\n")}` : `${blockName} :`;
129363
129763
  }
129364
129764
  let data = buf.subarray(offset, offset + length20);
129365
129765
  offset += length20;
129366
- if (mask != null) {
129367
- data = applyMask(data, mask);
129766
+ if (mask2 != null) {
129767
+ data = applyMask(data, mask2);
129368
129768
  }
129369
129769
  buf.consume(offset);
129370
129770
  return {
@@ -129372,12 +129772,12 @@ ${values.join("\n")}` : `${blockName} :`;
129372
129772
  data
129373
129773
  };
129374
129774
  }
129375
- function applyMask(data, mask) {
129775
+ function applyMask(data, mask2) {
129376
129776
  let m2 = 0;
129377
129777
  for (let i = 0; i < data.byteLength; i++) {
129378
- data[i] = data[i] ^ mask[m2];
129778
+ data[i] = data[i] ^ mask2[m2];
129379
129779
  m2++;
129380
- if (m2 === mask.byteLength) {
129780
+ if (m2 === mask2.byteLength) {
129381
129781
  m2 = 0;
129382
129782
  }
129383
129783
  }
@@ -131917,18 +132317,18 @@ ${values.join("\n")}` : `${blockName} :`;
131917
132317
  * Zig-zag encodes this long bits
131918
132318
  */
131919
132319
  zzEncode() {
131920
- const mask = this.hi >> 31;
131921
- this.hi = ((this.hi << 1 | this.lo >>> 31) ^ mask) >>> 0;
131922
- this.lo = (this.lo << 1 ^ mask) >>> 0;
132320
+ const mask2 = this.hi >> 31;
132321
+ this.hi = ((this.hi << 1 | this.lo >>> 31) ^ mask2) >>> 0;
132322
+ this.lo = (this.lo << 1 ^ mask2) >>> 0;
131923
132323
  return this;
131924
132324
  }
131925
132325
  /**
131926
132326
  * Zig-zag decodes this long bits
131927
132327
  */
131928
132328
  zzDecode() {
131929
- const mask = -(this.lo & 1);
131930
- this.lo = ((this.lo >>> 1 | this.hi << 31) ^ mask) >>> 0;
131931
- this.hi = (this.hi >>> 1 ^ mask) >>> 0;
132329
+ const mask2 = -(this.lo & 1);
132330
+ this.lo = ((this.lo >>> 1 | this.hi << 31) ^ mask2) >>> 0;
132331
+ this.hi = (this.hi >>> 1 ^ mask2) >>> 0;
131932
132332
  return this;
131933
132333
  }
131934
132334
  /**
@@ -135418,12 +135818,12 @@ ${values.join("\n")}` : `${blockName} :`;
135418
135818
  g[i] &= 8191;
135419
135819
  }
135420
135820
  g[9] -= 1 << 13;
135421
- let mask = (c ^ 1) - 1;
135821
+ let mask2 = (c ^ 1) - 1;
135422
135822
  for (let i = 0; i < 10; i++)
135423
- g[i] &= mask;
135424
- mask = ~mask;
135823
+ g[i] &= mask2;
135824
+ mask2 = ~mask2;
135425
135825
  for (let i = 0; i < 10; i++)
135426
- h3[i] = h3[i] & mask | g[i];
135826
+ h3[i] = h3[i] & mask2 | g[i];
135427
135827
  h3[0] = (h3[0] | h3[1] << 13) & 65535;
135428
135828
  h3[1] = (h3[1] >>> 3 | h3[2] << 10) & 65535;
135429
135829
  h3[2] = (h3[2] >>> 6 | h3[3] << 7) & 65535;
@@ -136870,18 +137270,18 @@ ${values.join("\n")}` : `${blockName} :`;
136870
137270
  * Zig-zag encodes this long bits
136871
137271
  */
136872
137272
  zzEncode() {
136873
- const mask = this.hi >> 31;
136874
- this.hi = ((this.hi << 1 | this.lo >>> 31) ^ mask) >>> 0;
136875
- this.lo = (this.lo << 1 ^ mask) >>> 0;
137273
+ const mask2 = this.hi >> 31;
137274
+ this.hi = ((this.hi << 1 | this.lo >>> 31) ^ mask2) >>> 0;
137275
+ this.lo = (this.lo << 1 ^ mask2) >>> 0;
136876
137276
  return this;
136877
137277
  }
136878
137278
  /**
136879
137279
  * Zig-zag decodes this long bits
136880
137280
  */
136881
137281
  zzDecode() {
136882
- const mask = -(this.lo & 1);
136883
- this.lo = ((this.lo >>> 1 | this.hi << 31) ^ mask) >>> 0;
136884
- this.hi = (this.hi >>> 1 ^ mask) >>> 0;
137282
+ const mask2 = -(this.lo & 1);
137283
+ this.lo = ((this.lo >>> 1 | this.hi << 31) ^ mask2) >>> 0;
137284
+ this.hi = (this.hi >>> 1 ^ mask2) >>> 0;
136885
137285
  return this;
136886
137286
  }
136887
137287
  /**
@@ -139954,11 +140354,11 @@ a=end-of-candidates
139954
140354
  function toToken10(data, pos, prefix, length20, options2) {
139955
140355
  const totLength = prefix + length20;
139956
140356
  assertEnoughData3(data, pos, totLength);
139957
- const tok = new Token3(Type3.string, toStr3(data, pos + prefix, pos + totLength), totLength);
140357
+ const tok2 = new Token3(Type3.string, toStr3(data, pos + prefix, pos + totLength), totLength);
139958
140358
  if (options2.retainStringBytes === true) {
139959
- tok.byteValue = data.slice(pos + prefix, pos + totLength);
140359
+ tok2.byteValue = data.slice(pos + prefix, pos + totLength);
139960
140360
  }
139961
- return tok;
140361
+ return tok2;
139962
140362
  }
139963
140363
  function decodeStringCompact3(data, pos, minor, options2) {
139964
140364
  return toToken10(data, pos, 1, minor, options2);
@@ -142177,11 +142577,11 @@ a=end-of-candidates
142177
142577
  function toToken14(data, pos, prefix, length20, options2) {
142178
142578
  const totLength = prefix + length20;
142179
142579
  assertEnoughData4(data, pos, totLength);
142180
- const tok = new Token4(Type4.string, toStr4(data, pos + prefix, pos + totLength), totLength);
142580
+ const tok2 = new Token4(Type4.string, toStr4(data, pos + prefix, pos + totLength), totLength);
142181
142581
  if (options2.retainStringBytes === true) {
142182
- tok.byteValue = data.slice(pos + prefix, pos + totLength);
142582
+ tok2.byteValue = data.slice(pos + prefix, pos + totLength);
142183
142583
  }
142184
- return tok;
142584
+ return tok2;
142185
142585
  }
142186
142586
  function decodeStringCompact4(data, pos, minor, options2) {
142187
142587
  return toToken14(data, pos, 1, minor, options2);
@@ -148151,11 +148551,11 @@ ${indent}[Error list was empty]`;
148151
148551
  function toToken18(data, pos, prefix, length20, options2) {
148152
148552
  const totLength = prefix + length20;
148153
148553
  assertEnoughData5(data, pos, totLength);
148154
- const tok = new Token5(Type5.string, toStr5(data, pos + prefix, pos + totLength), totLength);
148554
+ const tok2 = new Token5(Type5.string, toStr5(data, pos + prefix, pos + totLength), totLength);
148155
148555
  if (options2.retainStringBytes === true) {
148156
- tok.byteValue = data.slice(pos + prefix, pos + totLength);
148556
+ tok2.byteValue = data.slice(pos + prefix, pos + totLength);
148157
148557
  }
148158
- return tok;
148558
+ return tok2;
148159
148559
  }
148160
148560
  function decodeStringCompact5(data, pos, minor, options2) {
148161
148561
  return toToken18(data, pos, 1, minor, options2);
@@ -150573,14 +150973,14 @@ ${error.stack}` : head;
150573
150973
  return out;
150574
150974
  }
150575
150975
  }
150576
- function heliaEnabled(storage2 = defaultStorage2()) {
150976
+ function heliaEnabled(storage2 = defaultStorage3()) {
150577
150977
  try {
150578
150978
  return storage2.getItem(HELIA_ENABLED_KEY) === "1";
150579
150979
  } catch {
150580
150980
  return false;
150581
150981
  }
150582
150982
  }
150583
- function setHeliaEnabled(enabled, storage2 = defaultStorage2()) {
150983
+ function setHeliaEnabled(enabled, storage2 = defaultStorage3()) {
150584
150984
  try {
150585
150985
  storage2.setItem(HELIA_ENABLED_KEY, enabled ? "1" : "0");
150586
150986
  return { ok: true, enabled: !!enabled };
@@ -150926,8 +151326,8 @@ ${error.stack}` : head;
150926
151326
  N3: 40,
150927
151327
  N4: 10
150928
151328
  };
150929
- exports.isValid = function isValid2(mask) {
150930
- return mask != null && mask !== "" && !isNaN(mask) && mask >= 0 && mask <= 7;
151329
+ exports.isValid = function isValid2(mask2) {
151330
+ return mask2 != null && mask2 !== "" && !isNaN(mask2) && mask2 >= 0 && mask2 <= 7;
150931
151331
  };
150932
151332
  exports.from = function from6(value2) {
150933
151333
  return exports.isValid(value2) ? parseInt(value2, 10) : void 0;
@@ -151731,8 +152131,8 @@ ${error.stack}` : head;
151731
152131
  var G15 = 1 << 10 | 1 << 8 | 1 << 5 | 1 << 4 | 1 << 2 | 1 << 1 | 1 << 0;
151732
152132
  var G15_MASK = 1 << 14 | 1 << 12 | 1 << 10 | 1 << 4 | 1 << 1;
151733
152133
  var G15_BCH = Utils.getBCHDigit(G15);
151734
- exports.getEncodedBits = function getEncodedBits(errorCorrectionLevel, mask) {
151735
- const data = errorCorrectionLevel.bit << 3 | mask;
152134
+ exports.getEncodedBits = function getEncodedBits(errorCorrectionLevel, mask2) {
152135
+ const data = errorCorrectionLevel.bit << 3 | mask2;
151736
152136
  let d2 = data << 10;
151737
152137
  while (Utils.getBCHDigit(d2) - G15_BCH >= 0) {
151738
152138
  d2 ^= G15 << Utils.getBCHDigit(d2) - G15_BCH;
@@ -152459,16 +152859,16 @@ ${error.stack}` : head;
152459
152859
  }
152460
152860
  let errorCorrectionLevel = ECLevel.M;
152461
152861
  let version4;
152462
- let mask;
152862
+ let mask2;
152463
152863
  if (typeof options2 !== "undefined") {
152464
152864
  errorCorrectionLevel = ECLevel.from(options2.errorCorrectionLevel, ECLevel.M);
152465
152865
  version4 = Version.from(options2.version);
152466
- mask = MaskPattern.from(options2.maskPattern);
152866
+ mask2 = MaskPattern.from(options2.maskPattern);
152467
152867
  if (options2.toSJISFunc) {
152468
152868
  Utils.setToSJISFunction(options2.toSJISFunc);
152469
152869
  }
152470
152870
  }
152471
- return createSymbol(data, version4, errorCorrectionLevel, mask);
152871
+ return createSymbol(data, version4, errorCorrectionLevel, mask2);
152472
152872
  };
152473
152873
  }
152474
152874
  });
@@ -153787,8 +154187,8 @@ ${error.stack}` : head;
153787
154187
  var bitsLeft = 8 - this.bitOffset;
153788
154188
  var toRead = numBits < bitsLeft ? numBits : bitsLeft;
153789
154189
  var bitsToNotRead = bitsLeft - toRead;
153790
- var mask = 255 >> 8 - toRead << bitsToNotRead;
153791
- result = (this.bytes[this.byteOffset] & mask) >> bitsToNotRead;
154190
+ var mask2 = 255 >> 8 - toRead << bitsToNotRead;
154191
+ result = (this.bytes[this.byteOffset] & mask2) >> bitsToNotRead;
153792
154192
  numBits -= toRead;
153793
154193
  this.bitOffset += toRead;
153794
154194
  if (this.bitOffset === 8) {
@@ -153804,8 +154204,8 @@ ${error.stack}` : head;
153804
154204
  }
153805
154205
  if (numBits > 0) {
153806
154206
  var bitsToNotRead = 8 - numBits;
153807
- var mask = 255 >> bitsToNotRead << bitsToNotRead;
153808
- result = result << numBits | (this.bytes[this.byteOffset] & mask) >> bitsToNotRead;
154207
+ var mask2 = 255 >> bitsToNotRead << bitsToNotRead;
154208
+ result = result << numBits | (this.bytes[this.byteOffset] & mask2) >> bitsToNotRead;
153809
154209
  this.bitOffset += numBits;
153810
154210
  }
153811
154211
  }
@@ -162829,7 +163229,7 @@ ${error.stack}` : head;
162829
163229
  },
162830
163230
  {
162831
163231
  title: "\u4E94\u3001\u7CFB\u7EDF\u6743\u9650",
162832
- body: "\u84DD\u7259\u626B\u63CF\u4E0E\u8FDE\u63A5\uFF1A\u53D1\u73B0\u5E76\u8FDE\u63A5\u9644\u8FD1\u8BBE\u5907\u4E0E\u597D\u53CB\uFF08\u5DF2\u58F0\u660E neverForLocation\uFF0C\u4E0D\u7528\u4E8E\u63A8\u65AD\u4F4D\u7F6E\uFF09\u3002\u4F4D\u7F6E\u6743\u9650\uFF1A\u4EC5 Android 11 \u53CA\u4EE5\u4E0B\u7CFB\u7EDF\u8981\u6C42\u84DD\u7259\u626B\u63CF\u9700\u8981\u5B83\uFF08\u5DF2\u9650\u5236 maxSdkVersion=30\uFF0CAndroid 12+ \u4E0D\u518D\u7533\u8BF7\uFF09\u3002\u7F51\u7EDC\uFF1AP2P \u8FDE\u63A5\u4E0E\u4E0B\u8F7D\u3002\u76F8\u673A\uFF1A\u8C03\u7528\u7CFB\u7EDF\u76F8\u673A\u5E94\u7528\u5B8C\u6210\u62CD\u6444\uFF0C\u672C\u5E94\u7528\u4E0D\u7533\u8BF7\u76F8\u673A\u6743\u9650\u3002\u65E0\u969C\u788D\u670D\u52A1\u4E0E Shizuku\uFF1A\u4EC5\u5B98\u7F51\u76F4\u88C5\u7248\u672C\u5305\u542B\uFF0C\u7528\u4E8E\u4F60\u663E\u5F0F\u5F00\u542F\u7684\u300C\u667A\u80FD\u4F53\u63A7\u5236\u300D\uFF0C\u53EF\u968F\u65F6\u5173\u95ED\uFF1B\u5E94\u7528\u5546\u5E97\u7248\u672C\u4E0D\u5305\u542B\u3002"
163232
+ body: "\u84DD\u7259\u626B\u63CF\u4E0E\u8FDE\u63A5\uFF1A\u53D1\u73B0\u5E76\u8FDE\u63A5\u9644\u8FD1\u8BBE\u5907\u4E0E\u597D\u53CB\uFF08\u5DF2\u58F0\u660E neverForLocation\uFF0C\u4E0D\u7528\u4E8E\u63A8\u65AD\u4F4D\u7F6E\uFF09\u3002\u4F4D\u7F6E\u6743\u9650\uFF1A\u4EC5 Android 11 \u53CA\u4EE5\u4E0B\u7CFB\u7EDF\u8981\u6C42\u84DD\u7259\u626B\u63CF\u9700\u8981\u5B83\uFF08\u5DF2\u9650\u5236 maxSdkVersion=30\uFF0CAndroid 12+ \u4E0D\u518D\u7533\u8BF7\uFF09\u3002\u7F51\u7EDC\uFF1AP2P \u8FDE\u63A5\u4E0E\u4E0B\u8F7D\u3002\u76F8\u673A\uFF1A\u8C03\u7528\u7CFB\u7EDF\u76F8\u673A\u5E94\u7528\u5B8C\u6210\u62CD\u6444\uFF0C\u672C\u5E94\u7528\u4E0D\u7533\u8BF7\u76F8\u673A\u6743\u9650\u3002\u5B8C\u5168\u8BBF\u95EE\u6743\u9650\uFF08\u8BA9\u667A\u80FD\u4F53\u5728\u8FD9\u53F0\u624B\u673A\u4E0A\u70B9\u6309\u3001\u6ED1\u52A8\u5C4F\u5E55\u6216\u8C03\u7528\u7CFB\u7EDF\u80FD\u529B\uFF09\u4E0E Shizuku\uFF1A\u4EC5\u5B98\u7F51\u76F4\u88C5\u7248\u672C\u5305\u542B\uFF0C\u9ED8\u8BA4\u5F00\u542F\uFF08\u9996\u6B21\u4F7F\u7528\u4F1A\u76F4\u63A5\u5E26\u4F60\u53BB\u7CFB\u7EDF\u5F00\u5173\u9875\u786E\u8BA4\u4E00\u6B21\uFF0C\u4E4B\u540E\u4E00\u76F4\u6709\u6548\uFF09\u3001\u968F\u65F6\u53EF\u4EE5\u5173\u95ED\uFF1B\u5E94\u7528\u5546\u5E97\u4E0B\u8F7D\u7684\u7248\u672C\u4E0D\u542B\u8FD9\u4E24\u9879\uFF0C\u4E5F\u6CA1\u6709\u8FD9\u4E2A\u80FD\u529B\u3002"
162833
163233
  },
162834
163234
  {
162835
163235
  title: "\u516D\u3001\u4F60\u7684\u6743\u5229\u4E0E\u6CE8\u9500",
@@ -162923,6 +163323,587 @@ ${error.stack}` : head;
162923
163323
  return result;
162924
163324
  }
162925
163325
 
163326
+ // src/web/mobile-core.ts
163327
+ init_mobile_contacts();
163328
+
163329
+ // src/agents/mobile-task-actions.ts
163330
+ var MOBILE_TASK_ACTION_KINDS = [
163331
+ "group_join",
163332
+ // 入群 (加入一个 OrbitDB 群 store)
163333
+ "group_leave",
163334
+ // 退群
163335
+ "group_create",
163336
+ // 建群 (会自动入群)
163337
+ "announce_publish",
163338
+ // 发布任务公告 (落盘公告 + 向注册表公告 + 记脉冲)
163339
+ "announce_to_group",
163340
+ // 把板上的公告推进群里 (CLI: bolloon task announce)
163341
+ "trail_post"
163342
+ // 过程留痕: 接单/交付/初筛/终审 (CLI: bolloon task post)
163343
+ ];
163344
+ var TASK_ACTION_TTL_MS = 10 * 6e4;
163345
+ var TASK_ACTION_DEFAULT_TTL_MS = 5 * 6e4;
163346
+ var TASK_ACTION_CLOCK_SKEW_MS = 2 * 6e4;
163347
+ function tok(v) {
163348
+ if (v === null || v === void 0) return "-";
163349
+ const s2 = String(v);
163350
+ if (!s2) return "-";
163351
+ return s2.replace(/\r?\n/g, "\\n");
163352
+ }
163353
+ function taskActionContentText(req) {
163354
+ const kind = String(req?.kind ?? "");
163355
+ const base6 = [
163356
+ `kind=${tok(kind)}`,
163357
+ `group=${tok(req?.groupRef)}`,
163358
+ `ann=${tok(req?.announcementId)}`
163359
+ ];
163360
+ if (kind === "announce_publish") {
163361
+ base6.push(`cap=${tok(req?.capability)}`);
163362
+ base6.push(`budget=${tok(req?.budgetHuman)}${req?.currency ? `@${tok(req.currency)}` : ""}`);
163363
+ base6.push(`deadline=${tok(req?.deadline)}`);
163364
+ base6.push(`instruction=${tok(req?.instruction)}`);
163365
+ } else if (kind === "announce_to_group") {
163366
+ base6.push(`criteria=${tok(req?.criteria)}`);
163367
+ } else if (kind === "trail_post") {
163368
+ base6.push(`trail=${tok(req?.trailKind)}`);
163369
+ base6.push(`round=${tok(req?.round)}`);
163370
+ base6.push(`price=${tok(req?.price)}`);
163371
+ base6.push(`hash=${tok(req?.hash)}`);
163372
+ base6.push(`bytes=${tok(req?.bytes)}`);
163373
+ base6.push(`checks=${tok(req?.checks)}`);
163374
+ base6.push(`verdict=${tok(req?.verdict)}`);
163375
+ }
163376
+ return base6.join("\n");
163377
+ }
163378
+ function canonicalTaskActionPayload(a) {
163379
+ return JSON.stringify({
163380
+ actionId: a.actionId,
163381
+ kind: a.kind,
163382
+ deviceId: a.deviceId,
163383
+ ownerDid: a.ownerDid,
163384
+ targetRef: a.targetRef || "",
163385
+ contentDigest: a.contentDigest,
163386
+ createdAt: a.createdAt,
163387
+ expiresAt: a.expiresAt,
163388
+ grantedBy: a.grantedBy,
163389
+ via: a.via
163390
+ });
163391
+ }
163392
+ function isIso(s2) {
163393
+ return typeof s2 === "string" && s2.length >= 20 && Number.isFinite(Date.parse(s2));
163394
+ }
163395
+ function checkTaskActionFreshness(a, now) {
163396
+ if (!isIso(a?.createdAt) || !isIso(a?.expiresAt)) return { ok: false, reason: "bad_time" };
163397
+ const created = Date.parse(a.createdAt);
163398
+ const expires = Date.parse(a.expiresAt);
163399
+ if (expires - created > TASK_ACTION_TTL_MS) return { ok: false, reason: "ttl_too_long" };
163400
+ if (expires < created) return { ok: false, reason: "bad_time" };
163401
+ if (now > expires) return { ok: false, reason: "expired" };
163402
+ if (now < created - TASK_ACTION_CLOCK_SKEW_MS) return { ok: false, reason: "not_yet_valid" };
163403
+ return { ok: true };
163404
+ }
163405
+
163406
+ // src/agents/task-public-text.ts
163407
+ var PRIVACY_RULES = [
163408
+ { rule: "wallet-address", why: "\u4EE5\u592A\u574A/EVM \u94B1\u5305\u5730\u5740", re: /(?<![0-9a-fA-FxX])0x[0-9a-fA-F]{40}(?![0-9a-fA-F])/ },
163409
+ { rule: "private-key-hex", why: "32 \u5B57\u8282\u79C1\u94A5\u5F62\u6001 (0x + 64 hex)", re: /(?<![0-9a-fA-FxX])0x[0-9a-fA-F]{64}(?![0-9a-fA-F])/ },
163410
+ { rule: "hex-0x-blob", why: "0x \u5F00\u5934\u7684\u5341\u516D\u8FDB\u5236\u5757 (\u7B7E\u540D/\u54C8\u5E0C/\u5BC6\u94A5\u90FD\u957F\u8FD9\u6837, \u7FA4\u91CC\u4E00\u5F8B\u4E0D\u653E\u539F\u6587)", re: /(?<![0-9a-fA-FxX])0x[0-9a-fA-F]{8,}(?![0-9a-fA-F])/ },
163411
+ { rule: "did", why: "\u53BB\u4E2D\u5FC3\u5316\u8EAB\u4EFD DID", re: /did:[a-z0-9]+:[A-Za-z0-9._:%-]{3,}/i },
163412
+ { rule: "peer-id", why: "libp2p peerId (12D3Koo\u2026/Qm\u2026)", re: /12D3Koo[A-Za-z0-9]{8,}|Qm[1-9A-HJ-NP-Za-km-z]{30,}/ },
163413
+ { rule: "multiaddr", why: "libp2p multiaddr \u6216 store \u5730\u5740 (/ip4 /tcp /p2p /orbitdb \u2026)", re: /\/(ip4|ip6|dns|dns4|dns6|tcp|udp|ws|wss|quic|p2p|p2p-circuit|ipfs|orbitdb)(?![A-Za-z0-9])/i },
163414
+ { rule: "orbitdb-link", why: "OrbitDB \u94FE\u63A5 (\u7FA4\u9080\u8BF7\u94FE\u63A5\u672C\u8EAB\u4E5F\u4E0D\u8FDB\u7FA4\u6D88\u606F)", re: /orbitdb:\/\//i },
163415
+ { rule: "ipv4", why: "IPv4 \u5730\u5740", re: /(?<!\d)\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}(?!\d)/ },
163416
+ { rule: "ipv6", why: "IPv6 \u5730\u5740 (\u4E0D\u542B ISO \u65F6\u95F4\u6233)", re: /(?<![0-9A-Za-z])(?:[0-9a-fA-F]{1,4})?::(?:[0-9a-fA-F]{1,4}:){0,6}[0-9a-fA-F]{1,4}(?![0-9A-Za-z])|(?<![0-9A-Za-z:])(?:[0-9a-fA-F]{1,4}:){3,}[0-9a-fA-F]{1,4}(?![0-9A-Za-z])/ },
163417
+ { rule: "pem", why: "PEM \u6750\u6599 (\u79C1\u94A5/\u8BC1\u4E66)", re: /-----BEGIN [A-Z ]*(PRIVATE KEY|CERTIFICATE)/ },
163418
+ { rule: "secret-words", why: "\u79C1\u94A5/\u52A9\u8BB0\u8BCD/\u5BC6\u94A5\u5B57\u6837 (\u6B63\u6587\u91CC\u63D0\u5230\u5373\u505C, \u4EBA\u4E0D\u8BE5\u628A\u5BC6\u94A5\u5199\u8FDB\u7FA4)", re: /(private\s*key|seed\s*phrase|mnemonic|私钥|助记词|密钥材料)/i },
163419
+ { rule: "url", why: "http(s) \u7AEF\u70B9 (\u7AEF\u70B9\u4F1A\u5E26 host/IP \u4E0E\u7528\u9014\u6307\u7EB9)", re: /https?:\/\/\S+/i },
163420
+ { rule: "email", why: "\u90AE\u7BB1\u5730\u5740", re: /[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\.[A-Za-z]{2,}/ }
163421
+ ];
163422
+ function mask(s2) {
163423
+ const t = String(s2 || "");
163424
+ return t.length <= 4 ? "****" : `${t.slice(0, 4)}\u2026`;
163425
+ }
163426
+ function scanPublicText(text) {
163427
+ const t = String(text ?? "");
163428
+ const out = [];
163429
+ const seen = /* @__PURE__ */ new Set();
163430
+ for (const r of PRIVACY_RULES) {
163431
+ const m2 = r.re.exec(t);
163432
+ if (!m2) continue;
163433
+ if (seen.has(r.rule)) continue;
163434
+ seen.add(r.rule);
163435
+ out.push({ rule: r.rule, why: r.why, masked: mask(String(m2[0])), chars: String(m2[0]).length });
163436
+ }
163437
+ return out;
163438
+ }
163439
+ function requirePublicText(text) {
163440
+ const v = scanPublicText(text);
163441
+ return v.length === 0 ? { ok: true } : { ok: false, violations: v };
163442
+ }
163443
+ var NODE_IDENTITY_RULES = PRIVACY_RULES.filter((r) => r.rule !== "orbitdb-link").map((r) => r.rule === "multiaddr" ? { ...r, re: /\/(ip4|ip6|dns|dns4|dns6|tcp|udp|ws|wss|quic|p2p|p2p-circuit|ipfs)(?![A-Za-z0-9])/i } : r);
163444
+
163445
+ // src/agents/mobile-task-views.ts
163446
+ function shortId(id, n = 12) {
163447
+ const s2 = String(id ?? "").trim();
163448
+ if (!s2) return "";
163449
+ return s2.length <= n ? s2 : `${s2.slice(0, n)}\u2026`;
163450
+ }
163451
+ function isProtocolId(s2) {
163452
+ const v = String(s2 ?? "").trim();
163453
+ return /^ann-[0-9a-f]{8,}$/i.test(v) || /^act-[a-z0-9-]{6,}$/i.test(v) || /^zdpu[0-9a-zA-Z]{8,}$/.test(v) || /^\/orbitdb\//.test(v);
163454
+ }
163455
+ function formatRelative(ms2, lang) {
163456
+ if (ms2 === null || !Number.isFinite(ms2)) return lang === "zh" ? "\u2014" : "\u2014";
163457
+ const past = ms2 >= 0;
163458
+ const abs = Math.abs(ms2);
163459
+ const min = Math.floor(abs / 6e4);
163460
+ const hr = Math.floor(abs / 36e5);
163461
+ const day = Math.floor(abs / 864e5);
163462
+ const unit = day >= 1 ? lang === "zh" ? `${day} \u5929` : `${day} d` : hr >= 1 ? lang === "zh" ? `${hr} \u5C0F\u65F6` : `${hr} h` : min >= 1 ? lang === "zh" ? `${min} \u5206\u949F` : `${min} min` : lang === "zh" ? "\u4E0D\u5230 1 \u5206\u949F" : "under a minute";
163463
+ if (lang === "zh") return past ? `${unit}\u524D` : `${unit}\u540E`;
163464
+ return past ? `${unit} ago` : `in ${unit}`;
163465
+ }
163466
+ var STATUS_LABELS = {
163467
+ open: { zh: "\u53EF\u63A5\u5355", en: "Open for claims" },
163468
+ claimed: { zh: "\u5DF2\u88AB\u63A5\u5355", en: "Claimed" },
163469
+ cancelled: { zh: "\u5DF2\u53D6\u6D88", en: "Cancelled" },
163470
+ unknown: { zh: "\u72B6\u6001\u672A\u77E5", en: "Unknown status" }
163471
+ };
163472
+ function budgetLabelOf(b) {
163473
+ if (!b || typeof b !== "object") return "";
163474
+ const amt = String(b.maxAmount ?? "").trim();
163475
+ if (!amt) return "";
163476
+ return `${amt} ${String(b.currency || "").toUpperCase()}${b.network ? ` \xB7 ${String(b.network)}` : ""}`;
163477
+ }
163478
+ function boardItemOf(e, now) {
163479
+ const dl = Number.isFinite(Number(e?.deadline)) ? Number(e.deadline) : null;
163480
+ const ca = Number.isFinite(Number(e?.createdAt)) ? Number(e.createdAt) : null;
163481
+ const status = String(e?.status || "unknown");
163482
+ return {
163483
+ idShort: shortId(e?.announcementId),
163484
+ ref: String(e?.announcementId || ""),
163485
+ capability: String(e?.capability || ""),
163486
+ status,
163487
+ statusLabel: STATUS_LABELS[status] || STATUS_LABELS.unknown,
163488
+ budgetLabel: budgetLabelOf(e?.budget),
163489
+ deadlineInMs: dl === null ? null : dl - now,
163490
+ createdAtMs: ca,
163491
+ claimCount: Number.isFinite(Number(e?.claimCount)) ? Number(e.claimCount) : 0,
163492
+ preview: e?.instructionPreview ? String(e.instructionPreview).slice(0, 120) : null,
163493
+ remote: !!e?.remote,
163494
+ claimable: !!e?.claimable,
163495
+ signatureVerified: e?.signatureVerified === true ? true : e?.signatureVerified === false ? false : null
163496
+ };
163497
+ }
163498
+ function buildBoardView(view, now) {
163499
+ const items = (Array.isArray(view?.entries) ? view.entries : []).map((e) => boardItemOf(e, now));
163500
+ return {
163501
+ items,
163502
+ localCount: Number(view?.localCount) || 0,
163503
+ remoteCount: Number(view?.remoteCount) || 0,
163504
+ registryReady: view?.registryReady === true,
163505
+ registryError: view?.registryError ? String(view.registryError).slice(0, 160) : null,
163506
+ notes: Array.isArray(view?.notes) ? view.notes.map((n) => String(n)) : [],
163507
+ openCount: items.filter((i) => i.claimable).length
163508
+ };
163509
+ }
163510
+ var TRAIL_KIND_LABELS = {
163511
+ announce: { zh: "\u516C\u544A", en: "Announce" },
163512
+ claim: { zh: "\u63A5\u5355\u58F0\u660E", en: "Claim" },
163513
+ deliver: { zh: "\u4EA4\u4ED8", en: "Delivery" },
163514
+ screen: { zh: "\u521D\u7B5B\u7ED3\u679C", en: "Screening" },
163515
+ final: { zh: "\u7EC8\u5BA1\u7ED3\u8BBA", en: "Final verdict" }
163516
+ };
163517
+ var INCONSISTENCY_LABELS = {
163518
+ "final-accept-without-delivery": { zh: "\u8BF4\u901A\u8FC7\u4E86, \u4F46\u7FA4\u91CC\u6CA1\u6709\u4EA4\u4ED8\u75D5\u8FF9", en: "Accepted, but no delivery trace in the group" },
163519
+ "screen-without-delivery": { zh: "\u6709\u521D\u7B5B\u7ED3\u679C, \u4F46\u6CA1\u6709\u4EA4\u4ED8\u75D5\u8FF9", en: "Screening exists without a delivery trace" },
163520
+ "claim-without-announce": { zh: "\u6709\u4EBA\u63A5\u5355, \u4F46\u7FA4\u91CC\u6CA1\u6709\u516C\u544A\u75D5\u8FF9", en: "Claim without an announcement trace" },
163521
+ "deliver-without-claim": { zh: "\u6709\u4EA4\u4ED8, \u4F46\u6CA1\u4EBA\u63A5\u8FC7\u5355", en: "Delivery without a claim" },
163522
+ "both-accept-and-reject": { zh: "\u540C\u65F6\u51FA\u73B0\u901A\u8FC7\u548C\u62D2\u7EDD", en: "Both accepted and rejected appear" },
163523
+ "group-message-hit-privacy-rule": { zh: "\u7FA4\u91CC\u6709\u4EBA\u53D1\u4E86\u5E26\u6807\u8BC6\u7B26\u7684\u6D88\u606F (\u5DF2\u906E\u853D, \u4E0D\u5F53\u4E8B\u5B9E\u91C7\u7528)", en: "A group message hit a privacy rule (masked, not used as fact)" }
163524
+ };
163525
+ function buildTrailView(summary) {
163526
+ const entries = (Array.isArray(summary?.entries) ? summary.entries : []).map((e) => {
163527
+ const facts = [];
163528
+ for (const [k, v] of Object.entries(e?.fields || {})) {
163529
+ if (k === "kind") continue;
163530
+ const raw = String(v ?? "");
163531
+ const hit = scanPublicText(raw);
163532
+ if (hit.length) {
163533
+ facts.push({ k: String(k), v: `[\u5DF2\u906E\u853D:${hit[0].rule}]` });
163534
+ continue;
163535
+ }
163536
+ facts.push({ k: String(k), v: k === "id" || isProtocolId(raw) ? shortId(raw) : raw });
163537
+ }
163538
+ const kind = String(e?.kind || "");
163539
+ return {
163540
+ idShort: shortId(e?.announcementId),
163541
+ kind,
163542
+ kindLabel: TRAIL_KIND_LABELS[kind] || { zh: kind, en: kind },
163543
+ sender: String(e?.sender || "unknown"),
163544
+ atMs: Number.isFinite(Number(e?.at)) ? Number(e.at) : 0,
163545
+ facts
163546
+ };
163547
+ });
163548
+ const inc = (Array.isArray(summary?.inconsistencies) ? summary.inconsistencies : []).map((c) => ({
163549
+ code: String(c),
163550
+ label: INCONSISTENCY_LABELS[String(c)] || { zh: String(c), en: String(c) }
163551
+ }));
163552
+ return {
163553
+ count: Number(summary?.count) || entries.length,
163554
+ byKind: summary?.byKind || {},
163555
+ entries,
163556
+ announcementIdsShort: (Array.isArray(summary?.announcements) ? summary.announcements : []).map((a) => shortId(a)),
163557
+ flags: summary?.flags || {},
163558
+ inconsistencies: inc,
163559
+ redactedCount: Array.isArray(summary?.redacted) ? summary.redacted.length : 0,
163560
+ ignoredMessages: Number(summary?.ignoredMessages) || 0,
163561
+ privacyHits: inc.some((x) => x.code === "group-message-hit-privacy-rule") || Array.isArray(summary?.redacted) && summary.redacted.length > 0
163562
+ };
163563
+ }
163564
+ function buildGroupsView(groups) {
163565
+ return (Array.isArray(groups) ? groups : []).map((g) => ({
163566
+ idShort: shortId(g?.id),
163567
+ name: String(g?.name || ""),
163568
+ joinedAt: String(g?.createdAt || "")
163569
+ }));
163570
+ }
163571
+ function describeTaskActionForConfirm(kind, req) {
163572
+ const lines = [];
163573
+ const push = (k, kEn, v) => {
163574
+ const s2 = String(v ?? "").trim();
163575
+ if (s2 && s2 !== "-") lines.push({ k, kEn, v: s2 });
163576
+ };
163577
+ push("\u7FA4", "group", req?.groupRef ? shortId(req.groupRef, 24) : "");
163578
+ push("\u516C\u544A\u53F7", "announcement", req?.announcementId ? shortId(req.announcementId) : "");
163579
+ push("\u80FD\u529B", "capability", req?.capability);
163580
+ push("\u9884\u7B97", "budget", req?.budgetHuman ? `${req.budgetHuman} ${String(req?.currency || "").toUpperCase()}` : "");
163581
+ push("\u4EFB\u52A1\u6B63\u6587", "instruction", req?.instruction);
163582
+ push("\u622A\u6B62", "deadline", req?.deadline);
163583
+ push("\u9A8C\u6536\u5224\u636E", "criteria", req?.criteria);
163584
+ push("\u671F\u53F7", "round", req?.round);
163585
+ push("\u75D5\u8FF9\u7C7B\u578B", "trail kind", req?.trailKind ? TRAIL_KIND_LABELS[String(req.trailKind)]?.zh || String(req.trailKind) : "");
163586
+ push("\u58F0\u660E\u4EF7\u683C", "declared price", req?.price);
163587
+ push("\u4EA4\u4ED8\u54C8\u5E0C", "delivery hash", req?.hash);
163588
+ push("\u5B57\u8282\u6570", "bytes", req?.bytes);
163589
+ push("\u9010\u6761\u521D\u7B5B", "per-item screen", req?.checks);
163590
+ push("\u7EC8\u5BA1\u7ED3\u8BBA", "final verdict", req?.verdict);
163591
+ const titles = {
163592
+ group_join: { zh: "\u52A0\u5165\u8FD9\u4E2A\u7FA4", en: "Join this group" },
163593
+ group_leave: { zh: "\u9000\u51FA\u8FD9\u4E2A\u7FA4", en: "Leave this group" },
163594
+ group_create: { zh: "\u5EFA\u4E00\u4E2A\u65B0\u7FA4", en: "Create a new group" },
163595
+ announce_publish: { zh: "\u53D1\u5E03\u4EFB\u52A1\u516C\u544A", en: "Publish a task announcement" },
163596
+ announce_to_group: { zh: "\u628A\u8FD9\u671F\u516C\u544A\u53D1\u8FDB\u7FA4", en: "Post this announcement into the group" },
163597
+ trail_post: { zh: "\u5F80\u7FA4\u91CC\u7559\u4E00\u6761\u8FC7\u7A0B\u75D5\u8FF9", en: "Post a process trail entry into the group" }
163598
+ };
163599
+ const t = titles[String(kind)] || { zh: "\u6267\u884C\u8FD9\u4E2A\u52A8\u4F5C", en: "Run this action" };
163600
+ return { titleZh: t.zh, titleEn: t.en, lines };
163601
+ }
163602
+
163603
+ // src/agents/goal-flywheel/types.ts
163604
+ var MUST_NOT_EXPOSE_FIELDS = [
163605
+ "lease",
163606
+ "reducer",
163607
+ "internal_status",
163608
+ "retry_counter",
163609
+ "worker_owner"
163610
+ ];
163611
+
163612
+ // src/agents/goal-flywheel/work-monitor.ts
163613
+ var NO_PROGRESS_FALLBACK_MS = 30 * 60 * 1e3;
163614
+ var DEFAULT_REPORT_GRACE_MS = 60 * 1e3;
163615
+ var DEFAULT_ESCALATION_MS = 10 * 60 * 1e3;
163616
+
163617
+ // src/agents/mobile-flywheel-view.ts
163618
+ function findInternalFieldLeaks(text) {
163619
+ const t = String(text ?? "");
163620
+ return MUST_NOT_EXPOSE_FIELDS.filter((f) => t.includes(f));
163621
+ }
163622
+
163623
+ // src/web/mobile-tasks.ts
163624
+ init_mobile_contacts();
163625
+ var K_TASKS_HINT = "bolloon.mobile.tasks.hint.v1";
163626
+ function defaultStorage2() {
163627
+ try {
163628
+ if (typeof localStorage !== "undefined") return localStorage;
163629
+ } catch {
163630
+ }
163631
+ const mem2 = /* @__PURE__ */ new Map();
163632
+ return { getItem: (k) => mem2.has(k) ? mem2.get(k) : null, setItem: (k, v) => {
163633
+ mem2.set(k, v);
163634
+ }, removeItem: (k) => {
163635
+ mem2.delete(k);
163636
+ } };
163637
+ }
163638
+ async function baseOf(deps) {
163639
+ if (deps.base && String(deps.base).trim()) return String(deps.base).replace(/\/+$/, "");
163640
+ try {
163641
+ if (typeof localStorage !== "undefined") {
163642
+ const v = localStorage.getItem("bolloon_desktop_base_url");
163643
+ if (v) return String(v).replace(/\/+$/, "");
163644
+ }
163645
+ } catch {
163646
+ }
163647
+ return "";
163648
+ }
163649
+ function fetchOf(deps) {
163650
+ return deps.fetchImpl || globalThis.fetch;
163651
+ }
163652
+ async function getJson(base6, path, f) {
163653
+ const res = await f(`${base6}${path}`);
163654
+ let json = null;
163655
+ try {
163656
+ json = await res.json();
163657
+ } catch {
163658
+ }
163659
+ return { status: res.status, json };
163660
+ }
163661
+ async function postJson(base6, path, body, f) {
163662
+ const res = await f(`${base6}${path}`, {
163663
+ method: "POST",
163664
+ headers: { "Content-Type": "application/json" },
163665
+ body: JSON.stringify(body ?? {})
163666
+ });
163667
+ let json = null;
163668
+ try {
163669
+ json = await res.json();
163670
+ } catch {
163671
+ }
163672
+ return { status: res.status, json };
163673
+ }
163674
+ var OFFLINE_NOTE = "\u5730\u5740\u5728 \u6211 \u2192 \u8BBE\u7F6E \u2192 \u7535\u8111\u7AEF\u5730\u5740 \u91CC\u586B; \u624B\u673A\u4E0D\u66FF\u684C\u9762\u8BB0\u8D26";
163675
+ function mapFail(r, what) {
163676
+ const code10 = r.json?.code ? String(r.json.code) : r.status ? `desktop_http_${r.status}` : "desktop_unreachable";
163677
+ return { ok: false, code: code10, error: `${what} \u5931\u8D25: ${r.json?.error || r.json?.message || code10}`, note: OFFLINE_NOTE };
163678
+ }
163679
+ function emptyTaskActionRequest(kind) {
163680
+ return {
163681
+ kind,
163682
+ groupRef: null,
163683
+ announcementId: null,
163684
+ capability: null,
163685
+ instruction: null,
163686
+ budgetHuman: null,
163687
+ currency: null,
163688
+ deadline: null,
163689
+ criteria: null,
163690
+ round: null,
163691
+ price: null,
163692
+ hash: null,
163693
+ bytes: null,
163694
+ checks: null,
163695
+ verdict: null,
163696
+ trailKind: null
163697
+ };
163698
+ }
163699
+ async function signTaskAction(req, deps = {}) {
163700
+ const storage2 = deps.storage || defaultStorage2();
163701
+ const c = deps.cryptoObj || globalThis.crypto;
163702
+ if (!ed25519Available(c)) {
163703
+ return { ok: false, code: "device_signing_unavailable", error: "\u672C\u673A WebView \u4E0D\u652F\u6301 Ed25519 \u8BBE\u5907\u7B7E\u540D \u2014\u2014 \u8BF7\u5728\u684C\u9762\u7AEF\u6267\u884C\u8FD9\u4E2A\u52A8\u4F5C (\u6216\u5347\u7EA7\u7CFB\u7EDF WebView)" };
163704
+ }
163705
+ if (!MOBILE_TASK_ACTION_KINDS.includes(String(req?.kind))) {
163706
+ return { ok: false, code: "unknown_kind", error: `\u672A\u77E5\u52A8\u4F5C: ${String(req?.kind || "")}` };
163707
+ }
163708
+ const text = taskActionContentText(req);
163709
+ if (req.kind === "trail_post" || req.kind === "announce_publish" || req.kind === "announce_to_group") {
163710
+ for (const fieldText of [req.round, req.price, req.criteria, req.checks, req.verdict, req.capability, req.hash]) {
163711
+ if (!fieldText) continue;
163712
+ const gate = requirePublicText(String(fieldText));
163713
+ if (!gate.ok) {
163714
+ return { ok: false, code: "privacy_denied", error: `\u672C\u5730\u9690\u79C1\u95F8\u62E6\u4E0B: ${gate.violations.map((v) => v.rule).join(", ")} (\u7FA4\u91CC/\u516C\u544A\u91CC\u4E0D\u653E\u6807\u8BC6\u7B26)`, violations: gate.violations };
163715
+ }
163716
+ }
163717
+ }
163718
+ const now = deps.now ? deps.now() : Date.now();
163719
+ const ttl = Math.min(Number(deps.ttlMs) || TASK_ACTION_DEFAULT_TTL_MS, TASK_ACTION_DEFAULT_TTL_MS);
163720
+ let contentDigest;
163721
+ try {
163722
+ contentDigest = await sha256HexOf(text, c);
163723
+ } catch (e) {
163724
+ return { ok: false, code: "device_signing_unavailable", error: String(e?.message || e) };
163725
+ }
163726
+ const action = {
163727
+ actionId: `act-${now.toString(36)}-${Math.random().toString(36).slice(2, 8)}`,
163728
+ kind: req.kind,
163729
+ deviceId: "",
163730
+ // 由 signPayloadOnDevice 填 (它知道设备 id)
163731
+ ownerDid: String(deps.ownerDid || "").trim(),
163732
+ targetRef: String(req.groupRef || req.announcementId || ""),
163733
+ contentDigest,
163734
+ createdAt: new Date(now).toISOString(),
163735
+ expiresAt: new Date(now + ttl).toISOString(),
163736
+ grantedBy: deps.grantedBy || "leo",
163737
+ via: "mobile"
163738
+ };
163739
+ let signature;
163740
+ try {
163741
+ const { loadOrCreateDeviceKey: loadOrCreateDeviceKey2, signPayloadWithMaterial: signPayloadWithMaterial2 } = await Promise.resolve().then(() => (init_mobile_contacts(), mobile_contacts_exports));
163742
+ const material = await loadOrCreateDeviceKey2(storage2, c);
163743
+ action.deviceId = material.deviceId;
163744
+ signature = await signPayloadWithMaterial2(canonicalTaskActionPayload(action), material, c);
163745
+ if (signature.deviceId !== action.deviceId) {
163746
+ return { ok: false, code: "device_signing_unavailable", error: "\u8BBE\u5907\u5BC6\u94A5\u4E0D\u4E00\u81F4 (\u7B7E\u540D\u4E0E\u8F7D\u8377\u8BBE\u5907\u5BF9\u4E0D\u4E0A) \u2192 \u4E0D\u53D1\u9001" };
163747
+ }
163748
+ const fresh = checkTaskActionFreshness(action, now);
163749
+ if (!fresh.ok) return { ok: false, code: fresh.reason, error: `\u52A8\u4F5C\u65F6\u6548\u4E0D\u5408\u6CD5: ${fresh.reason}` };
163750
+ } catch (e) {
163751
+ return { ok: false, code: "device_signing_unavailable", error: String(e?.message || e).slice(0, 160) };
163752
+ }
163753
+ return {
163754
+ ok: true,
163755
+ data: { signed: { action, signature }, contentText: text, confirm: describeTaskActionForConfirm(req.kind, req) }
163756
+ };
163757
+ }
163758
+ async function executeTaskAction(req, deps = {}) {
163759
+ const storage2 = deps.storage || defaultStorage2();
163760
+ const base6 = await baseOf(deps);
163761
+ if (!base6) return { ok: false, code: "desktop_offline", error: "\u8FD8\u6CA1\u8BBE\u7F6E\u7535\u8111\u7AEF\u5730\u5740: \u9AD8\u98CE\u9669\u52A8\u4F5C\u5FC5\u987B\u7531\u684C\u9762\u6267\u884C (\u624B\u673A\u7B7E\u4E86\u540D\u4E5F\u8981\u9001\u5230\u684C\u9762)", note: OFFLINE_NOTE };
163762
+ const signed = await signTaskAction(req, { ...deps, storage: storage2 });
163763
+ if (!signed.ok || !signed.data) return { ok: false, code: signed.code, error: signed.error, violations: signed.violations };
163764
+ const f = fetchOf(deps);
163765
+ let r;
163766
+ try {
163767
+ r = await postJson(base6, "/api/mobile/tasks/execute", { request: req, ...signed.data.signed }, f);
163768
+ } catch (e) {
163769
+ return { ok: false, code: "desktop_offline", error: `\u684C\u9762\u4E0D\u53EF\u8FBE: ${String(e?.message || e).slice(0, 120)}`, note: OFFLINE_NOTE };
163770
+ }
163771
+ if (r.status !== 200 || !r.json?.ok) return mapFail(r, "\u6267\u884C");
163772
+ return { ok: true, data: r.json, note: "\u684C\u9762\u5DF2\u9A8C\u7B7E\u5E76\u6267\u884C (\u540C\u4E00\u5957\u5B58\u50A8\u4E0E\u534F\u8BAE)" };
163773
+ }
163774
+ async function previewGroupMessage(req, deps = {}) {
163775
+ const base6 = await baseOf(deps);
163776
+ if (!base6) return { ok: false, code: "desktop_offline", error: "\u9884\u89C8\u9700\u8981\u684C\u9762\u5728\u7EBF (\u7FA4\u6D88\u606F\u7531\u684C\u9762\u7684\u6784\u9020\u5668\u751F\u6210)", note: OFFLINE_NOTE };
163777
+ const c = deps.cryptoObj || globalThis.crypto;
163778
+ let digestPreview = "";
163779
+ try {
163780
+ digestPreview = await sha256HexOf(taskActionContentText(req), c);
163781
+ } catch {
163782
+ digestPreview = "";
163783
+ }
163784
+ const f = fetchOf(deps);
163785
+ try {
163786
+ const r = await postJson(base6, "/api/mobile/tasks/preview", { request: req }, f);
163787
+ if (r.status !== 200 || !r.json?.ok) return mapFail(r, "\u9884\u89C8");
163788
+ return { ok: true, data: { text: String(r.json.text || ""), contentText: taskActionContentText(req), digestPreview } };
163789
+ } catch (e) {
163790
+ return { ok: false, code: "desktop_offline", error: `\u684C\u9762\u4E0D\u53EF\u8FBE: ${String(e?.message || e).slice(0, 120)}`, note: OFFLINE_NOTE };
163791
+ }
163792
+ }
163793
+ async function listGroups(deps = {}) {
163794
+ const base6 = await baseOf(deps);
163795
+ if (!base6) return { ok: false, code: "desktop_offline", error: "\u770B\u7FA4\u5217\u8868\u9700\u8981\u7535\u8111\u7AEF\u5728\u7EBF (\u7FA4\u5B58\u5728\u4E8E\u684C\u9762\u8282\u70B9\u7684 OrbitDB)", note: OFFLINE_NOTE };
163796
+ try {
163797
+ const r = await getJson(base6, "/api/mobile/tasks/groups", fetchOf(deps));
163798
+ if (r.status !== 200 || !r.json?.ok) return mapFail(r, "\u8BFB\u7FA4\u5217\u8868");
163799
+ return { ok: true, data: buildGroupsView(r.json.groups || []) };
163800
+ } catch (e) {
163801
+ return { ok: false, code: "desktop_offline", error: `\u684C\u9762\u4E0D\u53EF\u8FBE: ${String(e?.message || e).slice(0, 120)}`, note: OFFLINE_NOTE };
163802
+ }
163803
+ }
163804
+ function joinGroup(link, deps = {}) {
163805
+ const req = { ...emptyTaskActionRequest("group_join"), groupRef: String(link || "").trim() };
163806
+ return executeTaskAction(req, deps);
163807
+ }
163808
+ function leaveGroup(groupRef, deps = {}) {
163809
+ const req = { ...emptyTaskActionRequest("group_leave"), groupRef: String(groupRef || "").trim() };
163810
+ return executeTaskAction(req, deps);
163811
+ }
163812
+ function createGroup(name10, deps = {}) {
163813
+ const req = { ...emptyTaskActionRequest("group_create"), groupRef: String(name10 || "").trim() };
163814
+ return executeTaskAction(req, deps);
163815
+ }
163816
+ async function loadBoard(deps = {}) {
163817
+ const base6 = await baseOf(deps);
163818
+ if (!base6) return { ok: false, code: "desktop_offline", error: "\u770B\u677F\u9700\u8981\u7535\u8111\u7AEF\u5728\u7EBF (\u516C\u544A\u677F\u5728\u684C\u9762\u8282\u70B9\u4E0A)", note: OFFLINE_NOTE };
163819
+ const now = deps.now ? deps.now() : Date.now();
163820
+ try {
163821
+ const r = await getJson(base6, "/api/mobile/tasks/board", fetchOf(deps));
163822
+ if (r.status !== 200 || !r.json?.ok) return mapFail(r, "\u8BFB\u770B\u677F");
163823
+ return { ok: true, data: buildBoardView(r.json, now) };
163824
+ } catch (e) {
163825
+ return { ok: false, code: "desktop_offline", error: `\u684C\u9762\u4E0D\u53EF\u8FBE: ${String(e?.message || e).slice(0, 120)}`, note: OFFLINE_NOTE };
163826
+ }
163827
+ }
163828
+ function publishAnnouncement(input, deps = {}) {
163829
+ const req = {
163830
+ ...emptyTaskActionRequest("announce_publish"),
163831
+ capability: String(input.capability || "").trim(),
163832
+ instruction: String(input.instruction || ""),
163833
+ budgetHuman: String(input.budgetHuman || "").trim(),
163834
+ currency: String(input.currency || "USDC").toUpperCase(),
163835
+ deadline: input.deadline ? String(input.deadline).trim() : null
163836
+ };
163837
+ return executeTaskAction(req, deps);
163838
+ }
163839
+ function announceIntoGroup(input, deps = {}) {
163840
+ const req = {
163841
+ ...emptyTaskActionRequest("announce_to_group"),
163842
+ groupRef: String(input.groupRef || "").trim(),
163843
+ announcementId: String(input.announcementId || "").trim(),
163844
+ round: input.round ? String(input.round) : null,
163845
+ criteria: input.criteria ? String(input.criteria) : null
163846
+ };
163847
+ return executeTaskAction(req, deps);
163848
+ }
163849
+ function postTrail(input, deps = {}) {
163850
+ const req = {
163851
+ ...emptyTaskActionRequest("trail_post"),
163852
+ groupRef: String(input.groupRef || "").trim(),
163853
+ announcementId: String(input.announcementId || "").trim(),
163854
+ round: input.round ? String(input.round) : null,
163855
+ price: input.price ? String(input.price) : null,
163856
+ hash: input.hash ? String(input.hash) : null,
163857
+ bytes: typeof input.bytes === "number" ? input.bytes : null,
163858
+ checks: input.checks ? String(input.checks) : null,
163859
+ verdict: input.verdict ? String(input.verdict) : null,
163860
+ trailKind: input.kind
163861
+ };
163862
+ return executeTaskAction(req, deps);
163863
+ }
163864
+ async function loadTrail(input, deps = {}) {
163865
+ const base6 = await baseOf(deps);
163866
+ if (!base6) return { ok: false, code: "desktop_offline", error: "\u8BFB\u7FA4\u75D5\u8FF9\u9700\u8981\u7535\u8111\u7AEF\u5728\u7EBF", note: OFFLINE_NOTE };
163867
+ const q = new URLSearchParams();
163868
+ q.set("group", String(input.groupRef || "").trim());
163869
+ if (input.announcementId) q.set("announcementId", String(input.announcementId));
163870
+ if (input.limit) q.set("limit", String(input.limit));
163871
+ try {
163872
+ const r = await getJson(base6, `/api/mobile/tasks/trail?${q.toString()}`, fetchOf(deps));
163873
+ if (r.status !== 200 || !r.json?.ok) return mapFail(r, "\u8BFB\u7FA4\u75D5\u8FF9");
163874
+ return { ok: true, data: buildTrailView(r.json.summary || r.json) };
163875
+ } catch (e) {
163876
+ return { ok: false, code: "desktop_offline", error: `\u684C\u9762\u4E0D\u53EF\u8FBE: ${String(e?.message || e).slice(0, 120)}`, note: OFFLINE_NOTE };
163877
+ }
163878
+ }
163879
+ async function loadFlywheel(deps = {}) {
163880
+ const base6 = await baseOf(deps);
163881
+ if (!base6) return { ok: false, code: "desktop_offline", error: "\u770B\u98DE\u8F6E\u8FDB\u5EA6\u9700\u8981\u7535\u8111\u7AEF\u5728\u7EBF (Goal \u8BB0\u5F55\u5728\u684C\u9762\u8282\u70B9\u4E0A)", note: OFFLINE_NOTE };
163882
+ try {
163883
+ const r = await getJson(base6, "/api/mobile/tasks/flywheel", fetchOf(deps));
163884
+ if (r.status !== 200 || !r.json?.ok) return mapFail(r, "\u8BFB\u98DE\u8F6E\u8FDB\u5EA6");
163885
+ const goals = Array.isArray(r.json.goals) ? r.json.goals : [];
163886
+ const leaks = findInternalFieldLeaks(JSON.stringify(goals));
163887
+ if (leaks.length) return { ok: false, code: "view_leak", error: `\u89C6\u56FE\u91CC\u542B\u5185\u90E8\u5B57\u6BB5 (${leaks.join(", ")}) \u2192 \u62D2\u7EDD\u6E32\u67D3` };
163888
+ return { ok: true, data: { goals, hint: r.json.hint ? String(r.json.hint) : null } };
163889
+ } catch (e) {
163890
+ return { ok: false, code: "desktop_offline", error: `\u684C\u9762\u4E0D\u53EF\u8FBE: ${String(e?.message || e).slice(0, 120)}`, note: OFFLINE_NOTE };
163891
+ }
163892
+ }
163893
+ function setTaskHint(text, storage2 = defaultStorage2()) {
163894
+ try {
163895
+ storage2.setItem(K_TASKS_HINT, String(text || "").slice(0, 160));
163896
+ } catch {
163897
+ }
163898
+ }
163899
+ function getTaskHint(storage2 = defaultStorage2()) {
163900
+ try {
163901
+ return String(storage2.getItem(K_TASKS_HINT) || "");
163902
+ } catch {
163903
+ return "";
163904
+ }
163905
+ }
163906
+
162926
163907
  // src/web/mobile-core.ts
162927
163908
  var busHandlers = /* @__PURE__ */ new Set();
162928
163909
  function busBroadcast(msg) {
@@ -163033,6 +164014,8 @@ ${error.stack}` : head;
163033
164014
  if (p === "/api/peers") return () => core.peers.list();
163034
164015
  if (p === "/api/mcp/tools") return () => core.mcp.tools();
163035
164016
  if (p === "/api/skills") return () => core.skills.list();
164017
+ if (p === "/api/contacts") return () => core.contacts.view();
164018
+ if (p === "/api/contacts/grants") return () => core.contacts.grants();
163036
164019
  if (p === "/api/auth/status") return () => core.identity.status();
163037
164020
  if (p === "/api/payments/pending") return () => core.payments.pending();
163038
164021
  if (p === "/api/llm-config") return () => core.data.getLlmConfig();
@@ -163786,6 +164769,111 @@ ${error.stack}` : head;
163786
164769
  return mobileGatewayTool2(String(name10 || ""), args || {});
163787
164770
  }
163788
164771
  },
164772
+ /**
164773
+ * 联系方式与持久授权 (2026-09-19, Phase 5/10)
164774
+ * 手机负责: 输入 · OTP 确认 · 生物识别/系统确认 · 展示待发内容 · 批准高风险联系 · **签名长期授权**
164775
+ * 桌面负责: 落盘 · 执行 · 等待回复 · 证据
164776
+ * 铁律: 明文不进手机存储 (只存 capability 副本), 桌面离线不假装成功, 不支持 Ed25519 就明说。
164777
+ */
164778
+ contacts: {
164779
+ /** 本机是否能做设备签名 (老 WebView 可能没有 Ed25519) */
164780
+ deviceSigning() {
164781
+ return ed25519Available();
164782
+ },
164783
+ /** 桌面 HTTP 地址 (拿不到 → null, 不猜) */
164784
+ async desktopBase() {
164785
+ try {
164786
+ const u = await core.desktop?.url?.();
164787
+ const raw = u && typeof u === "object" ? u.url || u.baseUrl || "" : u;
164788
+ const s2 = String(raw || "").replace(/\/+$/, "");
164789
+ return s2 || null;
164790
+ } catch {
164791
+ return null;
164792
+ }
164793
+ },
164794
+ /** 手机端本地存储 (只放: 设备私钥 JWK / capability 副本 / 离线队列) */
164795
+ storage() {
164796
+ try {
164797
+ if (typeof localStorage !== "undefined") return localStorage;
164798
+ } catch {
164799
+ }
164800
+ const mem2 = /* @__PURE__ */ new Map();
164801
+ return { getItem: (k) => mem2.has(k) ? mem2.get(k) : null, setItem: (k, v) => {
164802
+ mem2.set(k, v);
164803
+ }, removeItem: (k) => {
164804
+ mem2.delete(k);
164805
+ } };
164806
+ },
164807
+ /** 从桌面读脱敏视图 (桌面离线 → 退回本地 capability 副本并标注) */
164808
+ async view() {
164809
+ const base6 = await core.contacts.desktopBase();
164810
+ const r = await loadFromDesktop(base6, core.contacts.storage());
164811
+ return { ...r.data || { contacts: [], grants: [], effective: "", approvals: [], waiting: [] }, offline: !r.ok, note: r.note, error: r.error };
164812
+ },
164813
+ async grants() {
164814
+ const v = await core.contacts.view();
164815
+ return { grants: v.grants || [], effective: v.effective || "", offline: v.offline };
164816
+ },
164817
+ /** 手机端摘要卡 (给 UI 直接渲染) */
164818
+ async card() {
164819
+ const base6 = await core.contacts.desktopBase();
164820
+ const r = await loadFromDesktop(base6, core.contacts.storage());
164821
+ return buildPhoneCard(r.data || null, { deviceSigning: ed25519Available(), offline: r.error });
164822
+ },
164823
+ /** 确认授权 (三个选项之一) → 设备签名 → 桌面验签; 桌面离线则进本地队列 */
164824
+ async authorize(choice, ownerDid) {
164825
+ const base6 = await core.contacts.desktopBase();
164826
+ let did = ownerDid;
164827
+ if (!did) {
164828
+ try {
164829
+ const st = await core.identity?.status?.();
164830
+ did = st?.did;
164831
+ } catch {
164832
+ }
164833
+ }
164834
+ return authorizeFromPhone({
164835
+ base: base6 || "",
164836
+ choice,
164837
+ ownerDid: did || "did:bolln:local",
164838
+ storage: core.contacts.storage(),
164839
+ grantedBy: "leo"
164840
+ });
164841
+ },
164842
+ /** 手机撤销 (带签名; 桌面离线不假装已撤销) */
164843
+ async revoke(grantId, reason) {
164844
+ const base6 = await core.contacts.desktopBase();
164845
+ if (!base6) return { ok: false, error: "desktop_offline: \u64A4\u9500\u9700\u8981\u684C\u9762\u5728\u7EBF" };
164846
+ return revokeFromPhone({ base: base6, grantId, reason, storage: core.contacts.storage(), version: Date.now() });
164847
+ },
164848
+ async bind(kind, value2, region) {
164849
+ const base6 = await core.contacts.desktopBase();
164850
+ return bindFromPhone(base6, { kind, value: value2, region }, core.contacts.storage());
164851
+ },
164852
+ async verify(contactId, challengeId, code10) {
164853
+ const base6 = await core.contacts.desktopBase();
164854
+ return verifyFromPhone(base6, { contactId, challengeId, code: code10 }, core.contacts.storage());
164855
+ },
164856
+ /** 手机上批准/拒绝高风险联系 (展示待发内容后) */
164857
+ async decide(consentId, action, opts = {}) {
164858
+ const base6 = await core.contacts.desktopBase();
164859
+ return decideApprovalFromPhone(base6, { consentId, action, ...opts });
164860
+ },
164861
+ /** 桌面回来后补同步排队中的授权 */
164862
+ async flushQueue() {
164863
+ const base6 = await core.contacts.desktopBase();
164864
+ if (!base6) return { sent: 0, failed: pendingQueue(core.contacts.storage()).length, results: [] };
164865
+ return flushQueuedGrants(base6, core.contacts.storage());
164866
+ },
164867
+ queue() {
164868
+ return pendingQueue(core.contacts.storage());
164869
+ },
164870
+ capabilities() {
164871
+ return loadCapabilityCopy(core.contacts.storage());
164872
+ },
164873
+ device() {
164874
+ return loadOrCreateDeviceKey(core.contacts.storage());
164875
+ }
164876
+ },
163789
164877
  skills: {
163790
164878
  async list() {
163791
164879
  const s2 = await Promise.resolve().then(() => (init_mobile_sync(), mobile_sync_exports));
@@ -163793,6 +164881,66 @@ ${error.stack}` : head;
163793
164881
  return snap && Array.isArray(snap.skills) ? snap.skills : [];
163794
164882
  }
163795
164883
  },
164884
+ /**
164885
+ * 任务协作 (2026-09-25) — 手机与桌面/CLI 共用同一套存储与协议:
164886
+ * 入群 (`task group …`) · 发公告 (`task publish/announce/post`) · 看飞轮进度 (goal-flywheel 冻结类型, 只读)
164887
+ * 四个高风险动作 (入群/退群/建群/发公告/留痕) 一律**先签设备名再由桌面验签执行** —— 手机不自己执行、不记账。
164888
+ * 桌面不可达 → 明确失败 (任务动作**不进离线队列**: 几小时后突然生效的批准比失败更危险)。
164889
+ */
164890
+ tasks: {
164891
+ /** 本机能不能签 (老 WebView 没 Ed25519 → 高风险动作一律拒, 不降级) */
164892
+ deviceSigning() {
164893
+ return ed25519Available();
164894
+ },
164895
+ /** 桌面基址 (拿不到 → null, 不猜) */
164896
+ async desktopBase() {
164897
+ return core.contacts.desktopBase();
164898
+ },
164899
+ deps() {
164900
+ return { storage: core.contacts.storage(), ownerDid: void 0, grantedBy: "leo" };
164901
+ },
164902
+ /** ① 群: 列本机已加入的群 (脱敏, 只给缩短 id/群名/时间) */
164903
+ listGroups: () => listGroups(core.tasks.deps()),
164904
+ /** ① 入群 (高风险: 展示待发内容 → 设备签名 → 桌面验签执行) */
164905
+ joinGroup: (link) => joinGroup(link, core.tasks.deps()),
164906
+ /** ① 退群 (高风险) */
164907
+ leaveGroup: (ref) => leaveGroup(ref, core.tasks.deps()),
164908
+ /** ① 建群 (高风险; 建完自动入群) */
164909
+ createGroup: (name10) => createGroup(name10, core.tasks.deps()),
164910
+ /** ② 看板 (只读; 与 CLI `task board` 同一份事实) */
164911
+ loadBoard: () => loadBoard(core.tasks.deps()),
164912
+ /** ② 发布公告 (高风险) */
164913
+ publishAnnouncement: (input) => publishAnnouncement(input, core.tasks.deps()),
164914
+ /** ② 把公告发进群 (高风险; 预览 → 确认 → 签名) */
164915
+ announceIntoGroup: (input) => announceIntoGroup(input, core.tasks.deps()),
164916
+ /** ② 过程留痕 (高风险: claim/deliver/screen/final) */
164917
+ postTrail: (input) => postTrail(input, core.tasks.deps()),
164918
+ /** ② 读群里的一期痕迹 (只读) */
164919
+ loadTrail: (input) => loadTrail(input, core.tasks.deps()),
164920
+ /** 预览群消息那一行 (由桌面同一个构造器生成) */
164921
+ previewGroupMessage: (req) => previewGroupMessage(req, core.tasks.deps()),
164922
+ /** ③ 飞轮进度 (只读消费 goal-flywheel 冻结类型; 投影在桌面做) */
164923
+ loadFlywheel: () => loadFlywheel(core.tasks.deps()),
164924
+ /** 确认页文案 (展示待发内容) */
164925
+ describeConfirm: (kind, req) => describeTaskActionForConfirm(kind, req),
164926
+ /** 直接执行一个已构造好的请求 (UI 的统一入口: 签名 → 桌面验签执行) */
164927
+ execute: (req) => executeTaskAction(req, core.tasks.deps()),
164928
+ /** 相对时间人话 (毫秒差 → 双语; 只用于写文字节点) */
164929
+ relative: (ms2, lang) => formatRelative(ms2, lang === "en" ? "en" : "zh"),
164930
+ /** id 缩短 (页面上不出现原文) */
164931
+ shorten: (id, n) => shortId(id, n),
164932
+ /** 公开文本红线 (UI 最后一道自检: 渲染前扫一遍, 命中就不显示原文) */
164933
+ scanText: (text) => scanPublicText(String(text ?? "")),
164934
+ /** 构造一个空请求 (UI 填字段用) */
164935
+ emptyRequest: (kind) => emptyTaskActionRequest(kind),
164936
+ /** 最近一条操作提示 */
164937
+ hint() {
164938
+ return getTaskHint(core.contacts.storage());
164939
+ },
164940
+ setHint(text) {
164941
+ setTaskHint(text, core.contacts.storage());
164942
+ }
164943
+ },
163796
164944
  message: {
163797
164945
  async send({ text, channelId }) {
163798
164946
  if (!text || !channelId) return { ok: false, error: "text \u548C channelId \u5FC5\u586B" };
@@ -163819,8 +164967,13 @@ ${error.stack}` : head;
163819
164967
  const wl = agentLayer.getLastWorklog && agentLayer.getLastWorklog() || [];
163820
164968
  if (wl.length) busBroadcast({ type: "agent-worklog", lines: wl });
163821
164969
  } catch (e) {
164970
+ const errText = "\uFF08\u672C\u5730 Agent \u672A\u5C31\u7EEA: " + String(e?.message || e).slice(0, 80) + "\uFF09";
164971
+ try {
164972
+ await dataLayer.appendMessage(channelId, { role: "ai", content: errText, ts: Date.now() });
164973
+ } catch {
164974
+ }
163822
164975
  busBroadcast({ type: "loop-status", status: "done", message: "\u6267\u884C\u5931\u8D25: " + (e?.message || "").slice(0, 80) });
163823
- busBroadcast({ type: "ai", channelId, content: "\uFF08\u672C\u5730 Agent \u672A\u5C31\u7EEA: " + String(e?.message || e).slice(0, 80) + "\uFF09", role: "ai" });
164976
+ busBroadcast({ type: "ai", channelId, content: errText, role: "ai" });
163824
164977
  busBroadcast({ type: "done", channelId });
163825
164978
  }
163826
164979
  return { ok: true };