@threadbase-sh/streamer 1.36.0 → 1.36.1
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 +66 -18
- package/dist/cli.cjs.map +1 -1
- package/dist/index.cjs +66 -18
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +11 -1
- package/dist/index.d.ts +11 -1
- package/dist/index.js +66 -18
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.cjs
CHANGED
|
@@ -1449,9 +1449,13 @@ var import_fs6 = require("fs");
|
|
|
1449
1449
|
var import_path6 = require("path");
|
|
1450
1450
|
|
|
1451
1451
|
// src/services/questions/detectPermissionGate.ts
|
|
1452
|
-
var
|
|
1452
|
+
var OSC_777_PERMISSION_RE = /\x1b\]777;notify;Claude Code;[^\x07\x1b]*needs your permission/;
|
|
1453
|
+
var OSC_777_WAITING_RE = /\x1b\]777;notify;Claude Code;[^\x07\x1b]*waiting for your input/;
|
|
1453
1454
|
function hasPermissionOsc(rawData) {
|
|
1454
|
-
return
|
|
1455
|
+
return OSC_777_PERMISSION_RE.test(rawData);
|
|
1456
|
+
}
|
|
1457
|
+
function hasWaitingForInputOsc(rawData) {
|
|
1458
|
+
return OSC_777_WAITING_RE.test(rawData);
|
|
1455
1459
|
}
|
|
1456
1460
|
var OPTION_RE = /^\s*(❯)?\s*(\d+)\.\s+(.+?)\s*$/;
|
|
1457
1461
|
var FOOTER_RE = /Enter to select|Esc to cancel|↑|↓|to navigate|to cancel/i;
|
|
@@ -1602,22 +1606,29 @@ function detectShellPrompt(lines) {
|
|
|
1602
1606
|
};
|
|
1603
1607
|
}
|
|
1604
1608
|
const lastNumberedIdx = (() => {
|
|
1605
|
-
|
|
1606
|
-
|
|
1609
|
+
let i = last.idx;
|
|
1610
|
+
if (!NUMBERED_RE.test(lines[i])) {
|
|
1611
|
+
if (i > 0 && (PRESS_ENTER_RE.test(lines[i].trim()) || CONTINUE_RE.test(lines[i].trim()))) {
|
|
1612
|
+
i--;
|
|
1613
|
+
} else {
|
|
1614
|
+
return -1;
|
|
1615
|
+
}
|
|
1607
1616
|
}
|
|
1608
|
-
|
|
1617
|
+
while (i >= 0 && !NUMBERED_RE.test(lines[i]) && lines[i].trim().length === 0) i--;
|
|
1618
|
+
return i >= 0 && NUMBERED_RE.test(lines[i]) ? i : -1;
|
|
1609
1619
|
})();
|
|
1610
1620
|
if (lastNumberedIdx >= 0) {
|
|
1611
1621
|
const options = [];
|
|
1612
|
-
|
|
1622
|
+
let firstRow = lastNumberedIdx;
|
|
1623
|
+
for (let i = lastNumberedIdx; i >= 0; i--) {
|
|
1613
1624
|
const m = NUMBERED_RE.exec(lines[i]);
|
|
1614
|
-
if (!m)
|
|
1625
|
+
if (!m) break;
|
|
1615
1626
|
const num = Number.parseInt(m[1], 10);
|
|
1616
|
-
if (!Number.isFinite(num))
|
|
1617
|
-
options.
|
|
1627
|
+
if (!Number.isFinite(num)) break;
|
|
1628
|
+
options.unshift({ index: num, label: m[2].trim(), answerKeys: `${num}${ENTER}` });
|
|
1629
|
+
firstRow = i;
|
|
1618
1630
|
}
|
|
1619
1631
|
if (options.length >= 2) {
|
|
1620
|
-
const firstRow = lines.findIndex((l) => NUMBERED_RE.test(l));
|
|
1621
1632
|
let prompt = "";
|
|
1622
1633
|
for (let i = firstRow - 1; i >= 0; i--) {
|
|
1623
1634
|
const t = lines[i].trim();
|
|
@@ -2186,12 +2197,13 @@ var PTYManager = class {
|
|
|
2186
2197
|
const session = this.sessions.get(sessionId);
|
|
2187
2198
|
if (!session) return;
|
|
2188
2199
|
const oscPermission = hasPermissionOsc(rawData);
|
|
2200
|
+
const oscWaitingForInput = hasWaitingForInputOsc(rawData);
|
|
2189
2201
|
const hasAskFooter = /Enter to select/i.test(stripped);
|
|
2190
2202
|
const hasPromptMarker = CLAUDE_PROMPT_MARKERS.some((m) => stripped.includes(m));
|
|
2191
2203
|
const hasShellPromptHint = /[[(]\s*y\s*\/\s*n\s*[\])]|press\s+(enter|return|any key)|\bcontinue\b\s*\?|^\s*(?:❯|>)?\s*\d+[.)]\s+\S/im.test(
|
|
2192
2204
|
stripped
|
|
2193
2205
|
);
|
|
2194
|
-
if (!oscPermission && !hasAskFooter && !hasShellPromptHint && !this.permissionOpen.has(sessionId) && !this.shellPromptOpen.has(sessionId) && !this.lastScreenQuestionKey.has(sessionId)) {
|
|
2206
|
+
if (!oscPermission && !oscWaitingForInput && !hasAskFooter && !hasShellPromptHint && !this.permissionOpen.has(sessionId) && !this.shellPromptOpen.has(sessionId) && !this.lastScreenQuestionKey.has(sessionId)) {
|
|
2195
2207
|
return;
|
|
2196
2208
|
}
|
|
2197
2209
|
const lines = await this.getOutputLines(sessionId, 60);
|
|
@@ -2214,11 +2226,11 @@ var PTYManager = class {
|
|
|
2214
2226
|
this.onPermissionChange?.(sessionId, gate ?? { options: [] });
|
|
2215
2227
|
} else if (this.permissionOpen.has(sessionId) && !askFooterOnScreen) {
|
|
2216
2228
|
const gate = scrapePermissionGate(lines);
|
|
2217
|
-
if (gate) {
|
|
2218
|
-
this.onPermissionChange?.(sessionId, gate);
|
|
2219
|
-
} else if (hasPromptMarker) {
|
|
2229
|
+
if (oscWaitingForInput || !gate && hasPromptMarker) {
|
|
2220
2230
|
this.permissionOpen.delete(sessionId);
|
|
2221
2231
|
this.onPermissionChange?.(sessionId, null);
|
|
2232
|
+
} else if (gate) {
|
|
2233
|
+
this.onPermissionChange?.(sessionId, gate);
|
|
2222
2234
|
}
|
|
2223
2235
|
}
|
|
2224
2236
|
if (askFooterOnScreen) {
|
|
@@ -3630,8 +3642,8 @@ var createSessionRoutes = (deps) => {
|
|
|
3630
3642
|
await deps.handleStopSession(c.req.param("id"), c.env.outgoing);
|
|
3631
3643
|
return alreadyHandled6();
|
|
3632
3644
|
});
|
|
3633
|
-
app.get("/:id", (c) => {
|
|
3634
|
-
deps.handleGetSession(c.req.param("id"), c.env.outgoing);
|
|
3645
|
+
app.get("/:id", async (c) => {
|
|
3646
|
+
await deps.handleGetSession(c.req.param("id"), c.env.outgoing);
|
|
3635
3647
|
return alreadyHandled6();
|
|
3636
3648
|
});
|
|
3637
3649
|
return app;
|
|
@@ -5995,6 +6007,32 @@ function deriveProjectChatTitle(input) {
|
|
|
5995
6007
|
return `Untitled \xB7 ${input.id.slice(0, 8)}`;
|
|
5996
6008
|
}
|
|
5997
6009
|
|
|
6010
|
+
// src/services/questions/parseStatusLine.ts
|
|
6011
|
+
var MODEL_RE = /(Opus|Sonnet|Haiku|Fable)\s+[\d.]+(?:\s*\([^)]*\))?/;
|
|
6012
|
+
var EFFORT_RE = /●\s*([A-Za-z]+)\s*·\s*\/effort/;
|
|
6013
|
+
var PERMISSION_MODE_RE = /⏵⏵\s*([^(·\n]+?)\s*(?:\(|·|$)/;
|
|
6014
|
+
function parseStatusLine(lines) {
|
|
6015
|
+
const info = {};
|
|
6016
|
+
for (let i = lines.length - 1; i >= 0; i--) {
|
|
6017
|
+
const line = lines[i];
|
|
6018
|
+
if (!line) continue;
|
|
6019
|
+
if (info.effort === void 0) {
|
|
6020
|
+
const m = EFFORT_RE.exec(line);
|
|
6021
|
+
if (m) info.effort = m[1];
|
|
6022
|
+
}
|
|
6023
|
+
if (info.permissionMode === void 0) {
|
|
6024
|
+
const m = PERMISSION_MODE_RE.exec(line);
|
|
6025
|
+
if (m) info.permissionMode = m[1].trim();
|
|
6026
|
+
}
|
|
6027
|
+
if (info.model === void 0) {
|
|
6028
|
+
const m = MODEL_RE.exec(line);
|
|
6029
|
+
if (m) info.model = m[0].replace(/\s+/g, " ").trim();
|
|
6030
|
+
}
|
|
6031
|
+
if (info.model && info.effort && info.permissionMode) break;
|
|
6032
|
+
}
|
|
6033
|
+
return info;
|
|
6034
|
+
}
|
|
6035
|
+
|
|
5998
6036
|
// src/services/questions/detectAskUserQuestion.ts
|
|
5999
6037
|
function normalizeContent2(raw) {
|
|
6000
6038
|
if (Array.isArray(raw)) return raw;
|
|
@@ -7151,7 +7189,7 @@ var StreamerServer = class {
|
|
|
7151
7189
|
}
|
|
7152
7190
|
}
|
|
7153
7191
|
if (msg.type === "hold_session" && typeof msg.sessionId === "string") {
|
|
7154
|
-
this.startGraceTimer(msg.sessionId,
|
|
7192
|
+
this.startGraceTimer(msg.sessionId, this.ptyGracePeriodMs);
|
|
7155
7193
|
}
|
|
7156
7194
|
} catch {
|
|
7157
7195
|
}
|
|
@@ -8666,13 +8704,23 @@ var StreamerServer = class {
|
|
|
8666
8704
|
throw err;
|
|
8667
8705
|
}
|
|
8668
8706
|
}
|
|
8669
|
-
handleGetSession(sessionId, res) {
|
|
8707
|
+
async handleGetSession(sessionId, res) {
|
|
8670
8708
|
if (this.rejectIfWarmingUp(res)) return;
|
|
8671
8709
|
const session = this.sessionStore.get(sessionId, this.ptyAttachedIds());
|
|
8672
8710
|
if (session) {
|
|
8673
8711
|
if (!(0, import_fs17.existsSync)(session.projectPath)) {
|
|
8674
8712
|
session.failureReason = `Project directory not found: ${session.projectPath}`;
|
|
8675
8713
|
}
|
|
8714
|
+
if (this.ptyManager.hasSession(sessionId)) {
|
|
8715
|
+
try {
|
|
8716
|
+
const lines = await this.ptyManager.getOutputLines(sessionId, 10);
|
|
8717
|
+
const status = parseStatusLine(lines);
|
|
8718
|
+
if (session.model == null && status.model) session.model = status.model;
|
|
8719
|
+
if (status.effort) session.effort = status.effort;
|
|
8720
|
+
if (status.permissionMode) session.permissionMode = status.permissionMode;
|
|
8721
|
+
} catch {
|
|
8722
|
+
}
|
|
8723
|
+
}
|
|
8676
8724
|
json(res, 200, session);
|
|
8677
8725
|
return;
|
|
8678
8726
|
}
|