feat: add conversational replies and stable output
Some checks failed
tamq-ci / test (push) Failing after 6s

Assistant: codex
Assistant-Model: gpt-5.6-sol
Assistant-Session: 01a03397-4d51-7fd1-8ff2-946eb22ea2bc
This commit is contained in:
tegwick 2026-08-24 23:03:30 +02:00
parent 704eeea5c1
commit a4ba6e32e5
17 changed files with 363 additions and 59 deletions

View file

@ -10,6 +10,7 @@ import pytest
from tamq.broker import BrokerIdentity, InputBroker
from tamq.control import ControlModeClient
from tamq.store import Store
from tamq.terminal import terminal_frame, write_terminal_output
from tamq.tmux import LaunchPlan, TmuxManager
@ -112,3 +113,88 @@ def test_real_tmux_starts_two_repo_windows_and_reuses_them(tmp_path, monkeypatch
store.close()
finally:
manager._run("kill-server", check=False)
@pytest.mark.skipif(shutil.which("tmux") is None, reason="tmux is not installed")
def test_real_tmux_output_preserves_partial_input_line_and_cursor(tmp_path):
repo = tmp_path / "audit-core"
repo.mkdir()
socket_name = f"tamq-output-{os.getpid()}-{uuid4().hex[:8]}"
session = f"tamq-output-{uuid4().hex[:8]}"
manager = TmuxManager(
session,
tmux_command=("tmux", "-L", socket_name),
tamq_command=(sys.executable, "-m", "tamq.cli"),
command_dir=tmp_path / "commands",
)
target = f"{session}:audit-core"
plan = LaunchPlan(("audit-core",), {"audit-core": str(repo)}, ())
try:
manager.ensure_plan(plan)
deadline = time.monotonic() + 5
while time.monotonic() < deadline:
current_command = manager._run(
"display-message", "-p", "-t", target, "#{pane_current_command}"
)
if current_command in {"bash", "sh", "zsh", "fish"}:
break
time.sleep(0.05)
assert current_command in {"bash", "sh", "zsh", "fish"}
manager._run(
"send-keys", "-t", target, "-l", "--", "printf 'line-one\\nline-two\\n'"
)
manager._run("send-keys", "-t", target, "Enter")
deadline = time.monotonic() + 5
while time.monotonic() < deadline:
initial_capture = manager._run("capture-pane", "-p", "-t", target)
initial_lines = initial_capture.splitlines()
if "line-one" in initial_lines and "line-two" in initial_lines:
break
time.sleep(0.05)
assert "line-one" in initial_lines and "line-two" in initial_lines
manager._run("send-keys", "-t", target, "-l", "--", "PARTIAL-INPUT")
deadline = time.monotonic() + 5
while time.monotonic() < deadline:
before_capture = manager._run("capture-pane", "-p", "-t", target)
if "PARTIAL-INPUT" in before_capture:
break
time.sleep(0.05)
assert "PARTIAL-INPUT" in before_capture
control = ControlModeClient(
session,
tmux_command=("tmux", "-L", socket_name),
)
before = control.pane_display(target)
write_terminal_output(
before.tty_path,
terminal_frame(
"flex-auth",
"stable-message",
"m-stable",
cursor_y=before.cursor_y,
pane_height=before.pane_height,
alternate_on=before.alternate_on,
),
)
deadline = time.monotonic() + 5
while time.monotonic() < deadline:
after_capture = manager._run("capture-pane", "-p", "-t", target)
if "#flex-auth: stable-message [m-stable]" in after_capture:
break
time.sleep(0.05)
after = control.pane_display(target)
assert "#flex-auth: stable-message [m-stable]" in after_capture
before_input = next(line for line in before_capture.splitlines() if "PARTIAL-INPUT" in line)
after_lines = after_capture.splitlines()
assert any("PARTIAL-INPUT" in line for line in after_lines), repr(after_capture)
after_input_index = next(
index for index, line in enumerate(after_lines) if "PARTIAL-INPUT" in line
)
assert after_lines[after_input_index] == before_input
assert after_lines[after_input_index - 1] == "#flex-auth: stable-message [m-stable]"
assert (after.cursor_x, after.cursor_y) == (before.cursor_x, before.cursor_y)
finally:
manager._run("kill-server", check=False)