diff --git a/README.md b/README.md index d722800a..b453f028 100644 --- a/README.md +++ b/README.md @@ -2,30 +2,30 @@ HAPI means "哈皮," a Chinese transliteration of [happy](https://github.com/slopus/happy), great credit to the original Happy project. -Run Claude Code / Codex / Coding Agent sessions locally and control them remotely through a Web / PWA / Telegram mini App. +Run Claude Code / Codex / Gemini sessions locally and control them remotely through a Web / PWA / Telegram Mini App. + +## Features + +- Start AI coding sessions from any machine. +- Monitor and control sessions from your phone or browser. +- Approve or deny tool permissions remotely. +- Browse files and view git diffs. +- Track session progress with todo lists. +- Supports multiple AI backends: Claude Code, Codex, and Gemini. ## Quickstart (single executable) 1. Download the prebuilt `hapi` binary for your platform and put it on your PATH. -2. Start the server on a machine you control: `hapi server` - -Optional for telegram, add a `.env` file and then start server: +2. Start the server on a machine you control: +```bash +hapi server ``` -WEBAPP_URL="https://your-domain.example" # required for Telegram Mini App -TELEGRAM_BOT_TOKEN="..." -ALLOWED_CHAT_IDS="12345678" -``` - -If you only want the web app + CLI, you can skip these vars. -To enable Telegram later, set TELEGRAM_BOT_TOKEN and WEBAPP_URL, start the server, send `/start` -to the bot to get your chat ID, set ALLOWED_CHAT_IDS, and restart the server. 3. If the server has no public IP, expose it over HTTPS: -- Cloudflare Tunnel docs: https://developers.cloudflare.com/cloudflare-one/connections/connect-networks/ -- Tailscale docs: https://tailscale.com/kb/ -- Telegram Mini Apps require HTTPS. + - Cloudflare Tunnel: https://developers.cloudflare.com/cloudflare-one/connections/connect-networks/ + - Tailscale: https://tailscale.com/kb/ 4. Run the CLI on the machine where you want sessions: @@ -36,34 +36,67 @@ export HAPI_BOT_URL="https://your-domain.example" hapi ``` -5. Open the UI: -- In Telegram, run `/app` in the bot chat. -- In a browser, open `WEBAPP_URL` and log in with `CLI_API_TOKEN`. +5. Open the UI in a browser at the server URL and log in with `CLI_API_TOKEN`. + +## Telegram Mini App (optional) + +To use Telegram for notifications and the Mini App: + +1. Create a bot with @BotFather and get the token. + +2. Expose your server over HTTPS (Cloudflare Tunnel, Tailscale, etc.). + +3. Add environment variables: + +``` +WEBAPP_URL="https://your-domain.example" +TELEGRAM_BOT_TOKEN="..." +``` + +4. Start the server and send `/start` to the bot to get your chat ID. + +5. Add your chat ID and restart: + +``` +ALLOWED_CHAT_IDS="12345678" +``` + +6. Run `/app` in the bot chat to open the Mini App. + +## Multi-agent support + +- `hapi` - Start a Claude Code session. +- `hapi codex` - Start an OpenAI Codex session. +- `hapi gemini` - Start a Google Gemini session. ## CLI config file + You can store the token in `~/.hapi/settings.json` instead of an env var. Environment variables take priority over the file. ## Requirements -- Claude CLI installed and logged in (`claude` on PATH). -- A Telegram bot token from @BotFather (for Mini App access). + +- Claude CLI installed and logged in (`claude` on PATH) for Claude Code sessions. - Bun if building from source. ## Build from source + ```bash bun install bun run build ``` Build a single binary with embedded web assets: + ```bash bun run build:single-exe ``` ## Docs + - `cli/README.md` - CLI usage and config -- `server/README.md` - server setup and architecture -- `web/README.md` - web app behavior and dev workflow +- `server/README.md` - Server setup and architecture +- `web/README.md` - Web app behavior and dev workflow ## License diff --git a/cli/README.md b/cli/README.md index a5f46589..4b572fc5 100644 --- a/cli/README.md +++ b/cli/README.md @@ -1,56 +1,107 @@ # hapi CLI -Run Claude Code or Codex sessions from your terminal and control them remotely through the hapi server. +Run Claude Code, Codex, or Gemini sessions from your terminal and control them remotely through the hapi server. ## What it does + - Starts Claude Code sessions and registers them with hapi-server. - Starts Codex mode for OpenAI-based sessions. +- Starts Gemini mode via ACP (Anthropic Code Plugins). - Provides an MCP stdio bridge for external tools. - Manages a background daemon for long-running sessions. - Includes diagnostics and auth helpers. ## Typical flow + 1. Start the server and set env vars (see ../server/README.md). 2. Set the same CLI_API_TOKEN on this machine or run `hapi auth login`. 3. Run `hapi` to start a session. 4. Use the web app or Telegram Mini App to monitor and control. -## Quickstart -```bash -# Point to the server if it is not on localhost:3006 -export HAPI_BOT_URL="https://your-server-domain" - -hapi # prompts for CLI_API_TOKEN and saves it locally -``` - ## Commands -- `hapi` - start a Claude Code session (passes through Claude CLI flags) -- `hapi codex` - start Codex mode -- `hapi mcp` - start MCP stdio bridge -- `hapi auth` - login/status/logout for CLI_API_TOKEN -- `hapi server` - start the bundled server (single binary workflow) -- `hapi daemon` - manage background service -- `hapi doctor` - diagnostics and cleanup + +### Session commands + +- `hapi` - Start a Claude Code session (passes through Claude CLI flags). See `src/index.ts`. +- `hapi codex` - Start Codex mode. See `src/codex/runCodex.ts`. +- `hapi gemini` - Start Gemini mode via ACP. See `src/agent/runners/runAgentSession.ts`. + +### Authentication + +- `hapi auth status` - Show authentication configuration and token source. +- `hapi auth login` - Interactively enter and save CLI_API_TOKEN. +- `hapi auth logout` - Clear saved credentials. + +See `src/commands/auth.ts`. + +### Daemon management + +- `hapi daemon start` - Start daemon as detached process. +- `hapi daemon stop` - Stop daemon gracefully. +- `hapi daemon status` - Show daemon diagnostics. +- `hapi daemon list` - List active sessions managed by daemon. +- `hapi daemon stop-session ` - Terminate specific session. +- `hapi daemon logs` - Print path to latest daemon log file. +- `hapi daemon install` - Install daemon as system service. +- `hapi daemon uninstall` - Remove daemon system service. + +See `src/daemon/run.ts`. + +### Diagnostics + +- `hapi doctor` - Show full diagnostics (version, daemon status, logs, processes). +- `hapi doctor clean` - Kill runaway HAPI processes. + +See `src/ui/doctor.ts`. + +### Other + +- `hapi mcp` - Start MCP stdio bridge. See `src/codex/happyMcpStdioBridge.ts`. +- `hapi server` - Start the bundled server (single binary workflow). ## Configuration -Required: -- `CLI_API_TOKEN` - shared secret; must match the server -- `HAPI_BOT_URL` - server base URL (default: http://localhost:3006) -`CLI_API_TOKEN` can be set via env or stored in `~/.hapi/settings.json` (env wins). +See `src/configuration.ts` for all options. -Optional: -- `HAPI_HOME` - config/data directory (default: ~/.hapi) -- `HAPI_EXPERIMENTAL` - enable experimental features (true/1/yes) -- `HAPI_HTTP_MCP_URL` - default MCP target for `hapi mcp` -- `HAPI_CLAUDE_PATH` - path to a specific `claude` executable +### Required + +- `CLI_API_TOKEN` - Shared secret; must match the server. Can be set via env or `~/.hapi/settings.json` (env wins). +- `HAPI_BOT_URL` - Server base URL (default: http://localhost:3006). + +### Optional + +- `HAPI_HOME` - Config/data directory (default: ~/.hapi). +- `HAPI_EXPERIMENTAL` - Enable experimental features (true/1/yes). +- `HAPI_CLAUDE_PATH` - Path to a specific `claude` executable. +- `HAPI_HTTP_MCP_URL` - Default MCP target for `hapi mcp`. + +### Daemon + +- `HAPI_DAEMON_HEARTBEAT_INTERVAL` - Heartbeat interval in ms (default: 60000). +- `HAPI_DAEMON_HTTP_TIMEOUT` - HTTP timeout for daemon control in ms (default: 10000). + +### Gemini/Agent + +- `HAPPY_GEMINI_COMMAND` - Gemini executable command (default: gemini). +- `HAPPY_GEMINI_ARGS` - Gemini arguments (default: --acp). + +## Storage + +Data is stored in `~/.hapi/` (or `$HAPI_HOME`): + +- `settings.json` - User settings (machineId, token, onboarding flag). See `src/persistence.ts`. +- `daemon.state.json` - Daemon state (pid, port, version, heartbeat). +- `logs/` - Log files. ## Requirements + - Claude CLI installed and logged in (`claude` on PATH). - Bun for building from source. ## Build from source + From the repo root: + ```bash bun install bun run build:cli @@ -58,10 +109,23 @@ bun run build:cli:exe ``` For an all-in-one binary that also embeds the web app: + ```bash bun run build:single-exe ``` +## Source structure + +- `src/api/` - Bot communication (Socket.IO + REST). +- `src/claude/` - Claude Code integration. +- `src/codex/` - Codex mode integration. +- `src/agent/` - Multi-agent support (Gemini via ACP). +- `src/daemon/` - Background service. +- `src/commands/` - CLI command handlers. +- `src/ui/` - User interface and diagnostics. +- `src/modules/` - Tool implementations (ripgrep, difftastic, git). + ## Related docs + - `../server/README.md` - `../web/README.md` diff --git a/server/README.md b/server/README.md index 83be3d7b..6af05db8 100644 --- a/server/README.md +++ b/server/README.md @@ -3,6 +3,7 @@ Telegram bot + HTTP API + realtime updates for hapi. ## What it does + - Telegram bot for notifications and the Mini App entrypoint. - HTTP API for sessions, messages, permissions, machines, and files. - Server-Sent Events stream for live updates in the web app. @@ -10,29 +11,31 @@ Telegram bot + HTTP API + realtime updates for hapi. - Serves the web app from `web/dist` or embedded assets in the single binary. - Persists state in SQLite. -## Typical deployment flow -1. Configure env vars. -2. Expose the server to the internet (HTTPS) if you need Telegram Mini App access. -3. Run the server. -4. Point the CLI to the server and open the web app. - ## Configuration -Required: -- `CLI_API_TOKEN` - shared secret used by CLI and web login. -Optional (Telegram): -- `TELEGRAM_BOT_TOKEN` - token from @BotFather. -- `ALLOWED_CHAT_IDS` - comma-separated chat IDs allowed to use the bot. -- `WEBAPP_URL` - public HTTPS URL for Telegram Mini App access. +See `src/configuration.ts` for all options. + +### Required + +- `CLI_API_TOKEN` - Shared secret used by CLI and web login. Auto-generated if not set. + +### Optional (Telegram) + +- `TELEGRAM_BOT_TOKEN` - Token from @BotFather. +- `ALLOWED_CHAT_IDS` - Comma-separated chat IDs allowed to use the bot. +- `WEBAPP_URL` - Public HTTPS URL for Telegram Mini App access. + +### Optional -Optional: - `WEBAPP_PORT` - HTTP port (default: 3006). -- `CORS_ORIGINS` - comma-separated origins, or `*`. -- `HAPI_HOME` - data directory (default: ~/.hapi). -- `DB_PATH` - SQLite database path. +- `CORS_ORIGINS` - Comma-separated origins, or `*`. +- `HAPI_HOME` - Data directory (default: ~/.hapi). +- `DB_PATH` - SQLite database path (default: HAPI_HOME/hapi.db). ## Running + Binary (single executable): + ```bash export TELEGRAM_BOT_TOKEN="..." export ALLOWED_CHAT_IDS="12345678" @@ -47,18 +50,146 @@ To enable Telegram, set TELEGRAM_BOT_TOKEN and WEBAPP_URL, start the server, sen to the bot to get your chat ID, set ALLOWED_CHAT_IDS, and restart the server. From source: + ```bash bun install bun run dev:server ``` -Or inside `server/`: -```bash -bun run start -``` +## HTTP API + +See `src/web/routes/` for all endpoints. + +### Authentication (`src/web/routes/auth.ts`) + +- `POST /api/auth` - Get JWT token (Telegram initData or CLI_API_TOKEN). + +### Sessions (`src/web/routes/sessions.ts`) + +- `GET /api/sessions` - List all sessions. +- `GET /api/sessions/:id` - Get session details. +- `POST /api/sessions/:id/abort` - Abort session. +- `POST /api/sessions/:id/switch` - Switch session mode (remote/local). +- `POST /api/sessions/:id/permission-mode` - Set permission mode. +- `POST /api/sessions/:id/model` - Set model preference. + +### Messages (`src/web/routes/messages.ts`) + +- `GET /api/sessions/:id/messages` - Get messages (paginated). +- `POST /api/sessions/:id/messages` - Send message. + +### Permissions (`src/web/routes/permissions.ts`) + +- `POST /api/sessions/:id/permissions/:requestId/approve` - Approve permission. +- `POST /api/sessions/:id/permissions/:requestId/deny` - Deny permission. + +### Machines (`src/web/routes/machines.ts`) + +- `GET /api/machines` - List online machines. +- `POST /api/machines/:id/spawn` - Spawn new session on machine. + +### Git/Files (`src/web/routes/git.ts`) + +- `GET /api/sessions/:id/git-status` - Git status. +- `GET /api/sessions/:id/git-diff-numstat` - Diff summary. +- `GET /api/sessions/:id/git-diff-file` - File-specific diff. +- `GET /api/sessions/:id/file` - Read file content. +- `GET /api/sessions/:id/files` - File search with ripgrep. + +### Events (`src/web/routes/events.ts`) + +- `GET /api/events` - SSE stream for live updates. + +### CLI (`src/web/routes/cli.ts`) + +- `POST /cli/sessions` - Create/load session. +- `GET /cli/sessions/:id` - Get session by ID. +- `POST /cli/machines` - Create/load machine. +- `GET /cli/machines/:id` - Get machine by ID. + +## Socket.IO + +See `src/socket/handlers/cli.ts` for event handlers. + +Namespace: `/cli` + +### Client events (CLI to server) + +- `message` - Send message to session. +- `update-metadata` - Update session metadata. +- `update-state` - Update agent state. +- `session-alive` - Keep session active. +- `session-end` - Mark session ended. +- `machine-alive` - Keep machine online. +- `rpc-register` - Register RPC handler. +- `rpc-unregister` - Unregister RPC handler. + +### Server events (server to clients) + +- `update` - Broadcast session/message updates. +- `rpc-request` - Incoming RPC call. + +See `src/socket/rpcRegistry.ts` for RPC routing. + +## Telegram Bot + +See `src/telegram/bot.ts` for bot implementation. + +### Commands + +- `/start` - Welcome message with chat ID. +- `/app` - Open Mini App. + +### Features + +- Permission request notifications with approve/deny buttons. +- Session ready notifications. +- Deep links to Mini App sessions. + +See `src/telegram/callbacks.ts` for button handlers. + +## Core Logic + +See `src/sync/syncEngine.ts` for the main session/message manager: + +- In-memory session cache with versioning. +- Message pagination and retrieval. +- Permission approval/denial. +- RPC method routing via Socket.IO. +- Event publishing to SSE and Telegram. +- Git operations and file search. +- Activity tracking and timeouts. + +## Storage + +See `src/store/index.ts` for SQLite persistence: + +- Sessions with metadata and agent state. +- Messages with pagination support. +- Machines with daemon state. +- Todo extraction from messages. + +## Source structure + +- `src/web/` - HTTP server and routes. +- `src/socket/` - Socket.IO setup and handlers. +- `src/telegram/` - Telegram bot. +- `src/sync/` - Core session/message logic. +- `src/store/` - SQLite persistence. +- `src/sse/` - Server-Sent Events. + +## Security model + +Access is controlled by: +- Telegram chat ID allowlist (when Telegram is enabled). +- `CLI_API_TOKEN` shared secret for CLI and browser access. + +Transport security depends on HTTPS in front of the server. ## Build for deployment + From the repo root: + ```bash bun run build:server bun run build:web @@ -67,15 +198,6 @@ bun run build:web The server build output is `server/dist/index.js`, and the web assets are in `web/dist`. ## Networking notes + - Telegram Mini Apps require HTTPS and a public URL. If the server has no public IP, use Cloudflare Tunnel or Tailscale and set `WEBAPP_URL` to the HTTPS endpoint. - If the web app is hosted on a different origin, set `CORS_ORIGINS` accordingly. - -## Architecture overview -The server is the hub for direct-connect mode. It accepts CLI connections over Socket.IO, exposes HTTP endpoints for the web UI, and publishes live updates over SSE. A Telegram bot provides notifications and a Mini App entrypoint. Session and machine state are stored in a local SQLite database. - -## Security model -Access is controlled by: -- Telegram chat ID allowlist (when Telegram is enabled). -- `CLI_API_TOKEN` shared secret for CLI and browser access. - -Transport security depends on HTTPS in front of the server. diff --git a/web/README.md b/web/README.md index b2807c20..1437bd16 100644 --- a/web/README.md +++ b/web/README.md @@ -3,20 +3,109 @@ React Mini App / PWA for monitoring and controlling hapi sessions. ## What it does -- Session list with status, pending approvals, and summaries. + +- Session list with status, pending approvals, todos, and summaries. - Chat view with streaming updates and message sending. - Permission approval and denial workflows. +- Permission mode and model selection. - Machine list and remote session spawn. - File browser and git status/diff views. - PWA install prompt and offline banner. ## Runtime behavior + - When opened inside Telegram, auth uses Telegram WebApp init data. - When opened in a normal browser, you can log in with the shared `CLI_API_TOKEN`. - Live updates come from the server via SSE. +## Routes + +See `src/router.tsx` for route definitions. + +- `/` - Redirect to /sessions. +- `/sessions` - Session list. +- `/sessions/$sessionId` - Chat interface. +- `/sessions/new` - Create new session. +- `/sessions/$sessionId/files` - File browser with git status. +- `/sessions/$sessionId/file` - File viewer with diff support. + +## Features + +### Session list (`src/components/SessionList.tsx`) + +- Active/inactive status indicator. +- Session title from name, summary, or path. +- Todo progress display. +- Pending permission request count. +- Agent flavor label (claude/codex/gemini). +- Model mode display. + +### Chat interface (`src/components/SessionChat.tsx`) + +- Message thread with infinite scroll. +- Composer for sending messages. +- Permission mode toggle (default/acceptEdits/bypassPermissions/plan). +- Model selection (default/sonnet/opus). +- Session abort and mode switch controls. +- Context size display. + +### File browser (`src/routes/sessions/files.tsx`) + +- Git status view (staged/unstaged files). +- File search with ripgrep. +- Navigate to file viewer. + +### File viewer (`src/routes/sessions/file.tsx`) + +- File content display with syntax highlighting. +- Staged/unstaged diff view. + +### New session (`src/components/NewSession.tsx`) + +- Machine selector. +- Directory input with recent paths. +- Agent type selector (claude/codex/gemini). + +## Authentication + +See `src/hooks/useAuth.ts` and `src/hooks/useAuthSource.ts`. + +- Telegram Mini App: Uses initData from WebApp SDK. +- Browser: Uses CLI_API_TOKEN from login prompt. +- JWT tokens with auto-refresh. + +## Data fetching + +See `src/hooks/queries/` for query hooks and `src/hooks/mutations/` for mutations. + +- Sessions, messages, machines via TanStack Query. +- Git status and file operations. +- Optimistic updates for message sending. + +## Real-time updates + +See `src/hooks/useSSE.ts`. + +- SSE connection to `/api/events`. +- Session/message/machine update events. +- Automatic cache invalidation on events. + +## Stack + +React 19 + Vite + TanStack Router/Query + Tailwind + @assistant-ui/react. + +## Source structure + +- `src/router.tsx` - Route definitions. +- `src/components/` - UI components. +- `src/hooks/` - Data fetching and state hooks. +- `src/api/client.ts` - API client. +- `src/types/api.ts` - Type definitions. + ## Development + From the repo root: + ```bash bun install bun run dev:web @@ -27,11 +116,9 @@ If testing in Telegram, set: - `CORS_ORIGINS` to include the dev server origin. ## Build + ```bash bun run build:web ``` The built assets land in `web/dist` and are served by hapi-server. The single executable can embed these assets. - -## Stack -React 19 + Vite + TanStack Router/Query + Tailwind.