@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 CHANGED
@@ -138354,8 +138354,8 @@ var createSessionRoutes = (deps) => {
138354
138354
  await deps.handleStopSession(c.req.param("id"), c.env.outgoing);
138355
138355
  return alreadyHandled6();
138356
138356
  });
138357
- app.get("/:id", (c) => {
138358
- deps.handleGetSession(c.req.param("id"), c.env.outgoing);
138357
+ app.get("/:id", async (c) => {
138358
+ await deps.handleGetSession(c.req.param("id"), c.env.outgoing);
138359
138359
  return alreadyHandled6();
138360
138360
  });
138361
138361
  return app;
@@ -141048,9 +141048,13 @@ var import_path22 = require("path");
141048
141048
  init_logger();
141049
141049
 
141050
141050
  // src/services/questions/detectPermissionGate.ts
141051
- var OSC_777_RE = /\x1b\]777;notify;Claude Code;[^\x07\x1b]*/;
141051
+ var OSC_777_PERMISSION_RE = /\x1b\]777;notify;Claude Code;[^\x07\x1b]*needs your permission/;
141052
+ var OSC_777_WAITING_RE = /\x1b\]777;notify;Claude Code;[^\x07\x1b]*waiting for your input/;
141052
141053
  function hasPermissionOsc(rawData) {
141053
- return OSC_777_RE.test(rawData);
141054
+ return OSC_777_PERMISSION_RE.test(rawData);
141055
+ }
141056
+ function hasWaitingForInputOsc(rawData) {
141057
+ return OSC_777_WAITING_RE.test(rawData);
141054
141058
  }
141055
141059
  var OPTION_RE = /^\s*(❯)?\s*(\d+)\.\s+(.+?)\s*$/;
141056
141060
  var FOOTER_RE = /Enter to select|Esc to cancel|↑|↓|to navigate|to cancel/i;
@@ -141201,22 +141205,29 @@ function detectShellPrompt(lines) {
141201
141205
  };
141202
141206
  }
