Assistant: codex Assistant-Model: gpt-5.6-sol Assistant-Session: 01a03397-4d51-7fd1-8ff2-946eb22ea2bc
This commit is contained in:
parent
2009d01ae4
commit
452235a01f
6 changed files with 133 additions and 8 deletions
|
|
@ -3,6 +3,7 @@ from __future__ import annotations
|
|||
import fcntl
|
||||
import os
|
||||
import pty
|
||||
import re
|
||||
import select
|
||||
import signal
|
||||
import sys
|
||||
|
|
@ -13,6 +14,35 @@ from collections.abc import Callable, Sequence
|
|||
from .broker import InputBroker
|
||||
|
||||
|
||||
ENHANCED_ENTER = re.compile(
|
||||
rb"\x1b(?:\[13(?:;[0-9:]+)*u|\[27;[0-9:]+;13~|OM)"
|
||||
)
|
||||
TERMINAL_INPUT_SEQUENCE = re.compile(
|
||||
rb"\x1b(?:"
|
||||
rb"\[[0-?]*[ -/]*[@-~]"
|
||||
rb"|O."
|
||||
rb"|P.*?(?:\x1b\\)"
|
||||
rb"|\].*?(?:\x07|\x1b\\)"
|
||||
rb")",
|
||||
re.DOTALL,
|
||||
)
|
||||
|
||||
|
||||
def observed_line(raw: bytes) -> str:
|
||||
"""Return typed text without terminal replies or local editing controls."""
|
||||
decoded = TERMINAL_INPUT_SEQUENCE.sub(b"", raw).decode(
|
||||
"utf-8", errors="replace"
|
||||
)
|
||||
text: list[str] = []
|
||||
for character in decoded:
|
||||
if character in ("\b", "\x7f"):
|
||||
if text:
|
||||
text.pop()
|
||||
elif character == "\t" or character >= " ":
|
||||
text.append(character)
|
||||
return "".join(text)
|
||||
|
||||
|
||||
class PtyTap:
|
||||
"""Full-duplex PTY proxy. Input is observed, never rewritten."""
|
||||
|
||||
|
|
@ -24,13 +54,19 @@ class PtyTap:
|
|||
def _observe_input(self, buffer: bytearray, data: bytes) -> None:
|
||||
buffer.extend(data)
|
||||
while True:
|
||||
delimiters = [index for marker in (b"\r", b"\n") if (index := buffer.find(marker)) >= 0]
|
||||
if not delimiters:
|
||||
boundaries = [
|
||||
(index, index + 1)
|
||||
for marker in (b"\r", b"\n")
|
||||
if (index := buffer.find(marker)) >= 0
|
||||
]
|
||||
if match := ENHANCED_ENTER.search(buffer):
|
||||
boundaries.append(match.span())
|
||||
if not boundaries:
|
||||
return
|
||||
index = min(delimiters)
|
||||
raw = bytes(buffer[:index])
|
||||
del buffer[: index + 1]
|
||||
line = raw.decode("utf-8", errors="replace")
|
||||
start, end = min(boundaries)
|
||||
raw = bytes(buffer[:start])
|
||||
del buffer[:end]
|
||||
line = observed_line(raw)
|
||||
routed = self.broker.inspect_line(line)
|
||||
if routed and self.on_line:
|
||||
self.on_line(line)
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue