Skip to content

feat(onboard): uplift first-run wizard flow#690

Closed
gh-xj wants to merge 53 commits intoeastreams:devfrom
gh-xj:feat/onboard-cli-uplift-20260328
Closed

feat(onboard): uplift first-run wizard flow#690
gh-xj wants to merge 53 commits intoeastreams:devfrom
gh-xj:feat/onboard-cli-uplift-20260328

Conversation

@gh-xj
Copy link
Copy Markdown
Collaborator

@gh-xj gh-xj commented Mar 29, 2026

Summary

  • Problem:
    Guided onboarding had grown into a monolithic flow with no explicit workspace or protocol stages, weak back-navigation, and readiness handling that could surface review and write too early or persist values the user never explicitly chose.
  • Why it matters:
    First-run setup is the main path to a working CLI. When reruns blur detected versus current values or blocked preflight results do not stop before write, operators lose trust in loongclaw onboard and can end up with confusing config outcomes.
  • What changed:
    Extracted a shared OnboardDraft plus OnboardFlowController, made the wizard an explicit eight-stage flow, added interactive workspace and ACP protocol stages, grouped readiness outcomes (ready, ready with warnings, blocked), added plain-prompt fallback for degraded terminals, tightened rerun/file-root/review-write semantics, and aligned README plus product specs with the shipped contract.
  • What did not change (scope boundary):
    This PR does not add a permanent dashboard or full TUI shell, does not change the broader install flow, and does not introduce a new config schema or provider catalog surface outside onboarding orchestration and presentation.

Linked Issues

Change Type

  • Bug fix
  • Feature
  • Refactor
  • Documentation
  • Security hardening
  • CI / workflow / release

Touched Areas

  • Kernel / policy / approvals
  • Contracts / protocol / spec
  • Daemon / CLI / install
  • Providers / routing
  • Tools
  • Browser automation
  • Channels / integrations
  • ACP / conversation / session runtime
  • Memory / context assembly
  • Config / migration / onboarding
  • Docs / contributor workflow
  • CI / release / workflows

Risk Track

  • Track A (routine / low-risk)
  • Track B (higher-risk / policy-impacting)

If Track B, fill these in:

  • Risk notes:
    Onboarding now owns more of the first-run decision path through a shared controller and explicit readiness gate, so regressions would show up as navigation drift, rerun-state mistakes, or write/rollback mistakes rather than isolated copy issues.
  • Rollout / guardrails:
    Land on dev only, rely on the expanded onboard_cli integration suite plus full workspace gates, and keep existing backup/restore plus post-write verification paths active. Blocked outcomes stop before write; degraded terminals fall back to plain prompts.
  • Rollback path:
    Revert this PR to restore the prior onboarding path. If a regression is discovered after merge, operators can rerun loongclaw onboard or loongclaw doctor --fix from preserved configs/backups.

Validation

  • cargo fmt --all -- --check
  • cargo clippy --workspace --all-targets --all-features -- -D warnings
  • cargo test --workspace --locked
  • cargo test --workspace --all-features --locked
  • Relevant architecture / dep-graph / docs checks for touched areas
  • Additional scenario, benchmark, or manual checks when behavior changed
  • If this changes config/env fallback, limits, or defaults: include before/after behavior and regression coverage for explicit path, fallback path, and boundary values
  • If tests mutate process-global env: document how state is restored or serialized

Commands and evidence:

cargo fmt --all -- --check
pass

cargo clippy --workspace --all-targets --all-features -- -D warnings
pass

cargo test -p loongclaw-daemon cli_onboard_help_mentions_detected_reusable_settings -- --nocapture
pass

cargo test -p loongclaw-daemon onboard_cli -- --nocapture
pass

rg -n "workspace|protocol|environment check|ready with warnings|doctor --fix|start fresh|detected starting point" README.md docs/product-specs/onboarding.md docs/product-specs/doctor.md
pass; README, onboarding spec, and doctor spec all reflect the shipped wizard contract

