Commit Graph
401 Commits
Author SHA1 Message Date
J. F. ZhangandGitHub c0502d128c Dispose terminal addons before terminal teardown (#58) 2026-01-11 17:28:19 +08:00
ChenandGitHub aaaad33e61 feat: add i18n support and enhance session UI (#50) 2026-01-10 22:07:22 +08:00
JovinesandGitHub 2fb61940e4 fix: prevent click navigation after long press on session list (#52) 2026-01-10 19:58:20 +08:00
Ruihang XiaandGitHub c0446766a5 feat(ui): change session action menu UI style (#33) 2026-01-08 11:09:42 +08:00
Begonia, HEandGitHub 146cbf8db0 feat(terminal): add Nerd Font support for Powerline themes (#29) 2026-01-08 10:55:03 +08:00
weishu cb69001385 fix: prevent continuous "Load More" triggering in message virtualization
The IntersectionObserver's useEffect had handleLoadMore in its dependency
array, but handleLoadMore depended on isLoadingMoreMessages. When loading
completed, isLoadingMoreMessages changed, causing handleLoadMore to be
recreated and the observer to rebuild, immediately firing again and
triggering continuous load requests.

Fixed by storing handleLoadMore in a ref and removing it from the
IntersectionObserver's dependency array, allowing it to rebuild only when
hasMoreMessages or isLoadingMessages change.
2026-01-08 09:09:53 +08:00
weishu 803c2f65a9 feat: add notification optimization with visibility tracking and toast messages
Implement a visibility-aware notification system that delivers toast messages via SSE to visible browser tabs instead of sending push notifications, reducing unnecessary push requests. Includes VisibilityTracker for monitoring connection visibility, toast UI components, and enhanced SSEManager with toast delivery capability.
2026-01-07 18:58:31 +08:00
weishu 0f29ee182c refactor: replace React Query message cache with windowed message store
Introduces a new message-window-store module to manage message state with
automatic windowing of visible and pending messages. This replaces manual
React Query cache operations with a centralized, observable state system.
close #39

Key changes:
- New MessageWindowState tracks visible/pending messages with size limits
- Automatic trimming of message windows (400 visible, 200 pending messages)
- Pending message buffering when user scrolls away from bottom
- Centralized status updates for optimistic messages
- Thread component simplified with forwarded scroll and pending callbacks
- Removes message count tracking from components

This improves performance for chats with many messages and provides a
cleaner separation of concerns between UI and state management.
2026-01-07 16:59:12 +08:00
weishu 918f752b1c refactor: move Server button into help links section below login form
Reorganizes the LoginPrompt layout by moving the Server button from an
absolute-positioned top-right corner into the main content flow as a text
link in a new "Help links" section below the login form. Also adds a
"Needs help?" link pointing to the documentation. This reduces visual
clutter, improves hierarchy by grouping related actions, and provides
better guidance for new users.
2026-01-06 10:32:42 +08:00
weishu c1092bcfec refactor: improve LoginPrompt UI/UX with simplified layout and better navigation
- Update subtitle to official slogan "Vibe Coding Anytime, Anywhere"
- Simplify input placeholder to "Access token"
- Remove verbose help text below the input field
- Move server settings from top-right corner to footer below form
- Add "Needs help?" link to docs (https://hapi.run/docs)
- Add underline styling to both help and server links for better affordance
- Add footer with copyright and Vibe Coding message
2026-01-05 21:28:42 +08:00
weishu 77eefcd8da refactor: move path utilities to utils directory 2026-01-05 13:00:48 +08:00
Ruihang XiaandGitHub d1c532301e feat: sync thinking state to session list view (#32)
Signed-off-by: Ruihang Xia <waynestxia@gmail.com>
2026-01-04 20:48:21 +08:00
weishu 34cfe49f87 refactor: extract chat normalization and reducer logic, cleanup legacy credentials
- Split normalize.ts into focused modules: normalizeAgent, normalizeUser, normalizeUtils
- Extract reducer.ts into specialized modules: reducerCliOutput, reducerEvents, reducerTimeline, reducerTools
- Remove legacy credentials support (zod schema, readCredentials, writeCredentialsLegacy)
- Refactor NewSession component from monolithic file into modular subcomponents
- Improves code organization and maintainability across chat and authentication layers
2026-01-03 23:39:10 +08:00
weishu 4d18789d50 refactor: extract permission mode utilities and consolidate styling logic
Extract permission mode display logic into shared utilities for better reusability and maintainability. Add PermissionModeTone type and related helpers to centralize mode-based styling rules across components. Update components to use new PermissionModeOption type for consistent permission mode presentation.
2026-01-03 22:49:40 +08:00
weishu a2c4315e99 fix: allow dismissing PWA install prompt in Chrome/Edge
Add close button to Chrome/Edge install prompt and respect dismissed state
when determining if prompt can be shown. iOS version already had dismiss
capability, so this brings feature parity across all supported browsers.
2026-01-03 16:09:07 +08:00
weishu e2028b6914 Unify protocol types and modes 2026-01-03 14:43:59 +08:00
weishu bc602ff5ea fix: archive session 2026-01-03 10:31:54 +08:00
weishu 2de3a3d635 fix: expand codex custom prompt 2026-01-02 21:45:29 +08:00
weishu 41fd1abd53 feat: add session management (rename, archive, delete)
Implements comprehensive session lifecycle management with user-friendly interactions:

Rename: Update session metadata.name via PATCH endpoint with conflict detection
Archive: Abort active sessions via DELETE endpoint with validation
Delete: Permanently remove inactive sessions with cascade cleanup

Backend:
- Store.deleteSession() removes session and cascade-deletes messages
- SyncEngine.renameSession() with concurrency error handling
- SyncEngine.deleteSession() with active session validation
- PATCH /sessions/:id for rename, DELETE /sessions/:id for delete

Frontend Components:
- RenameSessionDialog: Text input with auto-focus and error display
- SessionActionMenu: Modal with rename, archive, delete buttons
- ConfirmDialog: Reusable confirmation with error feedback
- SessionHeader: Menu button (⋮) triggering action menu
- SessionList: Long-press detection triggering item actions

Interactions:
- Long-press on session list items (500ms threshold) opens action menu
- Menu button in session header (non-Telegram environments only)
- Confirmation dialogs with descriptive warnings for destructive actions
- Real-time error display in dialogs on operation failure
- Haptic feedback on long-press via usePlatform hook

Accessibility:
- Keyboard support (Enter/Space) for long-press handler
- Focus management in RenameSessionDialog
- Proper ARIA labels and semantic HTML
2026-01-02 19:15:01 +08:00
weishu c2d1f8c507 feat: auto-scroll selected suggestion into view 2026-01-02 19:11:43 +08:00
weishu e821458af8 feat: add namespace-based multi-user isolation
Implement namespace support across sessions, machines, and users for multi-user server deployments. Add access control with specific error reasons (namespace-missing, access-denied, not-found) and database schema updates with namespace columns and indexes.
2025-12-31 21:56:01 +08:00
weishu 8f7dcf848b refactor: Add Telegram binding storage and auth 2025-12-31 17:43:57 +08:00
weishu f796ad8749 feat(web): add sticky group headers to session list 2025-12-30 18:49:38 +08:00
ecfe0eff60 feat(web): 优化会话列表展示 - 按目录分组并显示更新时间 (#22)
* feat(web): add session list grouping by project directory

- Group sessions by project path with collapsible sections
- Sort groups by active status first, then by latest update time
- Sort sessions within each group by update time (descending)
- Add visual indicators for groups with active sessions
- Display project count in header statistics

Co-authored-by: weishu <twsxtd@gmail.com>
2025-12-30 17:42:20 +08:00
weishu e758efb0ec feat: unify app name 2025-12-29 14:36:24 +08:00
weishu 334cebc2da feat: add real-time permission and model mode synchronization close #21
Implements bidirectional sync of permission/model modes between CLI sessions and web app. Adds Codex-specific permission modes (read-only, safe-yolo, yolo) alongside Claude's modes. Web can now control CLI session state via RPC set-session-config handler, while CLI broadcasts state changes through keep-alive payloads. UI controls are flavor-aware, showing appropriate modes for Claude vs Codex vs Gemini. Type centralization in api/types eliminates circular dependencies.
2025-12-28 20:51:18 +08:00
weishu 05deb6fff8 feat: add directory autocomplete with validation for new session form 2025-12-28 16:31:53 +08:00
weishu fbc0d601f8 feat: add slash command autocomplete to HappyComposer
Implements full-stack slash command autocomplete with agent-specific built-in commands and user-defined command discovery. Includes React Strict Mode fix for suggestion handling.
2025-12-28 15:19:08 +08:00
weishu c35a5ce827 feat: add git worktree session support with improved UI
Implement comprehensive worktree session support allowing users to spawn sessions in temporary git worktrees. Includes backend worktree management, full-stack integration, and refined UI for session type selection.

Backend:
- Add worktree creation/removal utilities with branch management
- Track worktree metadata (basePath, branch, name, path) in session metadata
- Automatic cleanup of worktrees when sessions fail or exit
- Enhanced error handling with stderr tail logging

UI improvements:
- Redesign session type toggle with improved alignment and spacing
- Move worktree description inline with label for cleaner layout
- Add branch name input field that appears when worktree mode selected
- Auto-focus on worktree input when switching modes
- Reduce gap between radio options from gap-3 to gap-1.5
- Update descriptive text and placeholders for clarity

Integration:
- Thread worktree parameters through API client, RPC handlers, and daemon
- Add worktreeEnv utility to read worktree info from environment
- Update session spawning to support both simple and worktree modes
2025-12-28 13:17:58 +08:00
weishu 0eab45c49c refactor: consolidate copy-to-clipboard logic and icons 2025-12-28 13:13:38 +08:00
58e61b3db9 feat: create new session with yolo mode (#13)
* feat: create new session with yolo mode

Signed-off-by: Ruihang Xia <waynestxia@gmail.com>

* fix: harden sequence typecheck

* feat: add unified --yolo flag across all agents

---------

Signed-off-by: Ruihang Xia <waynestxia@gmail.com>
Co-authored-by: weishu <twsxtd@gmail.com>
2025-12-27 21:03:34 +08:00
weishu 8122768a01 feat: add reasoning block support to chat system
Add comprehensive support for handling reasoning blocks throughout the chat pipeline, including normalization, reconciliation, type definitions, and UI rendering. Implements collapsible reasoning group component with auto-expand during streaming and shimmer indicator.
2025-12-26 13:35:27 +08:00
weishu 18e6310451 feat: implement web terminal feature with xterm.js and Socket.IO proxy
- Add CLI-side terminal management via Bun.Terminal with TerminalManager
- Implement server-side Socket.IO proxy for terminal I/O between web and CLI
- Create web terminal UI component with xterm.js and support for resize/reconnect
- Add terminal route and navigation button in session chat
- Include comprehensive terminal implementation plan and architecture docs
2025-12-25 21:57:18 +08:00
weishu 6dc80f14bc refactor: adjust safe area padding for Safari browser 2025-12-25 19:27:31 +08:00
weishu 8e6ab5394b refactor: optimize safe area handling in web components
Apply safe area insets to sticky/fixed headers (using top inset) and bottom-fixed elements (using bottom inset), rather than to scroll containers. This ensures proper spacing on devices with notches and home indicators (e.g., iPhone).

- Sessions List page: Move header outside scroll container with sticky positioning and pt-[env(safe-area-inset-top)]
- SessionList component: Add renderHeader prop to optionally hide internal header when parent renders it
- HappyComposer: Change bottom padding to pb-[calc(0.75rem+env(safe-area-inset-bottom))] for proper iPhone home indicator spacing
2025-12-25 17:44:44 +08:00
weishu 0be023b23b feat: add configurable server URL for standalone web hosting
Adds support for hosting the web UI separately from the hapi server on static hosts (GitHub Pages, Cloudflare Pages). Users can now set a custom server origin via a dialog on the login screen, with the ability to return to same-origin behavior.

Changes include:
- New useServerUrl hook for managing server URL configuration and storage
- Updated API client to support baseUrl parameter for all requests
- Enhanced login UI with server picker dialog (top-right button)
- Auth system now keys tokens per baseUrl to support multiple servers
- SSE connection updated to use configured baseUrl
- Documentation updates for standalone hosting setup
2025-12-25 17:42:30 +08:00
weishu b953391737 fix: improve message counter initialization with bootstrap check
Add hasBootstrappedRef to track component initialization and prevent
counting messages during the initial render. This fixes the new message
counter behavior when messages load on component mount and ensures
accurate message tracking when autoScroll is disabled.
2025-12-25 14:58:56 +08:00
weishu e0f0221453 fix: improve "Load older" button styling and alignment
- Centered button using mx-auto w-fit wrapper (matches SystemMessage pattern)
- Changed variant from secondary to outline for subtler appearance
- Reduced visual weight with text-xs opacity-80 hover:opacity-100
- Added ↑ arrow icon before the text
- Adjusted spacing to py-1 mb-2 and gap-1.5

Fixes alignment issues where button wasn't centered with content below and improves visual consistency with page design.
2025-12-24 18:16:26 +08:00
weishu 2b3fa635f6 fix: constrain session disabled banner width to max-w-content 2025-12-24 17:56:37 +08:00
weishu 7f2a36117c feat: add Spinner and LoadingState components for unified loading UX
Introduces two reusable loading components to standardize loading states:
- Spinner: Base spinner with accessibility support (role, aria-label)
- LoadingState: Semantic loading indicator combining spinner and label

Updates loading patterns across the app:
- Full-screen/block loading now uses LoadingState (App, router, files, file)
- Inline button loading states show spinner + text with aria-busy
- Message list loading replaced with MessageSkeleton component
- Removes duplicate SpinnerIcon definition from PermissionFooter

Improves UX and accessibility:
- Loading screens centered and full-height
- Consistent ellipsis character (…)
- Semantic accessibility (role="status", aria-live, aria-busy)
- Adds CSS variables for banner styling
2025-12-24 17:23:39 +08:00
weishu a2edd88d93 refactor: rename normalizedMessagesCount to renderedMessagesCount for clarity 2025-12-24 15:37:21 +08:00
weishu 6d401fb9ec feat: add syncing banner and smart scroll behavior for chat thread
Implement two key UX improvements:

1. Syncing banner with visibility tracking:
   - New useSyncingState hook manages syncing state with safety timeout
   - Banner shows when SSE connects/reconnects
   - Auto-hides after 10s to prevent stuck spinner
   - Smart visibility detection to suppress banner when returning from background

2. Smart scroll behavior for chat thread:
   - Only auto-scrolls when user is near bottom (<120px threshold)
   - Shows "X new messages" indicator when user is reading history
   - Smooth scroll to bottom with indicator button
   - Resets state on session change

Files:
- New: useSyncingState hook for syncing state management
- New: SyncingBanner component for non-blocking indicator
- Modified: App.tsx integrates syncing with SSE handling
- Modified: HappyThread implements smart scroll with dynamic autoScroll
- Modified: index.css adds spinner and bounce-in animations
2025-12-24 14:05:55 +08:00
weishu a2bdc73236 refactor(web): unify max-width constraints with tailwind content class
Adds maxWidth.content: '720px' to tailwind.config.ts for centralized width management across the web app. Replaces all hardcoded max-w-[720px] references with the new max-w-content class. Adds missing max-width constraints to file.tsx, files.tsx, and SessionList.tsx. Moves border-b dividers from outer full-width divs to inner max-w-content divs for consistent visual hierarchy.
2025-12-23 18:40:51 +08:00
weishu e637f2bb27 refactor(web): simplify NewSession component layout with divided sections
Replace Card wrapper with a flex column layout using dividers for better visual separation and simpler structure.
2025-12-23 15:53:42 +08:00
weishu 422018299c refactor(web): redesign SessionList component with enhanced session metadata
Replace Card-based layout with semantic button elements for better accessibility and keyboard navigation. Add session metadata fields (flavor, activeAt, modelMode) and implement helper functions to format session information including agent flavor, model mode, and relative last-seen timestamps. Update hover styles and add focus-visible indicators.
2025-12-23 14:17:15 +08:00
weishu c8f7a23f2f feat(web): add continue hint in HappyComposer when switching to remote mode
When switching from local mode to remote mode, the placeholder text now
suggests users can type "continue" to resume interrupted tasks. This helps
users understand they can continue where they left off after experiencing
permission prompts that were stuck in the terminal during local mode.
2025-12-23 11:13:37 +08:00
weishu aef3ed367b refactor(web): move message loading header into HappyThread with infinite scroll
Move the message loading header UI and infinite scroll logic from SessionChat into HappyThread component. This improves component isolation and adds IntersectionObserver-based automatic loading with proper scroll position preservation and error handling.
2025-12-22 21:45:34 +08:00
weishu 999ee64852 refactor(web): unify session creation into single page with path history 2025-12-22 21:45:11 +08:00
weishu 439778c875 fix(web): enable auto-scroll and add key prop to HappyThread component 2025-12-22 18:11:07 +08:00
weishu f16ccb2759 fix(web): handle null values in permissionMode and modelMode using nullish coalescing
The settings popup in HappyComposer did not show any option selected when
permissionMode or modelMode was null, since destructuring defaults only
handle undefined, not null. This fix uses the ?? operator to properly
handle both null and undefined cases, falling back to 'default' in both.
2025-12-22 12:25:01 +08:00