From ae010b3d9bd41db27370a78795e52452b0956e58 Mon Sep 17 00:00:00 2001 From: Claude Date: Fri, 19 Jun 2026 04:38:06 +0000 Subject: [PATCH 1/2] assembly code: harden clipboard copy and voice/text switching Exploratory testing of the `assembly code` TUI surfaced three issues in keypress-driven flows that the snapshot/pilot suites didn't cover: - Ctrl-Y (copy last reply) called pyperclip.copy unguarded, so on a headless/clipboard-less box (where pyperclip raises) a harmless keypress tore down the whole TUI. It also gave no feedback when there was nothing to copy. Extracted the logic into a pure tui_status.copy_note helper that notes the outcome on every press and absorbs PyperclipException. - Ctrl-V to switch from voice to text never cancelled the in-flight mic capture, so the UI showed "Voice off" and the text prompt while listen() kept the mic open in the background. Toggling off now cancels voice, the same as the Escape/Ctrl-C interrupt path. - _capture_voice_turn submitted a captured turn with no re-check, so a turn that finalized in the window between switching to text (or interrupting) and the capture unwinding was submitted behind the user's back. It now re-checks that voice is still active before submitting. Co-Authored-By: Claude Opus 4.8 (1M context) Claude-Session: https://claude.ai/code/session_01FrvC8NrLtFzGHSToC36Zgc --- aai_cli/code_agent/tui.py | 8 ++-- aai_cli/code_agent/tui_status.py | 22 ++++++++++ aai_cli/code_agent/voice_ui.py | 5 ++- tests/test_code_tui_status.py | 28 +++++++++++++ tests/test_code_tui_voice_switch.py | 62 +++++++++++++++++++++++++++++ 5 files changed, 120 insertions(+), 5 deletions(-) create mode 100644 tests/test_code_tui_voice_switch.py diff --git a/aai_cli/code_agent/tui.py b/aai_cli/code_agent/tui.py index 2624f4f..2a04a99 100644 --- a/aai_cli/code_agent/tui.py +++ b/aai_cli/code_agent/tui.py @@ -47,6 +47,7 @@ VOICE_FRAMES, _spinner_text, _status_text, + copy_note, voicebar_markup, ) from aai_cli.code_agent.voice_ui import _VoiceIO, _VoiceLegs @@ -242,12 +243,10 @@ def _finalize_reply(self, text: str) -> None: msg.finalize(text) def action_copy_last(self) -> None: - """Copy the most recent assistant reply to the system clipboard.""" + """Copy the most recent assistant reply to the system clipboard, noting the outcome.""" import pyperclip - if self._last_reply: - pyperclip.copy(self._last_reply) - self._note("(copied last reply to clipboard)") + self._note(copy_note(self._last_reply, pyperclip.copy)) def action_toggle_output(self) -> None: """Ctrl-O: expand/collapse the most recent tool output (a no-op if there's none).""" @@ -318,6 +317,7 @@ def action_toggle_voice(self) -> None: self._refresh_status() self._sync_input_mode() # show/hide the text box vs. the listening affordance if self._voice_paused: + self._voice.cancel() # release the mic now, don't leave a capture running unseen self.notify("Voice off — type your request") elif not self._turn_running(): self.notify("Voice on — listening") diff --git a/aai_cli/code_agent/tui_status.py b/aai_cli/code_agent/tui_status.py index e163ea0..09fd5ba 100644 --- a/aai_cli/code_agent/tui_status.py +++ b/aai_cli/code_agent/tui_status.py @@ -7,11 +7,16 @@ from __future__ import annotations from pathlib import Path +from typing import TYPE_CHECKING +import pyperclip from rich.markup import escape from aai_cli.ui import theme +if TYPE_CHECKING: + from collections.abc import Callable + # Animated meter for the voice bar — a 3-cell block-char pulse (BMP, single-width, no emoji). # Public: both the `code` and `live` TUIs cycle it for their bar animation. VOICE_FRAMES = ("▁▃▅", "▃▅▇", "▅▇▆", "▆▇▅", "▇▅▃", "▅▃▁") # pragma: no mutate @@ -39,6 +44,23 @@ def _spinner_text(elapsed_s: int, frame: str) -> str: return f"{frame} Working… ({elapsed_s}s)" +def copy_note(reply: str, copier: Callable[[str], None]) -> str: + """Copy ``reply`` to the clipboard via ``copier``, returning the transcript note to show. + + Keeps the Ctrl-Y action a one-liner and handles its two non-happy paths so they can't + surprise the user: nothing has been said yet, and a headless/clipboard-less box where + ``pyperclip`` raises (an unhandled raise there would tear down the whole TUI). ``copier`` + is ``pyperclip.copy`` in production, injected so this unit-tests with no real clipboard. + """ + if not reply: + return "(nothing to copy yet)" + try: + copier(reply) + except pyperclip.PyperclipException: + return "(couldn't copy: no clipboard available)" + return "(copied last reply to clipboard)" + + def _abbrev_home(path: Path) -> str: """Render ``path`` with the home directory collapsed to ``~``.""" try: diff --git a/aai_cli/code_agent/voice_ui.py b/aai_cli/code_agent/voice_ui.py index f105fa4..c4b6ad2 100644 --- a/aai_cli/code_agent/voice_ui.py +++ b/aai_cli/code_agent/voice_ui.py @@ -113,7 +113,10 @@ def _capture_voice_turn(self) -> None: self._voice_typed = True self.call_from_thread(self._notice_voice_off, exc.message) return - if transcript: + # Re-check after listen(): the user may have switched to text (Ctrl-V) or interrupted + # (Escape/Ctrl-C) while this capture was blocking, in which case a turn that finalized + # in that window must not be submitted behind their back. + if transcript and self._voice_active(): self.call_from_thread(self._enter_and_submit, transcript) def _notice_voice_off(self, detail: str) -> None: diff --git a/tests/test_code_tui_status.py b/tests/test_code_tui_status.py index fc53dbc..1104f91 100644 --- a/tests/test_code_tui_status.py +++ b/tests/test_code_tui_status.py @@ -8,6 +8,8 @@ from pathlib import Path +import pyperclip + from aai_cli.code_agent import tui_status from aai_cli.ui import theme @@ -51,6 +53,32 @@ def test_voicebar_markup_per_phase_carries_label_meter_accent_and_hint() -> None assert "Speaking" in speaking and "#22c55e" in speaking # green +def test_copy_note_copies_and_confirms() -> None: + # The happy path: the reply is handed to the copier and a confirmation note returned. + copied: list[str] = [] + note = tui_status.copy_note("a reply", copied.append) + assert copied == ["a reply"] + assert "copied" in note + + +def test_copy_note_when_nothing_to_copy() -> None: + # No reply yet: don't touch the clipboard, and tell the user there's nothing to copy. + copied: list[str] = [] + note = tui_status.copy_note("", copied.append) + assert copied == [] # copier never called + assert "nothing to copy" in note + + +def test_copy_note_degrades_when_no_clipboard() -> None: + # A headless/clipboard-less box: pyperclip raises; copy_note must absorb it and return a + # note rather than letting the raise propagate (which would tear down the TUI). + def _boom(_text: str) -> None: + raise pyperclip.PyperclipException("no copy/paste mechanism") + + note = tui_status.copy_note("a reply", _boom) + assert "no clipboard available" in note + + def test_status_text_renders_voice_badge(tmp_path: Path) -> None: # No voice front-end -> no voice badge (the dot glyphs are absent); on/off render the # state so the Ctrl-V toggle shows. (Asserts on the dots, not the word — the tmp_path name diff --git a/tests/test_code_tui_voice_switch.py b/tests/test_code_tui_voice_switch.py new file mode 100644 index 0000000..9687b79 --- /dev/null +++ b/tests/test_code_tui_voice_switch.py @@ -0,0 +1,62 @@ +"""Tests for switching between voice and text mode in the `assembly code` TUI. + +Switching input mode (Ctrl-V) and interrupting (Escape / Ctrl-C) both have to stop an +in-flight microphone capture so it neither keeps the mic open behind the text prompt nor +submits a turn the user no longer wants. These cancel-safety cases are split out of +test_code_tui_voice.py to keep each file under the 500-line gate, reusing that module's +app/voice doubles. +""" + +from __future__ import annotations + +import threading + +import pytest + +from aai_cli.code_agent.tui import CodeAgentApp +from tests.test_code_tui_voice import FakeAgent, FakeVoice, _run, _wait_until + + +def test_toggle_voice_off_cancels_in_flight_capture() -> None: + # Switching to text (Ctrl-V) must release the mic now — cancel the blocking listen() + # rather than leaving a capture running unseen behind the text prompt. + async def go() -> None: + voice = FakeVoice() + app = CodeAgentApp(agent=FakeAgent([]), voice=voice) + app._voice_paused = True # start paused so on_mount doesn't race a capture thread + async with app.run_test(size=(100, 30)) as pilot: + await pilot.pause() + app.action_toggle_voice() # voice on + assert voice.cancels == 0 # turning on never cancels + app.action_toggle_voice() # voice off -> must cancel the in-flight capture + assert voice.cancels == 1 + + _run(go()) + + +def test_capture_after_switching_to_text_is_not_submitted(monkeypatch: pytest.MonkeyPatch) -> None: + # A turn that finalizes in the window between the user pressing Ctrl-V and the capture + # unwinding must NOT be submitted — otherwise a spoken phrase lands as a turn after the + # user already switched to typing. + async def go() -> None: + voice = FakeVoice() + app = CodeAgentApp(agent=FakeAgent([]), voice=voice) + app._voice_paused = True # block the on_mount auto-listen + async with app.run_test(size=(100, 30)) as pilot: + await pilot.pause() + submitted: list[str] = [] + monkeypatch.setattr(app, "_submit", submitted.append) # spy: _enter_and_submit calls it + + def listen() -> str: + voice.listens += 1 + app._voice_paused = True # user switched to text DURING the capture + return "late turn" + + monkeypatch.setattr(voice, "listen", listen) + app._voice_paused = False # active when the capture starts + thread = threading.Thread(target=app._capture_voice_turn) + thread.start() + assert await _wait_until(pilot, lambda: not thread.is_alive()) + assert submitted == [] # the late turn was dropped, not submitted + + _run(go()) From 088ae015a488c0f7f6bd385c4fe22ae24ac15479 Mon Sep 17 00:00:00 2001 From: Claude Date: Fri, 19 Jun 2026 04:51:50 +0000 Subject: [PATCH 2/2] assembly code: add a dim key-legend footer for discoverability MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The code TUI has no Footer widget, so its keyboard shortcuts (copy, voice toggle, expand output, interrupt, quit) were undiscoverable — unlike the live TUI, which carries a hint line. Add a second footer row beneath the status line: a dim, caret-notation legend that lists the shortcuts worth surfacing. The Ctrl-V voice hint is shown only when the session has a voice front-end, and caret notation keeps the legend short enough to fit a narrow terminal. Folded into _status_text as a two-row footer (one #status widget, height 2) so _refresh_status keeps both rows on a mode/voice change and the layout needs no extra docked widget. Regenerated the code TUI snapshots. Co-Authored-By: Claude Opus 4.8 (1M context) Claude-Session: https://claude.ai/code/session_01FrvC8NrLtFzGHSToC36Zgc --- aai_cli/code_agent/tui.py | 9 +- aai_cli/code_agent/tui_status.py | 25 ++- .../test_code_approval_modal.raw | 152 ++++++++--------- .../test_code_approval_modal_benign.raw | 152 ++++++++--------- .../test_code_approval_modal_expanded.raw | 152 ++++++++--------- .../test_code_ask_modal.raw | 155 ++++++++--------- .../test_tui_snapshots/test_code_error.raw | 155 ++++++++--------- .../test_tui_snapshots/test_code_splash.raw | 151 ++++++++--------- .../test_code_status_auto_approve.raw | 151 ++++++++--------- .../test_code_streaming_reply.raw | 153 ++++++++--------- .../test_code_tool_output_collapsed.raw | 157 ++++++++--------- .../test_code_tool_output_expanded.raw | 157 ++++++++--------- .../test_code_transcript.raw | 159 +++++++++--------- .../test_code_voice_listening.raw | 147 ++++++++-------- .../test_code_working_spinner.raw | 153 ++++++++--------- tests/test_code_tui_status.py | 24 +++ 16 files changed, 1051 insertions(+), 1001 deletions(-) diff --git a/aai_cli/code_agent/tui.py b/aai_cli/code_agent/tui.py index 2a04a99..9dd8582 100644 --- a/aai_cli/code_agent/tui.py +++ b/aai_cli/code_agent/tui.py @@ -82,12 +82,11 @@ class CodeAgentApp(_VoiceLegs): #promptmark {{ width: 3; color: {banner.BRAND_HEX}; content-align: center middle; }} #prompt {{ border: none; background: #000000; padding: 0; }} /* Shown in place of the prompt while voice capture is on (Ctrl-V brings the prompt back). */ - #voicebar {{ dock: bottom; height: 3; background: #000000; border: round {banner.BRAND_HEX}; - margin: 1 1; content-align: center middle; display: none; }} + #voicebar {{ dock: bottom; height: 3; background: #000000; border: round {banner.BRAND_HEX}; margin: 1 1; content-align: center middle; display: none; }} /* In normal flow below the 1fr log, so it sits just above the docked prompt bar. */ - #spinner {{ height: 1; background: #000000; padding: 0 2; - color: {banner.BRAND_HEX}; display: none; }} - #status {{ dock: bottom; height: 1; background: #000000; padding: 0 1; }} + #spinner {{ height: 1; background: #000000; padding: 0 2; color: {banner.BRAND_HEX}; display: none; }} + /* Two rows: the mode/cwd/branch/voice line and the dim key-legend below it. */ + #status {{ dock: bottom; height: 2; background: #000000; padding: 0 1; }} """ TITLE = "AssemblyAI Code" # Ctrl-C quits (in addition to Ctrl-Q); the built-in command palette is removed. diff --git a/aai_cli/code_agent/tui_status.py b/aai_cli/code_agent/tui_status.py index 09fd5ba..95fca7a 100644 --- a/aai_cli/code_agent/tui_status.py +++ b/aai_cli/code_agent/tui_status.py @@ -44,6 +44,21 @@ def _spinner_text(elapsed_s: int, frame: str) -> str: return f"{frame} Working… ({elapsed_s}s)" +def keyhints_text(*, voice: bool) -> str: + """The dim key-legend footer for the `code` TUI — the shortcuts worth surfacing. + + The keyboard chords are otherwise undiscoverable (the app has no Footer widget). The + Ctrl-V voice toggle is only listed when the session has a voice front-end. Caret notation + (``^Y``) keeps the legend short enough to fit a narrow terminal; the chords are bold so + they read against the dim labels. + """ + hints = ["[b]^Y[/b] copy"] + if voice: + hints.append("[b]^V[/b] voice") + hints += ["[b]^O[/b] expand", "[b]esc[/b] interrupt", "[b]^C[/b] quit"] + return f"[dim]{' · '.join(hints)}[/dim]" + + def copy_note(reply: str, copier: Callable[[str], None]) -> str: """Copy ``reply`` to the clipboard via ``copier``, returning the transcript note to show. @@ -80,10 +95,12 @@ def _git_branch(start: Path) -> str | None: def _status_text(cwd: Path, *, auto_approve: bool, voice_state: str | None = None) -> str: - """The bottom status line: a mode badge, the working directory, git branch, and voice state. + """The two-row bottom footer: a status line, and a dim key-legend beneath it. - ``voice_state`` is ``"on"``/``"off"`` when the session has a voice front-end (so the - Ctrl-V toggle shows its effect), or ``None`` when voice isn't wired up at all. + Row one is a mode badge, the working directory, the git branch, and voice state; row two + is :func:`keyhints_text`. ``voice_state`` is ``"on"``/``"off"`` when the session has a + voice front-end (so the Ctrl-V toggle shows its effect, and the legend lists it), or + ``None`` when voice isn't wired up at all. """ mode = "auto" if auto_approve else "manual" badge = f"[black on #f59e0b] {mode} [/]" @@ -95,4 +112,4 @@ def _status_text(cwd: Path, *, auto_approve: bool, voice_state: str | None = Non # A filled/hollow dot (BMP glyphs, like the rest of the UI — no double-width emoji). glyph, color = ("●", "#22c55e") if voice_state == "on" else ("○", "#6b7280") parts.append(f"[{color}]{glyph} voice {voice_state}[/]") - return " ".join(parts) + return " ".join(parts) + "\n" + keyhints_text(voice=voice_state is not None) diff --git a/tests/__snapshots__/test_tui_snapshots/test_code_approval_modal.raw b/tests/__snapshots__/test_tui_snapshots/test_code_approval_modal.raw index 9355a4d..aa9e569 100644 --- a/tests/__snapshots__/test_tui_snapshots/test_code_approval_modal.raw +++ b/tests/__snapshots__/test_tui_snapshots/test_code_approval_modal.raw @@ -19,164 +19,164 @@ font-weight: 700; } - .terminal-2623049041-matrix { + .terminal-2084666923-matrix { font-family: Fira Code, monospace; font-size: 20px; line-height: 24.4px; font-variant-east-asian: full-width; } - .terminal-2623049041-title { + .terminal-2084666923-title { font-size: 18px; font-weight: bold; font-family: arial; } - .terminal-2623049041-r1 { fill: #e0e0e0 } -.terminal-2623049041-r2 { fill: #c5c8c6 } -.terminal-2623049041-r3 { fill: #614fd2;font-weight: bold } -.terminal-2623049041-r4 { fill: #939393 } -.terminal-2623049041-r5 { fill: #614fd2 } -.terminal-2623049041-r6 { fill: #f59e0b } -.terminal-2623049041-r7 { fill: #f04438;font-weight: bold } -.terminal-2623049041-r8 { fill: #e0e0e0;font-weight: bold } -.terminal-2623049041-r9 { fill: #22c55e;font-weight: bold } -.terminal-2623049041-r10 { fill: #000000 } + .terminal-2084666923-r1 { fill: #e0e0e0 } +.terminal-2084666923-r2 { fill: #c5c8c6 } +.terminal-2084666923-r3 { fill: #614fd2;font-weight: bold } +.terminal-2084666923-r4 { fill: #939393 } +.terminal-2084666923-r5 { fill: #614fd2 } +.terminal-2084666923-r6 { fill: #f59e0b } +.terminal-2084666923-r7 { fill: #f04438;font-weight: bold } +.terminal-2084666923-r8 { fill: #e0e0e0;font-weight: bold } +.terminal-2084666923-r9 { fill: #22c55e;font-weight: bold } +.terminal-2084666923-r10 { fill: #939393;font-weight: bold } - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - AssemblyAI Code + AssemblyAI Code - - - - - █████╗  ███████╗ ███████╗ ███████╗ ███╗   ███╗ ██████╗  ██╗      ██╗   ██╗ -██╔══██╗ ██╔════╝ ██╔════╝ ██╔════╝ ████╗ ████║ ██╔══██╗ ██║      ╚██╗ ██╔╝ -███████║ ███████╗ ███████╗ █████╗   ██╔████╔██║ ██████╔╝ ██║       ╚████╔╝  -██╔══██║ ╚════██║ ╚════██║ ██╔══╝   ██║╚██╔╝██║ ██╔══██╗ ██║        ╚██╔╝   -██║  ██║ ███████║ ███████║ ███████╗ ██║ ╚═╝ ██║ ██████╔╝ ███████╗    ██║    -╚═╝  ╚═╝ ╚══════╝ ╚══════╝ ╚══════╝ ╚═╝     ╚═╝ ╚═════╝  ╚══════╝    ╚═╝    -v9.9.9 - -Thread: default - -Ready to code! What would you like to build? -Tip: approve tools as they run, or pass --auto to skip the prompts. - - - - - - - - - - - -╭────────────────────────────────────────────────────────────────────────────────────────────────╮ -⚠ This command deletes files recursively/forcibly. -Run tool execute?  rm -rf build/ -y approve   a auto-approve   n reject   e expand -╰────────────────────────────────────────────────────────────────────────────────────────────────╯ - manual ~/demo↗ main + + + + + █████╗  ███████╗ ███████╗ ███████╗ ███╗   ███╗ ██████╗  ██╗      ██╗   ██╗ +██╔══██╗ ██╔════╝ ██╔════╝ ██╔════╝ ████╗ ████║ ██╔══██╗ ██║      ╚██╗ ██╔╝ +███████║ ███████╗ ███████╗ █████╗   ██╔████╔██║ ██████╔╝ ██║       ╚████╔╝  +██╔══██║ ╚════██║ ╚════██║ ██╔══╝   ██║╚██╔╝██║ ██╔══██╗ ██║        ╚██╔╝   +██║  ██║ ███████║ ███████║ ███████╗ ██║ ╚═╝ ██║ ██████╔╝ ███████╗    ██║    +╚═╝  ╚═╝ ╚══════╝ ╚══════╝ ╚══════╝ ╚═╝     ╚═╝ ╚═════╝  ╚══════╝    ╚═╝    +v9.9.9 + +Thread: default + +Ready to code! What would you like to build? +Tip: approve tools as they run, or pass --auto to skip the prompts. + + + + + + + + + + + +╭────────────────────────────────────────────────────────────────────────────────────────────────╮ +⚠ This command deletes files recursively/forcibly. +Run tool execute?  rm -rf build/ +y approve   a auto-approve   n reject   e expand +╰────────────────────────────────────────────────────────────────────────────────────────────────╯ +^Y copy · ^O expand · esc interrupt · ^C quit diff --git a/tests/__snapshots__/test_tui_snapshots/test_code_approval_modal_benign.raw b/tests/__snapshots__/test_tui_snapshots/test_code_approval_modal_benign.raw index 673aebf..9ebc31b 100644 --- a/tests/__snapshots__/test_tui_snapshots/test_code_approval_modal_benign.raw +++ b/tests/__snapshots__/test_tui_snapshots/test_code_approval_modal_benign.raw @@ -19,164 +19,164 @@ font-weight: 700; } - .terminal-901522975-matrix { + .terminal-1417549561-matrix { font-family: Fira Code, monospace; font-size: 20px; line-height: 24.4px; font-variant-east-asian: full-width; } - .terminal-901522975-title { + .terminal-1417549561-title { font-size: 18px; font-weight: bold; font-family: arial; } - .terminal-901522975-r1 { fill: #e0e0e0 } -.terminal-901522975-r2 { fill: #c5c8c6 } -.terminal-901522975-r3 { fill: #614fd2;font-weight: bold } -.terminal-901522975-r4 { fill: #939393 } -.terminal-901522975-r5 { fill: #614fd2 } -.terminal-901522975-r6 { fill: #f59e0b } -.terminal-901522975-r7 { fill: #e0e0e0;font-weight: bold } -.terminal-901522975-r8 { fill: #22c55e;font-weight: bold } -.terminal-901522975-r9 { fill: #f04438;font-weight: bold } -.terminal-901522975-r10 { fill: #000000 } + .terminal-1417549561-r1 { fill: #e0e0e0 } +.terminal-1417549561-r2 { fill: #c5c8c6 } +.terminal-1417549561-r3 { fill: #614fd2;font-weight: bold } +.terminal-1417549561-r4 { fill: #939393 } +.terminal-1417549561-r5 { fill: #614fd2 } +.terminal-1417549561-r6 { fill: #f59e0b } +.terminal-1417549561-r7 { fill: #e0e0e0;font-weight: bold } +.terminal-1417549561-r8 { fill: #22c55e;font-weight: bold } +.terminal-1417549561-r9 { fill: #f04438;font-weight: bold } +.terminal-1417549561-r10 { fill: #939393;font-weight: bold } - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - AssemblyAI Code + AssemblyAI Code - - - - - █████╗  ███████╗ ███████╗ ███████╗ ███╗   ███╗ ██████╗  ██╗      ██╗   ██╗ -██╔══██╗ ██╔════╝ ██╔════╝ ██╔════╝ ████╗ ████║ ██╔══██╗ ██║      ╚██╗ ██╔╝ -███████║ ███████╗ ███████╗ █████╗   ██╔████╔██║ ██████╔╝ ██║       ╚████╔╝  -██╔══██║ ╚════██║ ╚════██║ ██╔══╝   ██║╚██╔╝██║ ██╔══██╗ ██║        ╚██╔╝   -██║  ██║ ███████║ ███████║ ███████╗ ██║ ╚═╝ ██║ ██████╔╝ ███████╗    ██║    -╚═╝  ╚═╝ ╚══════╝ ╚══════╝ ╚══════╝ ╚═╝     ╚═╝ ╚═════╝  ╚══════╝    ╚═╝    -v9.9.9 - -Thread: default - -Ready to code! What would you like to build? -Tip: approve tools as they run, or pass --auto to skip the prompts. - - - - - - - - - - - - -╭────────────────────────────────────────────────────────────────────────────────────────────────╮ -Run tool execute?  ls -la -y approve   a auto-approve   n reject   e expand -╰────────────────────────────────────────────────────────────────────────────────────────────────╯ - manual ~/demo↗ main + + + + + █████╗  ███████╗ ███████╗ ███████╗ ███╗   ███╗ ██████╗  ██╗      ██╗   ██╗ +██╔══██╗ ██╔════╝ ██╔════╝ ██╔════╝ ████╗ ████║ ██╔══██╗ ██║      ╚██╗ ██╔╝ +███████║ ███████╗ ███████╗ █████╗   ██╔████╔██║ ██████╔╝ ██║       ╚████╔╝  +██╔══██║ ╚════██║ ╚════██║ ██╔══╝   ██║╚██╔╝██║ ██╔══██╗ ██║        ╚██╔╝   +██║  ██║ ███████║ ███████║ ███████╗ ██║ ╚═╝ ██║ ██████╔╝ ███████╗    ██║    +╚═╝  ╚═╝ ╚══════╝ ╚══════╝ ╚══════╝ ╚═╝     ╚═╝ ╚═════╝  ╚══════╝    ╚═╝    +v9.9.9 + +Thread: default + +Ready to code! What would you like to build? +Tip: approve tools as they run, or pass --auto to skip the prompts. + + + + + + + + + + + + +╭────────────────────────────────────────────────────────────────────────────────────────────────╮ +Run tool execute?  ls -la +y approve   a auto-approve   n reject   e expand +╰────────────────────────────────────────────────────────────────────────────────────────────────╯ +^Y copy · ^O expand · esc interrupt · ^C quit diff --git a/tests/__snapshots__/test_tui_snapshots/test_code_approval_modal_expanded.raw b/tests/__snapshots__/test_tui_snapshots/test_code_approval_modal_expanded.raw index f15782d..1754ee9 100644 --- a/tests/__snapshots__/test_tui_snapshots/test_code_approval_modal_expanded.raw +++ b/tests/__snapshots__/test_tui_snapshots/test_code_approval_modal_expanded.raw @@ -19,164 +19,164 @@ font-weight: 700; } - .terminal-1367203125-matrix { + .terminal-3998338575-matrix { font-family: Fira Code, monospace; font-size: 20px; line-height: 24.4px; font-variant-east-asian: full-width; } - .terminal-1367203125-title { + .terminal-3998338575-title { font-size: 18px; font-weight: bold; font-family: arial; } - .terminal-1367203125-r1 { fill: #e0e0e0 } -.terminal-1367203125-r2 { fill: #c5c8c6 } -.terminal-1367203125-r3 { fill: #614fd2;font-weight: bold } -.terminal-1367203125-r4 { fill: #939393 } -.terminal-1367203125-r5 { fill: #614fd2 } -.terminal-1367203125-r6 { fill: #f59e0b } -.terminal-1367203125-r7 { fill: #e0e0e0;font-weight: bold } -.terminal-1367203125-r8 { fill: #22c55e;font-weight: bold } -.terminal-1367203125-r9 { fill: #f04438;font-weight: bold } -.terminal-1367203125-r10 { fill: #000000 } + .terminal-3998338575-r1 { fill: #e0e0e0 } +.terminal-3998338575-r2 { fill: #c5c8c6 } +.terminal-3998338575-r3 { fill: #614fd2;font-weight: bold } +.terminal-3998338575-r4 { fill: #939393 } +.terminal-3998338575-r5 { fill: #614fd2 } +.terminal-3998338575-r6 { fill: #f59e0b } +.terminal-3998338575-r7 { fill: #e0e0e0;font-weight: bold } +.terminal-3998338575-r8 { fill: #22c55e;font-weight: bold } +.terminal-3998338575-r9 { fill: #f04438;font-weight: bold } +.terminal-3998338575-r10 { fill: #939393;font-weight: bold } - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - AssemblyAI Code + AssemblyAI Code - - - - - █████╗  ███████╗ ███████╗ ███████╗ ███╗   ███╗ ██████╗  ██╗      ██╗   ██╗ -██╔══██╗ ██╔════╝ ██╔════╝ ██╔════╝ ████╗ ████║ ██╔══██╗ ██║      ╚██╗ ██╔╝ -███████║ ███████╗ ███████╗ █████╗   ██╔████╔██║ ██████╔╝ ██║       ╚████╔╝  -██╔══██║ ╚════██║ ╚════██║ ██╔══╝   ██║╚██╔╝██║ ██╔══██╗ ██║        ╚██╔╝   -██║  ██║ ███████║ ███████║ ███████╗ ██║ ╚═╝ ██║ ██████╔╝ ███████╗    ██║    -╚═╝  ╚═╝ ╚══════╝ ╚══════╝ ╚══════╝ ╚═╝     ╚═╝ ╚═════╝  ╚══════╝    ╚═╝    -v9.9.9 - -Thread: default - -Ready to code! What would you like to build? -Tip: approve tools as they run, or pass --auto to skip the prompts. - - - - - - - - - - -╭────────────────────────────────────────────────────────────────────────────────────────────────╮ -Run tool write_file?  file_path=app.py -content=PORT = 8080 -DEBUG = 1 -y approve   a auto-approve   n reject   e expand -╰────────────────────────────────────────────────────────────────────────────────────────────────╯ - manual ~/demo↗ main + + + + + █████╗  ███████╗ ███████╗ ███████╗ ███╗   ███╗ ██████╗  ██╗      ██╗   ██╗ +██╔══██╗ ██╔════╝ ██╔════╝ ██╔════╝ ████╗ ████║ ██╔══██╗ ██║      ╚██╗ ██╔╝ +███████║ ███████╗ ███████╗ █████╗   ██╔████╔██║ ██████╔╝ ██║       ╚████╔╝  +██╔══██║ ╚════██║ ╚════██║ ██╔══╝   ██║╚██╔╝██║ ██╔══██╗ ██║        ╚██╔╝   +██║  ██║ ███████║ ███████║ ███████╗ ██║ ╚═╝ ██║ ██████╔╝ ███████╗    ██║    +╚═╝  ╚═╝ ╚══════╝ ╚══════╝ ╚══════╝ ╚═╝     ╚═╝ ╚═════╝  ╚══════╝    ╚═╝    +v9.9.9 + +Thread: default + +Ready to code! What would you like to build? +Tip: approve tools as they run, or pass --auto to skip the prompts. + + + + + + + + + + +╭────────────────────────────────────────────────────────────────────────────────────────────────╮ +Run tool write_file?  file_path=app.py +content=PORT = 8080 +DEBUG = 1 +y approve   a auto-approve   n reject   e expand +╰────────────────────────────────────────────────────────────────────────────────────────────────╯ +^Y copy · ^O expand · esc interrupt · ^C quit diff --git a/tests/__snapshots__/test_tui_snapshots/test_code_ask_modal.raw b/tests/__snapshots__/test_tui_snapshots/test_code_ask_modal.raw index 02bbd4f..3eed1ac 100644 --- a/tests/__snapshots__/test_tui_snapshots/test_code_ask_modal.raw +++ b/tests/__snapshots__/test_tui_snapshots/test_code_ask_modal.raw @@ -19,165 +19,166 @@ font-weight: 700; } - .terminal-1386297441-matrix { + .terminal-4063177019-matrix { font-family: Fira Code, monospace; font-size: 20px; line-height: 24.4px; font-variant-east-asian: full-width; } - .terminal-1386297441-title { + .terminal-4063177019-title { font-size: 18px; font-weight: bold; font-family: arial; } - .terminal-1386297441-r1 { fill: #e0e0e0 } -.terminal-1386297441-r2 { fill: #c5c8c6 } -.terminal-1386297441-r3 { fill: #614fd2;font-weight: bold } -.terminal-1386297441-r4 { fill: #939393 } -.terminal-1386297441-r5 { fill: #614fd2 } -.terminal-1386297441-r6 { fill: #3a3f55 } -.terminal-1386297441-r7 { fill: #e0e0e0;font-weight: bold } -.terminal-1386297441-r8 { fill: #000000 } -.terminal-1386297441-r9 { fill: #0178d4 } -.terminal-1386297441-r10 { fill: #121212 } -.terminal-1386297441-r11 { fill: #797979 } + .terminal-4063177019-r1 { fill: #e0e0e0 } +.terminal-4063177019-r2 { fill: #c5c8c6 } +.terminal-4063177019-r3 { fill: #614fd2;font-weight: bold } +.terminal-4063177019-r4 { fill: #939393 } +.terminal-4063177019-r5 { fill: #614fd2 } +.terminal-4063177019-r6 { fill: #3a3f55 } +.terminal-4063177019-r7 { fill: #e0e0e0;font-weight: bold } +.terminal-4063177019-r8 { fill: #000000 } +.terminal-4063177019-r9 { fill: #0178d4 } +.terminal-4063177019-r10 { fill: #121212 } +.terminal-4063177019-r11 { fill: #797979 } +.terminal-4063177019-r12 { fill: #939393;font-weight: bold } - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - AssemblyAI Code + AssemblyAI Code - - - - - █████╗  ███████╗ ███████╗ ███████╗ ███╗   ███╗ ██████╗  ██╗      ██╗   ██╗ -██╔══██╗ ██╔════╝ ██╔════╝ ██╔════╝ ████╗ ████║ ██╔══██╗ ██║      ╚██╗ ██╔╝ -███████║ ███████╗ ███████╗ █████╗   ██╔████╔██║ ██████╔╝ ██║       ╚████╔╝  -██╔══██║ ╚════██║ ╚════██║ ██╔══╝   ██║╚██╔╝██║ ██╔══██╗ ██║        ╚██╔╝   -██║  ██║ ███████║ ███████║ ███████╗ ██║ ╚═╝ ██║ ██████╔╝ ███████╗    ██║    -╚═╝  ╚═╝ ╚══════╝ ╚══════╝ ╚══════╝ ╚═╝     ╚═╝ ╚═════╝  ╚══════╝    ╚═╝    -v9.9.9 - -Thread: default - -Ready to code! What would you like to build? -Tip: approve tools as they run, or pass --auto to skip the prompts. - - - - - - - - - - -╭────────────────────────────────────────────────────────────────────────────────────────────────╮ -The agent asks: Which port should the dev server use? -▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ -Type your answer and press Enter… -▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ -╰────────────────────────────────────────────────────────────────────────────────────────────────╯ - manual ~/demo↗ main + + + + + █████╗  ███████╗ ███████╗ ███████╗ ███╗   ███╗ ██████╗  ██╗      ██╗   ██╗ +██╔══██╗ ██╔════╝ ██╔════╝ ██╔════╝ ████╗ ████║ ██╔══██╗ ██║      ╚██╗ ██╔╝ +███████║ ███████╗ ███████╗ █████╗   ██╔████╔██║ ██████╔╝ ██║       ╚████╔╝  +██╔══██║ ╚════██║ ╚════██║ ██╔══╝   ██║╚██╔╝██║ ██╔══██╗ ██║        ╚██╔╝   +██║  ██║ ███████║ ███████║ ███████╗ ██║ ╚═╝ ██║ ██████╔╝ ███████╗    ██║    +╚═╝  ╚═╝ ╚══════╝ ╚══════╝ ╚══════╝ ╚═╝     ╚═╝ ╚═════╝  ╚══════╝    ╚═╝    +v9.9.9 + +Thread: default + +Ready to code! What would you like to build? +Tip: approve tools as they run, or pass --auto to skip the prompts. + + + + + + + + + + +╭────────────────────────────────────────────────────────────────────────────────────────────────╮ +The agent asks: Which port should the dev server use? +▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ +Type your answer and press Enter… +▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ +╰────────────────────────────────────────────────────────────────────────────────────────────────╯ +^Y copy · ^O expand · esc interrupt · ^C quit diff --git a/tests/__snapshots__/test_tui_snapshots/test_code_error.raw b/tests/__snapshots__/test_tui_snapshots/test_code_error.raw index bb805a7..5a40a2d 100644 --- a/tests/__snapshots__/test_tui_snapshots/test_code_error.raw +++ b/tests/__snapshots__/test_tui_snapshots/test_code_error.raw @@ -19,165 +19,166 @@ font-weight: 700; } - .terminal-1956613797-matrix { + .terminal-2239750680-matrix { font-family: Fira Code, monospace; font-size: 20px; line-height: 24.4px; font-variant-east-asian: full-width; } - .terminal-1956613797-title { + .terminal-2239750680-title { font-size: 18px; font-weight: bold; font-family: arial; } - .terminal-1956613797-r1 { fill: #c5c8c6 } -.terminal-1956613797-r2 { fill: #614fd2;font-weight: bold } -.terminal-1956613797-r3 { fill: #939393 } -.terminal-1956613797-r4 { fill: #e0e0e0 } -.terminal-1956613797-r5 { fill: #614fd2 } -.terminal-1956613797-r6 { fill: #38bdf8;font-weight: bold } -.terminal-1956613797-r7 { fill: #f04438 } -.terminal-1956613797-r8 { fill: #3a3f55 } -.terminal-1956613797-r9 { fill: #121212 } -.terminal-1956613797-r10 { fill: #676767 } -.terminal-1956613797-r11 { fill: #000000 } + .terminal-2239750680-r1 { fill: #c5c8c6 } +.terminal-2239750680-r2 { fill: #614fd2;font-weight: bold } +.terminal-2239750680-r3 { fill: #939393 } +.terminal-2239750680-r4 { fill: #e0e0e0 } +.terminal-2239750680-r5 { fill: #614fd2 } +.terminal-2239750680-r6 { fill: #38bdf8;font-weight: bold } +.terminal-2239750680-r7 { fill: #f04438 } +.terminal-2239750680-r8 { fill: #3a3f55 } +.terminal-2239750680-r9 { fill: #121212 } +.terminal-2239750680-r10 { fill: #676767 } +.terminal-2239750680-r11 { fill: #000000 } +.terminal-2239750680-r12 { fill: #939393;font-weight: bold } - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - AssemblyAI Code + AssemblyAI Code - - - - - █████╗  ███████╗ ███████╗ ███████╗ ███╗   ███╗ ██████╗  ██╗      ██╗   ██╗ -██╔══██╗ ██╔════╝ ██╔════╝ ██╔════╝ ████╗ ████║ ██╔══██╗ ██║      ╚██╗ ██╔╝ -███████║ ███████╗ ███████╗ █████╗   ██╔████╔██║ ██████╔╝ ██║       ╚████╔╝  -██╔══██║ ╚════██║ ╚════██║ ██╔══╝   ██║╚██╔╝██║ ██╔══██╗ ██║        ╚██╔╝   -██║  ██║ ███████║ ███████║ ███████╗ ██║ ╚═╝ ██║ ██████╔╝ ███████╗    ██║    -╚═╝  ╚═╝ ╚══════╝ ╚══════╝ ╚══════╝ ╚═╝     ╚═╝ ╚═════╝  ╚══════╝    ╚═╝    -v9.9.9 - -Thread: default - -Ready to code! What would you like to build? -Tip: approve tools as they run, or pass --auto to skip the prompts. - -» deploy to prod -✗ gateway unreachable: connection refused - - - - - - - - - - -╭────────────────────────────────────────────────────────────────────────────────────────────────╮ ->Ask the agent to build something… -╰────────────────────────────────────────────────────────────────────────────────────────────────╯ - manual ~/demo↗ main + + + + + █████╗  ███████╗ ███████╗ ███████╗ ███╗   ███╗ ██████╗  ██╗      ██╗   ██╗ +██╔══██╗ ██╔════╝ ██╔════╝ ██╔════╝ ████╗ ████║ ██╔══██╗ ██║      ╚██╗ ██╔╝ +███████║ ███████╗ ███████╗ █████╗   ██╔████╔██║ ██████╔╝ ██║       ╚████╔╝  +██╔══██║ ╚════██║ ╚════██║ ██╔══╝   ██║╚██╔╝██║ ██╔══██╗ ██║        ╚██╔╝   +██║  ██║ ███████║ ███████║ ███████╗ ██║ ╚═╝ ██║ ██████╔╝ ███████╗    ██║    +╚═╝  ╚═╝ ╚══════╝ ╚══════╝ ╚══════╝ ╚═╝     ╚═╝ ╚═════╝  ╚══════╝    ╚═╝    +v9.9.9 + +Thread: default + +Ready to code! What would you like to build? +Tip: approve tools as they run, or pass --auto to skip the prompts. + +» deploy to prod +✗ gateway unreachable: connection refused + + + + + + + + + + +╭────────────────────────────────────────────────────────────────────────────────────────────────╮ +>Ask the agent to build something… + manual ~/demo↗ main +^Y copy · ^O expand · esc interrupt · ^C quit diff --git a/tests/__snapshots__/test_tui_snapshots/test_code_splash.raw b/tests/__snapshots__/test_tui_snapshots/test_code_splash.raw index 770b28c..b9553b2 100644 --- a/tests/__snapshots__/test_tui_snapshots/test_code_splash.raw +++ b/tests/__snapshots__/test_tui_snapshots/test_code_splash.raw @@ -19,163 +19,164 @@ font-weight: 700; } - .terminal-2744299105-matrix { + .terminal-189530595-matrix { font-family: Fira Code, monospace; font-size: 20px; line-height: 24.4px; font-variant-east-asian: full-width; } - .terminal-2744299105-title { + .terminal-189530595-title { font-size: 18px; font-weight: bold; font-family: arial; } - .terminal-2744299105-r1 { fill: #c5c8c6 } -.terminal-2744299105-r2 { fill: #614fd2;font-weight: bold } -.terminal-2744299105-r3 { fill: #939393 } -.terminal-2744299105-r4 { fill: #e0e0e0 } -.terminal-2744299105-r5 { fill: #614fd2 } -.terminal-2744299105-r6 { fill: #3a3f55 } -.terminal-2744299105-r7 { fill: #121212 } -.terminal-2744299105-r8 { fill: #676767 } -.terminal-2744299105-r9 { fill: #000000 } + .terminal-189530595-r1 { fill: #c5c8c6 } +.terminal-189530595-r2 { fill: #614fd2;font-weight: bold } +.terminal-189530595-r3 { fill: #939393 } +.terminal-189530595-r4 { fill: #e0e0e0 } +.terminal-189530595-r5 { fill: #614fd2 } +.terminal-189530595-r6 { fill: #3a3f55 } +.terminal-189530595-r7 { fill: #121212 } +.terminal-189530595-r8 { fill: #676767 } +.terminal-189530595-r9 { fill: #000000 } +.terminal-189530595-r10 { fill: #939393;font-weight: bold } - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - AssemblyAI Code + AssemblyAI Code - - - - - █████╗  ███████╗ ███████╗ ███████╗ ███╗   ███╗ ██████╗  ██╗      ██╗   ██╗ -██╔══██╗ ██╔════╝ ██╔════╝ ██╔════╝ ████╗ ████║ ██╔══██╗ ██║      ╚██╗ ██╔╝ -███████║ ███████╗ ███████╗ █████╗   ██╔████╔██║ ██████╔╝ ██║       ╚████╔╝  -██╔══██║ ╚════██║ ╚════██║ ██╔══╝   ██║╚██╔╝██║ ██╔══██╗ ██║        ╚██╔╝   -██║  ██║ ███████║ ███████║ ███████╗ ██║ ╚═╝ ██║ ██████╔╝ ███████╗    ██║    -╚═╝  ╚═╝ ╚══════╝ ╚══════╝ ╚══════╝ ╚═╝     ╚═╝ ╚═════╝  ╚══════╝    ╚═╝    -v9.9.9 - -Thread: default - -Ready to code! What would you like to build? -Tip: approve tools as they run, or pass --auto to skip the prompts. - - - - - - - - - - - - - -╭────────────────────────────────────────────────────────────────────────────────────────────────╮ ->Ask the agent to build something… -╰────────────────────────────────────────────────────────────────────────────────────────────────╯ - manual ~/demo↗ main + + + + + █████╗  ███████╗ ███████╗ ███████╗ ███╗   ███╗ ██████╗  ██╗      ██╗   ██╗ +██╔══██╗ ██╔════╝ ██╔════╝ ██╔════╝ ████╗ ████║ ██╔══██╗ ██║      ╚██╗ ██╔╝ +███████║ ███████╗ ███████╗ █████╗   ██╔████╔██║ ██████╔╝ ██║       ╚████╔╝  +██╔══██║ ╚════██║ ╚════██║ ██╔══╝   ██║╚██╔╝██║ ██╔══██╗ ██║        ╚██╔╝   +██║  ██║ ███████║ ███████║ ███████╗ ██║ ╚═╝ ██║ ██████╔╝ ███████╗    ██║    +╚═╝  ╚═╝ ╚══════╝ ╚══════╝ ╚══════╝ ╚═╝     ╚═╝ ╚═════╝  ╚══════╝    ╚═╝    +v9.9.9 + +Thread: default + +Ready to code! What would you like to build? +Tip: approve tools as they run, or pass --auto to skip the prompts. + + + + + + + + + + + + + +╭────────────────────────────────────────────────────────────────────────────────────────────────╮ +>Ask the agent to build something… + manual ~/demo↗ main +^Y copy · ^O expand · esc interrupt · ^C quit diff --git a/tests/__snapshots__/test_tui_snapshots/test_code_status_auto_approve.raw b/tests/__snapshots__/test_tui_snapshots/test_code_status_auto_approve.raw index 71d048f..3932905 100644 --- a/tests/__snapshots__/test_tui_snapshots/test_code_status_auto_approve.raw +++ b/tests/__snapshots__/test_tui_snapshots/test_code_status_auto_approve.raw @@ -19,163 +19,164 @@ font-weight: 700; } - .terminal-2985930204-matrix { + .terminal-3300524382-matrix { font-family: Fira Code, monospace; font-size: 20px; line-height: 24.4px; font-variant-east-asian: full-width; } - .terminal-2985930204-title { + .terminal-3300524382-title { font-size: 18px; font-weight: bold; font-family: arial; } - .terminal-2985930204-r1 { fill: #c5c8c6 } -.terminal-2985930204-r2 { fill: #614fd2;font-weight: bold } -.terminal-2985930204-r3 { fill: #939393 } -.terminal-2985930204-r4 { fill: #e0e0e0 } -.terminal-2985930204-r5 { fill: #614fd2 } -.terminal-2985930204-r6 { fill: #3a3f55 } -.terminal-2985930204-r7 { fill: #121212 } -.terminal-2985930204-r8 { fill: #676767 } -.terminal-2985930204-r9 { fill: #000000 } + .terminal-3300524382-r1 { fill: #c5c8c6 } +.terminal-3300524382-r2 { fill: #614fd2;font-weight: bold } +.terminal-3300524382-r3 { fill: #939393 } +.terminal-3300524382-r4 { fill: #e0e0e0 } +.terminal-3300524382-r5 { fill: #614fd2 } +.terminal-3300524382-r6 { fill: #3a3f55 } +.terminal-3300524382-r7 { fill: #121212 } +.terminal-3300524382-r8 { fill: #676767 } +.terminal-3300524382-r9 { fill: #000000 } +.terminal-3300524382-r10 { fill: #939393;font-weight: bold } - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - AssemblyAI Code + AssemblyAI Code - - - - - █████╗  ███████╗ ███████╗ ███████╗ ███╗   ███╗ ██████╗  ██╗      ██╗   ██╗ -██╔══██╗ ██╔════╝ ██╔════╝ ██╔════╝ ████╗ ████║ ██╔══██╗ ██║      ╚██╗ ██╔╝ -███████║ ███████╗ ███████╗ █████╗   ██╔████╔██║ ██████╔╝ ██║       ╚████╔╝  -██╔══██║ ╚════██║ ╚════██║ ██╔══╝   ██║╚██╔╝██║ ██╔══██╗ ██║        ╚██╔╝   -██║  ██║ ███████║ ███████║ ███████╗ ██║ ╚═╝ ██║ ██████╔╝ ███████╗    ██║    -╚═╝  ╚═╝ ╚══════╝ ╚══════╝ ╚══════╝ ╚═╝     ╚═╝ ╚═════╝  ╚══════╝    ╚═╝    -v9.9.9 - -Thread: default - -Ready to code! What would you like to build? -Tip: approve tools as they run, or pass --auto to skip the prompts. - - - - - - - - - - - - - -╭────────────────────────────────────────────────────────────────────────────────────────────────╮ ->Ask the agent to build something… -╰────────────────────────────────────────────────────────────────────────────────────────────────╯ - auto ~/demo↗ main + + + + + █████╗  ███████╗ ███████╗ ███████╗ ███╗   ███╗ ██████╗  ██╗      ██╗   ██╗ +██╔══██╗ ██╔════╝ ██╔════╝ ██╔════╝ ████╗ ████║ ██╔══██╗ ██║      ╚██╗ ██╔╝ +███████║ ███████╗ ███████╗ █████╗   ██╔████╔██║ ██████╔╝ ██║       ╚████╔╝  +██╔══██║ ╚════██║ ╚════██║ ██╔══╝   ██║╚██╔╝██║ ██╔══██╗ ██║        ╚██╔╝   +██║  ██║ ███████║ ███████║ ███████╗ ██║ ╚═╝ ██║ ██████╔╝ ███████╗    ██║    +╚═╝  ╚═╝ ╚══════╝ ╚══════╝ ╚══════╝ ╚═╝     ╚═╝ ╚═════╝  ╚══════╝    ╚═╝    +v9.9.9 + +Thread: default + +Ready to code! What would you like to build? +Tip: approve tools as they run, or pass --auto to skip the prompts. + + + + + + + + + + + + + +╭────────────────────────────────────────────────────────────────────────────────────────────────╮ +>Ask the agent to build something… + auto ~/demo↗ main +^Y copy · ^O expand · esc interrupt · ^C quit diff --git a/tests/__snapshots__/test_tui_snapshots/test_code_streaming_reply.raw b/tests/__snapshots__/test_tui_snapshots/test_code_streaming_reply.raw index 95ca020..b3ae8b1 100644 --- a/tests/__snapshots__/test_tui_snapshots/test_code_streaming_reply.raw +++ b/tests/__snapshots__/test_tui_snapshots/test_code_streaming_reply.raw @@ -19,164 +19,165 @@ font-weight: 700; } - .terminal-773362532-matrix { + .terminal-730392279-matrix { font-family: Fira Code, monospace; font-size: 20px; line-height: 24.4px; font-variant-east-asian: full-width; } - .terminal-773362532-title { + .terminal-730392279-title { font-size: 18px; font-weight: bold; font-family: arial; } - .terminal-773362532-r1 { fill: #c5c8c6 } -.terminal-773362532-r2 { fill: #614fd2;font-weight: bold } -.terminal-773362532-r3 { fill: #939393 } -.terminal-773362532-r4 { fill: #e0e0e0 } -.terminal-773362532-r5 { fill: #614fd2 } -.terminal-773362532-r6 { fill: #38bdf8;font-weight: bold } -.terminal-773362532-r7 { fill: #3a3f55 } -.terminal-773362532-r8 { fill: #121212 } -.terminal-773362532-r9 { fill: #676767 } -.terminal-773362532-r10 { fill: #000000 } + .terminal-730392279-r1 { fill: #c5c8c6 } +.terminal-730392279-r2 { fill: #614fd2;font-weight: bold } +.terminal-730392279-r3 { fill: #939393 } +.terminal-730392279-r4 { fill: #e0e0e0 } +.terminal-730392279-r5 { fill: #614fd2 } +.terminal-730392279-r6 { fill: #38bdf8;font-weight: bold } +.terminal-730392279-r7 { fill: #3a3f55 } +.terminal-730392279-r8 { fill: #121212 } +.terminal-730392279-r9 { fill: #676767 } +.terminal-730392279-r10 { fill: #000000 } +.terminal-730392279-r11 { fill: #939393;font-weight: bold } - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - AssemblyAI Code + AssemblyAI Code - - - - - █████╗  ███████╗ ███████╗ ███████╗ ███╗   ███╗ ██████╗  ██╗      ██╗   ██╗ -██╔══██╗ ██╔════╝ ██╔════╝ ██╔════╝ ████╗ ████║ ██╔══██╗ ██║      ╚██╗ ██╔╝ -███████║ ███████╗ ███████╗ █████╗   ██╔████╔██║ ██████╔╝ ██║       ╚████╔╝  -██╔══██║ ╚════██║ ╚════██║ ██╔══╝   ██║╚██╔╝██║ ██╔══██╗ ██║        ╚██╔╝   -██║  ██║ ███████║ ███████║ ███████╗ ██║ ╚═╝ ██║ ██████╔╝ ███████╗    ██║    -╚═╝  ╚═╝ ╚══════╝ ╚══════╝ ╚══════╝ ╚═╝     ╚═╝ ╚═════╝  ╚══════╝    ╚═╝    -v9.9.9 - -Thread: default - -Ready to code! What would you like to build? -Tip: approve tools as they run, or pass --auto to skip the prompts. - -» explain the plan -Here's the plan. First **scaffold** the project, then wire up the tests. - - - - - - - - - - -╭────────────────────────────────────────────────────────────────────────────────────────────────╮ ->Ask the agent to build something… -╰────────────────────────────────────────────────────────────────────────────────────────────────╯ - manual ~/demo↗ main + + + + + █████╗  ███████╗ ███████╗ ███████╗ ███╗   ███╗ ██████╗  ██╗      ██╗   ██╗ +██╔══██╗ ██╔════╝ ██╔════╝ ██╔════╝ ████╗ ████║ ██╔══██╗ ██║      ╚██╗ ██╔╝ +███████║ ███████╗ ███████╗ █████╗   ██╔████╔██║ ██████╔╝ ██║       ╚████╔╝  +██╔══██║ ╚════██║ ╚════██║ ██╔══╝   ██║╚██╔╝██║ ██╔══██╗ ██║        ╚██╔╝   +██║  ██║ ███████║ ███████║ ███████╗ ██║ ╚═╝ ██║ ██████╔╝ ███████╗    ██║    +╚═╝  ╚═╝ ╚══════╝ ╚══════╝ ╚══════╝ ╚═╝     ╚═╝ ╚═════╝  ╚══════╝    ╚═╝    +v9.9.9 + +Thread: default + +Ready to code! What would you like to build? +Tip: approve tools as they run, or pass --auto to skip the prompts. + +» explain the plan +Here's the plan. First **scaffold** the project, then wire up the tests. + + + + + + + + + + +╭────────────────────────────────────────────────────────────────────────────────────────────────╮ +>Ask the agent to build something… + manual ~/demo↗ main +^Y copy · ^O expand · esc interrupt · ^C quit diff --git a/tests/__snapshots__/test_tui_snapshots/test_code_tool_output_collapsed.raw b/tests/__snapshots__/test_tui_snapshots/test_code_tool_output_collapsed.raw index 705dbe0..62998d0 100644 --- a/tests/__snapshots__/test_tui_snapshots/test_code_tool_output_collapsed.raw +++ b/tests/__snapshots__/test_tui_snapshots/test_code_tool_output_collapsed.raw @@ -19,166 +19,167 @@ font-weight: 700; } - .terminal-2885406642-matrix { + .terminal-246752052-matrix { font-family: Fira Code, monospace; font-size: 20px; line-height: 24.4px; font-variant-east-asian: full-width; } - .terminal-2885406642-title { + .terminal-246752052-title { font-size: 18px; font-weight: bold; font-family: arial; } - .terminal-2885406642-r1 { fill: #c5c8c6 } -.terminal-2885406642-r2 { fill: #614fd2;font-weight: bold } -.terminal-2885406642-r3 { fill: #939393 } -.terminal-2885406642-r4 { fill: #e0e0e0 } -.terminal-2885406642-r5 { fill: #614fd2 } -.terminal-2885406642-r6 { fill: #38bdf8;font-weight: bold } -.terminal-2885406642-r7 { fill: #8a8f98 } -.terminal-2885406642-r8 { fill: #8a8f98;font-style: italic; } -.terminal-2885406642-r9 { fill: #3a3f55 } -.terminal-2885406642-r10 { fill: #121212 } -.terminal-2885406642-r11 { fill: #676767 } -.terminal-2885406642-r12 { fill: #000000 } + .terminal-246752052-r1 { fill: #c5c8c6 } +.terminal-246752052-r2 { fill: #614fd2;font-weight: bold } +.terminal-246752052-r3 { fill: #939393 } +.terminal-246752052-r4 { fill: #e0e0e0 } +.terminal-246752052-r5 { fill: #614fd2 } +.terminal-246752052-r6 { fill: #38bdf8;font-weight: bold } +.terminal-246752052-r7 { fill: #8a8f98 } +.terminal-246752052-r8 { fill: #8a8f98;font-style: italic; } +.terminal-246752052-r9 { fill: #3a3f55 } +.terminal-246752052-r10 { fill: #121212 } +.terminal-246752052-r11 { fill: #676767 } +.terminal-246752052-r12 { fill: #000000 } +.terminal-246752052-r13 { fill: #939393;font-weight: bold } - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - AssemblyAI Code + AssemblyAI Code - - - - - █████╗  ███████╗ ███████╗ ███████╗ ███╗   ███╗ ██████╗  ██╗      ██╗   ██╗ -██╔══██╗ ██╔════╝ ██╔════╝ ██╔════╝ ████╗ ████║ ██╔══██╗ ██║      ╚██╗ ██╔╝ -███████║ ███████╗ ███████╗ █████╗   ██╔████╔██║ ██████╔╝ ██║       ╚████╔╝  -██╔══██║ ╚════██║ ╚════██║ ██╔══╝   ██║╚██╔╝██║ ██╔══██╗ ██║        ╚██╔╝   -██║  ██║ ███████║ ███████║ ███████╗ ██║ ╚═╝ ██║ ██████╔╝ ███████╗    ██║    -╚═╝  ╚═╝ ╚══════╝ ╚══════╝ ╚══════╝ ╚═╝     ╚═╝ ╚═════╝  ╚══════╝    ╚═╝    -v9.9.9 - -Thread: default - -Ready to code! What would you like to build? -Tip: approve tools as they run, or pass --auto to skip the prompts. - -» run the tests -→ execute(pytest -q) -  execute: tests/test_module_0.py .... [ 0%] -tests/test_module_1.py .... [ 10%] -tests/test_module_2.py .... [ 20%] -tests/test_module_3.py .... [ 30%] … (+4 more lines) (Ctrl+O to expand) - - - - - - -╭────────────────────────────────────────────────────────────────────────────────────────────────╮ ->Ask the agent to build something… -╰────────────────────────────────────────────────────────────────────────────────────────────────╯ - manual ~/demo↗ main + + + + + █████╗  ███████╗ ███████╗ ███████╗ ███╗   ███╗ ██████╗  ██╗      ██╗   ██╗ +██╔══██╗ ██╔════╝ ██╔════╝ ██╔════╝ ████╗ ████║ ██╔══██╗ ██║      ╚██╗ ██╔╝ +███████║ ███████╗ ███████╗ █████╗   ██╔████╔██║ ██████╔╝ ██║       ╚████╔╝  +██╔══██║ ╚════██║ ╚════██║ ██╔══╝   ██║╚██╔╝██║ ██╔══██╗ ██║        ╚██╔╝   +██║  ██║ ███████║ ███████║ ███████╗ ██║ ╚═╝ ██║ ██████╔╝ ███████╗    ██║    +╚═╝  ╚═╝ ╚══════╝ ╚══════╝ ╚══════╝ ╚═╝     ╚═╝ ╚═════╝  ╚══════╝    ╚═╝    +v9.9.9 + +Thread: default + +Ready to code! What would you like to build? +Tip: approve tools as they run, or pass --auto to skip the prompts. + +» run the tests +→ execute(pytest -q) +  execute: tests/test_module_0.py .... [ 0%] +tests/test_module_1.py .... [ 10%] +tests/test_module_2.py .... [ 20%] +tests/test_module_3.py .... [ 30%] … (+4 more lines) (Ctrl+O to expand) + + + + + + +╭────────────────────────────────────────────────────────────────────────────────────────────────╮ +>Ask the agent to build something… + manual ~/demo↗ main +^Y copy · ^O expand · esc interrupt · ^C quit diff --git a/tests/__snapshots__/test_tui_snapshots/test_code_tool_output_expanded.raw b/tests/__snapshots__/test_tui_snapshots/test_code_tool_output_expanded.raw index 8e9a713..1e11c72 100644 --- a/tests/__snapshots__/test_tui_snapshots/test_code_tool_output_expanded.raw +++ b/tests/__snapshots__/test_tui_snapshots/test_code_tool_output_expanded.raw @@ -19,166 +19,167 @@ font-weight: 700; } - .terminal-2213969501-matrix { + .terminal-2792346064-matrix { font-family: Fira Code, monospace; font-size: 20px; line-height: 24.4px; font-variant-east-asian: full-width; } - .terminal-2213969501-title { + .terminal-2792346064-title { font-size: 18px; font-weight: bold; font-family: arial; } - .terminal-2213969501-r1 { fill: #c5c8c6 } -.terminal-2213969501-r2 { fill: #614fd2;font-weight: bold } -.terminal-2213969501-r3 { fill: #939393 } -.terminal-2213969501-r4 { fill: #e0e0e0 } -.terminal-2213969501-r5 { fill: #614fd2 } -.terminal-2213969501-r6 { fill: #38bdf8;font-weight: bold } -.terminal-2213969501-r7 { fill: #8a8f98 } -.terminal-2213969501-r8 { fill: #8a8f98;font-style: italic; } -.terminal-2213969501-r9 { fill: #3a3f55 } -.terminal-2213969501-r10 { fill: #121212 } -.terminal-2213969501-r11 { fill: #676767 } -.terminal-2213969501-r12 { fill: #000000 } + .terminal-2792346064-r1 { fill: #c5c8c6 } +.terminal-2792346064-r2 { fill: #614fd2;font-weight: bold } +.terminal-2792346064-r3 { fill: #939393 } +.terminal-2792346064-r4 { fill: #e0e0e0 } +.terminal-2792346064-r5 { fill: #614fd2 } +.terminal-2792346064-r6 { fill: #38bdf8;font-weight: bold } +.terminal-2792346064-r7 { fill: #8a8f98 } +.terminal-2792346064-r8 { fill: #8a8f98;font-style: italic; } +.terminal-2792346064-r9 { fill: #3a3f55 } +.terminal-2792346064-r10 { fill: #121212 } +.terminal-2792346064-r11 { fill: #676767 } +.terminal-2792346064-r12 { fill: #000000 } +.terminal-2792346064-r13 { fill: #939393;font-weight: bold } - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - AssemblyAI Code + AssemblyAI Code - - - - - █████╗  ███████╗ ███████╗ ███████╗ ███╗   ███╗ ██████╗  ██╗      ██╗   ██╗ -██╔══██╗ ██╔════╝ ██╔════╝ ██╔════╝ ████╗ ████║ ██╔══██╗ ██║      ╚██╗ ██╔╝ -███████║ ███████╗ ███████╗ █████╗   ██╔████╔██║ ██████╔╝ ██║       ╚████╔╝  -██╔══██║ ╚════██║ ╚════██║ ██╔══╝   ██║╚██╔╝██║ ██╔══██╗ ██║        ╚██╔╝   -██║  ██║ ███████║ ███████║ ███████╗ ██║ ╚═╝ ██║ ██████╔╝ ███████╗    ██║    -╚═╝  ╚═╝ ╚══════╝ ╚══════╝ ╚══════╝ ╚═╝     ╚═╝ ╚═════╝  ╚══════╝    ╚═╝    -v9.9.9 - -Thread: default - -Ready to code! What would you like to build? -Tip: approve tools as they run, or pass --auto to skip the prompts. - -» run the tests -→ execute(pytest -q) -  execute: tests/test_module_0.py .... [ 0%] -tests/test_module_1.py .... [ 10%] -tests/test_module_2.py .... [ 20%] -tests/test_module_3.py .... [ 30%] -tests/test_module_4.py .... [ 40%] -tests/test_module_5.py .... [ 50%] -tests/test_module_6.py .... [ 60%] -tests/test_module_7.py .... [ 70%] (Ctrl+O to collapse) - - -╭────────────────────────────────────────────────────────────────────────────────────────────────╮ ->Ask the agent to build something… -╰────────────────────────────────────────────────────────────────────────────────────────────────╯ - manual ~/demo↗ main + + + + + █████╗  ███████╗ ███████╗ ███████╗ ███╗   ███╗ ██████╗  ██╗      ██╗   ██╗ +██╔══██╗ ██╔════╝ ██╔════╝ ██╔════╝ ████╗ ████║ ██╔══██╗ ██║      ╚██╗ ██╔╝ +███████║ ███████╗ ███████╗ █████╗   ██╔████╔██║ ██████╔╝ ██║       ╚████╔╝  +██╔══██║ ╚════██║ ╚════██║ ██╔══╝   ██║╚██╔╝██║ ██╔══██╗ ██║        ╚██╔╝   +██║  ██║ ███████║ ███████║ ███████╗ ██║ ╚═╝ ██║ ██████╔╝ ███████╗    ██║    +╚═╝  ╚═╝ ╚══════╝ ╚══════╝ ╚══════╝ ╚═╝     ╚═╝ ╚═════╝  ╚══════╝    ╚═╝    +v9.9.9 + +Thread: default + +Ready to code! What would you like to build? +Tip: approve tools as they run, or pass --auto to skip the prompts. + +» run the tests +→ execute(pytest -q) +  execute: tests/test_module_0.py .... [ 0%] +tests/test_module_1.py .... [ 10%] +tests/test_module_2.py .... [ 20%] +tests/test_module_3.py .... [ 30%] +tests/test_module_4.py .... [ 40%] +tests/test_module_5.py .... [ 50%] +tests/test_module_6.py .... [ 60%] +tests/test_module_7.py .... [ 70%] (Ctrl+O to collapse) + + +╭────────────────────────────────────────────────────────────────────────────────────────────────╮ +>Ask the agent to build something… + manual ~/demo↗ main +^Y copy · ^O expand · esc interrupt · ^C quit diff --git a/tests/__snapshots__/test_tui_snapshots/test_code_transcript.raw b/tests/__snapshots__/test_tui_snapshots/test_code_transcript.raw index 152213d..fb3fe8d 100644 --- a/tests/__snapshots__/test_tui_snapshots/test_code_transcript.raw +++ b/tests/__snapshots__/test_tui_snapshots/test_code_transcript.raw @@ -19,167 +19,168 @@ font-weight: 700; } - .terminal-2481357719-matrix { + .terminal-1120851722-matrix { font-family: Fira Code, monospace; font-size: 20px; line-height: 24.4px; font-variant-east-asian: full-width; } - .terminal-2481357719-title { + .terminal-1120851722-title { font-size: 18px; font-weight: bold; font-family: arial; } - .terminal-2481357719-r1 { fill: #c5c8c6 } -.terminal-2481357719-r2 { fill: #614fd2;font-weight: bold } -.terminal-2481357719-r3 { fill: #939393 } -.terminal-2481357719-r4 { fill: #e0e0e0 } -.terminal-2481357719-r5 { fill: #614fd2 } -.terminal-2481357719-r6 { fill: #38bdf8;font-weight: bold } -.terminal-2481357719-r7 { fill: #e0e0e0;font-weight: bold } -.terminal-2481357719-r8 { fill: #58d1eb } -.terminal-2481357719-r9 { fill: #8a8f98 } -.terminal-2481357719-r10 { fill: #3a3f55 } -.terminal-2481357719-r11 { fill: #121212 } -.terminal-2481357719-r12 { fill: #676767 } -.terminal-2481357719-r13 { fill: #000000 } + .terminal-1120851722-r1 { fill: #c5c8c6 } +.terminal-1120851722-r2 { fill: #614fd2;font-weight: bold } +.terminal-1120851722-r3 { fill: #939393 } +.terminal-1120851722-r4 { fill: #e0e0e0 } +.terminal-1120851722-r5 { fill: #614fd2 } +.terminal-1120851722-r6 { fill: #38bdf8;font-weight: bold } +.terminal-1120851722-r7 { fill: #e0e0e0;font-weight: bold } +.terminal-1120851722-r8 { fill: #58d1eb } +.terminal-1120851722-r9 { fill: #8a8f98 } +.terminal-1120851722-r10 { fill: #3a3f55 } +.terminal-1120851722-r11 { fill: #121212 } +.terminal-1120851722-r12 { fill: #676767 } +.terminal-1120851722-r13 { fill: #000000 } +.terminal-1120851722-r14 { fill: #939393;font-weight: bold } - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - AssemblyAI Code + AssemblyAI Code - - - - - █████╗  ███████╗ ███████╗ ███████╗ ███╗   ███╗ ██████╗  ██╗      ██╗   ██╗ -██╔══██╗ ██╔════╝ ██╔════╝ ██╔════╝ ████╗ ████║ ██╔══██╗ ██║      ╚██╗ ██╔╝ -███████║ ███████╗ ███████╗ █████╗   ██╔████╔██║ ██████╔╝ ██║       ╚████╔╝  -██╔══██║ ╚════██║ ╚════██║ ██╔══╝   ██║╚██╔╝██║ ██╔══██╗ ██║        ╚██╔╝   -██║  ██║ ███████║ ███████║ ███████╗ ██║ ╚═╝ ██║ ██████╔╝ ███████╗    ██║    -╚═╝  ╚═╝ ╚══════╝ ╚══════╝ ╚══════╝ ╚═╝     ╚═╝ ╚═════╝  ╚══════╝    ╚═╝    -v9.9.9 - -Thread: default - -Ready to code! What would you like to build? -Tip: approve tools as they run, or pass --auto to skip the prompts. - -» add a /health endpoint -Adding a health check:                                                                           - - 1 New route                                                                                     - 2 A test                                                                                        -→ write_file(app.py) -  write_file: wrote 8 lines to app.py - - - - - -╭────────────────────────────────────────────────────────────────────────────────────────────────╮ ->Ask the agent to build something… -╰────────────────────────────────────────────────────────────────────────────────────────────────╯ - manual ~/demo↗ main + + + + + █████╗  ███████╗ ███████╗ ███████╗ ███╗   ███╗ ██████╗  ██╗      ██╗   ██╗ +██╔══██╗ ██╔════╝ ██╔════╝ ██╔════╝ ████╗ ████║ ██╔══██╗ ██║      ╚██╗ ██╔╝ +███████║ ███████╗ ███████╗ █████╗   ██╔████╔██║ ██████╔╝ ██║       ╚████╔╝  +██╔══██║ ╚════██║ ╚════██║ ██╔══╝   ██║╚██╔╝██║ ██╔══██╗ ██║        ╚██╔╝   +██║  ██║ ███████║ ███████║ ███████╗ ██║ ╚═╝ ██║ ██████╔╝ ███████╗    ██║    +╚═╝  ╚═╝ ╚══════╝ ╚══════╝ ╚══════╝ ╚═╝     ╚═╝ ╚═════╝  ╚══════╝    ╚═╝    +v9.9.9 + +Thread: default + +Ready to code! What would you like to build? +Tip: approve tools as they run, or pass --auto to skip the prompts. + +» add a /health endpoint +Adding a health check:                                                                           + + 1 New route                                                                                     + 2 A test                                                                                        +→ write_file(app.py) +  write_file: wrote 8 lines to app.py + + + + + +╭────────────────────────────────────────────────────────────────────────────────────────────────╮ +>Ask the agent to build something… + manual ~/demo↗ main +^Y copy · ^O expand · esc interrupt · ^C quit diff --git a/tests/__snapshots__/test_tui_snapshots/test_code_voice_listening.raw b/tests/__snapshots__/test_tui_snapshots/test_code_voice_listening.raw index 310de20..7b0288b 100644 --- a/tests/__snapshots__/test_tui_snapshots/test_code_voice_listening.raw +++ b/tests/__snapshots__/test_tui_snapshots/test_code_voice_listening.raw @@ -19,161 +19,162 @@ font-weight: 700; } - .terminal-1669332747-matrix { + .terminal-3917210796-matrix { font-family: Fira Code, monospace; font-size: 20px; line-height: 24.4px; font-variant-east-asian: full-width; } - .terminal-1669332747-title { + .terminal-3917210796-title { font-size: 18px; font-weight: bold; font-family: arial; } - .terminal-1669332747-r1 { fill: #c5c8c6 } -.terminal-1669332747-r2 { fill: #614fd2;font-weight: bold } -.terminal-1669332747-r3 { fill: #939393 } -.terminal-1669332747-r4 { fill: #e0e0e0 } -.terminal-1669332747-r5 { fill: #614fd2 } -.terminal-1669332747-r6 { fill: #000000 } -.terminal-1669332747-r7 { fill: #22c55e } + .terminal-3917210796-r1 { fill: #c5c8c6 } +.terminal-3917210796-r2 { fill: #614fd2;font-weight: bold } +.terminal-3917210796-r3 { fill: #939393 } +.terminal-3917210796-r4 { fill: #e0e0e0 } +.terminal-3917210796-r5 { fill: #614fd2 } +.terminal-3917210796-r6 { fill: #000000 } +.terminal-3917210796-r7 { fill: #22c55e } +.terminal-3917210796-r8 { fill: #939393;font-weight: bold } - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - AssemblyAI Code + AssemblyAI Code - - - - - █████╗  ███████╗ ███████╗ ███████╗ ███╗   ███╗ ██████╗  ██╗      ██╗   ██╗ -██╔══██╗ ██╔════╝ ██╔════╝ ██╔════╝ ████╗ ████║ ██╔══██╗ ██║      ╚██╗ ██╔╝ -███████║ ███████╗ ███████╗ █████╗   ██╔████╔██║ ██████╔╝ ██║       ╚████╔╝  -██╔══██║ ╚════██║ ╚════██║ ██╔══╝   ██║╚██╔╝██║ ██╔══██╗ ██║        ╚██╔╝   -██║  ██║ ███████║ ███████║ ███████╗ ██║ ╚═╝ ██║ ██████╔╝ ███████╗    ██║    -╚═╝  ╚═╝ ╚══════╝ ╚══════╝ ╚══════╝ ╚═╝     ╚═╝ ╚═════╝  ╚══════╝    ╚═╝    -v9.9.9 - -Thread: default - -Ready to code! What would you like to build? -Tip: approve tools as they run, or pass --auto to skip the prompts. - - - - - - - - - - - - - -╭────────────────────────────────────────────────────────────────────────────────────────────────╮ -▁▃▅ Listening — speak your request   (Ctrl-V to type) -╰────────────────────────────────────────────────────────────────────────────────────────────────╯ - manual ~/demo↗ main● voice on + + + + + █████╗  ███████╗ ███████╗ ███████╗ ███╗   ███╗ ██████╗  ██╗      ██╗   ██╗ +██╔══██╗ ██╔════╝ ██╔════╝ ██╔════╝ ████╗ ████║ ██╔══██╗ ██║      ╚██╗ ██╔╝ +███████║ ███████╗ ███████╗ █████╗   ██╔████╔██║ ██████╔╝ ██║       ╚████╔╝  +██╔══██║ ╚════██║ ╚════██║ ██╔══╝   ██║╚██╔╝██║ ██╔══██╗ ██║        ╚██╔╝   +██║  ██║ ███████║ ███████║ ███████╗ ██║ ╚═╝ ██║ ██████╔╝ ███████╗    ██║    +╚═╝  ╚═╝ ╚══════╝ ╚══════╝ ╚══════╝ ╚═╝     ╚═╝ ╚═════╝  ╚══════╝    ╚═╝    +v9.9.9 + +Thread: default + +Ready to code! What would you like to build? +Tip: approve tools as they run, or pass --auto to skip the prompts. + + + + + + + + + + + + + +╭────────────────────────────────────────────────────────────────────────────────────────────────╮ +▁▃▅ Listening — speak your request   (Ctrl-V to type) + manual ~/demo↗ main● voice on +^Y copy · ^V voice · ^O expand · esc interrupt · ^C quit diff --git a/tests/__snapshots__/test_tui_snapshots/test_code_working_spinner.raw b/tests/__snapshots__/test_tui_snapshots/test_code_working_spinner.raw index d48171b..6bcc995 100644 --- a/tests/__snapshots__/test_tui_snapshots/test_code_working_spinner.raw +++ b/tests/__snapshots__/test_tui_snapshots/test_code_working_spinner.raw @@ -19,164 +19,165 @@ font-weight: 700; } - .terminal-3063843344-matrix { + .terminal-3227114883-matrix { font-family: Fira Code, monospace; font-size: 20px; line-height: 24.4px; font-variant-east-asian: full-width; } - .terminal-3063843344-title { + .terminal-3227114883-title { font-size: 18px; font-weight: bold; font-family: arial; } - .terminal-3063843344-r1 { fill: #c5c8c6 } -.terminal-3063843344-r2 { fill: #614fd2;font-weight: bold } -.terminal-3063843344-r3 { fill: #939393 } -.terminal-3063843344-r4 { fill: #e0e0e0 } -.terminal-3063843344-r5 { fill: #614fd2 } -.terminal-3063843344-r6 { fill: #38bdf8;font-weight: bold } -.terminal-3063843344-r7 { fill: #3a3f55 } -.terminal-3063843344-r8 { fill: #121212 } -.terminal-3063843344-r9 { fill: #676767 } -.terminal-3063843344-r10 { fill: #000000 } + .terminal-3227114883-r1 { fill: #c5c8c6 } +.terminal-3227114883-r2 { fill: #614fd2;font-weight: bold } +.terminal-3227114883-r3 { fill: #939393 } +.terminal-3227114883-r4 { fill: #e0e0e0 } +.terminal-3227114883-r5 { fill: #614fd2 } +.terminal-3227114883-r6 { fill: #38bdf8;font-weight: bold } +.terminal-3227114883-r7 { fill: #3a3f55 } +.terminal-3227114883-r8 { fill: #121212 } +.terminal-3227114883-r9 { fill: #676767 } +.terminal-3227114883-r10 { fill: #000000 } +.terminal-3227114883-r11 { fill: #939393;font-weight: bold } - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - AssemblyAI Code + AssemblyAI Code - - - - - █████╗  ███████╗ ███████╗ ███████╗ ███╗   ███╗ ██████╗  ██╗      ██╗   ██╗ -██╔══██╗ ██╔════╝ ██╔════╝ ██╔════╝ ████╗ ████║ ██╔══██╗ ██║      ╚██╗ ██╔╝ -███████║ ███████╗ ███████╗ █████╗   ██╔████╔██║ ██████╔╝ ██║       ╚████╔╝  -██╔══██║ ╚════██║ ╚════██║ ██╔══╝   ██║╚██╔╝██║ ██╔══██╗ ██║        ╚██╔╝   -██║  ██║ ███████║ ███████║ ███████╗ ██║ ╚═╝ ██║ ██████╔╝ ███████╗    ██║    -╚═╝  ╚═╝ ╚══════╝ ╚══════╝ ╚══════╝ ╚═╝     ╚═╝ ╚═════╝  ╚══════╝    ╚═╝    -v9.9.9 - -Thread: default - -Ready to code! What would you like to build? -Tip: approve tools as they run, or pass --auto to skip the prompts. - -» build a web scraper - - - - - - - - - -✶ Working… (7s) - -╭────────────────────────────────────────────────────────────────────────────────────────────────╮ ->Ask the agent to build something… -╰────────────────────────────────────────────────────────────────────────────────────────────────╯ - manual ~/demo↗ main + + + + + █████╗  ███████╗ ███████╗ ███████╗ ███╗   ███╗ ██████╗  ██╗      ██╗   ██╗ +██╔══██╗ ██╔════╝ ██╔════╝ ██╔════╝ ████╗ ████║ ██╔══██╗ ██║      ╚██╗ ██╔╝ +███████║ ███████╗ ███████╗ █████╗   ██╔████╔██║ ██████╔╝ ██║       ╚████╔╝  +██╔══██║ ╚════██║ ╚════██║ ██╔══╝   ██║╚██╔╝██║ ██╔══██╗ ██║        ╚██╔╝   +██║  ██║ ███████║ ███████║ ███████╗ ██║ ╚═╝ ██║ ██████╔╝ ███████╗    ██║    +╚═╝  ╚═╝ ╚══════╝ ╚══════╝ ╚══════╝ ╚═╝     ╚═╝ ╚═════╝  ╚══════╝    ╚═╝    +v9.9.9 + +Thread: default + +Ready to code! What would you like to build? +Tip: approve tools as they run, or pass --auto to skip the prompts. + +» build a web scraper + + + + + + + + + +✶ Working… (7s) + +╭────────────────────────────────────────────────────────────────────────────────────────────────╮ +>Ask the agent to build something… + manual ~/demo↗ main +^Y copy · ^O expand · esc interrupt · ^C quit diff --git a/tests/test_code_tui_status.py b/tests/test_code_tui_status.py index 1104f91..9d6de03 100644 --- a/tests/test_code_tui_status.py +++ b/tests/test_code_tui_status.py @@ -79,6 +79,30 @@ def _boom(_text: str) -> None: assert "no clipboard available" in note +def test_keyhints_lists_shortcuts_and_gates_voice_on_availability() -> None: + # The legend always lists copy/expand/interrupt/quit; the Ctrl-V voice toggle appears + # only when a voice front-end exists, and the whole line is dim. + with_voice = tui_status.keyhints_text(voice=True) + assert "copy" in with_voice and "expand" in with_voice and "quit" in with_voice + assert "voice" in with_voice # the Ctrl-V hint is listed when voice is available + assert with_voice.startswith("[dim]") # rendered as a dim legend + without_voice = tui_status.keyhints_text(voice=False) + assert "voice" not in without_voice # no Ctrl-V hint without a voice front-end + assert "copy" in without_voice and "quit" in without_voice + + +def test_status_text_appends_the_key_legend(tmp_path: Path) -> None: + # The footer is two rows: the status info, then the dim key legend beneath it. + footer = tui_status._status_text(tmp_path, auto_approve=False) + info, _, hints = footer.partition("\n") + assert "manual" in info # row one is the status info + assert "quit" in hints and "copy" in hints # row two is the key legend + assert "voice" not in hints # no voice front-end -> the legend omits the Ctrl-V hint + # With a voice front-end the legend's second row gains the Ctrl-V hint. + voiced = tui_status._status_text(tmp_path, auto_approve=False, voice_state="on") + assert "voice" in voiced.partition("\n")[2] + + def test_status_text_renders_voice_badge(tmp_path: Path) -> None: # No voice front-end -> no voice badge (the dot glyphs are absent); on/off render the # state so the Ctrl-V toggle shows. (Asserts on the dots, not the word — the tmp_path name