Introduces a frontend-owned render-session layer under
`src/components/ChatBox/renderSession/` that normalizes raw messages
into typed `ChatBlock` / `ChatTurn` structures. The agent no longer
needs to emit runtime UI schemas — the frontend classifies blocks from
existing message steps and task state.
Key changes:
- Add `renderSession/types.ts`: `ChatBlock` discriminated union
(markdown, user_message, question, completion, plan, work_log …)
- Add `renderSession/normalizeMessages.ts`: converts `Message[]` +
task state into `ChatTurn[]` with input-type detection for HITL
- Add `renderSession/RenderSessionProvider.tsx`: context that supplies
`chatTurns`, `activeAsk`, `taskId`, and a `submitReply` action
- Add `renderSession/ChatTurnView.tsx` and `MessageBlockRenderer.tsx`
as routing shells for individual blocks
- Add `MessageItem/blocks/QuestionBlock.tsx`: renders `AgentStep.ASK`
inline with text, choice, or context controls; owns a 30-second
visible countdown that auto-submits "skip" when it expires
- Update `UserQueryGroup` to render ASK messages as `QuestionBlock`
instead of plain `AgentMessageCard`
- Wrap `ProjectSection` content with `RenderSessionProvider`
- Remove the global 30-second auto-skip timer from `ChatBox/index.tsx`
(it now lives in `QuestionBlock` where the countdown is visible)
Tests (39 passing):
- Unit: normalizer covers simple turns, ASK active/inactive, files,
orphan messages, multi-turn, detectInputType, extractChoices
- Component: QuestionBlock text/choice submit, disabled-when-inactive,
skipped state after fake-timer advancement
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>