Run a peer CLI directly in the real terminal (no nested PTY). Used for CLIs that bundle their own native PTY module and crash when spawned inside pexpect's PTY. Output is captured via the `script` utility so Codey can read it. The prepared prompt is shown above the CLI so you c
(cli_name: str, cmd: str, prompt_text: str = "")
| 327 | |
| 328 | |
| 329 | def run_direct(cli_name: str, cmd: str, prompt_text: str = "") -> str: |
| 330 | """ |
| 331 | Run a peer CLI directly in the real terminal (no nested PTY). |
| 332 | Used for CLIs that bundle their own native PTY module |
| 333 | and crash when spawned inside pexpect's PTY. |
| 334 | |
| 335 | Output is captured via the `script` utility so Codey can read it. |
| 336 | The prepared prompt is shown above the CLI so you can paste it in. |
| 337 | """ |
| 338 | import tempfile |
| 339 | width = _terminal_width() |
| 340 | border = "─" * width |
| 341 | outfile = tempfile.mktemp(prefix="codey_peer_", suffix=".txt") |
| 342 | |
| 343 | print(f"\n{_CYAN}{_header(cli_name.upper() + ' CLI', width)}{_RESET}") |
| 344 | info(f"Opening {cli_name} in your terminal.") |
| 345 | |
| 346 | if prompt_text: |
| 347 | print(f"\n{_DIM}── Paste this into {cli_name} ──────────────────────────{_RESET}") |
| 348 | print(f"{prompt_text}") |
| 349 | print(f"{_DIM}{border}{_RESET}\n") |
| 350 | |
| 351 | info(f"Close {cli_name} normally when done (/exit, Ctrl+D, /quit…)") |
| 352 | print(f"{_DIM}Ctrl+B → return to Codey at any point{_RESET}\n") |
| 353 | |
| 354 | # `script -q -c <cmd> <file>` records the session to outfile |
| 355 | # while letting the CLI run in the real terminal with full PTY support. |
| 356 | # -q = quiet (no "Script started/done" lines) |
| 357 | os.system(f'script -q -c "{cmd}" "{outfile}"') |
| 358 | |
| 359 | print(f"\n{_DIM}{border}{_RESET}") |
| 360 | print(f"{_CYAN}{_header(cli_name.upper() + ' DONE', width)}{_RESET}\n") |
| 361 | info(f"Back in Codey — reading {cli_name} output…") |
| 362 | |
| 363 | try: |
| 364 | raw = Path(outfile).read_bytes() |
| 365 | Path(outfile).unlink(missing_ok=True) |
| 366 | # Strip ANSI escape codes from the recorded script output |
| 367 | text = raw.decode("utf-8", errors="replace") |
| 368 | text = re.sub(r"\x1b\[[0-9;]*[a-zA-Z]", "", text) |
| 369 | text = re.sub(r"\x1b\][^\x07]*\x07", "", text) |
| 370 | return text |
| 371 | except Exception as e: |
| 372 | return f"[Could not read output: {e}]" |
| 373 | |
| 374 | |
| 375 | def _wait_for_gemini(child, pexpect_mod) -> None: |
no test coverage detected