141203
141207
  const lastNumberedIdx = (() => {
141204
- for (let i = last.idx; i >= 0; i--) {
141205
- if (NUMBERED_RE.test(lines[i])) return i;
141208
+ let i = last.idx;
141209
+ if (!NUMBERED_RE.test(lines[i])) {
141210
+ if (i > 0 && (PRESS_ENTER_RE.test(lines[i].trim()) || CONTINUE_RE.test(lines[i].trim()))) {
141211
+ i--;
141212
+ } else {
141213
+ return -1;
141214
+ }
141206
141215
  }
141207
- return -1;
141216
+ while (i >= 0 && !NUMBERED_RE.test(lines[i]) && lines[i].trim().length === 0) i--;
141217
+ return i >= 0 && NUMBERED_RE.test(lines[i]) ? i : -1;
141208
141218
  })();
141209
141219
  if (lastNumberedIdx >= 0) {
141210
141220
  const options = [];
141211
- for (let i = 0; i <= lastNumberedIdx; i++) {
141221
+ let firstRow = lastNumberedIdx;
141222
+ for (let i = lastNumberedIdx; i >= 0; i--) {
141212
141223
  const m2 = NUMBERED_RE.exec(lines[i]);
141213
- if (!m2) continue;
141224
+ if (!m2) break;
141214
141225
  const num = Number.parseInt(m2[1], 10);
141215
- if (!Number.isFinite(num)) continue;
141216
- options.push({ index: num, label: m2[2].trim(), answerKeys: `${num}${ENTER}` });
141226
+ if (!Number.isFinite(num)) break;
141227
+ options.unshift({ index: num, label: m2[2].trim(), answerKeys: `${num}${ENTER}` });
141228
+ firstRow = i;
141217
141229
  }
141218
141230
  if (options.length >= 2) {
141219
- const firstRow = lines.findIndex((l) => NUMBERED_RE.test(l));
141220
141231
  let prompt = "";
141221
141232
  for (let i = firstRow - 1; i >= 0; i--) {
141222
141233
  const t = lines[i].trim();
@@ -141785,12 +141796,13 @@ var PTYManager = class {
141785
141796
  const session = this.sessions.get(sessionId);
141786
141797
  if (!session) return;
141787
141798
  const oscPermission = hasPermissionOsc(rawData);
141799
+ const oscWaitingForInput = hasWaitingForInputOsc(rawData);
141788
141800
  const hasAskFooter = /Enter to select/i.test(stripped);
141789
141801
  const hasPromptMarker = CLAUDE_PROMPT_MARKERS.some((m2) => stripped.includes(m2));
141790
141802
  const hasShellPromptHint = /[[(]\s*y\s*\/\s*n\s*[\])]|press\s+(enter|return|any key)|\bcontinue\b\s*\?|^\s*(?:❯|>)?\s*\d+[.)]\s+\S/im.test(
141791
141803
  stripped
141792
141804
  );
141793
- if (!oscPermission && !hasAskFooter && !hasShellPromptHint && !this.permissionOpen.has(sessionId) && !this.shellPromptOpen.has(sessionId) && !this.lastScreenQuestionKey.has(sessionId)) {
141805
+ if (!oscPermission && !oscWaitingForInput && !hasAskFooter && !hasShellPromptHint && !this.permissionOpen.has(sessionId) && !this.shellPromptOpen.has(sessionId) && !this.lastScreenQuestionKey.has(sessionId)) {
141794
141806
  return;
141795
141807
  }
141796
141808
  const lines = await this.getOutputLines(sessionId, 60);
@@ -141813,11 +141825,11 @@ var PTYManager = class {
141813
141825
  this.onPermissionChange?.(sessionId, gate ?? { options: [] });
141814
141826
  } else if (this.permissionOpen.has(sessionId) && !askFooterOnScreen) {
141815
141827
  const gate = scrapePermissionGate(lines);
141816
- if (gate) {
141817
- this.onPermissionChange?.(sessionId, gate);
141818
- } else if (hasPromptMarker) {
141828
+ if (oscWaitingForInput || !gate && hasPromptMarker) {
141819
141829
  this.permissionOpen.delete(sessionId);
141820
141830
  this.onPermissionChange?.(sessionId, null);
141831
+ } else if (gate) {
141832
+ this.onPermissionChange?.(sessionId, gate);
141821
141833
  }
141822
141834
  }
141823
141835
  if (askFooterOnScreen) {
@@ -142935,6 +142947,32 @@ function deriveProjectChatTitle(input) {
142935
142947
  return `Untitled \xB7 ${input.id.slice(0, 8)}`;
142936
142948
  }
142937
142949
 
142950
+ // src/services/questions/parseStatusLine.ts
142951
+ var MODEL_RE = /(Opus|Sonnet|Haiku|Fable)\s+[\d.]+(?:\s*\([^)]*\))?/;
142952
+ var EFFORT_RE = /●\s*([A-Za-z]+)\s*·\s*\/effort/;
142953
+ var PERMISSION_MODE_RE = /⏵⏵\s*([^(·\n]+?)\s*(?:\(|·|$)/;
142954
+ function parseStatusLine(lines) {
142955
+ const info = {};
142956
+ for (let i = lines.length - 1; i >= 0; i--) {
142957
+ const line = lines[i];
142958
+ if (!line) continue;
142959
+ if (info.effort === void 0) {
142960
+ const m2 = EFFORT_RE.exec(line);
142961
+ if (m2) info.effort = m2[1];
142962
+ }
142963
+ if (info.permissionMode === void 0) {
142964
+ const m2 = PERMISSION_MODE_RE.exec(line);
142965
+ if (m2) info.permissionMode = m2[1].trim();
142966
+ }
142967
+ if (info.model === void 0) {
142968
+ const m2 = MODEL_RE.exec(line);
142969
+ if (m2) info.model = m2[0].replace(/\s+/g, " ").trim();
142970
+ }
142971
+ if (info.model && info.effort && info.permissionMode) break;
142972
+ }
142973
+ return info;
142974
+ }
142975
+
142938
142976
  // src/services/questions/detectAskUserQuestion.ts
142939
142977
  function normalizeContent2(raw2) {
142940
142978
  if (Array.isArray(raw2)) return raw2;
@@ -144329,7 +144367,7 @@ var StreamerServer = class {
144329
144367
  }
144330
144368
  }
144331
144369
  if (msg.type === "hold_session" && typeof msg.sessionId === "string") {
144332
- this.startGraceTimer(msg.sessionId, 0);
144370
+ this.startGraceTimer(msg.sessionId, this.ptyGracePeriodMs);
144333
144371
  }
144334
144372
  } catch {
144335
144373
  }
@@ -145844,13 +145882,23 @@ var StreamerServer = class {
145844
145882
  throw err;
145845
145883
  }
145846
145884
  }
145847
- handleGetSession(sessionId, res) {
145885
+ async handleGetSession(sessionId, res) {
145848
145886
  if (this.rejectIfWarmingUp(res)) return;
145849
145887
  const session = this.sessionStore.get(sessionId, this.ptyAttachedIds());
145850
145888
  if (session) {
145851
145889
  if (!(0, import_fs28.existsSync)(session.projectPath)) {
145852
145890
  session.failureReason = `Project directory not found: ${session.projectPath}`;
145853
145891
  }
145892
+ if (this.ptyManager.hasSession(sessionId)) {
145893
+ try {
145894
+ const lines = await this.ptyManager.getOutputLines(sessionId, 10);
145895
+ const status = parseStatusLine(lines);
145896
+ if (session.model == null && status.model) session.model = status.model;
145897
+ if (status.effort) session.effort = status.effort;
145898
+ if (status.permissionMode) session.permissionMode = status.permissionMode;
145899
+ } catch {
145900
+ }
145901
+ }
145854
145902
  json2(res, 200, session);
145855
145903
  return;
145856
145904
  }