Skip to content

feat(index): show indexing progress during background code indexing #1923

@bug-ops

Description

@bug-ops

Problem

When the code indexer runs at startup (tokio::spawn in agent_setup.rs), the user sees no progress feedback. For a typical Zeph workspace (~571 indexable files, ~410 Rust sources), each file requires an embedding call to the LLM provider — this can take 30–120 seconds total. During this time:

  • CLI mode: silent, nothing is shown
  • TUI mode: no spinner, no status label — only a log line tracing::info!("project indexed") appears at the very end

The user has no idea whether indexing is still running or how far along it is.

Analysis

The current flow in indexer.rs (index_project()):

  1. Walks the file tree, collects entries: Vec<_> — total count is known upfront (total = entries.len())
  2. Iterates with for (i, entry) in entries.iter().enumerate() — both i and total are available at every step
  3. Only emits tracing::info!(progress = "{i+1}/{total}") — no channel to surface this to the UI

All the data needed for a progress display is already there — it just isn't surfaced to the caller.

Proposed solution

1. Add a progress channel to IndexerConfig

pub struct IndexProgress {
    pub files_done: usize,
    pub files_total: usize,
    pub chunks_created: usize,
}

Add progress_tx: Option<tokio::sync::watch::Sender<IndexProgress>> to IndexerConfig.
Send an update inside the loop after each file is processed.

2. CLI mode: print progress to the channel

In agent_setup.rs, after spawning the background task, send a system message:

⚙ Indexing codebase in the background (571 files) — you can start chatting now.

On completion:

✓ Codebase indexed: 410 files, 4823 chunks (42s) — code search is ready.

3. TUI mode: show spinner + counter in the status bar

Wire the watch::Receiver<IndexProgress> into App:

  • During indexing: ⠸ Indexing codebase… 127/571 files (22%)
  • On completion: ✓ Index ready (571 files, 4823 chunks) shown for 3s, then cleared

The TUI already has status_label: Option<String> and a spinner — minimal wiring needed.

Scope

  • crates/zeph-index/src/indexer.rs — add IndexProgress struct, send updates via watch::Sender after each file
  • src/agent_setup.rs — create the channel, pass sender to indexer, emit start/done messages
  • crates/zeph-tui/src/app.rs — receive IndexProgress and render in status bar
  • crates/zeph-channels/src/cli.rs or agent startup — emit start/done system messages in CLI mode

Acceptance criteria

  • Progress counter is visible in both CLI and TUI modes during background indexing
  • TUI status bar shows N/M files (X%) updated after each file
  • Completion message includes: files indexed, chunks created, total duration
  • No blocking — user can interact while indexing runs in the background
  • No performance regression from progress update overhead

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or request

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions