Commit Graph
166 Commits
Author SHA1 Message Date
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 73f5a51548 fix url of happy project 2025-12-25 17:42:22 +08:00
5adf0f20e7 docs: add macOS quarantine fix and Access Token guide (#5)
- Add macOS quarantine fix instructions for prebuilt binaries
- Document Access Token location (~/.hapi/settings.json)
- Show how to view and set custom token

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-25 17:37:43 +08:00
weishu 21ed9fca2f docs: update Gemini default args to experimental-acp
Update HAPPY_GEMINI_ARGS default from --acp to --experimental-acp and add note about Gemini remote-only mode.
2025-12-25 16:56:26 +08:00
weishu fa63529d04 fix: persist CLI_API_TOKEN from env var to settings when not already saved
When CLI_API_TOKEN is provided via environment variable, persist it to settings.json
if not already saved. This prevents token regeneration if the env var fails to load
on subsequent startups, ensuring token consistency across server restarts.
2025-12-25 15:48:45 +08:00
weishu 1405e2bca9 Release version 0.1.3 2025-12-25 15:18:03 +08:00
abe215d5d5 fix: use Bun.main to detect compiled binary instead of Bun.isCompiled (#4)
Bun.isCompiled does not exist and always returns undefined, causing
embeddedAssetMap to be null. This makes the server fall back to looking
for web/dist directory, which doesn't exist when running the compiled
binary from a different location.

The correct way to detect a compiled Bun binary is to check if Bun.main
starts with '/$bunfs' (the virtual filesystem path used by compiled binaries).

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-25 15:15:04 +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 6829ca35a4 docs: add architectural comparison with Happy and update README
Add comprehensive WHY_NOT_HAPPY.md documenting the architectural
differences between HAPI's local-first design and Happy's cloud-first
approach. Update README with clearer project description and link to
new documentation.
2025-12-25 14:01:13 +08:00
weishu 3cdfee0c36 0.1.2 2025-12-25 13:05:15 +08:00
weishu 8353d34dfb refactor: move web asset module declarations to dedicated types file 2025-12-25 12:48:41 +08:00
weishu c224188dd3 chore: allow release dry-run without npm login 2025-12-25 12:46:26 +08:00
weishu ffabc0196d chore: remove unused 2025-12-25 12:34:16 +08:00
weishu 4fb2a203c6 feat: add pre-checks to release-all script for safety
Add validation checks before releasing:
- Ensure we're on the main branch to prevent accidental releases from feature branches
- Verify npm authentication to prevent failed publish attempts

This prevents common release mistakes and improves release workflow reliability.
2025-12-25 12:30:10 +08:00
weishu e5f9d8cbe8 feat: implement server configuration persistence to ~/.hapi/settings.json
Configuration now loads with priority: environment variable > settings.json > default value.
When values are read from environment variables and not present in settings.json, they are automatically saved for future use. This eliminates the need to repeatedly set environment variables.

- New serverSettings.ts module handles loading/saving with persistence logic
- Async createConfiguration() factory for proper initialization ordering
- Configuration sources tracked and displayed in startup logs
- Exported Settings interface and read/write functions from cliApiToken.ts
- Updated index.ts to display configuration sources in log output
2025-12-25 12:27:14 +08:00
weishu dbbeedea0d refactor: unify release workflow into single release-all script
Consolidate version bumping, building, npm publishing, and git operations into a single release script that handles platform packages first. This solves the issue where optionalDependencies needed platform packages published before bun install could generate complete lockfile hashes.

Changes:
- Created cli/scripts/release-all.ts with support for --dry-run, --publish-npm, and --skip-build flags
- Removed release-it dependency and old release/publish-npm scripts
- Simplified GitHub Actions release workflow to always use --generate-notes
- Deleted obsolete release configuration files (.release-it.json, .release-it.notes.js, publish-npm.ts)
2025-12-25 12:26:49 +08:00
weishu d11bfbef86 chore: prepare release 0.1.0 with native binary support
- Update CLI version to 0.1.0
- Change bin script extension from .js to .cjs for ES module compatibility
- Add release-it as dev dependency for version management
- Update all platform-specific binary package versions to 0.1.0
- Enhance release workflow to support custom RELEASE_NOTES.md
2025-12-25 11:31:03 +08:00
weishu f65611b287 chore: run tools:unpack before tests 2025-12-25 11:12:29 +08:00
weishu 19abddb997 chore: setup integration test environment in CI workflow 2025-12-25 11:07:47 +08:00
weishuandGitHub ac50ae3df0 Merge pull request #3 from CherryLover/fix/esm-cjs-compatibility
fix: use .cjs extension for bin script to fix ES module compatibility
2025-12-25 10:41:28 +08:00
jiangjiweiandClaude Opus 4.5 cde0a09134 fix: use .cjs extension for bin script to fix ES module compatibility
The package.json has "type": "module" but bin/hapi.js uses CommonJS
require() syntax. Renaming to .cjs forces Node.js to treat it as
CommonJS regardless of the package type setting.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-25 10:30:58 +08:00
weishu 90cb7dae05 feat: add Homebrew installation support for hapi CLI
- Update CI workflow to package release artifacts with correct naming (hapi-* prefix)
- Generate SHA256 checksums for all artifacts
- Auto-update homebrew-tap repository on release
- Add Installation section to README with Homebrew, npm, and binary options
- Simplify .release-it.json config as CI now handles release process
- Add update-homebrew-formula script to update formula in homebrew-tap
- Add release-artifacts directory to .gitignore

Users can now install via: brew install tiann/tap/hapi
2025-12-25 10:23:16 +08:00
weishu 5a3f10078e chore: add GitHub Actions CI/CD workflows 2025-12-25 09:19:34 +08:00
weishu 958e78dc6e refactor: rename HAPI_BOT_URL to HAPI_SERVER_URL
The project is no longer primarily a bot - it now provides HTTP API,
Socket.IO, SSE, and web app backend services. This rename reflects the
broader scope of server functionality.

Updates references in:
- cli/src/configuration.ts (core config)
- cli/src/ui/logger.ts (remote logging)
- cli/src/ui/doctor.ts (diagnostics)
- cli/src/commands/auth.ts (auth status)
- cli/src/daemon/daemon.integration.test.ts (test comments)
- README.md (quickstart docs)
- cli/README.md (CLI docs)
- cli/CLAUDE.md (dev docs)
2025-12-24 19:15:47 +08:00
weishu 4017590af9 docs: recommend npx @twsxtd/hapi as primary installation method
Update documentation to promote npm package usage over binary downloads:
- Changed primary quickstart command to use npx @twsxtd/hapi
- Moved binary download to alternative option with link to releases
- Updated Multi-agent support section to use npx commands
- Simplified Quickstart section title
- Adjusted step numbering to reflect changes
2025-12-24 19:08:53 +08:00
weishu 31dfaebc85 chore: remove Windows ARM64 build support and add npm publish scripts
- Add publish-npm and publish-npm:dry-run scripts to root package.json (forwarding to cli)
- Remove Windows ARM64 (bun-windows-arm64) from DEFAULT_TARGETS in build-executable.ts
- Remove Windows ARM64 check from getPlatformDir in build-executable.ts
- Remove HAPI_TARGET_WIN32_ARM64 from bunBundle.d.ts type definitions
- Remove Windows ARM64 check from embeddedAssets.bun.ts
2025-12-24 18:51:49 +08:00
weishu c47316d173 fix: prevent flash of white background in dark mode 2025-12-24 18:42:15 +08:00
weishu 92d9546a9d chore: add module declaration for web asset imports 2025-12-24 18:17:06 +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 d15eafba4c fix: prevent LoginPrompt flash on page refresh with stored token
Add additional condition to check for the intermediate auth state where
authSource exists but token hasn't been fetched yet. This prevents the
LoginPrompt from briefly flashing when the page is refreshed and the user
already has a stored access token.

Changes the condition from just `isAuthLoading` to also cover the gap
before the useAuth effect starts fetching the token, displaying the
loading state instead of the login prompt.
2025-12-24 18:16:23 +08:00
weishu 4497f437fd docs: rewrite daemon README with current codebase state
Complete documentation refresh covering:
- Version detection via CLI binary mtime (not package.json)
- Multi-Agent Support section with token authentication for claude/codex/gemini
- Directory creation approval flow for session spawning
- HTTP Control Server endpoints with Fastify + Zod schemas
- State persistence fields including startedWithCliMtimeMs
- Integration Testing section with test environment and key scenarios
- Typed shutdown sources (hapi-app, hapi-cli, os-signal, exception)
- MachineMetadata with new happyLibDir field
- WebSocket communication patterns and RPC methods
- Machine sync architecture with separated metadata and daemon state

Replaces CLAUDE.md with structured daemon documentation.
2025-12-24 18:16:01 +08:00
weishu b2eeb97d27 fix: handle abort signal before and during codex spawn
Add checks to gracefully handle abort signals:
- Check if abort is already signaled before attempting spawn
- Check if abort caused the spawn error instead of rejecting
2025-12-24 17:56:51 +08:00
weishu 2b3fa635f6 fix: constrain session disabled banner width to max-w-content 2025-12-24 17:56:37 +08:00
weishu eee4489b0f docs: update all README files with comprehensive documentation
Update documentation across the project to reflect current state of codebase:
- cli/README.md: Add all commands (codex, gemini, daemon subcommands, doctor, mcp),
  configuration options, storage locations, and source structure references
- server/README.md: Add complete HTTP API reference, Socket.IO events, Telegram bot
  features, core logic descriptions, and source structure
- web/README.md: Add all routes, feature descriptions, authentication flow, data
  fetching, real-time updates, and source structure
- README.md: Improve feature list clarity, add HTTPS exposure instructions in
  quickstart, add multi-agent support section
2025-12-24 17:56:07 +08:00
weishu 852c7f4c4e Licenses 2025-12-24 17:35:19 +08:00
weishu 2a10ce9675 feat: add support for user message events from Codex
Add sendUserMessage() method to ApiSessionClient and CodexSession to handle
user_message events from Codex. Updates CodexConversionResult type and
convertCodexEvent() to process user_message payloads, with test coverage.
2025-12-24 17:24:16 +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 9b9f792ff6 fix: navigate to parent path generically in useAppGoBack instead of hardcoded /sessions 2025-12-24 16:26:20 +08:00
weishu a2edd88d93 refactor: rename normalizedMessagesCount to renderedMessagesCount for clarity 2025-12-24 15:37:21 +08:00
weishu 0bb5dcc086 fix: add 300ms debounce to sync banner display
Debounce the sync banner to only show if sync takes longer than 300ms.
This prevents the banner from flashing on quick syncs while still showing
for slower operations.

Changes:
- Added DEBOUNCE_MS constant (300ms)
- Changed doStartSync to delay banner display by 300ms
- Changed endSync to immediately clear all timeouts
- Renamed endSyncTimeoutRef to startDelayTimeoutRef (now for debounce)
2025-12-24 15:10:00 +08:00
weishu baaf02daf5 fix: prevent sync banner from flashing on session switches
Added isFirstConnectRef to distinguish between first SSE connection
(page load) and subsequent reconnects (session switches). Only the
first connection forces the banner to show; subsequent connects use
non-forced mode which only displays the banner when returning from
background within 30s, eliminating unwanted banner flashes on
session changes.
2025-12-24 15:10:00 +08:00
weishu 3e4b8ddc64 refactor: remove non-allinone build scripts and fix npm publish build command
Remove build:cli:exe and build:cli:exe:all scripts since building executables
without web assets serves no practical purpose. Update npm publish script to use
build:single-exe:all which includes embedded web assets in published packages.
2025-12-24 15:04:26 +08:00
weishu 6078c136bb style: unify button and link colors to black/white theme 2025-12-24 14:49:25 +08:00
weishu 85c2dc10ea feat: add npx/bunx binary distribution support
Adds infrastructure for distributing Hapi via npm as a scoped package
(@twsxtd/hapi) with platform-specific optional dependencies. This enables
installation via `npx @twsxtd/hapi` or `bunx @twsxtd/hapi`.

- Add bin/hapi.js wrapper script for platform detection and binary selection
- Create npm/ directory structure for platform-specific packages (darwin-{arm64,x64},
  linux-{arm64,x64}, win32-x64)
- Add scripts/prepare-npm-packages.ts to generate platform-specific package.json files
  and copy binaries to npm packages
- Add scripts/publish-npm.ts for automated publishing of platform packages
- Update package.json with new scoped name, bin entry, optionalDependencies, and
  prepack/publish scripts
- Update .gitignore to ignore generated npm packages and build outputs
- Update .npmignore to only include bin/hapi.js wrapper, excluding source and build files
2025-12-24 14:39:05 +08:00
weishu bb9c5b66d3 refactor(telegram): remove interactive features and simplify to notifications only
Remove all interactive features from the Telegram bot that are now handled by the
Telegram Mini App. The bot now serves a single purpose: sending notifications for
permission requests and ready events.

Changes:
- bot.ts: Remove /help command and message handler, simplify /start to show Mini App link
- callbacks.ts: Remove all callback handlers except APPROVE and DENY for permissions
- sessionView.ts: Remove detail views and settings, keep only notification formatting
- renderer.ts: Remove session/machine list rendering, keep utility functions

This reduces the codebase by ~1000 lines (58% reduction) while preserving notification
functionality that the Mini App cannot provide.
2025-12-24 14:23:01 +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 61ae777c3d refactor(telegram): simplify notifications and remove emoji
Remove Switch and Message notifications, update Ready notification to
use agent flavor from session metadata, and remove emoji from button
text and titles to align with happy-cli notification style.
2025-12-24 13:46:30 +08:00
weishu c09b870fe7 refactor(test): simplify keyboard input handling and extract type definitions
Remove reliance on key.name and key.sequence in favor of using input directly.
Extract TTY type definitions for clarity and add scoping constraints to prevent
variable shadowing. Update AGENTS.md documentation for accuracy.
2025-12-24 13:34:55 +08:00
weishu 1a23bfa430 refactor: remove custom executable support and simplify Claude CLI resolution
Remove support for custom executable paths and bundled Claude versions, including
deprecated environment variables HAPI_USE_BUNDLED_CLAUDE and HAPI_USE_GLOBAL_CLAUDE.
This simplifies the codebase to rely only on the global Claude CLI installation.

Updates Claude Code spawning logic to remove special handling for .js/.cjs files,
adds configurable BUN_BE_BUN environment variable handling, and streamlines path
resolution to throw an error when Claude Code CLI is not found on PATH.
2025-12-24 13:20:06 +08:00