feat(frontend) - Add web frontend and FastAPI web server#87
Open
Shun-Calvin wants to merge 21 commits intoHKUDS:mainfrom
Open
feat(frontend) - Add web frontend and FastAPI web server#87Shun-Calvin wants to merge 21 commits intoHKUDS:mainfrom
Shun-Calvin wants to merge 21 commits intoHKUDS:mainfrom
Conversation
Introduce a full browser-based web frontend (React + Vite + TypeScript) under frontend/web with components, hooks, styles, configs and README. Add installation scripts (scripts/install-web.sh, install-web.bat) and multiple web frontend docs (WEB_FRONTEND*, GETTING_STARTED_WEB.md, QUICKSTART). Add FastAPI-based backend entrypoint src/openharness/web_server.py and wire up CLI support for `oh web` (src/openharness/cli.py); update pyproject.toml for web dependencies. Also simplify the terminal TUI hook (useBackendSession) by removing expensive stable-stringify snapshot comparisons and always updating snapshots, and update README to document the new web UI option.
Introduce SPA routing and multiple new pages, enable theme persistence, improve model selection and backend synchronization, and refine chat and sidebar UX. Key changes: add react-router-based navigation and new page components; persist and toggle light/dark theme; enhance ModelSelector with custom input, sync status and backend updates; update ChatView with new header, new-chat flow, response time/token usage display, and safer submit/resize handling; allow renaming chat sessions and add update action; refactor Sidebar to use NavLink routes and surface quick stats; enhance useBackendConnection to integrate socketManager, sync session state (models, skills, settings), and compute response times/token updates. Also add socketManager util, new styles/pages, and update package.json dependencies. Removed GEMINI_UI_ENHANCEMENT.md documentation file.
Add react-markdown and remark-gfm to enable Markdown/GFM rendering in the frontend and update package-lock with required dependencies. Integrate markdown rendering and related UI changes across App, ChatView, ModelSelector and other components; add a new PermissionModal component and styles. Also include assorted UI tweaks (Header, Sidebar, SettingsPanel, SkillsPanel), update hooks/store/socket manager, add start-web shell and batch scripts, and modify the backend web_server.py to support the frontend changes.
Adds multiple new pages and routes (Plugins, Tools, Hooks, Prompts, Commands, Providers, Doctor) and registers them in the Sidebar and App routing. Enhances ChatView with a timeline scrollbar synced to message scroll, message refs, copy-to-clipboard with temporary UI feedback, scroll-to-message via timeline markers, and various UI/refactor updates. Upgrades ModelSelector with a portal dropdown, dropdown positioning, custom-model management (add/edit/delete), grouped default/custom lists, and improved selection flow. Improves PermissionModal to handle backend connectivity, show loading/error states, support reconnect, and respect auto permission mode. SettingsPanel now uses hook-provided saveSettingsToBackend, exposes reset-to-default behavior, and consolidates settings update handlers. Major refactor of useBackendConnection: introduces global locks/guards to prevent feedback loops and rapid save storms, deduplicates incoming transcript items, stabilizes streaming assistant handling, batches and normalizes settings/state syncs, cleans up socket listeners, and adds fetch/save settings helpers to /api/config. Miscellaneous CSS and type updates to support the above features.
Introduce a SlashCommandAutocomplete React component and its styles, and integrate autocomplete support into the chat UI. Update ChatView, its styles and shared types to use the new autocomplete flow; adjust the backend connection hook and make minor server updates to support the feature. Also bump frontend dev dependencies (vite and @vitejs/plugin-react) in package.json and regenerate lockfile.
Calculate and sync actual message positions for the chat timeline (scroll/resize observers, markers use absolute top positions), improve timeline viewport syncing, and update ChatView to recalc positions and useCallback refs. Add sidebar/chat-sessions layout and toggle on ChatsPage and PageLayout styles; make ChatSessions and ChatView responsive and adjust timeline CSS. Persist OpenHarness config to localStorage and initialize local config from storage in OpenHarnessConfigPage. Update useBackendConnection to avoid duplicating user messages, add immediate user message on submit, surface backend errors into the chat, and add more robust fetch/save error handling. Update useAppStore to persist openHarness config, save messages into chatSessions on create/switch/delete/update/clear, and keep storage in sync.
Updated the README to enhance clarity and detail about OpenHarness and its features.
Introduce a frontend testing setup and related tooling: add Vitest and Testing Library dev dependencies (jsdom / happy-dom), plus a test setup file and two new ChatView tests (imagePaste and timeline). Update Vite config and package.json to enable the test environment. Make focused changes across ChatView, hooks, store, styles, types, and socket manager to support the new tests and related UI behavior, and apply a small backend tweak in web_server.py to accommodate the changes.
Implement search across chats, resizable chat sidebar and timeline, and pasted image previews. - ChatSessions: add search UI, search results, clear/search actions, resize handle and drag logic, and header action buttons. Supports focusing input and navigating to found chat messages. - ChatView: add timeline drag-to-resize, paste image preview generation and removal, and minor UI adjustments for timeline bar and pasted images. - ChatsPage: render ChatSessions conditionally and adjust sidebar toggle position based on sidebar width. - useAppStore: add persisted chatSidebarWidth and timelineWidth, new resizing flags, search state/actions (searchQuery/searchResults/searchMessages/clearSearch), getInitialMessages helper to initialize messages, and persistence helpers. - CSS: extensive styles for search, search results, resize handles, timeline drag handle, pasted images preview, and message role styling changes. These changes add UX features (search, resizing, image previews) and persist sizes to localStorage.
Use requestAnimationFrame for smoother drag resizing (sidebar, chat, input, timeline) with cancellation and transition disabling during drags; avoid redundant state updates by tracking last size. Enhance ChatView timeline: show markers for all messages with role-aware styling, add quick jump-to-first/last buttons, improved marker click scrolling, and message count/info. Clean up message refs when messages are removed, adjust message layout (right-aligned user bubbles, unified tool/assistant styling), and add copy button handling. CSS updates for timeline markers, nav buttons and message bubbles. Add socket heartbeat and pong handling, limit reconnection attempts, improve reconnect/disconnect handling, and expose isSocketHealthy/forceReconnect utilities.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Introduce a full browser-based web frontend (React + Vite + TypeScript) under frontend/web with components, hooks, styles, configs and README. Add installation scripts (scripts/install-web.sh, install-web.bat) and multiple web frontend docs (WEB_FRONTEND*, GETTING_STARTED_WEB.md, QUICKSTART). Add FastAPI-based backend entrypoint src/openharness/web_server.py and wire up CLI support for
oh web(src/openharness/cli.py); update pyproject.toml for web dependencies. Also simplify the terminal TUI hook (useBackendSession) by removing expensive stable-stringify snapshot comparisons and always updating snapshots, and update README to document the new web UI option.Summary
Limited Accessibility: Previously, OpenHarness was likely restricted to a Terminal UI (TUI) or CLI environment. This PR introduces a modern web-based interface, making the tool accessible to users who require a GUI for better data visualization or remote management via a browser.
- Frontend Architecture (frontend/web)
Tech Stack: Bootstrapped a full React + Vite + TypeScript application.
Structure: Implemented standard modularity with dedicated directories for components, hooks, styles, and configs.
DevEx: Included a localized README and automated installation via scripts/install-web.sh and install-web.bat.
- Backend & CLI Integration
Web Server: Created src/openharness/web_server.py using FastAPI to serve the frontend and handle API requests.
CLI Expansion: Added the oh web command in src/openharness/cli.py to trigger the web server directly from the terminal.
Dependency Management: Updated pyproject.toml to include necessary Python dependencies for the web server (likely FastAPI, Uvicorn, etc.).
Validation
uv run ruff check src tests scriptsuv run pytest -qcd frontend/terminal && npx tsc --noEmit(if frontend touched)Notes
Validation
uv run ruff check src tests scriptsuv run pytest -qcd frontend/terminal && npx tsc --noEmit(if frontend touched)Notes