Add contributor guide and project usage docs
This commit is contained in:
56
src/lazy_enter/pty_manager.py
Normal file
56
src/lazy_enter/pty_manager.py
Normal file
@@ -0,0 +1,56 @@
|
||||
"""pexpect 기반 PTY 프로세스 관리."""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
import logging
|
||||
|
||||
import pexpect
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
|
||||
class PtyManager:
|
||||
"""가상 터미널에서 CLI 프로세스를 생성하고 입출력을 제어한다."""
|
||||
|
||||
def __init__(self, command: str = "claude") -> None:
|
||||
self.command = command
|
||||
self._process: pexpect.spawn | None = None
|
||||
|
||||
@property
|
||||
def is_alive(self) -> bool:
|
||||
return self._process is not None and self._process.isalive()
|
||||
|
||||
def start(self) -> None:
|
||||
"""프로세스를 시작한다."""
|
||||
logger.info("프로세스 시작: %s", self.command)
|
||||
self._process = pexpect.spawn(
|
||||
self.command,
|
||||
encoding="utf-8",
|
||||
timeout=None,
|
||||
)
|
||||
|
||||
def send(self, text: str) -> None:
|
||||
"""프로세스에 텍스트 입력을 전달한다."""
|
||||
if not self.is_alive:
|
||||
raise RuntimeError("프로세스가 실행 중이 아닙니다.")
|
||||
assert self._process is not None
|
||||
logger.debug("입력 전송: %s", text)
|
||||
self._process.sendline(text)
|
||||
|
||||
def read_output(self, timeout: int = 5) -> str:
|
||||
"""프로세스의 출력을 읽는다."""
|
||||
if not self.is_alive:
|
||||
raise RuntimeError("프로세스가 실행 중이 아닙니다.")
|
||||
assert self._process is not None
|
||||
try:
|
||||
self._process.expect(pexpect.TIMEOUT, timeout=timeout)
|
||||
except pexpect.TIMEOUT:
|
||||
pass
|
||||
return self._process.before or ""
|
||||
|
||||
def stop(self) -> None:
|
||||
"""프로세스를 종료한다."""
|
||||
if self._process is not None:
|
||||
logger.info("프로세스 종료")
|
||||
self._process.close(force=True)
|
||||
self._process = None
|
||||
Reference in New Issue
Block a user