@threadbase-sh/streamer 1.69.2 → 1.69.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -1046,11 +1046,6 @@ var PTY_COLS = 120;
1046
1046
  var PTY_ROWS = 40;
1047
1047
  var SCREEN_SCROLLBACK = 1e3;
1048
1048
  var REPLAY_MAX_LINES = SCREEN_SCROLLBACK + PTY_ROWS;
1049
- function digestBytes(s) {
1050
- const escaped = s.replace(new RegExp(String.fromCharCode(27), "g"), "\\x1b").replace(/\r/g, "\\r").replace(/\n/g, "\\n").replace(/\t/g, "\\t");
1051
- if (escaped.length <= 200) return escaped;
1052
- return `${escaped.slice(0, 100)}\u2026[${escaped.length - 200}B omitted]\u2026${escaped.slice(-100)}`;
1053
- }
1054
1049
  var pty = null;
1055
1050
  async function loadPty() {
1056
1051
  if (pty) return pty;
@@ -1485,17 +1480,12 @@ var CodexPtyRunner = class {
1485
1480
  const lines = await this.getOutputLines(sessionId, PTY_ROWS);
1486
1481
  if (!this.pendingReady.has(sessionId)) return;
1487
1482
  const busy = codexScreenBlocksComposer(lines);
1488
- const bar = codexStatusBarLine(lines);
1489
- this.log.info(
1490
- `[codex.ready_fallback] ${sessionId.slice(0, 8)} busy=${busy} bar=${JSON.stringify(bar.slice(0, 120))}`,
1491
- {
1492
- event: "codex.ready_fallback",
1493
- sessionId,
1494
- busy,
1495
- hasReady: codexScreenShowsReady(lines),
1496
- statusBar: bar.slice(0, 160)
1497
- }
1498
- );
1483
+ this.log.info(`[codex.ready_fallback] ${sessionId.slice(0, 8)} busy=${busy}`, {
1484
+ event: "codex.ready_fallback",
1485
+ sessionId,
1486
+ busy,
1487
+ hasReady: codexScreenShowsReady(lines)
1488
+ });
1499
1489
  if (busy) {
1500
1490
  this.armReadyFallback(sessionId);
1501
1491
  return;
@@ -1530,10 +1520,11 @@ var CodexPtyRunner = class {
1530
1520
  const gate = this.openGate.get(sessionId);
1531
1521
  const digit = gate ? /^([0-9])\r?$/.exec(keys)?.[1] : void 0;
1532
1522
  const out = gate && digit ? this.resolveGateAnswer(sessionId, gate, digit) : keys;
1533
- this.log.info(
1534
- `[codex.keys.write] ${sessionId.slice(0, 8)} bytes=${out.length} digest=${digestBytes(out)}`,
1535
- { event: "codex.keys_write", sessionId, byteLen: out.length }
1536
- );
1523
+ this.log.info(`[codex.keys.write] ${sessionId.slice(0, 8)} bytes=${out.length}`, {
1524
+ event: "codex.keys_write",
1525
+ sessionId,
1526
+ byteLen: out.length
1527
+ });
1537
1528
  session.process.write(out);
1538
1529
  session.lastActivityAt = /* @__PURE__ */ new Date();
1539
1530
  }
@@ -1612,13 +1603,12 @@ var CodexPtyRunner = class {
1612
1603
  writeSubmit(sessionId, session, input, path, promptCount) {
1613
1604
  this.recordUserMessage(session, input);
1614
1605
  this.log.info(
1615
- `[codex.input.write] ${sessionId.slice(0, 8)} promptCount=${promptCount} bytes=${input.length} digest=${digestBytes(input)}`,
1606
+ `[codex.input.write] ${sessionId.slice(0, 8)} promptCount=${promptCount} bytes=${input.length}`,
1616
1607
  {
1617
1608
  event: "codex.input_write",
1618
1609
  sessionId,
1619
1610
  promptCount,
1620
1611
  byteLen: input.length,
1621
- digest: digestBytes(input),
1622
1612
  path,
1623
1613
  phase: "input"
1624
1614
  }
@@ -1682,8 +1672,7 @@ var CodexPtyRunner = class {
1682
1672
  }
1683
1673
  this.log.info(`[codex.submit_stale] ${sessionId.slice(0, 8)} recovering`, {
1684
1674
  event: "codex.submit_stale",
1685
- sessionId,
1686
- statusBar: codexStatusBarLine(lines).slice(0, 160)
1675
+ sessionId
1687
1676
  });
1688
1677
  this.markReady(sessionId, session, "quiet-fallback", "submit-stale");
1689
1678
  } catch (err) {
@@ -1966,7 +1955,7 @@ var CodexPtyRunner = class {
1966
1955
  if (this.lastScreenLog.get(sessionId) !== screenFp) {
1967
1956
  this.lastScreenLog.set(sessionId, screenFp);
1968
1957
  this.log.info(
1969
- `[codex.screen] ${sessionId.slice(0, 8)} pending=${this.pendingReady.has(sessionId)} status=${session.status} ready=${hasReady} busy=${busy} usage=${Boolean(blocking)} bar=${JSON.stringify(bar.slice(0, 100))}`,
1958
+ `[codex.screen] ${sessionId.slice(0, 8)} pending=${this.pendingReady.has(sessionId)} status=${session.status} ready=${hasReady} busy=${busy} usage=${Boolean(blocking)}`,
1970
1959
  {
1971
1960
  event: "codex.screen",
1972
1961
  sessionId,
@@ -1976,8 +1965,7 @@ var CodexPtyRunner = class {
1976
1965
  hasReady,
1977
1966
  busy,
1978
1967
  usageHit: Boolean(blocking),
1979
- usageSoft: Boolean(blocking?.soft),
1980
- statusBar: bar.slice(0, 160)
1968
+ usageSoft: Boolean(blocking?.soft)
1981
1969
  }
1982
1970
  );
1983
1971
  }
@@ -2012,8 +2000,7 @@ var CodexPtyRunner = class {
2012
2000
  session.failureReason = blocking.detail ? `${blocking.prompt} ${blocking.detail}` : blocking.prompt;
2013
2001
  this.log.info(`[codex.usage_limit] ${sessionId.slice(0, 8)}`, {
2014
2002
  event: "codex.usage_limit",
2015
- sessionId,
2016
- prompt: blocking.prompt
2003
+ sessionId
2017
2004
  });
2018
2005
  this.onPermissionChange?.(sessionId, blocking);
2019
2006
  }
@@ -2059,8 +2046,7 @@ var CodexPtyRunner = class {
2059
2046
  this.log.info(`[codex.gate_prompt] ${sessionId.slice(0, 8)} ${gate}`, {
2060
2047
  event: "codex.gate_prompt",
2061
2048
  sessionId,
2062
- gate,
2063
- prompt: card.prompt
2049
+ gate
2064
2050
  });
2065
2051
  this.onPermissionChange?.(sessionId, card);
2066
2052
  }
@@ -3078,10 +3064,11 @@ var PTYManager = class {
3078
3064
  session.statusUpdatedAt = /* @__PURE__ */ new Date();
3079
3065
  this.onStatusChange?.(toPublicSession2(session));
3080
3066
  }
3081
- this.log.info(
3082
- `[pty.keys.write] ${sessionId.slice(0, 8)} bytes=${keys.length} digest=${digestBytes(keys)}`,
3083
- { event: "pty.keys_write", sessionId, byteLen: keys.length }
3084
- );
3067
+ this.log.info(`[pty.keys.write] ${sessionId.slice(0, 8)} bytes=${keys.length}`, {
3068
+ event: "pty.keys_write",
3069
+ sessionId,
3070
+ byteLen: keys.length
3071
+ });
3085
3072
  session.process.write(keys);
3086
3073
  session.lastActivityAt = /* @__PURE__ */ new Date();
3087
3074
  const openGate = this.permissionOpen.get(sessionId);
@@ -3143,13 +3130,12 @@ var PTYManager = class {
3143
3130
  this.recordUserMessage(session, input);
3144
3131
  const pasteBytes = buildPasteBytes(input);
3145
3132
  this.log.info(
3146
- `[pty.input.write] ${sessionId.slice(0, 8)} promptCount=${promptCount} bytes=${pasteBytes.length} digest=${digestBytes(pasteBytes)}`,
3133
+ `[pty.input.write] ${sessionId.slice(0, 8)} promptCount=${promptCount} bytes=${pasteBytes.length}`,
3147
3134
  {
3148
3135
  event: "pty.input_write",
3149
3136
  sessionId,
3150
3137
  promptCount,
3151
3138
  byteLen: pasteBytes.length,
3152
- digest: digestBytes(pasteBytes),
3153
3139
  path,
3154
3140
  phase: "paste"
3155
3141
  }
@@ -3349,7 +3335,7 @@ var PTYManager = class {
3349
3335
  this.lastChunkAt.set(sessionId, now);
3350
3336
  const gapMs = last == null ? 0 : now - last;
3351
3337
  this.log.info(
3352
- `[pty.chunk] ${sessionId.slice(0, 8)} #${idx} +${chunk.length}B gap=${gapMs}ms status=${session.status} digest=${digestBytes(data)}`,
3338
+ `[pty.chunk] ${sessionId.slice(0, 8)} #${idx} +${chunk.length}B gap=${gapMs}ms status=${session.status}`,
3353
3339
  {
3354
3340
  event: "pty.chunk",
3355
3341
  sessionId,
@@ -3357,8 +3343,7 @@ var PTYManager = class {
3357
3343
  chunkBytes: chunk.length,
3358
3344
  gapMs,
3359
3345
  status: session.status,
3360
- pendingReady: this.pendingReady.has(sessionId),
3361
- digest: digestBytes(data)
3346
+ pendingReady: this.pendingReady.has(sessionId)
3362
3347
  }
3363
3348
  );
3364
3349
  session.outputBuffer = Buffer.concat([session.outputBuffer, chunk]);
@@ -3422,15 +3407,18 @@ var PTYManager = class {
3422
3407
  }
3423
3408
  const askFooterOnScreen = lines.some((l) => /Enter to select/i.test(l));
3424
3409
  if (oscPermission || hasAskFooter || askFooterOnScreen) {
3410
+ const permGate = oscPermission && !askFooterOnScreen ? scrapePermissionGate(lines) : null;
3411
+ const askQuestion = askFooterOnScreen ? detectQuestionFromScreen(lines) : null;
3425
3412
  this.log.debug?.(`[pty.prompt_detect] ${sessionId.slice(0, 8)} trigger`, {
3426
3413
  event: "pty.prompt_detect",
3427
3414
  sessionId,
3428
3415
  oscPermission,
3429
3416
  hasAskFooter,
3430
3417
  askFooterOnScreen,
3431
- permGate: oscPermission && !askFooterOnScreen ? scrapePermissionGate(lines) : void 0,
3432
- askQuestion: askFooterOnScreen ? detectQuestionFromScreen(lines) : void 0,
3433
- renderedTail: lines.slice(-25)
3418
+ permGateDetected: permGate !== null,
3419
+ permGateOptionCount: permGate?.options.length ?? 0,
3420
+ askQuestionDetected: askQuestion !== null,
3421
+ askQuestionCount: askQuestion?.questions.length ?? 0
3434
3422
  });
3435
3423
  }
3436
3424
  if (oscPermission && !askFooterOnScreen) {
@@ -4101,7 +4089,7 @@ async function readGitBranch(dir) {
4101
4089
  // src/server.ts
4102
4090
  import { createNodeWebSocket } from "@hono/node-ws";
4103
4091
  import { Connection, Client as TemporalClient } from "@temporalio/client";
4104
- import { randomUUID as randomUUID5 } from "crypto";
4092
+ import { randomUUID as randomUUID6 } from "crypto";
4105
4093
  import { EventEmitter } from "events";
4106
4094
  import { existsSync as existsSync16 } from "fs";
4107
4095
  import { realpath as realpath2 } from "fs/promises";
@@ -9223,6 +9211,7 @@ var ConversationHandlers = class {
9223
9211
  };
9224
9212
 
9225
9213
  // src/api/handlers/sessions.handlers.ts
9214
+ import { randomUUID as randomUUID4 } from "crypto";
9226
9215
  import { existsSync as existsSync10 } from "fs";
9227
9216
  import { basename as basename6, dirname as dirname9, join as join16 } from "path";
9228
9217
 
@@ -10518,7 +10507,9 @@ var SessionHandlers = class {
10518
10507
  }
10519
10508
  const key = permissionContentKey(gate);
10520
10509
  if (this.pendingPermissionKey.get(sessionId) === key) return;
10521
- this.pendingPermission.set(sessionId, gate);
10510
+ const prior = this.pendingPermission.get(sessionId);
10511
+ const gateId = prior && permissionGateKey(prior) === permissionGateKey(gate) ? prior.gateId : randomUUID4();
10512
+ this.pendingPermission.set(sessionId, { ...gate, gateId });
10522
10513
  this.pendingPermissionKey.set(sessionId, key);
10523
10514
  const subscriberCount = this.sessionSubscribers.get(sessionId)?.size ?? 0;
10524
10515
  this.log.info(
@@ -10532,7 +10523,8 @@ var SessionHandlers = class {
10532
10523
  ...gate.detail ? { detail: gate.detail } : {},
10533
10524
  options: gate.options,
10534
10525
  ...gate.cursor !== void 0 ? { cursor: gate.cursor } : {},
10535
- contentKey: permissionGateKey(gate)
10526
+ contentKey: permissionGateKey(gate),
10527
+ gateId
10536
10528
  });
10537
10529
  }
10538
10530
  /**
@@ -10560,10 +10552,15 @@ var SessionHandlers = class {
10560
10552
  const body = await readBody2(req);
10561
10553
  const contentKey = body?.contentKey;
10562
10554
  const optionIndex = body?.optionIndex;
10555
+ const gateId = body?.gateId;
10563
10556
  if (typeof contentKey !== "string" || !Number.isInteger(optionIndex) || optionIndex < 0) {
10564
10557
  json(res, 400, { ok: false, reason: "Expected { contentKey: string, optionIndex: number }" });
10565
10558
  return;
10566
10559
  }
10560
+ if (gateId !== void 0 && typeof gateId !== "string") {
10561
+ json(res, 400, { ok: false, reason: "Expected gateId to be a string" });
10562
+ return;
10563
+ }
10567
10564
  const gateClosed = () => {
10568
10565
  this.pendingPermission.delete(sessionId);
10569
10566
  this.pendingPermissionKey.delete(sessionId);
@@ -10575,6 +10572,16 @@ var SessionHandlers = class {
10575
10572
  gateClosed();
10576
10573
  return;
10577
10574
  }
10575
+ if (gateId !== void 0 && gateId !== gate.gateId) {
10576
+ json(res, 409, { ok: false, reason: "gate_mismatch" });
10577
+ return;
10578
+ }
10579
+ if (gateId === void 0) {
10580
+ this.log.info(`[permission.answer_legacy_identity] ${sessionId.slice(0, 8)}`, {
10581
+ event: "permission.answer_legacy_identity",
10582
+ sessionId
10583
+ });
10584
+ }
10578
10585
  if (permissionGateKey(gate) !== contentKey) {
10579
10586
  json(res, 409, { ok: false, reason: "gate_mismatch" });
10580
10587
  return;
@@ -10584,7 +10591,8 @@ var SessionHandlers = class {
10584
10591
  json(res, 409, { ok: false, reason: "unknown_option" });
10585
10592
  return;
10586
10593
  }
10587
- if (!await this.permissionGateStillOpen(sessionId, contentKey)) {
10594
+ const provider = this.sessionStore.getManaged(sessionId)?.provider;
10595
+ if (provider !== CODEX_CLI_PROVIDER && !await this.permissionGateStillOpen(sessionId, contentKey)) {
10588
10596
  gateClosed();
10589
10597
  return;
10590
10598
  }
@@ -11292,7 +11300,7 @@ var ManagedSessionsRepository = class {
11292
11300
  };
11293
11301
 
11294
11302
  // src/db/repositories/projects.repository.ts
11295
- import { randomUUID as randomUUID4 } from "crypto";
11303
+ import { randomUUID as randomUUID5 } from "crypto";
11296
11304
  function rowToProject(row) {
11297
11305
  return {
11298
11306
  id: row.id,
@@ -11377,7 +11385,7 @@ var ProjectsRepository = class {
11377
11385
  });
11378
11386
  return rowToProject(this.getById.get(existing.id));
11379
11387
  }
11380
- const id = randomUUID4();
11388
+ const id = randomUUID5();
11381
11389
  this.insert.run({
11382
11390
  id,
11383
11391
  path,
@@ -13154,7 +13162,8 @@ function createApiDeps(deps) {
13154
13162
  ...pendingGate.detail ? { detail: pendingGate.detail } : {},
13155
13163
  options: pendingGate.options,
13156
13164
  ...pendingGate.cursor !== void 0 ? { cursor: pendingGate.cursor } : {},
13157
- contentKey: permissionGateKey(pendingGate)
13165
+ contentKey: permissionGateKey(pendingGate),
13166
+ gateId: pendingGate.gateId
13158
13167
  })
13159
13168
  );
13160
13169
  }
@@ -16012,7 +16021,7 @@ var StreamerServer = class {
16012
16021
  runtimeStore = null;
16013
16022
  // Identifies this streamer run. A registry row carrying a different id is a
16014
16023
  // session that outlived the process that started it.
16015
- streamerInstanceId = randomUUID5();
16024
+ streamerInstanceId = randomUUID6();
16016
16025
  cacheMetadataRepo = null;
16017
16026
  // Push registration + delivery state (C7). Null when the cache DB failed to
16018
16027
  // open — registration then degrades to a no-op rather than 500ing.