CLI App (happy-cli)
Relevant source files
The following files were used as context for generating this wiki page:
happy-cli (also known as happy-coder) is a Node.js-based command-line interface that serves as a wrapper for Claude Code. Its primary purpose is to enable remote control and real-time session sharing across devices while maintaining end-to-end encryption. It acts as the local bridge between the developer's environment and the wider Happy ecosystem, which includes mobile clients and a synchronization server.
Sources: apps/cli/CLAUDE.md, CLAUDE.md:12-15
The application operates in two primary modes: interactive mode, where it runs within a terminal via a PTY (Pseudo-Terminal), and remote mode, where control is handed over to a mobile or web client. It captures the state of Claude sessions, encrypts the data using AES-256-GCM or TweetNaCl, and synchronizes it via WebSockets to the Happy server.
Sources: apps/cli/CLAUDE.md, knowledge.md:28-33
Architecture and Core Components
The architecture of happy-cli is designed around a central control loop that manages the lifecycle of the AI agent and its communication with external clients.
System Data Flow
The following diagram illustrates how the CLI interacts with Claude Code locally and the Happy ecosystem remotely.
Explanation: The CLI wraps the Claude Code subprocess, captures its output, encrypts it, and sends updates to the Happy Server, which then relays them to authorized remote clients.
Sources: CLAUDE.md:125-135, apps/cli/CLAUDE.md
Key Components
| Component | Description |
|---|---|
| Control Loop | Managed in loop.ts, it orchestrates the transition between interactive terminal sessions and remote mobile control. |
| API Module | Handles authentication (TweetNaCl signatures), WebSocket connections (Socket.IO), and E2E encryption. |
| Command Registry | A centralized definition of all CLI commands, subcommands, and options used for auto-generated help. |
| Daemon Subsystem | A background service that enables spawning new sessions remotely without manual terminal interaction. |
| Path Security | Implements defense-in-depth by restricting allowed shell commands to a predefined list. |
Sources: apps/cli/CLAUDE.md, apps/cli/src/commands/registry.ts:13-100
Command System
The CLI uses a structured command registry to ensure consistency and type safety. This registry is defined using Zod schemas for runtime validation of command metadata.
Command Execution Flow
When a user executes a command, it passes through the registry and router before hitting the specific handler.
Explanation: Every command input is validated against the registry schema before being routed to the appropriate module handler.
Sources: apps/cli/src/commands/registry.ts:20-60, apps/cli/CLAUDE.md
Primary Commands
| Command | Subcommands | Description |
|---|---|---|
auth | login, logout, status | Manages Ed25519-based authentication and machine registration. |
daemon | start, stop, status, logs | Controls the background service for remote session spawning. |
doctor | clean, (none) | System diagnostics and process cleanup (kills runaway Happy/caffeinate processes). |
mcp | list, add, remove, enable | Manages Model Context Protocol servers for AI tool integration. |
notify | -p (message), -t (title) | Sends push notifications to connected mobile devices via Expo. |
Sources: apps/cli/src/commands/registry.ts:102-220
Claude Integration and Loop
The core logic for interacting with Claude is located in src/claude/loop.ts. The CLI leverages a globally installed version of Claude Code rather than bundling it.
Interaction Modes
- Interactive Mode: The CLI spawns Claude in a PTY. A file system watcher monitors session files (JSONL) to snoop on the conversation and sync it to the server.
- Remote Mode: Control is driven by the Happy Server via RPC. The CLI uses the Claude SDK to execute tasks and returns results to the remote client.
Sources: apps/cli/CLAUDE.md, apps/cli/src/claude/loop.ts
Session Resumption
The CLI supports the --resume flag, which allows Claude to continue previous conversations. When resuming, Claude creates a new session ID and file, but prefixes it with the history of the original session. The CLI handles this by updating historical message session IDs to match the new unified history.
Sources: apps/cli/CLAUDE.md
Security and Encryption
Security is a fundamental requirement of the CLI, utilizing end-to-end encryption so that the server never sees plaintext user data.
Encryption Standards
- Algorithm: AES-256-GCM (clients) and TweetNaCl secretbox (server secrets).
- Key Management: Private keys are stored locally in
~/.happy/access.keywith restricted permissions. - Nonce Strategy: Uses a hybrid nonce (4 random bytes + 8-byte monotonic counter) to prevent collisions.
Sources: CLAUDE.md:180-185, apps/cli/CLAUDE.md
Command Allowlist (Defense-in-Depth)
To prevent arbitrary code execution if a remote device is compromised, the CLI implements a strict command allowlist in src/modules/common/pathSecurity.ts.
| Category | Allowed Commands |
|---|---|
| Git | status, diff, log, branch, show, fetch, ls-files |
| Files | ls, cat, head, tail, pwd, find, tree |
| Build | npm, yarn, pnpm, node, tsc |
| Search | grep, rg, jq, yq |
Sources: apps/cli/CLAUDE.md
Process Lifecycle Management
The CLI handles complex process lifecycles, especially when wrapping subprocesses and managing background daemons.
Signal Handling
Handlers for SIGINT, SIGTERM, and exit must follow strict patterns to avoid memory leaks and handler accumulation:
- Per-Call Pattern: Functions called multiple times (like
runClaude) must explicitly remove listeners after execution. - Singleton Pattern: Global setup functions (like
caffeinate) keep listeners for the life of the process.
// Example of correct handler removal
const exitHandler = () => cleanup();
process.on('exit', exitHandler);
// ... after operation ...
process.removeListener('exit', exitHandler);
Sources: apps/cli/CLAUDE.md
Summary
The happy-cli application is a robust TypeScript-based tool that extends the capabilities of Claude Code into a multi-device environment. By combining PTY-based interaction, WebSocket synchronization, and rigorous E2E encryption, it provides developers with a secure way to monitor and control AI coding agents remotely. Its architecture emphasizes strict typing, defensive security (command allowlists), and reliable process management.
Sources: CLAUDE.md:12-20, apps/cli/CLAUDE.md