cargo test --workspace --locked
pass

cargo test --workspace --all-features --locked
pass

Before/after behavior and regression coverage:

  • Before: guided flow could reach review/write before a true environment-check boundary, fail-level preflight and warn-level preflight shared the same confirmation path, and reruns could materialize a blank tools.file_root as an explicit persisted value.
  • After: workspace and protocol stages are explicit, environment check resolves to ready, ready with warnings, or blocked before review/write, reruns preserve current-versus-detected labeling, and blank file roots stay implicit unless the user explicitly selects them.
  • Regression coverage: crates/daemon/tests/integration/onboard_cli.rs now covers back-navigation, skip preservation, workspace/protocol steps, readiness grouping, blocked-after-verification reporting, degraded-terminal fallback, and rerun semantics around blank file roots.
  • Process-global env handling: the touched onboarding/integration coverage continues to use the repo's scoped env helpers and serialized test harness for env-sensitive paths.

User-visible / Operator-visible Changes

  • Guided onboarding now runs as an eight-stage wizard: welcome, authentication, runtime defaults, workspace, protocols, environment check, review and write, and ready.
  • Reruns label current saved values separately from the detected starting point so operators can choose whether to keep, import, or start fresh without losing provenance.
  • Environment check now reports green, ready with warnings, or blocked. Warn-only runs require explicit confirmation before write; blocked runs stop before write and point users to loongclaw doctor or loongclaw doctor --fix.
  • When rich terminal prompts are unavailable, onboarding falls back to plain prompts instead of aborting the flow.

Failure Recovery

  • Fast rollback or disable path:
    Revert this PR to restore the previous wizard semantics. Runtime/operator recovery stays the same: overwrite paths keep backups and blocked post-write verification preserves the old config.
  • Observable failure symptoms reviewers should watch for:
    Guided flow jumping from protocols straight to review, blocked preflight still allowing write confirmation, reruns persisting an explicit blank tools.file_root, or plain interactive terminals aborting instead of falling back.

Adjacent Context

Reviewer Focus

  • crates/daemon/src/onboard_cli.rs, crates/daemon/src/onboard_flow.rs, and crates/daemon/src/onboard_state.rs for step ordering, shared draft ownership, and back/skip semantics.
  • crates/daemon/src/onboard_workspace.rs, crates/daemon/src/onboard_protocols.rs, crates/daemon/src/onboard_preflight.rs, and crates/daemon/src/onboard_finalize.rs for persistence, readiness grouping, outcome reporting, and rollback behavior.
  • crates/daemon/tests/integration/onboard_cli.rs, README.md, docs/product-specs/onboarding.md, and docs/product-specs/doctor.md for contract coverage and user-facing alignment.

Summary by CodeRabbit

  • New Features

    • Eight-stage guided onboarding wizard with back-navigation, explicit write confirmation, and rich/plain prompt fallbacks; updated progress labels (review-and-write / ready)
    • Environment checks with three outcomes (green / ready with warnings / blocked) and clear next steps
  • Improvements

    • Reruns preserve and display current vs detected values for clearer review and choice
    • Success screen shows outcome and verification status; failed verification can roll back with guided messaging
    • Better protocol/workspace defaults, ACP backend handling, and write-discipline enforcement
  • Documentation

    • Expanded onboarding and doctor docs with detailed behaviors and acceptance criteria

Copilot AI review requested due to automatic review settings March 29, 2026 06:15
@coderabbitai
Copy link
Copy Markdown

coderabbitai bot commented Mar 29, 2026

Note

Reviews paused

It looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the reviews.auto_review.auto_pause_after_reviewed_commits setting.

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review
📝 Walkthrough

Walkthrough

Adds a stepwise onboarding wizard with provenance-tracked draft state, a flow controller and guided-step runner, rich/plain interaction-mode detection with back-navigation, workspace/protocol derivation and validation, grouped preflight outcome classification (including post-write verification), and outcome-aware success summaries.

Changes

