# Startup Optimization Specification

## Problem Statement

When the application starts, there is a noticeable delay (2-3 seconds) before the input box appears. During this time, the user sees only the banner and then waits with no visual feedback. This creates a poor user experience as the application appears unresponsive.

## Current Startup Sequence

```
1. Display banner
2. Initialize LLM core service
   - Initialize API communication service
   - Initialize provider system
   - Register hooks
   - Start background MCP discovery
   - Initialize conversation
3. Check and display provider warnings
4. Initialize all plugins (sequentially)
   - Initialize each plugin
   - Register hooks for each plugin
5. Display ready message
6. Mark startup as complete
7. Start render loop (input box appears here) ← DELAY OCCURS HERE
8. Start input handler
9. Initialize script widget refresh scheduler
10. Check for first-run wizard
```

## Root Cause Analysis

### Why the delay occurs:
- The render loop doesn't start until step 7, after all initialization is complete
- Plugin initialization is sequential (one at a time), adding latency
- The input box is rendered by the render loop, so it can't appear until the loop starts
- LLM initialization, provider checks, and plugin loading all block the UI from appearing

### Architecture constraints discovered:
- **Message coordinator state**: The `writing_messages` flag and render state must be properly managed
- **Input handler timing**: Input handler needs to be started AFTER certain initialization to avoid conflicts
- **Modal system**: Starting render loop early may interfere with modal state during initialization
- **Plugin dependencies**: Some plugins may depend on LLM service being fully initialized

## Proposed Solution

### Goal
Show the input box immediately (within 100ms of banner) while initialization happens in the background.

### Approach

#### Option 1: Early Render Loop with Loading State (RECOMMENDED)
```
1. Display banner
2. Start render loop (with special "initializing" state)
3. Show input box immediately with "Initializing..." indicator
4. Initialize LLM core service (in background)
5. Initialize plugins in parallel
6. Update input box to "Ready" when complete
7. Start input handler after initialization
```

**Pros:**
- Input box visible immediately
- User gets visual feedback during initialization
- Clear loading state
- Minimal architecture changes

**Cons:**
- Need to handle render loop state before full initialization
- Must ensure input handler doesn't start too early
- Need to prevent user input during initialization

**Key implementation details:**
- Add `initializing` flag to track startup state
- Modify `render_active_area()` to check `initializing` flag
- Show loading indicator instead of normal input box during init
- Only enable input after `_startup_complete = True`

#### Option 2: Parallel Initialization
```
1. Display banner
2. Start these in parallel:
   - Initialize LLM core
   - Initialize plugins (already can be parallel)
   - Pre-warm render loop components
3. Wait for all parallel tasks to complete
4. Start render loop and input handler together
5. Display ready message
```

**Pros:**
- Faster overall startup
- Maintains current architecture
- Less risk of state conflicts

**Cons:**
- Input box still delayed (just less delay)
- More complex dependency management
- Some components can't truly be parallel

#### Option 3: Lazy Initialization
```
1. Display banner
2. Start render loop and input handler immediately
3. Initialize core services lazily on first use
4. Queue user input until initialization complete
```

**Pros:**
- Instant UI
- Feels very responsive

**Cons:**
- Complex deferred initialization logic
- Risk of race conditions
- Harder to debug startup issues

## Recommended Implementation Plan

**Phase 1: Quick Win - Parallel Plugin Init**
- Parallelize plugin initialization using `asyncio.gather()`
- Keep hook registration sequential to preserve priority
- Estimated speedup: 50-70% reduction in plugin init time
- Low risk, no architecture changes

**Phase 2: Early Render Loop with Loading State**
1. Add `self.initializing = True` flag to TerminalLLMChat
2. Start render loop immediately after banner
3. Modify `render_active_area()`:
   ```python
   if self.initializing:
       # Show loading input box with spinner
       lines.extend(self._render_loading_input())
       return
   ```
4. Run initialization in background
5. Set `self.initializing = False` when complete
6. Start input handler after initialization completes

**Phase 3: Optimization Refinement**
- Profile initialization to find slowest components
- Move non-critical initialization to background tasks
- Add progress indicators for each initialization stage

## Testing Requirements

1. **Visual Testing**
   - Verify input box appears within 100ms of banner
   - Check that loading indicator is visible and animates
   - Confirm no duplicate input boxes
   - Test resize behavior during initialization

2. **Functional Testing**
   - Ensure user input during initialization is queued properly
   - Verify all plugins initialize correctly
   - Check that hooks are registered in correct order
   - Test first-run wizard still works

3. **Edge Cases**
   - Very slow plugin initialization
   - Network timeout during LLM provider check
   - Terminal resize during startup
   - Ctrl+C during initialization

## Rollback Plan

If issues occur:
1. Revert changes to `kollabor/application.py`
2. Keep parallel plugin initialization (low risk)
3. Document issues in known_issues/
4. Create regression test

## Success Metrics

- Input box visible within 100ms of banner (currently 2-3s)
- Overall startup time reduced by 30-50%
- No duplicate input boxes or render artifacts
- No regression in plugin functionality
- User can start typing immediately (input queued if needed)

## Related Files

- `kollabor/application.py` - Main startup sequence
- `kollabor/io/terminal_renderer.py` - Render loop and input box rendering
- `kollabor/io/message_coordinator.py` - Render state management
- `kollabor/io/input_handler.py` - Input handling and raw mode

## Notes

- **CRITICAL**: Never directly manipulate `writing_messages`, `input_line_written`, or other render state flags. Always use MessageDisplayCoordinator methods.
- The render loop checks `writing_messages` flag to avoid rendering during message display
- Modal system uses `command_mode` to block render loop during modal display
- Input handler must be started AFTER render loop to ensure proper terminal state
