The conditional Telegram SDK loading (commit 4606ba2) caused dark mode to
break in non-Telegram browsers. Added dark mode CSS variable overrides with
proper fallbacks, and restored the module-level applyTheme() call that applies
theme before React renders, preventing a flash of incorrect styling.
- web/src/index.css: Added dark mode overrides for primary colors (--app-bg,
--app-fg, --app-hint, --app-link, --app-button, --app-button-text,
--app-secondary-bg) with system-appropriate dark fallbacks when Telegram
theme variables are unavailable
- web/src/hooks/useTheme.ts: Restored module-level applyTheme(currentScheme)
call to ensure theme is applied before React renders
Add comprehensive support for the AskUserQuestion tool including:
- New footer component for handling user responses with multi-step question flow
- Type definitions and parsing utilities for question and answer formats
- View component for displaying questions and options
- Integration with permission system to capture user answers
- Support for single and multi-select questions with optional text input
- Haptic feedback and error handling for better UX
Add lazy loading of Telegram SDK only when running inside Telegram Mini App
environment instead of unconditionally loading in all browsers. Includes:
- New environment detection functions: isTelegramEnvironment(), isTelegramApp()
- Dynamic SDK loading with 3s timeout via loadTelegramSdk()
- Removed static script tag from index.html
- Made haptic feedback lazy (SDK check on each call)
- Made theme listeners lazy (attached in initializeTheme())
- Updated all components to use unified detection functions
This prevents SDK load time overhead in regular browser environments while
ensuring the app works correctly both in Telegram and browser contexts.
Improve service worker update handling to fix caching issues during development:
- Add skipWaiting and clientsClaim in Workbox config for immediate SW activation
- Remove user confirmation prompt and switch to silent automatic updates
- Replace hourly polling with visibility-based update checks via visibilitychange event
This resolves the issue where web updates would not take effect without manual cache clearing.
Remove unreliable conditions from Telegram environment detection in useAuthSource:
- window.Telegram !== undefined: Always true due to unconditional SDK loading
- window.self !== window.top: Causes false positives in iframe scenarios
Only keep URL parameter detection (tgWebApp in search/hash) which is reliable.
This prevents 5-second polling delay before login page displays on PC browser.
Syncs React routing state with browser History API. Clicking the browser
back button now navigates within the app instead of exiting. Telegram
BackButton behavior is preserved by checking for initData.
Replaces react-shiki with a custom minimal Shiki highlighter to significantly reduce bundle size. Only loads 29 common languages and 2 themes (github-light/dark), using the JavaScript RegExp engine instead of WASM.
- Reduced web bundle from 5.8MB to 2.5MB (57% reduction)
- Saves 622KB by avoiding WASM runtime
- Graceful fallback for unsupported languages
- Removed react-shiki dependency
- Added @shikijs/langs, @shikijs/themes, shiki, hast-util-to-jsx-runtime
- Added light mode CSS rules for syntax highlighting
- Add iOS Safari install prompt with step-by-step modal guide
- Fix Telegram environment detection (check initData, not just SDK presence)
- Fix install prompt re-entrancy issue (clear deferredPrompt immediately)
- Extract icon components to separate file (web/src/components/icons.tsx)
- Rename "Happy App" to "Hapi" throughout the UI and manifests
- Change button/icon colors from blue (--app-button) to neutral theme (--app-fg/--app-bg)
- Add install dismiss state to prevent repeated prompts
- Improve iOS Safari detection with robust user agent parsing
Add complete PWA implementation including service worker registration,
offline support, and installation prompts:
- Add vite-plugin-pwa and workbox-window dependencies for PWA tooling
- Configure VitePWA plugin with web app manifest and app metadata
- Set up Workbox caching strategies for API endpoints and CDN assets
- Implement service worker auto-update with user-triggered refresh
- Create usePWAInstall hook to handle beforeinstallprompt events
- Create useOnlineStatus hook for monitoring network connectivity
- Add InstallPrompt component with haptic feedback integration
- Add OfflineBanner component to notify users of offline status
- Configure PWA icons and assets (64x64, 192x192, 512x512 variants)
- Add TypeScript type declarations for virtual PWA register module
- Integrate PWA components and service worker into App.tsx and main.tsx
- Add PWA meta tags and viewport configuration to index.html
Replace no-op browser haptic feedback with Web Vibration API support,
allowing haptic feedback when running outside Telegram Mini App. Also
remove stale react-syntax-highlighter type reference from tsconfig.
Enable the web client to run in plain browser environments alongside Telegram Mini App support:
- Server: Add CLI_API_TOKEN authentication path as alternative to Telegram initData
- Client: Add useAuthSource hook to detect and manage Telegram vs browser auth sources
- Client: Add usePlatform hook for platform abstraction with graceful haptic feedback degradation
- Client: Add LoginPrompt component for browser access token login
- Client: Extend useTheme to fall back to system prefers-color-scheme in browser
- Client: Migrate all direct HapticFeedback calls to use usePlatform hook
Consolidate markdown rendering logic into dedicated assistant-ui components and update syntax highlighting to use Shiki with GitHub themes. Removes dependency on react-markdown and react-syntax-highlighter in favor of @assistant-ui/react-markdown with Shiki-based highlighting.
Consolidate markdown rendering logic into dedicated assistant-ui components and update syntax highlighting to use Shiki with GitHub themes. Removes dependency on react-markdown and react-syntax-highlighter in favor of @assistant-ui/react-markdown with Shiki-based highlighting.
- Refactor HappyComposer settings overlay to conditionally render permission and model settings based on their availability
- Add showPermissionSettings and showModelSettings flags for cleaner conditional rendering
- Enhance ToolMessage fallback UI with styled card layout and code blocks for arguments and results
- Improve type validation in isToolCallBlock with comprehensive property checks
- Add safeStringify utility for robust JSON serialization with fallback handling
Remove 5 unused component files that were not imported anywhere:
- SessionDetail.tsx (replaced by SessionChat)
- PermissionPanel.tsx (only used by dead SessionDetail)
- MessageList.tsx
- PermissionBanner.tsx
- PermissionDialog.tsx
Confirmed via grep searches and successful build.
- Unify session title logic across components to check metadata.name first
- Add Telegram Web App detection with re-check after mount
- Hide header and buttons when running in Telegram environment
- Replace host display with path information in session details
- Remove unused Badge components for session status
- Simplify SessionList and SessionHeader layouts
Adds todo tracking infrastructure with TodoWrite tool integration to extract
and persist todos in sessions. Refactors ToolCard component to support
custom tool view rendering and displays todo progress in SessionList.
- Display connection status indicators (online, offline, thinking, permission required) in ChatInput with dynamic vibing messages
- Add context size percentage display showing remaining context availability
- Track latest usage data in reducer with inputTokens, outputTokens, cache metrics, and contextSize
- Calculate contextSize from message usage data and expose via latestUsage in reduceChatBlocks
- Pass thinking, agentState, and contextSize props to ChatInput component
- Remove redundant status indicators from SessionHeader (moved to ChatInput for unified display)
Extract word detection and suggestion logic into reusable utilities and hooks.
Add FloatingOverlay and Autocomplete components for intelligent input assistance.
Integrate settings panel and abort button directly into ChatInput component.
Simplify SessionHeader by removing settings dialog (now in ChatInput).