Cohort / File(s) Summary
Documentation
README.md, docs/product-specs/onboarding.md, docs/product-specs/doctor.md, docs/releases/architecture-drift-2026-03.md
Expanded onboarding and doctor acceptance criteria, enumerated wizard stages and rerun behavior, documented environment-check outcomes and prompt-mode fallback; updated release/report timestamps and metrics.
Onboarding State & Flow
crates/daemon/src/onboard_state.rs, crates/daemon/src/onboard_flow.rs, crates/daemon/src/lib.rs
Added onboarding state types (value origins, wizard steps, outcomes, interaction modes), OnboardDraft with provenance and mutators, OnboardFlowController, GuidedOnboardFlowStepRunner trait, and exported new modules.
Onboarding CLI & UI
crates/daemon/src/onboard_cli.rs, crates/daemon/src/onboard_presentation.rs, crates/daemon/tests/integration/onboard_cli.rs
Reworked CLI to use the flow controller and guided-runner pattern; introduced SelectAction::{Selected, Back}, back-navigation and write-confirmation guard, interaction-mode detection and rich→plain fallback, changed selection API and updated progress/presentation strings; tests adapted for new flow and summary fields.
Workspace Step & Config
crates/daemon/src/onboard_workspace.rs, crates/app/src/config/tools.rs
New workspace-step derivation/validation/apply logic for sqlite path and tool file_root with origin tracking and persistence rules; ToolConfig::explicit_file_root() added and resolved-file-root now ignores whitespace-only values.
Protocol Step
crates/daemon/src/onboard_protocols.rs
New protocol-step derivation, ACP backend listing/resolution, bootstrap MCP server summarization, and helpers for protocol defaults and selection resolution.
Preflight & Finalize
crates/daemon/src/onboard_preflight.rs, crates/daemon/src/onboard_finalize.rs
Grouped preflight checks into subsystems, added outcome derivation including post-write verification checks, extended OnboardingSuccessSummary with outcome and verification_status, and adjusted success-screen copy and conditional verification display.
Tests & Integration
crates/daemon/tests/integration/onboard_cli.rs
Expanded integration tests for step ordering, write-confirmation guard and rollback, workspace-root derivation/persistence, scripted UI supports SelectAction::Back, and updated success-summary construction in tests.

Sequence Diagram

sequenceDiagram
    participant User
    participant CLI as Onboard CLI
    participant UI as OnboardUi
    participant Flow as OnboardFlowController
    participant Runner as GuidedOnboardFlowStepRunner
    participant Draft as OnboardDraft

    User->>CLI: run onboarding
    CLI->>UI: set_interaction_mode(mode)
    CLI->>Draft: OnboardDraft::from_config(...)
    CLI->>Flow: OnboardFlowController::new(draft)

    loop per wizard step (until EnvironmentCheck)
        Flow->>Runner: run_step(current_step, &mut draft)
        Runner->>UI: render step UI
        UI->>User: prompt / select
        alt user selects value
            User->>UI: choose
            UI->>Runner: SelectAction::Selected(index)
            Runner->>Draft: apply selection
            Runner->>Flow: Next
        else user presses back
            User->>UI: "back"
            UI->>Runner: SelectAction::Back
            Runner->>Flow: Back
        else user skips
            Runner->>Flow: Skip
        end
        Flow->>Flow: advance/back/skip cursor
    end

    CLI->>CLI: run preflight checks
    CLI->>CLI: derive OnboardOutcome (green/warnings/blocked)
    CLI->>UI: render review & write confirmation
    UI->>User: show diff and ask confirm
    User->>CLI: confirm
    CLI->>Draft: write config
    CLI->>UI: build success summary with outcome
    UI->>User: display final readiness
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~60 minutes

Possibly related PRs

Suggested reviewers

  • chumyin

Poem

🐰 Eight soft hops from welcome to ready,
Drafts recall where values first came — steady,
Back-steps, plain prompts when terminals lack flair,
Roots and protocols checked with gentle care,
A tiny rabbit cheers: onboard complete!

