@0xmaxma/claude-gateway 1.3.18 → 1.3.19
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/config.template.json +3 -2
- package/dist/agent/runner.d.ts.map +1 -1
- package/dist/agent/runner.js +2 -1
- package/dist/agent/runner.js.map +1 -1
- package/dist/session/process.d.ts.map +1 -1
- package/dist/session/process.js +2 -3
- package/dist/session/process.js.map +1 -1
- package/dist/shell/claude-pty-shell.js +187 -99
- package/dist/shell/claude-pty-shell.js.map +1 -1
- package/dist/shell/menu-probe.d.ts +77 -0
- package/dist/shell/menu-probe.d.ts.map +1 -0
- package/dist/shell/menu-probe.js +89 -0
- package/dist/shell/menu-probe.js.map +1 -0
- package/dist/shell/screen.d.ts +60 -72
- package/dist/shell/screen.d.ts.map +1 -1
- package/dist/shell/screen.js +149 -153
- package/dist/shell/screen.js.map +1 -1
- package/dist/shell/tailer.d.ts +0 -7
- package/dist/shell/tailer.d.ts.map +1 -1
- package/dist/shell/tailer.js +0 -29
- package/dist/shell/tailer.js.map +1 -1
- package/mcp/tools/telegram/receiver-server.ts +2 -1
- package/package.json +1 -1
package/dist/shell/screen.js
CHANGED
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.ScreenModel = exports.
|
|
3
|
+
exports.ScreenModel = exports.TUI_MENU_OPTION_RE = exports.TUI_SYNTHETIC_MODEL = exports.TUI_REQUEST_TOO_LARGE_DISMISS = exports.TUI_REQUEST_TOO_LARGE = exports.TUI_BYPASS_PERMS = exports.TUI_PROMPT_RE = exports.TUI_BUSY_MARKER = void 0;
|
|
4
4
|
exports.neutralizeTuiTriggers = neutralizeTuiTriggers;
|
|
5
|
+
exports.parseInteractivePrompt = parseInteractivePrompt;
|
|
5
6
|
exports.parseMenuChoice = parseMenuChoice;
|
|
6
7
|
exports.extractChannelContent = extractChannelContent;
|
|
7
8
|
exports.formatMenuPrompt = formatMenuPrompt;
|
|
@@ -88,59 +89,55 @@ function neutralizeTuiTriggers(text) {
|
|
|
88
89
|
.split(exports.TUI_REQUEST_TOO_LARGE).join('Request too large ( max')
|
|
89
90
|
.split(exports.TUI_REQUEST_TOO_LARGE_DISMISS).join('esc to go back');
|
|
90
91
|
}
|
|
91
|
-
/**
|
|
92
|
-
* Interactive select-menu footer markers (e.g. AskUserQuestion). The footer reads
|
|
93
|
-
* "Enter to select · ↑/↓ to navigate · Esc to cancel"; we match on the two stable
|
|
94
|
-
* fragments so spacing/middle-dot variations across TUI versions don't break it.
|
|
95
|
-
*/
|
|
96
|
-
exports.TUI_MENU_FOOTER = ['to navigate', 'to cancel'];
|
|
97
92
|
/** A numbered option row, with an optional leading ❯/> highlight marker. */
|
|
98
93
|
exports.TUI_MENU_OPTION_RE = /^\s*[❯>]?\s*(\d+)\.\s+(.+?)\s*$/;
|
|
99
94
|
/**
|
|
100
|
-
*
|
|
101
|
-
*
|
|
102
|
-
*
|
|
103
|
-
*
|
|
104
|
-
*
|
|
105
|
-
*
|
|
106
|
-
* prompt ever appears, so without this detector the PTY wedges at the Yes/No
|
|
107
|
-
* forever — nobody can answer it from chat and the typing indicator never clears.
|
|
108
|
-
*
|
|
109
|
-
* Matched by the universal question line plus a footer token unique to permission
|
|
110
|
-
* prompts: the select-menu footer carries "↑/↓ to navigate" and the 32MB overlay
|
|
111
|
-
* carries "esc to go back", so "Tab to amend" / "ctrl+e to explain" disambiguate
|
|
112
|
-
* cleanly. The tokens are the fuller phrases (not bare "to amend" / "to explain")
|
|
113
|
-
* so a chat reply that merely contains those words can't satisfy the footer gate.
|
|
114
|
-
* Region-restricted (bottom rows) + multi-marker + a required ❯/> selection caret
|
|
115
|
-
* so quoted prose in scrollback (a numbered list with none of the live-prompt
|
|
116
|
-
* chrome) cannot trip it — the same defense detectDialog() uses, plus more.
|
|
117
|
-
* Detection only ever BRIDGES the choice to a human; it never presses a key on its
|
|
118
|
-
* own (a destructive guard must not be auto-accepted), making it strictly safer
|
|
119
|
-
* than detectDialog.
|
|
95
|
+
* The universal question line Claude Code's tool-permission prompt (e.g. the
|
|
96
|
+
* dangerous-rm circuit breaker that fires even under
|
|
97
|
+
* --dangerously-skip-permissions) always renders. Used only as a cosmetic
|
|
98
|
+
* classifier in readInteractivePrompt() — never a gate: liveness itself is
|
|
99
|
+
* established behaviorally (see Driver.advanceProbe() in claude-pty-shell.ts)
|
|
100
|
+
* before this is ever consulted.
|
|
120
101
|
*/
|
|
121
|
-
|
|
122
|
-
|
|
102
|
+
const PERMISSION_QUESTION = 'Do you want to proceed?';
|
|
103
|
+
/** A live select prompt always highlights one option with a leading ❯ caret
|
|
104
|
+
* (kept even inside a box border) — used by parseInteractivePrompt() and
|
|
105
|
+
* interactivePromptBlocking() to tell a real option row apart from a numbered
|
|
106
|
+
* list in ordinary prose. Deliberately U+276F only, NOT the `[❯>]`
|
|
107
|
+
* alternation TUI_MENU_OPTION_RE uses for row content: the real TUI never
|
|
108
|
+
* renders an ASCII `>` caret, but prose does constantly (markdown blockquotes
|
|
109
|
+
* like "> 1. …"), and accepting `>` here is what let static quoted text
|
|
110
|
+
* qualify as a live highlight (PR #181 review, finding F1). */
|
|
111
|
+
const CARET_OPTION_RE = /^\s*│?\s*❯\s*\d+\./;
|
|
123
112
|
/**
|
|
124
113
|
* Parse the numbered option rows out of a block of screen lines and return the
|
|
125
|
-
* live run as 1..N options
|
|
126
|
-
*
|
|
127
|
-
*
|
|
128
|
-
*
|
|
129
|
-
*
|
|
114
|
+
* live run as 1..N options plus the 1-based index of its ❯-highlighted row.
|
|
115
|
+
* Scrollback above a prompt can contain stale numbered lines (a prior chat
|
|
116
|
+
* message rendered as "1. … 2. …"), so we take the LAST run that starts at
|
|
117
|
+
* "1." and increments by one — that is the live prompt, not history.
|
|
118
|
+
*
|
|
119
|
+
* The highlight is read from the run's OWN rows, never from elsewhere on
|
|
120
|
+
* screen: a separate whole-screen caret scan once let the input line — which
|
|
121
|
+
* renders "❯ <recalled text>" after the probe's Up fallback recalls input
|
|
122
|
+
* history — supply a "moved" highlight for static menu-shaped scrollback and
|
|
123
|
+
* bridge a fabricated menu (PR #181 review round 2, finding 2). A live select
|
|
124
|
+
* prompt highlights exactly one of its rows, so anything else (zero carets =
|
|
125
|
+
* prose that merely looks numbered; two+ = a run polluted by a caret-bearing
|
|
126
|
+
* non-menu line) returns null (fail-safe: no bridge rather than a forged one).
|
|
127
|
+
*
|
|
128
|
+
* Returns null for fewer than two options.
|
|
130
129
|
*
|
|
131
130
|
* `stripBorder` strips a left box border ("│ ") before matching, for prompts that
|
|
132
|
-
* render inside a rounded dialog box (the permission prompt).
|
|
133
|
-
* it off so its full-buffer scan stays byte-identical to before — stripping the
|
|
134
|
-
* border there would let "│ 1. …" lines in dialog-bordered scrollback newly parse
|
|
135
|
-
* as options and shift the live run it picks.
|
|
131
|
+
* render inside a rounded dialog box (the permission prompt).
|
|
136
132
|
*/
|
|
137
|
-
function
|
|
133
|
+
function parseLiveOptionRun(lines, stripBorder = false) {
|
|
138
134
|
const matches = [];
|
|
139
135
|
for (const raw of lines) {
|
|
140
136
|
const line = stripBorder ? raw.replace(/^\s*│\s?/, '') : raw;
|
|
141
137
|
const m = exports.TUI_MENU_OPTION_RE.exec(line);
|
|
138
|
+
// CARET_OPTION_RE tolerates the box border itself, so test the raw line.
|
|
142
139
|
if (m)
|
|
143
|
-
matches.push({ index: Number(m[1]), label: m[2].trim() });
|
|
140
|
+
matches.push({ index: Number(m[1]), label: m[2].trim(), caret: CARET_OPTION_RE.test(raw) });
|
|
144
141
|
}
|
|
145
142
|
if (matches.length < 2)
|
|
146
143
|
return null;
|
|
@@ -157,7 +154,89 @@ function parseOptionRun(lines, stripBorder = false) {
|
|
|
157
154
|
run.push(matches[i]);
|
|
158
155
|
expected++;
|
|
159
156
|
}
|
|
160
|
-
|
|
157
|
+
if (run.length < 2)
|
|
158
|
+
return null;
|
|
159
|
+
const caretRows = run.filter((r) => r.caret);
|
|
160
|
+
if (caretRows.length !== 1)
|
|
161
|
+
return null;
|
|
162
|
+
return {
|
|
163
|
+
options: run.map(({ index, label }) => ({ index, label })),
|
|
164
|
+
highlighted: caretRows[0].index,
|
|
165
|
+
};
|
|
166
|
+
}
|
|
167
|
+
/**
|
|
168
|
+
* Parse a live interactive overlay out of a full screen snapshot — an
|
|
169
|
+
* AskUserQuestion-style menu or a tool-permission Yes/No prompt. Pure
|
|
170
|
+
* function over screen text (as produced by ScreenModel.text()) so the
|
|
171
|
+
* behavioral probe can parse its BEFORE snapshot and the live screen with
|
|
172
|
+
* identical logic and compare the highlighted row across the two
|
|
173
|
+
* (Driver.advanceProbe() in claude-pty-shell.ts).
|
|
174
|
+
*
|
|
175
|
+
* This is a PURE READER: it never decides whether a prompt exists. Callers
|
|
176
|
+
* must already have proven liveness behaviorally — the probe only bridges
|
|
177
|
+
* when the ❯ highlight MOVED between snapshots (confirmProbeReaction() in
|
|
178
|
+
* menu-probe.ts), which static menu-shaped text in prose/scrollback cannot do.
|
|
179
|
+
*
|
|
180
|
+
* Returns null when the region doesn't parse into a clean 1..N option run
|
|
181
|
+
* with a ❯-highlighted row (fail-safe: no bridge rather than a garbled one).
|
|
182
|
+
*
|
|
183
|
+
* isPermission is decided by whether "Do you want to proceed?" appears in the
|
|
184
|
+
* bottom region — a COSMETIC classification (chooses warning-style vs
|
|
185
|
+
* plain-menu-style chat formatting) that defaults to a plain menu when
|
|
186
|
+
* ambiguous; it never gates whether to bridge.
|
|
187
|
+
*/
|
|
188
|
+
function parseInteractivePrompt(screenText) {
|
|
189
|
+
const allLines = screenText.split('\n');
|
|
190
|
+
const bottomLines = allLines.slice(-DIALOG_REGION_ROWS);
|
|
191
|
+
const isPermission = bottomLines.some((l) => l.includes(PERMISSION_QUESTION));
|
|
192
|
+
if (!isPermission) {
|
|
193
|
+
// A menu can render tall (more options than fit a bottom-region window)
|
|
194
|
+
// or sit high on a sparse screen (fresh session, short scrollback), so
|
|
195
|
+
// scan the whole viewport. parseLiveOptionRun() already isolates the
|
|
196
|
+
// live 1..N run nearest the end of the buffer — with its ❯ highlight
|
|
197
|
+
// read from the run's own rows — so stale numbered scrollback above it
|
|
198
|
+
// can't inflate or shift the list, and plain prose that merely happens
|
|
199
|
+
// to look like a numbered list never parses (no highlight row).
|
|
200
|
+
const run = parseLiveOptionRun(allLines);
|
|
201
|
+
return run
|
|
202
|
+
? { options: run.options, context: '', isPermission: false, highlighted: run.highlighted }
|
|
203
|
+
: null;
|
|
204
|
+
}
|
|
205
|
+
// Use the LAST occurrence of the question — the live prompt sits nearest
|
|
206
|
+
// the bottom, so a reply/history that quotes the question higher in the
|
|
207
|
+
// bottom region can't capture the question index and empty the context.
|
|
208
|
+
let qIdx = -1;
|
|
209
|
+
for (let i = bottomLines.length - 1; i >= 0; i--) {
|
|
210
|
+
if (bottomLines[i].includes(PERMISSION_QUESTION)) {
|
|
211
|
+
qIdx = i;
|
|
212
|
+
break;
|
|
213
|
+
}
|
|
214
|
+
}
|
|
215
|
+
const optionRegion = bottomLines.slice(qIdx + 1);
|
|
216
|
+
const run = parseLiveOptionRun(optionRegion, true);
|
|
217
|
+
if (!run)
|
|
218
|
+
return null;
|
|
219
|
+
// Context = the warning + command shown above the question. Bound it to the
|
|
220
|
+
// dialog box (scan up for the rounded top border ╭) so conversation lines
|
|
221
|
+
// that merely share the bottom region aren't swept in; fall back to the
|
|
222
|
+
// few lines immediately above the question when the prompt isn't boxed.
|
|
223
|
+
const isBorderOnly = (l) => /^[\s│╭╮╰╯─]*$/.test(l);
|
|
224
|
+
const stripBorder = (l) => l.replace(/^[\s│]+/, '').replace(/[\s│]+$/, '');
|
|
225
|
+
const aboveQ = bottomLines.slice(0, qIdx);
|
|
226
|
+
let boxTop = -1;
|
|
227
|
+
for (let i = aboveQ.length - 1; i >= 0; i--) {
|
|
228
|
+
if (/[╭╮]/.test(aboveQ[i])) {
|
|
229
|
+
boxTop = i;
|
|
230
|
+
break;
|
|
231
|
+
}
|
|
232
|
+
}
|
|
233
|
+
const contextLines = boxTop >= 0 ? aboveQ.slice(boxTop + 1) : aboveQ.slice(-4);
|
|
234
|
+
const context = contextLines
|
|
235
|
+
.filter((l) => !isBorderOnly(l))
|
|
236
|
+
.map(stripBorder)
|
|
237
|
+
.filter((l) => l.length > 0)
|
|
238
|
+
.join('\n');
|
|
239
|
+
return { options: run.options, context, isPermission: true, highlighted: run.highlighted };
|
|
161
240
|
}
|
|
162
241
|
/**
|
|
163
242
|
* Parse a user's menu reply (typed number or a button's choice payload) into a
|
|
@@ -266,21 +345,6 @@ class ScreenModel {
|
|
|
266
345
|
hasPrompt() {
|
|
267
346
|
return exports.TUI_PROMPT_RE.test(this.text());
|
|
268
347
|
}
|
|
269
|
-
/**
|
|
270
|
-
* The TUI is showing the recoverable "Request too large (max 32MB)" error.
|
|
271
|
-
* Requires both the error prefix and the dismiss-footer marker.
|
|
272
|
-
*
|
|
273
|
-
* SUPERSEDED as the trigger: a verbatim copy of the overlay sentence carries
|
|
274
|
-
* BOTH markers, so re-injected history or an agent quoting the error tripped a
|
|
275
|
-
* false restart loop. Detection now comes from the transcript's `<synthetic>`
|
|
276
|
-
* assistant record (see TranscriptTailer.onRequestTooLarge), which text on
|
|
277
|
-
* screen cannot forge. Kept (and tested) only to document that screen-scraping
|
|
278
|
-
* this error is unreliable — do NOT re-wire it into the tick() trigger.
|
|
279
|
-
*/
|
|
280
|
-
detectRequestTooLarge() {
|
|
281
|
-
const text = this.text();
|
|
282
|
-
return text.includes(exports.TUI_REQUEST_TOO_LARGE) && text.includes(exports.TUI_REQUEST_TOO_LARGE_DISMISS);
|
|
283
|
-
}
|
|
284
348
|
detectDialog() {
|
|
285
349
|
// Scan only the bottom region: a real modal dialog renders there, while a
|
|
286
350
|
// reply/history quoting "Bypass Permissions mode … Yes, I accept" sits in the
|
|
@@ -294,109 +358,41 @@ class ScreenModel {
|
|
|
294
358
|
return null;
|
|
295
359
|
}
|
|
296
360
|
/**
|
|
297
|
-
*
|
|
298
|
-
*
|
|
299
|
-
*
|
|
300
|
-
*
|
|
301
|
-
*
|
|
302
|
-
* numbered lists in assistant output never carry the footer, so this won't
|
|
303
|
-
* false-positive on them. The bypass-permissions dialog also matches the
|
|
304
|
-
* footer; callers must check detectDialog() first and let it auto-accept.
|
|
361
|
+
* Extract the option labels (and, for a permission prompt, the warning/command
|
|
362
|
+
* context) from a live interactive overlay on the current screen. Thin
|
|
363
|
+
* wrapper over {@link parseInteractivePrompt} — see its doc for semantics
|
|
364
|
+
* (pure reader, never a gate; probe callers compare `highlighted` across
|
|
365
|
+
* before/after snapshots to prove liveness).
|
|
305
366
|
*/
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
if (!exports.TUI_MENU_FOOTER.every((s) => text.includes(s)))
|
|
309
|
-
return null;
|
|
310
|
-
// Scan only the region ABOVE the footer — the live menu's options always
|
|
311
|
-
// sit between the question and the "to navigate · to cancel" footer.
|
|
312
|
-
const lines = text.split('\n');
|
|
313
|
-
const footerIdx = lines.findIndex((l) => exports.TUI_MENU_FOOTER.some((s) => l.includes(s)));
|
|
314
|
-
const region = footerIdx >= 0 ? lines.slice(0, footerIdx) : lines;
|
|
315
|
-
// parseOptionRun() takes the live 1..N run nearest the footer, so stale
|
|
316
|
-
// numbered scrollback above the menu can't inflate or shift the option list.
|
|
317
|
-
return parseOptionRun(region);
|
|
367
|
+
readInteractivePrompt() {
|
|
368
|
+
return parseInteractivePrompt(this.text());
|
|
318
369
|
}
|
|
319
370
|
/**
|
|
320
|
-
*
|
|
321
|
-
*
|
|
322
|
-
*
|
|
371
|
+
* True if a selectable prompt (menu row or permission Yes/No) still visibly
|
|
372
|
+
* occupies the screen — a live caret (❯) beside a numbered option, scanned
|
|
373
|
+
* over the FULL viewport (a bottom-region window once let a bridged menu
|
|
374
|
+
* sit outside the check's view and skip its confirming Enter — PR #181
|
|
375
|
+
* review, F4).
|
|
323
376
|
*
|
|
324
|
-
*
|
|
325
|
-
*
|
|
326
|
-
*
|
|
327
|
-
*
|
|
328
|
-
*
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
const lines = text.split('\n');
|
|
341
|
-
// Use the LAST occurrence of the question — the live prompt sits nearest the
|
|
342
|
-
// footer, so a reply/history that quotes "Do you want to proceed?" higher in
|
|
343
|
-
// the bottom region can't capture the question index and empty the context.
|
|
344
|
-
let qIdx = -1;
|
|
345
|
-
for (let i = lines.length - 1; i >= 0; i--) {
|
|
346
|
-
if (lines[i].includes(exports.TUI_PERMISSION_PROMPT)) {
|
|
347
|
-
qIdx = i;
|
|
348
|
-
break;
|
|
349
|
-
}
|
|
350
|
-
}
|
|
351
|
-
const footerIdx = lines.findIndex((l, i) => i > qIdx && exports.TUI_PERMISSION_FOOTER_TOKENS.some((t) => l.includes(t)));
|
|
352
|
-
// Options live strictly between the question and the footer.
|
|
353
|
-
const optionRegion = footerIdx >= 0 ? lines.slice(qIdx + 1, footerIdx) : lines.slice(qIdx + 1);
|
|
354
|
-
// A live select prompt always highlights one option with the ❯/> caret (kept
|
|
355
|
-
// even inside a box border). Quoted prose numbered lists never carry it, so
|
|
356
|
-
// requiring it closes the false-positive where conversational text pairs a
|
|
357
|
-
// numbered list with the question + a footer-ish phrase.
|
|
358
|
-
const hasCaret = optionRegion.some((l) => /^\s*│?\s*[❯>]\s*\d+\./.test(l));
|
|
359
|
-
if (!hasCaret)
|
|
360
|
-
return null;
|
|
361
|
-
const options = parseOptionRun(optionRegion, true);
|
|
362
|
-
if (!options)
|
|
363
|
-
return null;
|
|
364
|
-
// Context = the warning + command shown above the question. Bound it to the
|
|
365
|
-
// dialog box (scan up for the rounded top border ╭) so conversation lines that
|
|
366
|
-
// merely share the bottom region aren't swept in; fall back to the few lines
|
|
367
|
-
// immediately above the question when the prompt isn't boxed.
|
|
368
|
-
const isBorderOnly = (l) => /^[\s│╭╮╰╯─]*$/.test(l);
|
|
369
|
-
const stripBorder = (l) => l.replace(/^[\s│]+/, '').replace(/[\s│]+$/, '');
|
|
370
|
-
const aboveQ = lines.slice(0, qIdx);
|
|
371
|
-
let boxTop = -1;
|
|
372
|
-
for (let i = aboveQ.length - 1; i >= 0; i--) {
|
|
373
|
-
if (/[╭╮]/.test(aboveQ[i])) {
|
|
374
|
-
boxTop = i;
|
|
375
|
-
break;
|
|
376
|
-
}
|
|
377
|
-
}
|
|
378
|
-
const contextLines = boxTop >= 0 ? aboveQ.slice(boxTop + 1) : aboveQ.slice(-4);
|
|
379
|
-
const context = contextLines
|
|
380
|
-
.filter((l) => !isBorderOnly(l))
|
|
381
|
-
.map(stripBorder)
|
|
382
|
-
.filter((l) => l.length > 0)
|
|
383
|
-
.join('\n');
|
|
384
|
-
return { options, context };
|
|
385
|
-
}
|
|
386
|
-
/**
|
|
387
|
-
* True if a select menu or permission prompt is still blocking on input at the
|
|
388
|
-
* BOTTOM of the screen. Used to decide whether the confirming Enter after a typed
|
|
389
|
-
* selection is still needed: scoping to the bottom region means stale footer /
|
|
390
|
-
* numbered rows left in scrollback by an already-answered prompt can't keep a
|
|
391
|
-
* stray Enter alive (which would submit an empty line at the idle caret).
|
|
392
|
-
* detectMenu() deliberately scans the full buffer to parse a tall menu's options,
|
|
393
|
-
* so it's the wrong signal for this liveness check — hence the dedicated method.
|
|
377
|
+
* DELIBERATELY PERMISSIVE — only safe where a false positive is cheap.
|
|
378
|
+
* The input line renders "❯ <text>", so a user draft or recalled history
|
|
379
|
+
* entry whose text starts with "N." matches CARET_OPTION_RE exactly like a
|
|
380
|
+
* menu row; quoted menu text in visible scrollback matches too. Static text
|
|
381
|
+
* can never prove liveness (that's the behavioral probe's job), so this
|
|
382
|
+
* check must only gate actions that are harmless when it's wrong:
|
|
383
|
+
*
|
|
384
|
+
* - selectMenuOption()'s confirming Enter — a stray Enter at an idle
|
|
385
|
+
* empty caret is a no-op;
|
|
386
|
+
* - decideMenuCancel()'s menuVisible — worst case a bounded ESC re-send
|
|
387
|
+
* and a delayed submit (hard timeout caps it);
|
|
388
|
+
* - the Enter-swallowed retry, but ONLY for a menu-selection turn where
|
|
389
|
+
* a live menu genuinely can be on screen. Gating the retry of an
|
|
390
|
+
* ordinary turn on this check suppressed the retry whenever the
|
|
391
|
+
* unsubmitted draft itself started with "N." — wedging the turn into
|
|
392
|
+
* the 30-min watchdog (PR #181 review round 2, finding 1).
|
|
394
393
|
*/
|
|
395
394
|
interactivePromptBlocking() {
|
|
396
|
-
|
|
397
|
-
if (exports.TUI_MENU_FOOTER.every((s) => text.includes(s)))
|
|
398
|
-
return true;
|
|
399
|
-
return this.detectPermissionPrompt() !== null;
|
|
395
|
+
return this.text().split('\n').some((l) => CARET_OPTION_RE.test(l));
|
|
400
396
|
}
|
|
401
397
|
}
|
|
402
398
|
exports.ScreenModel = ScreenModel;
|
package/dist/shell/screen.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"screen.js","sourceRoot":"","sources":["../../src/shell/screen.ts"],"names":[],"mappings":";;;AA0FA,sDAKC;
|
|
1
|
+
{"version":3,"file":"screen.js","sourceRoot":"","sources":["../../src/shell/screen.ts"],"names":[],"mappings":"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"}
|
package/dist/shell/tailer.d.ts
CHANGED
|
@@ -43,13 +43,6 @@ export interface TailerEvents {
|
|
|
43
43
|
* model id AND the overlay text — neither alone is unique to the genuine error.
|
|
44
44
|
*/
|
|
45
45
|
export declare function isSyntheticRequestTooLarge(message: AssistantRecord['message']): boolean;
|
|
46
|
-
/**
|
|
47
|
-
* True when an assistant record invokes a tool that raises a blocking menu. This
|
|
48
|
-
* is the AUTHORITATIVE signal that a menu is genuinely on screen — used to gate
|
|
49
|
-
* screen-based menu bridging so a reply/history that merely renders a menu-shaped
|
|
50
|
-
* numbered list + footer can't spawn a phantom menu in chat.
|
|
51
|
-
*/
|
|
52
|
-
export declare function hasInteractiveMenuToolUse(message: AssistantRecord['message']): boolean;
|
|
53
46
|
/**
|
|
54
47
|
* cwd → Claude Code project-dir slug (verified against v2.1.x: `/` and `.` both become `-`).
|
|
55
48
|
* If Claude Code ever changes this scheme, findFile()'s fallback UUID scan will still
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"tailer.d.ts","sourceRoot":"","sources":["../../src/shell/tailer.ts"],"names":[],"mappings":"AAKA,MAAM,WAAW,SAAS;IACxB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,uBAAuB,CAAC,EAAE,MAAM,CAAC;IACjC,2BAA2B,CAAC,EAAE,MAAM,CAAC;IACrC,aAAa,CAAC,EAAE,MAAM,CAAC;CACxB;AAED,MAAM,WAAW,eAAe;IAC9B,IAAI,EAAE,WAAW,CAAC;IAClB,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,OAAO,EAAE;QACP,IAAI,EAAE,WAAW,CAAC;QAClB,uFAAuF;QACvF,KAAK,CAAC,EAAE,MAAM,CAAC;QACf,OAAO,EAAE,KAAK,CAAC;YAAE,IAAI,EAAE,MAAM,CAAC;YAAC,CAAC,CAAC,EAAE,MAAM,GAAG,OAAO,CAAA;SAAE,CAAC,CAAC;QACvD,WAAW,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;QAC5B,KAAK,CAAC,EAAE,SAAS,CAAC;KACnB,CAAC;IACF,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED,MAAM,WAAW,YAAY;IAC3B,2DAA2D;IAC3D,WAAW,EAAE,CAAC,MAAM,EAAE,eAAe,KAAK,IAAI,CAAC;IAC/C,4DAA4D;IAC5D,SAAS,EAAE,CAAC,UAAU,EAAE,MAAM,KAAK,IAAI,CAAC;IACxC;;;;;;;OAOG;IACH,iBAAiB,CAAC,EAAE,MAAM,IAAI,CAAC;IAC/B,OAAO,EAAE,CAAC,GAAG,EAAE,KAAK,KAAK,IAAI,CAAC;CAC/B;AAED;;;;GAIG;AACH,wBAAgB,0BAA0B,CAAC,OAAO,EAAE,eAAe,CAAC,SAAS,CAAC,GAAG,OAAO,CAMvF;
|
|
1
|
+
{"version":3,"file":"tailer.d.ts","sourceRoot":"","sources":["../../src/shell/tailer.ts"],"names":[],"mappings":"AAKA,MAAM,WAAW,SAAS;IACxB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,uBAAuB,CAAC,EAAE,MAAM,CAAC;IACjC,2BAA2B,CAAC,EAAE,MAAM,CAAC;IACrC,aAAa,CAAC,EAAE,MAAM,CAAC;CACxB;AAED,MAAM,WAAW,eAAe;IAC9B,IAAI,EAAE,WAAW,CAAC;IAClB,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,OAAO,EAAE;QACP,IAAI,EAAE,WAAW,CAAC;QAClB,uFAAuF;QACvF,KAAK,CAAC,EAAE,MAAM,CAAC;QACf,OAAO,EAAE,KAAK,CAAC;YAAE,IAAI,EAAE,MAAM,CAAC;YAAC,CAAC,CAAC,EAAE,MAAM,GAAG,OAAO,CAAA;SAAE,CAAC,CAAC;QACvD,WAAW,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;QAC5B,KAAK,CAAC,EAAE,SAAS,CAAC;KACnB,CAAC;IACF,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED,MAAM,WAAW,YAAY;IAC3B,2DAA2D;IAC3D,WAAW,EAAE,CAAC,MAAM,EAAE,eAAe,KAAK,IAAI,CAAC;IAC/C,4DAA4D;IAC5D,SAAS,EAAE,CAAC,UAAU,EAAE,MAAM,KAAK,IAAI,CAAC;IACxC;;;;;;;OAOG;IACH,iBAAiB,CAAC,EAAE,MAAM,IAAI,CAAC;IAC/B,OAAO,EAAE,CAAC,GAAG,EAAE,KAAK,KAAK,IAAI,CAAC;CAC/B;AAED;;;;GAIG;AACH,wBAAgB,0BAA0B,CAAC,OAAO,EAAE,eAAe,CAAC,SAAS,CAAC,GAAG,OAAO,CAMvF;AAED;;;;GAIG;AACH,wBAAgB,WAAW,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAE/C;AAED,wBAAgB,cAAc,CAAC,GAAG,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,MAAM,CAErE;AAED;;;;GAIG;AACH,qBAAa,gBAAgB;IAYzB,OAAO,CAAC,QAAQ,CAAC,GAAG;IACpB,OAAO,CAAC,QAAQ,CAAC,SAAS;IAC1B,OAAO,CAAC,QAAQ,CAAC,MAAM;IACvB,OAAO,CAAC,QAAQ,CAAC,MAAM;IAdzB,OAAO,CAAC,MAAM,CAAK;IACnB,OAAO,CAAC,WAAW,CAAM;IACzB,OAAO,CAAC,KAAK,CAA+C;IAC5D,OAAO,CAAC,YAAY,CAAuB;IAC3C,sFAAsF;IACtF,WAAW,SAAK;IAChB,mFAAmF;IACnF,OAAO,CAAC,kBAAkB,CAAK;IAC/B,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,yBAAyB,CAAS;gBAGvC,GAAG,EAAE,MAAM,EACX,SAAS,EAAE,MAAM,EACjB,MAAM,EAAE,YAAY,EACpB,MAAM,SAAM;IAG/B,KAAK,IAAI,IAAI;IAIb,IAAI,IAAI,IAAI;IAKZ,wEAAwE;IACxE,KAAK,IAAI,IAAI;IAIb,OAAO,CAAC,QAAQ;IA0BhB,OAAO,CAAC,IAAI;IA2CZ,OAAO,CAAC,QAAQ;CAwBjB"}
|
package/dist/shell/tailer.js
CHANGED
|
@@ -35,7 +35,6 @@ var __importStar = (this && this.__importStar) || (function () {
|
|
|
35
35
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
36
36
|
exports.TranscriptTailer = void 0;
|
|
37
37
|
exports.isSyntheticRequestTooLarge = isSyntheticRequestTooLarge;
|
|
38
|
-
exports.hasInteractiveMenuToolUse = hasInteractiveMenuToolUse;
|
|
39
38
|
exports.projectSlug = projectSlug;
|
|
40
39
|
exports.transcriptPath = transcriptPath;
|
|
41
40
|
const fs = __importStar(require("fs"));
|
|
@@ -55,34 +54,6 @@ function isSyntheticRequestTooLarge(message) {
|
|
|
55
54
|
.join(' ');
|
|
56
55
|
return text.includes(screen_1.TUI_REQUEST_TOO_LARGE);
|
|
57
56
|
}
|
|
58
|
-
/**
|
|
59
|
-
* Tools whose invocation puts the TUI into a blocking interactive select-menu the
|
|
60
|
-
* gateway bridges to chat: AskUserQuestion and the plan-approval ExitPlanMode.
|
|
61
|
-
*
|
|
62
|
-
* - `AskUserQuestion` — verified present as a `tool_use` record in real transcripts.
|
|
63
|
-
* - `ExitPlanMode` / `exit_plan_mode` — the plan-approval tool. Both the PascalCase
|
|
64
|
-
* and legacy snake_case names appear in the Claude Code CLI binary, and the tool
|
|
65
|
-
* name field varies by model, so both are listed to be safe. (No transcript
|
|
66
|
-
* sample was available to confirm which the running model emits.)
|
|
67
|
-
*
|
|
68
|
-
* If a future tool raises a bridgeable menu, add it here; an omission only means
|
|
69
|
-
* that menu isn't bridged (fail-safe), never a crash.
|
|
70
|
-
*/
|
|
71
|
-
const MENU_TOOL_NAMES = new Set(['AskUserQuestion', 'ExitPlanMode', 'exit_plan_mode']);
|
|
72
|
-
/**
|
|
73
|
-
* True when an assistant record invokes a tool that raises a blocking menu. This
|
|
74
|
-
* is the AUTHORITATIVE signal that a menu is genuinely on screen — used to gate
|
|
75
|
-
* screen-based menu bridging so a reply/history that merely renders a menu-shaped
|
|
76
|
-
* numbered list + footer can't spawn a phantom menu in chat.
|
|
77
|
-
*/
|
|
78
|
-
function hasInteractiveMenuToolUse(message) {
|
|
79
|
-
return message.content.some((b) => {
|
|
80
|
-
if (b.type !== 'tool_use')
|
|
81
|
-
return false;
|
|
82
|
-
const name = b.name;
|
|
83
|
-
return typeof name === 'string' && MENU_TOOL_NAMES.has(name);
|
|
84
|
-
});
|
|
85
|
-
}
|
|
86
57
|
/**
|
|
87
58
|
* cwd → Claude Code project-dir slug (verified against v2.1.x: `/` and `.` both become `-`).
|
|
88
59
|
* If Claude Code ever changes this scheme, findFile()'s fallback UUID scan will still
|
package/dist/shell/tailer.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"tailer.js","sourceRoot":"","sources":["../../src/shell/tailer.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAiDA,gEAMC;
|
|
1
|
+
{"version":3,"file":"tailer.js","sourceRoot":"","sources":["../../src/shell/tailer.ts"],"names":[],"mappings":"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"}
|
|
@@ -710,9 +710,10 @@ const BOT_COMMANDS = [
|
|
|
710
710
|
|
|
711
711
|
// Available AI models for /models command
|
|
712
712
|
const AVAILABLE_MODELS = [
|
|
713
|
-
{ id: 'claude-fable-5',
|
|
713
|
+
{ id: 'claude-fable-5[1m]', label: 'Fable 5 (1M)', alias: 'fable[1m]' },
|
|
714
714
|
{ id: 'claude-opus-4-8[1m]', label: 'Opus 4.8 (1M)', alias: 'opus[1m]' },
|
|
715
715
|
{ id: 'claude-sonnet-5[1m]', label: 'Sonnet 5 (1M)', alias: 'sonnet[1m]' },
|
|
716
|
+
{ id: 'claude-fable-5', label: 'Fable 5', alias: 'fable' },
|
|
716
717
|
{ id: 'claude-opus-4-8', label: 'Opus 4.8', alias: 'opus' },
|
|
717
718
|
{ id: 'claude-opus-4-6', label: 'Opus 4.6', alias: 'opus46' },
|
|
718
719
|
{ id: 'claude-sonnet-5', label: 'Sonnet 5', alias: 'sonnet' },
|