You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Make Wright's interactive terminal provide immediate, truthful, phase-aware feedback for human users, while keeping machine-oriented output deterministic and presentation-free.
Context
#210 / PR #211 introduced the first TUI-lite activity indicator, and PR #216 attempted to refine it. Real-project use after merge shows that the intended interactive behavior is still not implemented.
Current main still behaves as follows:
Activity::start() waits 150 ms and then prints the fixed string wright: working…;
there is no spinner animation and no workflow phase information such as loading, parsing, semantic resolution, analysis, linting, or emission;
run_command() keeps the activity guard alive through present::render(), so final output can still appear on the same live line as the activity text, e.g. wright: working…PASS analyze;
the existing cleanup test verifies the escape sequence used to clear a line, but not the end-to-end lifecycle activity → workflow → stop/clear → final render on a TTY.
The original issue wording was too weak: it required only a delayed transient activity state and explicitly discouraged a progress-event abstraction before real evidence existed. Real usage now provides that evidence. Wright's session already has meaningful workflow boundaries such as input resolution, frontend/project loading, parsing, validation/lowering, semantic analysis, lint execution, and emission. The CLI should be able to observe those real phases without coupling terminal text into the driver.
A representative human experience should be closer to:
The exact wording and number of phases should follow real workflow events; do not manufacture fake progress percentages or phases that did not occur.
Scope
Immediate feedback and animation
Interactive TTY text commands should show an initial activity/status line immediately when work begins rather than waiting 150 ms before any feedback.
Separate initial feedback from animation: a static status may appear immediately, while spinner animation may begin only after a short implementation-level threshold (for example roughly 50–80 ms) to avoid flicker.
The animation threshold is presentation behavior, not a public semantic/configuration contract unless later evidence requires configurability.
Phase-aware progress
Introduce the smallest transport-neutral progress/observer contract needed for the driver/session to expose truthful workflow phase transitions to interested callers.
Keep phase events semantic rather than terminal-specific. The driver must not emit ANSI, spinner frames, or human presentation strings.
Use real phases that exist in each workflow. Examples may include input/project loading, parsing, semantic resolution, validation/lowering, analysis, lint-rule execution, and emission.
Do not force every command through the same phase list. check, lint, analyze, compile, convert, and inspect should expose only work they actually perform.
When real counts are available without expensive duplicate work, progress may include useful bounded metadata such as file count or lint-rule count. Do not invent counts.
Terminal lifecycle
Progress/activity must be stopped and its live line fully cleared before final diagnostics, verdicts, reports, or source output are rendered.
Fix the current guard lifetime so present::render() cannot run while an interactive activity line is still active.
Prefer transient phase output that collapses/clears into a concise final summary rather than permanently leaving several boilerplate progress lines after every successful fast command.
Environment boundaries
Apply interactive progress only to human TTY text rendering.
--format json, explicit plain rendering, redirected/piped output, non-TTY environments, TERM=dumb, and GitHub Actions must remain static, deterministic, and free of spinner/progress artifacts.
Agents and embedding consumers must use structured results/events rather than scrape terminal presentation.
Non-goals
Do not build a full-screen TUI or persistent dashboard.
Do not add fake percentage progress.
Do not introduce terminal presentation concerns into language frontends or semantic owner repositories.
Do not add a broad async/task framework merely to support progress.
Do not preserve wright: working… as the long-term activity UX.
Acceptance criteria
An interactive TTY receives immediate visible feedback when a workflow starts, including for commands that commonly complete in well under 150 ms.
A slower representative workflow visibly transitions through at least two truthful workflow phases before completion.
Spinner animation, when used, starts only after a short anti-flicker threshold while the initial status is already visible.
Final output is rendered only after the live activity/progress line has been stopped and cleared.
No accepted implementation can produce output of the form wright: working…PASS ... or otherwise concatenate transient activity with final output.
lint can surface a real lint-execution phase, and workflows with different pipelines do not present fabricated identical phase sequences.
Successful completion collapses transient progress into a concise final result instead of permanently retaining every intermediate phase by default.
--format json, plain/piped output, CI, GitHub Actions, and non-TTY output contain no ANSI spinner frames or progress text and remain deterministic.
Tests include an end-to-end pseudo-TTY/TTY lifecycle case that proves ordering: activity starts → workflow/phase updates occur → activity stops/clears → final render begins.
Tests do not merely unit-test the line-clearing escape sequence; they fail if final render occurs while activity is still alive.
Planning notes
Keep the progress contract small and evidence-driven. A callback/observer/event sink owned at the session/orchestration boundary is preferable to coupling the driver to a specific terminal library. The CLI may choose its own lightweight spinner/status implementation.
Use real-project latency as the UX reference: Wright is fast enough that a 150 ms delay often suppresses all feedback, so the design should optimize for immediate responsiveness without introducing visible spinner flicker.
Goal
Make Wright's interactive terminal provide immediate, truthful, phase-aware feedback for human users, while keeping machine-oriented output deterministic and presentation-free.
Context
#210 / PR #211 introduced the first TUI-lite activity indicator, and PR #216 attempted to refine it. Real-project use after merge shows that the intended interactive behavior is still not implemented.
Current
mainstill behaves as follows:Activity::start()waits 150 ms and then prints the fixed stringwright: working…;run_command()keeps the activity guard alive throughpresent::render(), so final output can still appear on the same live line as the activity text, e.g.wright: working…PASS analyze;activity → workflow → stop/clear → final renderon a TTY.The original issue wording was too weak: it required only a delayed transient activity state and explicitly discouraged a progress-event abstraction before real evidence existed. Real usage now provides that evidence. Wright's session already has meaningful workflow boundaries such as input resolution, frontend/project loading, parsing, validation/lowering, semantic analysis, lint execution, and emission. The CLI should be able to observe those real phases without coupling terminal text into the driver.
A representative human experience should be closer to:
The exact wording and number of phases should follow real workflow events; do not manufacture fake progress percentages or phases that did not occur.
Scope
Immediate feedback and animation
Phase-aware progress
check,lint,analyze,compile,convert, andinspectshould expose only work they actually perform.Terminal lifecycle
present::render()cannot run while an interactive activity line is still active.Environment boundaries
--format json, explicit plain rendering, redirected/piped output, non-TTY environments,TERM=dumb, and GitHub Actions must remain static, deterministic, and free of spinner/progress artifacts.Non-goals
analyzereport contract.wright: working…as the long-term activity UX.Acceptance criteria
wright: working…PASS ...or otherwise concatenate transient activity with final output.lintcan surface a real lint-execution phase, and workflows with different pipelines do not present fabricated identical phase sequences.--format json, plain/piped output, CI, GitHub Actions, and non-TTY output contain no ANSI spinner frames or progress text and remain deterministic.Planning notes
Keep the progress contract small and evidence-driven. A callback/observer/event sink owned at the session/orchestration boundary is preferable to coupling the driver to a specific terminal library. The CLI may choose its own lightweight spinner/status implementation.
Use real-project latency as the UX reference: Wright is fast enough that a 150 ms delay often suppresses all feedback, so the design should optimize for immediate responsiveness without introducing visible spinner flicker.