@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/api/handlers/sessions.handlers.d.ts +2 -0
- package/dist/api/handlers/sessions.handlers.d.ts.map +1 -1
- package/dist/cli.cjs +83 -74
- package/dist/cli.cjs.map +1 -1
- package/dist/codex-pty-runner.d.ts.map +1 -1
- package/dist/index.cjs +76 -67
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +60 -51
- package/dist/index.js.map +1 -1
- package/dist/pty-manager.d.ts.map +1 -1
- package/dist/pty-shared.d.ts +0 -1
- package/dist/pty-shared.d.ts.map +1 -1
- package/dist/server-wiring.d.ts +2 -0
- package/dist/server-wiring.d.ts.map +1 -1
- package/dist/server.d.ts.map +1 -1
- package/dist/types.d.ts +8 -0
- package/dist/types.d.ts.map +1 -1
- package/package.json +1 -1
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
|
-
|
|
1489
|
-
|
|
1490
|
-
|
|
1491
|
-
|
|
1492
|
-
|
|
1493
|
-
|
|
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
|
-
|
|
1535
|
-
|
|
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}
|
|
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)}
|
|
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
|
-
|
|
3083
|
-
|
|
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}
|
|
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}
|
|
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
|
-
|
|
3432
|
-
|
|
3433
|
-
|
|
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
|
|
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.
|
|
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
|
-
|
|
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
|
|
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 =
|
|
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 =
|
|
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.
|