Skip to content

UX: Show initialization progress and hide cursor until backend ready #57

@randomm

Description

@randomm

Problem

The Setting up environment... spinner completes in ~2 seconds, showing ✓ Ready, but the backend is NOT actually ready. When user types /start immediately after, the system hangs for 5-10 more seconds.

Root Cause (Confirmed by Research)

bootstrap() only loads config, plugins, and file watchers (~2s). The HEAVY initialization is lazy:

  1. Provider.state() (~1-3s) — fetches model configs, checks auth keys for ~30 providers
  2. MCP.state() (~2-5s) — connects to each MCP server (stdio/HTTP transport + listTools())
  3. Agent.state() (~0.2s) — loads agent definitions

These trigger on the FIRST command (resolveTools() in session/tools.ts), NOT during bootstrap.

Fix

Force eager initialization INSIDE the bootstrap callback, before showing ✓ Ready:

await bootstrap(process.cwd(), async () => {
  // Force eager init of heavy subsystems
  await Promise.all([
    Provider.list(),    // Forces Provider.state() 
    MCP.tools(),        // Forces MCP.state() — connects all servers
  ])
  // Now we're actually ready
  setup.stop(true)
  write('✓ Ready')
})

This moves the 5-10s delay INTO the spinner, so users see ⠋ Setting up environment... for the full duration and ✓ Ready means it's truly ready.

Key Files

  • packages/opencode/src/cli/lite/index.ts — add eager init calls inside bootstrap callback
  • packages/opencode/src/provider/provider.tsProvider.list() forces state init
  • packages/opencode/src/mcp/index.tsMCP.tools() forces connection

Related

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions