@threadbase-sh/streamer 1.55.2 → 1.55.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/cli.cjs +70 -5
- package/dist/cli.cjs.map +1 -1
- package/dist/index.cjs +67 -3
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +67 -3
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/cli.cjs
CHANGED
|
@@ -108227,7 +108227,7 @@ function createScreen() {
|
|
|
108227
108227
|
function stripAnsi(str) {
|
|
108228
108228
|
return str.replace(/\x1b\[[0-9;]*[a-zA-Z]/g, "").replace(/\x1b\][^\x07]*\x07/g, "");
|
|
108229
108229
|
}
|
|
108230
|
-
var import_headless, PTY_COLS, PTY_ROWS, SCREEN_SCROLLBACK, pty;
|
|
108230
|
+
var import_headless, PTY_COLS, PTY_ROWS, SCREEN_SCROLLBACK, REPLAY_MAX_LINES, pty;
|
|
108231
108231
|
var init_pty_shared = __esm({
|
|
108232
108232
|
"src/pty-shared.ts"() {
|
|
108233
108233
|
"use strict";
|
|
@@ -108235,11 +108235,38 @@ var init_pty_shared = __esm({
|
|
|
108235
108235
|
PTY_COLS = 120;
|
|
108236
108236
|
PTY_ROWS = 40;
|
|
108237
108237
|
SCREEN_SCROLLBACK = 1e3;
|
|
108238
|
+
REPLAY_MAX_LINES = SCREEN_SCROLLBACK + PTY_ROWS;
|
|
108238
108239
|
pty = null;
|
|
108239
108240
|
}
|
|
108240
108241
|
});
|
|
108241
108242
|
|
|
108242
108243
|
// src/services/questions/codexScreen.ts
|
|
108244
|
+
function detectCodexCommandApproval(lines) {
|
|
108245
|
+
let heading = -1;
|
|
108246
|
+
for (let i = 0; i < lines.length; i++) {
|
|
108247
|
+
if (CODEX_COMMAND_APPROVAL_HEADING_RE.test(lines[i])) heading = i;
|
|
108248
|
+
}
|
|
108249
|
+
if (heading < 0) return null;
|
|
108250
|
+
if (lines.some((line) => CODEX_USAGE_LIMIT_RE.test(line) || CODEX_RATE_LIMIT_MENU_RE.test(line))) {
|
|
108251
|
+
return null;
|
|
108252
|
+
}
|
|
108253
|
+
const card = lines.slice(heading);
|
|
108254
|
+
if (!card.some((line) => CODEX_COMMAND_APPROVAL_ENV_RE.test(line)) || !card.some((line) => CODEX_COMMAND_APPROVAL_REASON_RE.test(line)) || !card.some((line) => CODEX_COMMAND_APPROVAL_YES_RE.test(line)) || !card.some((line) => CODEX_COMMAND_APPROVAL_NO_RE.test(line)) || !card.some((line) => CODEX_COMMAND_APPROVAL_CONFIRM_RE.test(line))) {
|
|
108255
|
+
return null;
|
|
108256
|
+
}
|
|
108257
|
+
const detail = card.filter((line) => {
|
|
108258
|
+
const trimmed = line.trim();
|
|
108259
|
+
return trimmed.length > 0 && !CODEX_COMMAND_APPROVAL_HEADING_RE.test(line) && !CODEX_COMMAND_APPROVAL_YES_RE.test(line) && !CODEX_COMMAND_APPROVAL_NO_RE.test(line) && !CODEX_COMMAND_APPROVAL_CONFIRM_RE.test(line);
|
|
108260
|
+
}).join("\n");
|
|
108261
|
+
return {
|
|
108262
|
+
prompt: "Codex requests command approval",
|
|
108263
|
+
...detail ? { detail } : {},
|
|
108264
|
+
options: [
|
|
108265
|
+
{ index: 1, label: "Yes", answerKeys: "y" },
|
|
108266
|
+
{ index: 2, label: "No", answerKeys: "\x1B" }
|
|
108267
|
+
]
|
|
108268
|
+
};
|
|
108269
|
+
}
|
|
108243
108270
|
function parseCodexNumberedOptions(lines) {
|
|
108244
108271
|
const options = [];
|
|
108245
108272
|
for (const line of lines) {
|
|
@@ -108322,7 +108349,7 @@ function gateCard(gate, lines) {
|
|
|
108322
108349
|
]
|
|
108323
108350
|
};
|
|
108324
108351
|
}
|
|
108325
|
-
var CODEX_PROMPT_READY_TEXT, CODEX_BUSY_STATUS_RE, CODEX_WORKING_STATUS_RE, CODEX_MCP_BOOT_RE, CODEX_TRUST_GATE_REGEX, CODEX_HOOKS_GATE_REGEX, CODEX_ACTIVE_WRITER_RE, CODEX_ACTIVE_WRITER_CODE, CODEX_USAGE_LIMIT_RE, CODEX_USAGE_RESET_TIP_RE, CODEX_RATE_LIMIT_MENU_RE;
|
|
108352
|
+
var CODEX_PROMPT_READY_TEXT, CODEX_BUSY_STATUS_RE, CODEX_WORKING_STATUS_RE, CODEX_MCP_BOOT_RE, CODEX_TRUST_GATE_REGEX, CODEX_HOOKS_GATE_REGEX, CODEX_ACTIVE_WRITER_RE, CODEX_ACTIVE_WRITER_CODE, CODEX_USAGE_LIMIT_RE, CODEX_USAGE_RESET_TIP_RE, CODEX_RATE_LIMIT_MENU_RE, CODEX_COMMAND_APPROVAL_HEADING_RE, CODEX_COMMAND_APPROVAL_ENV_RE, CODEX_COMMAND_APPROVAL_REASON_RE, CODEX_COMMAND_APPROVAL_CONFIRM_RE, CODEX_COMMAND_APPROVAL_YES_RE, CODEX_COMMAND_APPROVAL_NO_RE;
|
|
108326
108353
|
var init_codexScreen = __esm({
|
|
108327
108354
|
"src/services/questions/codexScreen.ts"() {
|
|
108328
108355
|
"use strict";
|
|
@@ -108337,6 +108364,12 @@ var init_codexScreen = __esm({
|
|
|
108337
108364
|
CODEX_USAGE_LIMIT_RE = /you(?:'ve| have) hit your usage limit/i;
|
|
108338
108365
|
CODEX_USAGE_RESET_TIP_RE = /usage limit reset available/i;
|
|
108339
108366
|
CODEX_RATE_LIMIT_MENU_RE = /approaching rate limits/i;
|
|
108367
|
+
CODEX_COMMAND_APPROVAL_HEADING_RE = /^\s*E\s*X\s*E\s*C\s*$/i;
|
|
108368
|
+
CODEX_COMMAND_APPROVAL_ENV_RE = /^\s*Environment:\s*.+/i;
|
|
108369
|
+
CODEX_COMMAND_APPROVAL_REASON_RE = /^\s*Reason:\s*.+/i;
|
|
108370
|
+
CODEX_COMMAND_APPROVAL_CONFIRM_RE = /(?:enter|return) to (?:confirm|approve)|press (?:enter|return) to (?:confirm|approve)/i;
|
|
108371
|
+
CODEX_COMMAND_APPROVAL_YES_RE = /^\s*›?\s*\d+\.\s*yes\b/i;
|
|
108372
|
+
CODEX_COMMAND_APPROVAL_NO_RE = /^\s*›?\s*\d+\.\s*no\b/i;
|
|
108340
108373
|
}
|
|
108341
108374
|
});
|
|
108342
108375
|
|
|
@@ -120636,6 +120669,10 @@ var init_codex_pty_runner = __esm({
|
|
|
120636
120669
|
turnBusy = /* @__PURE__ */ new Set();
|
|
120637
120670
|
// Usage-limit / rate-limit menus — content key for deduped permission cards.
|
|
120638
120671
|
openBlockingPrompt = /* @__PURE__ */ new Map();
|
|
120672
|
+
// Command-approval cards are independent of quota cards: both use the
|
|
120673
|
+
// permission transport, but a repaint/removal of one must not suppress the
|
|
120674
|
+
// other detector's state.
|
|
120675
|
+
openCommandApproval = /* @__PURE__ */ new Map();
|
|
120639
120676
|
// Last codex.screen fingerprint per session — only emit when it changes so
|
|
120640
120677
|
// MCP boot redraw storms don't flood the log.
|
|
120641
120678
|
lastScreenLog = /* @__PURE__ */ new Map();
|
|
@@ -120868,7 +120905,7 @@ var init_codex_pty_runner = __esm({
|
|
|
120868
120905
|
if (session.status === "idle") {
|
|
120869
120906
|
throw new Error(`Session is idle (no active PTY): ${sessionId}`);
|
|
120870
120907
|
}
|
|
120871
|
-
if (this.pendingReady.has(sessionId) || this.openGate.has(sessionId)) {
|
|
120908
|
+
if (this.pendingReady.has(sessionId) || this.openGate.has(sessionId) || this.openCommandApproval.has(sessionId)) {
|
|
120872
120909
|
const queue = this.queuedInputs.get(sessionId) ?? [];
|
|
120873
120910
|
queue.push(input);
|
|
120874
120911
|
this.queuedInputs.set(sessionId, queue);
|
|
@@ -120995,7 +121032,9 @@ var init_codex_pty_runner = __esm({
|
|
|
120995
121032
|
// pendingReady (markReady drains it) — the gate-close path re-drives it for
|
|
120996
121033
|
// the ready-with-gate-open case.
|
|
120997
121034
|
flushQueuedInputs(sessionId) {
|
|
120998
|
-
if (this.openGate.has(sessionId) || this.pendingReady.has(sessionId))
|
|
121035
|
+
if (this.openGate.has(sessionId) || this.openCommandApproval.has(sessionId) || this.pendingReady.has(sessionId)) {
|
|
121036
|
+
return;
|
|
121037
|
+
}
|
|
120999
121038
|
const queue = this.queuedInputs.get(sessionId);
|
|
121000
121039
|
if (!queue || queue.length === 0) return;
|
|
121001
121040
|
this.queuedInputs.delete(sessionId);
|
|
@@ -121075,6 +121114,9 @@ var init_codex_pty_runner = __esm({
|
|
|
121075
121114
|
if (this.openBlockingPrompt.delete(sessionId)) {
|
|
121076
121115
|
this.onPermissionChange?.(sessionId, null);
|
|
121077
121116
|
}
|
|
121117
|
+
if (this.openCommandApproval.delete(sessionId)) {
|
|
121118
|
+
this.onPermissionChange?.(sessionId, null);
|
|
121119
|
+
}
|
|
121078
121120
|
this.lastScreenLog.delete(sessionId);
|
|
121079
121121
|
}
|
|
121080
121122
|
getOutput(sessionId) {
|
|
@@ -121154,6 +121196,7 @@ var init_codex_pty_runner = __esm({
|
|
|
121154
121196
|
this.lastChunkAt.clear();
|
|
121155
121197
|
this.turnBusy.clear();
|
|
121156
121198
|
this.openBlockingPrompt.clear();
|
|
121199
|
+
this.openCommandApproval.clear();
|
|
121157
121200
|
this.lastScreenLog.clear();
|
|
121158
121201
|
}
|
|
121159
121202
|
handleOutput(sessionId, data) {
|
|
@@ -121224,6 +121267,13 @@ var init_codex_pty_runner = __esm({
|
|
|
121224
121267
|
this.onPermissionChange?.(sessionId, null);
|
|
121225
121268
|
this.flushQueuedInputs(sessionId);
|
|
121226
121269
|
}
|
|
121270
|
+
const commandApproval = gate ? null : detectCodexCommandApproval(lines);
|
|
121271
|
+
if (commandApproval) {
|
|
121272
|
+
this.handleCommandApproval(sessionId, commandApproval);
|
|
121273
|
+
} else if (this.openCommandApproval.delete(sessionId)) {
|
|
121274
|
+
this.onPermissionChange?.(sessionId, null);
|
|
121275
|
+
this.flushQueuedInputs(sessionId);
|
|
121276
|
+
}
|
|
121227
121277
|
const blocking = detectCodexBlockingPrompt(lines);
|
|
121228
121278
|
if (blocking) {
|
|
121229
121279
|
const elevateSoft = !blocking.soft || session.status === "running" && session.statusSource === "user-input" && !this.turnBusy.has(sessionId) && !this.pendingReady.has(sessionId);
|
|
@@ -121303,6 +121353,20 @@ var init_codex_pty_runner = __esm({
|
|
|
121303
121353
|
this.markReady(sessionId, session, "quiet-fallback", "usage-limit");
|
|
121304
121354
|
}
|
|
121305
121355
|
}
|
|
121356
|
+
// Surface Codex's EXEC card through the existing permission event. The
|
|
121357
|
+
// rendered screen is authoritative: keying it by content suppresses TUI
|
|
121358
|
+
// repaint repeats and the absence path above clears it only after the card
|
|
121359
|
+
// has left the screen.
|
|
121360
|
+
handleCommandApproval(sessionId, approval) {
|
|
121361
|
+
const key = `${approval.detail ?? ""}\0${approval.options.map((o) => o.answerKeys).join(",")}`;
|
|
121362
|
+
if (this.openCommandApproval.get(sessionId) === key) return;
|
|
121363
|
+
this.openCommandApproval.set(sessionId, key);
|
|
121364
|
+
this.log.info(`[codex.command_approval] ${sessionId.slice(0, 8)}`, {
|
|
121365
|
+
event: "codex.command_approval",
|
|
121366
|
+
sessionId
|
|
121367
|
+
});
|
|
121368
|
+
this.onPermissionChange?.(sessionId, approval);
|
|
121369
|
+
}
|
|
121306
121370
|
// Answer a gate from the persisted remember-store, or surface it as a
|
|
121307
121371
|
// question card over the permission transport. Actioned once per session and
|
|
121308
121372
|
// gate type — repaints of the same dialog neither re-write nor re-broadcast.
|
|
@@ -149795,6 +149859,7 @@ function handleListProjects(url2, res) {
|
|
|
149795
149859
|
|
|
149796
149860
|
// src/server-wiring.ts
|
|
149797
149861
|
init_logger();
|
|
149862
|
+
init_pty_shared();
|
|
149798
149863
|
init_capabilities();
|
|
149799
149864
|
function wsAllows(principal, required2) {
|
|
149800
149865
|
return principal === null || hasCapability(principal, required2);
|
|
@@ -150110,7 +150175,7 @@ function createApiDeps(deps) {
|
|
|
150110
150175
|
}
|
|
150111
150176
|
deps.addSessionSubscriber(msg.sessionId, ws2);
|
|
150112
150177
|
if (deps.ptyManager.hasSession(msg.sessionId)) {
|
|
150113
|
-
const lines = await deps.ptyManager.getOutputLines(msg.sessionId,
|
|
150178
|
+
const lines = await deps.ptyManager.getOutputLines(msg.sessionId, REPLAY_MAX_LINES);
|
|
150114
150179
|
const userMessages = deps.ptyManager.getInputHistory(msg.sessionId);
|
|
150115
150180
|
ws2.send(
|
|
150116
150181
|
JSON.stringify({
|