## ADDED Requirements

### Requirement: Channel-based streaming reducer

The streaming layer SHALL dispatch WS frames into typed channels (`text`, `tool_call`, `tool_result`, `status`, `error`) instead of a flat `applyFrame` pattern match. Each channel SHALL produce deltas independently but merge into a single `StreamState` via a deterministic ordering function.

#### Scenario: Text delta dispatched to text channel
- **WHEN** a `delta` frame with `content` arrives
- **THEN** the text channel accumulates the chunk and the merged state appends it to the target message's content

#### Scenario: Tool call dispatched to tool_call channel
- **WHEN** a `tool_call` frame with a `tool_call` object arrives
- **THEN** the tool_call channel pushes it to `message.tool_calls` on the target message id

### Requirement: Mid-stream reconnection without snapshot

The hook SHALL support mid-stream reconnection by replaying missed deltas per-channel, using a monotonic `seq` counter on each frame. If the server cannot replay, a full `snapshot` frame SHALL be used as fallback.

#### Scenario: Reconnection with missed deltas
- **WHEN** the WebSocket reconnects during an active stream
- **THEN** the client sends the last processed `seq` per-channel and the server replays missed deltas
- **AND** if replay is unavailable, the server sends a `snapshot` frame and the reducer resets to that state

### Requirement: Out-of-order frame buffering

The reducer SHALL buffer out-of-order frames per-channel and flush them only when the sequence number is contiguous from the last known value.

#### Scenario: Frame arrives out of order
- **WHEN** a frame with `seq=5` arrives before `seq=4` for the same channel
- **THEN** the reducer holds `seq=5` in a per-channel buffer
- **AND** when `seq=4` arrives, both frames SHALL be applied in order

### Requirement: Channel frame schema in ws-frames

The `@boocode/contracts` ws-frames schema SHALL define typed channel delta frames with a `seq` field, a `channel` discriminator, and channel-specific payloads.

#### Scenario: Channel frame validates correctly
- **WHEN** a channel delta frame matches the schema
- **THEN** `WsFrameSchema.safeParse` returns success
