docs: plan cli ux progress redesign
This commit is contained in:
parent
d1b9754c0b
commit
ab60ee641f
2 changed files with 509 additions and 0 deletions
222
.plans/005-cli-ux-progress/2026-03-20-cli-ux-progress-design.md
Normal file
222
.plans/005-cli-ux-progress/2026-03-20-cli-ux-progress-design.md
Normal file
|
|
@ -0,0 +1,222 @@
|
||||||
|
# CLI UX And Progress Design
|
||||||
|
|
||||||
|
## Goal
|
||||||
|
|
||||||
|
Bring the terminal UX back in line with spec 000 by making the CLI visibly active during long-running work and by replacing the current plain-text summaries with a styled, intentional presentation layer.
|
||||||
|
|
||||||
|
## Problem Statement
|
||||||
|
|
||||||
|
The current CLI has two obvious gaps:
|
||||||
|
|
||||||
|
- long-running flows such as `aim <QUERY>` stay silent until the operation is effectively complete
|
||||||
|
- terminal output across add, update, list, remove, review, and prompts is still raw and inconsistent
|
||||||
|
|
||||||
|
This is a product and architecture drift issue relative to the original design. Spec 000 explicitly called for:
|
||||||
|
|
||||||
|
- `dialoguer` for prompts
|
||||||
|
- `console` for styled terminal summaries
|
||||||
|
- `indicatif` for spinners and progress bars
|
||||||
|
- terminal rendering in `aim-cli`
|
||||||
|
- typed progress or interaction models in `aim-core`
|
||||||
|
|
||||||
|
## Design Goals
|
||||||
|
|
||||||
|
- show immediate feedback for long-running operations
|
||||||
|
- make all CLI commands feel like one coherent tool instead of separate text dumps
|
||||||
|
- keep `aim-core` reusable by a future GUI client
|
||||||
|
- avoid pushing terminal-specific logic into `aim-core`
|
||||||
|
- add real progress where possible and honest staged progress elsewhere
|
||||||
|
|
||||||
|
## Non-Goals
|
||||||
|
|
||||||
|
- a full-screen TUI
|
||||||
|
- async runtime migration across the entire application
|
||||||
|
- provider-specific live rich progress beyond what the current transport layers can expose cleanly
|
||||||
|
- redesigning core application behavior or registry semantics
|
||||||
|
|
||||||
|
## Architectural Decision
|
||||||
|
|
||||||
|
Use an event-driven CLI boundary.
|
||||||
|
|
||||||
|
`aim-core` will emit typed operation events for add, update, and remove flows. `aim-cli` will consume those events and render them using `console`, `indicatif`, and `dialoguer`.
|
||||||
|
|
||||||
|
This preserves the intended layering:
|
||||||
|
|
||||||
|
- `aim-core` owns workflow and operation semantics
|
||||||
|
- `aim-cli` owns prompts, colors, layout, spinners, and progress bars
|
||||||
|
|
||||||
|
## Command UX Shape
|
||||||
|
|
||||||
|
### `aim <QUERY>` add/install
|
||||||
|
|
||||||
|
This becomes the richest progress flow because it is the most visibly long-running command.
|
||||||
|
|
||||||
|
Target behavior:
|
||||||
|
|
||||||
|
- render an immediate spinner as soon as the operation begins
|
||||||
|
- update stage text as the operation advances through:
|
||||||
|
- resolving source
|
||||||
|
- discovering releases
|
||||||
|
- selecting artifact
|
||||||
|
- downloading artifact
|
||||||
|
- staging payload
|
||||||
|
- writing desktop entry
|
||||||
|
- extracting icon
|
||||||
|
- refreshing integration
|
||||||
|
- saving registry
|
||||||
|
- when the transport can report total bytes, upgrade the spinner to a byte progress bar during download
|
||||||
|
- end with a styled success or failure summary
|
||||||
|
|
||||||
|
### `aim update`
|
||||||
|
|
||||||
|
Target behavior:
|
||||||
|
|
||||||
|
- show a batch-level progress indicator immediately
|
||||||
|
- emit per-app status rows as each update starts and completes
|
||||||
|
- show a styled final summary with updated count, failed count, and warnings
|
||||||
|
|
||||||
|
### `aim remove <QUERY>`
|
||||||
|
|
||||||
|
Target behavior:
|
||||||
|
|
||||||
|
- short-lived spinner while resolving and deleting managed files
|
||||||
|
- styled completion summary including warnings when integration refresh is degraded
|
||||||
|
|
||||||
|
### `aim list`
|
||||||
|
|
||||||
|
Target behavior:
|
||||||
|
|
||||||
|
- styled header and aligned entries
|
||||||
|
- proper empty state when no apps are registered
|
||||||
|
|
||||||
|
### bare `aim`
|
||||||
|
|
||||||
|
Target behavior:
|
||||||
|
|
||||||
|
- remain review-only
|
||||||
|
- render a styled update review summary instead of a raw single-line counter
|
||||||
|
|
||||||
|
## Prompt Strategy
|
||||||
|
|
||||||
|
`dialoguer` remains the prompt mechanism, but prompt rendering becomes centralized in `aim-cli`.
|
||||||
|
|
||||||
|
Design rules:
|
||||||
|
|
||||||
|
- use one shared prompt theme definition
|
||||||
|
- standardize prompt titles, selected-item labels, and cancel behavior
|
||||||
|
- render non-interactive fallback text using the same wording used in interactive mode
|
||||||
|
|
||||||
|
This keeps prompt copy and prompt appearance consistent across tracking selection and future artifact or app disambiguation prompts.
|
||||||
|
|
||||||
|
## Event Model
|
||||||
|
|
||||||
|
Add a small typed event model inside `aim-core`.
|
||||||
|
|
||||||
|
Recommended event families:
|
||||||
|
|
||||||
|
- `OperationStarted { kind, label }`
|
||||||
|
- `OperationStageChanged { stage, message }`
|
||||||
|
- `OperationProgress { current, total }`
|
||||||
|
- `OperationWarning { message }`
|
||||||
|
- `OperationFinished { summary }`
|
||||||
|
- `OperationFailed { stage, reason }`
|
||||||
|
|
||||||
|
Recommended operation kinds:
|
||||||
|
|
||||||
|
- add
|
||||||
|
- update-batch
|
||||||
|
- update-item
|
||||||
|
- remove
|
||||||
|
|
||||||
|
Recommended stages:
|
||||||
|
|
||||||
|
- resolve-query
|
||||||
|
- discover-release
|
||||||
|
- select-artifact
|
||||||
|
- download-artifact
|
||||||
|
- stage-payload
|
||||||
|
- write-desktop-entry
|
||||||
|
- extract-icon
|
||||||
|
- refresh-integration
|
||||||
|
- save-registry
|
||||||
|
- finalize
|
||||||
|
|
||||||
|
The event model must stay terminal-agnostic. It should not mention spinners, colors, or bars.
|
||||||
|
|
||||||
|
## Core Integration Strategy
|
||||||
|
|
||||||
|
The current blocking shape is:
|
||||||
|
|
||||||
|
- `aim-cli` dispatches
|
||||||
|
- `aim-core` completes all work synchronously
|
||||||
|
- `aim-cli` prints one final string
|
||||||
|
|
||||||
|
The new shape becomes:
|
||||||
|
|
||||||
|
- `aim-cli` constructs an operation reporter
|
||||||
|
- `aim-core` executes workflows while invoking a callback or reporter trait with typed events
|
||||||
|
- `aim-cli` renders events live and then prints the final styled summary
|
||||||
|
|
||||||
|
The first implementation should avoid invasive redesign beyond what is needed to surface events.
|
||||||
|
|
||||||
|
That means:
|
||||||
|
|
||||||
|
- keep existing workflow functions where practical
|
||||||
|
- add event-capable variants where needed
|
||||||
|
- refactor download and install helpers just enough to emit useful staged progress
|
||||||
|
|
||||||
|
## Crate Usage
|
||||||
|
|
||||||
|
### `dialoguer`
|
||||||
|
|
||||||
|
- keep for interactive prompts
|
||||||
|
- use a shared theme and prompt formatting helper
|
||||||
|
|
||||||
|
### `console`
|
||||||
|
|
||||||
|
- use for styled headers, labels, warnings, empty states, and final summaries
|
||||||
|
- centralize styling tokens in one CLI UI module instead of scattering style calls around render functions
|
||||||
|
|
||||||
|
### `indicatif`
|
||||||
|
|
||||||
|
- use spinners for staged operations
|
||||||
|
- use a progress bar for downloads when content length is known
|
||||||
|
- fall back to spinner plus stage text when byte totals are unavailable
|
||||||
|
|
||||||
|
## Testing Strategy
|
||||||
|
|
||||||
|
### Core tests
|
||||||
|
|
||||||
|
- verify add flow emits ordered stages for fixture-backed installs
|
||||||
|
- verify update flow emits per-app started and finished events
|
||||||
|
- verify remove flow emits resolve and cleanup stages
|
||||||
|
- verify progress events are optional and do not break fixture mode when total size is unavailable
|
||||||
|
|
||||||
|
### CLI tests
|
||||||
|
|
||||||
|
- assert styled output contains clearer headers and summary markers
|
||||||
|
- assert prompt text remains stable and intentional
|
||||||
|
- assert progress-aware commands still finish with the correct final summary
|
||||||
|
|
||||||
|
### Scope of snapshotting
|
||||||
|
|
||||||
|
Avoid over-snapshotting ANSI-heavy output. Prefer targeted assertions around:
|
||||||
|
|
||||||
|
- visible labels
|
||||||
|
- operation headings
|
||||||
|
- empty-state text
|
||||||
|
- summary wording
|
||||||
|
- warning wording
|
||||||
|
|
||||||
|
## Incremental Rollout
|
||||||
|
|
||||||
|
Implement in this order:
|
||||||
|
|
||||||
|
1. shared CLI styling primitives and prompt theme
|
||||||
|
2. typed core operation events
|
||||||
|
3. add/install live progress path
|
||||||
|
4. update batch progress path
|
||||||
|
5. remove/list/review restyling
|
||||||
|
6. README command and flow description refresh
|
||||||
|
|
||||||
|
This order fixes the biggest user-visible problem first while still delivering a complete CLI presentation pass in the same slice.
|
||||||
|
|
@ -0,0 +1,287 @@
|
||||||
|
# CLI UX And Progress Implementation Plan
|
||||||
|
|
||||||
|
> **For Claude:** REQUIRED SUB-SKILL: Use superpowers:executing-plans to implement this plan task-by-task.
|
||||||
|
|
||||||
|
**Goal:** Redesign the terminal UX across all CLI commands so prompts use `dialoguer`, summaries use `console`, and long-running operations show live `indicatif` progress driven by typed events from `aim-core`.
|
||||||
|
|
||||||
|
**Architecture:** Add a terminal-agnostic operation event model in `aim-core`, thread it through add, update, and remove workflows, then render those events in `aim-cli` through centralized styling and progress helpers. Keep the current business logic in `aim-core` and keep all terminal behavior in `aim-cli`.
|
||||||
|
|
||||||
|
**Tech Stack:** Rust, Cargo workspace, clap, dialoguer, console, indicatif, reqwest blocking client, existing fixture-backed tests in `crates/aim-core/tests` and `crates/aim-cli/tests`.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### Task 1: Add failing CLI presentation tests
|
||||||
|
|
||||||
|
**Files:**
|
||||||
|
- Modify: `crates/aim-cli/tests/end_to_end_cli.rs`
|
||||||
|
- Modify: `crates/aim-cli/tests/ui_summary.rs`
|
||||||
|
- Modify: `crates/aim-cli/Cargo.toml`
|
||||||
|
- Modify: `Cargo.toml`
|
||||||
|
|
||||||
|
**Step 1: Write the failing tests**
|
||||||
|
|
||||||
|
Add focused tests that assert:
|
||||||
|
- add/install output uses clearer sectioned summary wording instead of the current raw line bundle
|
||||||
|
- list empty state and update review output use improved labels
|
||||||
|
- prompt rendering keeps explicit tracking wording while moving to shared prompt formatting
|
||||||
|
|
||||||
|
**Step 2: Run tests to verify they fail**
|
||||||
|
|
||||||
|
Run: `cargo test --package aim-cli --test ui_summary`
|
||||||
|
Expected: FAIL because the current renderer still emits plain legacy text.
|
||||||
|
|
||||||
|
**Step 3: Add the missing CLI dependencies**
|
||||||
|
|
||||||
|
Add `console` and `indicatif` to the workspace and `aim-cli` crate so the new UI helpers can be implemented cleanly.
|
||||||
|
|
||||||
|
**Step 4: Re-run the focused tests**
|
||||||
|
|
||||||
|
Run: `cargo test --package aim-cli --test ui_summary`
|
||||||
|
Expected: still FAIL for behavior, not setup.
|
||||||
|
|
||||||
|
**Step 5: Commit**
|
||||||
|
|
||||||
|
```bash
|
||||||
|
git add Cargo.toml crates/aim-cli/Cargo.toml crates/aim-cli/tests/end_to_end_cli.rs crates/aim-cli/tests/ui_summary.rs
|
||||||
|
git commit -m "test: cover cli presentation refresh"
|
||||||
|
```
|
||||||
|
|
||||||
|
### Task 2: Add typed operation events in aim-core
|
||||||
|
|
||||||
|
**Files:**
|
||||||
|
- Create: `crates/aim-core/src/app/progress.rs`
|
||||||
|
- Modify: `crates/aim-core/src/app/mod.rs`
|
||||||
|
- Modify: `crates/aim-core/src/app/add.rs`
|
||||||
|
- Modify: `crates/aim-core/src/app/update.rs`
|
||||||
|
- Modify: `crates/aim-core/src/app/remove.rs`
|
||||||
|
- Test: `crates/aim-core/tests/install_integration.rs`
|
||||||
|
- Test: `crates/aim-core/tests/update_planning.rs`
|
||||||
|
- Test: `crates/aim-core/tests/remove_flow.rs`
|
||||||
|
|
||||||
|
**Step 1: Write the failing core tests**
|
||||||
|
|
||||||
|
Add tests that assert event order for:
|
||||||
|
- add/install fixture flow
|
||||||
|
- update execution over one app
|
||||||
|
- remove flow for managed artifacts
|
||||||
|
|
||||||
|
**Step 2: Run the focused tests to verify they fail**
|
||||||
|
|
||||||
|
Run: `cargo test --package aim-core --test install_integration`
|
||||||
|
Expected: FAIL because no operation event model exists.
|
||||||
|
|
||||||
|
**Step 3: Implement the minimal event model**
|
||||||
|
|
||||||
|
Add:
|
||||||
|
- typed operation and stage enums
|
||||||
|
- event payload structs
|
||||||
|
- a reporter callback or trait that defaults to no-op when not supplied
|
||||||
|
|
||||||
|
Do not introduce terminal dependencies into `aim-core`.
|
||||||
|
|
||||||
|
**Step 4: Thread events through add, update, and remove flows**
|
||||||
|
|
||||||
|
Use event-capable variants or optional reporter parameters so existing business logic stays intact.
|
||||||
|
|
||||||
|
**Step 5: Run the focused core tests**
|
||||||
|
|
||||||
|
Run: `cargo test --package aim-core --test install_integration`
|
||||||
|
Expected: PASS.
|
||||||
|
|
||||||
|
**Step 6: Commit**
|
||||||
|
|
||||||
|
```bash
|
||||||
|
git add crates/aim-core/src/app/progress.rs crates/aim-core/src/app/mod.rs crates/aim-core/src/app/add.rs crates/aim-core/src/app/update.rs crates/aim-core/src/app/remove.rs crates/aim-core/tests/install_integration.rs crates/aim-core/tests/update_planning.rs crates/aim-core/tests/remove_flow.rs
|
||||||
|
git commit -m "feat: add core operation progress events"
|
||||||
|
```
|
||||||
|
|
||||||
|
### Task 3: Emit real add/install progress, including download progress when possible
|
||||||
|
|
||||||
|
**Files:**
|
||||||
|
- Modify: `crates/aim-core/src/app/add.rs`
|
||||||
|
- Modify: `crates/aim-core/src/integration/install.rs`
|
||||||
|
- Test: `crates/aim-core/tests/install_integration.rs`
|
||||||
|
- Test: `crates/aim-cli/tests/end_to_end_cli.rs`
|
||||||
|
|
||||||
|
**Step 1: Write the failing tests**
|
||||||
|
|
||||||
|
Add tests that assert the add/install path emits:
|
||||||
|
- stage transitions before final success
|
||||||
|
- download progress events when content length is known or simulated
|
||||||
|
- fallback stage events when byte totals are unavailable
|
||||||
|
|
||||||
|
**Step 2: Run the focused tests to verify they fail**
|
||||||
|
|
||||||
|
Run: `cargo test --package aim-core --test install_integration`
|
||||||
|
Expected: FAIL because download and install helpers do not yet emit progress.
|
||||||
|
|
||||||
|
**Step 3: Implement minimal progress emission**
|
||||||
|
|
||||||
|
Refactor download and install helpers just enough to report:
|
||||||
|
- download started
|
||||||
|
- download byte progress when available
|
||||||
|
- payload staging
|
||||||
|
- desktop integration
|
||||||
|
- icon extraction
|
||||||
|
- refresh and finalize
|
||||||
|
|
||||||
|
Keep the blocking transport for now.
|
||||||
|
|
||||||
|
**Step 4: Run focused tests**
|
||||||
|
|
||||||
|
Run: `cargo test --package aim-core --test install_integration`
|
||||||
|
Expected: PASS.
|
||||||
|
|
||||||
|
**Step 5: Commit**
|
||||||
|
|
||||||
|
```bash
|
||||||
|
git add crates/aim-core/src/app/add.rs crates/aim-core/src/integration/install.rs crates/aim-core/tests/install_integration.rs crates/aim-cli/tests/end_to_end_cli.rs
|
||||||
|
git commit -m "feat: emit live add install progress"
|
||||||
|
```
|
||||||
|
|
||||||
|
### Task 4: Build shared CLI styling and prompt primitives
|
||||||
|
|
||||||
|
**Files:**
|
||||||
|
- Create: `crates/aim-cli/src/ui/theme.rs`
|
||||||
|
- Create: `crates/aim-cli/src/ui/progress.rs`
|
||||||
|
- Modify: `crates/aim-cli/src/ui/mod.rs`
|
||||||
|
- Modify: `crates/aim-cli/src/ui/prompt.rs`
|
||||||
|
- Modify: `crates/aim-cli/src/ui/render.rs`
|
||||||
|
- Test: `crates/aim-cli/tests/ui_summary.rs`
|
||||||
|
|
||||||
|
**Step 1: Write the failing tests**
|
||||||
|
|
||||||
|
Add focused tests that assert:
|
||||||
|
- section headers and empty states use new wording
|
||||||
|
- warnings are rendered consistently
|
||||||
|
- prompt copy still contains the tracking choice details
|
||||||
|
|
||||||
|
**Step 2: Run the focused tests to verify they fail**
|
||||||
|
|
||||||
|
Run: `cargo test --package aim-cli --test ui_summary`
|
||||||
|
Expected: FAIL because there is no shared styling layer.
|
||||||
|
|
||||||
|
**Step 3: Implement minimal CLI UI helpers**
|
||||||
|
|
||||||
|
Add:
|
||||||
|
- shared console styles and header helpers
|
||||||
|
- shared prompt theme for `dialoguer`
|
||||||
|
- a thin indicatif wrapper for spinners and progress bars
|
||||||
|
|
||||||
|
**Step 4: Migrate prompt and summary rendering onto the shared helpers**
|
||||||
|
|
||||||
|
Do not change core logic in this step.
|
||||||
|
|
||||||
|
**Step 5: Re-run the focused tests**
|
||||||
|
|
||||||
|
Run: `cargo test --package aim-cli --test ui_summary`
|
||||||
|
Expected: PASS.
|
||||||
|
|
||||||
|
**Step 6: Commit**
|
||||||
|
|
||||||
|
```bash
|
||||||
|
git add crates/aim-cli/src/ui/theme.rs crates/aim-cli/src/ui/progress.rs crates/aim-cli/src/ui/mod.rs crates/aim-cli/src/ui/prompt.rs crates/aim-cli/src/ui/render.rs crates/aim-cli/tests/ui_summary.rs
|
||||||
|
git commit -m "feat: add shared cli styling and prompt helpers"
|
||||||
|
```
|
||||||
|
|
||||||
|
### Task 5: Wire live progress rendering through CLI dispatch
|
||||||
|
|
||||||
|
**Files:**
|
||||||
|
- Modify: `crates/aim-cli/src/lib.rs`
|
||||||
|
- Modify: `crates/aim-cli/src/main.rs`
|
||||||
|
- Modify: `crates/aim-cli/src/ui/progress.rs`
|
||||||
|
- Test: `crates/aim-cli/tests/end_to_end_cli.rs`
|
||||||
|
|
||||||
|
**Step 1: Write the failing tests**
|
||||||
|
|
||||||
|
Add tests that assert:
|
||||||
|
- add/install commands emit status output before the final summary marker
|
||||||
|
- update execution emits per-app progress lines and a final styled summary
|
||||||
|
- remove emits status plus final completion output
|
||||||
|
|
||||||
|
**Step 2: Run the focused tests to verify they fail**
|
||||||
|
|
||||||
|
Run: `cargo test --package aim-cli --test end_to_end_cli`
|
||||||
|
Expected: FAIL because dispatch still returns only a final renderable result.
|
||||||
|
|
||||||
|
**Step 3: Implement minimal dispatch integration**
|
||||||
|
|
||||||
|
Thread a CLI reporter through dispatch so long-running operations can stream progress while preserving the final typed result for summary rendering.
|
||||||
|
|
||||||
|
**Step 4: Re-run the CLI tests**
|
||||||
|
|
||||||
|
Run: `cargo test --package aim-cli --test end_to_end_cli`
|
||||||
|
Expected: PASS.
|
||||||
|
|
||||||
|
**Step 5: Commit**
|
||||||
|
|
||||||
|
```bash
|
||||||
|
git add crates/aim-cli/src/lib.rs crates/aim-cli/src/main.rs crates/aim-cli/src/ui/progress.rs crates/aim-cli/tests/end_to_end_cli.rs
|
||||||
|
git commit -m "feat: render live cli progress"
|
||||||
|
```
|
||||||
|
|
||||||
|
### Task 6: Restyle all command summaries and refresh documentation
|
||||||
|
|
||||||
|
**Files:**
|
||||||
|
- Modify: `crates/aim-cli/src/ui/render.rs`
|
||||||
|
- Modify: `README.md`
|
||||||
|
- Test: `crates/aim-cli/tests/end_to_end_cli.rs`
|
||||||
|
- Test: `crates/aim-cli/tests/ui_summary.rs`
|
||||||
|
|
||||||
|
**Step 1: Write the failing assertions**
|
||||||
|
|
||||||
|
Add or tighten tests for:
|
||||||
|
- list empty state and populated list presentation
|
||||||
|
- remove completion summary
|
||||||
|
- update review summary for bare `aim`
|
||||||
|
- README text matching actual `aim` versus `aim update` behavior
|
||||||
|
|
||||||
|
**Step 2: Run focused tests**
|
||||||
|
|
||||||
|
Run: `cargo test --package aim-cli --test end_to_end_cli`
|
||||||
|
Expected: FAIL for updated wording.
|
||||||
|
|
||||||
|
**Step 3: Implement minimal rendering refresh**
|
||||||
|
|
||||||
|
Use the shared theme helpers so every command output looks coherent.
|
||||||
|
|
||||||
|
**Step 4: Re-run focused tests**
|
||||||
|
|
||||||
|
Run: `cargo test --package aim-cli --test end_to_end_cli`
|
||||||
|
Expected: PASS.
|
||||||
|
|
||||||
|
**Step 5: Commit**
|
||||||
|
|
||||||
|
```bash
|
||||||
|
git add crates/aim-cli/src/ui/render.rs README.md crates/aim-cli/tests/end_to_end_cli.rs crates/aim-cli/tests/ui_summary.rs
|
||||||
|
git commit -m "docs: refresh cli command presentation"
|
||||||
|
```
|
||||||
|
|
||||||
|
### Task 7: Full verification
|
||||||
|
|
||||||
|
**Files:**
|
||||||
|
- Modify: none expected
|
||||||
|
|
||||||
|
**Step 1: Run format check**
|
||||||
|
|
||||||
|
Run: `cargo fmt --check`
|
||||||
|
Expected: PASS.
|
||||||
|
|
||||||
|
**Step 2: Run clippy**
|
||||||
|
|
||||||
|
Run: `cargo clippy --workspace --all-targets --all-features -- -D warnings`
|
||||||
|
Expected: PASS.
|
||||||
|
|
||||||
|
**Step 3: Run tests**
|
||||||
|
|
||||||
|
Run: `cargo test --workspace`
|
||||||
|
Expected: PASS.
|
||||||
|
|
||||||
|
**Step 4: Fix only regressions caused by the CLI UX and progress work, then re-run verification**
|
||||||
|
|
||||||
|
**Step 5: Commit**
|
||||||
|
|
||||||
|
```bash
|
||||||
|
git add -A
|
||||||
|
git commit -m "test: verify cli ux and progress redesign"
|
||||||
|
```
|
||||||
Loading…
Add table
Add a link
Reference in a new issue