feat(chat): implement web chat interface with accessibility
Core implementation:
- chat_app.py: Chainlit entry point with @cl.on_chat_start,
@cl.on_message (streaming via llm.stream_complete), @cl.on_chat_end
Reuses Config, KnowledgeBase, ConversationStore, AdminNotifier from src/
Handles registration completion, post-completion updates, new-child flow
- src/llm.py: add stream_complete() generator (litellm stream=True)
alongside existing complete(); tests added in tests/test_llm.py
- src/agent/response_parser.py: extract parse_llm_response(),
apply_updates(), fallback_message() from EmailAgent into shared module
EmailAgent now delegates to these functions (no logic change)
Chainlit configuration:
- chainlit.toml: telemetry off, German default, custom CSS + JS paths
- chainlit.md: German welcome page with playgroup info
Accessibility (WCAG 2.1 AA):
- public/custom.css: contrast overrides (≥4.5:1), prefers-reduced-motion
(static "…" replaces animated dots), skip link styles, 100dvh fix
- public/accessibility.js: MutationObserver injects aria-live="polite"
on message list, focus management after agent replies, skip link element
Other:
- .gitignore: add .chainlit/ (Chainlit runtime, auto-generated)
- openspec/config.yaml: populate context field with tech stack
- openspec/changes/implement-web-chat/tasks.md: mark completed tasks
95 tests pass.
https://claude.ai/code/session_01SUWzMzFvSfWiHXA2p6rPg9