@kangentic/protocol 0.2.0 → 0.5.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.cjs CHANGED
@@ -23,15 +23,20 @@ __export(index_exports, {
23
23
  BOARD_TOOL_READ_NAMES: () => BOARD_TOOL_READ_NAMES,
24
24
  BOARD_TOOL_WRITE_NAMES: () => BOARD_TOOL_WRITE_NAMES,
25
25
  CAPABILITY_VERBS: () => CAPABILITY_VERBS,
26
+ COMPRESSION_THRESHOLD: () => COMPRESSION_THRESHOLD,
26
27
  CipherState: () => CipherState,
27
28
  ED25519_KEY_LENGTH: () => ED25519_KEY_LENGTH,
28
29
  FrameTag: () => FrameTag,
29
30
  HandshakeState: () => HandshakeState,
30
31
  IKPSK0_PATTERN: () => IKPSK0_PATTERN,
31
32
  KK_PATTERN: () => KK_PATTERN,
33
+ MAX_DECODED_LENGTH: () => MAX_DECODED_LENGTH,
32
34
  MAX_FRAME_LENGTH: () => MAX_FRAME_LENGTH,
33
35
  PAIRING_URI_SCHEME: () => PAIRING_URI_SCHEME,
34
36
  PROTOCOL_VERSION: () => PROTOCOL_VERSION,
37
+ PUSH_CATEGORIES: () => PUSH_CATEGORIES,
38
+ PUSH_ENVELOPE_MAX_AGE_MS: () => PUSH_ENVELOPE_MAX_AGE_MS,
39
+ PUSH_ENVELOPE_MAX_FUTURE_SKEW_MS: () => PUSH_ENVELOPE_MAX_FUTURE_SKEW_MS,
35
40
  SecretstreamState: () => SecretstreamState,
36
41
  SessionFrameKind: () => SessionFrameKind,
37
42
  X25519_KEY_LENGTH: () => X25519_KEY_LENGTH,
@@ -62,8 +67,10 @@ __export(index_exports, {
62
67
  isBridgeEvent: () => isBridgeEvent,
63
68
  isCapabilityVerb: () => isCapabilityVerb,
64
69
  isJsonValue: () => isJsonValue,
70
+ isPushCategory: () => isPushCategory,
65
71
  isRecord: () => isRecord,
66
72
  isRosterEntryExpired: () => isRosterEntryExpired,
73
+ openPushEnvelope: () => openPushEnvelope,
67
74
  parseActivityEventPayload: () => parseActivityEventPayload,
68
75
  parseBacklogItemWire: () => parseBacklogItemWire,
69
76
  parseBoardColumnWire: () => parseBoardColumnWire,
@@ -71,14 +78,20 @@ __export(index_exports, {
71
78
  parseCapabilityRequestPayload: () => parseCapabilityRequestPayload,
72
79
  parseDiffFileContentWire: () => parseDiffFileContentWire,
73
80
  parseDiffFileListWire: () => parseDiffFileListWire,
81
+ parsePushEnvelopePlaintext: () => parsePushEnvelopePlaintext,
74
82
  parseReadBoardResponsePayload: () => parseReadBoardResponsePayload,
75
83
  parseReadDiffResponsePayload: () => parseReadDiffResponsePayload,
76
84
  parseReadStreamResponsePayload: () => parseReadStreamResponsePayload,
85
+ parseRegisterPushRequestPayload: () => parseRegisterPushRequestPayload,
77
86
  parseSessionEventWire: () => parseSessionEventWire,
78
87
  parseSessionUsageWire: () => parseSessionUsageWire,
88
+ parseTerminalDimensionsWire: () => parseTerminalDimensionsWire,
79
89
  parseTranscriptEntriesWire: () => parseTranscriptEntriesWire,
90
+ parseTranscriptEventPayload: () => parseTranscriptEventPayload,
91
+ parseTranscriptWindowResponsePayload: () => parseTranscriptWindowResponsePayload,
80
92
  randomBytes: () => randomBytes4,
81
93
  rosterDeviceCapabilitySet: () => rosterDeviceCapabilitySet,
94
+ sealPushEnvelope: () => sealPushEnvelope,
82
95
  signRosterEntry: () => signRosterEntry,
83
96
  unwrapSessionFrame: () => unwrapSessionFrame,
84
97
  verifyRosterEntry: () => verifyRosterEntry,
@@ -88,7 +101,7 @@ __export(index_exports, {
88
101
  module.exports = __toCommonJS(index_exports);
89
102
 
90
103
  // src/version.ts
91
- var PROTOCOL_VERSION = "1";
104
+ var PROTOCOL_VERSION = "2";
92
105
  function encodeProtocolVersion(version = PROTOCOL_VERSION) {
93
106
  return new TextEncoder().encode(`kangentic-bridge-v${version}`);
94
107
  }
@@ -718,12 +731,12 @@ function asciiToBytes(ascii) {
718
731
  });
719
732
  }
720
733
  var isPosBig = (n) => typeof n === "bigint" && _0n <= n;
721
- function inRange(n, min, max) {
722
- return isPosBig(n) && isPosBig(min) && isPosBig(max) && min <= n && n < max;
734
+ function inRange(n, min, max2) {
735
+ return isPosBig(n) && isPosBig(min) && isPosBig(max2) && min <= n && n < max2;
723
736
  }
724
- function aInRange(title, n, min, max) {
725
- if (!inRange(n, min, max))
726
- throw new RangeError("expected valid " + title + ": " + min + " <= n < " + max + ", got " + n);
737
+ function aInRange(title, n, min, max2) {
738
+ if (!inRange(n, min, max2))
739
+ throw new RangeError("expected valid " + title + ": " + min + " <= n < " + max2 + ", got " + n);
727
740
  }
728
741
  function bitLen(n) {
729
742
  if (n < _0n)
@@ -1000,10 +1013,10 @@ function nLength(n, nBitLength) {
1000
1013
  throw new Error("invalid n length: expected positive n, got " + n);
1001
1014
  if (nBitLength !== void 0 && nBitLength < 1)
1002
1015
  throw new Error("invalid n length: expected positive bit length, got " + nBitLength);
1003
- const bits = bitLen(n);
1004
- if (nBitLength !== void 0 && nBitLength < bits)
1005
- throw new Error(`invalid n length: expected bit length (${bits}) >= n.length (${nBitLength})`);
1006
- const _nBitLength = nBitLength !== void 0 ? nBitLength : bits;
1016
+ const bits2 = bitLen(n);
1017
+ if (nBitLength !== void 0 && nBitLength < bits2)
1018
+ throw new Error(`invalid n length: expected bit length (${bits2}) >= n.length (${nBitLength})`);
1019
+ const _nBitLength = nBitLength !== void 0 ? nBitLength : bits2;
1007
1020
  const nByteLength = Math.ceil(_nBitLength / 8);
1008
1021
  return { nBitLength: _nBitLength, nByteLength };
1009
1022
  }
@@ -1158,9 +1171,9 @@ function normalizeZ(c, points) {
1158
1171
  const invertedZs = FpInvertBatch(c.Fp, points.map((p) => p.Z));
1159
1172
  return points.map((p, i) => c.fromAffine(p.toAffine(invertedZs[i])));
1160
1173
  }
1161
- function validateW(W, bits) {
1162
- if (!Number.isSafeInteger(W) || W <= 0 || W > bits)
1163
- throw new Error("invalid window size, expected [1.." + bits + "], got W=" + W);
1174
+ function validateW(W, bits2) {
1175
+ if (!Number.isSafeInteger(W) || W <= 0 || W > bits2)
1176
+ throw new Error("invalid window size, expected [1.." + bits2 + "], got W=" + W);
1164
1177
  }
1165
1178
  function calcWOpts(W, scalarBits) {
1166
1179
  validateW(W, scalarBits);
@@ -1173,16 +1186,16 @@ function calcWOpts(W, scalarBits) {
1173
1186
  }
1174
1187
  function calcOffsets(n, window, wOpts) {
1175
1188
  const { windowSize, mask, maxNumber, shiftBy } = wOpts;
1176
- let wbits = Number(n & mask);
1189
+ let wbits2 = Number(n & mask);
1177
1190
  let nextN = n >> shiftBy;
1178
- if (wbits > windowSize) {
1179
- wbits -= maxNumber;
1191
+ if (wbits2 > windowSize) {
1192
+ wbits2 -= maxNumber;
1180
1193
  nextN += _1n3;
1181
1194
  }
1182
1195
  const offsetStart = window * windowSize;
1183
- const offset = offsetStart + Math.abs(wbits) - 1;
1184
- const isZero = wbits === 0;
1185
- const isNeg = wbits < 0;
1196
+ const offset = offsetStart + Math.abs(wbits2) - 1;
1197
+ const isZero = wbits2 === 0;
1198
+ const isNeg = wbits2 < 0;
1186
1199
  const isNegF = window % 2 !== 0;
1187
1200
  const offsetF = offsetStart;
1188
1201
  return { nextN, offset, isZero, isNeg, isNegF, offsetF };
@@ -1202,11 +1215,11 @@ var wNAF = class {
1202
1215
  Fn;
1203
1216
  bits;
1204
1217
  // Parametrized with a given Point class (not individual point)
1205
- constructor(Point, bits) {
1218
+ constructor(Point, bits2) {
1206
1219
  this.BASE = Point.BASE;
1207
1220
  this.ZERO = Point.ZERO;
1208
1221
  this.Fn = Point.Fn;
1209
- this.bits = bits;
1222
+ this.bits = bits2;
1210
1223
  }
1211
1224
  // non-const time multiplication ladder
1212
1225
  _unsafeLadder(elm, n, p = this.ZERO) {
@@ -1350,8 +1363,8 @@ function createCurveFields(type, CURVE, curveOpts = {}, FpFnLE) {
1350
1363
  }
1351
1364
  const Fp2 = createField(CURVE.p, curveOpts.Fp, FpFnLE);
1352
1365
  const Fn2 = createField(CURVE.n, curveOpts.Fn, FpFnLE);
1353
- const _b = type === "weierstrass" ? "b" : "d";
1354
- const params = ["Gx", "Gy", "a", _b];
1366
+ const _b2 = type === "weierstrass" ? "b" : "d";
1367
+ const params = ["Gx", "Gy", "a", _b2];
1355
1368
  for (const p of params) {
1356
1369
  if (!Fp2.isValid(CURVE[p]))
1357
1370
  throw new Error(`CURVE.${p} must be valid field element of CURVE.Fp`);
@@ -1452,8 +1465,8 @@ function edwards(params, extraOpts = {}) {
1452
1465
  const lastByte = bytes[len - 1];
1453
1466
  normed[len - 1] = lastByte & ~128;
1454
1467
  const y = bytesToNumberLE(normed);
1455
- const max = zip215 ? MASK : Fp2.ORDER;
1456
- aInRange("point.y", y, _0n4, max);
1468
+ const max2 = zip215 ? MASK : Fp2.ORDER;
1469
+ aInRange("point.y", y, _0n4, max2);
1457
1470
  const y2 = modP(y * y);
1458
1471
  const u = modP(y2 - _1n4);
1459
1472
  const v = modP(d * y2 - a);
@@ -4267,6 +4280,700 @@ function deriveSessionSlotId(desktopStaticPublicKey, phoneStaticPublicKey) {
4267
4280
  return bytesToHex(deriveLabeledKey(material, SESSION_SLOT_LABEL, SESSION_SLOT_LENGTH));
4268
4281
  }
4269
4282
 
4283
+ // ../../node_modules/fflate/esm/index.mjs
4284
+ var import_module = require("module");
4285
+ var require2 = (0, import_module.createRequire)("/");
4286
+ var _a;
4287
+ var Worker;
4288
+ var isMarkedAsUntransferable;
4289
+ try {
4290
+ _a = require2("worker_threads"), Worker = _a.Worker, isMarkedAsUntransferable = _a.isMarkedAsUntransferable;
4291
+ } catch (e) {
4292
+ }
4293
+ var u8 = Uint8Array;
4294
+ var u16 = Uint16Array;
4295
+ var i32 = Int32Array;
4296
+ var fleb = new u8([
4297
+ 0,
4298
+ 0,
4299
+ 0,
4300
+ 0,
4301
+ 0,
4302
+ 0,
4303
+ 0,
4304
+ 0,
4305
+ 1,
4306
+ 1,
4307
+ 1,
4308
+ 1,
4309
+ 2,
4310
+ 2,
4311
+ 2,
4312
+ 2,
4313
+ 3,
4314
+ 3,
4315
+ 3,
4316
+ 3,
4317
+ 4,
4318
+ 4,
4319
+ 4,
4320
+ 4,
4321
+ 5,
4322
+ 5,
4323
+ 5,
4324
+ 5,
4325
+ 0,
4326
+ /* unused */
4327
+ 0,
4328
+ 0,
4329
+ /* impossible */
4330
+ 0
4331
+ ]);
4332
+ var fdeb = new u8([
4333
+ 0,
4334
+ 0,
4335
+ 0,
4336
+ 0,
4337
+ 1,
4338
+ 1,
4339
+ 2,
4340
+ 2,
4341
+ 3,
4342
+ 3,
4343
+ 4,
4344
+ 4,
4345
+ 5,
4346
+ 5,
4347
+ 6,
4348
+ 6,
4349
+ 7,
4350
+ 7,
4351
+ 8,
4352
+ 8,
4353
+ 9,
4354
+ 9,
4355
+ 10,
4356
+ 10,
4357
+ 11,
4358
+ 11,
4359
+ 12,
4360
+ 12,
4361
+ 13,
4362
+ 13,
4363
+ /* unused */
4364
+ 0,
4365
+ 0
4366
+ ]);
4367
+ var clim = new u8([16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15]);
4368
+ var freb = function(eb, start) {
4369
+ var b = new u16(31);
4370
+ for (var i = 0; i < 31; ++i) {
4371
+ b[i] = start += 1 << eb[i - 1];
4372
+ }
4373
+ var r = new i32(b[30]);
4374
+ for (var i = 1; i < 30; ++i) {
4375
+ for (var j = b[i]; j < b[i + 1]; ++j) {
4376
+ r[j] = j - b[i] << 5 | i;
4377
+ }
4378
+ }
4379
+ return { b, r };
4380
+ };
4381
+ var _a = freb(fleb, 2);
4382
+ var fl = _a.b;
4383
+ var revfl = _a.r;
4384
+ fl[28] = 258, revfl[258] = 28;
4385
+ var _b = freb(fdeb, 0);
4386
+ var fd = _b.b;
4387
+ var revfd = _b.r;
4388
+ var rev = new u16(32768);
4389
+ for (i = 0; i < 32768; ++i) {
4390
+ x = (i & 43690) >> 1 | (i & 21845) << 1;
4391
+ x = (x & 52428) >> 2 | (x & 13107) << 2;
4392
+ x = (x & 61680) >> 4 | (x & 3855) << 4;
4393
+ rev[i] = ((x & 65280) >> 8 | (x & 255) << 8) >> 1;
4394
+ }
4395
+ var x;
4396
+ var i;
4397
+ var hMap = (function(cd, mb, r) {
4398
+ var s = cd.length;
4399
+ var i = 0;
4400
+ var l = new u16(mb);
4401
+ for (; i < s; ++i) {
4402
+ if (cd[i])
4403
+ ++l[cd[i] - 1];
4404
+ }
4405
+ var le = new u16(mb);
4406
+ for (i = 1; i < mb; ++i) {
4407
+ le[i] = le[i - 1] + l[i - 1] << 1;
4408
+ }
4409
+ var co;
4410
+ if (r) {
4411
+ co = new u16(1 << mb);
4412
+ var rvb = 15 - mb;
4413
+ for (i = 0; i < s; ++i) {
4414
+ if (cd[i]) {
4415
+ var sv = i << 4 | cd[i];
4416
+ var r_1 = mb - cd[i];
4417
+ var v = le[cd[i] - 1]++ << r_1;
4418
+ for (var m = v | (1 << r_1) - 1; v <= m; ++v) {
4419
+ co[rev[v] >> rvb] = sv;
4420
+ }
4421
+ }
4422
+ }
4423
+ } else {
4424
+ co = new u16(s);
4425
+ for (i = 0; i < s; ++i) {
4426
+ if (cd[i]) {
4427
+ co[i] = rev[le[cd[i] - 1]++] >> 15 - cd[i];
4428
+ }
4429
+ }
4430
+ }
4431
+ return co;
4432
+ });
4433
+ var flt = new u8(288);
4434
+ for (i = 0; i < 144; ++i)
4435
+ flt[i] = 8;
4436
+ var i;
4437
+ for (i = 144; i < 256; ++i)
4438
+ flt[i] = 9;
4439
+ var i;
4440
+ for (i = 256; i < 280; ++i)
4441
+ flt[i] = 7;
4442
+ var i;
4443
+ for (i = 280; i < 288; ++i)
4444
+ flt[i] = 8;
4445
+ var i;
4446
+ var fdt = new u8(32);
4447
+ for (i = 0; i < 32; ++i)
4448
+ fdt[i] = 5;
4449
+ var i;
4450
+ var flm = /* @__PURE__ */ hMap(flt, 9, 0);
4451
+ var flrm = /* @__PURE__ */ hMap(flt, 9, 1);
4452
+ var fdm = /* @__PURE__ */ hMap(fdt, 5, 0);
4453
+ var fdrm = /* @__PURE__ */ hMap(fdt, 5, 1);
4454
+ var max = function(a) {
4455
+ var m = a[0];
4456
+ for (var i = 1; i < a.length; ++i) {
4457
+ if (a[i] > m)
4458
+ m = a[i];
4459
+ }
4460
+ return m;
4461
+ };
4462
+ var bits = function(d, p, m) {
4463
+ var o = p / 8 | 0;
4464
+ return (d[o] | d[o + 1] << 8) >> (p & 7) & m;
4465
+ };
4466
+ var bits16 = function(d, p) {
4467
+ var o = p / 8 | 0;
4468
+ return (d[o] | d[o + 1] << 8 | d[o + 2] << 16) >> (p & 7);
4469
+ };
4470
+ var shft = function(p) {
4471
+ return (p + 7) / 8 | 0;
4472
+ };
4473
+ var slc = function(v, s, e) {
4474
+ if (s == null || s < 0)
4475
+ s = 0;
4476
+ if (e == null || e > v.length)
4477
+ e = v.length;
4478
+ return new u8(v.subarray(s, e));
4479
+ };
4480
+ var ec = [
4481
+ "unexpected EOF",
4482
+ "invalid block type",
4483
+ "invalid length/literal",
4484
+ "invalid distance",
4485
+ "stream finished",
4486
+ "no stream handler",
4487
+ ,
4488
+ // determined by compression function
4489
+ "no callback",
4490
+ "invalid UTF-8 data",
4491
+ "extra field too long",
4492
+ "date not in range 1980-2099",
4493
+ "filename too long",
4494
+ "stream finishing",
4495
+ "invalid zip data"
4496
+ // determined by unknown compression method
4497
+ ];
4498
+ var err = function(ind, msg, nt) {
4499
+ var e = new Error(msg || ec[ind]);
4500
+ e.code = ind;
4501
+ if (Error.captureStackTrace)
4502
+ Error.captureStackTrace(e, err);
4503
+ if (!nt)
4504
+ throw e;
4505
+ return e;
4506
+ };
4507
+ var inflt = function(dat, st, buf, dict) {
4508
+ var sl = dat.length, dl = dict ? dict.length : 0;
4509
+ if (!sl || st.f && !st.l)
4510
+ return buf || new u8(0);
4511
+ var noBuf = !buf;
4512
+ var resize = noBuf || st.i != 2;
4513
+ var noSt = st.i;
4514
+ if (noBuf)
4515
+ buf = new u8(sl * 3);
4516
+ var cbuf = function(l2) {
4517
+ var bl = buf.length;
4518
+ if (l2 > bl) {
4519
+ var nbuf = new u8(Math.max(bl * 2, l2));
4520
+ nbuf.set(buf);
4521
+ buf = nbuf;
4522
+ }
4523
+ };
4524
+ var final = st.f || 0, pos = st.p || 0, bt = st.b || 0, lm = st.l, dm = st.d, lbt = st.m, dbt = st.n;
4525
+ var tbts = sl * 8;
4526
+ do {
4527
+ if (!lm) {
4528
+ final = bits(dat, pos, 1);
4529
+ var type = bits(dat, pos + 1, 3);
4530
+ pos += 3;
4531
+ if (!type) {
4532
+ var s = shft(pos) + 4, l = dat[s - 4] | dat[s - 3] << 8, t = s + l;
4533
+ if (t > sl) {
4534
+ if (noSt)
4535
+ err(0);
4536
+ break;
4537
+ }
4538
+ if (resize)
4539
+ cbuf(bt + l);
4540
+ buf.set(dat.subarray(s, t), bt);
4541
+ st.b = bt += l, st.p = pos = t * 8, st.f = final;
4542
+ continue;
4543
+ } else if (type == 1)
4544
+ lm = flrm, dm = fdrm, lbt = 9, dbt = 5;
4545
+ else if (type == 2) {
4546
+ var hLit = bits(dat, pos, 31) + 257, hcLen = bits(dat, pos + 10, 15) + 4;
4547
+ var tl = hLit + bits(dat, pos + 5, 31) + 1;
4548
+ pos += 14;
4549
+ var ldt = new u8(tl);
4550
+ var clt = new u8(19);
4551
+ for (var i = 0; i < hcLen; ++i) {
4552
+ clt[clim[i]] = bits(dat, pos + i * 3, 7);
4553
+ }
4554
+ pos += hcLen * 3;
4555
+ var clb = max(clt), clbmsk = (1 << clb) - 1;
4556
+ var clm = hMap(clt, clb, 1);
4557
+ for (var i = 0; i < tl; ) {
4558
+ var r = clm[bits(dat, pos, clbmsk)];
4559
+ pos += r & 15;
4560
+ var s = r >> 4;
4561
+ if (s < 16) {
4562
+ ldt[i++] = s;
4563
+ } else {
4564
+ var c = 0, n = 0;
4565
+ if (s == 16)
4566
+ n = 3 + bits(dat, pos, 3), pos += 2, c = ldt[i - 1];
4567
+ else if (s == 17)
4568
+ n = 3 + bits(dat, pos, 7), pos += 3;
4569
+ else if (s == 18)
4570
+ n = 11 + bits(dat, pos, 127), pos += 7;
4571
+ while (n--)
4572
+ ldt[i++] = c;
4573
+ }
4574
+ }
4575
+ var lt = ldt.subarray(0, hLit), dt = ldt.subarray(hLit);
4576
+ lbt = max(lt);
4577
+ dbt = max(dt);
4578
+ lm = hMap(lt, lbt, 1);
4579
+ dm = hMap(dt, dbt, 1);
4580
+ } else
4581
+ err(1);
4582
+ if (pos > tbts) {
4583
+ if (noSt)
4584
+ err(0);
4585
+ break;
4586
+ }
4587
+ }
4588
+ if (resize)
4589
+ cbuf(bt + 131072);
4590
+ var lms = (1 << lbt) - 1, dms = (1 << dbt) - 1;
4591
+ var lpos = pos;
4592
+ for (; ; lpos = pos) {
4593
+ var c = lm[bits16(dat, pos) & lms], sym = c >> 4;
4594
+ pos += c & 15;
4595
+ if (pos > tbts) {
4596
+ if (noSt)
4597
+ err(0);
4598
+ break;
4599
+ }
4600
+ if (!c)
4601
+ err(2);
4602
+ if (sym < 256)
4603
+ buf[bt++] = sym;
4604
+ else if (sym == 256) {
4605
+ lpos = pos, lm = null;
4606
+ break;
4607
+ } else {
4608
+ var add2 = sym - 254;
4609
+ if (sym > 264) {
4610
+ var i = sym - 257, b = fleb[i];
4611
+ add2 = bits(dat, pos, (1 << b) - 1) + fl[i];
4612
+ pos += b;
4613
+ }
4614
+ var d = dm[bits16(dat, pos) & dms], dsym = d >> 4;
4615
+ if (!d)
4616
+ err(3);
4617
+ pos += d & 15;
4618
+ var dt = fd[dsym];
4619
+ if (dsym > 3) {
4620
+ var b = fdeb[dsym];
4621
+ dt += bits16(dat, pos) & (1 << b) - 1, pos += b;
4622
+ }
4623
+ if (pos > tbts) {
4624
+ if (noSt)
4625
+ err(0);
4626
+ break;
4627
+ }
4628
+ if (resize)
4629
+ cbuf(bt + 131072);
4630
+ var end = bt + add2;
4631
+ if (bt < dt) {
4632
+ var shift = dl - dt, dend = Math.min(dt, end);
4633
+ if (shift + bt < 0)
4634
+ err(3);
4635
+ for (; bt < dend; ++bt)
4636
+ buf[bt] = dict[shift + bt];
4637
+ }
4638
+ for (; bt < end; ++bt)
4639
+ buf[bt] = buf[bt - dt];
4640
+ }
4641
+ }
4642
+ st.l = lm, st.p = lpos, st.b = bt, st.f = final;
4643
+ if (lm)
4644
+ final = 1, st.m = lbt, st.d = dm, st.n = dbt;
4645
+ } while (!final);
4646
+ return bt != buf.length && noBuf ? slc(buf, 0, bt) : buf.subarray(0, bt);
4647
+ };
4648
+ var wbits = function(d, p, v) {
4649
+ v <<= p & 7;
4650
+ var o = p / 8 | 0;
4651
+ d[o] |= v;
4652
+ d[o + 1] |= v >> 8;
4653
+ };
4654
+ var wbits16 = function(d, p, v) {
4655
+ v <<= p & 7;
4656
+ var o = p / 8 | 0;
4657
+ d[o] |= v;
4658
+ d[o + 1] |= v >> 8;
4659
+ d[o + 2] |= v >> 16;
4660
+ };
4661
+ var hTree = function(d, mb) {
4662
+ var t = [];
4663
+ for (var i = 0; i < d.length; ++i) {
4664
+ if (d[i])
4665
+ t.push({ s: i, f: d[i] });
4666
+ }
4667
+ var s = t.length;
4668
+ var t2 = t.slice();
4669
+ if (!s)
4670
+ return { t: et, l: 0 };
4671
+ if (s == 1) {
4672
+ var v = new u8(t[0].s + 1);
4673
+ v[t[0].s] = 1;
4674
+ return { t: v, l: 1 };
4675
+ }
4676
+ t.sort(function(a, b) {
4677
+ return a.f - b.f;
4678
+ });
4679
+ t.push({ s: -1, f: 25001 });
4680
+ var l = t[0], r = t[1], i0 = 0, i1 = 1, i2 = 2;
4681
+ t[0] = { s: -1, f: l.f + r.f, l, r };
4682
+ while (i1 != s - 1) {
4683
+ l = t[t[i0].f < t[i2].f ? i0++ : i2++];
4684
+ r = t[i0 != i1 && t[i0].f < t[i2].f ? i0++ : i2++];
4685
+ t[i1++] = { s: -1, f: l.f + r.f, l, r };
4686
+ }
4687
+ var maxSym = t2[0].s;
4688
+ for (var i = 1; i < s; ++i) {
4689
+ if (t2[i].s > maxSym)
4690
+ maxSym = t2[i].s;
4691
+ }
4692
+ var tr = new u16(maxSym + 1);
4693
+ var mbt = ln(t[i1 - 1], tr, 0);
4694
+ if (mbt > mb) {
4695
+ var i = 0, dt = 0;
4696
+ var lft = mbt - mb, cst = 1 << lft;
4697
+ t2.sort(function(a, b) {
4698
+ return tr[b.s] - tr[a.s] || a.f - b.f;
4699
+ });
4700
+ for (; i < s; ++i) {
4701
+ var i2_1 = t2[i].s;
4702
+ if (tr[i2_1] > mb) {
4703
+ dt += cst - (1 << mbt - tr[i2_1]);
4704
+ tr[i2_1] = mb;
4705
+ } else
4706
+ break;
4707
+ }
4708
+ dt >>= lft;
4709
+ while (dt > 0) {
4710
+ var i2_2 = t2[i].s;
4711
+ if (tr[i2_2] < mb)
4712
+ dt -= 1 << mb - tr[i2_2]++ - 1;
4713
+ else
4714
+ ++i;
4715
+ }
4716
+ for (; i >= 0 && dt; --i) {
4717
+ var i2_3 = t2[i].s;
4718
+ if (tr[i2_3] == mb) {
4719
+ --tr[i2_3];
4720
+ ++dt;
4721
+ }
4722
+ }
4723
+ mbt = mb;
4724
+ }
4725
+ return { t: new u8(tr), l: mbt };
4726
+ };
4727
+ var ln = function(n, l, d) {
4728
+ return n.s == -1 ? Math.max(ln(n.l, l, d + 1), ln(n.r, l, d + 1)) : l[n.s] = d;
4729
+ };
4730
+ var lc = function(c) {
4731
+ var s = c.length;
4732
+ while (s && !c[--s])
4733
+ ;
4734
+ var cl = new u16(++s);
4735
+ var cli = 0, cln = c[0], cls = 1;
4736
+ var w = function(v) {
4737
+ cl[cli++] = v;
4738
+ };
4739
+ for (var i = 1; i <= s; ++i) {
4740
+ if (c[i] == cln && i != s)
4741
+ ++cls;
4742
+ else {
4743
+ if (!cln && cls > 2) {
4744
+ for (; cls > 138; cls -= 138)
4745
+ w(32754);
4746
+ if (cls > 2) {
4747
+ w(cls > 10 ? cls - 11 << 5 | 28690 : cls - 3 << 5 | 12305);
4748
+ cls = 0;
4749
+ }
4750
+ } else if (cls > 3) {
4751
+ w(cln), --cls;
4752
+ for (; cls > 6; cls -= 6)
4753
+ w(8304);
4754
+ if (cls > 2)
4755
+ w(cls - 3 << 5 | 8208), cls = 0;
4756
+ }
4757
+ while (cls--)
4758
+ w(cln);
4759
+ cls = 1;
4760
+ cln = c[i];
4761
+ }
4762
+ }
4763
+ return { c: cl.subarray(0, cli), n: s };
4764
+ };
4765
+ var clen = function(cf, cl) {
4766
+ var l = 0;
4767
+ for (var i = 0; i < cl.length; ++i)
4768
+ l += cf[i] * cl[i];
4769
+ return l;
4770
+ };
4771
+ var wfblk = function(out, pos, dat) {
4772
+ var s = dat.length;
4773
+ var o = shft(pos + 2);
4774
+ out[o] = s & 255;
4775
+ out[o + 1] = s >> 8;
4776
+ out[o + 2] = out[o] ^ 255;
4777
+ out[o + 3] = out[o + 1] ^ 255;
4778
+ for (var i = 0; i < s; ++i)
4779
+ out[o + i + 4] = dat[i];
4780
+ return (o + 4 + s) * 8;
4781
+ };
4782
+ var wblk = function(dat, out, final, syms, lf, df, eb, li, bs, bl, p) {
4783
+ wbits(out, p++, final);
4784
+ ++lf[256];
4785
+ var _a2 = hTree(lf, 15), dlt = _a2.t, mlb = _a2.l;
4786
+ var _b2 = hTree(df, 15), ddt = _b2.t, mdb = _b2.l;
4787
+ var _c = lc(dlt), lclt = _c.c, nlc = _c.n;
4788
+ var _d = lc(ddt), lcdt = _d.c, ndc = _d.n;
4789
+ var lcfreq = new u16(19);
4790
+ for (var i = 0; i < lclt.length; ++i)
4791
+ ++lcfreq[lclt[i] & 31];
4792
+ for (var i = 0; i < lcdt.length; ++i)
4793
+ ++lcfreq[lcdt[i] & 31];
4794
+ var _e = hTree(lcfreq, 7), lct = _e.t, mlcb = _e.l;
4795
+ var nlcc = 19;
4796
+ for (; nlcc > 4 && !lct[clim[nlcc - 1]]; --nlcc)
4797
+ ;
4798
+ var flen = bl + 5 << 3;
4799
+ var ftlen = clen(lf, flt) + clen(df, fdt) + eb;
4800
+ var dtlen = clen(lf, dlt) + clen(df, ddt) + eb + 14 + 3 * nlcc + clen(lcfreq, lct) + 2 * lcfreq[16] + 3 * lcfreq[17] + 7 * lcfreq[18];
4801
+ if (bs >= 0 && flen <= ftlen && flen <= dtlen)
4802
+ return wfblk(out, p, dat.subarray(bs, bs + bl));
4803
+ var lm, ll, dm, dl;
4804
+ wbits(out, p, 1 + (dtlen < ftlen)), p += 2;
4805
+ if (dtlen < ftlen) {
4806
+ lm = hMap(dlt, mlb, 0), ll = dlt, dm = hMap(ddt, mdb, 0), dl = ddt;
4807
+ var llm = hMap(lct, mlcb, 0);
4808
+ wbits(out, p, nlc - 257);
4809
+ wbits(out, p + 5, ndc - 1);
4810
+ wbits(out, p + 10, nlcc - 4);
4811
+ p += 14;
4812
+ for (var i = 0; i < nlcc; ++i)
4813
+ wbits(out, p + 3 * i, lct[clim[i]]);
4814
+ p += 3 * nlcc;
4815
+ var lcts = [lclt, lcdt];
4816
+ for (var it = 0; it < 2; ++it) {
4817
+ var clct = lcts[it];
4818
+ for (var i = 0; i < clct.length; ++i) {
4819
+ var len = clct[i] & 31;
4820
+ wbits(out, p, llm[len]), p += lct[len];
4821
+ if (len > 15)
4822
+ wbits(out, p, clct[i] >> 5 & 127), p += clct[i] >> 12;
4823
+ }
4824
+ }
4825
+ } else {
4826
+ lm = flm, ll = flt, dm = fdm, dl = fdt;
4827
+ }
4828
+ for (var i = 0; i < li; ++i) {
4829
+ var sym = syms[i];
4830
+ if (sym > 255) {
4831
+ var len = sym >> 18 & 31;
4832
+ wbits16(out, p, lm[len + 257]), p += ll[len + 257];
4833
+ if (len > 7)
4834
+ wbits(out, p, sym >> 23 & 31), p += fleb[len];
4835
+ var dst = sym & 31;
4836
+ wbits16(out, p, dm[dst]), p += dl[dst];
4837
+ if (dst > 3)
4838
+ wbits16(out, p, sym >> 5 & 8191), p += fdeb[dst];
4839
+ } else {
4840
+ wbits16(out, p, lm[sym]), p += ll[sym];
4841
+ }
4842
+ }
4843
+ wbits16(out, p, lm[256]);
4844
+ return p + ll[256];
4845
+ };
4846
+ var deo = /* @__PURE__ */ new i32([65540, 131080, 131088, 131104, 262176, 1048704, 1048832, 2114560, 2117632]);
4847
+ var et = /* @__PURE__ */ new u8(0);
4848
+ var dflt = function(dat, lvl, plvl, pre, post, st) {
4849
+ var s = st.z || dat.length;
4850
+ var o = new u8(pre + s + 5 * (1 + Math.ceil(s / 7e3)) + post);
4851
+ var w = o.subarray(pre, o.length - post);
4852
+ var lst = st.l;
4853
+ var pos = (st.r || 0) & 7;
4854
+ if (lvl) {
4855
+ if (pos)
4856
+ w[0] = st.r >> 3;
4857
+ var opt = deo[lvl - 1];
4858
+ var n = opt >> 13, c = opt & 8191;
4859
+ var msk_1 = (1 << plvl) - 1;
4860
+ var prev = st.p || new u16(32768), head = st.h || new u16(msk_1 + 1);
4861
+ var bs1_1 = Math.ceil(plvl / 3), bs2_1 = 2 * bs1_1;
4862
+ var hsh = function(i2) {
4863
+ return (dat[i2] ^ dat[i2 + 1] << bs1_1 ^ dat[i2 + 2] << bs2_1) & msk_1;
4864
+ };
4865
+ var syms = new i32(25e3);
4866
+ var lf = new u16(288), df = new u16(32);
4867
+ var lc_1 = 0, eb = 0, i = st.i || 0, li = 0, wi = st.w || 0, bs = 0;
4868
+ for (; i + 2 < s; ++i) {
4869
+ var hv = hsh(i);
4870
+ var imod = i & 32767, pimod = head[hv];
4871
+ prev[imod] = pimod;
4872
+ head[hv] = imod;
4873
+ if (wi <= i) {
4874
+ var rem = s - i;
4875
+ if ((lc_1 > 7e3 || li > 24576) && (rem > 423 || !lst)) {
4876
+ pos = wblk(dat, w, 0, syms, lf, df, eb, li, bs, i - bs, pos);
4877
+ li = lc_1 = eb = 0, bs = i;
4878
+ for (var j = 0; j < 286; ++j)
4879
+ lf[j] = 0;
4880
+ for (var j = 0; j < 30; ++j)
4881
+ df[j] = 0;
4882
+ }
4883
+ var l = 2, d = 0, ch_1 = c, dif = imod - pimod & 32767;
4884
+ if (rem > 2 && hv == hsh(i - dif)) {
4885
+ var maxn = Math.min(n, rem) - 1;
4886
+ var maxd = Math.min(32767, i);
4887
+ var ml = Math.min(258, rem);
4888
+ while (dif <= maxd && --ch_1 && imod != pimod) {
4889
+ if (dat[i + l] == dat[i + l - dif]) {
4890
+ var nl = 0;
4891
+ for (; nl < ml && dat[i + nl] == dat[i + nl - dif]; ++nl)
4892
+ ;
4893
+ if (nl > l) {
4894
+ l = nl, d = dif;
4895
+ if (nl > maxn)
4896
+ break;
4897
+ var mmd = Math.min(dif, nl - 2);
4898
+ var md = 0;
4899
+ for (var j = 0; j < mmd; ++j) {
4900
+ var ti = i - dif + j & 32767;
4901
+ var pti = prev[ti];
4902
+ var cd = ti - pti & 32767;
4903
+ if (cd > md)
4904
+ md = cd, pimod = ti;
4905
+ }
4906
+ }
4907
+ }
4908
+ imod = pimod, pimod = prev[imod];
4909
+ dif += imod - pimod & 32767;
4910
+ }
4911
+ }
4912
+ if (d) {
4913
+ syms[li++] = 268435456 | revfl[l] << 18 | revfd[d];
4914
+ var lin = revfl[l] & 31, din = revfd[d] & 31;
4915
+ eb += fleb[lin] + fdeb[din];
4916
+ ++lf[257 + lin];
4917
+ ++df[din];
4918
+ wi = i + l;
4919
+ ++lc_1;
4920
+ } else {
4921
+ syms[li++] = dat[i];
4922
+ ++lf[dat[i]];
4923
+ }
4924
+ }
4925
+ }
4926
+ for (i = Math.max(i, wi); i < s; ++i) {
4927
+ syms[li++] = dat[i];
4928
+ ++lf[dat[i]];
4929
+ }
4930
+ pos = wblk(dat, w, lst, syms, lf, df, eb, li, bs, i - bs, pos);
4931
+ if (!lst) {
4932
+ st.r = pos & 7 | w[pos / 8 | 0] << 3;
4933
+ pos -= 7;
4934
+ st.h = head, st.p = prev, st.i = i, st.w = wi;
4935
+ }
4936
+ } else {
4937
+ for (var i = st.w || 0; i < s + lst; i += 65535) {
4938
+ var e = i + 65535;
4939
+ if (e >= s) {
4940
+ w[pos / 8 | 0] = lst;
4941
+ e = s;
4942
+ }
4943
+ pos = wfblk(w, pos + 1, dat.subarray(i, e));
4944
+ }
4945
+ st.i = s;
4946
+ }
4947
+ return slc(o, 0, pre + shft(pos) + post);
4948
+ };
4949
+ var dopt = function(dat, opt, pre, post, st) {
4950
+ if (!st) {
4951
+ st = { l: 1 };
4952
+ if (opt.dictionary) {
4953
+ var dict = opt.dictionary.subarray(-32768);
4954
+ var newDat = new u8(dict.length + dat.length);
4955
+ newDat.set(dict);
4956
+ newDat.set(dat, dict.length);
4957
+ dat = newDat;
4958
+ st.w = dict.length;
4959
+ }
4960
+ }
4961
+ return dflt(dat, opt.level == null ? 6 : opt.level, opt.mem == null ? st.l ? Math.ceil(Math.max(8, Math.min(13, Math.log(dat.length))) * 1.5) : 20 : 12 + opt.mem, pre, post, st);
4962
+ };
4963
+ function deflateSync(data, opts) {
4964
+ return dopt(data, opts || {}, 0, 0);
4965
+ }
4966
+ function inflateSync(data, opts) {
4967
+ return inflt(data, { i: 2 }, opts && opts.out, opts && opts.dictionary);
4968
+ }
4969
+ var td = typeof TextDecoder != "undefined" && /* @__PURE__ */ new TextDecoder();
4970
+ var tds = 0;
4971
+ try {
4972
+ td.decode(et, { stream: true });
4973
+ tds = 1;
4974
+ } catch (e) {
4975
+ }
4976
+
4270
4977
  // src/capabilities/verbs.ts
4271
4978
  var CAPABILITY_VERBS = [
4272
4979
  "read-stream",
@@ -4277,7 +4984,8 @@ var CAPABILITY_VERBS = [
4277
4984
  "answer-permission-prompt",
4278
4985
  "interactive-terminal",
4279
4986
  "board-tool-read",
4280
- "board-tool-write"
4987
+ "board-tool-write",
4988
+ "register-push"
4281
4989
  ];
4282
4990
  function isCapabilityVerb(value) {
4283
4991
  return CAPABILITY_VERBS.includes(value);
@@ -4308,18 +5016,53 @@ function isRecord(value) {
4308
5016
 
4309
5017
  // src/wire/framing.ts
4310
5018
  var MAX_FRAME_LENGTH = 1024 * 1024;
5019
+ var MAX_DECODED_LENGTH = 4 * 1024 * 1024;
5020
+ var COMPRESSION_THRESHOLD = 4 * 1024;
5021
+ var FRAME_FORMAT_DEFLATE = 1;
5022
+ var JSON_OPEN_BRACE = 123;
5023
+ var DEFLATE_HEADER_LENGTH = 5;
4311
5024
  function encodeMessage(message) {
4312
- const bytes = new TextEncoder().encode(JSON.stringify(message));
4313
- if (bytes.length > MAX_FRAME_LENGTH) {
5025
+ const json = new TextEncoder().encode(JSON.stringify(message));
5026
+ if (json.length > MAX_DECODED_LENGTH) {
5027
+ throw new Error(`Encoded bridge message exceeds ${MAX_DECODED_LENGTH} bytes before compression`);
5028
+ }
5029
+ let frame = json;
5030
+ if (json.length > COMPRESSION_THRESHOLD) {
5031
+ const compressed = deflateSync(json);
5032
+ if (compressed.length + DEFLATE_HEADER_LENGTH < json.length) {
5033
+ frame = new Uint8Array(DEFLATE_HEADER_LENGTH + compressed.length);
5034
+ frame[0] = FRAME_FORMAT_DEFLATE;
5035
+ new DataView(frame.buffer).setUint32(1, json.length, true);
5036
+ frame.set(compressed, DEFLATE_HEADER_LENGTH);
5037
+ }
5038
+ }
5039
+ if (frame.length > MAX_FRAME_LENGTH) {
4314
5040
  throw new Error(`Encoded bridge message exceeds ${MAX_FRAME_LENGTH} bytes`);
4315
5041
  }
4316
- return bytes;
5042
+ return frame;
4317
5043
  }
4318
5044
  function decodeMessage(bytes) {
4319
5045
  if (bytes.length > MAX_FRAME_LENGTH) {
4320
5046
  throw new Error(`Bridge message frame exceeds ${MAX_FRAME_LENGTH} bytes`);
4321
5047
  }
4322
- const parsed = JSON.parse(new TextDecoder().decode(bytes));
5048
+ if (bytes.length === 0) throw new Error("Bridge message frame is empty");
5049
+ let json;
5050
+ if (bytes[0] === JSON_OPEN_BRACE) {
5051
+ json = bytes;
5052
+ } else if (bytes[0] === FRAME_FORMAT_DEFLATE) {
5053
+ if (bytes.length < DEFLATE_HEADER_LENGTH + 1) throw new Error("Compressed bridge message frame is truncated");
5054
+ const declaredLength = new DataView(bytes.buffer, bytes.byteOffset).getUint32(1, true);
5055
+ if (declaredLength === 0 || declaredLength > MAX_DECODED_LENGTH) {
5056
+ throw new Error(`Compressed bridge message declares an invalid decoded length: ${declaredLength}`);
5057
+ }
5058
+ json = inflateSync(bytes.subarray(DEFLATE_HEADER_LENGTH), { out: new Uint8Array(declaredLength) });
5059
+ if (json.length !== declaredLength) {
5060
+ throw new Error("Compressed bridge message decoded length does not match its declaration");
5061
+ }
5062
+ } else {
5063
+ throw new Error(`Unknown bridge message frame format: 0x${bytes[0].toString(16)}`);
5064
+ }
5065
+ const parsed = JSON.parse(new TextDecoder().decode(json));
4323
5066
  return validateBridgeMessage(parsed);
4324
5067
  }
4325
5068
  function validateEvent(event) {
@@ -4328,7 +5071,8 @@ function validateEvent(event) {
4328
5071
  switch (event.kind) {
4329
5072
  case "transcript":
4330
5073
  case "activity":
4331
- case "terminal": {
5074
+ case "terminal":
5075
+ case "terminal-resize": {
4332
5076
  if (typeof event.sessionId !== "string") throw new Error(`"${event.kind}" event is missing "sessionId"`);
4333
5077
  if (typeof event.taskId !== "string") throw new Error(`"${event.kind}" event is missing "taskId"`);
4334
5078
  return event;
@@ -4401,6 +5145,47 @@ function unwrapSessionFrame(frame) {
4401
5145
  return { kind, payload: frame.subarray(1) };
4402
5146
  }
4403
5147
 
5148
+ // src/wire/base64url.ts
5149
+ var ALPHABET = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_";
5150
+ var DECODE_MAP = {};
5151
+ for (let i = 0; i < ALPHABET.length; i++) DECODE_MAP[ALPHABET[i]] = i;
5152
+ function base64UrlEncode(bytes) {
5153
+ let result = "";
5154
+ let i = 0;
5155
+ for (; i + 2 < bytes.length; i += 3) {
5156
+ const chunk = bytes[i] << 16 | bytes[i + 1] << 8 | bytes[i + 2];
5157
+ result += ALPHABET[chunk >> 18 & 63] + ALPHABET[chunk >> 12 & 63] + ALPHABET[chunk >> 6 & 63] + ALPHABET[chunk & 63];
5158
+ }
5159
+ const remaining = bytes.length - i;
5160
+ if (remaining === 1) {
5161
+ const chunk = bytes[i] << 16;
5162
+ result += ALPHABET[chunk >> 18 & 63] + ALPHABET[chunk >> 12 & 63];
5163
+ } else if (remaining === 2) {
5164
+ const chunk = bytes[i] << 16 | bytes[i + 1] << 8;
5165
+ result += ALPHABET[chunk >> 18 & 63] + ALPHABET[chunk >> 12 & 63] + ALPHABET[chunk >> 6 & 63];
5166
+ }
5167
+ return result;
5168
+ }
5169
+ function base64UrlDecode(encoded) {
5170
+ const byteLength = Math.floor(encoded.length * 6 / 8);
5171
+ const bytes = new Uint8Array(byteLength);
5172
+ let bitBuffer = 0;
5173
+ let bitCount = 0;
5174
+ let outputIndex = 0;
5175
+ for (const char of encoded) {
5176
+ const value = DECODE_MAP[char];
5177
+ if (value === void 0) throw new Error(`Invalid base64url character: "${char}"`);
5178
+ bitBuffer = bitBuffer << 6 | value;
5179
+ bitCount += 6;
5180
+ if (bitCount >= 8) {
5181
+ bitCount -= 8;
5182
+ bytes[outputIndex] = bitBuffer >> bitCount & 255;
5183
+ outputIndex += 1;
5184
+ }
5185
+ }
5186
+ return bytes;
5187
+ }
5188
+
4404
5189
  // src/events/payloads.ts
4405
5190
  var DIFF_FILE_STATUSES = ["A", "M", "D", "R", "C", "U"];
4406
5191
  var TRANSCRIPT_SYSTEM_SUBTYPES = ["compaction", "command", "command_output", "session_boundary"];
@@ -4448,6 +5233,32 @@ function parseTranscriptEntriesWire(payload) {
4448
5233
  return entry;
4449
5234
  });
4450
5235
  }
5236
+ function parseTranscriptEventPayload(payload) {
5237
+ if (!isRecord(payload)) throw new Error("transcript payload must be an object");
5238
+ const revision = requireNumber(payload, "revision", "transcript payload");
5239
+ const totalEntries = requireNumber(payload, "totalEntries", "transcript payload");
5240
+ if (!Number.isInteger(revision) || revision < 0) throw new Error('transcript payload has an invalid "revision"');
5241
+ if (!Number.isInteger(totalEntries) || totalEntries < 0) throw new Error('transcript payload has an invalid "totalEntries"');
5242
+ if (payload.mode === "reset") return { mode: "reset", revision, totalEntries };
5243
+ if (payload.mode !== "delta") throw new Error('transcript payload has an invalid "mode"');
5244
+ if (!Array.isArray(payload.upserts)) throw new Error('transcript delta is missing "upserts"');
5245
+ const upserts = payload.upserts.map((upsert, position) => {
5246
+ if (!isRecord(upsert) || typeof upsert.index !== "number" || !Number.isInteger(upsert.index) || upsert.index < 0) {
5247
+ throw new Error(`transcript delta upsert ${position} has an invalid "index"`);
5248
+ }
5249
+ if (!isTranscriptEntryWire(upsert.entry)) throw new Error(`transcript delta upsert ${position} has a malformed "entry"`);
5250
+ return { index: upsert.index, entry: upsert.entry };
5251
+ });
5252
+ return { mode: "delta", revision, totalEntries, upserts };
5253
+ }
5254
+ function parseTerminalDimensionsWire(payload) {
5255
+ if (!isRecord(payload)) throw new Error("terminal dimensions must be an object");
5256
+ const cols = requireNumber(payload, "cols", "terminal dimensions");
5257
+ const rows = requireNumber(payload, "rows", "terminal dimensions");
5258
+ if (!Number.isInteger(cols) || cols < 2 || cols > 1e3) throw new Error('terminal dimensions have an invalid "cols"');
5259
+ if (!Number.isInteger(rows) || rows < 1 || rows > 1e3) throw new Error('terminal dimensions have an invalid "rows"');
5260
+ return { cols, rows };
5261
+ }
4451
5262
  function isActivityStateWire(value) {
4452
5263
  return value === "thinking" || value === "idle" || value === "permission";
4453
5264
  }
@@ -4608,6 +5419,7 @@ function parseDiffFileContentWire(payload) {
4608
5419
  }
4609
5420
 
4610
5421
  // src/wire/payloads.ts
5422
+ var READ_STREAM_SESSION_STATUSES = ["running", "queued", "suspended", "exited"];
4611
5423
  function parseReadStreamResponsePayload(payload) {
4612
5424
  if (!isRecord(payload)) throw new Error("read-stream response must be an object");
4613
5425
  if (typeof payload.scrollback !== "string") throw new Error('read-stream response is missing "scrollback"');
@@ -4619,20 +5431,69 @@ function parseReadStreamResponsePayload(payload) {
4619
5431
  if (payload.awaitedPromptId !== null && typeof payload.awaitedPromptId !== "string") {
4620
5432
  throw new Error('read-stream response has an invalid "awaitedPromptId"');
4621
5433
  }
4622
- return {
5434
+ const response = {
4623
5435
  scrollback: payload.scrollback,
4624
5436
  activity: { state: state ?? null, reason: reason ?? null },
4625
5437
  usage: payload.usage === null || payload.usage === void 0 ? null : parseSessionUsageWire(payload.usage),
4626
5438
  awaitedPromptId: payload.awaitedPromptId ?? null
4627
5439
  };
5440
+ if (payload.ptyDimensions !== void 0) {
5441
+ response.ptyDimensions = parseTerminalDimensionsWire(payload.ptyDimensions);
5442
+ }
5443
+ if (payload.sessionStatus !== void 0) {
5444
+ if (typeof payload.sessionStatus !== "string" || !READ_STREAM_SESSION_STATUSES.includes(payload.sessionStatus)) {
5445
+ throw new Error('read-stream response has an invalid "sessionStatus"');
5446
+ }
5447
+ response.sessionStatus = payload.sessionStatus;
5448
+ }
5449
+ return response;
5450
+ }
5451
+ function parseTranscriptWindowResponsePayload(payload) {
5452
+ if (!isRecord(payload)) throw new Error("transcript-window response must be an object");
5453
+ const { revision, totalEntries, startIndex } = payload;
5454
+ if (typeof revision !== "number" || !Number.isInteger(revision) || revision < 0) {
5455
+ throw new Error('transcript-window response has an invalid "revision"');
5456
+ }
5457
+ if (typeof totalEntries !== "number" || !Number.isInteger(totalEntries) || totalEntries < 0) {
5458
+ throw new Error('transcript-window response has an invalid "totalEntries"');
5459
+ }
5460
+ if (typeof startIndex !== "number" || !Number.isInteger(startIndex) || startIndex < 0) {
5461
+ throw new Error('transcript-window response has an invalid "startIndex"');
5462
+ }
5463
+ return {
5464
+ revision,
5465
+ totalEntries,
5466
+ startIndex,
5467
+ entries: parseTranscriptEntriesWire(payload.entries)
5468
+ };
4628
5469
  }
4629
5470
  function parseReadStreamRequestPayload(payload) {
4630
5471
  if (!isRecord(payload)) throw new Error("read-stream payload must be an object");
4631
5472
  if (typeof payload.sessionId !== "string") throw new Error('read-stream payload missing "sessionId"');
4632
- if (payload.action !== "subscribe" && payload.action !== "unsubscribe") {
5473
+ if (payload.action !== "subscribe" && payload.action !== "unsubscribe" && payload.action !== "transcript-window") {
4633
5474
  throw new Error('read-stream payload has an invalid "action"');
4634
5475
  }
4635
- return { sessionId: payload.sessionId, action: payload.action };
5476
+ const request = { sessionId: payload.sessionId, action: payload.action };
5477
+ if (payload.beforeIndex !== void 0) {
5478
+ if (typeof payload.beforeIndex !== "number" || !Number.isInteger(payload.beforeIndex) || payload.beforeIndex < 0) {
5479
+ throw new Error('read-stream payload has an invalid "beforeIndex"');
5480
+ }
5481
+ request.beforeIndex = payload.beforeIndex;
5482
+ }
5483
+ if (payload.limit !== void 0) {
5484
+ if (typeof payload.limit !== "number" || !Number.isInteger(payload.limit) || payload.limit < 1) {
5485
+ throw new Error('read-stream payload has an invalid "limit"');
5486
+ }
5487
+ request.limit = payload.limit;
5488
+ }
5489
+ return request;
5490
+ }
5491
+ var ACCENT_COLOR_PATTERN = /^#[0-9a-fA-F]{6}$/;
5492
+ function parseAccentColor(value, context) {
5493
+ if (typeof value !== "string" || !ACCENT_COLOR_PATTERN.test(value)) {
5494
+ throw new Error(`${context} has an invalid accent color (expected "#rrggbb")`);
5495
+ }
5496
+ return value;
4636
5497
  }
4637
5498
  function parseReadBoardResponsePayload(payload) {
4638
5499
  if (!isRecord(payload)) throw new Error("read-board response must be an object");
@@ -4641,7 +5502,11 @@ function parseReadBoardResponsePayload(payload) {
4641
5502
  if (!isRecord(project) || typeof project.id !== "string" || typeof project.name !== "string") {
4642
5503
  throw new Error(`read-board project ${index} is malformed`);
4643
5504
  }
4644
- return { id: project.id, name: project.name };
5505
+ return {
5506
+ id: project.id,
5507
+ name: project.name,
5508
+ ...project.color !== void 0 ? { color: parseAccentColor(project.color, `read-board project ${index}`) } : {}
5509
+ };
4645
5510
  });
4646
5511
  return { projects };
4647
5512
  }
@@ -4653,7 +5518,8 @@ function parseReadBoardResponsePayload(payload) {
4653
5518
  projectId: payload.projectId,
4654
5519
  columns: payload.columns.map((column) => parseBoardColumnWire(column)),
4655
5520
  tasks: payload.tasks.map((task) => parseBoardTaskWire(task)),
4656
- backlog: payload.backlog.map((item) => parseBacklogItemWire(item))
5521
+ backlog: payload.backlog.map((item) => parseBacklogItemWire(item)),
5522
+ ...payload.projectColor !== void 0 ? { projectColor: parseAccentColor(payload.projectColor, "read-board snapshot") } : {}
4657
5523
  };
4658
5524
  }
4659
5525
  function parseReadBoardRequestPayload(payload) {
@@ -4720,8 +5586,21 @@ function parseAnswerPermissionPromptRequestPayload(payload) {
4720
5586
  function parseInteractiveTerminalRequestPayload(payload) {
4721
5587
  if (!isRecord(payload)) throw new Error("interactive-terminal payload must be an object");
4722
5588
  if (typeof payload.sessionId !== "string") throw new Error('interactive-terminal payload missing "sessionId"');
4723
- if (typeof payload.data !== "string") throw new Error('interactive-terminal payload missing "data"');
4724
- return { sessionId: payload.sessionId, data: payload.data };
5589
+ if (payload.action === void 0 || payload.action === "write") {
5590
+ if (typeof payload.data !== "string") throw new Error('interactive-terminal payload missing "data"');
5591
+ return { sessionId: payload.sessionId, action: "write", data: payload.data };
5592
+ }
5593
+ if (payload.action === "resize") {
5594
+ return {
5595
+ sessionId: payload.sessionId,
5596
+ action: "resize",
5597
+ dimensions: parseTerminalDimensionsWire(payload.dimensions)
5598
+ };
5599
+ }
5600
+ if (payload.action === "release-size") {
5601
+ return { sessionId: payload.sessionId, action: "release-size" };
5602
+ }
5603
+ throw new Error('interactive-terminal payload has an invalid "action"');
4725
5604
  }
4726
5605
  function parseBoardToolRequestPayload(payload) {
4727
5606
  if (!isRecord(payload)) throw new Error("board-tool payload must be an object");
@@ -4729,6 +5608,42 @@ function parseBoardToolRequestPayload(payload) {
4729
5608
  if (payload.params === void 0 || !isJsonValue(payload.params)) throw new Error('board-tool payload missing a JSON "params"');
4730
5609
  return { tool: payload.tool, params: payload.params };
4731
5610
  }
5611
+ var PUSH_KEY_LENGTH = 32;
5612
+ function parseRegisterPushRequestPayload(payload) {
5613
+ if (!isRecord(payload)) throw new Error("register-push payload must be an object");
5614
+ if (payload.action !== "register" && payload.action !== "unregister") {
5615
+ throw new Error('register-push payload has an invalid "action"');
5616
+ }
5617
+ const request = { action: payload.action };
5618
+ if (payload.expoPushToken !== void 0) {
5619
+ if (typeof payload.expoPushToken !== "string") throw new Error('register-push payload has a non-string "expoPushToken"');
5620
+ request.expoPushToken = payload.expoPushToken;
5621
+ }
5622
+ if (payload.pushKeyBase64 !== void 0) {
5623
+ if (typeof payload.pushKeyBase64 !== "string") throw new Error('register-push payload has a non-string "pushKeyBase64"');
5624
+ let decodedKey;
5625
+ try {
5626
+ decodedKey = base64UrlDecode(payload.pushKeyBase64);
5627
+ } catch {
5628
+ throw new Error('register-push payload has a malformed "pushKeyBase64"');
5629
+ }
5630
+ if (decodedKey.length !== PUSH_KEY_LENGTH) {
5631
+ throw new Error(`register-push payload "pushKeyBase64" must decode to ${PUSH_KEY_LENGTH} bytes`);
5632
+ }
5633
+ request.pushKeyBase64 = payload.pushKeyBase64;
5634
+ }
5635
+ if (payload.platform !== void 0) {
5636
+ if (payload.platform !== "android" && payload.platform !== "ios") {
5637
+ throw new Error('register-push payload has an invalid "platform"');
5638
+ }
5639
+ request.platform = payload.platform;
5640
+ }
5641
+ if (request.action === "register") {
5642
+ if (request.expoPushToken === void 0) throw new Error('register-push register payload missing "expoPushToken"');
5643
+ if (request.pushKeyBase64 === void 0) throw new Error('register-push register payload missing "pushKeyBase64"');
5644
+ }
5645
+ return request;
5646
+ }
4732
5647
  function parseCapabilityRequestPayload(verb, payload) {
4733
5648
  switch (verb) {
4734
5649
  case "read-stream":
@@ -4748,6 +5663,8 @@ function parseCapabilityRequestPayload(verb, payload) {
4748
5663
  case "board-tool-read":
4749
5664
  case "board-tool-write":
4750
5665
  return parseBoardToolRequestPayload(payload);
5666
+ case "register-push":
5667
+ return parseRegisterPushRequestPayload(payload);
4751
5668
  default: {
4752
5669
  const exhaustiveCheck = verb;
4753
5670
  throw new Error(`Unknown capability verb: ${String(exhaustiveCheck)}`);
@@ -4755,45 +5672,54 @@ function parseCapabilityRequestPayload(verb, payload) {
4755
5672
  }
4756
5673
  }
4757
5674
 
4758
- // src/wire/base64url.ts
4759
- var ALPHABET = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_";
4760
- var DECODE_MAP = {};
4761
- for (let i = 0; i < ALPHABET.length; i++) DECODE_MAP[ALPHABET[i]] = i;
4762
- function base64UrlEncode(bytes) {
4763
- let result = "";
4764
- let i = 0;
4765
- for (; i + 2 < bytes.length; i += 3) {
4766
- const chunk = bytes[i] << 16 | bytes[i + 1] << 8 | bytes[i + 2];
4767
- result += ALPHABET[chunk >> 18 & 63] + ALPHABET[chunk >> 12 & 63] + ALPHABET[chunk >> 6 & 63] + ALPHABET[chunk & 63];
4768
- }
4769
- const remaining = bytes.length - i;
4770
- if (remaining === 1) {
4771
- const chunk = bytes[i] << 16;
4772
- result += ALPHABET[chunk >> 18 & 63] + ALPHABET[chunk >> 12 & 63];
4773
- } else if (remaining === 2) {
4774
- const chunk = bytes[i] << 16 | bytes[i + 1] << 8;
4775
- result += ALPHABET[chunk >> 18 & 63] + ALPHABET[chunk >> 12 & 63] + ALPHABET[chunk >> 6 & 63];
4776
- }
4777
- return result;
5675
+ // src/crypto/push-envelope.ts
5676
+ var PUSH_CATEGORIES = ["permission-needed", "agent-question", "turn-complete", "session-failed"];
5677
+ function isPushCategory(value) {
5678
+ return typeof value === "string" && PUSH_CATEGORIES.includes(value);
5679
+ }
5680
+ var PUSH_ENVELOPE_MAX_AGE_MS = 24 * 60 * 60 * 1e3;
5681
+ var PUSH_ENVELOPE_MAX_FUTURE_SKEW_MS = 5 * 60 * 1e3;
5682
+ function requireEnvelopeString(record, field) {
5683
+ const value = record[field];
5684
+ if (typeof value !== "string") throw new Error(`push envelope plaintext is missing a string "${field}"`);
5685
+ return value;
4778
5686
  }
4779
- function base64UrlDecode(encoded) {
4780
- const byteLength = Math.floor(encoded.length * 6 / 8);
4781
- const bytes = new Uint8Array(byteLength);
4782
- let bitBuffer = 0;
4783
- let bitCount = 0;
4784
- let outputIndex = 0;
4785
- for (const char of encoded) {
4786
- const value = DECODE_MAP[char];
4787
- if (value === void 0) throw new Error(`Invalid base64url character: "${char}"`);
4788
- bitBuffer = bitBuffer << 6 | value;
4789
- bitCount += 6;
4790
- if (bitCount >= 8) {
4791
- bitCount -= 8;
4792
- bytes[outputIndex] = bitBuffer >> bitCount & 255;
4793
- outputIndex += 1;
4794
- }
5687
+ function parsePushEnvelopePlaintext(value) {
5688
+ if (!isRecord(value)) throw new Error("push envelope plaintext must be an object");
5689
+ if (!isPushCategory(value.category)) throw new Error('push envelope plaintext has an unknown "category"');
5690
+ if (typeof value.sentAt !== "number" || !Number.isFinite(value.sentAt)) {
5691
+ throw new Error('push envelope plaintext has an invalid "sentAt"');
4795
5692
  }
4796
- return bytes;
5693
+ return {
5694
+ category: value.category,
5695
+ projectId: requireEnvelopeString(value, "projectId"),
5696
+ taskId: requireEnvelopeString(value, "taskId"),
5697
+ sessionId: requireEnvelopeString(value, "sessionId"),
5698
+ taskTitle: requireEnvelopeString(value, "taskTitle"),
5699
+ detail: requireEnvelopeString(value, "detail"),
5700
+ sentAt: value.sentAt
5701
+ };
5702
+ }
5703
+ function sealPushEnvelope(pushKey, recipientStaticPublicKey, plaintext) {
5704
+ const nonce = randomBytes4(XCHACHA_NONCE_LENGTH);
5705
+ const encodedPlaintext = new TextEncoder().encode(JSON.stringify(plaintext));
5706
+ const ciphertext = xaeadEncrypt(pushKey, nonce, recipientStaticPublicKey, encodedPlaintext);
5707
+ return base64UrlEncode(concatBytes4(nonce, ciphertext));
5708
+ }
5709
+ function openPushEnvelope(pushKey, recipientStaticPublicKey, blob) {
5710
+ const bytes = base64UrlDecode(blob);
5711
+ if (bytes.length < XCHACHA_NONCE_LENGTH + AEAD_TAG_LENGTH) {
5712
+ throw new Error("push envelope blob is too short");
5713
+ }
5714
+ const nonce = bytes.subarray(0, XCHACHA_NONCE_LENGTH);
5715
+ const ciphertext = bytes.subarray(XCHACHA_NONCE_LENGTH);
5716
+ const decrypted = xaeadDecrypt(pushKey, nonce, recipientStaticPublicKey, ciphertext);
5717
+ const decoded = JSON.parse(new TextDecoder().decode(decrypted));
5718
+ const plaintext = parsePushEnvelopePlaintext(decoded);
5719
+ const now = Date.now();
5720
+ if (plaintext.sentAt < now - PUSH_ENVELOPE_MAX_AGE_MS) throw new Error("push envelope is stale");
5721
+ if (plaintext.sentAt > now + PUSH_ENVELOPE_MAX_FUTURE_SKEW_MS) throw new Error("push envelope sentAt is in the future");
5722
+ return plaintext;
4797
5723
  }
4798
5724
 
4799
5725
  // src/pairing/qr.ts
@@ -4971,6 +5897,10 @@ function parseActivityEventPayload(payload) {
4971
5897
  if (typeof payload.pending !== "boolean") throw new Error('permission payload is missing "pending"');
4972
5898
  return { type: "permission", promptId: payload.promptId, pending: payload.pending };
4973
5899
  }
5900
+ case "session-ended": {
5901
+ if (typeof payload.intentional !== "boolean") throw new Error('session-ended payload is missing "intentional"');
5902
+ return { type: "session-ended", intentional: payload.intentional };
5903
+ }
4974
5904
  default:
4975
5905
  throw new Error('activity payload has an unknown "type"');
4976
5906
  }
@@ -4981,7 +5911,7 @@ function isBridgeEvent(value) {
4981
5911
  case "transcript": {
4982
5912
  if (typeof value.sessionId !== "string" || typeof value.taskId !== "string") return false;
4983
5913
  try {
4984
- parseTranscriptEntriesWire(value.payload);
5914
+ parseTranscriptEventPayload(value.payload);
4985
5915
  return true;
4986
5916
  } catch {
4987
5917
  return false;
@@ -5000,6 +5930,15 @@ function isBridgeEvent(value) {
5000
5930
  if (typeof value.sessionId !== "string" || typeof value.taskId !== "string") return false;
5001
5931
  return isRecord(value.payload) && typeof value.payload.data === "string";
5002
5932
  }
5933
+ case "terminal-resize": {
5934
+ if (typeof value.sessionId !== "string" || typeof value.taskId !== "string") return false;
5935
+ try {
5936
+ parseTerminalDimensionsWire(value.payload);
5937
+ return true;
5938
+ } catch {
5939
+ return false;
5940
+ }
5941
+ }
5003
5942
  case "board": {
5004
5943
  if (typeof value.projectId !== "string") return false;
5005
5944
  if (value.taskId !== void 0 && typeof value.taskId !== "string") return false;
@@ -5019,15 +5958,20 @@ function isBridgeEvent(value) {
5019
5958
  BOARD_TOOL_READ_NAMES,
5020
5959
  BOARD_TOOL_WRITE_NAMES,
5021
5960
  CAPABILITY_VERBS,
5961
+ COMPRESSION_THRESHOLD,
5022
5962
  CipherState,
5023
5963
  ED25519_KEY_LENGTH,
5024
5964
  FrameTag,
5025
5965
  HandshakeState,
5026
5966
  IKPSK0_PATTERN,
5027
5967
  KK_PATTERN,
5968
+ MAX_DECODED_LENGTH,
5028
5969
  MAX_FRAME_LENGTH,
5029
5970
  PAIRING_URI_SCHEME,
5030
5971
  PROTOCOL_VERSION,
5972
+ PUSH_CATEGORIES,
5973
+ PUSH_ENVELOPE_MAX_AGE_MS,
5974
+ PUSH_ENVELOPE_MAX_FUTURE_SKEW_MS,
5031
5975
  SecretstreamState,
5032
5976
  SessionFrameKind,
5033
5977
  X25519_KEY_LENGTH,
@@ -5058,8 +6002,10 @@ function isBridgeEvent(value) {
5058
6002
  isBridgeEvent,
5059
6003
  isCapabilityVerb,
5060
6004
  isJsonValue,
6005
+ isPushCategory,
5061
6006
  isRecord,
5062
6007
  isRosterEntryExpired,
6008
+ openPushEnvelope,
5063
6009
  parseActivityEventPayload,
5064
6010
  parseBacklogItemWire,
5065
6011
  parseBoardColumnWire,
@@ -5067,14 +6013,20 @@ function isBridgeEvent(value) {
5067
6013
  parseCapabilityRequestPayload,
5068
6014
  parseDiffFileContentWire,
5069
6015
  parseDiffFileListWire,
6016
+ parsePushEnvelopePlaintext,
5070
6017
  parseReadBoardResponsePayload,
5071
6018
  parseReadDiffResponsePayload,
5072
6019
  parseReadStreamResponsePayload,
6020
+ parseRegisterPushRequestPayload,
5073
6021
  parseSessionEventWire,
5074
6022
  parseSessionUsageWire,
6023
+ parseTerminalDimensionsWire,
5075
6024
  parseTranscriptEntriesWire,
6025
+ parseTranscriptEventPayload,
6026
+ parseTranscriptWindowResponsePayload,
5076
6027
  randomBytes,
5077
6028
  rosterDeviceCapabilitySet,
6029
+ sealPushEnvelope,
5078
6030
  signRosterEntry,
5079
6031
  unwrapSessionFrame,
5080
6032
  verifyRosterEntry,