@paigy/harness 0.3.13 → 0.3.15

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 (3) hide show
  1. package/dist/cli.js +485 -2838
  2. package/dist/main.js +485 -2838
  3. package/package.json +2 -2
package/dist/main.js CHANGED
@@ -3479,7 +3479,7 @@ var require_sync_inflate = __commonJS({
3479
3479
  if (typeof asyncCb === "function") {
3480
3480
  return zlib.Inflate._processChunk.call(this, chunk, flushFlag, asyncCb);
3481
3481
  }
3482
- let self2 = this;
3482
+ let self = this;
3483
3483
  let availInBefore = chunk && chunk.length;
3484
3484
  let availOutBefore = this._chunkSize - this._offset;
3485
3485
  let leftToInflate = this._maxLength;
@@ -3491,14 +3491,14 @@ var require_sync_inflate = __commonJS({
3491
3491
  error = err;
3492
3492
  });
3493
3493
  function handleChunk(availInAfter, availOutAfter) {
3494
- if (self2._hadError) {
3494
+ if (self._hadError) {
3495
3495
  return;
3496
3496
  }
3497
3497
  let have = availOutBefore - availOutAfter;
3498
3498
  assert(have >= 0, "have should not go down");
3499
3499
  if (have > 0) {
3500
- let out = self2._buffer.slice(self2._offset, self2._offset + have);
3501
- self2._offset += have;
3500
+ let out = self._buffer.slice(self._offset, self._offset + have);
3501
+ self._offset += have;
3502
3502
  if (out.length > leftToInflate) {
3503
3503
  out = out.slice(0, leftToInflate);
3504
3504
  }
@@ -3509,10 +3509,10 @@ var require_sync_inflate = __commonJS({
3509
3509
  return false;
3510
3510
  }
3511
3511
  }
3512
- if (availOutAfter === 0 || self2._offset >= self2._chunkSize) {
3513
- availOutBefore = self2._chunkSize;
3514
- self2._offset = 0;
3515
- self2._buffer = Buffer.allocUnsafe(self2._chunkSize);
3512
+ if (availOutAfter === 0 || self._offset >= self._chunkSize) {
3513
+ availOutBefore = self._chunkSize;
3514
+ self._offset = 0;
3515
+ self._buffer = Buffer.allocUnsafe(self._chunkSize);
3516
3516
  }
3517
3517
  if (availOutAfter === 0) {
3518
3518
  inOff += availInBefore - availInAfter;
@@ -4578,13 +4578,17 @@ var require_lib = __commonJS({
4578
4578
  // src/main.ts
4579
4579
  import { app, BrowserWindow, dialog, ipcMain } from "electron";
4580
4580
  import { spawn as spawn2 } from "child_process";
4581
- import { readFileSync as readFileSync4 } from "fs";
4581
+ import { readFileSync as readFileSync5 } from "fs";
4582
4582
  import { fileURLToPath } from "url";
4583
- import { dirname as dirname4, join as join7 } from "path";
4583
+ import { dirname as dirname4, join as join8 } from "path";
4584
4584
 
4585
4585
  // ../../packages/sdk/dist/index.js
4586
4586
  import { createRequire as __sdkCreateRequire } from "module";
4587
+ import { execFileSync } from "child_process";
4587
4588
  import { createHash, randomUUID } from "crypto";
4589
+ import { readFileSync } from "fs";
4590
+ import { homedir } from "os";
4591
+ import { join } from "path";
4588
4592
  import { randomUUID as randomUUID3 } from "crypto";
4589
4593
  import { setTimeout as sleep2 } from "timers/promises";
4590
4594
 
@@ -8631,2265 +8635,12 @@ var NEVER = INVALID;
8631
8635
 
8632
8636
  // ../../packages/sdk/dist/index.js
8633
8637
  import { randomUUID as randomUUID2 } from "crypto";
8634
- import { closeSync, existsSync, mkdirSync, openSync, readFileSync, rmSync, statSync, writeFileSync } from "fs";
8635
- import { homedir } from "os";
8636
- import { join } from "path";
8638
+ import { closeSync, existsSync, mkdirSync, openSync, readFileSync as readFileSync2, rmSync, statSync, writeFileSync } from "fs";
8639
+ import { homedir as homedir2 } from "os";
8640
+ import { join as join2 } from "path";
8641
+ import { execFileSync as execFileSync2 } from "child_process";
8637
8642
  var import_undici = __toESM(require_undici(), 1);
8638
8643
  var require2 = __sdkCreateRequire(import.meta.url);
8639
- var __create = Object.create;
8640
- var __defProp = Object.defineProperty;
8641
- var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
8642
- var __getOwnPropNames = Object.getOwnPropertyNames;
8643
- var __getProtoOf = Object.getPrototypeOf;
8644
- var __hasOwnProp = Object.prototype.hasOwnProperty;
8645
- var __require2 = /* @__PURE__ */ ((x) => typeof require2 !== "undefined" ? require2 : typeof Proxy !== "undefined" ? new Proxy(x, {
8646
- get: (a, b) => (typeof require2 !== "undefined" ? require2 : a)[b]
8647
- }) : x)(function(x) {
8648
- if (typeof require2 !== "undefined") return require2.apply(this, arguments);
8649
- throw Error('Dynamic require of "' + x + '" is not supported');
8650
- });
8651
- var __commonJS2 = (cb, mod) => function __require22() {
8652
- return mod || (0, cb[__getOwnPropNames(cb)[0]])((mod = { exports: {} }).exports, mod), mod.exports;
8653
- };
8654
- var __copyProps = (to, from, except, desc) => {
8655
- if (from && typeof from === "object" || typeof from === "function") {
8656
- for (let key of __getOwnPropNames(from))
8657
- if (!__hasOwnProp.call(to, key) && key !== except)
8658
- __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
8659
- }
8660
- return to;
8661
- };
8662
- var __toESM2 = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
8663
- // If the importer is in node compatibility mode or this is not an ESM
8664
- // file that has been converted to a CommonJS file using a Babel-
8665
- // compatible transform (i.e. "__esModule" has not been set), then set
8666
- // "default" to the CommonJS "module.exports" for node compatibility.
8667
- isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
8668
- mod
8669
- ));
8670
- var require_nacl_fast = __commonJS2({
8671
- "../../node_modules/.pnpm/tweetnacl@1.0.3/node_modules/tweetnacl/nacl-fast.js"(exports, module) {
8672
- "use strict";
8673
- (function(nacl6) {
8674
- "use strict";
8675
- var gf = function(init) {
8676
- var i, r = new Float64Array(16);
8677
- if (init) for (i = 0; i < init.length; i++) r[i] = init[i];
8678
- return r;
8679
- };
8680
- var randombytes = function() {
8681
- throw new Error("no PRNG");
8682
- };
8683
- var _0 = new Uint8Array(16);
8684
- var _9 = new Uint8Array(32);
8685
- _9[0] = 9;
8686
- var gf0 = gf(), gf1 = gf([1]), _121665 = gf([56129, 1]), D = gf([30883, 4953, 19914, 30187, 55467, 16705, 2637, 112, 59544, 30585, 16505, 36039, 65139, 11119, 27886, 20995]), D2 = gf([61785, 9906, 39828, 60374, 45398, 33411, 5274, 224, 53552, 61171, 33010, 6542, 64743, 22239, 55772, 9222]), X = gf([54554, 36645, 11616, 51542, 42930, 38181, 51040, 26924, 56412, 64982, 57905, 49316, 21502, 52590, 14035, 8553]), Y = gf([26200, 26214, 26214, 26214, 26214, 26214, 26214, 26214, 26214, 26214, 26214, 26214, 26214, 26214, 26214, 26214]), I = gf([41136, 18958, 6951, 50414, 58488, 44335, 6150, 12099, 55207, 15867, 153, 11085, 57099, 20417, 9344, 11139]);
8687
- function ts64(x, i, h, l) {
8688
- x[i] = h >> 24 & 255;
8689
- x[i + 1] = h >> 16 & 255;
8690
- x[i + 2] = h >> 8 & 255;
8691
- x[i + 3] = h & 255;
8692
- x[i + 4] = l >> 24 & 255;
8693
- x[i + 5] = l >> 16 & 255;
8694
- x[i + 6] = l >> 8 & 255;
8695
- x[i + 7] = l & 255;
8696
- }
8697
- function vn(x, xi, y, yi, n) {
8698
- var i, d = 0;
8699
- for (i = 0; i < n; i++) d |= x[xi + i] ^ y[yi + i];
8700
- return (1 & d - 1 >>> 8) - 1;
8701
- }
8702
- function crypto_verify_16(x, xi, y, yi) {
8703
- return vn(x, xi, y, yi, 16);
8704
- }
8705
- function crypto_verify_32(x, xi, y, yi) {
8706
- return vn(x, xi, y, yi, 32);
8707
- }
8708
- function core_salsa20(o, p, k, c) {
8709
- var j0 = c[0] & 255 | (c[1] & 255) << 8 | (c[2] & 255) << 16 | (c[3] & 255) << 24, j1 = k[0] & 255 | (k[1] & 255) << 8 | (k[2] & 255) << 16 | (k[3] & 255) << 24, j2 = k[4] & 255 | (k[5] & 255) << 8 | (k[6] & 255) << 16 | (k[7] & 255) << 24, j3 = k[8] & 255 | (k[9] & 255) << 8 | (k[10] & 255) << 16 | (k[11] & 255) << 24, j4 = k[12] & 255 | (k[13] & 255) << 8 | (k[14] & 255) << 16 | (k[15] & 255) << 24, j5 = c[4] & 255 | (c[5] & 255) << 8 | (c[6] & 255) << 16 | (c[7] & 255) << 24, j6 = p[0] & 255 | (p[1] & 255) << 8 | (p[2] & 255) << 16 | (p[3] & 255) << 24, j7 = p[4] & 255 | (p[5] & 255) << 8 | (p[6] & 255) << 16 | (p[7] & 255) << 24, j8 = p[8] & 255 | (p[9] & 255) << 8 | (p[10] & 255) << 16 | (p[11] & 255) << 24, j9 = p[12] & 255 | (p[13] & 255) << 8 | (p[14] & 255) << 16 | (p[15] & 255) << 24, j10 = c[8] & 255 | (c[9] & 255) << 8 | (c[10] & 255) << 16 | (c[11] & 255) << 24, j11 = k[16] & 255 | (k[17] & 255) << 8 | (k[18] & 255) << 16 | (k[19] & 255) << 24, j12 = k[20] & 255 | (k[21] & 255) << 8 | (k[22] & 255) << 16 | (k[23] & 255) << 24, j13 = k[24] & 255 | (k[25] & 255) << 8 | (k[26] & 255) << 16 | (k[27] & 255) << 24, j14 = k[28] & 255 | (k[29] & 255) << 8 | (k[30] & 255) << 16 | (k[31] & 255) << 24, j15 = c[12] & 255 | (c[13] & 255) << 8 | (c[14] & 255) << 16 | (c[15] & 255) << 24;
8710
- var x0 = j0, x1 = j1, x2 = j2, x3 = j3, x4 = j4, x5 = j5, x6 = j6, x7 = j7, x8 = j8, x9 = j9, x10 = j10, x11 = j11, x12 = j12, x13 = j13, x14 = j14, x15 = j15, u;
8711
- for (var i = 0; i < 20; i += 2) {
8712
- u = x0 + x12 | 0;
8713
- x4 ^= u << 7 | u >>> 32 - 7;
8714
- u = x4 + x0 | 0;
8715
- x8 ^= u << 9 | u >>> 32 - 9;
8716
- u = x8 + x4 | 0;
8717
- x12 ^= u << 13 | u >>> 32 - 13;
8718
- u = x12 + x8 | 0;
8719
- x0 ^= u << 18 | u >>> 32 - 18;
8720
- u = x5 + x1 | 0;
8721
- x9 ^= u << 7 | u >>> 32 - 7;
8722
- u = x9 + x5 | 0;
8723
- x13 ^= u << 9 | u >>> 32 - 9;
8724
- u = x13 + x9 | 0;
8725
- x1 ^= u << 13 | u >>> 32 - 13;
8726
- u = x1 + x13 | 0;
8727
- x5 ^= u << 18 | u >>> 32 - 18;
8728
- u = x10 + x6 | 0;
8729
- x14 ^= u << 7 | u >>> 32 - 7;
8730
- u = x14 + x10 | 0;
8731
- x2 ^= u << 9 | u >>> 32 - 9;
8732
- u = x2 + x14 | 0;
8733
- x6 ^= u << 13 | u >>> 32 - 13;
8734
- u = x6 + x2 | 0;
8735
- x10 ^= u << 18 | u >>> 32 - 18;
8736
- u = x15 + x11 | 0;
8737
- x3 ^= u << 7 | u >>> 32 - 7;
8738
- u = x3 + x15 | 0;
8739
- x7 ^= u << 9 | u >>> 32 - 9;
8740
- u = x7 + x3 | 0;
8741
- x11 ^= u << 13 | u >>> 32 - 13;
8742
- u = x11 + x7 | 0;
8743
- x15 ^= u << 18 | u >>> 32 - 18;
8744
- u = x0 + x3 | 0;
8745
- x1 ^= u << 7 | u >>> 32 - 7;
8746
- u = x1 + x0 | 0;
8747
- x2 ^= u << 9 | u >>> 32 - 9;
8748
- u = x2 + x1 | 0;
8749
- x3 ^= u << 13 | u >>> 32 - 13;
8750
- u = x3 + x2 | 0;
8751
- x0 ^= u << 18 | u >>> 32 - 18;
8752
- u = x5 + x4 | 0;
8753
- x6 ^= u << 7 | u >>> 32 - 7;
8754
- u = x6 + x5 | 0;
8755
- x7 ^= u << 9 | u >>> 32 - 9;
8756
- u = x7 + x6 | 0;
8757
- x4 ^= u << 13 | u >>> 32 - 13;
8758
- u = x4 + x7 | 0;
8759
- x5 ^= u << 18 | u >>> 32 - 18;
8760
- u = x10 + x9 | 0;
8761
- x11 ^= u << 7 | u >>> 32 - 7;
8762
- u = x11 + x10 | 0;
8763
- x8 ^= u << 9 | u >>> 32 - 9;
8764
- u = x8 + x11 | 0;
8765
- x9 ^= u << 13 | u >>> 32 - 13;
8766
- u = x9 + x8 | 0;
8767
- x10 ^= u << 18 | u >>> 32 - 18;
8768
- u = x15 + x14 | 0;
8769
- x12 ^= u << 7 | u >>> 32 - 7;
8770
- u = x12 + x15 | 0;
8771
- x13 ^= u << 9 | u >>> 32 - 9;
8772
- u = x13 + x12 | 0;
8773
- x14 ^= u << 13 | u >>> 32 - 13;
8774
- u = x14 + x13 | 0;
8775
- x15 ^= u << 18 | u >>> 32 - 18;
8776
- }
8777
- x0 = x0 + j0 | 0;
8778
- x1 = x1 + j1 | 0;
8779
- x2 = x2 + j2 | 0;
8780
- x3 = x3 + j3 | 0;
8781
- x4 = x4 + j4 | 0;
8782
- x5 = x5 + j5 | 0;
8783
- x6 = x6 + j6 | 0;
8784
- x7 = x7 + j7 | 0;
8785
- x8 = x8 + j8 | 0;
8786
- x9 = x9 + j9 | 0;
8787
- x10 = x10 + j10 | 0;
8788
- x11 = x11 + j11 | 0;
8789
- x12 = x12 + j12 | 0;
8790
- x13 = x13 + j13 | 0;
8791
- x14 = x14 + j14 | 0;
8792
- x15 = x15 + j15 | 0;
8793
- o[0] = x0 >>> 0 & 255;
8794
- o[1] = x0 >>> 8 & 255;
8795
- o[2] = x0 >>> 16 & 255;
8796
- o[3] = x0 >>> 24 & 255;
8797
- o[4] = x1 >>> 0 & 255;
8798
- o[5] = x1 >>> 8 & 255;
8799
- o[6] = x1 >>> 16 & 255;
8800
- o[7] = x1 >>> 24 & 255;
8801
- o[8] = x2 >>> 0 & 255;
8802
- o[9] = x2 >>> 8 & 255;
8803
- o[10] = x2 >>> 16 & 255;
8804
- o[11] = x2 >>> 24 & 255;
8805
- o[12] = x3 >>> 0 & 255;
8806
- o[13] = x3 >>> 8 & 255;
8807
- o[14] = x3 >>> 16 & 255;
8808
- o[15] = x3 >>> 24 & 255;
8809
- o[16] = x4 >>> 0 & 255;
8810
- o[17] = x4 >>> 8 & 255;
8811
- o[18] = x4 >>> 16 & 255;
8812
- o[19] = x4 >>> 24 & 255;
8813
- o[20] = x5 >>> 0 & 255;
8814
- o[21] = x5 >>> 8 & 255;
8815
- o[22] = x5 >>> 16 & 255;
8816
- o[23] = x5 >>> 24 & 255;
8817
- o[24] = x6 >>> 0 & 255;
8818
- o[25] = x6 >>> 8 & 255;
8819
- o[26] = x6 >>> 16 & 255;
8820
- o[27] = x6 >>> 24 & 255;
8821
- o[28] = x7 >>> 0 & 255;
8822
- o[29] = x7 >>> 8 & 255;
8823
- o[30] = x7 >>> 16 & 255;
8824
- o[31] = x7 >>> 24 & 255;
8825
- o[32] = x8 >>> 0 & 255;
8826
- o[33] = x8 >>> 8 & 255;
8827
- o[34] = x8 >>> 16 & 255;
8828
- o[35] = x8 >>> 24 & 255;
8829
- o[36] = x9 >>> 0 & 255;
8830
- o[37] = x9 >>> 8 & 255;
8831
- o[38] = x9 >>> 16 & 255;
8832
- o[39] = x9 >>> 24 & 255;
8833
- o[40] = x10 >>> 0 & 255;
8834
- o[41] = x10 >>> 8 & 255;
8835
- o[42] = x10 >>> 16 & 255;
8836
- o[43] = x10 >>> 24 & 255;
8837
- o[44] = x11 >>> 0 & 255;
8838
- o[45] = x11 >>> 8 & 255;
8839
- o[46] = x11 >>> 16 & 255;
8840
- o[47] = x11 >>> 24 & 255;
8841
- o[48] = x12 >>> 0 & 255;
8842
- o[49] = x12 >>> 8 & 255;
8843
- o[50] = x12 >>> 16 & 255;
8844
- o[51] = x12 >>> 24 & 255;
8845
- o[52] = x13 >>> 0 & 255;
8846
- o[53] = x13 >>> 8 & 255;
8847
- o[54] = x13 >>> 16 & 255;
8848
- o[55] = x13 >>> 24 & 255;
8849
- o[56] = x14 >>> 0 & 255;
8850
- o[57] = x14 >>> 8 & 255;
8851
- o[58] = x14 >>> 16 & 255;
8852
- o[59] = x14 >>> 24 & 255;
8853
- o[60] = x15 >>> 0 & 255;
8854
- o[61] = x15 >>> 8 & 255;
8855
- o[62] = x15 >>> 16 & 255;
8856
- o[63] = x15 >>> 24 & 255;
8857
- }
8858
- function core_hsalsa20(o, p, k, c) {
8859
- var j0 = c[0] & 255 | (c[1] & 255) << 8 | (c[2] & 255) << 16 | (c[3] & 255) << 24, j1 = k[0] & 255 | (k[1] & 255) << 8 | (k[2] & 255) << 16 | (k[3] & 255) << 24, j2 = k[4] & 255 | (k[5] & 255) << 8 | (k[6] & 255) << 16 | (k[7] & 255) << 24, j3 = k[8] & 255 | (k[9] & 255) << 8 | (k[10] & 255) << 16 | (k[11] & 255) << 24, j4 = k[12] & 255 | (k[13] & 255) << 8 | (k[14] & 255) << 16 | (k[15] & 255) << 24, j5 = c[4] & 255 | (c[5] & 255) << 8 | (c[6] & 255) << 16 | (c[7] & 255) << 24, j6 = p[0] & 255 | (p[1] & 255) << 8 | (p[2] & 255) << 16 | (p[3] & 255) << 24, j7 = p[4] & 255 | (p[5] & 255) << 8 | (p[6] & 255) << 16 | (p[7] & 255) << 24, j8 = p[8] & 255 | (p[9] & 255) << 8 | (p[10] & 255) << 16 | (p[11] & 255) << 24, j9 = p[12] & 255 | (p[13] & 255) << 8 | (p[14] & 255) << 16 | (p[15] & 255) << 24, j10 = c[8] & 255 | (c[9] & 255) << 8 | (c[10] & 255) << 16 | (c[11] & 255) << 24, j11 = k[16] & 255 | (k[17] & 255) << 8 | (k[18] & 255) << 16 | (k[19] & 255) << 24, j12 = k[20] & 255 | (k[21] & 255) << 8 | (k[22] & 255) << 16 | (k[23] & 255) << 24, j13 = k[24] & 255 | (k[25] & 255) << 8 | (k[26] & 255) << 16 | (k[27] & 255) << 24, j14 = k[28] & 255 | (k[29] & 255) << 8 | (k[30] & 255) << 16 | (k[31] & 255) << 24, j15 = c[12] & 255 | (c[13] & 255) << 8 | (c[14] & 255) << 16 | (c[15] & 255) << 24;
8860
- var x0 = j0, x1 = j1, x2 = j2, x3 = j3, x4 = j4, x5 = j5, x6 = j6, x7 = j7, x8 = j8, x9 = j9, x10 = j10, x11 = j11, x12 = j12, x13 = j13, x14 = j14, x15 = j15, u;
8861
- for (var i = 0; i < 20; i += 2) {
8862
- u = x0 + x12 | 0;
8863
- x4 ^= u << 7 | u >>> 32 - 7;
8864
- u = x4 + x0 | 0;
8865
- x8 ^= u << 9 | u >>> 32 - 9;
8866
- u = x8 + x4 | 0;
8867
- x12 ^= u << 13 | u >>> 32 - 13;
8868
- u = x12 + x8 | 0;
8869
- x0 ^= u << 18 | u >>> 32 - 18;
8870
- u = x5 + x1 | 0;
8871
- x9 ^= u << 7 | u >>> 32 - 7;
8872
- u = x9 + x5 | 0;
8873
- x13 ^= u << 9 | u >>> 32 - 9;
8874
- u = x13 + x9 | 0;
8875
- x1 ^= u << 13 | u >>> 32 - 13;
8876
- u = x1 + x13 | 0;
8877
- x5 ^= u << 18 | u >>> 32 - 18;
8878
- u = x10 + x6 | 0;
8879
- x14 ^= u << 7 | u >>> 32 - 7;
8880
- u = x14 + x10 | 0;
8881
- x2 ^= u << 9 | u >>> 32 - 9;
8882
- u = x2 + x14 | 0;
8883
- x6 ^= u << 13 | u >>> 32 - 13;
8884
- u = x6 + x2 | 0;
8885
- x10 ^= u << 18 | u >>> 32 - 18;
8886
- u = x15 + x11 | 0;
8887
- x3 ^= u << 7 | u >>> 32 - 7;
8888
- u = x3 + x15 | 0;
8889
- x7 ^= u << 9 | u >>> 32 - 9;
8890
- u = x7 + x3 | 0;
8891
- x11 ^= u << 13 | u >>> 32 - 13;
8892
- u = x11 + x7 | 0;
8893
- x15 ^= u << 18 | u >>> 32 - 18;
8894
- u = x0 + x3 | 0;
8895
- x1 ^= u << 7 | u >>> 32 - 7;
8896
- u = x1 + x0 | 0;
8897
- x2 ^= u << 9 | u >>> 32 - 9;
8898
- u = x2 + x1 | 0;
8899
- x3 ^= u << 13 | u >>> 32 - 13;
8900
- u = x3 + x2 | 0;
8901
- x0 ^= u << 18 | u >>> 32 - 18;
8902
- u = x5 + x4 | 0;
8903
- x6 ^= u << 7 | u >>> 32 - 7;
8904
- u = x6 + x5 | 0;
8905
- x7 ^= u << 9 | u >>> 32 - 9;
8906
- u = x7 + x6 | 0;
8907
- x4 ^= u << 13 | u >>> 32 - 13;
8908
- u = x4 + x7 | 0;
8909
- x5 ^= u << 18 | u >>> 32 - 18;
8910
- u = x10 + x9 | 0;
8911
- x11 ^= u << 7 | u >>> 32 - 7;
8912
- u = x11 + x10 | 0;
8913
- x8 ^= u << 9 | u >>> 32 - 9;
8914
- u = x8 + x11 | 0;
8915
- x9 ^= u << 13 | u >>> 32 - 13;
8916
- u = x9 + x8 | 0;
8917
- x10 ^= u << 18 | u >>> 32 - 18;
8918
- u = x15 + x14 | 0;
8919
- x12 ^= u << 7 | u >>> 32 - 7;
8920
- u = x12 + x15 | 0;
8921
- x13 ^= u << 9 | u >>> 32 - 9;
8922
- u = x13 + x12 | 0;
8923
- x14 ^= u << 13 | u >>> 32 - 13;
8924
- u = x14 + x13 | 0;
8925
- x15 ^= u << 18 | u >>> 32 - 18;
8926
- }
8927
- o[0] = x0 >>> 0 & 255;
8928
- o[1] = x0 >>> 8 & 255;
8929
- o[2] = x0 >>> 16 & 255;
8930
- o[3] = x0 >>> 24 & 255;
8931
- o[4] = x5 >>> 0 & 255;
8932
- o[5] = x5 >>> 8 & 255;
8933
- o[6] = x5 >>> 16 & 255;
8934
- o[7] = x5 >>> 24 & 255;
8935
- o[8] = x10 >>> 0 & 255;
8936
- o[9] = x10 >>> 8 & 255;
8937
- o[10] = x10 >>> 16 & 255;
8938
- o[11] = x10 >>> 24 & 255;
8939
- o[12] = x15 >>> 0 & 255;
8940
- o[13] = x15 >>> 8 & 255;
8941
- o[14] = x15 >>> 16 & 255;
8942
- o[15] = x15 >>> 24 & 255;
8943
- o[16] = x6 >>> 0 & 255;
8944
- o[17] = x6 >>> 8 & 255;
8945
- o[18] = x6 >>> 16 & 255;
8946
- o[19] = x6 >>> 24 & 255;
8947
- o[20] = x7 >>> 0 & 255;
8948
- o[21] = x7 >>> 8 & 255;
8949
- o[22] = x7 >>> 16 & 255;
8950
- o[23] = x7 >>> 24 & 255;
8951
- o[24] = x8 >>> 0 & 255;
8952
- o[25] = x8 >>> 8 & 255;
8953
- o[26] = x8 >>> 16 & 255;
8954
- o[27] = x8 >>> 24 & 255;
8955
- o[28] = x9 >>> 0 & 255;
8956
- o[29] = x9 >>> 8 & 255;
8957
- o[30] = x9 >>> 16 & 255;
8958
- o[31] = x9 >>> 24 & 255;
8959
- }
8960
- function crypto_core_salsa20(out, inp, k, c) {
8961
- core_salsa20(out, inp, k, c);
8962
- }
8963
- function crypto_core_hsalsa20(out, inp, k, c) {
8964
- core_hsalsa20(out, inp, k, c);
8965
- }
8966
- var sigma = new Uint8Array([101, 120, 112, 97, 110, 100, 32, 51, 50, 45, 98, 121, 116, 101, 32, 107]);
8967
- function crypto_stream_salsa20_xor(c, cpos, m, mpos, b, n, k) {
8968
- var z4 = new Uint8Array(16), x = new Uint8Array(64);
8969
- var u, i;
8970
- for (i = 0; i < 16; i++) z4[i] = 0;
8971
- for (i = 0; i < 8; i++) z4[i] = n[i];
8972
- while (b >= 64) {
8973
- crypto_core_salsa20(x, z4, k, sigma);
8974
- for (i = 0; i < 64; i++) c[cpos + i] = m[mpos + i] ^ x[i];
8975
- u = 1;
8976
- for (i = 8; i < 16; i++) {
8977
- u = u + (z4[i] & 255) | 0;
8978
- z4[i] = u & 255;
8979
- u >>>= 8;
8980
- }
8981
- b -= 64;
8982
- cpos += 64;
8983
- mpos += 64;
8984
- }
8985
- if (b > 0) {
8986
- crypto_core_salsa20(x, z4, k, sigma);
8987
- for (i = 0; i < b; i++) c[cpos + i] = m[mpos + i] ^ x[i];
8988
- }
8989
- return 0;
8990
- }
8991
- function crypto_stream_salsa20(c, cpos, b, n, k) {
8992
- var z4 = new Uint8Array(16), x = new Uint8Array(64);
8993
- var u, i;
8994
- for (i = 0; i < 16; i++) z4[i] = 0;
8995
- for (i = 0; i < 8; i++) z4[i] = n[i];
8996
- while (b >= 64) {
8997
- crypto_core_salsa20(x, z4, k, sigma);
8998
- for (i = 0; i < 64; i++) c[cpos + i] = x[i];
8999
- u = 1;
9000
- for (i = 8; i < 16; i++) {
9001
- u = u + (z4[i] & 255) | 0;
9002
- z4[i] = u & 255;
9003
- u >>>= 8;
9004
- }
9005
- b -= 64;
9006
- cpos += 64;
9007
- }
9008
- if (b > 0) {
9009
- crypto_core_salsa20(x, z4, k, sigma);
9010
- for (i = 0; i < b; i++) c[cpos + i] = x[i];
9011
- }
9012
- return 0;
9013
- }
9014
- function crypto_stream(c, cpos, d, n, k) {
9015
- var s = new Uint8Array(32);
9016
- crypto_core_hsalsa20(s, n, k, sigma);
9017
- var sn = new Uint8Array(8);
9018
- for (var i = 0; i < 8; i++) sn[i] = n[i + 16];
9019
- return crypto_stream_salsa20(c, cpos, d, sn, s);
9020
- }
9021
- function crypto_stream_xor(c, cpos, m, mpos, d, n, k) {
9022
- var s = new Uint8Array(32);
9023
- crypto_core_hsalsa20(s, n, k, sigma);
9024
- var sn = new Uint8Array(8);
9025
- for (var i = 0; i < 8; i++) sn[i] = n[i + 16];
9026
- return crypto_stream_salsa20_xor(c, cpos, m, mpos, d, sn, s);
9027
- }
9028
- var poly1305 = function(key) {
9029
- this.buffer = new Uint8Array(16);
9030
- this.r = new Uint16Array(10);
9031
- this.h = new Uint16Array(10);
9032
- this.pad = new Uint16Array(8);
9033
- this.leftover = 0;
9034
- this.fin = 0;
9035
- var t0, t1, t2, t3, t4, t5, t6, t7;
9036
- t0 = key[0] & 255 | (key[1] & 255) << 8;
9037
- this.r[0] = t0 & 8191;
9038
- t1 = key[2] & 255 | (key[3] & 255) << 8;
9039
- this.r[1] = (t0 >>> 13 | t1 << 3) & 8191;
9040
- t2 = key[4] & 255 | (key[5] & 255) << 8;
9041
- this.r[2] = (t1 >>> 10 | t2 << 6) & 7939;
9042
- t3 = key[6] & 255 | (key[7] & 255) << 8;
9043
- this.r[3] = (t2 >>> 7 | t3 << 9) & 8191;
9044
- t4 = key[8] & 255 | (key[9] & 255) << 8;
9045
- this.r[4] = (t3 >>> 4 | t4 << 12) & 255;
9046
- this.r[5] = t4 >>> 1 & 8190;
9047
- t5 = key[10] & 255 | (key[11] & 255) << 8;
9048
- this.r[6] = (t4 >>> 14 | t5 << 2) & 8191;
9049
- t6 = key[12] & 255 | (key[13] & 255) << 8;
9050
- this.r[7] = (t5 >>> 11 | t6 << 5) & 8065;
9051
- t7 = key[14] & 255 | (key[15] & 255) << 8;
9052
- this.r[8] = (t6 >>> 8 | t7 << 8) & 8191;
9053
- this.r[9] = t7 >>> 5 & 127;
9054
- this.pad[0] = key[16] & 255 | (key[17] & 255) << 8;
9055
- this.pad[1] = key[18] & 255 | (key[19] & 255) << 8;
9056
- this.pad[2] = key[20] & 255 | (key[21] & 255) << 8;
9057
- this.pad[3] = key[22] & 255 | (key[23] & 255) << 8;
9058
- this.pad[4] = key[24] & 255 | (key[25] & 255) << 8;
9059
- this.pad[5] = key[26] & 255 | (key[27] & 255) << 8;
9060
- this.pad[6] = key[28] & 255 | (key[29] & 255) << 8;
9061
- this.pad[7] = key[30] & 255 | (key[31] & 255) << 8;
9062
- };
9063
- poly1305.prototype.blocks = function(m, mpos, bytes) {
9064
- var hibit = this.fin ? 0 : 1 << 11;
9065
- var t0, t1, t2, t3, t4, t5, t6, t7, c;
9066
- var d0, d1, d2, d3, d4, d5, d6, d7, d8, d9;
9067
- var h0 = this.h[0], h1 = this.h[1], h2 = this.h[2], h3 = this.h[3], h4 = this.h[4], h5 = this.h[5], h6 = this.h[6], h7 = this.h[7], h8 = this.h[8], h9 = this.h[9];
9068
- var r0 = this.r[0], r1 = this.r[1], r2 = this.r[2], r3 = this.r[3], r4 = this.r[4], r5 = this.r[5], r6 = this.r[6], r7 = this.r[7], r8 = this.r[8], r9 = this.r[9];
9069
- while (bytes >= 16) {
9070
- t0 = m[mpos + 0] & 255 | (m[mpos + 1] & 255) << 8;
9071
- h0 += t0 & 8191;
9072
- t1 = m[mpos + 2] & 255 | (m[mpos + 3] & 255) << 8;
9073
- h1 += (t0 >>> 13 | t1 << 3) & 8191;
9074
- t2 = m[mpos + 4] & 255 | (m[mpos + 5] & 255) << 8;
9075
- h2 += (t1 >>> 10 | t2 << 6) & 8191;
9076
- t3 = m[mpos + 6] & 255 | (m[mpos + 7] & 255) << 8;
9077
- h3 += (t2 >>> 7 | t3 << 9) & 8191;
9078
- t4 = m[mpos + 8] & 255 | (m[mpos + 9] & 255) << 8;
9079
- h4 += (t3 >>> 4 | t4 << 12) & 8191;
9080
- h5 += t4 >>> 1 & 8191;
9081
- t5 = m[mpos + 10] & 255 | (m[mpos + 11] & 255) << 8;
9082
- h6 += (t4 >>> 14 | t5 << 2) & 8191;
9083
- t6 = m[mpos + 12] & 255 | (m[mpos + 13] & 255) << 8;
9084
- h7 += (t5 >>> 11 | t6 << 5) & 8191;
9085
- t7 = m[mpos + 14] & 255 | (m[mpos + 15] & 255) << 8;
9086
- h8 += (t6 >>> 8 | t7 << 8) & 8191;
9087
- h9 += t7 >>> 5 | hibit;
9088
- c = 0;
9089
- d0 = c;
9090
- d0 += h0 * r0;
9091
- d0 += h1 * (5 * r9);
9092
- d0 += h2 * (5 * r8);
9093
- d0 += h3 * (5 * r7);
9094
- d0 += h4 * (5 * r6);
9095
- c = d0 >>> 13;
9096
- d0 &= 8191;
9097
- d0 += h5 * (5 * r5);
9098
- d0 += h6 * (5 * r4);
9099
- d0 += h7 * (5 * r3);
9100
- d0 += h8 * (5 * r2);
9101
- d0 += h9 * (5 * r1);
9102
- c += d0 >>> 13;
9103
- d0 &= 8191;
9104
- d1 = c;
9105
- d1 += h0 * r1;
9106
- d1 += h1 * r0;
9107
- d1 += h2 * (5 * r9);
9108
- d1 += h3 * (5 * r8);
9109
- d1 += h4 * (5 * r7);
9110
- c = d1 >>> 13;
9111
- d1 &= 8191;
9112
- d1 += h5 * (5 * r6);
9113
- d1 += h6 * (5 * r5);
9114
- d1 += h7 * (5 * r4);
9115
- d1 += h8 * (5 * r3);
9116
- d1 += h9 * (5 * r2);
9117
- c += d1 >>> 13;
9118
- d1 &= 8191;
9119
- d2 = c;
9120
- d2 += h0 * r2;
9121
- d2 += h1 * r1;
9122
- d2 += h2 * r0;
9123
- d2 += h3 * (5 * r9);
9124
- d2 += h4 * (5 * r8);
9125
- c = d2 >>> 13;
9126
- d2 &= 8191;
9127
- d2 += h5 * (5 * r7);
9128
- d2 += h6 * (5 * r6);
9129
- d2 += h7 * (5 * r5);
9130
- d2 += h8 * (5 * r4);
9131
- d2 += h9 * (5 * r3);
9132
- c += d2 >>> 13;
9133
- d2 &= 8191;
9134
- d3 = c;
9135
- d3 += h0 * r3;
9136
- d3 += h1 * r2;
9137
- d3 += h2 * r1;
9138
- d3 += h3 * r0;
9139
- d3 += h4 * (5 * r9);
9140
- c = d3 >>> 13;
9141
- d3 &= 8191;
9142
- d3 += h5 * (5 * r8);
9143
- d3 += h6 * (5 * r7);
9144
- d3 += h7 * (5 * r6);
9145
- d3 += h8 * (5 * r5);
9146
- d3 += h9 * (5 * r4);
9147
- c += d3 >>> 13;
9148
- d3 &= 8191;
9149
- d4 = c;
9150
- d4 += h0 * r4;
9151
- d4 += h1 * r3;
9152
- d4 += h2 * r2;
9153
- d4 += h3 * r1;
9154
- d4 += h4 * r0;
9155
- c = d4 >>> 13;
9156
- d4 &= 8191;
9157
- d4 += h5 * (5 * r9);
9158
- d4 += h6 * (5 * r8);
9159
- d4 += h7 * (5 * r7);
9160
- d4 += h8 * (5 * r6);
9161
- d4 += h9 * (5 * r5);
9162
- c += d4 >>> 13;
9163
- d4 &= 8191;
9164
- d5 = c;
9165
- d5 += h0 * r5;
9166
- d5 += h1 * r4;
9167
- d5 += h2 * r3;
9168
- d5 += h3 * r2;
9169
- d5 += h4 * r1;
9170
- c = d5 >>> 13;
9171
- d5 &= 8191;
9172
- d5 += h5 * r0;
9173
- d5 += h6 * (5 * r9);
9174
- d5 += h7 * (5 * r8);
9175
- d5 += h8 * (5 * r7);
9176
- d5 += h9 * (5 * r6);
9177
- c += d5 >>> 13;
9178
- d5 &= 8191;
9179
- d6 = c;
9180
- d6 += h0 * r6;
9181
- d6 += h1 * r5;
9182
- d6 += h2 * r4;
9183
- d6 += h3 * r3;
9184
- d6 += h4 * r2;
9185
- c = d6 >>> 13;
9186
- d6 &= 8191;
9187
- d6 += h5 * r1;
9188
- d6 += h6 * r0;
9189
- d6 += h7 * (5 * r9);
9190
- d6 += h8 * (5 * r8);
9191
- d6 += h9 * (5 * r7);
9192
- c += d6 >>> 13;
9193
- d6 &= 8191;
9194
- d7 = c;
9195
- d7 += h0 * r7;
9196
- d7 += h1 * r6;
9197
- d7 += h2 * r5;
9198
- d7 += h3 * r4;
9199
- d7 += h4 * r3;
9200
- c = d7 >>> 13;
9201
- d7 &= 8191;
9202
- d7 += h5 * r2;
9203
- d7 += h6 * r1;
9204
- d7 += h7 * r0;
9205
- d7 += h8 * (5 * r9);
9206
- d7 += h9 * (5 * r8);
9207
- c += d7 >>> 13;
9208
- d7 &= 8191;
9209
- d8 = c;
9210
- d8 += h0 * r8;
9211
- d8 += h1 * r7;
9212
- d8 += h2 * r6;
9213
- d8 += h3 * r5;
9214
- d8 += h4 * r4;
9215
- c = d8 >>> 13;
9216
- d8 &= 8191;
9217
- d8 += h5 * r3;
9218
- d8 += h6 * r2;
9219
- d8 += h7 * r1;
9220
- d8 += h8 * r0;
9221
- d8 += h9 * (5 * r9);
9222
- c += d8 >>> 13;
9223
- d8 &= 8191;
9224
- d9 = c;
9225
- d9 += h0 * r9;
9226
- d9 += h1 * r8;
9227
- d9 += h2 * r7;
9228
- d9 += h3 * r6;
9229
- d9 += h4 * r5;
9230
- c = d9 >>> 13;
9231
- d9 &= 8191;
9232
- d9 += h5 * r4;
9233
- d9 += h6 * r3;
9234
- d9 += h7 * r2;
9235
- d9 += h8 * r1;
9236
- d9 += h9 * r0;
9237
- c += d9 >>> 13;
9238
- d9 &= 8191;
9239
- c = (c << 2) + c | 0;
9240
- c = c + d0 | 0;
9241
- d0 = c & 8191;
9242
- c = c >>> 13;
9243
- d1 += c;
9244
- h0 = d0;
9245
- h1 = d1;
9246
- h2 = d2;
9247
- h3 = d3;
9248
- h4 = d4;
9249
- h5 = d5;
9250
- h6 = d6;
9251
- h7 = d7;
9252
- h8 = d8;
9253
- h9 = d9;
9254
- mpos += 16;
9255
- bytes -= 16;
9256
- }
9257
- this.h[0] = h0;
9258
- this.h[1] = h1;
9259
- this.h[2] = h2;
9260
- this.h[3] = h3;
9261
- this.h[4] = h4;
9262
- this.h[5] = h5;
9263
- this.h[6] = h6;
9264
- this.h[7] = h7;
9265
- this.h[8] = h8;
9266
- this.h[9] = h9;
9267
- };
9268
- poly1305.prototype.finish = function(mac, macpos) {
9269
- var g = new Uint16Array(10);
9270
- var c, mask, f, i;
9271
- if (this.leftover) {
9272
- i = this.leftover;
9273
- this.buffer[i++] = 1;
9274
- for (; i < 16; i++) this.buffer[i] = 0;
9275
- this.fin = 1;
9276
- this.blocks(this.buffer, 0, 16);
9277
- }
9278
- c = this.h[1] >>> 13;
9279
- this.h[1] &= 8191;
9280
- for (i = 2; i < 10; i++) {
9281
- this.h[i] += c;
9282
- c = this.h[i] >>> 13;
9283
- this.h[i] &= 8191;
9284
- }
9285
- this.h[0] += c * 5;
9286
- c = this.h[0] >>> 13;
9287
- this.h[0] &= 8191;
9288
- this.h[1] += c;
9289
- c = this.h[1] >>> 13;
9290
- this.h[1] &= 8191;
9291
- this.h[2] += c;
9292
- g[0] = this.h[0] + 5;
9293
- c = g[0] >>> 13;
9294
- g[0] &= 8191;
9295
- for (i = 1; i < 10; i++) {
9296
- g[i] = this.h[i] + c;
9297
- c = g[i] >>> 13;
9298
- g[i] &= 8191;
9299
- }
9300
- g[9] -= 1 << 13;
9301
- mask = (c ^ 1) - 1;
9302
- for (i = 0; i < 10; i++) g[i] &= mask;
9303
- mask = ~mask;
9304
- for (i = 0; i < 10; i++) this.h[i] = this.h[i] & mask | g[i];
9305
- this.h[0] = (this.h[0] | this.h[1] << 13) & 65535;
9306
- this.h[1] = (this.h[1] >>> 3 | this.h[2] << 10) & 65535;
9307
- this.h[2] = (this.h[2] >>> 6 | this.h[3] << 7) & 65535;
9308
- this.h[3] = (this.h[3] >>> 9 | this.h[4] << 4) & 65535;
9309
- this.h[4] = (this.h[4] >>> 12 | this.h[5] << 1 | this.h[6] << 14) & 65535;
9310
- this.h[5] = (this.h[6] >>> 2 | this.h[7] << 11) & 65535;
9311
- this.h[6] = (this.h[7] >>> 5 | this.h[8] << 8) & 65535;
9312
- this.h[7] = (this.h[8] >>> 8 | this.h[9] << 5) & 65535;
9313
- f = this.h[0] + this.pad[0];
9314
- this.h[0] = f & 65535;
9315
- for (i = 1; i < 8; i++) {
9316
- f = (this.h[i] + this.pad[i] | 0) + (f >>> 16) | 0;
9317
- this.h[i] = f & 65535;
9318
- }
9319
- mac[macpos + 0] = this.h[0] >>> 0 & 255;
9320
- mac[macpos + 1] = this.h[0] >>> 8 & 255;
9321
- mac[macpos + 2] = this.h[1] >>> 0 & 255;
9322
- mac[macpos + 3] = this.h[1] >>> 8 & 255;
9323
- mac[macpos + 4] = this.h[2] >>> 0 & 255;
9324
- mac[macpos + 5] = this.h[2] >>> 8 & 255;
9325
- mac[macpos + 6] = this.h[3] >>> 0 & 255;
9326
- mac[macpos + 7] = this.h[3] >>> 8 & 255;
9327
- mac[macpos + 8] = this.h[4] >>> 0 & 255;
9328
- mac[macpos + 9] = this.h[4] >>> 8 & 255;
9329
- mac[macpos + 10] = this.h[5] >>> 0 & 255;
9330
- mac[macpos + 11] = this.h[5] >>> 8 & 255;
9331
- mac[macpos + 12] = this.h[6] >>> 0 & 255;
9332
- mac[macpos + 13] = this.h[6] >>> 8 & 255;
9333
- mac[macpos + 14] = this.h[7] >>> 0 & 255;
9334
- mac[macpos + 15] = this.h[7] >>> 8 & 255;
9335
- };
9336
- poly1305.prototype.update = function(m, mpos, bytes) {
9337
- var i, want;
9338
- if (this.leftover) {
9339
- want = 16 - this.leftover;
9340
- if (want > bytes)
9341
- want = bytes;
9342
- for (i = 0; i < want; i++)
9343
- this.buffer[this.leftover + i] = m[mpos + i];
9344
- bytes -= want;
9345
- mpos += want;
9346
- this.leftover += want;
9347
- if (this.leftover < 16)
9348
- return;
9349
- this.blocks(this.buffer, 0, 16);
9350
- this.leftover = 0;
9351
- }
9352
- if (bytes >= 16) {
9353
- want = bytes - bytes % 16;
9354
- this.blocks(m, mpos, want);
9355
- mpos += want;
9356
- bytes -= want;
9357
- }
9358
- if (bytes) {
9359
- for (i = 0; i < bytes; i++)
9360
- this.buffer[this.leftover + i] = m[mpos + i];
9361
- this.leftover += bytes;
9362
- }
9363
- };
9364
- function crypto_onetimeauth(out, outpos, m, mpos, n, k) {
9365
- var s = new poly1305(k);
9366
- s.update(m, mpos, n);
9367
- s.finish(out, outpos);
9368
- return 0;
9369
- }
9370
- function crypto_onetimeauth_verify(h, hpos, m, mpos, n, k) {
9371
- var x = new Uint8Array(16);
9372
- crypto_onetimeauth(x, 0, m, mpos, n, k);
9373
- return crypto_verify_16(h, hpos, x, 0);
9374
- }
9375
- function crypto_secretbox(c, m, d, n, k) {
9376
- var i;
9377
- if (d < 32) return -1;
9378
- crypto_stream_xor(c, 0, m, 0, d, n, k);
9379
- crypto_onetimeauth(c, 16, c, 32, d - 32, c);
9380
- for (i = 0; i < 16; i++) c[i] = 0;
9381
- return 0;
9382
- }
9383
- function crypto_secretbox_open(m, c, d, n, k) {
9384
- var i;
9385
- var x = new Uint8Array(32);
9386
- if (d < 32) return -1;
9387
- crypto_stream(x, 0, 32, n, k);
9388
- if (crypto_onetimeauth_verify(c, 16, c, 32, d - 32, x) !== 0) return -1;
9389
- crypto_stream_xor(m, 0, c, 0, d, n, k);
9390
- for (i = 0; i < 32; i++) m[i] = 0;
9391
- return 0;
9392
- }
9393
- function set25519(r, a) {
9394
- var i;
9395
- for (i = 0; i < 16; i++) r[i] = a[i] | 0;
9396
- }
9397
- function car25519(o) {
9398
- var i, v, c = 1;
9399
- for (i = 0; i < 16; i++) {
9400
- v = o[i] + c + 65535;
9401
- c = Math.floor(v / 65536);
9402
- o[i] = v - c * 65536;
9403
- }
9404
- o[0] += c - 1 + 37 * (c - 1);
9405
- }
9406
- function sel25519(p, q, b) {
9407
- var t, c = ~(b - 1);
9408
- for (var i = 0; i < 16; i++) {
9409
- t = c & (p[i] ^ q[i]);
9410
- p[i] ^= t;
9411
- q[i] ^= t;
9412
- }
9413
- }
9414
- function pack25519(o, n) {
9415
- var i, j, b;
9416
- var m = gf(), t = gf();
9417
- for (i = 0; i < 16; i++) t[i] = n[i];
9418
- car25519(t);
9419
- car25519(t);
9420
- car25519(t);
9421
- for (j = 0; j < 2; j++) {
9422
- m[0] = t[0] - 65517;
9423
- for (i = 1; i < 15; i++) {
9424
- m[i] = t[i] - 65535 - (m[i - 1] >> 16 & 1);
9425
- m[i - 1] &= 65535;
9426
- }
9427
- m[15] = t[15] - 32767 - (m[14] >> 16 & 1);
9428
- b = m[15] >> 16 & 1;
9429
- m[14] &= 65535;
9430
- sel25519(t, m, 1 - b);
9431
- }
9432
- for (i = 0; i < 16; i++) {
9433
- o[2 * i] = t[i] & 255;
9434
- o[2 * i + 1] = t[i] >> 8;
9435
- }
9436
- }
9437
- function neq25519(a, b) {
9438
- var c = new Uint8Array(32), d = new Uint8Array(32);
9439
- pack25519(c, a);
9440
- pack25519(d, b);
9441
- return crypto_verify_32(c, 0, d, 0);
9442
- }
9443
- function par25519(a) {
9444
- var d = new Uint8Array(32);
9445
- pack25519(d, a);
9446
- return d[0] & 1;
9447
- }
9448
- function unpack25519(o, n) {
9449
- var i;
9450
- for (i = 0; i < 16; i++) o[i] = n[2 * i] + (n[2 * i + 1] << 8);
9451
- o[15] &= 32767;
9452
- }
9453
- function A(o, a, b) {
9454
- for (var i = 0; i < 16; i++) o[i] = a[i] + b[i];
9455
- }
9456
- function Z(o, a, b) {
9457
- for (var i = 0; i < 16; i++) o[i] = a[i] - b[i];
9458
- }
9459
- function M(o, a, b) {
9460
- var v, c, t0 = 0, t1 = 0, t2 = 0, t3 = 0, t4 = 0, t5 = 0, t6 = 0, t7 = 0, t8 = 0, t9 = 0, t10 = 0, t11 = 0, t12 = 0, t13 = 0, t14 = 0, t15 = 0, t16 = 0, t17 = 0, t18 = 0, t19 = 0, t20 = 0, t21 = 0, t22 = 0, t23 = 0, t24 = 0, t25 = 0, t26 = 0, t27 = 0, t28 = 0, t29 = 0, t30 = 0, b0 = b[0], b1 = b[1], b2 = b[2], b3 = b[3], b4 = b[4], b5 = b[5], b6 = b[6], b7 = b[7], b8 = b[8], b9 = b[9], b10 = b[10], b11 = b[11], b12 = b[12], b13 = b[13], b14 = b[14], b15 = b[15];
9461
- v = a[0];
9462
- t0 += v * b0;
9463
- t1 += v * b1;
9464
- t2 += v * b2;
9465
- t3 += v * b3;
9466
- t4 += v * b4;
9467
- t5 += v * b5;
9468
- t6 += v * b6;
9469
- t7 += v * b7;
9470
- t8 += v * b8;
9471
- t9 += v * b9;
9472
- t10 += v * b10;
9473
- t11 += v * b11;
9474
- t12 += v * b12;
9475
- t13 += v * b13;
9476
- t14 += v * b14;
9477
- t15 += v * b15;
9478
- v = a[1];
9479
- t1 += v * b0;
9480
- t2 += v * b1;
9481
- t3 += v * b2;
9482
- t4 += v * b3;
9483
- t5 += v * b4;
9484
- t6 += v * b5;
9485
- t7 += v * b6;
9486
- t8 += v * b7;
9487
- t9 += v * b8;
9488
- t10 += v * b9;
9489
- t11 += v * b10;
9490
- t12 += v * b11;
9491
- t13 += v * b12;
9492
- t14 += v * b13;
9493
- t15 += v * b14;
9494
- t16 += v * b15;
9495
- v = a[2];
9496
- t2 += v * b0;
9497
- t3 += v * b1;
9498
- t4 += v * b2;
9499
- t5 += v * b3;
9500
- t6 += v * b4;
9501
- t7 += v * b5;
9502
- t8 += v * b6;
9503
- t9 += v * b7;
9504
- t10 += v * b8;
9505
- t11 += v * b9;
9506
- t12 += v * b10;
9507
- t13 += v * b11;
9508
- t14 += v * b12;
9509
- t15 += v * b13;
9510
- t16 += v * b14;
9511
- t17 += v * b15;
9512
- v = a[3];
9513
- t3 += v * b0;
9514
- t4 += v * b1;
9515
- t5 += v * b2;
9516
- t6 += v * b3;
9517
- t7 += v * b4;
9518
- t8 += v * b5;
9519
- t9 += v * b6;
9520
- t10 += v * b7;
9521
- t11 += v * b8;
9522
- t12 += v * b9;
9523
- t13 += v * b10;
9524
- t14 += v * b11;
9525
- t15 += v * b12;
9526
- t16 += v * b13;
9527
- t17 += v * b14;
9528
- t18 += v * b15;
9529
- v = a[4];
9530
- t4 += v * b0;
9531
- t5 += v * b1;
9532
- t6 += v * b2;
9533
- t7 += v * b3;
9534
- t8 += v * b4;
9535
- t9 += v * b5;
9536
- t10 += v * b6;
9537
- t11 += v * b7;
9538
- t12 += v * b8;
9539
- t13 += v * b9;
9540
- t14 += v * b10;
9541
- t15 += v * b11;
9542
- t16 += v * b12;
9543
- t17 += v * b13;
9544
- t18 += v * b14;
9545
- t19 += v * b15;
9546
- v = a[5];
9547
- t5 += v * b0;
9548
- t6 += v * b1;
9549
- t7 += v * b2;
9550
- t8 += v * b3;
9551
- t9 += v * b4;
9552
- t10 += v * b5;
9553
- t11 += v * b6;
9554
- t12 += v * b7;
9555
- t13 += v * b8;
9556
- t14 += v * b9;
9557
- t15 += v * b10;
9558
- t16 += v * b11;
9559
- t17 += v * b12;
9560
- t18 += v * b13;
9561
- t19 += v * b14;
9562
- t20 += v * b15;
9563
- v = a[6];
9564
- t6 += v * b0;
9565
- t7 += v * b1;
9566
- t8 += v * b2;
9567
- t9 += v * b3;
9568
- t10 += v * b4;
9569
- t11 += v * b5;
9570
- t12 += v * b6;
9571
- t13 += v * b7;
9572
- t14 += v * b8;
9573
- t15 += v * b9;
9574
- t16 += v * b10;
9575
- t17 += v * b11;
9576
- t18 += v * b12;
9577
- t19 += v * b13;
9578
- t20 += v * b14;
9579
- t21 += v * b15;
9580
- v = a[7];
9581
- t7 += v * b0;
9582
- t8 += v * b1;
9583
- t9 += v * b2;
9584
- t10 += v * b3;
9585
- t11 += v * b4;
9586
- t12 += v * b5;
9587
- t13 += v * b6;
9588
- t14 += v * b7;
9589
- t15 += v * b8;
9590
- t16 += v * b9;
9591
- t17 += v * b10;
9592
- t18 += v * b11;
9593
- t19 += v * b12;
9594
- t20 += v * b13;
9595
- t21 += v * b14;
9596
- t22 += v * b15;
9597
- v = a[8];
9598
- t8 += v * b0;
9599
- t9 += v * b1;
9600
- t10 += v * b2;
9601
- t11 += v * b3;
9602
- t12 += v * b4;
9603
- t13 += v * b5;
9604
- t14 += v * b6;
9605
- t15 += v * b7;
9606
- t16 += v * b8;
9607
- t17 += v * b9;
9608
- t18 += v * b10;
9609
- t19 += v * b11;
9610
- t20 += v * b12;
9611
- t21 += v * b13;
9612
- t22 += v * b14;
9613
- t23 += v * b15;
9614
- v = a[9];
9615
- t9 += v * b0;
9616
- t10 += v * b1;
9617
- t11 += v * b2;
9618
- t12 += v * b3;
9619
- t13 += v * b4;
9620
- t14 += v * b5;
9621
- t15 += v * b6;
9622
- t16 += v * b7;
9623
- t17 += v * b8;
9624
- t18 += v * b9;
9625
- t19 += v * b10;
9626
- t20 += v * b11;
9627
- t21 += v * b12;
9628
- t22 += v * b13;
9629
- t23 += v * b14;
9630
- t24 += v * b15;
9631
- v = a[10];
9632
- t10 += v * b0;
9633
- t11 += v * b1;
9634
- t12 += v * b2;
9635
- t13 += v * b3;
9636
- t14 += v * b4;
9637
- t15 += v * b5;
9638
- t16 += v * b6;
9639
- t17 += v * b7;
9640
- t18 += v * b8;
9641
- t19 += v * b9;
9642
- t20 += v * b10;
9643
- t21 += v * b11;
9644
- t22 += v * b12;
9645
- t23 += v * b13;
9646
- t24 += v * b14;
9647
- t25 += v * b15;
9648
- v = a[11];
9649
- t11 += v * b0;
9650
- t12 += v * b1;
9651
- t13 += v * b2;
9652
- t14 += v * b3;
9653
- t15 += v * b4;
9654
- t16 += v * b5;
9655
- t17 += v * b6;
9656
- t18 += v * b7;
9657
- t19 += v * b8;
9658
- t20 += v * b9;
9659
- t21 += v * b10;
9660
- t22 += v * b11;
9661
- t23 += v * b12;
9662
- t24 += v * b13;
9663
- t25 += v * b14;
9664
- t26 += v * b15;
9665
- v = a[12];
9666
- t12 += v * b0;
9667
- t13 += v * b1;
9668
- t14 += v * b2;
9669
- t15 += v * b3;
9670
- t16 += v * b4;
9671
- t17 += v * b5;
9672
- t18 += v * b6;
9673
- t19 += v * b7;
9674
- t20 += v * b8;
9675
- t21 += v * b9;
9676
- t22 += v * b10;
9677
- t23 += v * b11;
9678
- t24 += v * b12;
9679
- t25 += v * b13;
9680
- t26 += v * b14;
9681
- t27 += v * b15;
9682
- v = a[13];
9683
- t13 += v * b0;
9684
- t14 += v * b1;
9685
- t15 += v * b2;
9686
- t16 += v * b3;
9687
- t17 += v * b4;
9688
- t18 += v * b5;
9689
- t19 += v * b6;
9690
- t20 += v * b7;
9691
- t21 += v * b8;
9692
- t22 += v * b9;
9693
- t23 += v * b10;
9694
- t24 += v * b11;
9695
- t25 += v * b12;
9696
- t26 += v * b13;
9697
- t27 += v * b14;
9698
- t28 += v * b15;
9699
- v = a[14];
9700
- t14 += v * b0;
9701
- t15 += v * b1;
9702
- t16 += v * b2;
9703
- t17 += v * b3;
9704
- t18 += v * b4;
9705
- t19 += v * b5;
9706
- t20 += v * b6;
9707
- t21 += v * b7;
9708
- t22 += v * b8;
9709
- t23 += v * b9;
9710
- t24 += v * b10;
9711
- t25 += v * b11;
9712
- t26 += v * b12;
9713
- t27 += v * b13;
9714
- t28 += v * b14;
9715
- t29 += v * b15;
9716
- v = a[15];
9717
- t15 += v * b0;
9718
- t16 += v * b1;
9719
- t17 += v * b2;
9720
- t18 += v * b3;
9721
- t19 += v * b4;
9722
- t20 += v * b5;
9723
- t21 += v * b6;
9724
- t22 += v * b7;
9725
- t23 += v * b8;
9726
- t24 += v * b9;
9727
- t25 += v * b10;
9728
- t26 += v * b11;
9729
- t27 += v * b12;
9730
- t28 += v * b13;
9731
- t29 += v * b14;
9732
- t30 += v * b15;
9733
- t0 += 38 * t16;
9734
- t1 += 38 * t17;
9735
- t2 += 38 * t18;
9736
- t3 += 38 * t19;
9737
- t4 += 38 * t20;
9738
- t5 += 38 * t21;
9739
- t6 += 38 * t22;
9740
- t7 += 38 * t23;
9741
- t8 += 38 * t24;
9742
- t9 += 38 * t25;
9743
- t10 += 38 * t26;
9744
- t11 += 38 * t27;
9745
- t12 += 38 * t28;
9746
- t13 += 38 * t29;
9747
- t14 += 38 * t30;
9748
- c = 1;
9749
- v = t0 + c + 65535;
9750
- c = Math.floor(v / 65536);
9751
- t0 = v - c * 65536;
9752
- v = t1 + c + 65535;
9753
- c = Math.floor(v / 65536);
9754
- t1 = v - c * 65536;
9755
- v = t2 + c + 65535;
9756
- c = Math.floor(v / 65536);
9757
- t2 = v - c * 65536;
9758
- v = t3 + c + 65535;
9759
- c = Math.floor(v / 65536);
9760
- t3 = v - c * 65536;
9761
- v = t4 + c + 65535;
9762
- c = Math.floor(v / 65536);
9763
- t4 = v - c * 65536;
9764
- v = t5 + c + 65535;
9765
- c = Math.floor(v / 65536);
9766
- t5 = v - c * 65536;
9767
- v = t6 + c + 65535;
9768
- c = Math.floor(v / 65536);
9769
- t6 = v - c * 65536;
9770
- v = t7 + c + 65535;
9771
- c = Math.floor(v / 65536);
9772
- t7 = v - c * 65536;
9773
- v = t8 + c + 65535;
9774
- c = Math.floor(v / 65536);
9775
- t8 = v - c * 65536;
9776
- v = t9 + c + 65535;
9777
- c = Math.floor(v / 65536);
9778
- t9 = v - c * 65536;
9779
- v = t10 + c + 65535;
9780
- c = Math.floor(v / 65536);
9781
- t10 = v - c * 65536;
9782
- v = t11 + c + 65535;
9783
- c = Math.floor(v / 65536);
9784
- t11 = v - c * 65536;
9785
- v = t12 + c + 65535;
9786
- c = Math.floor(v / 65536);
9787
- t12 = v - c * 65536;
9788
- v = t13 + c + 65535;
9789
- c = Math.floor(v / 65536);
9790
- t13 = v - c * 65536;
9791
- v = t14 + c + 65535;
9792
- c = Math.floor(v / 65536);
9793
- t14 = v - c * 65536;
9794
- v = t15 + c + 65535;
9795
- c = Math.floor(v / 65536);
9796
- t15 = v - c * 65536;
9797
- t0 += c - 1 + 37 * (c - 1);
9798
- c = 1;
9799
- v = t0 + c + 65535;
9800
- c = Math.floor(v / 65536);
9801
- t0 = v - c * 65536;
9802
- v = t1 + c + 65535;
9803
- c = Math.floor(v / 65536);
9804
- t1 = v - c * 65536;
9805
- v = t2 + c + 65535;
9806
- c = Math.floor(v / 65536);
9807
- t2 = v - c * 65536;
9808
- v = t3 + c + 65535;
9809
- c = Math.floor(v / 65536);
9810
- t3 = v - c * 65536;
9811
- v = t4 + c + 65535;
9812
- c = Math.floor(v / 65536);
9813
- t4 = v - c * 65536;
9814
- v = t5 + c + 65535;
9815
- c = Math.floor(v / 65536);
9816
- t5 = v - c * 65536;
9817
- v = t6 + c + 65535;
9818
- c = Math.floor(v / 65536);
9819
- t6 = v - c * 65536;
9820
- v = t7 + c + 65535;
9821
- c = Math.floor(v / 65536);
9822
- t7 = v - c * 65536;
9823
- v = t8 + c + 65535;
9824
- c = Math.floor(v / 65536);
9825
- t8 = v - c * 65536;
9826
- v = t9 + c + 65535;
9827
- c = Math.floor(v / 65536);
9828
- t9 = v - c * 65536;
9829
- v = t10 + c + 65535;
9830
- c = Math.floor(v / 65536);
9831
- t10 = v - c * 65536;
9832
- v = t11 + c + 65535;
9833
- c = Math.floor(v / 65536);
9834
- t11 = v - c * 65536;
9835
- v = t12 + c + 65535;
9836
- c = Math.floor(v / 65536);
9837
- t12 = v - c * 65536;
9838
- v = t13 + c + 65535;
9839
- c = Math.floor(v / 65536);
9840
- t13 = v - c * 65536;
9841
- v = t14 + c + 65535;
9842
- c = Math.floor(v / 65536);
9843
- t14 = v - c * 65536;
9844
- v = t15 + c + 65535;
9845
- c = Math.floor(v / 65536);
9846
- t15 = v - c * 65536;
9847
- t0 += c - 1 + 37 * (c - 1);
9848
- o[0] = t0;
9849
- o[1] = t1;
9850
- o[2] = t2;
9851
- o[3] = t3;
9852
- o[4] = t4;
9853
- o[5] = t5;
9854
- o[6] = t6;
9855
- o[7] = t7;
9856
- o[8] = t8;
9857
- o[9] = t9;
9858
- o[10] = t10;
9859
- o[11] = t11;
9860
- o[12] = t12;
9861
- o[13] = t13;
9862
- o[14] = t14;
9863
- o[15] = t15;
9864
- }
9865
- function S(o, a) {
9866
- M(o, a, a);
9867
- }
9868
- function inv25519(o, i) {
9869
- var c = gf();
9870
- var a;
9871
- for (a = 0; a < 16; a++) c[a] = i[a];
9872
- for (a = 253; a >= 0; a--) {
9873
- S(c, c);
9874
- if (a !== 2 && a !== 4) M(c, c, i);
9875
- }
9876
- for (a = 0; a < 16; a++) o[a] = c[a];
9877
- }
9878
- function pow2523(o, i) {
9879
- var c = gf();
9880
- var a;
9881
- for (a = 0; a < 16; a++) c[a] = i[a];
9882
- for (a = 250; a >= 0; a--) {
9883
- S(c, c);
9884
- if (a !== 1) M(c, c, i);
9885
- }
9886
- for (a = 0; a < 16; a++) o[a] = c[a];
9887
- }
9888
- function crypto_scalarmult(q, n, p) {
9889
- var z4 = new Uint8Array(32);
9890
- var x = new Float64Array(80), r, i;
9891
- var a = gf(), b = gf(), c = gf(), d = gf(), e = gf(), f = gf();
9892
- for (i = 0; i < 31; i++) z4[i] = n[i];
9893
- z4[31] = n[31] & 127 | 64;
9894
- z4[0] &= 248;
9895
- unpack25519(x, p);
9896
- for (i = 0; i < 16; i++) {
9897
- b[i] = x[i];
9898
- d[i] = a[i] = c[i] = 0;
9899
- }
9900
- a[0] = d[0] = 1;
9901
- for (i = 254; i >= 0; --i) {
9902
- r = z4[i >>> 3] >>> (i & 7) & 1;
9903
- sel25519(a, b, r);
9904
- sel25519(c, d, r);
9905
- A(e, a, c);
9906
- Z(a, a, c);
9907
- A(c, b, d);
9908
- Z(b, b, d);
9909
- S(d, e);
9910
- S(f, a);
9911
- M(a, c, a);
9912
- M(c, b, e);
9913
- A(e, a, c);
9914
- Z(a, a, c);
9915
- S(b, a);
9916
- Z(c, d, f);
9917
- M(a, c, _121665);
9918
- A(a, a, d);
9919
- M(c, c, a);
9920
- M(a, d, f);
9921
- M(d, b, x);
9922
- S(b, e);
9923
- sel25519(a, b, r);
9924
- sel25519(c, d, r);
9925
- }
9926
- for (i = 0; i < 16; i++) {
9927
- x[i + 16] = a[i];
9928
- x[i + 32] = c[i];
9929
- x[i + 48] = b[i];
9930
- x[i + 64] = d[i];
9931
- }
9932
- var x32 = x.subarray(32);
9933
- var x16 = x.subarray(16);
9934
- inv25519(x32, x32);
9935
- M(x16, x16, x32);
9936
- pack25519(q, x16);
9937
- return 0;
9938
- }
9939
- function crypto_scalarmult_base(q, n) {
9940
- return crypto_scalarmult(q, n, _9);
9941
- }
9942
- function crypto_box_keypair(y, x) {
9943
- randombytes(x, 32);
9944
- return crypto_scalarmult_base(y, x);
9945
- }
9946
- function crypto_box_beforenm(k, y, x) {
9947
- var s = new Uint8Array(32);
9948
- crypto_scalarmult(s, x, y);
9949
- return crypto_core_hsalsa20(k, _0, s, sigma);
9950
- }
9951
- var crypto_box_afternm = crypto_secretbox;
9952
- var crypto_box_open_afternm = crypto_secretbox_open;
9953
- function crypto_box(c, m, d, n, y, x) {
9954
- var k = new Uint8Array(32);
9955
- crypto_box_beforenm(k, y, x);
9956
- return crypto_box_afternm(c, m, d, n, k);
9957
- }
9958
- function crypto_box_open(m, c, d, n, y, x) {
9959
- var k = new Uint8Array(32);
9960
- crypto_box_beforenm(k, y, x);
9961
- return crypto_box_open_afternm(m, c, d, n, k);
9962
- }
9963
- var K = [
9964
- 1116352408,
9965
- 3609767458,
9966
- 1899447441,
9967
- 602891725,
9968
- 3049323471,
9969
- 3964484399,
9970
- 3921009573,
9971
- 2173295548,
9972
- 961987163,
9973
- 4081628472,
9974
- 1508970993,
9975
- 3053834265,
9976
- 2453635748,
9977
- 2937671579,
9978
- 2870763221,
9979
- 3664609560,
9980
- 3624381080,
9981
- 2734883394,
9982
- 310598401,
9983
- 1164996542,
9984
- 607225278,
9985
- 1323610764,
9986
- 1426881987,
9987
- 3590304994,
9988
- 1925078388,
9989
- 4068182383,
9990
- 2162078206,
9991
- 991336113,
9992
- 2614888103,
9993
- 633803317,
9994
- 3248222580,
9995
- 3479774868,
9996
- 3835390401,
9997
- 2666613458,
9998
- 4022224774,
9999
- 944711139,
10000
- 264347078,
10001
- 2341262773,
10002
- 604807628,
10003
- 2007800933,
10004
- 770255983,
10005
- 1495990901,
10006
- 1249150122,
10007
- 1856431235,
10008
- 1555081692,
10009
- 3175218132,
10010
- 1996064986,
10011
- 2198950837,
10012
- 2554220882,
10013
- 3999719339,
10014
- 2821834349,
10015
- 766784016,
10016
- 2952996808,
10017
- 2566594879,
10018
- 3210313671,
10019
- 3203337956,
10020
- 3336571891,
10021
- 1034457026,
10022
- 3584528711,
10023
- 2466948901,
10024
- 113926993,
10025
- 3758326383,
10026
- 338241895,
10027
- 168717936,
10028
- 666307205,
10029
- 1188179964,
10030
- 773529912,
10031
- 1546045734,
10032
- 1294757372,
10033
- 1522805485,
10034
- 1396182291,
10035
- 2643833823,
10036
- 1695183700,
10037
- 2343527390,
10038
- 1986661051,
10039
- 1014477480,
10040
- 2177026350,
10041
- 1206759142,
10042
- 2456956037,
10043
- 344077627,
10044
- 2730485921,
10045
- 1290863460,
10046
- 2820302411,
10047
- 3158454273,
10048
- 3259730800,
10049
- 3505952657,
10050
- 3345764771,
10051
- 106217008,
10052
- 3516065817,
10053
- 3606008344,
10054
- 3600352804,
10055
- 1432725776,
10056
- 4094571909,
10057
- 1467031594,
10058
- 275423344,
10059
- 851169720,
10060
- 430227734,
10061
- 3100823752,
10062
- 506948616,
10063
- 1363258195,
10064
- 659060556,
10065
- 3750685593,
10066
- 883997877,
10067
- 3785050280,
10068
- 958139571,
10069
- 3318307427,
10070
- 1322822218,
10071
- 3812723403,
10072
- 1537002063,
10073
- 2003034995,
10074
- 1747873779,
10075
- 3602036899,
10076
- 1955562222,
10077
- 1575990012,
10078
- 2024104815,
10079
- 1125592928,
10080
- 2227730452,
10081
- 2716904306,
10082
- 2361852424,
10083
- 442776044,
10084
- 2428436474,
10085
- 593698344,
10086
- 2756734187,
10087
- 3733110249,
10088
- 3204031479,
10089
- 2999351573,
10090
- 3329325298,
10091
- 3815920427,
10092
- 3391569614,
10093
- 3928383900,
10094
- 3515267271,
10095
- 566280711,
10096
- 3940187606,
10097
- 3454069534,
10098
- 4118630271,
10099
- 4000239992,
10100
- 116418474,
10101
- 1914138554,
10102
- 174292421,
10103
- 2731055270,
10104
- 289380356,
10105
- 3203993006,
10106
- 460393269,
10107
- 320620315,
10108
- 685471733,
10109
- 587496836,
10110
- 852142971,
10111
- 1086792851,
10112
- 1017036298,
10113
- 365543100,
10114
- 1126000580,
10115
- 2618297676,
10116
- 1288033470,
10117
- 3409855158,
10118
- 1501505948,
10119
- 4234509866,
10120
- 1607167915,
10121
- 987167468,
10122
- 1816402316,
10123
- 1246189591
10124
- ];
10125
- function crypto_hashblocks_hl(hh, hl, m, n) {
10126
- var wh = new Int32Array(16), wl = new Int32Array(16), bh0, bh1, bh2, bh3, bh4, bh5, bh6, bh7, bl0, bl1, bl2, bl3, bl4, bl5, bl6, bl7, th, tl, i, j, h, l, a, b, c, d;
10127
- var ah0 = hh[0], ah1 = hh[1], ah2 = hh[2], ah3 = hh[3], ah4 = hh[4], ah5 = hh[5], ah6 = hh[6], ah7 = hh[7], al0 = hl[0], al1 = hl[1], al2 = hl[2], al3 = hl[3], al4 = hl[4], al5 = hl[5], al6 = hl[6], al7 = hl[7];
10128
- var pos = 0;
10129
- while (n >= 128) {
10130
- for (i = 0; i < 16; i++) {
10131
- j = 8 * i + pos;
10132
- wh[i] = m[j + 0] << 24 | m[j + 1] << 16 | m[j + 2] << 8 | m[j + 3];
10133
- wl[i] = m[j + 4] << 24 | m[j + 5] << 16 | m[j + 6] << 8 | m[j + 7];
10134
- }
10135
- for (i = 0; i < 80; i++) {
10136
- bh0 = ah0;
10137
- bh1 = ah1;
10138
- bh2 = ah2;
10139
- bh3 = ah3;
10140
- bh4 = ah4;
10141
- bh5 = ah5;
10142
- bh6 = ah6;
10143
- bh7 = ah7;
10144
- bl0 = al0;
10145
- bl1 = al1;
10146
- bl2 = al2;
10147
- bl3 = al3;
10148
- bl4 = al4;
10149
- bl5 = al5;
10150
- bl6 = al6;
10151
- bl7 = al7;
10152
- h = ah7;
10153
- l = al7;
10154
- a = l & 65535;
10155
- b = l >>> 16;
10156
- c = h & 65535;
10157
- d = h >>> 16;
10158
- h = (ah4 >>> 14 | al4 << 32 - 14) ^ (ah4 >>> 18 | al4 << 32 - 18) ^ (al4 >>> 41 - 32 | ah4 << 32 - (41 - 32));
10159
- l = (al4 >>> 14 | ah4 << 32 - 14) ^ (al4 >>> 18 | ah4 << 32 - 18) ^ (ah4 >>> 41 - 32 | al4 << 32 - (41 - 32));
10160
- a += l & 65535;
10161
- b += l >>> 16;
10162
- c += h & 65535;
10163
- d += h >>> 16;
10164
- h = ah4 & ah5 ^ ~ah4 & ah6;
10165
- l = al4 & al5 ^ ~al4 & al6;
10166
- a += l & 65535;
10167
- b += l >>> 16;
10168
- c += h & 65535;
10169
- d += h >>> 16;
10170
- h = K[i * 2];
10171
- l = K[i * 2 + 1];
10172
- a += l & 65535;
10173
- b += l >>> 16;
10174
- c += h & 65535;
10175
- d += h >>> 16;
10176
- h = wh[i % 16];
10177
- l = wl[i % 16];
10178
- a += l & 65535;
10179
- b += l >>> 16;
10180
- c += h & 65535;
10181
- d += h >>> 16;
10182
- b += a >>> 16;
10183
- c += b >>> 16;
10184
- d += c >>> 16;
10185
- th = c & 65535 | d << 16;
10186
- tl = a & 65535 | b << 16;
10187
- h = th;
10188
- l = tl;
10189
- a = l & 65535;
10190
- b = l >>> 16;
10191
- c = h & 65535;
10192
- d = h >>> 16;
10193
- h = (ah0 >>> 28 | al0 << 32 - 28) ^ (al0 >>> 34 - 32 | ah0 << 32 - (34 - 32)) ^ (al0 >>> 39 - 32 | ah0 << 32 - (39 - 32));
10194
- l = (al0 >>> 28 | ah0 << 32 - 28) ^ (ah0 >>> 34 - 32 | al0 << 32 - (34 - 32)) ^ (ah0 >>> 39 - 32 | al0 << 32 - (39 - 32));
10195
- a += l & 65535;
10196
- b += l >>> 16;
10197
- c += h & 65535;
10198
- d += h >>> 16;
10199
- h = ah0 & ah1 ^ ah0 & ah2 ^ ah1 & ah2;
10200
- l = al0 & al1 ^ al0 & al2 ^ al1 & al2;
10201
- a += l & 65535;
10202
- b += l >>> 16;
10203
- c += h & 65535;
10204
- d += h >>> 16;
10205
- b += a >>> 16;
10206
- c += b >>> 16;
10207
- d += c >>> 16;
10208
- bh7 = c & 65535 | d << 16;
10209
- bl7 = a & 65535 | b << 16;
10210
- h = bh3;
10211
- l = bl3;
10212
- a = l & 65535;
10213
- b = l >>> 16;
10214
- c = h & 65535;
10215
- d = h >>> 16;
10216
- h = th;
10217
- l = tl;
10218
- a += l & 65535;
10219
- b += l >>> 16;
10220
- c += h & 65535;
10221
- d += h >>> 16;
10222
- b += a >>> 16;
10223
- c += b >>> 16;
10224
- d += c >>> 16;
10225
- bh3 = c & 65535 | d << 16;
10226
- bl3 = a & 65535 | b << 16;
10227
- ah1 = bh0;
10228
- ah2 = bh1;
10229
- ah3 = bh2;
10230
- ah4 = bh3;
10231
- ah5 = bh4;
10232
- ah6 = bh5;
10233
- ah7 = bh6;
10234
- ah0 = bh7;
10235
- al1 = bl0;
10236
- al2 = bl1;
10237
- al3 = bl2;
10238
- al4 = bl3;
10239
- al5 = bl4;
10240
- al6 = bl5;
10241
- al7 = bl6;
10242
- al0 = bl7;
10243
- if (i % 16 === 15) {
10244
- for (j = 0; j < 16; j++) {
10245
- h = wh[j];
10246
- l = wl[j];
10247
- a = l & 65535;
10248
- b = l >>> 16;
10249
- c = h & 65535;
10250
- d = h >>> 16;
10251
- h = wh[(j + 9) % 16];
10252
- l = wl[(j + 9) % 16];
10253
- a += l & 65535;
10254
- b += l >>> 16;
10255
- c += h & 65535;
10256
- d += h >>> 16;
10257
- th = wh[(j + 1) % 16];
10258
- tl = wl[(j + 1) % 16];
10259
- h = (th >>> 1 | tl << 32 - 1) ^ (th >>> 8 | tl << 32 - 8) ^ th >>> 7;
10260
- l = (tl >>> 1 | th << 32 - 1) ^ (tl >>> 8 | th << 32 - 8) ^ (tl >>> 7 | th << 32 - 7);
10261
- a += l & 65535;
10262
- b += l >>> 16;
10263
- c += h & 65535;
10264
- d += h >>> 16;
10265
- th = wh[(j + 14) % 16];
10266
- tl = wl[(j + 14) % 16];
10267
- h = (th >>> 19 | tl << 32 - 19) ^ (tl >>> 61 - 32 | th << 32 - (61 - 32)) ^ th >>> 6;
10268
- l = (tl >>> 19 | th << 32 - 19) ^ (th >>> 61 - 32 | tl << 32 - (61 - 32)) ^ (tl >>> 6 | th << 32 - 6);
10269
- a += l & 65535;
10270
- b += l >>> 16;
10271
- c += h & 65535;
10272
- d += h >>> 16;
10273
- b += a >>> 16;
10274
- c += b >>> 16;
10275
- d += c >>> 16;
10276
- wh[j] = c & 65535 | d << 16;
10277
- wl[j] = a & 65535 | b << 16;
10278
- }
10279
- }
10280
- }
10281
- h = ah0;
10282
- l = al0;
10283
- a = l & 65535;
10284
- b = l >>> 16;
10285
- c = h & 65535;
10286
- d = h >>> 16;
10287
- h = hh[0];
10288
- l = hl[0];
10289
- a += l & 65535;
10290
- b += l >>> 16;
10291
- c += h & 65535;
10292
- d += h >>> 16;
10293
- b += a >>> 16;
10294
- c += b >>> 16;
10295
- d += c >>> 16;
10296
- hh[0] = ah0 = c & 65535 | d << 16;
10297
- hl[0] = al0 = a & 65535 | b << 16;
10298
- h = ah1;
10299
- l = al1;
10300
- a = l & 65535;
10301
- b = l >>> 16;
10302
- c = h & 65535;
10303
- d = h >>> 16;
10304
- h = hh[1];
10305
- l = hl[1];
10306
- a += l & 65535;
10307
- b += l >>> 16;
10308
- c += h & 65535;
10309
- d += h >>> 16;
10310
- b += a >>> 16;
10311
- c += b >>> 16;
10312
- d += c >>> 16;
10313
- hh[1] = ah1 = c & 65535 | d << 16;
10314
- hl[1] = al1 = a & 65535 | b << 16;
10315
- h = ah2;
10316
- l = al2;
10317
- a = l & 65535;
10318
- b = l >>> 16;
10319
- c = h & 65535;
10320
- d = h >>> 16;
10321
- h = hh[2];
10322
- l = hl[2];
10323
- a += l & 65535;
10324
- b += l >>> 16;
10325
- c += h & 65535;
10326
- d += h >>> 16;
10327
- b += a >>> 16;
10328
- c += b >>> 16;
10329
- d += c >>> 16;
10330
- hh[2] = ah2 = c & 65535 | d << 16;
10331
- hl[2] = al2 = a & 65535 | b << 16;
10332
- h = ah3;
10333
- l = al3;
10334
- a = l & 65535;
10335
- b = l >>> 16;
10336
- c = h & 65535;
10337
- d = h >>> 16;
10338
- h = hh[3];
10339
- l = hl[3];
10340
- a += l & 65535;
10341
- b += l >>> 16;
10342
- c += h & 65535;
10343
- d += h >>> 16;
10344
- b += a >>> 16;
10345
- c += b >>> 16;
10346
- d += c >>> 16;
10347
- hh[3] = ah3 = c & 65535 | d << 16;
10348
- hl[3] = al3 = a & 65535 | b << 16;
10349
- h = ah4;
10350
- l = al4;
10351
- a = l & 65535;
10352
- b = l >>> 16;
10353
- c = h & 65535;
10354
- d = h >>> 16;
10355
- h = hh[4];
10356
- l = hl[4];
10357
- a += l & 65535;
10358
- b += l >>> 16;
10359
- c += h & 65535;
10360
- d += h >>> 16;
10361
- b += a >>> 16;
10362
- c += b >>> 16;
10363
- d += c >>> 16;
10364
- hh[4] = ah4 = c & 65535 | d << 16;
10365
- hl[4] = al4 = a & 65535 | b << 16;
10366
- h = ah5;
10367
- l = al5;
10368
- a = l & 65535;
10369
- b = l >>> 16;
10370
- c = h & 65535;
10371
- d = h >>> 16;
10372
- h = hh[5];
10373
- l = hl[5];
10374
- a += l & 65535;
10375
- b += l >>> 16;
10376
- c += h & 65535;
10377
- d += h >>> 16;
10378
- b += a >>> 16;
10379
- c += b >>> 16;
10380
- d += c >>> 16;
10381
- hh[5] = ah5 = c & 65535 | d << 16;
10382
- hl[5] = al5 = a & 65535 | b << 16;
10383
- h = ah6;
10384
- l = al6;
10385
- a = l & 65535;
10386
- b = l >>> 16;
10387
- c = h & 65535;
10388
- d = h >>> 16;
10389
- h = hh[6];
10390
- l = hl[6];
10391
- a += l & 65535;
10392
- b += l >>> 16;
10393
- c += h & 65535;
10394
- d += h >>> 16;
10395
- b += a >>> 16;
10396
- c += b >>> 16;
10397
- d += c >>> 16;
10398
- hh[6] = ah6 = c & 65535 | d << 16;
10399
- hl[6] = al6 = a & 65535 | b << 16;
10400
- h = ah7;
10401
- l = al7;
10402
- a = l & 65535;
10403
- b = l >>> 16;
10404
- c = h & 65535;
10405
- d = h >>> 16;
10406
- h = hh[7];
10407
- l = hl[7];
10408
- a += l & 65535;
10409
- b += l >>> 16;
10410
- c += h & 65535;
10411
- d += h >>> 16;
10412
- b += a >>> 16;
10413
- c += b >>> 16;
10414
- d += c >>> 16;
10415
- hh[7] = ah7 = c & 65535 | d << 16;
10416
- hl[7] = al7 = a & 65535 | b << 16;
10417
- pos += 128;
10418
- n -= 128;
10419
- }
10420
- return n;
10421
- }
10422
- function crypto_hash(out, m, n) {
10423
- var hh = new Int32Array(8), hl = new Int32Array(8), x = new Uint8Array(256), i, b = n;
10424
- hh[0] = 1779033703;
10425
- hh[1] = 3144134277;
10426
- hh[2] = 1013904242;
10427
- hh[3] = 2773480762;
10428
- hh[4] = 1359893119;
10429
- hh[5] = 2600822924;
10430
- hh[6] = 528734635;
10431
- hh[7] = 1541459225;
10432
- hl[0] = 4089235720;
10433
- hl[1] = 2227873595;
10434
- hl[2] = 4271175723;
10435
- hl[3] = 1595750129;
10436
- hl[4] = 2917565137;
10437
- hl[5] = 725511199;
10438
- hl[6] = 4215389547;
10439
- hl[7] = 327033209;
10440
- crypto_hashblocks_hl(hh, hl, m, n);
10441
- n %= 128;
10442
- for (i = 0; i < n; i++) x[i] = m[b - n + i];
10443
- x[n] = 128;
10444
- n = 256 - 128 * (n < 112 ? 1 : 0);
10445
- x[n - 9] = 0;
10446
- ts64(x, n - 8, b / 536870912 | 0, b << 3);
10447
- crypto_hashblocks_hl(hh, hl, x, n);
10448
- for (i = 0; i < 8; i++) ts64(out, 8 * i, hh[i], hl[i]);
10449
- return 0;
10450
- }
10451
- function add(p, q) {
10452
- var a = gf(), b = gf(), c = gf(), d = gf(), e = gf(), f = gf(), g = gf(), h = gf(), t = gf();
10453
- Z(a, p[1], p[0]);
10454
- Z(t, q[1], q[0]);
10455
- M(a, a, t);
10456
- A(b, p[0], p[1]);
10457
- A(t, q[0], q[1]);
10458
- M(b, b, t);
10459
- M(c, p[3], q[3]);
10460
- M(c, c, D2);
10461
- M(d, p[2], q[2]);
10462
- A(d, d, d);
10463
- Z(e, b, a);
10464
- Z(f, d, c);
10465
- A(g, d, c);
10466
- A(h, b, a);
10467
- M(p[0], e, f);
10468
- M(p[1], h, g);
10469
- M(p[2], g, f);
10470
- M(p[3], e, h);
10471
- }
10472
- function cswap(p, q, b) {
10473
- var i;
10474
- for (i = 0; i < 4; i++) {
10475
- sel25519(p[i], q[i], b);
10476
- }
10477
- }
10478
- function pack(r, p) {
10479
- var tx = gf(), ty = gf(), zi = gf();
10480
- inv25519(zi, p[2]);
10481
- M(tx, p[0], zi);
10482
- M(ty, p[1], zi);
10483
- pack25519(r, ty);
10484
- r[31] ^= par25519(tx) << 7;
10485
- }
10486
- function scalarmult(p, q, s) {
10487
- var b, i;
10488
- set25519(p[0], gf0);
10489
- set25519(p[1], gf1);
10490
- set25519(p[2], gf1);
10491
- set25519(p[3], gf0);
10492
- for (i = 255; i >= 0; --i) {
10493
- b = s[i / 8 | 0] >> (i & 7) & 1;
10494
- cswap(p, q, b);
10495
- add(q, p);
10496
- add(p, p);
10497
- cswap(p, q, b);
10498
- }
10499
- }
10500
- function scalarbase(p, s) {
10501
- var q = [gf(), gf(), gf(), gf()];
10502
- set25519(q[0], X);
10503
- set25519(q[1], Y);
10504
- set25519(q[2], gf1);
10505
- M(q[3], X, Y);
10506
- scalarmult(p, q, s);
10507
- }
10508
- function crypto_sign_keypair(pk, sk, seeded) {
10509
- var d = new Uint8Array(64);
10510
- var p = [gf(), gf(), gf(), gf()];
10511
- var i;
10512
- if (!seeded) randombytes(sk, 32);
10513
- crypto_hash(d, sk, 32);
10514
- d[0] &= 248;
10515
- d[31] &= 127;
10516
- d[31] |= 64;
10517
- scalarbase(p, d);
10518
- pack(pk, p);
10519
- for (i = 0; i < 32; i++) sk[i + 32] = pk[i];
10520
- return 0;
10521
- }
10522
- var L = new Float64Array([237, 211, 245, 92, 26, 99, 18, 88, 214, 156, 247, 162, 222, 249, 222, 20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16]);
10523
- function modL(r, x) {
10524
- var carry, i, j, k;
10525
- for (i = 63; i >= 32; --i) {
10526
- carry = 0;
10527
- for (j = i - 32, k = i - 12; j < k; ++j) {
10528
- x[j] += carry - 16 * x[i] * L[j - (i - 32)];
10529
- carry = Math.floor((x[j] + 128) / 256);
10530
- x[j] -= carry * 256;
10531
- }
10532
- x[j] += carry;
10533
- x[i] = 0;
10534
- }
10535
- carry = 0;
10536
- for (j = 0; j < 32; j++) {
10537
- x[j] += carry - (x[31] >> 4) * L[j];
10538
- carry = x[j] >> 8;
10539
- x[j] &= 255;
10540
- }
10541
- for (j = 0; j < 32; j++) x[j] -= carry * L[j];
10542
- for (i = 0; i < 32; i++) {
10543
- x[i + 1] += x[i] >> 8;
10544
- r[i] = x[i] & 255;
10545
- }
10546
- }
10547
- function reduce(r) {
10548
- var x = new Float64Array(64), i;
10549
- for (i = 0; i < 64; i++) x[i] = r[i];
10550
- for (i = 0; i < 64; i++) r[i] = 0;
10551
- modL(r, x);
10552
- }
10553
- function crypto_sign(sm, m, n, sk) {
10554
- var d = new Uint8Array(64), h = new Uint8Array(64), r = new Uint8Array(64);
10555
- var i, j, x = new Float64Array(64);
10556
- var p = [gf(), gf(), gf(), gf()];
10557
- crypto_hash(d, sk, 32);
10558
- d[0] &= 248;
10559
- d[31] &= 127;
10560
- d[31] |= 64;
10561
- var smlen = n + 64;
10562
- for (i = 0; i < n; i++) sm[64 + i] = m[i];
10563
- for (i = 0; i < 32; i++) sm[32 + i] = d[32 + i];
10564
- crypto_hash(r, sm.subarray(32), n + 32);
10565
- reduce(r);
10566
- scalarbase(p, r);
10567
- pack(sm, p);
10568
- for (i = 32; i < 64; i++) sm[i] = sk[i];
10569
- crypto_hash(h, sm, n + 64);
10570
- reduce(h);
10571
- for (i = 0; i < 64; i++) x[i] = 0;
10572
- for (i = 0; i < 32; i++) x[i] = r[i];
10573
- for (i = 0; i < 32; i++) {
10574
- for (j = 0; j < 32; j++) {
10575
- x[i + j] += h[i] * d[j];
10576
- }
10577
- }
10578
- modL(sm.subarray(32), x);
10579
- return smlen;
10580
- }
10581
- function unpackneg(r, p) {
10582
- var t = gf(), chk = gf(), num = gf(), den = gf(), den2 = gf(), den4 = gf(), den6 = gf();
10583
- set25519(r[2], gf1);
10584
- unpack25519(r[1], p);
10585
- S(num, r[1]);
10586
- M(den, num, D);
10587
- Z(num, num, r[2]);
10588
- A(den, r[2], den);
10589
- S(den2, den);
10590
- S(den4, den2);
10591
- M(den6, den4, den2);
10592
- M(t, den6, num);
10593
- M(t, t, den);
10594
- pow2523(t, t);
10595
- M(t, t, num);
10596
- M(t, t, den);
10597
- M(t, t, den);
10598
- M(r[0], t, den);
10599
- S(chk, r[0]);
10600
- M(chk, chk, den);
10601
- if (neq25519(chk, num)) M(r[0], r[0], I);
10602
- S(chk, r[0]);
10603
- M(chk, chk, den);
10604
- if (neq25519(chk, num)) return -1;
10605
- if (par25519(r[0]) === p[31] >> 7) Z(r[0], gf0, r[0]);
10606
- M(r[3], r[0], r[1]);
10607
- return 0;
10608
- }
10609
- function crypto_sign_open(m, sm, n, pk) {
10610
- var i;
10611
- var t = new Uint8Array(32), h = new Uint8Array(64);
10612
- var p = [gf(), gf(), gf(), gf()], q = [gf(), gf(), gf(), gf()];
10613
- if (n < 64) return -1;
10614
- if (unpackneg(q, pk)) return -1;
10615
- for (i = 0; i < n; i++) m[i] = sm[i];
10616
- for (i = 0; i < 32; i++) m[i + 32] = pk[i];
10617
- crypto_hash(h, m, n);
10618
- reduce(h);
10619
- scalarmult(p, q, h);
10620
- scalarbase(q, sm.subarray(32));
10621
- add(p, q);
10622
- pack(t, p);
10623
- n -= 64;
10624
- if (crypto_verify_32(sm, 0, t, 0)) {
10625
- for (i = 0; i < n; i++) m[i] = 0;
10626
- return -1;
10627
- }
10628
- for (i = 0; i < n; i++) m[i] = sm[i + 64];
10629
- return n;
10630
- }
10631
- var crypto_secretbox_KEYBYTES = 32, crypto_secretbox_NONCEBYTES = 24, crypto_secretbox_ZEROBYTES = 32, crypto_secretbox_BOXZEROBYTES = 16, crypto_scalarmult_BYTES = 32, crypto_scalarmult_SCALARBYTES = 32, crypto_box_PUBLICKEYBYTES = 32, crypto_box_SECRETKEYBYTES = 32, crypto_box_BEFORENMBYTES = 32, crypto_box_NONCEBYTES = crypto_secretbox_NONCEBYTES, crypto_box_ZEROBYTES = crypto_secretbox_ZEROBYTES, crypto_box_BOXZEROBYTES = crypto_secretbox_BOXZEROBYTES, crypto_sign_BYTES = 64, crypto_sign_PUBLICKEYBYTES = 32, crypto_sign_SECRETKEYBYTES = 64, crypto_sign_SEEDBYTES = 32, crypto_hash_BYTES = 64;
10632
- nacl6.lowlevel = {
10633
- crypto_core_hsalsa20,
10634
- crypto_stream_xor,
10635
- crypto_stream,
10636
- crypto_stream_salsa20_xor,
10637
- crypto_stream_salsa20,
10638
- crypto_onetimeauth,
10639
- crypto_onetimeauth_verify,
10640
- crypto_verify_16,
10641
- crypto_verify_32,
10642
- crypto_secretbox,
10643
- crypto_secretbox_open,
10644
- crypto_scalarmult,
10645
- crypto_scalarmult_base,
10646
- crypto_box_beforenm,
10647
- crypto_box_afternm,
10648
- crypto_box,
10649
- crypto_box_open,
10650
- crypto_box_keypair,
10651
- crypto_hash,
10652
- crypto_sign,
10653
- crypto_sign_keypair,
10654
- crypto_sign_open,
10655
- crypto_secretbox_KEYBYTES,
10656
- crypto_secretbox_NONCEBYTES,
10657
- crypto_secretbox_ZEROBYTES,
10658
- crypto_secretbox_BOXZEROBYTES,
10659
- crypto_scalarmult_BYTES,
10660
- crypto_scalarmult_SCALARBYTES,
10661
- crypto_box_PUBLICKEYBYTES,
10662
- crypto_box_SECRETKEYBYTES,
10663
- crypto_box_BEFORENMBYTES,
10664
- crypto_box_NONCEBYTES,
10665
- crypto_box_ZEROBYTES,
10666
- crypto_box_BOXZEROBYTES,
10667
- crypto_sign_BYTES,
10668
- crypto_sign_PUBLICKEYBYTES,
10669
- crypto_sign_SECRETKEYBYTES,
10670
- crypto_sign_SEEDBYTES,
10671
- crypto_hash_BYTES,
10672
- gf,
10673
- D,
10674
- L,
10675
- pack25519,
10676
- unpack25519,
10677
- M,
10678
- A,
10679
- S,
10680
- Z,
10681
- pow2523,
10682
- add,
10683
- set25519,
10684
- modL,
10685
- scalarmult,
10686
- scalarbase
10687
- };
10688
- function checkLengths(k, n) {
10689
- if (k.length !== crypto_secretbox_KEYBYTES) throw new Error("bad key size");
10690
- if (n.length !== crypto_secretbox_NONCEBYTES) throw new Error("bad nonce size");
10691
- }
10692
- function checkBoxLengths(pk, sk) {
10693
- if (pk.length !== crypto_box_PUBLICKEYBYTES) throw new Error("bad public key size");
10694
- if (sk.length !== crypto_box_SECRETKEYBYTES) throw new Error("bad secret key size");
10695
- }
10696
- function checkArrayTypes() {
10697
- for (var i = 0; i < arguments.length; i++) {
10698
- if (!(arguments[i] instanceof Uint8Array))
10699
- throw new TypeError("unexpected type, use Uint8Array");
10700
- }
10701
- }
10702
- function cleanup(arr) {
10703
- for (var i = 0; i < arr.length; i++) arr[i] = 0;
10704
- }
10705
- nacl6.randomBytes = function(n) {
10706
- var b = new Uint8Array(n);
10707
- randombytes(b, n);
10708
- return b;
10709
- };
10710
- nacl6.secretbox = function(msg, nonce, key) {
10711
- checkArrayTypes(msg, nonce, key);
10712
- checkLengths(key, nonce);
10713
- var m = new Uint8Array(crypto_secretbox_ZEROBYTES + msg.length);
10714
- var c = new Uint8Array(m.length);
10715
- for (var i = 0; i < msg.length; i++) m[i + crypto_secretbox_ZEROBYTES] = msg[i];
10716
- crypto_secretbox(c, m, m.length, nonce, key);
10717
- return c.subarray(crypto_secretbox_BOXZEROBYTES);
10718
- };
10719
- nacl6.secretbox.open = function(box, nonce, key) {
10720
- checkArrayTypes(box, nonce, key);
10721
- checkLengths(key, nonce);
10722
- var c = new Uint8Array(crypto_secretbox_BOXZEROBYTES + box.length);
10723
- var m = new Uint8Array(c.length);
10724
- for (var i = 0; i < box.length; i++) c[i + crypto_secretbox_BOXZEROBYTES] = box[i];
10725
- if (c.length < 32) return null;
10726
- if (crypto_secretbox_open(m, c, c.length, nonce, key) !== 0) return null;
10727
- return m.subarray(crypto_secretbox_ZEROBYTES);
10728
- };
10729
- nacl6.secretbox.keyLength = crypto_secretbox_KEYBYTES;
10730
- nacl6.secretbox.nonceLength = crypto_secretbox_NONCEBYTES;
10731
- nacl6.secretbox.overheadLength = crypto_secretbox_BOXZEROBYTES;
10732
- nacl6.scalarMult = function(n, p) {
10733
- checkArrayTypes(n, p);
10734
- if (n.length !== crypto_scalarmult_SCALARBYTES) throw new Error("bad n size");
10735
- if (p.length !== crypto_scalarmult_BYTES) throw new Error("bad p size");
10736
- var q = new Uint8Array(crypto_scalarmult_BYTES);
10737
- crypto_scalarmult(q, n, p);
10738
- return q;
10739
- };
10740
- nacl6.scalarMult.base = function(n) {
10741
- checkArrayTypes(n);
10742
- if (n.length !== crypto_scalarmult_SCALARBYTES) throw new Error("bad n size");
10743
- var q = new Uint8Array(crypto_scalarmult_BYTES);
10744
- crypto_scalarmult_base(q, n);
10745
- return q;
10746
- };
10747
- nacl6.scalarMult.scalarLength = crypto_scalarmult_SCALARBYTES;
10748
- nacl6.scalarMult.groupElementLength = crypto_scalarmult_BYTES;
10749
- nacl6.box = function(msg, nonce, publicKey, secretKey) {
10750
- var k = nacl6.box.before(publicKey, secretKey);
10751
- return nacl6.secretbox(msg, nonce, k);
10752
- };
10753
- nacl6.box.before = function(publicKey, secretKey) {
10754
- checkArrayTypes(publicKey, secretKey);
10755
- checkBoxLengths(publicKey, secretKey);
10756
- var k = new Uint8Array(crypto_box_BEFORENMBYTES);
10757
- crypto_box_beforenm(k, publicKey, secretKey);
10758
- return k;
10759
- };
10760
- nacl6.box.after = nacl6.secretbox;
10761
- nacl6.box.open = function(msg, nonce, publicKey, secretKey) {
10762
- var k = nacl6.box.before(publicKey, secretKey);
10763
- return nacl6.secretbox.open(msg, nonce, k);
10764
- };
10765
- nacl6.box.open.after = nacl6.secretbox.open;
10766
- nacl6.box.keyPair = function() {
10767
- var pk = new Uint8Array(crypto_box_PUBLICKEYBYTES);
10768
- var sk = new Uint8Array(crypto_box_SECRETKEYBYTES);
10769
- crypto_box_keypair(pk, sk);
10770
- return { publicKey: pk, secretKey: sk };
10771
- };
10772
- nacl6.box.keyPair.fromSecretKey = function(secretKey) {
10773
- checkArrayTypes(secretKey);
10774
- if (secretKey.length !== crypto_box_SECRETKEYBYTES)
10775
- throw new Error("bad secret key size");
10776
- var pk = new Uint8Array(crypto_box_PUBLICKEYBYTES);
10777
- crypto_scalarmult_base(pk, secretKey);
10778
- return { publicKey: pk, secretKey: new Uint8Array(secretKey) };
10779
- };
10780
- nacl6.box.publicKeyLength = crypto_box_PUBLICKEYBYTES;
10781
- nacl6.box.secretKeyLength = crypto_box_SECRETKEYBYTES;
10782
- nacl6.box.sharedKeyLength = crypto_box_BEFORENMBYTES;
10783
- nacl6.box.nonceLength = crypto_box_NONCEBYTES;
10784
- nacl6.box.overheadLength = nacl6.secretbox.overheadLength;
10785
- nacl6.sign = function(msg, secretKey) {
10786
- checkArrayTypes(msg, secretKey);
10787
- if (secretKey.length !== crypto_sign_SECRETKEYBYTES)
10788
- throw new Error("bad secret key size");
10789
- var signedMsg = new Uint8Array(crypto_sign_BYTES + msg.length);
10790
- crypto_sign(signedMsg, msg, msg.length, secretKey);
10791
- return signedMsg;
10792
- };
10793
- nacl6.sign.open = function(signedMsg, publicKey) {
10794
- checkArrayTypes(signedMsg, publicKey);
10795
- if (publicKey.length !== crypto_sign_PUBLICKEYBYTES)
10796
- throw new Error("bad public key size");
10797
- var tmp = new Uint8Array(signedMsg.length);
10798
- var mlen = crypto_sign_open(tmp, signedMsg, signedMsg.length, publicKey);
10799
- if (mlen < 0) return null;
10800
- var m = new Uint8Array(mlen);
10801
- for (var i = 0; i < m.length; i++) m[i] = tmp[i];
10802
- return m;
10803
- };
10804
- nacl6.sign.detached = function(msg, secretKey) {
10805
- var signedMsg = nacl6.sign(msg, secretKey);
10806
- var sig = new Uint8Array(crypto_sign_BYTES);
10807
- for (var i = 0; i < sig.length; i++) sig[i] = signedMsg[i];
10808
- return sig;
10809
- };
10810
- nacl6.sign.detached.verify = function(msg, sig, publicKey) {
10811
- checkArrayTypes(msg, sig, publicKey);
10812
- if (sig.length !== crypto_sign_BYTES)
10813
- throw new Error("bad signature size");
10814
- if (publicKey.length !== crypto_sign_PUBLICKEYBYTES)
10815
- throw new Error("bad public key size");
10816
- var sm = new Uint8Array(crypto_sign_BYTES + msg.length);
10817
- var m = new Uint8Array(crypto_sign_BYTES + msg.length);
10818
- var i;
10819
- for (i = 0; i < crypto_sign_BYTES; i++) sm[i] = sig[i];
10820
- for (i = 0; i < msg.length; i++) sm[i + crypto_sign_BYTES] = msg[i];
10821
- return crypto_sign_open(m, sm, sm.length, publicKey) >= 0;
10822
- };
10823
- nacl6.sign.keyPair = function() {
10824
- var pk = new Uint8Array(crypto_sign_PUBLICKEYBYTES);
10825
- var sk = new Uint8Array(crypto_sign_SECRETKEYBYTES);
10826
- crypto_sign_keypair(pk, sk);
10827
- return { publicKey: pk, secretKey: sk };
10828
- };
10829
- nacl6.sign.keyPair.fromSecretKey = function(secretKey) {
10830
- checkArrayTypes(secretKey);
10831
- if (secretKey.length !== crypto_sign_SECRETKEYBYTES)
10832
- throw new Error("bad secret key size");
10833
- var pk = new Uint8Array(crypto_sign_PUBLICKEYBYTES);
10834
- for (var i = 0; i < pk.length; i++) pk[i] = secretKey[32 + i];
10835
- return { publicKey: pk, secretKey: new Uint8Array(secretKey) };
10836
- };
10837
- nacl6.sign.keyPair.fromSeed = function(seed) {
10838
- checkArrayTypes(seed);
10839
- if (seed.length !== crypto_sign_SEEDBYTES)
10840
- throw new Error("bad seed size");
10841
- var pk = new Uint8Array(crypto_sign_PUBLICKEYBYTES);
10842
- var sk = new Uint8Array(crypto_sign_SECRETKEYBYTES);
10843
- for (var i = 0; i < 32; i++) sk[i] = seed[i];
10844
- crypto_sign_keypair(pk, sk, true);
10845
- return { publicKey: pk, secretKey: sk };
10846
- };
10847
- nacl6.sign.publicKeyLength = crypto_sign_PUBLICKEYBYTES;
10848
- nacl6.sign.secretKeyLength = crypto_sign_SECRETKEYBYTES;
10849
- nacl6.sign.seedLength = crypto_sign_SEEDBYTES;
10850
- nacl6.sign.signatureLength = crypto_sign_BYTES;
10851
- nacl6.hash = function(msg) {
10852
- checkArrayTypes(msg);
10853
- var h = new Uint8Array(crypto_hash_BYTES);
10854
- crypto_hash(h, msg, msg.length);
10855
- return h;
10856
- };
10857
- nacl6.hash.hashLength = crypto_hash_BYTES;
10858
- nacl6.verify = function(x, y) {
10859
- checkArrayTypes(x, y);
10860
- if (x.length === 0 || y.length === 0) return false;
10861
- if (x.length !== y.length) return false;
10862
- return vn(x, 0, y, 0, x.length) === 0 ? true : false;
10863
- };
10864
- nacl6.setPRNG = function(fn) {
10865
- randombytes = fn;
10866
- };
10867
- (function() {
10868
- var crypto = typeof self !== "undefined" ? self.crypto || self.msCrypto : null;
10869
- if (crypto && crypto.getRandomValues) {
10870
- var QUOTA = 65536;
10871
- nacl6.setPRNG(function(x, n) {
10872
- var i, v = new Uint8Array(n);
10873
- for (i = 0; i < n; i += QUOTA) {
10874
- crypto.getRandomValues(v.subarray(i, i + Math.min(n - i, QUOTA)));
10875
- }
10876
- for (i = 0; i < n; i++) x[i] = v[i];
10877
- cleanup(v);
10878
- });
10879
- } else if (typeof __require2 !== "undefined") {
10880
- crypto = __require2("crypto");
10881
- if (crypto && crypto.randomBytes) {
10882
- nacl6.setPRNG(function(x, n) {
10883
- var i, v = crypto.randomBytes(n);
10884
- for (i = 0; i < n; i++) x[i] = v[i];
10885
- cleanup(v);
10886
- });
10887
- }
10888
- }
10889
- })();
10890
- })(typeof module !== "undefined" && module.exports ? module.exports : self.nacl = self.nacl || {});
10891
- }
10892
- });
10893
8644
  var BACKEND_URL = process.env.PAIGY_BACKEND_URL ?? "https://paigy.ai";
10894
8645
  var NETWORK_MSG = `Can't reach ${BACKEND_URL} \u2014 the connection was blocked or dropped before an HTTP response. If this agent runs in a sandboxed environment with a network allowlist (e.g. Claude Code on the web, CI), ask the user to add the Paigy domain (paigy.ai) to the environment's allowed domains, then retry.`;
10895
8646
  var PROXY_ENV = ["HTTPS_PROXY", "https_proxy", "HTTP_PROXY", "http_proxy"];
@@ -10910,12 +8661,39 @@ var envSession = (key) => {
10910
8661
  const v = process.env[key];
10911
8662
  return v && v.trim() ? v : void 0;
10912
8663
  };
10913
- var SESSION_ID = envSession("PAIGY_SESSION_ID") ?? envSession("CLAUDE_CODE_SESSION_ID") ?? envSession("CODEX_THREAD_ID") ?? envSession("CODEX_SESSION_ID") ?? WORKSPACE_ID;
8664
+ function parentOf(pid) {
8665
+ try {
8666
+ if (process.platform === "win32") return void 0;
8667
+ const ppid = process.platform === "linux" ? readFileSync(`/proc/${pid}/stat`, "utf8").split(") ")[1]?.split(" ")[1] : execFileSync("ps", ["-o", "ppid=", "-p", String(pid)], { encoding: "utf8", timeout: 1e3 });
8668
+ return Number(ppid?.trim()) || void 0;
8669
+ } catch {
8670
+ return void 0;
8671
+ }
8672
+ }
8673
+ var lineage;
8674
+ function ancestors() {
8675
+ if (lineage) return lineage;
8676
+ lineage = [];
8677
+ for (let pid = process.ppid; pid && pid > 1 && lineage.length < 5; pid = parentOf(pid)) lineage.push(pid);
8678
+ return lineage;
8679
+ }
8680
+ function claudeConversation() {
8681
+ if (!envSession("CLAUDE_CODE_SESSION_ID") || process.env.CLAUDE_CODE_CHILD_SESSION) return void 0;
8682
+ const dir = envSession("CLAUDE_CONFIG_DIR") ?? join(homedir(), ".claude");
8683
+ for (const pid of ancestors()) {
8684
+ try {
8685
+ const { sessionId: sessionId2 } = JSON.parse(readFileSync(join(dir, "sessions", `${pid}.json`), "utf8"));
8686
+ return typeof sessionId2 === "string" && sessionId2.trim() ? sessionId2 : void 0;
8687
+ } catch {
8688
+ }
8689
+ }
8690
+ return void 0;
8691
+ }
10914
8692
  function sessionId() {
10915
- return SESSION_ID;
8693
+ return envSession("PAIGY_SESSION_ID") ?? claudeConversation() ?? envSession("CLAUDE_CODE_SESSION_ID") ?? envSession("CODEX_THREAD_ID") ?? envSession("CODEX_SESSION_ID") ?? WORKSPACE_ID;
10916
8694
  }
10917
8695
  async function reach(url, init) {
10918
- return send(url, init, SESSION_ID);
8696
+ return send(url, init, sessionId());
10919
8697
  }
10920
8698
  function reachAs(session) {
10921
8699
  return (url, init) => send(url, init, session);
@@ -12144,6 +9922,23 @@ var zodToJsonSchema = (schema, options) => {
12144
9922
  };
12145
9923
  var OPTIONS_MIN = 2;
12146
9924
  var OPTIONS_MAX = 6;
9925
+ var OptionSchema = external_exports.object({
9926
+ id: external_exports.string(),
9927
+ label: external_exports.string(),
9928
+ hint: external_exports.string().max(500).describe("Optional short projection of consequence or action if this option is chosen (e.g. 'Reruns test suite', 'Merges to main').").optional(),
9929
+ // .describe() flows into the MCP contact JSON schema (zodToJsonSchema), so
9930
+ // the constraints below are what an agent reads when deciding to use these.
9931
+ html: external_exports.string().max(16384).describe(
9932
+ "Optional sandboxed HTML/CSS preview for a visual 'pick one' (shown in the option card). Untrusted-sandboxed: NO JavaScript, NO external network or images \u2014 inline CSS and data: URIs only; <=16KB. Rendered edge-to-edge in a responsive card that is 200pt tall (about 320pt wide on a phone, with the next option peeking beside it); make your HTML fit that viewport. Use for layout/CSS mockups, tables, diffs. For a hosted image use `image` instead."
9933
+ ).optional(),
9934
+ image: external_exports.string().url().describe(
9935
+ "Optional image URL rendered as the option's preview (plain image, not sandboxed). For agent-generated HTML/CSS mockups, use `html` instead."
9936
+ ).optional()
9937
+ });
9938
+ var OptionInputSchema = OptionSchema.omit({ id: true }).extend({
9939
+ label: external_exports.string().trim().min(1).max(1e3)
9940
+ }).strict();
9941
+ var NIGHT = { from: 23, to: 7 };
12147
9942
  function draft2020(node) {
12148
9943
  if (Array.isArray(node)) return node.map(draft2020);
12149
9944
  if (node && typeof node === "object") {
@@ -12173,32 +9968,23 @@ function mcpInputSchema(s) {
12173
9968
  delete schema.$schema;
12174
9969
  return draft2020(schema);
12175
9970
  }
12176
- var StartContactSchema = external_exports.object({
12177
- goalIds: external_exports.tuple([external_exports.string().uuid()]),
12178
- // THE ASK IS THE QUESTION, not a bulletin with a question at the end (2026-09-16).
12179
- //
12180
- // A DecisionNeed is settled only by an answer in the shape THIS ask declares. Bundle news,
12181
- // findings and a decision into one, and the person answers whichever part engaged them —
12182
- // which settles nothing, leaves the need open, and gets them asked again. On call 619c5a92
12183
- // one ask carried a briefing, a side question ("the ring should show the agent's name now —
12184
- // what did you actually see?") and a one-of-four about how far an erase reaches. The owner
12185
- // answered the side question. The need stayed open; the card asked again. Of the 45 call
12186
- // asks carrying a decision, 27 are over 600 characters.
12187
- //
12188
- // Sending them separately costs nothing, because a CALL contact joins the call already
12189
- // happening (`goal/store.ts`, JOIN BEFORE MINTING) — several contacts on one Goal arrive as
12190
- // one call, planned as its turns, and each keeps its own settleable need.
9971
+ var AskInputSchema = external_exports.object({
9972
+ id: external_exports.string().optional().describe("Optional idempotency key or client-side ID for this specific ask."),
9973
+ parentId: external_exports.string().uuid().optional().describe("The Goal this question is about \u2014 usually the one you are working on. The question goes onto that Goal and its answer comes back there. Omit it and Paigy places the question in the tree itself."),
9974
+ repo: external_exports.string().optional().describe("Optional repository context."),
12191
9975
  ask: external_exports.string().trim().min(1).max(1e4).describe(
12192
9976
  "The question, and only what is needed to answer it. News, progress and findings are their own contact \u2014 a call contact JOINS a call already happening, so several arrive as one call. Do not bundle: a DecisionNeed is settled only by an answer in the shape this ask declares, so someone who answers the part that interested them settles nothing and is asked again."
12193
9977
  ),
9978
+ options: external_exports.array(OptionInputSchema).min(2).max(6).optional()
9979
+ }).strict();
9980
+ var StartContactSchema = external_exports.object({
9981
+ asks: external_exports.array(AskInputSchema).min(1).describe("The questions to pose, one per object. An ask with a parentId is filed on that Goal as it is; only an ask naming no Goal is placed in the tree by Paigy."),
12194
9982
  waiting: external_exports.enum(["none", "hard"]).default("none"),
12195
- channel: external_exports.enum(["notification", "call"]).default("notification"),
12196
- options: external_exports.array(external_exports.object({ label: external_exports.string().trim().min(1).max(1e3), image: external_exports.string().url().optional(), html: external_exports.string().max(16384).optional() }).strict()).min(2).max(6).optional(),
12197
- threadId: external_exports.string().uuid().optional().describe("Continue an existing Thread: the threadId a prior Delivery returned. Omit to start a new Thread.")
9983
+ channel: external_exports.enum(["notification", "call"]).default("notification")
12198
9984
  }).strict();
12199
9985
  var ContactSchema = external_exports.union([StartContactSchema, external_exports.object({ deliveryId: external_exports.string().uuid() }).strict()]);
12200
9986
  var CONTACT_SCHEMA = { type: "object", ...mcpInputSchema(ContactSchema) };
12201
- var CONTACT_DESCRIPTION = "Contact the user about exactly one existing Goal: pass goalIds:[goalId], ask, channel:'notification'|'call', and waiting:'none'|'hard'. Options supply choices. Notification returns immediately; collect durable answers with claim_goal/get_goal. On stdio, a Call holds one cancellable ~45s window; continue with ONLY {deliveryId}. Continuation sends nothing and rereads the same durable evidence, including previously read answers. Entries retain authorship and provenance; accepted decisions are separate from quoted speech. Call state open does not mean ringing. Unsupported: soft waiting, multiple Goals/questions, outcome admission, and re-presentation of an existing request. Create a Goal explicitly first; never resend a pending ask to continue waiting.";
9987
+ var CONTACT_DESCRIPTION = "Contact the user with one or more asks/questions. Pass an array of asks (each with 'ask', optional 'options', 'id', 'parentId', 'repo'), plus channel:'notification'|'call', and waiting:'none'|'hard'. An ask that names a Goal (parentId) goes onto that Goal; one that names none is placed in the person's tree by Paigy. Notification returns immediately; collect durable answers with check_replies. On stdio, a Call holds one cancellable ~45s window; continue with ONLY {deliveryId}. Never bundle multiple questions into a single 'ask' string; pass them as separate objects in the 'asks' array.";
12202
9988
  var CreateGoalSchema = external_exports.object({
12203
9989
  outcome: external_exports.string().trim().min(1).max(1e4),
12204
9990
  /** The work's NAME (#2115) — one to five words, how a person refers to it out loud ("the night
@@ -12206,11 +9992,6 @@ var CreateGoalSchema = external_exports.object({
12206
9992
  title: external_exports.string().trim().min(1).max(80).optional(),
12207
9993
  ownerParticipant: external_exports.string().trim().min(1).optional(),
12208
9994
  idempotencyKey: external_exports.string().trim().min(1).max(200),
12209
- /** A past conversation this Goal should be read against — History's "new session from this"
12210
- * (owner, on the call of 2026-09-14: "let's do the reference with the threading"). A
12211
- * reference only: the owner reads it through `get_thread`, which does its own scoping, and
12212
- * the writer refuses a thread belonging to another account. */
12213
- contextThreadId: external_exports.string().uuid().optional(),
12214
9995
  /** THE GOAL THIS ONE BELONGS UNDER (owner, 2026-09-15: "the ask I gave for the design doc
12215
9996
  * didn't get created as a child goal of the voice UI goal, which is how it should've
12216
9997
  * worked"). It could not have been: this door took no parent, so the only route was
@@ -12218,12 +9999,15 @@ var CreateGoalSchema = external_exports.object({
12218
9999
  * took the short one. The hierarchy has been modelled since Goals existed and had been used
12219
10000
  * ZERO times in 2,031 of them. Absent, the server judges it against the caller's open Goals
12220
10001
  * (`apps/api/src/goal/intake.ts`). The writer refuses a Goal belonging to another account. */
12221
- parentGoalId: external_exports.string().uuid().optional()
10002
+ parentGoalId: external_exports.string().uuid().optional(),
10003
+ /** The repository or project identifier this Goal belongs to (#2280) — e.g. "owner/repo" or
10004
+ * repo name. Delegated work inherits this from its parent Goal when omitted. */
10005
+ repo: external_exports.string().trim().min(1).max(200).optional()
12222
10006
  });
12223
10007
  var CreateGoalToolSchema = CreateGoalSchema.extend({
12224
10008
  idempotencyKey: CreateGoalSchema.shape.idempotencyKey.optional().describe("Optional. One is minted per call; pass your own only so a retry lands on the same Goal.")
12225
10009
  }).strict();
12226
- var CREATE_GOAL_DESCRIPTION = 'Create a durable Goal for an outcome. Without parentGoalId it is placed against your open Goals: if one already IS this work, that Goal comes back (existing: true) and nothing new is created \u2014 continue it; if the work belongs under one, it is created there (parentGoalId in the receipt); otherwise it is a root. Pass parentGoalId yourself to put it under a specific Goal. Pass title to name it in one to five words, as a person would refer to it out loud ("the night rings") \u2014 it heads every list and is spoken on a call; without one the brain writes it. Admission only: the owner must claim it before doing work, then update it as it advances. Returns an admission receipt with goalId, current state, revision, ownerParticipant, and the next step; no Goal content or execution lease.';
10010
+ var CREATE_GOAL_DESCRIPTION = 'Create a durable Goal for an outcome. Without parentGoalId it is placed against your open Goals: if one already IS this work, that Goal comes back (existing: true) and nothing new is created \u2014 continue it; if the work belongs under one, it is created there (parentGoalId in the receipt); otherwise it is a root. Pass parentGoalId yourself to put it under a specific Goal. Pass repo to anchor the work to a specific repository ("owner/repo" or repo name); delegated children inherit it. Pass title to name it in one to five words, as a person would refer to it out loud ("the night rings") \u2014 it heads every list and is spoken on a call; without one the brain writes it. Admission only: the owner must claim it before doing work, then update it as it advances. Returns an admission receipt with goalId, current state, revision, ownerParticipant, and the next step; no Goal content or execution lease.';
12227
10011
  var UpdateGoalSchema = external_exports.object({
12228
10012
  revision: external_exports.number().int().positive(),
12229
10013
  changes: external_exports.object({
@@ -12251,19 +10035,9 @@ var UPDATE_GOAL_DESCRIPTION = "Update an owned Goal at an exact revision. State,
12251
10035
  var CLAIM_GOAL_DESCRIPTION = "Claim the oldest runnable or review-pending Goal you own, or pass goalId to claim that Goal. Returns the Goal as get_goal reads it, and creates or renews the execution lease.";
12252
10036
  var CHECK_REPLIES_DESCRIPTION = "Your open Deliveries: every Notification or Call currently addressed to you \u2014 a request the user started toward you, an answer relayed to something you asked, a handoff \u2014 one row each: its Goals, how many decisions are still open, and the newest words in brief. A pure read with no arguments: nothing is consumed, acknowledged or claimed by reading it, so call it on startup, after a long wait, or whenever you want to know what is outstanding. To act on one, claim its Goal (claim_goal) or reread it in full with contact({deliveryId}). Once you have acted on what arrived, update_goal with reviewed: true closes the Deliveries addressed to you on that Goal. Your runnable and review-pending Goals come from claim_goal, not from here.";
12253
10037
  var CheckRepliesSchema = external_exports.object({}).strict();
12254
- var GetThreadSchema = external_exports.object({
12255
- parentId: external_exports.string().describe("The Thread to read \u2014 the threadId a Delivery returned, or the parentId of a search hit.")
12256
- }).strict();
12257
- var GET_THREAD_DESCRIPTION = "Read the authorized durable Entries on one conversation Thread \u2014 what you wrote there and what was delivered to you, oldest first. Use claim_goal to find the work to resume; use this to rehydrate a Thread that a search hit or a Delivery named.";
12258
- var SearchThreadsSchema = external_exports.object({
12259
- q: external_exports.string().describe("What to look for \u2014 plain words or a phrase (e.g. 'the livekit timeout', 'deploy to prod').")
12260
- }).strict();
12261
- var SEARCH_THREADS_DESCRIPTION = `Search your PAST conversations before asking \u2014 "have we discussed this before?". Full-text over your own threads (the asks you sent + the user's answers); returns ranked threads with highlighted snippets, NOT rows: { hits: [{ parentId, at, agentLabel, matches: [{ notificationId, role, snippet }] }] }. The loop this exists for: search first \u2192 get_thread the best hit to rehydrate it \u2192 THEN continue or contact, so you answer with receipts ("last week you said ship it") instead of re-asking. Read-only, safe to call anytime; scoped to your own account's threads.`;
12262
10038
  var AGENT_TOOLS = [
12263
10039
  { name: "contact", description: CONTACT_DESCRIPTION, inputSchema: CONTACT_SCHEMA },
12264
10040
  { name: "check_replies", description: CHECK_REPLIES_DESCRIPTION, inputSchema: mcpInputSchema(CheckRepliesSchema) },
12265
- { name: "get_thread", description: GET_THREAD_DESCRIPTION, inputSchema: mcpInputSchema(GetThreadSchema) },
12266
- { name: "search_threads", description: SEARCH_THREADS_DESCRIPTION, inputSchema: mcpInputSchema(SearchThreadsSchema) },
12267
10041
  { name: "create_goal", description: CREATE_GOAL_DESCRIPTION, inputSchema: mcpInputSchema(CreateGoalToolSchema) },
12268
10042
  { name: "claim_goal", description: CLAIM_GOAL_DESCRIPTION, inputSchema: mcpInputSchema(ClaimGoalSchema) },
12269
10043
  { name: "get_goal", description: GET_GOAL_DESCRIPTION, inputSchema: mcpInputSchema(GetGoalSchema) },
@@ -12297,18 +10071,6 @@ var TransformSchema = external_exports.enum([
12297
10071
  "summarize"
12298
10072
  // reduce volume, keep decision value — 30-turn cap, spoken briefing
12299
10073
  ]);
12300
- var OptionSchema = external_exports.object({
12301
- id: external_exports.string(),
12302
- label: external_exports.string(),
12303
- // .describe() flows into the MCP contact JSON schema (zodToJsonSchema), so
12304
- // the constraints below are what an agent reads when deciding to use these.
12305
- html: external_exports.string().max(16384).describe(
12306
- "Optional sandboxed HTML/CSS preview for a visual 'pick one' (shown in the option card). Untrusted-sandboxed: NO JavaScript, NO external network or images \u2014 inline CSS and data: URIs only; <=16KB. Use for layout/CSS mockups, tables, diffs. For a hosted image use `image` instead."
12307
- ).optional(),
12308
- image: external_exports.string().url().describe(
12309
- "Optional image URL rendered as the option's preview (plain image, not sandboxed). For agent-generated HTML/CSS mockups, use `html` instead."
12310
- ).optional()
12311
- });
12312
10074
  var VisualSchema = external_exports.object({
12313
10075
  url: external_exports.string().url(),
12314
10076
  label: external_exports.string().optional()
@@ -12362,7 +10124,7 @@ var NotifyRequestFields = external_exports.object({
12362
10124
  * ABSENT on the E2EE path, where the sealed `envelope` below carries it. The
12363
10125
  * superRefine at the bottom enforces exactly one of the two. */
12364
10126
  context: ContextSchema.optional(),
12365
- options: external_exports.array(OptionSchema.omit({ id: true })).min(OPTIONS_MIN).max(OPTIONS_MAX).optional().describe(
10127
+ options: external_exports.array(OptionInputSchema).min(OPTIONS_MIN).max(OPTIONS_MAX).optional().describe(
12366
10128
  "The choices, in order \u2014 required when select is 'one'/'many'/'rank', omitted otherwise. Ids are assigned automatically by position ('1', '2', \u2026); the user's answer references them as optionId(s)."
12367
10129
  ),
12368
10130
  points: external_exports.array(external_exports.string().min(1)).optional().describe(
@@ -12394,23 +10156,6 @@ var NotifyRequestFields = external_exports.object({
12394
10156
  * when `parentId` became the conversation handle: `parentId` says WHERE, this
12395
10157
  * says HOW. */
12396
10158
  clarifies: external_exports.string().optional(),
12397
- /** E2EE (text lane): when the pairing is E2EE, the sealed replacements for the
12398
- * plaintext content fields, keyed by field name. FINALIZED wire shape (was
12399
- * provisional in the storage PR): a per-field map `{ context?, options?,
12400
- * visuals? }` of opaque Envelopes — one seal per present content field, so a
12401
- * message with no options/visuals seals only `context`. It COEXISTS with the
12402
- * plaintext fields by mutual exclusion: the superRefine below requires that
12403
- * when `envelope` is present the plaintext `context`/`options`/`visuals` are
12404
- * ABSENT (and vice-versa), so a row is either fully plaintext or fully sealed —
12405
- * never a readable half. The server persists this OPAQUELY into
12406
- * notifications.envelope and relays it blindly; it never decrypts. Absent =
12407
- * today's plaintext path (context/options/visuals carry the cleartext).
12408
- * z.lazy because EnvelopeSchema is declared further down (E2EE section). */
12409
- envelope: external_exports.object({
12410
- context: external_exports.lazy(() => EnvelopeSchema).optional(),
12411
- options: external_exports.lazy(() => EnvelopeSchema).optional(),
12412
- visuals: external_exports.lazy(() => EnvelopeSchema).optional()
12413
- }).optional(),
12414
10159
  select: SelectShapeSchema.optional().describe(
12415
10160
  "How the user answers \u2014 required on the fully-shaped form, pick the shape that fits the question: 'one' = pick one option, 'many' = pick several, 'rank' = pick & order (each needs `options`); 'confirm' = yes/no or approve/deny; 'text' = free-form reply only (status updates, open questions). 'confirm' and 'text' take no options. Omit only when sending the simplified `ask` form \u2014 the broker picks the shape."
12416
10161
  ),
@@ -12464,22 +10209,6 @@ var NotifyRequestFields = external_exports.object({
12464
10209
  });
12465
10210
  var NotifyRequestSchema = NotifyRequestFields.superRefine((r, ctx) => {
12466
10211
  if (r.workId && r.goalId) ctx.addIssue({ code: external_exports.ZodIssueCode.custom, path: ["goalId"], message: "pass goalId or workId, not both" });
12467
- const sealed = !!r.envelope;
12468
- if (sealed) {
12469
- if (!r.envelope?.context)
12470
- ctx.addIssue({ code: external_exports.ZodIssueCode.custom, path: ["envelope", "context"], message: "sealed request must include envelope.context" });
12471
- for (const f of ["context", "options", "visuals"]) {
12472
- if (r[f] !== void 0)
12473
- ctx.addIssue({ code: external_exports.ZodIssueCode.custom, path: [f], message: `E2EE request must not carry plaintext ${f} \u2014 it's sealed in envelope.${f}` });
12474
- }
12475
- if (r.points !== void 0)
12476
- ctx.addIssue({ code: external_exports.ZodIssueCode.custom, path: ["points"], message: "E2EE request must not carry plaintext points" });
12477
- if (r.ask !== void 0)
12478
- ctx.addIssue({ code: external_exports.ZodIssueCode.custom, path: ["ask"], message: "E2EE request must not carry a plaintext ask \u2014 derive the shape agent-side and seal it" });
12479
- if (r.needs !== void 0)
12480
- ctx.addIssue({ code: external_exports.ZodIssueCode.custom, path: ["needs"], message: "E2EE request must not carry plaintext needs" });
12481
- return;
12482
- }
12483
10212
  if (r.ask !== void 0) {
12484
10213
  for (const f of ["context", "select", "points"]) {
12485
10214
  if (r[f] !== void 0)
@@ -12499,61 +10228,6 @@ var NotifyRequestSchema = NotifyRequestFields.superRefine((r, ctx) => {
12499
10228
  if (!needsOptions && r.options?.length)
12500
10229
  ctx.addIssue({ code: external_exports.ZodIssueCode.custom, path: ["options"], message: `select:'${r.select}' takes no options` });
12501
10230
  });
12502
- function normalizeWaiting(req) {
12503
- if (!req.waiting) return req;
12504
- const { waiting, ...rest } = req;
12505
- return {
12506
- ...rest,
12507
- urgencyHint: req.urgencyHint ?? { none: "whenever", soft: "soon", hard: "now" }[waiting],
12508
- blocking: req.blocking || waiting === "hard"
12509
- };
12510
- }
12511
- function unitsOf(text) {
12512
- const spans = [];
12513
- const re = /\n\s*\n+/g;
12514
- let cursor = 0;
12515
- const push = (from, to) => {
12516
- const slice = text.slice(from, to);
12517
- const lead = slice.length - slice.trimStart().length;
12518
- const tail = slice.length - slice.trimEnd().length;
12519
- if (from + lead < to - tail) spans.push({ start: from + lead, end: to - tail });
12520
- };
12521
- for (let m = re.exec(text); m; m = re.exec(text)) {
12522
- push(cursor, m.index);
12523
- cursor = m.index + m[0].length;
12524
- }
12525
- push(cursor, text.length);
12526
- return spans;
12527
- }
12528
- function headline(text) {
12529
- const line = text.split("\n").map((l) => l.trim()).filter((l) => l && !/^`{3,}/.test(l)).map((l) => l.replace(/^(?:#{1,6}|[-*>]|\d{1,3}\.)\s+/, "")).find(Boolean) ?? "";
12530
- return (/^[^.!?\n]+[.!?]?/.exec(line)?.[0] ?? line).trim();
12531
- }
12532
- function bodyAfterHeadline(text) {
12533
- const body = text.trim();
12534
- const title = headline(body);
12535
- const rest = body.slice(title.length).replace(/^[\s.!?—–-]+/, "").trim();
12536
- if (!rest) return { title, description: [] };
12537
- const chunks = unitsOf(rest).map((u) => rest.slice(u.start, u.end)).filter(Boolean);
12538
- return { title, description: chunks.length ? chunks : [rest] };
12539
- }
12540
- function deriveAsk(req) {
12541
- req = normalizeWaiting(req);
12542
- if (!req.ask) return req;
12543
- const text = req.ask.trim();
12544
- const hinted = req.urgencyHint === "now" ? "call" : req.urgencyHint === "soon" ? "banner" : req.urgencyHint === "whenever" ? "inbox" : req.urgency;
12545
- const urgency = req.channel === "call" ? "call" : req.channel === "message" && hinted === "call" ? "banner" : hinted;
12546
- const { ask: _ask, needs, urgencyHint: _hint, channel: _channel, ...rest } = req;
12547
- return {
12548
- ...rest,
12549
- context: bodyAfterHeadline(text),
12550
- // Options riding alongside the ask (#575: pixels can't be prose) floor to a
12551
- // single pick — the model broker may upgrade to many/rank from the wording.
12552
- select: req.options?.length ? "one" : "text",
12553
- urgency,
12554
- ...needs?.length ? { points: needs } : {}
12555
- };
12556
- }
12557
10231
  var NotifyStatusSchema = external_exports.enum(["pending", "answered", "ignored"]);
12558
10232
  var AgentStateSchema = external_exports.enum(["idle", "in_progress", "completed", "needs_input"]);
12559
10233
  var TurnSchema = external_exports.object({
@@ -12609,13 +10283,6 @@ var AwaitItemSchema = external_exports.discriminatedUnion("type", [
12609
10283
  workId: external_exports.string().uuid().optional(),
12610
10284
  decisionId: external_exports.string().uuid().optional(),
12611
10285
  answer: UserAnswerSchema,
12612
- /** E2EE: present when the answer is sealed. The server relays the opaque answer
12613
- * envelope + the plaintext `ignored` status hint; the receiving agent OPENS it
12614
- * with its device key and re-derives the real UserAnswer, treating a mismatch
12615
- * against `ignored` as tampering. Absent = today's plaintext answer (in `answer`).
12616
- * On a sealed reply the plaintext `answer` is a placeholder (kind reflects only
12617
- * the `ignored` bit) — never the real content, which stays sealed. */
12618
- sealed: external_exports.lazy(() => SealedAnswerSchema).optional(),
12619
10286
  /** WHAT THE AGENT CANNOT KNOW FROM THE FIELDS BESIDE IT (owner, 2026-09-04, issue
12620
10287
  * #1537). One line, built from the record: the ask and the caller's reply VERBATIM,
12621
10288
  * the notification they belong to, and the `contact` call that reaches the person
@@ -12651,7 +10318,7 @@ var AwaitItemSchema = external_exports.discriminatedUnion("type", [
12651
10318
  /** The awaited ask was REPLACED by a newer notification on its thread (e.g. a
12652
10319
  * post-feedback revision, #633) — the user will never answer this id. Stop
12653
10320
  * awaiting it; the live ask is the thread's newest turn (await that one, or
12654
- * re-orient via get_thread / check_replies). */
10321
+ * re-orient via check_replies). */
12655
10322
  external_exports.object({
12656
10323
  type: external_exports.literal("superseded"),
12657
10324
  parentId: external_exports.string(),
@@ -12765,10 +10432,6 @@ var InboxItemSchema = external_exports.object({
12765
10432
  options: external_exports.array(OptionSchema).optional(),
12766
10433
  /** The ask's declared coverage points (#396), when the agent sent them. */
12767
10434
  points: external_exports.array(external_exports.string()).optional(),
12768
- /** The call's AGENDA (broker/agenda-design.md): the ordered turns it is made of, built at
12769
- * ring/enqueue time. Replaces the condensed line + index-aligned phrased points, which
12770
- * between them could not express a call as a sequence. `question: null` is a real turn —
12771
- * a status update stays a statement instead of being shaped into a yes/no. */
12772
10435
  /** Does this claim want an ANSWER, or is it telling you something? Written per row from
12773
10436
  * `requestAsks` — the agent's own declaration, not a guess. `false` is what earns a card
12774
10437
  * its acknowledge affordance: without it a status update offers a text box and a dismiss,
@@ -12789,7 +10452,26 @@ var InboxItemSchema = external_exports.object({
12789
10452
  * instant the agent picks it up (#997). Absent = pre-trigger row; fall back to
12790
10453
  * `createdAt`. */
12791
10454
  agentStateAt: external_exports.string().datetime().optional(),
12792
- agenda: external_exports.array(AgendaTurnSchema).optional(),
10455
+ /** THE QUESTIONS A CALL CARRIES — the call screen's agenda spine (walk/design.md §11, owner
10456
+ * 2026-09-22). One per DecisionNeed on the Call, in the Call's order, answered or open (a
10457
+ * superseded or cancelled need is no longer a question anyone is asked). Present only on a
10458
+ * Call's cards, and every card of that Call carries the same list: the call screen reads it
10459
+ * once, off the one read it already makes (`GET /api/inbox/:callId`).
10460
+ *
10461
+ * It counts DECISIONS, not agenda turns: turns include context-only lines and are re-planned
10462
+ * every cycle, so a spine drawn from them would change length under the caller mid-call.
10463
+ *
10464
+ * `entryId` is the request Entry — the id the bot calls a CLAIM, and the one it names on the
10465
+ * `turn` topic (`asking`, `settled`), because the bot never sees a DecisionNeed id. `title` is
10466
+ * the card's own concise heading; `answer` the accepted answer in words, null while open. It
10467
+ * REPLACED `agenda` (turns), which nothing ever filled. */
10468
+ questions: external_exports.array(external_exports.object({
10469
+ id: external_exports.string(),
10470
+ entryId: external_exports.string(),
10471
+ title: external_exports.string(),
10472
+ state: external_exports.enum(["open", "answered"]),
10473
+ answer: external_exports.string().nullable()
10474
+ })).optional(),
12793
10475
  visuals: external_exports.array(VisualSchema).optional(),
12794
10476
  /** The connected agent's name (the single pairing name — user-typed, or the
12795
10477
  * agent's suggestion, or a default silly name). */
@@ -12810,12 +10492,21 @@ var InboxItemSchema = external_exports.object({
12810
10492
  * client may still flag a stall by age. Drives the inbox error badge + Retry. */
12811
10493
  error: external_exports.string().optional(),
12812
10494
  clarifies: external_exports.string().optional(),
12813
- /** The ring ladder ran out while this was still pending — we tried to reach you and
12814
- * STOPPED trying (`arbitration/arbitrate.ts` `nextRing` → `stop`). Distinct from an
12815
- * agent with nothing to say, which the roster drew identically until now: "nothing to
12816
- * say" and "gave up saying it" are opposite situations wearing the same face
12817
- * (navigation-design.md, gap 1). False for anything that never rang. */
12818
- gaveUp: external_exports.boolean().default(false),
10495
+ /** THE RING, ON THE ITEM (walk/design.md §12 §17, #2251): the last ring on this card was
10496
+ * declined, and what the ladder will do next — read off the cron's own row, never computed
10497
+ * on the phone. Present only while a `declined` receipt stands on the card's last Call.
10498
+ * The ladder is ACCOUNT-WIDE (#2259): `anchorAt` and `step` are the account's position;
10499
+ * `nextRingAt` is this card's armed instant (`deliveries.next_ring_at`), null once the cron
10500
+ * has disarmed it — the curve's end, `inbox`/`dismiss`, or a setting that said no more rings.
10501
+ * It replaced `gaveUp` (deleted 2026-09-22): "the ladder spent" was a boolean the projection
10502
+ * never set, and it is `nextRingAt === null` here — the party's *Missed you* (`party/dress.ts`)
10503
+ * and the roster's `unreached` read `declinedAt`, and stand while it does. */
10504
+ ring: external_exports.object({
10505
+ declinedAt: external_exports.string().datetime(),
10506
+ anchorAt: external_exports.string().datetime(),
10507
+ nextRingAt: external_exports.string().datetime().nullable(),
10508
+ step: external_exports.number().int()
10509
+ }).optional(),
12819
10510
  /** Why this arrived the way it did, read back off the delivery receipt (`notify/why.ts`).
12820
10511
  * Absent for anything never delivered through a push, and for older rows written before
12821
10512
  * the reason was recorded. Deliberately a debug affordance, shown small (owner,
@@ -12837,21 +10528,6 @@ var InboxItemSchema = external_exports.object({
12837
10528
  blocking: external_exports.boolean().default(false),
12838
10529
  /** The user's locked-in answer; present only for replied items (GET /api/replied/:id). */
12839
10530
  answer: UserAnswerSchema.optional(),
12840
- /** E2EE (text lane): the sealed content this item carries when the pairing is E2EE, in
12841
- * place of the plaintext `context`/`options`/`visuals` (which the operator would
12842
- * otherwise read). A per-field map of opaque Envelopes — the SAME shape as
12843
- * NotifyRequest.envelope. The native app decrypts it locally via openNotification;
12844
- * web / an un-enrolled device can't and renders a locked placeholder. Absent = today's
12845
- * plaintext item (context carries the cleartext), so plaintext items are unchanged. */
12846
- envelope: external_exports.object({
12847
- context: external_exports.lazy(() => EnvelopeSchema).optional(),
12848
- options: external_exports.lazy(() => EnvelopeSchema).optional(),
12849
- visuals: external_exports.lazy(() => EnvelopeSchema).optional()
12850
- }).optional(),
12851
- /** E2EE: the agent's device X25519 public key to seal the user's answer BACK to (the
12852
- * sender the phone replies to). Sourced server-side from this item's pairing credential.
12853
- * Present only alongside `envelope`; the phone seals via sealAnswer(answer, this, id). */
12854
- agentX25519: external_exports.string().optional(),
12855
10531
  /** THE TARGET FACTS A CARD RENDERS (#1796 point 5, 2026-09-11): the Delivery it is a view of,
12856
10532
  * that Delivery's kind, the request Entry, the Goals it answers for, the exact DecisionNeed (none
12857
10533
  * for a request that asks nothing), whether its content is sealed, and that Goal's state. The
@@ -12895,6 +10571,8 @@ var MissedCallSchema = external_exports.enum([
12895
10571
  "inbox",
12896
10572
  "dismiss"
12897
10573
  ]);
10574
+ var clock = (h) => h === 0 ? "midnight" : h === 12 ? "noon" : h < 12 ? `${h} am` : `${h - 12} pm`;
10575
+ var QUIET = ` Nothing rings from ${clock(NIGHT.from)} to ${clock(NIGHT.to)} your time; the count waits for morning.`;
12898
10576
  var BrokerTuningSchema = external_exports.object({
12899
10577
  /** 'none' = skip the spoken ack after a mapped answer (power users find it slow). */
12900
10578
  ackVerbosity: external_exports.enum(["normal", "none"]).optional(),
@@ -12929,6 +10607,12 @@ var UserSettingsSchema = external_exports.object({
12929
10607
  * must not silently reset this privacy choice. Absent = leave unchanged on
12930
10608
  * write, 'hosted' on read (see store.ts). */
12931
10609
  voiceMode: external_exports.enum(["hosted", "on_device"]).optional(),
10610
+ /** Talk — after you answer, the next step is read aloud (walk/design.md §6). ALWAYS ON until
10611
+ * turned off (owner, 2026-09-18, #2249): a setting, not a per-walk toggle. Optional, NOT
10612
+ * defaulted, for the same reason `voiceMode` is: a stale client PATCHing the full settings
10613
+ * object must not silently turn it back on. Absent = leave unchanged on write, true on
10614
+ * read (see store.ts). */
10615
+ talk: external_exports.boolean().optional(),
12932
10616
  /** Per-user ring budget (#603): calls per rolling day before further calls
12933
10617
  * degrade to banner. Absent = the global default (25). A number, never a
12934
10618
  * bypass — every account keeps a ceiling. No UI; set per user for testing. */
@@ -12949,13 +10633,6 @@ var UserSettingsSchema = external_exports.object({
12949
10633
  * setting. Absent = a spoken time can't be landed, so the reminder rides the next
12950
10634
  * call — honest about what we know. */
12951
10635
  timezone: external_exports.string().min(1).max(64).optional(),
12952
- /** Account E2EE state (text lane): 'off' (default) = today's plaintext; 'on' =
12953
- * content is sealed end-to-end between the local agent and the phone. Like
12954
- * voiceMode, OPTIONAL and NOT defaulted so a stale client PATCHing the full
12955
- * settings object without it can't silently flip the account's E2EE state.
12956
- * Absent = leave unchanged on write, 'off' on read (see store.ts). The demo
12957
- * account is plaintext by construction and refuses any non-'off' value. */
12958
- e2eeMode: external_exports.enum(["off", "on"]).optional(),
12959
10636
  /** Rung-2 broker tuning (#381). Optional and NOT defaulted, same stale-client
12960
10637
  * clobber guard as voiceMode: absent = leave unchanged on write. */
12961
10638
  broker: BrokerTuningSchema.optional()
@@ -13133,6 +10810,9 @@ var QueueItemSchema = external_exports.object({
13133
10810
  assignee: external_exports.string().nullable().default(null),
13134
10811
  /** What the agent last said it was doing; null if it has said nothing. */
13135
10812
  progress: external_exports.string().nullable().default(null),
10813
+ /** HOME'S LINE FOR THAT NOTE (owner, 2026-09-23): a few plain words one read wrote from `progress`,
10814
+ * served only while it was written for the current note. Null means show the Goal's name. */
10815
+ progressLine: external_exports.string().nullable().optional(),
13136
10816
  reviewPending: external_exports.boolean().default(false),
13137
10817
  dueAt: external_exports.string().nullable().default(null),
13138
10818
  /** The Goal this one was opened under; null at the root. */
@@ -13145,9 +10825,16 @@ var QueueItemSchema = external_exports.object({
13145
10825
  blocked: external_exports.boolean().default(false),
13146
10826
  /** Every decision need on it, open or settled — the page decides which to show. */
13147
10827
  questions: external_exports.array(QueueQuestionSchema).default([]),
10828
+ /** The repository or project identifier this Goal belongs to (#2280), null if untracked. */
10829
+ repo: external_exports.string().nullable().optional(),
13148
10830
  createdAt: external_exports.string(),
13149
- updatedAt: external_exports.string().nullable().default(null)
10831
+ updatedAt: external_exports.string().nullable().default(null),
10832
+ /** When its owner last SAID something about it (`goals.last_progress_at`, written by every
10833
+ * `update_goal` that changes `progress`). `updatedAt` moves for reasons nobody chose — a
10834
+ * state recomputed, a review flag — so it cannot tell work in hand from work gone quiet. */
10835
+ lastProgressAt: external_exports.string().nullable().optional()
13150
10836
  });
10837
+ var COLD_AFTER_MS = 3 * 24 * 60 * 60 * 1e3;
13151
10838
  var NoteSourceSchema = external_exports.enum(["app", "call"]);
13152
10839
  var NoteStatusSchema = external_exports.enum(["open", "assigned", "in_progress", "done"]);
13153
10840
  var NoteRepeatSchema = external_exports.enum(["once", "until_done"]);
@@ -13258,54 +10945,12 @@ var DeliveryConfigSchema = external_exports.object({
13258
10945
  * carries credentials; only a `poll` registration can come back with null here. */
13259
10946
  realtime: external_exports.object({ url: external_exports.string(), anonKey: external_exports.string() }).nullable()
13260
10947
  });
13261
- var EnvelopeRecipientSchema = external_exports.object({
13262
- keyId: external_exports.string(),
13263
- epk: external_exports.string(),
13264
- wnonce: external_exports.string(),
13265
- wrap: external_exports.string()
13266
- });
13267
- var EnvelopeHeaderSchema = external_exports.object({
13268
- field: external_exports.enum(["context", "options", "visuals", "answer"]),
13269
- kind: external_exports.string(),
13270
- senderRole: external_exports.enum(["agent", "user"]),
13271
- recipientKeyIds: external_exports.array(external_exports.string()),
13272
- seq: external_exports.number().int().nonnegative()
13273
- });
13274
- var EnvelopeSchema = external_exports.object({
13275
- v: external_exports.literal(1),
13276
- alg: external_exports.literal("x25519-xsalsa20poly1305"),
13277
- msgId: external_exports.string(),
13278
- hdr: EnvelopeHeaderSchema,
13279
- recipients: external_exports.array(EnvelopeRecipientSchema).min(1),
13280
- nonce: external_exports.string(),
13281
- ct: external_exports.string()
13282
- });
13283
- var SealedAnswerSchema = external_exports.object({
13284
- ignored: external_exports.boolean(),
13285
- envelope: EnvelopeSchema
13286
- });
13287
- var DeviceCredentialSchema = external_exports.object({
13288
- deviceId: external_exports.string(),
13289
- kind: external_exports.enum(["phone", "web", "agent"]),
13290
- x25519Pub: external_exports.string(),
13291
- ed25519Pub: external_exports.string(),
13292
- sig: external_exports.string()
13293
- });
13294
- var DeviceRosterSchema = external_exports.object({
13295
- uikPub: external_exports.string(),
13296
- devices: external_exports.array(DeviceCredentialSchema)
13297
- });
13298
10948
  var WakeNudgeSchema = external_exports.object({
13299
10949
  kind: external_exports.enum(["reply", "request", "callback"]),
13300
10950
  notificationId: external_exports.string().optional(),
13301
10951
  parentId: external_exports.string()
13302
10952
  });
13303
10953
  var PairingStatusSchema = external_exports.enum(["pending", "approved", "denied", "expired"]);
13304
- var PairingRevealSchema = external_exports.object({
13305
- x25519: external_exports.string(),
13306
- ed25519: external_exports.string(),
13307
- nonce: external_exports.string()
13308
- });
13309
10954
  var DeviceCodeSchema = external_exports.object({
13310
10955
  device_code: external_exports.string(),
13311
10956
  user_code: external_exports.string(),
@@ -13325,19 +10970,7 @@ var DeviceInfoSchema = external_exports.object({
13325
10970
  * (seen live: PAIGY-5T, 2026-07-21). Remove once a newer binary is the floor. */
13326
10971
  agent: external_exports.string().optional(),
13327
10972
  device: external_exports.string().nullable(),
13328
- status: PairingStatusSchema,
13329
- proto: external_exports.string().nullable().optional(),
13330
- agent_commitment: external_exports.string().nullable().optional(),
13331
- // Ca
13332
- agent_reveal: PairingRevealSchema.nullable().optional(),
13333
- // present once the agent reveals
13334
- agent_credential: DeviceCredentialSchema.nullable().optional(),
13335
- // the phone's UIK-signed cred over the agent's keys — the agent fetches it here to finalizeE2ee
13336
- // The phone's reveal + identity key, exposed here so a GATED agent (e2ee_mode='on', token
13337
- // withheld until e2ee=true) can compute the SAS WITHOUT a token. Public keys — same safety
13338
- // class as agent_reveal above. Present only once the phone reveals; null otherwise.
13339
- phone_reveal: PairingRevealSchema.nullable().optional(),
13340
- uik_pub: external_exports.string().nullable().optional()
10973
+ status: PairingStatusSchema
13341
10974
  });
13342
10975
  var DeviceTokenSchema = external_exports.object({
13343
10976
  access_token: external_exports.string(),
@@ -13356,8 +10989,6 @@ var DeviceTokenSchema = external_exports.object({
13356
10989
  * landed in the FIRST granted workspace and the agent rediscovered its own repo from
13357
10990
  * the thread each time (host.ts, live catch 2026-08-06 — prompt-papered until now). */
13358
10991
  workspace: external_exports.string().nullable().optional(),
13359
- phone_reveal: PairingRevealSchema.nullable().optional(),
13360
- // present once the phone reveals
13361
10992
  uik_pub: external_exports.string().nullable().optional()
13362
10993
  });
13363
10994
  var SupportRequestSchema = external_exports.object({
@@ -13379,29 +11010,19 @@ var NotificationFeedbackKindSchema = external_exports.enum([
13379
11010
  "other"
13380
11011
  // anything else — the note carries it.
13381
11012
  ]);
13382
- var FeedbackResolutionSchema = external_exports.enum(["broker_fixed", "sent_to_agent"]);
13383
- var FeedbackOutcomeSchema = external_exports.object({
13384
- resolution: FeedbackResolutionSchema,
13385
- transform: TransformSchema,
13386
- message: external_exports.string(),
13387
- childIds: external_exports.array(external_exports.string()).optional()
13388
- });
13389
- var import_tweetnacl = __toESM2(require_nacl_fast(), 1);
13390
- var import_tweetnacl2 = __toESM2(require_nacl_fast(), 1);
13391
- var import_tweetnacl3 = __toESM2(require_nacl_fast(), 1);
13392
- var import_tweetnacl4 = __toESM2(require_nacl_fast(), 1);
13393
- var import_tweetnacl5 = __toESM2(require_nacl_fast(), 1);
13394
11013
  function sessionSlot(sessionId2) {
13395
11014
  const id = sessionId2 ?? sessionId();
13396
11015
  return `session:${id.slice(0, 8)}`;
13397
11016
  }
13398
- var AGENT_NAME = process.env.PAIGY_AGENT || sessionSlot();
13399
- var TOKEN_PATH = join(homedir(), ".paigy", "token.json");
13400
- var KEY_PATH = join(homedir(), ".paigy", "key.json");
11017
+ function agentName() {
11018
+ return process.env.PAIGY_AGENT || sessionSlot();
11019
+ }
11020
+ var TOKEN_PATH = join2(homedir2(), ".paigy", "token.json");
11021
+ var KEY_PATH = join2(homedir2(), ".paigy", "key.json");
13401
11022
  function readTokenFile() {
13402
11023
  if (!existsSync(TOKEN_PATH)) return {};
13403
11024
  try {
13404
- const parsed = JSON.parse(readFileSync(TOKEN_PATH, "utf8"));
11025
+ const parsed = JSON.parse(readFileSync2(TOKEN_PATH, "utf8"));
13405
11026
  if (typeof parsed.access_token === "string") return {};
13406
11027
  const slots = parsed;
13407
11028
  delete slots["*"];
@@ -13413,7 +11034,7 @@ function readTokenFile() {
13413
11034
  function withTokenLock(mutate) {
13414
11035
  const lock = TOKEN_PATH + ".lock";
13415
11036
  const spin = new Int32Array(new SharedArrayBuffer(4));
13416
- mkdirSync(join(homedir(), ".paigy"), { recursive: true });
11037
+ mkdirSync(join2(homedir2(), ".paigy"), { recursive: true });
13417
11038
  for (const deadline = Date.now() + 5e3; Date.now() < deadline; ) {
13418
11039
  try {
13419
11040
  closeSync(openSync(lock, "wx"));
@@ -13430,7 +11051,7 @@ function withTokenLock(mutate) {
13430
11051
  rmSync(lock, { force: true });
13431
11052
  }
13432
11053
  }
13433
- function saveToken(token, agent2 = AGENT_NAME) {
11054
+ function saveToken(token, agent2 = agentName()) {
13434
11055
  withTokenLock(() => {
13435
11056
  const slots = { ...readTokenFile(), [agent2]: token };
13436
11057
  writeFileSync(TOKEN_PATH, JSON.stringify(slots, null, 2) + "\n", { mode: 384 });
@@ -13451,7 +11072,7 @@ function slotIdentity(agent2) {
13451
11072
  return { name: t?.name ?? null, voice: t?.voice ?? null, tokenId: t?.token_id ?? null, workspace: t?.workspace ?? null };
13452
11073
  }
13453
11074
  var sleep = (ms) => new Promise((r) => setTimeout(r, ms));
13454
- function readToken(agent2 = AGENT_NAME) {
11075
+ function readToken(agent2 = agentName()) {
13455
11076
  if (process.env.PAIGY_TOKEN) return process.env.PAIGY_TOKEN;
13456
11077
  return readTokenFile()[agent2]?.access_token ?? "";
13457
11078
  }
@@ -13461,24 +11082,23 @@ function listSlots() {
13461
11082
  function slotName(agent2) {
13462
11083
  return readTokenFile()[agent2]?.name ?? null;
13463
11084
  }
13464
- async function requestCode(suggestedName = AGENT_NAME, e2ee, device) {
11085
+ async function requestCode(suggestedName = agentName(), device) {
13465
11086
  const res = await reach(`${BACKEND_URL}/api/device/code`, {
13466
11087
  method: "POST",
13467
11088
  headers: { "content-type": "application/json" },
13468
11089
  body: JSON.stringify({
13469
11090
  suggestedName,
13470
- ...device ? { device } : {},
13471
- ...e2ee ? { proto: e2ee.proto, commitment: e2ee.commitment } : {}
11091
+ ...device ? { device } : {}
13472
11092
  })
13473
11093
  });
13474
11094
  if (!res.ok) throw new Error(`/api/device/code failed: ${res.status} ${await res.text()}`);
13475
11095
  return await res.json();
13476
11096
  }
13477
- async function pollToken(deviceCode, reveal) {
11097
+ async function pollToken(deviceCode) {
13478
11098
  const res = await reach(`${BACKEND_URL}/api/device/token`, {
13479
11099
  method: "POST",
13480
11100
  headers: { "content-type": "application/json" },
13481
- body: JSON.stringify(reveal ? { device_code: deviceCode, reveal } : { device_code: deviceCode })
11101
+ body: JSON.stringify({ device_code: deviceCode })
13482
11102
  });
13483
11103
  if (res.ok) return await res.json();
13484
11104
  const body = await res.json().catch(() => ({ error: "unknown" }));
@@ -13490,14 +11110,6 @@ async function pollToken(deviceCode, reveal) {
13490
11110
  if (err === "access_denied") throw new Error("Access denied by user. Pairing cancelled.");
13491
11111
  throw new Error(`Unexpected error from /api/device/token: ${err}`);
13492
11112
  }
13493
- function readKeyFile() {
13494
- if (!existsSync(KEY_PATH)) return null;
13495
- try {
13496
- return JSON.parse(readFileSync(KEY_PATH, "utf8"));
13497
- } catch {
13498
- return null;
13499
- }
13500
- }
13501
11113
  var UnpairedError = class extends Error {
13502
11114
  constructor() {
13503
11115
  super("Not paired with Paigy \u2014 no valid token (the API answered 401). Run the pairing flow, then retry.");
@@ -13523,9 +11135,21 @@ var ApiError = class extends Error {
13523
11135
  this.body = body;
13524
11136
  }
13525
11137
  };
11138
+ var tokenOverride = null;
11139
+ var authToken = (explicit) => explicit ?? tokenOverride ?? readToken();
13526
11140
  async function fail(what, res) {
13527
11141
  throw new ApiError(what, res.status, await res.text());
13528
11142
  }
11143
+ async function createGoal(input, opts = {}) {
11144
+ const token = authToken(opts.token) ?? "";
11145
+ const res = ensureAuthed(await (opts.reach ?? reach)(`${BACKEND_URL}/api/goals`, {
11146
+ method: "POST",
11147
+ headers: { "content-type": "application/json", authorization: `Bearer ${token}`, "x-paigy-model": "goal-entry-v1" },
11148
+ body: JSON.stringify(input)
11149
+ }));
11150
+ if (!res.ok) await fail("create_goal", res);
11151
+ return await res.json();
11152
+ }
13529
11153
  async function claimGoal(goalId, opts = {}) {
13530
11154
  const token = authToken(opts.token) ?? "";
13531
11155
  const res = ensureAuthed(await (opts.reach ?? reach)(`${BACKEND_URL}/api/goals/claim`, { method: "POST", headers: { "content-type": "application/json", authorization: `Bearer ${token}`, "x-paigy-model": "goal-entry-v1" }, body: JSON.stringify(goalId ? { goalId } : {}) }));
@@ -13549,8 +11173,6 @@ async function updateGoal(goalId, input, opts = {}) {
13549
11173
  return await res.json();
13550
11174
  }
13551
11175
  var AWAIT_WINDOW_MS = 45e3;
13552
- var tokenOverride = null;
13553
- var authToken = (explicit) => explicit ?? tokenOverride ?? readToken();
13554
11176
  async function whoAmI(opts = {}) {
13555
11177
  try {
13556
11178
  const res = await reach(`${BACKEND_URL}/api/identity`, {
@@ -13637,31 +11259,77 @@ async function dismissTriage(proposalId, opts = {}) {
13637
11259
  if (!res.ok) throw new Error(`dismiss_triage failed: ${res.status} ${await res.text()}`);
13638
11260
  return await res.json();
13639
11261
  }
11262
+ function repoFromRemote(url) {
11263
+ const said = (url ?? "").trim();
11264
+ if (!said) return null;
11265
+ const path = said.replace(/^[a-z+]+:\/\/[^/]+\//i, "").replace(/^[^@]+@[^:]+:/, "").replace(/\.git$/i, "").replace(/\/+$/, "");
11266
+ const parts = path.split("/").filter(Boolean);
11267
+ if (parts.length < 2) return null;
11268
+ const [owner, name] = parts.slice(-2);
11269
+ if (!owner || !name) return null;
11270
+ return `${owner}/${name}`.toLowerCase();
11271
+ }
11272
+ var asked;
11273
+ function currentRepo(cwd = process.cwd()) {
11274
+ if (asked !== void 0) return asked;
11275
+ try {
11276
+ const url = execFileSync2("git", ["remote", "get-url", "origin"], {
11277
+ cwd,
11278
+ encoding: "utf8",
11279
+ timeout: 2e3,
11280
+ stdio: ["ignore", "pipe", "ignore"]
11281
+ });
11282
+ asked = repoFromRemote(url);
11283
+ } catch {
11284
+ asked = null;
11285
+ }
11286
+ return asked;
11287
+ }
13640
11288
  async function contact(input, opts = {}) {
13641
11289
  const parsed = ContactSchema.parse(input);
13642
11290
  opts.signal?.throwIfAborted();
13643
11291
  const send22 = opts.reach ?? reach;
13644
11292
  const headers = { "content-type": "application/json", authorization: `Bearer ${authToken(opts.token) ?? ""}`, "x-paigy-model": "goal-entry-v1" };
13645
11293
  let deliveryId;
13646
- if ("deliveryId" in parsed) deliveryId = parsed.deliveryId;
13647
- else {
13648
- if (!opts.reach && readKeyFile()?.e2ee) throw new Error("Goal contact does not support E2EE yet; refusing to send plaintext.");
13649
- const shaped = deriveAsk(NotifyRequestSchema.parse({ ask: parsed.ask, waiting: parsed.waiting, options: parsed.options }));
13650
- const res = ensureAuthed(await send22(`${BACKEND_URL}/api/goals/${parsed.goalIds[0]}/contact`, {
11294
+ let deliveries = [];
11295
+ if ("deliveryId" in parsed) {
11296
+ deliveryId = parsed.deliveryId;
11297
+ } else {
11298
+ const reqAsks = parsed.asks.map((a) => ({
11299
+ id: a.id,
11300
+ parentId: a.parentId,
11301
+ // Derived, not asked for (#2315): the agent's own remote, in one spelling, so a project's
11302
+ // work does not grow three trees for "paigy", "mauurda/paigy" and "Paigy". An explicit one
11303
+ // still wins — normalised the same way — because a caller that names one knows something
11304
+ // this cannot see.
11305
+ repo: repoFromRemote(a.repo) ?? a.repo ?? currentRepo() ?? void 0,
11306
+ ask: a.ask,
11307
+ options: a.options ?? []
11308
+ }));
11309
+ const res = ensureAuthed(await send22(`${BACKEND_URL}/api/goals/contact`, {
13651
11310
  method: "POST",
13652
11311
  headers,
13653
11312
  signal: opts.signal,
13654
- body: JSON.stringify({ operationId: opts.operationId ?? randomUUID3(), threadId: parsed.threadId ?? null, content: parsed.ask, select: shaped.select, options: shaped.options ?? [], blocking: parsed.waiting === "hard", channel: parsed.channel === "call" ? "call" : "message" })
11313
+ body: JSON.stringify({
11314
+ operationId: opts.operationId ?? randomUUID3(),
11315
+ asks: reqAsks,
11316
+ waiting: parsed.waiting,
11317
+ channel: parsed.channel === "call" ? "call" : "message"
11318
+ })
13655
11319
  }));
13656
- if (!res.ok) await fail("goal contact", res);
11320
+ if (!res.ok) await fail("batch contact", res);
13657
11321
  const receipt = await res.json();
13658
- deliveryId = receipt.deliveryId ?? receipt.callId ?? receipt.notificationId ?? "";
13659
- if (!deliveryId) throw new Error("Goal contact returned no Delivery identity");
11322
+ deliveries = receipt.deliveries ?? [];
11323
+ if (deliveries.length === 0) throw new Error("Goal contact returned no Delivery identities");
11324
+ deliveryId = deliveries[0]?.deliveryId ?? "";
11325
+ if (!deliveryId) throw new Error("Goal contact returned no valid Delivery identity");
13660
11326
  }
11327
+ const all = deliveries.filter((d) => !!d.deliveryId && !!d.goalId);
13661
11328
  const read = async (signal2) => {
13662
11329
  const res = ensureAuthed(await send22(`${BACKEND_URL}/api/deliveries/${encodeURIComponent(deliveryId)}`, { headers, signal: signal2 }));
13663
11330
  if (!res.ok) await fail("read_delivery", res);
13664
- return await res.json();
11331
+ const one = await res.json();
11332
+ return all.length > 1 ? { ...one, deliveries: all } : one;
13665
11333
  };
13666
11334
  const settled = (d) => d.kind === "notification" || d.state === "closed" || d.answers.length > 0 || d.entries.some((e) => e.kind === "contribution");
13667
11335
  if (opts.waits === false) return read(opts.signal);
@@ -13765,7 +11433,8 @@ function subscribeRealtime(args) {
13765
11433
  };
13766
11434
  }
13767
11435
  async function subscribeWake(onNudge, opts = {}) {
13768
- const cfg = await registerDelivery("self_hosted", opts);
11436
+ const { release = true, ...client } = opts;
11437
+ const cfg = await registerDelivery("self_hosted", client);
13769
11438
  const { url, anonKey } = cfg.realtime;
13770
11439
  const channel = wakeChannel(cfg.tokenId);
13771
11440
  const ch = subscribeRealtime({
@@ -13780,7 +11449,7 @@ async function subscribeWake(onNudge, opts = {}) {
13780
11449
  channel,
13781
11450
  close: async () => {
13782
11451
  ch.close();
13783
- await registerDelivery("poll", opts).catch(() => {
11452
+ if (release) await registerDelivery("poll", client).catch(() => {
13784
11453
  });
13785
11454
  }
13786
11455
  };
@@ -13788,13 +11457,13 @@ async function subscribeWake(onNudge, opts = {}) {
13788
11457
 
13789
11458
  // src/main.ts
13790
11459
  var import_qrcode = __toESM(require_lib(), 1);
13791
- import { homedir as homedir8, hostname } from "os";
11460
+ import { homedir as homedir9, hostname } from "os";
13792
11461
 
13793
11462
  // src/harness/catalog.ts
13794
11463
  import { spawnSync } from "child_process";
13795
11464
  import { existsSync as existsSync2 } from "fs";
13796
- import { homedir as homedir2 } from "os";
13797
- import { delimiter, dirname, join as join2 } from "path";
11465
+ import { homedir as homedir3 } from "os";
11466
+ import { delimiter, dirname, join as join3 } from "path";
13798
11467
  var CATALOG = [
13799
11468
  {
13800
11469
  name: "claude",
@@ -13827,13 +11496,13 @@ var CATALOG = [
13827
11496
  installCli: "curl -fsSL https://antigravity.dev/install.sh | bash"
13828
11497
  }
13829
11498
  ];
13830
- function probeDirs(home = homedir2()) {
11499
+ function probeDirs(home = homedir3()) {
13831
11500
  return [
13832
11501
  dirname(process.execPath),
13833
- join2(home, ".local", "bin"),
11502
+ join3(home, ".local", "bin"),
13834
11503
  "/usr/local/bin",
13835
11504
  "/opt/homebrew/bin",
13836
- join2(home, ".npm-global", "bin")
11505
+ join3(home, ".npm-global", "bin")
13837
11506
  ];
13838
11507
  }
13839
11508
  function which(bin) {
@@ -13841,7 +11510,7 @@ function which(bin) {
13841
11510
  const fromPath = hit.status === 0 ? hit.stdout.trim() : "";
13842
11511
  if (fromPath) return fromPath;
13843
11512
  for (const dir of probeDirs()) {
13844
- const candidate = join2(dir, bin);
11513
+ const candidate = join3(dir, bin);
13845
11514
  if (existsSync2(candidate)) return candidate;
13846
11515
  }
13847
11516
  return null;
@@ -13881,27 +11550,27 @@ function detectAll(deps = {}) {
13881
11550
  }
13882
11551
 
13883
11552
  // src/host.ts
13884
- import { readFileSync as readFileSync3, writeFileSync as writeFileSync3 } from "fs";
13885
- import { homedir as homedir6 } from "os";
13886
- import { join as join6 } from "path";
11553
+ import { readFileSync as readFileSync4, writeFileSync as writeFileSync3 } from "fs";
11554
+ import { homedir as homedir7 } from "os";
11555
+ import { join as join7 } from "path";
13887
11556
 
13888
11557
  // src/workspaces.ts
13889
- import { existsSync as existsSync3, mkdirSync as mkdirSync2, readFileSync as readFileSync2, writeFileSync as writeFileSync2 } from "fs";
13890
- import { dirname as dirname2, join as join3, resolve } from "path";
13891
- import { homedir as homedir3 } from "os";
11558
+ import { existsSync as existsSync3, mkdirSync as mkdirSync2, readFileSync as readFileSync3, writeFileSync as writeFileSync2 } from "fs";
11559
+ import { dirname as dirname2, join as join4, resolve } from "path";
11560
+ import { homedir as homedir4 } from "os";
13892
11561
  function workspacesFile() {
13893
- return join3(homedir3(), ".paigy", "workspaces.json");
11562
+ return join4(homedir4(), ".paigy", "workspaces.json");
13894
11563
  }
13895
11564
  function listWorkspaces(deps) {
13896
11565
  try {
13897
- const parsed = JSON.parse(readFileSync2(deps.file, "utf8"));
11566
+ const parsed = JSON.parse(readFileSync3(deps.file, "utf8"));
13898
11567
  return Array.isArray(parsed) ? parsed.filter((w) => typeof w === "string") : [];
13899
11568
  } catch {
13900
11569
  return [];
13901
11570
  }
13902
11571
  }
13903
11572
  function addWorkspace(dir, deps) {
13904
- const next = resolve(dir.replace(/^~(?=$|\/)/, homedir3()));
11573
+ const next = resolve(dir.replace(/^~(?=$|\/)/, homedir4()));
13905
11574
  const all = listWorkspaces(deps);
13906
11575
  if (!all.includes(next)) {
13907
11576
  all.push(next);
@@ -13917,12 +11586,12 @@ function removeWorkspace(dir, deps) {
13917
11586
  return all;
13918
11587
  }
13919
11588
  function allowed(cwd, deps) {
13920
- const target = resolve(cwd.replace(/^~(?=$|\/)/, homedir3()));
11589
+ const target = resolve(cwd.replace(/^~(?=$|\/)/, homedir4()));
13921
11590
  return listWorkspaces(deps).some((w) => target === w || target.startsWith(`${w}/`));
13922
11591
  }
13923
11592
  function resolveWakeDir(pinned, deps) {
13924
11593
  if (pinned && allowed(pinned, deps)) {
13925
- const dir = resolve(pinned.replace(/^~(?=$|\/)/, homedir3()));
11594
+ const dir = resolve(pinned.replace(/^~(?=$|\/)/, homedir4()));
13926
11595
  if ((deps.exists ?? existsSync3)(dir)) return dir;
13927
11596
  }
13928
11597
  return listWorkspaces(deps)[0];
@@ -13930,8 +11599,8 @@ function resolveWakeDir(pinned, deps) {
13930
11599
 
13931
11600
  // src/owner.ts
13932
11601
  import { closeSync as closeSync2, openSync as openSync2, readSync, readdirSync } from "fs";
13933
- import { homedir as homedir4 } from "os";
13934
- import { join as join4 } from "path";
11602
+ import { homedir as homedir5 } from "os";
11603
+ import { join as join5 } from "path";
13935
11604
  var HEAD_BYTES = 64e3;
13936
11605
  function readHead(file) {
13937
11606
  const fd = openSync2(file, "r");
@@ -13947,7 +11616,7 @@ function ownerSession(slot, deps = {}) {
13947
11616
  const m = /^session:([0-9a-f]{8})$/.exec(slot);
13948
11617
  if (!m) return null;
13949
11618
  const prefix = m[1];
13950
- const root = deps.projectsDir ?? join4(homedir4(), ".claude", "projects");
11619
+ const root = deps.projectsDir ?? join5(homedir5(), ".claude", "projects");
13951
11620
  const list = deps.list ?? ((dir) => readdirSync(dir));
13952
11621
  const head = deps.head ?? readHead;
13953
11622
  let folders;
@@ -13959,7 +11628,7 @@ function ownerSession(slot, deps = {}) {
13959
11628
  for (const folder of folders) {
13960
11629
  let files;
13961
11630
  try {
13962
- files = list(join4(root, folder));
11631
+ files = list(join5(root, folder));
13963
11632
  } catch {
13964
11633
  continue;
13965
11634
  }
@@ -13967,7 +11636,7 @@ function ownerSession(slot, deps = {}) {
13967
11636
  if (!file) continue;
13968
11637
  let text;
13969
11638
  try {
13970
- text = head(join4(root, folder, file));
11639
+ text = head(join5(root, folder, file));
13971
11640
  } catch {
13972
11641
  continue;
13973
11642
  }
@@ -15271,6 +12940,23 @@ var zodToJsonSchema2 = (schema, options) => {
15271
12940
  // ../../packages/schema/dist/index.js
15272
12941
  var OPTIONS_MIN2 = 2;
15273
12942
  var OPTIONS_MAX2 = 6;
12943
+ var OptionSchema2 = external_exports.object({
12944
+ id: external_exports.string(),
12945
+ label: external_exports.string(),
12946
+ hint: external_exports.string().max(500).describe("Optional short projection of consequence or action if this option is chosen (e.g. 'Reruns test suite', 'Merges to main').").optional(),
12947
+ // .describe() flows into the MCP contact JSON schema (zodToJsonSchema), so
12948
+ // the constraints below are what an agent reads when deciding to use these.
12949
+ html: external_exports.string().max(16384).describe(
12950
+ "Optional sandboxed HTML/CSS preview for a visual 'pick one' (shown in the option card). Untrusted-sandboxed: NO JavaScript, NO external network or images \u2014 inline CSS and data: URIs only; <=16KB. Rendered edge-to-edge in a responsive card that is 200pt tall (about 320pt wide on a phone, with the next option peeking beside it); make your HTML fit that viewport. Use for layout/CSS mockups, tables, diffs. For a hosted image use `image` instead."
12951
+ ).optional(),
12952
+ image: external_exports.string().url().describe(
12953
+ "Optional image URL rendered as the option's preview (plain image, not sandboxed). For agent-generated HTML/CSS mockups, use `html` instead."
12954
+ ).optional()
12955
+ });
12956
+ var OptionInputSchema2 = OptionSchema2.omit({ id: true }).extend({
12957
+ label: external_exports.string().trim().min(1).max(1e3)
12958
+ }).strict();
12959
+ var NIGHT2 = { from: 23, to: 7 };
15274
12960
  function draft20202(node) {
15275
12961
  if (Array.isArray(node)) return node.map(draft20202);
15276
12962
  if (node && typeof node === "object") {
@@ -15300,32 +12986,23 @@ function mcpInputSchema2(s) {
15300
12986
  delete schema.$schema;
15301
12987
  return draft20202(schema);
15302
12988
  }
15303
- var StartContactSchema2 = external_exports.object({
15304
- goalIds: external_exports.tuple([external_exports.string().uuid()]),
15305
- // THE ASK IS THE QUESTION, not a bulletin with a question at the end (2026-09-16).
15306
- //
15307
- // A DecisionNeed is settled only by an answer in the shape THIS ask declares. Bundle news,
15308
- // findings and a decision into one, and the person answers whichever part engaged them —
15309
- // which settles nothing, leaves the need open, and gets them asked again. On call 619c5a92
15310
- // one ask carried a briefing, a side question ("the ring should show the agent's name now —
15311
- // what did you actually see?") and a one-of-four about how far an erase reaches. The owner
15312
- // answered the side question. The need stayed open; the card asked again. Of the 45 call
15313
- // asks carrying a decision, 27 are over 600 characters.
15314
- //
15315
- // Sending them separately costs nothing, because a CALL contact joins the call already
15316
- // happening (`goal/store.ts`, JOIN BEFORE MINTING) — several contacts on one Goal arrive as
15317
- // one call, planned as its turns, and each keeps its own settleable need.
12989
+ var AskInputSchema2 = external_exports.object({
12990
+ id: external_exports.string().optional().describe("Optional idempotency key or client-side ID for this specific ask."),
12991
+ parentId: external_exports.string().uuid().optional().describe("The Goal this question is about \u2014 usually the one you are working on. The question goes onto that Goal and its answer comes back there. Omit it and Paigy places the question in the tree itself."),
12992
+ repo: external_exports.string().optional().describe("Optional repository context."),
15318
12993
  ask: external_exports.string().trim().min(1).max(1e4).describe(
15319
12994
  "The question, and only what is needed to answer it. News, progress and findings are their own contact \u2014 a call contact JOINS a call already happening, so several arrive as one call. Do not bundle: a DecisionNeed is settled only by an answer in the shape this ask declares, so someone who answers the part that interested them settles nothing and is asked again."
15320
12995
  ),
12996
+ options: external_exports.array(OptionInputSchema2).min(2).max(6).optional()
12997
+ }).strict();
12998
+ var StartContactSchema2 = external_exports.object({
12999
+ asks: external_exports.array(AskInputSchema2).min(1).describe("The questions to pose, one per object. An ask with a parentId is filed on that Goal as it is; only an ask naming no Goal is placed in the tree by Paigy."),
15321
13000
  waiting: external_exports.enum(["none", "hard"]).default("none"),
15322
- channel: external_exports.enum(["notification", "call"]).default("notification"),
15323
- options: external_exports.array(external_exports.object({ label: external_exports.string().trim().min(1).max(1e3), image: external_exports.string().url().optional(), html: external_exports.string().max(16384).optional() }).strict()).min(2).max(6).optional(),
15324
- threadId: external_exports.string().uuid().optional().describe("Continue an existing Thread: the threadId a prior Delivery returned. Omit to start a new Thread.")
13001
+ channel: external_exports.enum(["notification", "call"]).default("notification")
15325
13002
  }).strict();
15326
13003
  var ContactSchema2 = external_exports.union([StartContactSchema2, external_exports.object({ deliveryId: external_exports.string().uuid() }).strict()]);
15327
13004
  var CONTACT_SCHEMA2 = { type: "object", ...mcpInputSchema2(ContactSchema2) };
15328
- var CONTACT_DESCRIPTION2 = "Contact the user about exactly one existing Goal: pass goalIds:[goalId], ask, channel:'notification'|'call', and waiting:'none'|'hard'. Options supply choices. Notification returns immediately; collect durable answers with claim_goal/get_goal. On stdio, a Call holds one cancellable ~45s window; continue with ONLY {deliveryId}. Continuation sends nothing and rereads the same durable evidence, including previously read answers. Entries retain authorship and provenance; accepted decisions are separate from quoted speech. Call state open does not mean ringing. Unsupported: soft waiting, multiple Goals/questions, outcome admission, and re-presentation of an existing request. Create a Goal explicitly first; never resend a pending ask to continue waiting.";
13005
+ var CONTACT_DESCRIPTION2 = "Contact the user with one or more asks/questions. Pass an array of asks (each with 'ask', optional 'options', 'id', 'parentId', 'repo'), plus channel:'notification'|'call', and waiting:'none'|'hard'. An ask that names a Goal (parentId) goes onto that Goal; one that names none is placed in the person's tree by Paigy. Notification returns immediately; collect durable answers with check_replies. On stdio, a Call holds one cancellable ~45s window; continue with ONLY {deliveryId}. Never bundle multiple questions into a single 'ask' string; pass them as separate objects in the 'asks' array.";
15329
13006
  var CreateGoalSchema2 = external_exports.object({
15330
13007
  outcome: external_exports.string().trim().min(1).max(1e4),
15331
13008
  /** The work's NAME (#2115) — one to five words, how a person refers to it out loud ("the night
@@ -15333,11 +13010,6 @@ var CreateGoalSchema2 = external_exports.object({
15333
13010
  title: external_exports.string().trim().min(1).max(80).optional(),
15334
13011
  ownerParticipant: external_exports.string().trim().min(1).optional(),
15335
13012
  idempotencyKey: external_exports.string().trim().min(1).max(200),
15336
- /** A past conversation this Goal should be read against — History's "new session from this"
15337
- * (owner, on the call of 2026-09-14: "let's do the reference with the threading"). A
15338
- * reference only: the owner reads it through `get_thread`, which does its own scoping, and
15339
- * the writer refuses a thread belonging to another account. */
15340
- contextThreadId: external_exports.string().uuid().optional(),
15341
13013
  /** THE GOAL THIS ONE BELONGS UNDER (owner, 2026-09-15: "the ask I gave for the design doc
15342
13014
  * didn't get created as a child goal of the voice UI goal, which is how it should've
15343
13015
  * worked"). It could not have been: this door took no parent, so the only route was
@@ -15345,12 +13017,15 @@ var CreateGoalSchema2 = external_exports.object({
15345
13017
  * took the short one. The hierarchy has been modelled since Goals existed and had been used
15346
13018
  * ZERO times in 2,031 of them. Absent, the server judges it against the caller's open Goals
15347
13019
  * (`apps/api/src/goal/intake.ts`). The writer refuses a Goal belonging to another account. */
15348
- parentGoalId: external_exports.string().uuid().optional()
13020
+ parentGoalId: external_exports.string().uuid().optional(),
13021
+ /** The repository or project identifier this Goal belongs to (#2280) — e.g. "owner/repo" or
13022
+ * repo name. Delegated work inherits this from its parent Goal when omitted. */
13023
+ repo: external_exports.string().trim().min(1).max(200).optional()
15349
13024
  });
15350
13025
  var CreateGoalToolSchema2 = CreateGoalSchema2.extend({
15351
13026
  idempotencyKey: CreateGoalSchema2.shape.idempotencyKey.optional().describe("Optional. One is minted per call; pass your own only so a retry lands on the same Goal.")
15352
13027
  }).strict();
15353
- var CREATE_GOAL_DESCRIPTION2 = 'Create a durable Goal for an outcome. Without parentGoalId it is placed against your open Goals: if one already IS this work, that Goal comes back (existing: true) and nothing new is created \u2014 continue it; if the work belongs under one, it is created there (parentGoalId in the receipt); otherwise it is a root. Pass parentGoalId yourself to put it under a specific Goal. Pass title to name it in one to five words, as a person would refer to it out loud ("the night rings") \u2014 it heads every list and is spoken on a call; without one the brain writes it. Admission only: the owner must claim it before doing work, then update it as it advances. Returns an admission receipt with goalId, current state, revision, ownerParticipant, and the next step; no Goal content or execution lease.';
13028
+ var CREATE_GOAL_DESCRIPTION2 = 'Create a durable Goal for an outcome. Without parentGoalId it is placed against your open Goals: if one already IS this work, that Goal comes back (existing: true) and nothing new is created \u2014 continue it; if the work belongs under one, it is created there (parentGoalId in the receipt); otherwise it is a root. Pass parentGoalId yourself to put it under a specific Goal. Pass repo to anchor the work to a specific repository ("owner/repo" or repo name); delegated children inherit it. Pass title to name it in one to five words, as a person would refer to it out loud ("the night rings") \u2014 it heads every list and is spoken on a call; without one the brain writes it. Admission only: the owner must claim it before doing work, then update it as it advances. Returns an admission receipt with goalId, current state, revision, ownerParticipant, and the next step; no Goal content or execution lease.';
15354
13029
  var UpdateGoalSchema2 = external_exports.object({
15355
13030
  revision: external_exports.number().int().positive(),
15356
13031
  changes: external_exports.object({
@@ -15378,19 +13053,9 @@ var UPDATE_GOAL_DESCRIPTION2 = "Update an owned Goal at an exact revision. State
15378
13053
  var CLAIM_GOAL_DESCRIPTION2 = "Claim the oldest runnable or review-pending Goal you own, or pass goalId to claim that Goal. Returns the Goal as get_goal reads it, and creates or renews the execution lease.";
15379
13054
  var CHECK_REPLIES_DESCRIPTION2 = "Your open Deliveries: every Notification or Call currently addressed to you \u2014 a request the user started toward you, an answer relayed to something you asked, a handoff \u2014 one row each: its Goals, how many decisions are still open, and the newest words in brief. A pure read with no arguments: nothing is consumed, acknowledged or claimed by reading it, so call it on startup, after a long wait, or whenever you want to know what is outstanding. To act on one, claim its Goal (claim_goal) or reread it in full with contact({deliveryId}). Once you have acted on what arrived, update_goal with reviewed: true closes the Deliveries addressed to you on that Goal. Your runnable and review-pending Goals come from claim_goal, not from here.";
15380
13055
  var CheckRepliesSchema2 = external_exports.object({}).strict();
15381
- var GetThreadSchema2 = external_exports.object({
15382
- parentId: external_exports.string().describe("The Thread to read \u2014 the threadId a Delivery returned, or the parentId of a search hit.")
15383
- }).strict();
15384
- var GET_THREAD_DESCRIPTION2 = "Read the authorized durable Entries on one conversation Thread \u2014 what you wrote there and what was delivered to you, oldest first. Use claim_goal to find the work to resume; use this to rehydrate a Thread that a search hit or a Delivery named.";
15385
- var SearchThreadsSchema2 = external_exports.object({
15386
- q: external_exports.string().describe("What to look for \u2014 plain words or a phrase (e.g. 'the livekit timeout', 'deploy to prod').")
15387
- }).strict();
15388
- var SEARCH_THREADS_DESCRIPTION2 = `Search your PAST conversations before asking \u2014 "have we discussed this before?". Full-text over your own threads (the asks you sent + the user's answers); returns ranked threads with highlighted snippets, NOT rows: { hits: [{ parentId, at, agentLabel, matches: [{ notificationId, role, snippet }] }] }. The loop this exists for: search first \u2192 get_thread the best hit to rehydrate it \u2192 THEN continue or contact, so you answer with receipts ("last week you said ship it") instead of re-asking. Read-only, safe to call anytime; scoped to your own account's threads.`;
15389
13056
  var AGENT_TOOLS2 = [
15390
13057
  { name: "contact", description: CONTACT_DESCRIPTION2, inputSchema: CONTACT_SCHEMA2 },
15391
13058
  { name: "check_replies", description: CHECK_REPLIES_DESCRIPTION2, inputSchema: mcpInputSchema2(CheckRepliesSchema2) },
15392
- { name: "get_thread", description: GET_THREAD_DESCRIPTION2, inputSchema: mcpInputSchema2(GetThreadSchema2) },
15393
- { name: "search_threads", description: SEARCH_THREADS_DESCRIPTION2, inputSchema: mcpInputSchema2(SearchThreadsSchema2) },
15394
13059
  { name: "create_goal", description: CREATE_GOAL_DESCRIPTION2, inputSchema: mcpInputSchema2(CreateGoalToolSchema2) },
15395
13060
  { name: "claim_goal", description: CLAIM_GOAL_DESCRIPTION2, inputSchema: mcpInputSchema2(ClaimGoalSchema2) },
15396
13061
  { name: "get_goal", description: GET_GOAL_DESCRIPTION2, inputSchema: mcpInputSchema2(GetGoalSchema2) },
@@ -15439,18 +13104,6 @@ var TransformSchema2 = external_exports.enum([
15439
13104
  "summarize"
15440
13105
  // reduce volume, keep decision value — 30-turn cap, spoken briefing
15441
13106
  ]);
15442
- var OptionSchema2 = external_exports.object({
15443
- id: external_exports.string(),
15444
- label: external_exports.string(),
15445
- // .describe() flows into the MCP contact JSON schema (zodToJsonSchema), so
15446
- // the constraints below are what an agent reads when deciding to use these.
15447
- html: external_exports.string().max(16384).describe(
15448
- "Optional sandboxed HTML/CSS preview for a visual 'pick one' (shown in the option card). Untrusted-sandboxed: NO JavaScript, NO external network or images \u2014 inline CSS and data: URIs only; <=16KB. Use for layout/CSS mockups, tables, diffs. For a hosted image use `image` instead."
15449
- ).optional(),
15450
- image: external_exports.string().url().describe(
15451
- "Optional image URL rendered as the option's preview (plain image, not sandboxed). For agent-generated HTML/CSS mockups, use `html` instead."
15452
- ).optional()
15453
- });
15454
13107
  var VisualSchema2 = external_exports.object({
15455
13108
  url: external_exports.string().url(),
15456
13109
  label: external_exports.string().optional()
@@ -15504,7 +13157,7 @@ var NotifyRequestFields2 = external_exports.object({
15504
13157
  * ABSENT on the E2EE path, where the sealed `envelope` below carries it. The
15505
13158
  * superRefine at the bottom enforces exactly one of the two. */
15506
13159
  context: ContextSchema2.optional(),
15507
- options: external_exports.array(OptionSchema2.omit({ id: true })).min(OPTIONS_MIN2).max(OPTIONS_MAX2).optional().describe(
13160
+ options: external_exports.array(OptionInputSchema2).min(OPTIONS_MIN2).max(OPTIONS_MAX2).optional().describe(
15508
13161
  "The choices, in order \u2014 required when select is 'one'/'many'/'rank', omitted otherwise. Ids are assigned automatically by position ('1', '2', \u2026); the user's answer references them as optionId(s)."
15509
13162
  ),
15510
13163
  points: external_exports.array(external_exports.string().min(1)).optional().describe(
@@ -15536,23 +13189,6 @@ var NotifyRequestFields2 = external_exports.object({
15536
13189
  * when `parentId` became the conversation handle: `parentId` says WHERE, this
15537
13190
  * says HOW. */
15538
13191
  clarifies: external_exports.string().optional(),
15539
- /** E2EE (text lane): when the pairing is E2EE, the sealed replacements for the
15540
- * plaintext content fields, keyed by field name. FINALIZED wire shape (was
15541
- * provisional in the storage PR): a per-field map `{ context?, options?,
15542
- * visuals? }` of opaque Envelopes — one seal per present content field, so a
15543
- * message with no options/visuals seals only `context`. It COEXISTS with the
15544
- * plaintext fields by mutual exclusion: the superRefine below requires that
15545
- * when `envelope` is present the plaintext `context`/`options`/`visuals` are
15546
- * ABSENT (and vice-versa), so a row is either fully plaintext or fully sealed —
15547
- * never a readable half. The server persists this OPAQUELY into
15548
- * notifications.envelope and relays it blindly; it never decrypts. Absent =
15549
- * today's plaintext path (context/options/visuals carry the cleartext).
15550
- * z.lazy because EnvelopeSchema is declared further down (E2EE section). */
15551
- envelope: external_exports.object({
15552
- context: external_exports.lazy(() => EnvelopeSchema2).optional(),
15553
- options: external_exports.lazy(() => EnvelopeSchema2).optional(),
15554
- visuals: external_exports.lazy(() => EnvelopeSchema2).optional()
15555
- }).optional(),
15556
13192
  select: SelectShapeSchema2.optional().describe(
15557
13193
  "How the user answers \u2014 required on the fully-shaped form, pick the shape that fits the question: 'one' = pick one option, 'many' = pick several, 'rank' = pick & order (each needs `options`); 'confirm' = yes/no or approve/deny; 'text' = free-form reply only (status updates, open questions). 'confirm' and 'text' take no options. Omit only when sending the simplified `ask` form \u2014 the broker picks the shape."
15558
13194
  ),
@@ -15606,22 +13242,6 @@ var NotifyRequestFields2 = external_exports.object({
15606
13242
  });
15607
13243
  var NotifyRequestSchema2 = NotifyRequestFields2.superRefine((r, ctx) => {
15608
13244
  if (r.workId && r.goalId) ctx.addIssue({ code: external_exports.ZodIssueCode.custom, path: ["goalId"], message: "pass goalId or workId, not both" });
15609
- const sealed = !!r.envelope;
15610
- if (sealed) {
15611
- if (!r.envelope?.context)
15612
- ctx.addIssue({ code: external_exports.ZodIssueCode.custom, path: ["envelope", "context"], message: "sealed request must include envelope.context" });
15613
- for (const f of ["context", "options", "visuals"]) {
15614
- if (r[f] !== void 0)
15615
- ctx.addIssue({ code: external_exports.ZodIssueCode.custom, path: [f], message: `E2EE request must not carry plaintext ${f} \u2014 it's sealed in envelope.${f}` });
15616
- }
15617
- if (r.points !== void 0)
15618
- ctx.addIssue({ code: external_exports.ZodIssueCode.custom, path: ["points"], message: "E2EE request must not carry plaintext points" });
15619
- if (r.ask !== void 0)
15620
- ctx.addIssue({ code: external_exports.ZodIssueCode.custom, path: ["ask"], message: "E2EE request must not carry a plaintext ask \u2014 derive the shape agent-side and seal it" });
15621
- if (r.needs !== void 0)
15622
- ctx.addIssue({ code: external_exports.ZodIssueCode.custom, path: ["needs"], message: "E2EE request must not carry plaintext needs" });
15623
- return;
15624
- }
15625
13245
  if (r.ask !== void 0) {
15626
13246
  for (const f of ["context", "select", "points"]) {
15627
13247
  if (r[f] !== void 0)
@@ -15696,13 +13316,6 @@ var AwaitItemSchema2 = external_exports.discriminatedUnion("type", [
15696
13316
  workId: external_exports.string().uuid().optional(),
15697
13317
  decisionId: external_exports.string().uuid().optional(),
15698
13318
  answer: UserAnswerSchema2,
15699
- /** E2EE: present when the answer is sealed. The server relays the opaque answer
15700
- * envelope + the plaintext `ignored` status hint; the receiving agent OPENS it
15701
- * with its device key and re-derives the real UserAnswer, treating a mismatch
15702
- * against `ignored` as tampering. Absent = today's plaintext answer (in `answer`).
15703
- * On a sealed reply the plaintext `answer` is a placeholder (kind reflects only
15704
- * the `ignored` bit) — never the real content, which stays sealed. */
15705
- sealed: external_exports.lazy(() => SealedAnswerSchema2).optional(),
15706
13319
  /** WHAT THE AGENT CANNOT KNOW FROM THE FIELDS BESIDE IT (owner, 2026-09-04, issue
15707
13320
  * #1537). One line, built from the record: the ask and the caller's reply VERBATIM,
15708
13321
  * the notification they belong to, and the `contact` call that reaches the person
@@ -15738,7 +13351,7 @@ var AwaitItemSchema2 = external_exports.discriminatedUnion("type", [
15738
13351
  /** The awaited ask was REPLACED by a newer notification on its thread (e.g. a
15739
13352
  * post-feedback revision, #633) — the user will never answer this id. Stop
15740
13353
  * awaiting it; the live ask is the thread's newest turn (await that one, or
15741
- * re-orient via get_thread / check_replies). */
13354
+ * re-orient via check_replies). */
15742
13355
  external_exports.object({
15743
13356
  type: external_exports.literal("superseded"),
15744
13357
  parentId: external_exports.string(),
@@ -15852,10 +13465,6 @@ var InboxItemSchema2 = external_exports.object({
15852
13465
  options: external_exports.array(OptionSchema2).optional(),
15853
13466
  /** The ask's declared coverage points (#396), when the agent sent them. */
15854
13467
  points: external_exports.array(external_exports.string()).optional(),
15855
- /** The call's AGENDA (broker/agenda-design.md): the ordered turns it is made of, built at
15856
- * ring/enqueue time. Replaces the condensed line + index-aligned phrased points, which
15857
- * between them could not express a call as a sequence. `question: null` is a real turn —
15858
- * a status update stays a statement instead of being shaped into a yes/no. */
15859
13468
  /** Does this claim want an ANSWER, or is it telling you something? Written per row from
15860
13469
  * `requestAsks` — the agent's own declaration, not a guess. `false` is what earns a card
15861
13470
  * its acknowledge affordance: without it a status update offers a text box and a dismiss,
@@ -15876,7 +13485,26 @@ var InboxItemSchema2 = external_exports.object({
15876
13485
  * instant the agent picks it up (#997). Absent = pre-trigger row; fall back to
15877
13486
  * `createdAt`. */
15878
13487
  agentStateAt: external_exports.string().datetime().optional(),
15879
- agenda: external_exports.array(AgendaTurnSchema2).optional(),
13488
+ /** THE QUESTIONS A CALL CARRIES — the call screen's agenda spine (walk/design.md §11, owner
13489
+ * 2026-09-22). One per DecisionNeed on the Call, in the Call's order, answered or open (a
13490
+ * superseded or cancelled need is no longer a question anyone is asked). Present only on a
13491
+ * Call's cards, and every card of that Call carries the same list: the call screen reads it
13492
+ * once, off the one read it already makes (`GET /api/inbox/:callId`).
13493
+ *
13494
+ * It counts DECISIONS, not agenda turns: turns include context-only lines and are re-planned
13495
+ * every cycle, so a spine drawn from them would change length under the caller mid-call.
13496
+ *
13497
+ * `entryId` is the request Entry — the id the bot calls a CLAIM, and the one it names on the
13498
+ * `turn` topic (`asking`, `settled`), because the bot never sees a DecisionNeed id. `title` is
13499
+ * the card's own concise heading; `answer` the accepted answer in words, null while open. It
13500
+ * REPLACED `agenda` (turns), which nothing ever filled. */
13501
+ questions: external_exports.array(external_exports.object({
13502
+ id: external_exports.string(),
13503
+ entryId: external_exports.string(),
13504
+ title: external_exports.string(),
13505
+ state: external_exports.enum(["open", "answered"]),
13506
+ answer: external_exports.string().nullable()
13507
+ })).optional(),
15880
13508
  visuals: external_exports.array(VisualSchema2).optional(),
15881
13509
  /** The connected agent's name (the single pairing name — user-typed, or the
15882
13510
  * agent's suggestion, or a default silly name). */
@@ -15897,12 +13525,21 @@ var InboxItemSchema2 = external_exports.object({
15897
13525
  * client may still flag a stall by age. Drives the inbox error badge + Retry. */
15898
13526
  error: external_exports.string().optional(),
15899
13527
  clarifies: external_exports.string().optional(),
15900
- /** The ring ladder ran out while this was still pending — we tried to reach you and
15901
- * STOPPED trying (`arbitration/arbitrate.ts` `nextRing` → `stop`). Distinct from an
15902
- * agent with nothing to say, which the roster drew identically until now: "nothing to
15903
- * say" and "gave up saying it" are opposite situations wearing the same face
15904
- * (navigation-design.md, gap 1). False for anything that never rang. */
15905
- gaveUp: external_exports.boolean().default(false),
13528
+ /** THE RING, ON THE ITEM (walk/design.md §12 §17, #2251): the last ring on this card was
13529
+ * declined, and what the ladder will do next — read off the cron's own row, never computed
13530
+ * on the phone. Present only while a `declined` receipt stands on the card's last Call.
13531
+ * The ladder is ACCOUNT-WIDE (#2259): `anchorAt` and `step` are the account's position;
13532
+ * `nextRingAt` is this card's armed instant (`deliveries.next_ring_at`), null once the cron
13533
+ * has disarmed it — the curve's end, `inbox`/`dismiss`, or a setting that said no more rings.
13534
+ * It replaced `gaveUp` (deleted 2026-09-22): "the ladder spent" was a boolean the projection
13535
+ * never set, and it is `nextRingAt === null` here — the party's *Missed you* (`party/dress.ts`)
13536
+ * and the roster's `unreached` read `declinedAt`, and stand while it does. */
13537
+ ring: external_exports.object({
13538
+ declinedAt: external_exports.string().datetime(),
13539
+ anchorAt: external_exports.string().datetime(),
13540
+ nextRingAt: external_exports.string().datetime().nullable(),
13541
+ step: external_exports.number().int()
13542
+ }).optional(),
15906
13543
  /** Why this arrived the way it did, read back off the delivery receipt (`notify/why.ts`).
15907
13544
  * Absent for anything never delivered through a push, and for older rows written before
15908
13545
  * the reason was recorded. Deliberately a debug affordance, shown small (owner,
@@ -15924,21 +13561,6 @@ var InboxItemSchema2 = external_exports.object({
15924
13561
  blocking: external_exports.boolean().default(false),
15925
13562
  /** The user's locked-in answer; present only for replied items (GET /api/replied/:id). */
15926
13563
  answer: UserAnswerSchema2.optional(),
15927
- /** E2EE (text lane): the sealed content this item carries when the pairing is E2EE, in
15928
- * place of the plaintext `context`/`options`/`visuals` (which the operator would
15929
- * otherwise read). A per-field map of opaque Envelopes — the SAME shape as
15930
- * NotifyRequest.envelope. The native app decrypts it locally via openNotification;
15931
- * web / an un-enrolled device can't and renders a locked placeholder. Absent = today's
15932
- * plaintext item (context carries the cleartext), so plaintext items are unchanged. */
15933
- envelope: external_exports.object({
15934
- context: external_exports.lazy(() => EnvelopeSchema2).optional(),
15935
- options: external_exports.lazy(() => EnvelopeSchema2).optional(),
15936
- visuals: external_exports.lazy(() => EnvelopeSchema2).optional()
15937
- }).optional(),
15938
- /** E2EE: the agent's device X25519 public key to seal the user's answer BACK to (the
15939
- * sender the phone replies to). Sourced server-side from this item's pairing credential.
15940
- * Present only alongside `envelope`; the phone seals via sealAnswer(answer, this, id). */
15941
- agentX25519: external_exports.string().optional(),
15942
13564
  /** THE TARGET FACTS A CARD RENDERS (#1796 point 5, 2026-09-11): the Delivery it is a view of,
15943
13565
  * that Delivery's kind, the request Entry, the Goals it answers for, the exact DecisionNeed (none
15944
13566
  * for a request that asks nothing), whether its content is sealed, and that Goal's state. The
@@ -15982,6 +13604,8 @@ var MissedCallSchema2 = external_exports.enum([
15982
13604
  "inbox",
15983
13605
  "dismiss"
15984
13606
  ]);
13607
+ var clock2 = (h) => h === 0 ? "midnight" : h === 12 ? "noon" : h < 12 ? `${h} am` : `${h - 12} pm`;
13608
+ var QUIET2 = ` Nothing rings from ${clock2(NIGHT2.from)} to ${clock2(NIGHT2.to)} your time; the count waits for morning.`;
15985
13609
  var BrokerTuningSchema2 = external_exports.object({
15986
13610
  /** 'none' = skip the spoken ack after a mapped answer (power users find it slow). */
15987
13611
  ackVerbosity: external_exports.enum(["normal", "none"]).optional(),
@@ -16016,6 +13640,12 @@ var UserSettingsSchema2 = external_exports.object({
16016
13640
  * must not silently reset this privacy choice. Absent = leave unchanged on
16017
13641
  * write, 'hosted' on read (see store.ts). */
16018
13642
  voiceMode: external_exports.enum(["hosted", "on_device"]).optional(),
13643
+ /** Talk — after you answer, the next step is read aloud (walk/design.md §6). ALWAYS ON until
13644
+ * turned off (owner, 2026-09-18, #2249): a setting, not a per-walk toggle. Optional, NOT
13645
+ * defaulted, for the same reason `voiceMode` is: a stale client PATCHing the full settings
13646
+ * object must not silently turn it back on. Absent = leave unchanged on write, true on
13647
+ * read (see store.ts). */
13648
+ talk: external_exports.boolean().optional(),
16019
13649
  /** Per-user ring budget (#603): calls per rolling day before further calls
16020
13650
  * degrade to banner. Absent = the global default (25). A number, never a
16021
13651
  * bypass — every account keeps a ceiling. No UI; set per user for testing. */
@@ -16036,13 +13666,6 @@ var UserSettingsSchema2 = external_exports.object({
16036
13666
  * setting. Absent = a spoken time can't be landed, so the reminder rides the next
16037
13667
  * call — honest about what we know. */
16038
13668
  timezone: external_exports.string().min(1).max(64).optional(),
16039
- /** Account E2EE state (text lane): 'off' (default) = today's plaintext; 'on' =
16040
- * content is sealed end-to-end between the local agent and the phone. Like
16041
- * voiceMode, OPTIONAL and NOT defaulted so a stale client PATCHing the full
16042
- * settings object without it can't silently flip the account's E2EE state.
16043
- * Absent = leave unchanged on write, 'off' on read (see store.ts). The demo
16044
- * account is plaintext by construction and refuses any non-'off' value. */
16045
- e2eeMode: external_exports.enum(["off", "on"]).optional(),
16046
13669
  /** Rung-2 broker tuning (#381). Optional and NOT defaulted, same stale-client
16047
13670
  * clobber guard as voiceMode: absent = leave unchanged on write. */
16048
13671
  broker: BrokerTuningSchema2.optional()
@@ -16220,6 +13843,9 @@ var QueueItemSchema2 = external_exports.object({
16220
13843
  assignee: external_exports.string().nullable().default(null),
16221
13844
  /** What the agent last said it was doing; null if it has said nothing. */
16222
13845
  progress: external_exports.string().nullable().default(null),
13846
+ /** HOME'S LINE FOR THAT NOTE (owner, 2026-09-23): a few plain words one read wrote from `progress`,
13847
+ * served only while it was written for the current note. Null means show the Goal's name. */
13848
+ progressLine: external_exports.string().nullable().optional(),
16223
13849
  reviewPending: external_exports.boolean().default(false),
16224
13850
  dueAt: external_exports.string().nullable().default(null),
16225
13851
  /** The Goal this one was opened under; null at the root. */
@@ -16232,9 +13858,16 @@ var QueueItemSchema2 = external_exports.object({
16232
13858
  blocked: external_exports.boolean().default(false),
16233
13859
  /** Every decision need on it, open or settled — the page decides which to show. */
16234
13860
  questions: external_exports.array(QueueQuestionSchema2).default([]),
13861
+ /** The repository or project identifier this Goal belongs to (#2280), null if untracked. */
13862
+ repo: external_exports.string().nullable().optional(),
16235
13863
  createdAt: external_exports.string(),
16236
- updatedAt: external_exports.string().nullable().default(null)
13864
+ updatedAt: external_exports.string().nullable().default(null),
13865
+ /** When its owner last SAID something about it (`goals.last_progress_at`, written by every
13866
+ * `update_goal` that changes `progress`). `updatedAt` moves for reasons nobody chose — a
13867
+ * state recomputed, a review flag — so it cannot tell work in hand from work gone quiet. */
13868
+ lastProgressAt: external_exports.string().nullable().optional()
16237
13869
  });
13870
+ var COLD_AFTER_MS2 = 3 * 24 * 60 * 60 * 1e3;
16238
13871
  var NoteSourceSchema2 = external_exports.enum(["app", "call"]);
16239
13872
  var NoteStatusSchema2 = external_exports.enum(["open", "assigned", "in_progress", "done"]);
16240
13873
  var NoteRepeatSchema2 = external_exports.enum(["once", "until_done"]);
@@ -16343,54 +13976,12 @@ var DeliveryConfigSchema2 = external_exports.object({
16343
13976
  * carries credentials; only a `poll` registration can come back with null here. */
16344
13977
  realtime: external_exports.object({ url: external_exports.string(), anonKey: external_exports.string() }).nullable()
16345
13978
  });
16346
- var EnvelopeRecipientSchema2 = external_exports.object({
16347
- keyId: external_exports.string(),
16348
- epk: external_exports.string(),
16349
- wnonce: external_exports.string(),
16350
- wrap: external_exports.string()
16351
- });
16352
- var EnvelopeHeaderSchema2 = external_exports.object({
16353
- field: external_exports.enum(["context", "options", "visuals", "answer"]),
16354
- kind: external_exports.string(),
16355
- senderRole: external_exports.enum(["agent", "user"]),
16356
- recipientKeyIds: external_exports.array(external_exports.string()),
16357
- seq: external_exports.number().int().nonnegative()
16358
- });
16359
- var EnvelopeSchema2 = external_exports.object({
16360
- v: external_exports.literal(1),
16361
- alg: external_exports.literal("x25519-xsalsa20poly1305"),
16362
- msgId: external_exports.string(),
16363
- hdr: EnvelopeHeaderSchema2,
16364
- recipients: external_exports.array(EnvelopeRecipientSchema2).min(1),
16365
- nonce: external_exports.string(),
16366
- ct: external_exports.string()
16367
- });
16368
- var SealedAnswerSchema2 = external_exports.object({
16369
- ignored: external_exports.boolean(),
16370
- envelope: EnvelopeSchema2
16371
- });
16372
- var DeviceCredentialSchema2 = external_exports.object({
16373
- deviceId: external_exports.string(),
16374
- kind: external_exports.enum(["phone", "web", "agent"]),
16375
- x25519Pub: external_exports.string(),
16376
- ed25519Pub: external_exports.string(),
16377
- sig: external_exports.string()
16378
- });
16379
- var DeviceRosterSchema2 = external_exports.object({
16380
- uikPub: external_exports.string(),
16381
- devices: external_exports.array(DeviceCredentialSchema2)
16382
- });
16383
13979
  var WakeNudgeSchema2 = external_exports.object({
16384
13980
  kind: external_exports.enum(["reply", "request", "callback"]),
16385
13981
  notificationId: external_exports.string().optional(),
16386
13982
  parentId: external_exports.string()
16387
13983
  });
16388
13984
  var PairingStatusSchema2 = external_exports.enum(["pending", "approved", "denied", "expired"]);
16389
- var PairingRevealSchema2 = external_exports.object({
16390
- x25519: external_exports.string(),
16391
- ed25519: external_exports.string(),
16392
- nonce: external_exports.string()
16393
- });
16394
13985
  var DeviceCodeSchema2 = external_exports.object({
16395
13986
  device_code: external_exports.string(),
16396
13987
  user_code: external_exports.string(),
@@ -16410,19 +14001,7 @@ var DeviceInfoSchema2 = external_exports.object({
16410
14001
  * (seen live: PAIGY-5T, 2026-07-21). Remove once a newer binary is the floor. */
16411
14002
  agent: external_exports.string().optional(),
16412
14003
  device: external_exports.string().nullable(),
16413
- status: PairingStatusSchema2,
16414
- proto: external_exports.string().nullable().optional(),
16415
- agent_commitment: external_exports.string().nullable().optional(),
16416
- // Ca
16417
- agent_reveal: PairingRevealSchema2.nullable().optional(),
16418
- // present once the agent reveals
16419
- agent_credential: DeviceCredentialSchema2.nullable().optional(),
16420
- // the phone's UIK-signed cred over the agent's keys — the agent fetches it here to finalizeE2ee
16421
- // The phone's reveal + identity key, exposed here so a GATED agent (e2ee_mode='on', token
16422
- // withheld until e2ee=true) can compute the SAS WITHOUT a token. Public keys — same safety
16423
- // class as agent_reveal above. Present only once the phone reveals; null otherwise.
16424
- phone_reveal: PairingRevealSchema2.nullable().optional(),
16425
- uik_pub: external_exports.string().nullable().optional()
14004
+ status: PairingStatusSchema2
16426
14005
  });
16427
14006
  var DeviceTokenSchema2 = external_exports.object({
16428
14007
  access_token: external_exports.string(),
@@ -16441,8 +14020,6 @@ var DeviceTokenSchema2 = external_exports.object({
16441
14020
  * landed in the FIRST granted workspace and the agent rediscovered its own repo from
16442
14021
  * the thread each time (host.ts, live catch 2026-08-06 — prompt-papered until now). */
16443
14022
  workspace: external_exports.string().nullable().optional(),
16444
- phone_reveal: PairingRevealSchema2.nullable().optional(),
16445
- // present once the phone reveals
16446
14023
  uik_pub: external_exports.string().nullable().optional()
16447
14024
  });
16448
14025
  var SupportRequestSchema2 = external_exports.object({
@@ -16464,13 +14041,6 @@ var NotificationFeedbackKindSchema2 = external_exports.enum([
16464
14041
  "other"
16465
14042
  // anything else — the note carries it.
16466
14043
  ]);
16467
- var FeedbackResolutionSchema2 = external_exports.enum(["broker_fixed", "sent_to_agent"]);
16468
- var FeedbackOutcomeSchema2 = external_exports.object({
16469
- resolution: FeedbackResolutionSchema2,
16470
- transform: TransformSchema2,
16471
- message: external_exports.string(),
16472
- childIds: external_exports.array(external_exports.string()).optional()
16473
- });
16474
14044
 
16475
14045
  // src/paigy/activity.ts
16476
14046
  function shortenPaths(s) {
@@ -16495,7 +14065,7 @@ function sameTail(a, b) {
16495
14065
  // src/harness/session.ts
16496
14066
  import { spawn } from "child_process";
16497
14067
  import { existsSync as existsSync4 } from "fs";
16498
- import { homedir as homedir5 } from "os";
14068
+ import { homedir as homedir6 } from "os";
16499
14069
  import { resolve as resolve2, delimiter as delimiter2 } from "path";
16500
14070
 
16501
14071
  // src/harness/acp.ts
@@ -16732,7 +14302,7 @@ function splitLines(buffer, chunk) {
16732
14302
  return { lines: parts.filter((l) => l.trim()), rest };
16733
14303
  }
16734
14304
  function startSession(opts) {
16735
- const cwd = resolve2(opts.cwd.replace(/^~(?=$|\/)/, homedir5()));
14305
+ const cwd = resolve2(opts.cwd.replace(/^~(?=$|\/)/, homedir6()));
16736
14306
  if (!existsSync4(cwd)) {
16737
14307
  queueMicrotask(() => opts.onEvent({ kind: "error", message: `workspace does not exist: ${cwd}` }));
16738
14308
  }
@@ -16746,7 +14316,13 @@ function startSession(opts) {
16746
14316
  ...process.env,
16747
14317
  PATH: [process.env.PATH, ...probeDirs()].filter(Boolean).join(delimiter2),
16748
14318
  ...opts.token ? { PAIGY_TOKEN: opts.token } : {},
16749
- ...opts.resume ? { PAIGY_SESSION_ID: opts.resume } : {}
14319
+ ...opts.resume ? { PAIGY_SESSION_ID: opts.resume } : {},
14320
+ // A PUMP DRIVES THIS PROCESS (2026-09-22, #2265): every run `runHarness` starts has the
14321
+ // bridge's pump typing answers in, so nothing inside it may start a second delivery path.
14322
+ // Exported on EVERY spawn — `PAIGY_SESSION_ID` above is the conversation to resume, and a
14323
+ // fresh spawn has none, which is how a fresh run read as "not harness-started" to the
14324
+ // session-start hook and the `listen` tool (they now test either mark; listening.ts).
14325
+ PAIGY_HARNESS: "1"
16750
14326
  },
16751
14327
  stdio: ["pipe", "pipe", "pipe"]
16752
14328
  });
@@ -16793,14 +14369,32 @@ function startSession(opts) {
16793
14369
  }
16794
14370
 
16795
14371
  // src/paigy/conversation.ts
14372
+ import { randomUUID as randomUUID4 } from "crypto";
14373
+ var HARNESS_INSTRUCTION = "You are running as an unattended background harness agent connected to your user through Paigy. The user is NOT at the terminal and cannot see text printed here. To ask questions, request approvals, or make decisions, use Paigy tools or end your turn with a clear question for the bridge to relay. When complete, provide a concise summary of what was accomplished.";
16796
14374
  function endsWithQuestion(text) {
16797
14375
  if (!text) return false;
16798
- const tail = text.trim().split("\n").filter(Boolean).slice(-3).join(" ").toLowerCase();
16799
- if (!tail) return false;
16800
- if (tail.endsWith("?")) return true;
14376
+ const trimmed = text.trim();
14377
+ if (!trimmed) return false;
14378
+ if (trimmed.endsWith("?")) return true;
14379
+ const lines2 = trimmed.split("\n").map((l) => l.trim()).filter(Boolean);
14380
+ if (lines2.length === 0) return false;
14381
+ let lastNonListIdx = lines2.length - 1;
14382
+ while (lastNonListIdx >= 0) {
14383
+ const line = lines2[lastNonListIdx];
14384
+ if (line && /^[-*•\d.)]\s+/.test(line)) {
14385
+ lastNonListIdx--;
14386
+ } else {
14387
+ break;
14388
+ }
14389
+ }
14390
+ const promptLine = lastNonListIdx >= 0 ? lines2[lastNonListIdx] : lines2[lines2.length - 1];
14391
+ if (promptLine?.endsWith("?")) return true;
14392
+ const tail = lines2.slice(-3).join(" ").toLowerCase();
16801
14393
  return [
16802
14394
  /\b(let me know|which (one|would|do you)|do you want|should i|shall i)\b/,
16803
- /\b(want me to|prefer|your call|up to you|confirm whether)\b/
14395
+ /\b(want me to|prefer|your call|up to you|confirm whether)\b/,
14396
+ /\b(how would you like|how should we|what would you like|what should we)\b/,
14397
+ /\b(please choose|choose one|select one|how do you want)\b/
16804
14398
  ].some((re) => re.test(tail));
16805
14399
  }
16806
14400
  var POLL_MS = 5e3;
@@ -16818,17 +14412,34 @@ function unheard(brief, state) {
16818
14412
  }
16819
14413
  return words2;
16820
14414
  }
16821
- async function step(session, state, rail) {
14415
+ async function step(session, state, rail, opts) {
16822
14416
  if (!state.goal) {
16823
14417
  if (!state.resting) return;
16824
- const brief2 = await rail.claim();
16825
- if (!brief2.goalId || brief2.revision === void 0) return;
14418
+ let brief2 = await rail.claim();
14419
+ if (!brief2.goalId || brief2.revision === void 0) {
14420
+ if (opts?.initialPrompt?.trim()) {
14421
+ const prompt = opts.initialPrompt.trim();
14422
+ opts.initialPrompt = void 0;
14423
+ const admitted = await rail.create({ outcome: prompt, idempotencyKey: randomUUID4() });
14424
+ brief2 = await rail.claim();
14425
+ if (!brief2.goalId || brief2.revision === void 0) {
14426
+ state.goal = { id: admitted.goalId, revision: admitted.revision };
14427
+ if (checkCallOnDone(prompt)) state.callOnDone = true;
14428
+ send2(session, state, [HARNESS_INSTRUCTION, prompt].join("\n\n"));
14429
+ return;
14430
+ }
14431
+ } else {
14432
+ return;
14433
+ }
14434
+ }
16826
14435
  unheard(brief2, state);
16827
14436
  if (ended(brief2.state)) await rail.update(brief2.goalId, { revision: brief2.revision, changes: { reviewed: true }, reason: "Typed into the session." });
16828
14437
  else state.goal = { id: brief2.goalId, revision: brief2.revision };
16829
14438
  const outcome = brief2.outcome?.trim() ?? "";
16830
14439
  const said = (brief2.entries ?? []).map((e) => entryWords(e).trim()).filter((w) => w && w.toLowerCase() !== outcome.toLowerCase());
16831
- send2(session, state, [outcome, ...said].filter(Boolean).join("\n\n"));
14440
+ const fullText = [outcome, ...said].filter(Boolean).join("\n\n");
14441
+ if (checkCallOnDone(fullText)) state.callOnDone = true;
14442
+ send2(session, state, [HARNESS_INSTRUCTION, fullText].filter(Boolean).join("\n\n"));
16832
14443
  return;
16833
14444
  }
16834
14445
  const brief = await rail.read(state.goal.id);
@@ -16847,16 +14458,21 @@ async function step(session, state, rail) {
16847
14458
  }
16848
14459
  if (state.asks?.size || !state.resting) return;
16849
14460
  const words2 = unheard(brief, state);
16850
- if (words2.length) send2(session, state, words2.join("\n\n"));
14461
+ if (words2.length) {
14462
+ const text = words2.join("\n\n");
14463
+ if (checkCallOnDone(text)) state.callOnDone = true;
14464
+ send2(session, state, text);
14465
+ }
16851
14466
  }
16852
14467
  function send2(session, state, text) {
16853
14468
  state.resting = false;
16854
14469
  session.send(text);
16855
14470
  }
16856
14471
  async function pump(session, state, rail, opts) {
14472
+ const promptRef = opts.initialPrompt ? { initialPrompt: opts.initialPrompt } : void 0;
16857
14473
  for (; ; ) {
16858
14474
  try {
16859
- await step(session, state, rail);
14475
+ await step(session, state, rail, promptRef);
16860
14476
  } catch {
16861
14477
  }
16862
14478
  if (!await opts.onIdle()) return;
@@ -16864,25 +14480,6 @@ async function pump(session, state, rail, opts) {
16864
14480
  }
16865
14481
  }
16866
14482
 
16867
- // src/paigy/level.ts
16868
- var DESTRUCTIVE = [
16869
- /\brm\s+-[a-z]*[rf]/,
16870
- // rm -rf, rm -f
16871
- /\bgit\s+push\b.*(--force|-f\b)/,
16872
- /\bgit\s+reset\s+--hard/,
16873
- /\bgit\s+clean\s+-[a-z]*f/,
16874
- /\bdrop\s+(table|database|schema)\b/i,
16875
- /\btruncate\s+table\b/i,
16876
- /\bdd\s+if=/,
16877
- /\bmkfs\b/,
16878
- /\b(shutdown|reboot)\b/,
16879
- /:\s*>\s*\/dev\/sd/
16880
- // writing over a raw device
16881
- ];
16882
- function isDestructive(summary) {
16883
- return DESTRUCTIVE.some((re) => re.test(summary));
16884
- }
16885
-
16886
14483
  // src/paigy/bridge.ts
16887
14484
  function railFor(opts) {
16888
14485
  return {
@@ -16890,7 +14487,8 @@ function railFor(opts) {
16890
14487
  read: (goalId) => getGoal(goalId, opts),
16891
14488
  update: (goalId, input) => updateGoal(goalId, input, opts),
16892
14489
  // One read and back: the pump owns the waiting, so a Call must not hold a window here.
16893
- contact: (input) => contact(input, { ...opts, waits: false })
14490
+ contact: (input) => contact(input, { ...opts, waits: false }),
14491
+ create: (input) => createGoal(input, opts)
16894
14492
  };
16895
14493
  }
16896
14494
  function cancelAsks(state) {
@@ -16927,11 +14525,9 @@ async function ask(state, rail, input) {
16927
14525
  if (!state.goal) return null;
16928
14526
  try {
16929
14527
  const sent = await rail.contact({
16930
- goalIds: [state.goal.id],
16931
- ask: input.ask,
14528
+ asks: [{ ask: input.ask, parentId: state.goal.id, ...input.options ? { options: input.options } : {} }],
16932
14529
  waiting: "hard",
16933
- channel: input.call ? "call" : "notification",
16934
- ...input.options ? { options: input.options } : {}
14530
+ channel: input.call ? "call" : "notification"
16935
14531
  });
16936
14532
  const entryId = sent.requestEntryIds[0];
16937
14533
  if (!entryId) return null;
@@ -16941,37 +14537,87 @@ async function ask(state, rail, input) {
16941
14537
  return null;
16942
14538
  }
16943
14539
  }
14540
+ function checkCallOnDone(text) {
14541
+ if (!text) return false;
14542
+ return /\b(call|ring|phone)\b.*\b(done|finish(ed)?|complete(d)?)\b/i.test(text) || /\b(when|if|once)\b.*\b(done|finish(ed)?|complete(d)?)\b.*\b(call|ring|phone)\b/i.test(text) || /\bcall\s+(me|us)\b/i.test(text);
14543
+ }
14544
+ function parseQuestionOptions(text) {
14545
+ if (!text) return { question: "" };
14546
+ const trimmed = text.trim();
14547
+ const lines2 = trimmed.split("\n").map((l) => l.trim()).filter(Boolean);
14548
+ const optionLines = [];
14549
+ const questionLines = [];
14550
+ for (const line of lines2) {
14551
+ const bulletMatch = line.match(/^[-*•]\s+(.*)$/) ?? line.match(/^\d+[.)]\s+(.*)$/);
14552
+ if (bulletMatch) {
14553
+ optionLines.push(bulletMatch[1].trim());
14554
+ } else {
14555
+ questionLines.push(line);
14556
+ }
14557
+ }
14558
+ if (optionLines.length >= 2 && optionLines.length <= 6) {
14559
+ return {
14560
+ question: questionLines.join("\n\n").trim() || trimmed,
14561
+ options: optionLines.map((raw) => {
14562
+ const colonSplit = raw.match(/^([^:—–-]+)\s*[:—–-]\s*(.+)$/);
14563
+ const parenSplit = raw.match(/^([^(]+)\s*\(([^)]+)\)$/);
14564
+ if (colonSplit && colonSplit[1] && colonSplit[2]) {
14565
+ return { label: colonSplit[1].trim().slice(0, 100), hint: colonSplit[2].trim().slice(0, 250) };
14566
+ }
14567
+ if (parenSplit && parenSplit[1] && parenSplit[2]) {
14568
+ return { label: parenSplit[1].trim().slice(0, 100), hint: parenSplit[2].trim().slice(0, 250) };
14569
+ }
14570
+ return { label: raw.slice(0, 1e3) };
14571
+ })
14572
+ };
14573
+ }
14574
+ return { question: trimmed };
14575
+ }
16944
14576
  async function askPermission(event, state, rail) {
16945
14577
  return decisionFrom(await ask(state, rail, {
16946
14578
  ask: [`The agent is blocked waiting to run: ${event.summary}`, ...event.reason ? [event.reason] : []].join("\n\n"),
16947
- options: [{ label: ALLOW }, { label: "Deny" }],
16948
- call: isDestructive(event.summary)
14579
+ options: [
14580
+ { label: ALLOW, hint: "Permits the agent to run this command" },
14581
+ { label: "Deny", hint: "Blocks execution of this command" }
14582
+ ],
14583
+ call: true
16949
14584
  }));
16950
14585
  }
16951
- async function askQuestion(question, state, rail) {
16952
- return wordsOf(await ask(state, rail, { ask: question }));
14586
+ async function askQuestion(question, state, rail, opts) {
14587
+ return wordsOf(await ask(state, rail, {
14588
+ ask: question,
14589
+ call: opts?.call ?? true,
14590
+ options: opts?.options
14591
+ }));
16953
14592
  }
16954
- async function finish(result, state, rail) {
14593
+ async function finish(result, state, rail, opts) {
16955
14594
  const goal = state.goal;
16956
14595
  if (!goal) return;
16957
14596
  state.goal = void 0;
16958
14597
  const report = result?.trim() || "Done.";
14598
+ const channel = opts?.call || state.callOnDone ? "call" : "notification";
16959
14599
  try {
16960
- await rail.contact({ goalIds: [goal.id], ask: report, waiting: "none", channel: "notification" });
14600
+ await rail.contact({ asks: [{ ask: report, parentId: goal.id }], waiting: "none", channel });
16961
14601
  const { revision } = await rail.read(goal.id);
16962
14602
  await rail.update(goal.id, { revision: revision ?? goal.revision, changes: { state: "done", progress: report.slice(0, 1e4) }, reason: "The agent finished its turn without asking anything." });
16963
- } catch {
14603
+ } catch (error) {
14604
+ opts?.log?.(`\u26A0 finish contact failed: ${error.message}`);
16964
14605
  }
16965
14606
  }
16966
- async function afterTurn(event, state, rail) {
14607
+ async function afterTurn(event, state, rail, opts) {
16967
14608
  if (!event.failed && !endsWithQuestion(event.result)) {
16968
- await finish(event.result, state, rail);
14609
+ await finish(event.result, state, rail, opts);
16969
14610
  state.resting = true;
16970
14611
  return null;
16971
14612
  }
16972
- const reply = await askQuestion(event.failed ? `The agent stopped without finishing.
14613
+ const rawText = event.failed ? `The agent stopped without finishing.
16973
14614
 
16974
- ${event.result?.trim() || "No result reported."}` : event.result ?? "", state, rail);
14615
+ ${event.result?.trim() || "No result reported."}` : event.result ?? "";
14616
+ const parsed = parseQuestionOptions(rawText);
14617
+ const reply = await askQuestion(parsed.question, state, rail, {
14618
+ call: true,
14619
+ options: parsed.options
14620
+ });
16975
14621
  if (!reply) state.resting = true;
16976
14622
  return reply;
16977
14623
  }
@@ -17018,7 +14664,7 @@ function runHarness(opts) {
17018
14664
  return;
17019
14665
  }
17020
14666
  }
17021
- const reply = await afterTurn(event, state, rail);
14667
+ const reply = await afterTurn(event, state, rail, { log: opts.log });
17022
14668
  if (reply && session && running) {
17023
14669
  opts.log(`you: ${reply.split("\n")[0] ?? ""}`);
17024
14670
  session.send(reply);
@@ -17035,11 +14681,7 @@ function runHarness(opts) {
17035
14681
  ...opts.onExit ? { onExit: opts.onExit } : {},
17036
14682
  onEvent: (event) => void handle(event).catch((err) => opts.log(`\u26A0 ${err.message}`))
17037
14683
  });
17038
- if (opts.prompt) {
17039
- state.resting = false;
17040
- session.send(opts.prompt);
17041
- }
17042
- void pump(session, state, rail, { onIdle: () => running }).catch(
14684
+ void pump(session, state, rail, { onIdle: () => running, initialPrompt: opts.prompt }).catch(
17043
14685
  (e) => opts.log(`\u26A0 conversation loop stopped: ${e.message}`)
17044
14686
  );
17045
14687
  opts.log(`\u25B6 started ${opts.harness} in ${opts.cwd} (${opts.mode} mode)`);
@@ -17063,7 +14705,7 @@ function runHarness(opts) {
17063
14705
  // src/update.ts
17064
14706
  import { execFile } from "child_process";
17065
14707
  import { createRequire } from "module";
17066
- import { dirname as dirname3, join as join5 } from "path";
14708
+ import { dirname as dirname3, join as join6 } from "path";
17067
14709
  import { promisify } from "util";
17068
14710
  var SERVICE_LABEL = "ai.paigy.harness";
17069
14711
  var VERSION = createRequire(import.meta.url)("../package.json").version;
@@ -17090,7 +14732,7 @@ async function latestVersion() {
17090
14732
  }
17091
14733
  async function install(version) {
17092
14734
  const bin = dirname3(process.execPath);
17093
- await promisify(execFile)(join5(bin, "npm"), ["install", "-g", `@paigy/harness@${version}`], {
14735
+ await promisify(execFile)(join6(bin, "npm"), ["install", "-g", `@paigy/harness@${version}`], {
17094
14736
  env: { ...process.env, PATH: `${bin}:${process.env.PATH ?? ""}`, npm_config_update_notifier: "false" },
17095
14737
  timeout: 5 * 6e4
17096
14738
  });
@@ -17141,10 +14783,10 @@ function selfUpdater(deps) {
17141
14783
  }
17142
14784
 
17143
14785
  // src/host.ts
17144
- var HOST_FILE = join6(homedir6(), ".paigy", "host.json");
14786
+ var HOST_FILE = join7(homedir7(), ".paigy", "host.json");
17145
14787
  function readHostState() {
17146
14788
  try {
17147
- const s = JSON.parse(readFileSync3(HOST_FILE, "utf8"));
14789
+ const s = JSON.parse(readFileSync4(HOST_FILE, "utf8"));
17148
14790
  if (Date.now() - s.at > 2e4) return null;
17149
14791
  try {
17150
14792
  process.kill(s.pid, 0);
@@ -17170,9 +14812,9 @@ async function slotHasWaitingWork(token, session) {
17170
14812
  }
17171
14813
  var PRESENCE_FRESH_MS = 3 * 6e4;
17172
14814
  function wakeAction(live, now, serverSeenAt) {
17173
- if (live) return "skip";
17174
- if (serverSeenAt !== void 0 && now - serverSeenAt < PRESENCE_FRESH_MS) return "skip";
17175
- return "spawn";
14815
+ if (live) return { action: "skip", why: "run" };
14816
+ if (serverSeenAt !== void 0 && now - serverSeenAt < PRESENCE_FRESH_MS) return { action: "skip", why: "presence" };
14817
+ return { action: "spawn", why: "nobody" };
17176
14818
  }
17177
14819
  function startHost(opts) {
17178
14820
  const runs = /* @__PURE__ */ new Map();
@@ -17223,6 +14865,7 @@ function startHost(opts) {
17223
14865
  mode: "bypass",
17224
14866
  prompt: "",
17225
14867
  token: spec.token,
14868
+ resume: spec.sessionId,
17226
14869
  onExit: () => {
17227
14870
  runs.delete(key);
17228
14871
  opts.log(`\u2716 ${label} ended`);
@@ -17261,7 +14904,11 @@ function startHost(opts) {
17261
14904
  const live = runs.get(key);
17262
14905
  const tokenId = slotIdentity(slot).tokenId;
17263
14906
  const seenByServer = tokenId ? presence.get(tokenId) : void 0;
17264
- if (wakeAction(!!live, Date.now(), seenByServer) === "skip") return;
14907
+ const decided = wakeAction(!!live, Date.now(), seenByServer);
14908
+ if (decided.action === "skip") {
14909
+ opts.log(decided.why === "run" ? `\u25CC ${slotName(slot) ?? slot} is running here \u2014 its pump types the work in; not spawning` : `\u25CC ${slotName(slot) ?? slot} is working somewhere this host cannot see (heartbeat) \u2014 not spawning`);
14910
+ return;
14911
+ }
17265
14912
  const token = readToken(slot);
17266
14913
  if (!token) return;
17267
14914
  const owner = ownerSession(slot);
@@ -17597,7 +15244,7 @@ function staleWhy(note) {
17597
15244
 
17598
15245
  // src/triage/judge.ts
17599
15246
  import { spawnSync as spawnSync2 } from "child_process";
17600
- import { homedir as homedir7 } from "os";
15247
+ import { homedir as homedir8 } from "os";
17601
15248
  import { delimiter as delimiter3 } from "path";
17602
15249
  var PRIVACY = {
17603
15250
  ollama: "never leaves this machine",
@@ -17641,9 +15288,9 @@ async function available(deps = {}) {
17641
15288
  });
17642
15289
  return [ollama, ...harnesses];
17643
15290
  }
17644
- function refusal(options, asked) {
15291
+ function refusal(options, asked2) {
17645
15292
  const lines2 = [
17646
- asked ? `Can't judge with --via ${asked}: ${options.find((o) => o.provider === asked)?.hint ?? "it isn't available on this machine"}` : "No local judge available \u2014 triage refuses rather than sending your queue to a cloud model.",
15293
+ asked2 ? `Can't judge with --via ${asked2}: ${options.find((o) => o.provider === asked2)?.hint ?? "it isn't available on this machine"}` : "No local judge available \u2014 triage refuses rather than sending your queue to a cloud model.",
17647
15294
  "",
17648
15295
  "Triage runs the model where your queue already lives (#1106). Your options:"
17649
15296
  ];
@@ -17667,10 +15314,10 @@ var RUNNERS = {
17667
15314
  agy: { cli: "agy", argv: () => ["-p"] }
17668
15315
  };
17669
15316
  var RUN_TIMEOUT_MS = 5 * 6e4;
17670
- async function judgeFor(asked, deps = {}) {
15317
+ async function judgeFor(asked2, deps = {}) {
17671
15318
  const options = await available(deps);
17672
- const chosen = asked ? options.find((o) => o.provider === asked) : options.find((o) => o.ready);
17673
- if (!chosen?.ready) return { error: refusal(options, asked) };
15319
+ const chosen = asked2 ? options.find((o) => o.provider === asked2) : options.find((o) => o.ready);
15320
+ if (!chosen?.ready) return { error: refusal(options, asked2) };
17674
15321
  if (chosen.provider === "ollama") {
17675
15322
  const model = chosen.model;
17676
15323
  return {
@@ -17691,9 +15338,9 @@ async function judgeFor(asked, deps = {}) {
17691
15338
  };
17692
15339
  }
17693
15340
  const runner = RUNNERS[chosen.provider];
17694
- if (!runner) return { error: refusal(options, asked) };
15341
+ if (!runner) return { error: refusal(options, asked2) };
17695
15342
  const bin = which(runner.cli);
17696
- if (!bin) return { error: refusal(options, asked) };
15343
+ if (!bin) return { error: refusal(options, asked2) };
17697
15344
  return {
17698
15345
  provider: chosen.provider,
17699
15346
  model: null,
@@ -17701,7 +15348,7 @@ async function judgeFor(asked, deps = {}) {
17701
15348
  const out = spawnSync2(bin, runner.argv(null), {
17702
15349
  input: prompt,
17703
15350
  encoding: "utf8",
17704
- cwd: homedir7(),
15351
+ cwd: homedir8(),
17705
15352
  timeout: RUN_TIMEOUT_MS,
17706
15353
  maxBuffer: 32 * 1024 * 1024,
17707
15354
  env: { ...process.env, PATH: [process.env["PATH"], ...probeDirs()].filter(Boolean).join(delimiter3) }
@@ -17999,7 +15646,7 @@ var win = null;
17999
15646
  function log(message) {
18000
15647
  win?.webContents.send("paigy:log", message);
18001
15648
  }
18002
- var ICON = join7(here, "..", "assets", "icon.png");
15649
+ var ICON = join8(here, "..", "assets", "icon.png");
18003
15650
  function createWindow() {
18004
15651
  win = new BrowserWindow({
18005
15652
  // Sized for the working log, which is now the window's centerpiece; the layout is a
@@ -18011,9 +15658,9 @@ function createWindow() {
18011
15658
  minHeight: 520,
18012
15659
  icon: ICON,
18013
15660
  // Windows/Linux window icon; macOS uses the dock icon below
18014
- webPreferences: { preload: join7(here, "preload.cjs"), contextIsolation: true, nodeIntegration: false }
15661
+ webPreferences: { preload: join8(here, "preload.cjs"), contextIsolation: true, nodeIntegration: false }
18015
15662
  });
18016
- void win.loadFile(join7(here, "..", "renderer", "index.html"));
15663
+ void win.loadFile(join8(here, "..", "renderer", "index.html"));
18017
15664
  }
18018
15665
  var host = null;
18019
15666
  app.whenReady().then(() => {
@@ -18082,7 +15729,7 @@ ipcMain.handle("paigy:agent", async (_e, name) => {
18082
15729
  });
18083
15730
  ipcMain.handle("paigy:agent-log", (_e, name) => {
18084
15731
  try {
18085
- const all = readFileSync4(join7(homedir8(), ".paigy", "host.log"), "utf8").split("\n");
15732
+ const all = readFileSync5(join8(homedir9(), ".paigy", "host.log"), "utf8").split("\n");
18086
15733
  const mine = all.filter((l) => l.includes(`[${name}]`) || /[▶✖◉⚠]/.test(l) && l.includes(name));
18087
15734
  return mine.slice(-500).join("\n");
18088
15735
  } catch {