mirror of
https://github.com/blamouche/obsidian-any-ai-code.git
synced 2026-07-22 06:53:38 +00:00
Set PTY size explicitly in python bridge fallback
This commit is contained in:
parent
5839ab5c1b
commit
7e663cb0d7
7 changed files with 82 additions and 5 deletions
|
|
@ -8,3 +8,4 @@
|
|||
- Proactive terminal handshake injection can be echoed back as raw input in bridge mode; prefer startup-config mitigations over escape-sequence injection.
|
||||
- If injected terminal response sequences are echoed as raw text, stop injection and instead disable Codex startup prompts/warnings via config flags to reduce hidden interactive blockers.
|
||||
- For interactive Codex/TUI output in embedded xterm, avoid forcing `convertEol: true`; it can distort line rendering and split characters across lines.
|
||||
- Python PTY bridge must set terminal size explicitly (`TIOCSWINSZ`) using requested cols/rows; otherwise interactive TUI output can degrade into letter-per-line rendering.
|
||||
|
|
|
|||
|
|
@ -28,3 +28,4 @@
|
|||
| 2026-03-13 20:15:06 CET | agent | Added proactive Codex startup terminal handshake (immediate + delayed retry) to address blank bridge startup, with validation and governance updates. | `main.ts`, `.prompt-hub/lessons.md`, `npm run build`, `npm test`, `.prompt-hub/todo/todo-20260313-201421-codex-proactive-handshake.md`, `.prompt-hub/version.md`, `.prompt-hub/releases.md` | success | Commit and push for user retest. |
|
||||
| 2026-03-13 23:24:39 CET | agent | Removed ineffective Codex escape injection (echoed as raw input) and switched to startup prompt-suppression flags in Codex launch command; validated build/tests. | `main.ts`, `.prompt-hub/lessons.md`, `npm run build`, `npm test`, `.prompt-hub/todo/todo-20260313-232410-codex-disable-startup-prompts.md`, `.prompt-hub/version.md`, `.prompt-hub/releases.md` | success | Commit and push for user retest. |
|
||||
| 2026-03-13 23:30:56 CET | agent | Fixed broken split-character Codex rendering by disabling forced xterm EOL conversion (`convertEol: false`); validated build/tests and updated governance files. | `main.ts`, `.prompt-hub/lessons.md`, `npm run build`, `npm test`, `.prompt-hub/todo/todo-20260313-233016-fix-codex-split-characters-output.md`, `.prompt-hub/version.md`, `.prompt-hub/releases.md` | success | Commit and push for user verification. |
|
||||
| 2026-03-13 23:37:35 CET | agent | Fixed letter-per-line Codex output by propagating cols/rows to python PTY bridge and applying `TIOCSWINSZ` in explicit PTY fork/exec bridge path; validated compile/smoke/build/tests. | `pty-proxy.js`, `pty-bridge.py`, `.prompt-hub/lessons.md`, `python3 -m py_compile pty-bridge.py`, `python3 pty-bridge.py <payload>`, `npm run build`, `npm test`, `.prompt-hub/todo/todo-20260313-233621-fix-codex-pty-size-python-bridge.md`, `.prompt-hub/version.md`, `.prompt-hub/releases.md` | success | Commit and push for user retest. |
|
||||
|
|
|
|||
|
|
@ -1,5 +1,9 @@
|
|||
# Releases
|
||||
|
||||
## 0.1.12 - 2026-03-13
|
||||
- Fixed python PTY fallback sizing by propagating requested cols/rows from the proxy and applying them in `pty-bridge.py` via `TIOCSWINSZ` at startup.
|
||||
- Reworked python bridge execution from `pty.spawn` convenience mode to explicit PTY fork/exec streaming for deterministic terminal sizing.
|
||||
|
||||
## 0.1.11 - 2026-03-13
|
||||
- Fixed split-character / broken newline rendering in embedded Codex output by disabling forced xterm EOL conversion (`convertEol: false`).
|
||||
|
||||
|
|
|
|||
|
|
@ -0,0 +1,19 @@
|
|||
# Task: Fix Codex letter-per-line output in python PTY bridge
|
||||
|
||||
## Context
|
||||
- Codex output appears as one character per line in embedded terminal.
|
||||
- Likely PTY size negotiation issue in python fallback bridge.
|
||||
|
||||
## Plan
|
||||
- [x] Pass cols/rows through proxy payload to python bridge.
|
||||
- [x] Replace bridge spawn path with explicit PTY fork + winsize setup.
|
||||
- [x] Validate build/tests and update traceability.
|
||||
|
||||
## Review
|
||||
- Updated `pty-proxy.js` to pass normalized `cols`/`rows` into python bridge payload.
|
||||
- Reworked `pty-bridge.py` to use explicit PTY fork/exec and apply terminal size (`TIOCSWINSZ`) before streaming.
|
||||
- Validation:
|
||||
- `python3 -m py_compile pty-bridge.py` passed.
|
||||
- `python3 pty-bridge.py <payload>` smoke test passed (`OK_BRIDGE`).
|
||||
- `npm run build` passed.
|
||||
- `npm test` passed (`12/12` tests).
|
||||
|
|
@ -1 +1 @@
|
|||
0.1.11
|
||||
0.1.12
|
||||
|
|
|
|||
|
|
@ -3,7 +3,11 @@ import base64
|
|||
import json
|
||||
import os
|
||||
import pty
|
||||
import fcntl
|
||||
import select
|
||||
import struct
|
||||
import sys
|
||||
import termios
|
||||
|
||||
|
||||
def decode_payload(raw: str):
|
||||
|
|
@ -21,6 +25,42 @@ def as_exit_code(status: int) -> int:
|
|||
return 1
|
||||
|
||||
|
||||
def set_winsize(fd: int, rows: int, cols: int) -> None:
|
||||
packed = struct.pack("HHHH", rows, cols, 0, 0)
|
||||
fcntl.ioctl(fd, termios.TIOCSWINSZ, packed)
|
||||
|
||||
|
||||
def stream_pty(pid: int, fd: int) -> int:
|
||||
stdin_open = True
|
||||
while True:
|
||||
readers = [fd]
|
||||
if stdin_open:
|
||||
readers.append(sys.stdin.fileno())
|
||||
|
||||
ready, _, _ = select.select(readers, [], [])
|
||||
if fd in ready:
|
||||
try:
|
||||
chunk = os.read(fd, 4096)
|
||||
except OSError:
|
||||
chunk = b""
|
||||
if not chunk:
|
||||
break
|
||||
os.write(sys.stdout.fileno(), chunk)
|
||||
|
||||
if stdin_open and sys.stdin.fileno() in ready:
|
||||
try:
|
||||
chunk = os.read(sys.stdin.fileno(), 4096)
|
||||
except OSError:
|
||||
chunk = b""
|
||||
if not chunk:
|
||||
stdin_open = False
|
||||
else:
|
||||
os.write(fd, chunk)
|
||||
|
||||
_, status = os.waitpid(pid, 0)
|
||||
return as_exit_code(status)
|
||||
|
||||
|
||||
def main() -> int:
|
||||
payload = decode_payload(sys.argv[1] if len(sys.argv) > 1 else "")
|
||||
|
||||
|
|
@ -35,6 +75,10 @@ def main() -> int:
|
|||
os.environ[str(key)] = str(value)
|
||||
|
||||
launches = payload.get("launches") or []
|
||||
cols = int(payload.get("cols") or 120)
|
||||
rows = int(payload.get("rows") or 30)
|
||||
cols = max(20, cols)
|
||||
rows = max(10, rows)
|
||||
if not launches:
|
||||
print("[py-bridge-error] no launch specs provided", file=sys.stderr)
|
||||
return 1
|
||||
|
|
@ -45,8 +89,12 @@ def main() -> int:
|
|||
args = launch.get("args") or []
|
||||
argv = [str(file)] + [str(x) for x in args]
|
||||
try:
|
||||
status = pty.spawn(argv)
|
||||
return as_exit_code(status)
|
||||
pid, fd = pty.fork()
|
||||
if pid == 0:
|
||||
os.execvpe(str(file), argv, os.environ)
|
||||
|
||||
set_winsize(fd, rows, cols)
|
||||
return stream_pty(pid, fd)
|
||||
except OSError as error:
|
||||
failures.append(f"{file}: {error}")
|
||||
|
||||
|
|
|
|||
|
|
@ -139,7 +139,9 @@ function spawnPythonBridge(payload, launches) {
|
|||
JSON.stringify({
|
||||
cwd: payload.cwd,
|
||||
env: payload.env,
|
||||
launches
|
||||
launches,
|
||||
cols: payload.cols,
|
||||
rows: payload.rows
|
||||
}),
|
||||
"utf8"
|
||||
).toString("base64");
|
||||
|
|
@ -185,7 +187,9 @@ async function main() {
|
|||
term = spawnPythonBridge(
|
||||
{
|
||||
cwd: payload.cwd,
|
||||
env: fallbackEnv
|
||||
env: fallbackEnv,
|
||||
cols: Math.max(20, Number(payload.cols) || 120),
|
||||
rows: Math.max(10, Number(payload.rows) || 30)
|
||||
},
|
||||
launches
|
||||
);
|
||||
|
|
|
|||
Loading…
Reference in a new issue