🚥 Pre-merge checks | ✅ 2 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 31.35% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (2 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The PR title 'feat(onboard): uplift first-run wizard flow' clearly summarizes the main change: a significant refactoring of the onboarding system into an explicit eight-stage wizard. The title is concise, specific, and directly reflects the primary objective documented in the PR.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@github-actions github-actions bot added documentation Improvements or additions to documentation. spec Architecture boundaries, product specs, and design docs. daemon Daemon binary, CLI entrypoints, and install flow. config Runtime config parsing, schema, and defaults. docs Contributor docs, references, and issue/PR guidance. size: XL Very large pull request: more than 1000 changed lines. labels Mar 29, 2026
Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Refactors and expands loongclaw onboard into an explicit 8-stage first-run wizard with shared draft/state handling, clearer readiness gating (ready, ready with warnings, blocked), new workspace/protocol stages, and updated docs/tests to match the shipped flow contract.

Changes:

  • Introduces OnboardDraft + OnboardFlowController to coordinate an 8-step guided wizard with origins tracking and back/skip semantics.
  • Adds explicit workspace and protocol (ACP/MCP) stages plus grouped preflight/readiness outcomes and post-write verification reporting.
  • Updates integration tests and documentation/specs (README + product specs) to reflect the new onboarding contract.

Reviewed changes

Copilot reviewed 14 out of 14 changed files in this pull request and generated 3 comments.

Show a summary per file
File Description
docs/product-specs/onboarding.md Marks acceptance criteria as shipped and documents the 8-stage wizard + readiness outcomes.
docs/product-specs/doctor.md Aligns doctor acceptance criteria with onboarding readiness/repair handoff expectations.
README.md Documents the new wizard stages, rerun semantics, readiness outcomes, and prompt fallback behavior.
crates/daemon/src/lib.rs Exposes new onboarding modules (onboard_flow, onboard_state).
crates/daemon/src/onboard_cli.rs Main orchestration refactor: flow controller integration, interaction-mode selection, workspace/protocol steps, readiness gating, write/rollback/verification behavior.
crates/daemon/src/onboard_flow.rs Adds ordered-step controller and runner interface for guided flow execution.
crates/daemon/src/onboard_state.rs Adds shared onboarding draft model, value origins, interaction modes, and outcome types.
crates/daemon/src/onboard_workspace.rs Implements workspace step value derivation, persistence, and path validation.
crates/daemon/src/onboard_protocols.rs Implements protocol step value derivation + ACP backend discovery/defaulting helpers.
crates/daemon/src/onboard_preflight.rs Adds protocol checks and grouped preflight presentation + outcome computation helpers.
crates/daemon/src/onboard_finalize.rs Extends success summary to include outcome + verification status and adjusts final screen copy.
crates/app/src/config/tools.rs Adds explicit_file_root() to distinguish blank/implicit values from explicit configuration.
crates/daemon/tests/integration/onboard_cli.rs Expands coverage for step order, back/skip, file_root blank semantics, readiness grouping, and post-write verification rollback/reporting.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread crates/daemon/src/onboard_cli.rs Outdated
Comment on lines +1659 to +1692
async fn run_authentication_step(&mut self, draft: &mut OnboardDraft) -> CliResult<()> {
let guided_prompt_path = resolve_guided_prompt_path(self.options, &draft.config);
let selected_provider = resolve_provider_selection(
self.options,
&draft.config,
&self.starting_selection.provider_selection,
guided_prompt_path,
self.ui,
self.context,
)?;
draft.set_provider_config(selected_provider);

let available_models = load_onboarding_model_catalog(self.options, &draft.config).await;
let selected_model = resolve_model_selection(
self.options,
&draft.config,
guided_prompt_path,
&available_models,
self.ui,
self.context,
)?;
draft.set_provider_model(selected_model);

let default_api_key_env = preferred_api_key_env_default(&draft.config);
let selected_api_key_env = resolve_api_key_env_selection(
self.options,
&draft.config,
default_api_key_env,
guided_prompt_path,
self.ui,
self.context,
)?;
draft.set_provider_credential_env(selected_api_key_env);
Ok(())
Copy link

Copilot AI Mar 29, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Back navigation from the authentication step isn’t handled: resolve_provider_selection / resolve_model_selection / resolve_api_key_env_selection can now return SelectAction::Back (surfaced as the ONBOARD_BACK_NAVIGATION_SIGNAL error via select_one_selected_index), but run_authentication_step currently propagates that error and aborts the flow with an internal sentinel string instead of returning OnboardFlowStepAction::Back to the controller. Handle the back signal in this step (similar to run_runtime_defaults_step) so selecting “Back” navigates to the previous wizard step rather than failing the command.

Suggested change
async fn run_authentication_step(&mut self, draft: &mut OnboardDraft) -> CliResult<()> {
let guided_prompt_path = resolve_guided_prompt_path(self.options, &draft.config);
let selected_provider = resolve_provider_selection(
self.options,
&draft.config,
&self.starting_selection.provider_selection,
guided_prompt_path,
self.ui,
self.context,
)?;
draft.set_provider_config(selected_provider);
let available_models = load_onboarding_model_catalog(self.options, &draft.config).await;
let selected_model = resolve_model_selection(
self.options,
&draft.config,
guided_prompt_path,
&available_models,
self.ui,
self.context,
)?;
draft.set_provider_model(selected_model);
let default_api_key_env = preferred_api_key_env_default(&draft.config);
let selected_api_key_env = resolve_api_key_env_selection(
self.options,
&draft.config,
default_api_key_env,
guided_prompt_path,
self.ui,
self.context,
)?;
draft.set_provider_credential_env(selected_api_key_env);
Ok(())
async fn run_authentication_step(
&mut self,
draft: &mut OnboardDraft,
) -> CliResult<OnboardFlowStepAction> {
let guided_prompt_path = resolve_guided_prompt_path(self.options, &draft.config);
let selected_provider = match resolve_provider_selection(
self.options,
&draft.config,
&self.starting_selection.provider_selection,
guided_prompt_path,
self.ui,
self.context,
) {
Ok(provider) => provider,
Err(err) => {
if err.to_string() == ONBOARD_BACK_NAVIGATION_SIGNAL {
return Ok(OnboardFlowStepAction::Back);
} else {
return Err(err.into());
}
}
};
draft.set_provider_config(selected_provider);
let available_models = load_onboarding_model_catalog(self.options, &draft.config).await;
let selected_model = match resolve_model_selection(
self.options,
&draft.config,
guided_prompt_path,
&available_models,
self.ui,
self.context,
) {
Ok(model) => model,
Err(err) => {
if err.to_string() == ONBOARD_BACK_NAVIGATION_SIGNAL {
return Ok(OnboardFlowStepAction::Back);
} else {
return Err(err.into());
}
}
};
draft.set_provider_model(selected_model);
let default_api_key_env = preferred_api_key_env_default(&draft.config);
let selected_api_key_env = match resolve_api_key_env_selection(
self.options,
&draft.config,
default_api_key_env,
guided_prompt_path,
self.ui,
self.context,
) {
Ok(api_key_env) => api_key_env,
Err(err) => {
if err.to_string() == ONBOARD_BACK_NAVIGATION_SIGNAL {
return Ok(OnboardFlowStepAction::Back);
} else {
return Err(err.into());
}
}
};
draft.set_provider_credential_env(selected_api_key_env);
Ok(OnboardFlowStepAction::Next)

Copilot uses AI. Check for mistakes.
Comment on lines 152 to +190
@@ -132,6 +155,8 @@ impl OnboardRuntimeContext {
render_width: detect_render_width(),
workspace_root: env::current_dir().ok(),
codex_config_paths: default_codex_config_paths(),
attended_terminal: user_attended(),
rich_prompt_ui_supported: rich_prompt_ui_available(),
}
}

@@ -144,10 +169,35 @@ impl OnboardRuntimeContext {
render_width,
workspace_root,
codex_config_paths: codex_config_paths.into_iter().collect(),
attended_terminal: true,
rich_prompt_ui_supported: true,
}
}
}

fn resolve_onboard_interaction_mode(
non_interactive: bool,
attended_terminal: bool,
rich_prompt_ui_supported: bool,
) -> OnboardInteractionMode {
if non_interactive {
return OnboardInteractionMode::NonInteractive;
}
if attended_terminal && rich_prompt_ui_supported {
return OnboardInteractionMode::RichInteractive;
}
OnboardInteractionMode::PlainInteractive
}
Copy link

Copilot AI Mar 29, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

OnboardRuntimeContext::capture sets both attended_terminal and rich_prompt_ui_supported from user_attended() (rich_prompt_ui_available() is just user_attended()), so resolve_onboard_interaction_mode will never choose PlainInteractive for an attended terminal in real runs. This makes the documented “plain-prompt fallback for degraded terminals” effectively unreachable. Consider implementing a real rich-prompt capability check (or dynamically falling back to plain prompts when dialoguer returns an I/O error) so rich_prompt_ui_supported can differ from attended_terminal.

Copilot uses AI. Check for mistakes.
Comment thread crates/daemon/src/onboard_workspace.rs Outdated
Comment on lines +25 to +41
let explicit_file_root = draft.config.tools.explicit_file_root();
let persist_displayed_file_root =
explicit_file_root.is_some() || context.workspace_root.is_some();
let (file_root, file_root_origin) =
if explicit_file_root.is_none() && context.workspace_root.is_some() {
(
context
.workspace_root
.clone()
.unwrap_or_else(|| draft.workspace.file_root.clone()),
Some(OnboardValueOrigin::DetectedStartingPoint),
)
} else {
(
draft.workspace.file_root.clone(),
draft.origin_for(OnboardDraft::WORKSPACE_FILE_ROOT_KEY),
)
Copy link

Copilot AI Mar 29, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

persist_displayed_file_root becomes true whenever context.workspace_root is Some(_). In normal CLI runs workspace_root is populated from env::current_dir(), so rerunning onboarding against a config with an implicit/blank tools.file_root will materialize and persist the current directory as an explicit tools.file_root even if the user just hits Enter. This conflicts with the stated goal that blank file roots remain implicit unless explicitly chosen. Consider making persistence depend on an explicit existing value or an explicit user override (e.g., persist only when explicit_file_root.is_some() or when the user edits the prompt), and avoid forcing DetectedStartingPoint origin purely because workspace_root exists.

Copilot uses AI. Check for mistakes.
gh-xj added 2 commits March 29, 2026 19:12
…din infra

Replace the trait-based UI abstraction with simple free functions that
read/write directly to stdin/stdout.  The guided flow now runs through
RatatuiOnboardRunner; pre-flow and post-flow screens use the new
prompt_stdin_* / print_stdout_* helpers.

Removed:
- OnboardUi trait and PlainOnboardUi struct
- StdioOnboardLineReader (background thread + paste-drain machinery)
- OnboardPromptCapture, OnboardPromptRead, OnboardPromptLineReader
- run_onboard_cli_with_ui (merged into run_onboard_cli_inner)
- dialoguer dependency (already gone from Cargo.toml)
- onboard_presentation.rs (moved to onboard_cli::presentation earlier)

Added:
- read_stdin_line, prompt_stdin_with_default, prompt_stdin_required,
  prompt_stdin_confirm, prompt_stdin_select
- print_stdout_lines, print_stdout_message

All resolver functions retain their signatures (minus the ui param) as
dead code covered by #![allow(dead_code)] -- they will be reconnected
in Tasks 8-10.

Unit and integration tests that depend on OnboardUi are disabled with
#[cfg(any())] and will be rewritten in Tasks 8-9.
Re-enable the test module (#[cfg(test)] mod tests) that was disabled
with #[cfg(any())] after the OnboardUi trait removal.

Removed all test infrastructure that depended on the deleted OnboardUi
trait: TestOnboardUi, SelectOnlyTestUi, AllowEmptyOnlyTestUi,
TestPromptLineReader, and all tests that scripted interactive flows
through the old UI parameter. Those interactive paths are now covered
by the RatatuiOnboardRunner tests in onboard_tui::runner::tests.

Kept 66 pure function tests covering: preflight checks, probe failure
diagnostics, credential validation, config resolution, rendering
screens, backup/rollback, web search provider recommendations, and
select/option formatting.
@gh-xj gh-xj marked this pull request as draft March 30, 2026 04:15
gh-xj added 2 commits March 29, 2026 21:23
Fix the non-interactive TUI bug: guard RatatuiOnboardRunner creation
with !options.non_interactive so headless/CI runs never attempt to
initialize a terminal.

Add apply_non_interactive_overrides() that applies CLI flags
(--provider, --model, --api-key-env, --personality, --memory-profile,
--system-prompt, --web-search-provider, --web-search-api-key-env) and
workspace defaults to the draft for non-interactive mode, replacing
the old resolver function call chain.

Add run_onboard_cli_with_context() test-only entrypoint so integration
tests can supply a custom OnboardRuntimeContext without touching the
real terminal.

Rewrite integration tests:
- Remove ScriptedOnboardUi, WriteConfirmationGuardUi, and OnboardUi
  trait impls (no longer exist)
- Remove run_scripted_onboard_flow* helpers
- Convert 20 non-interactive async tests to use
  run_onboard_cli_with_context directly
- Delete 33 interactive flow tests (covered by TUI runner unit tests)
- Keep 133 pure sync tests unchanged (rendering, validation, etc.)
- Re-enable the onboard_cli test module (remove #[cfg(any())] guard)

153 integration tests pass, 733 total integration tests pass,
3856 workspace tests pass.
…lver code

Remove ~1200 lines of dead interactive resolver functions that were
only called by the removed GuidedOnboardUiRunner (resolve_provider_selection,
resolve_model_selection, resolve_api_key_env_selection, etc.).

Extract ~2100 lines of screen rendering, review display, starting point
detail, and utility functions into onboard_cli/screens.rs submodule.

Gate test-only items (SystemPromptSelection, WebSearchCredentialSelection,
apply_selected_api_key_env, etc.) with #[cfg(test)].

Result: onboard_cli.rs reduced from 5990 to 2694 lines (55% reduction).
@github-actions github-actions bot added the dependencies Pull requests that update dependency files. label Mar 30, 2026
gh-xj added 9 commits March 29, 2026 22:25
Move TUI initialization to the start of the interactive onboard flow so
all screens (risk acknowledgement, entry choice, import selection,
shortcut choice, guided wizard, preflight, review, write confirmation,
success) render inside the ratatui alternate screen.

Key changes:

- Create RatatuiOnboardRunner at the top of run_onboard_cli_inner,
  before the risk screen, so it owns the terminal for the entire
  interactive session.

- Add pre-flow screen methods: run_risk_screen, run_entry_choice_screen,
  run_import_candidate_screen, run_shortcut_choice_screen. These use
  full-width content (no progress spine) with the same branded header.

- Add post-flow screen methods: run_preflight_screen (colored
  pass/warn/fail indicators), run_review_screen (scrollable),
  run_write_confirmation_screen, run_success_screen.

- Add generic building blocks: run_confirm_screen (yes/no),
  run_info_screen (scrollable, Enter to continue),
  run_standalone_selection_loop (no spine, for pre/post flow).

- Add load_import_starting_config_with_tui and
  select_interactive_import_starting_config_with_tui to route the
  entry/import choice through the TUI runner.

- Replace all print_stdout_lines + prompt_stdin_confirm calls in the
  interactive path with runner method calls.

- Non-interactive path remains unchanged.

- 17 new headless tests cover all new runner methods.
… screens

Add centered rounded-border dialog boxes to every onboard TUI screen
(welcome, selection, input, confirm, info, risk, preflight, review,
write-confirmation, success). Replace arrow indicators with radio
button symbols and use Cyan accent for selected items. Dialog boxes
are max 60 chars wide, horizontally and vertically centered, with
configurable border colors per screen type.
Replace EnterAlternateScreen/LeaveAlternateScreen with
Viewport::Inline(20) so the onboard TUI renders at the current cursor
position instead of taking over the full terminal. Remove the
OnboardTuiMode enum and all FullScreen vs Inline branching, including
the progress spine sidebar that only applied in fullscreen mode.
@gh-xj gh-xj marked this pull request as ready for review March 30, 2026 08:00
gh-xj added 6 commits March 30, 2026 01:49
- Defer backup-path message until after TUI runner is dropped so it does
  not corrupt the terminal by printing in raw mode (C1).
- Return Ok(()) on Esc in run_info_screen; the info screen is
  informational, not a decision point, so both Enter and Esc should
  dismiss it cleanly (C2).
- Remove dead _body_lines code in run_shortcut_choice_screen that was
  built but never rendered (C3).
- Fix pre-existing clippy issues: replace unreachable!() with proper
  error returns, remove unused import, collapse nested if.
- Show cursor before placeholder text when default is active, so it
  does not look like typed text (M3).
- Remove dead WelcomeScreen widget and its module declaration; the
  runner builds welcome content inline (M4).
… cleanup

- Gracefully fall back to non-interactive path when TUI init fails (dumb
  terminal, piped stdin) instead of hard-erroring
- Render text cursor at actual position instead of always at end, now
  that Left/Right navigation is supported
- Remove stale #[allow(dead_code)] annotations from widgets, layout,
  event source, and runner that are no longer needed
Add 14 new tests covering the interactive TUI runner via ScriptedEventSource:
- Full guided flow through all screens (ACP disabled and enabled)
- Back-navigation across steps (Auth -> Welcome replay)
- Sub-step back-navigation within Authentication
- Ctrl-C interruption on every step type (7 tests)
- Resize event handling on welcome and selection loops
- Zero-item SelectionCardState/Widget guard
@chumyin
Copy link
Copy Markdown
Collaborator

chumyin commented Apr 2, 2026

The integrated fullscreen first-run TUI handoff now also lives on #691 so the app-owned chat shell and the missing-config onboarding path can be reviewed together as one delivery branch.

Leaving #690 open for traceability for now. Until we decide the final landing path, please treat #691 as the combined review branch for the fullscreen chat shell plus first-run TUI handoff.

@chumyin chumyin mentioned this pull request Apr 2, 2026
3 tasks
@chumyin
Copy link
Copy Markdown
Collaborator

chumyin commented Apr 5, 2026

hi @gh-xj, thanks for carrying this forward.

i rechecked the branch lineage and the review context here. this pr is now effectively a traceability branch rather than the landing branch: the integrated fullscreen onboarding/chat path moved to #691, and the current top branch has continued on #866.

because of that overlap, and because this branch is still conflicting, i don't want to merge #690 directly and create another reconciliation pass on top of the later work. i'm leaving this open for traceability for now while the active landing path is settled on the later branch.

@chumyin
Copy link
Copy Markdown
Collaborator

chumyin commented Apr 20, 2026

closing this as outdated. we are redesigning the onboard flow and the tui ui/ux, so this is no longer the direction we want to keep open. we can reopen the work in a fresh pr once the new design is settled.

@chumyin chumyin closed this Apr 20, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

config Runtime config parsing, schema, and defaults. daemon Daemon binary, CLI entrypoints, and install flow. dependencies Pull requests that update dependency files. docs Contributor docs, references, and issue/PR guidance. documentation Improvements or additions to documentation. size: XL Very large pull request: more than 1000 changed lines. spec Architecture boundaries, product specs, and design docs.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants