Skip to content

Implement core App component and state management #11764

Closed as not planned
Closed as not planned

Description

@randomm

Parent Epic

Part of #11762 (Ink-based TUI Rewrite)

Objective

Create the main App component with centralized state management using useReducer.

Architecture

<App>
├── <Static items={completedMessages}>
├── <LiveSection>
├── <StatusBar>
└── <InputLine>

State Interface

interface AppState {
  messages: Message[]           // Completed messages
  streaming: {
    text: string                // Current streaming text
    tools: Map<string, Tool>    // Active tools
    tasks: Map<string, Task>    // Active tasks with child status
  }
  session: {
    id: string | null
    agent: string
    model: string | null
  }
  ui: {
    mode: 'input' | 'select' | 'navigation'
    selectOptions?: SelectOption[]
  }
}

Tasks

  • Create src/cli/ink/App.tsx with main component structure
  • Create src/cli/ink/state/types.ts with TypeScript interfaces
  • Create src/cli/ink/state/reducer.ts with action handlers:
    • SET_SESSION - Update current session
    • STREAM_TEXT - Append streaming text
    • TOOL_START - Add tool to active set
    • TOOL_END - Move tool to completed, remove from active
    • TASK_START - Add task to active set
    • TASK_UPDATE_CHILD - Update child tool status
    • TASK_END - Move task to completed
    • MESSAGE_COMPLETE - Finalize message, move to Static
    • SET_UI_MODE - Switch between input/select/navigation
  • Create src/cli/ink/state/context.tsx for state provider
  • Wire up basic render test

Acceptance Criteria

  • App component renders without errors
  • State updates via dispatch work correctly
  • TypeScript types are comprehensive
  • No runtime errors on state transitions

Estimated Effort

1.5 days

Dependencies

Activity

  1. randomm commented on Feb 2, 2026

    @randomm
    Author

    Research Findings

    Ink App Patterns (from Context7 + production analysis)

    • Structure: Single <App /> component rendered with render(), orchestrates layout and state
    • State: useReducer for complex transitions, useState for simple state
    • Static: <Static items={array}> renders completed content above dynamic - only new items trigger re-renders
    • Testing: ink-testing-library with render() and lastFrame() assertions

    Existing Lite TUI Analysis

    • Files: 6 files (~450 lines total)
    • SDK Events: MessageV2.Event.PartUpdated for streaming
    • Component Mapping:
      • LineEditor → TextInput
      • Spinner → ink-spinner
      • Raw ANSI writes → Ink render tree
    • State: Minimal - async generator yielding ChatChunk types

    Implementation Notes

    • Lite TUI uses buffering approach (no pausedForProse hack found in current code)
    • Ink's React reconciler will handle concurrent updates properly
    • Keep UI layer thin - direct model-tool communication pattern
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Labels

No labels
No labels

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions