The native HarmonyOS client for Hapi
A native rewrite of the official React Web/PWA frontend in ArkTS + ArkUI, talking to the same Hub backend — control your locally-running AI coding agents (Claude Code / Codex / Gemini) remotely from HarmonyOS devices.
English · 简体中文
hapi-hmos = Hapi + HarmonyOS
📱 Screenshots TBD: login / session list / chat / tool cards / reasoning / dark mode.
The protocol is identical to the official Web client — only the frontend is replaced with a native HarmonyOS implementation.
- Message stream: user / agent / reasoning (thinking, collapsible) / tool-call, color-coded bubbles
- Markdown rendering: code syntax highlighting + copy + fullscreen preview, in-app image preview, open external links
- Full tool-card lifecycle: running (elapsed timer) / completed / error / pending approval, with permission approval and AskUserQuestion / Checklist footers
- In-conversation message search: filter mode, searches body text + tool name / args / results
- Message long-press menu: copy / resend failed / share
- Message timestamps + cross-day date dividers (today / yesterday / date)
- Export / share an entire conversation as a plain-text transcript
- Session list: search & filter, pull-to-refresh, long-press menu (rename / archive / delete)
- Session lifecycle actions (aligned with Hub REST: PATCH rename, archive, DELETE)
- Live status: active / generating (thinking) indicators
- SSE realtime push: session & message deltas (
/api/events, an EventSource-equivalent implementation) - JWT auto-refresh: REST + SSE auth self-healing; tokens renew automatically on expiry
- Message pagination: load older history on scroll-to-top
- Abort (stop generation): interrupt an in-flight generation with one tap
- JS-driven palette + light / dark color sets
- Light / Dark / Follow system three-way toggle + local persistence
- Pure-logic unit tests (
entry/src/testLocalUnit): Reducer, ChatSearch, Message, SyncEvent, AgentState, HubClient/SSE utils, … - V2 state management (
@ComponentV2/@Local/@Param/@Event/@Builder) - Pure-function render pipeline:
ChatMessage[] + AgentState → Reducer → ChatBlock[](easy to test, easy to diff against upstream)
Official Hapi is a local-first AI coding agent platform: agents run on your local machine and are controlled remotely via Web/PWA/Telegram. Its core architecture is three-tier:
CLI (wraps agent) ←Socket.IO→ Hub (HTTP API + SSE + Telegram) ←SSE/REST→ Web (React PWA)
The official project ships only a Web/React PWA client. hapi-hmos ports it to a native HarmonyOS app:
- Protocol unchanged: reuses the same Hub backend, only the frontend is replaced
- Native experience: rewritten in ArkTS + ArkUI, using HarmonyOS system capabilities
- Tracks upstream: follows the official Web feature set over time
┌───────────────────────┐ HTTP REST + SSE ┌─────────────────┐
│ hapi-hmos (ArkTS) │ ←──────────────────→ │ Hapi Hub │
│ EntryAbility / Pages │ (CLI_API_TOKEN) │ (:3006 default) │
└───────────────────────┘ └─────────────────┘
Native app talks only ↑
to Hub, never to CLI/agent Socket.IO
│
┌─────────────┐
│ CLI (agent) │
└─────────────┘
Data flow (identical to the official Web client):
- On launch, the app logs in to the Hub with
CLI_API_TOKEN - Subscribes to SSE
/api/eventsfor realtime session / message updates - User actions → REST API → Hub → RPC → CLI → agent
- Agent events → CLI → Hub (persisted to SQLite + broadcast via SSE) → app
| Layer | Technology |
|---|---|
| Language | ArkTS (TypeScript superset; strongly typed, no dynamic features) |
| UI framework | ArkUI declarative, V2 state management (@ComponentV2 / @Local / @Param / @Event / @Builder) |
| App model | Stage model (UIAbility + EntryAbility) |
| Networking | @ohos.net.http + SSE (EventSource-equivalent, custom frame parser) |
| Persistence | @ohos.data.preferences |
| Sharing | @kit.ShareKit |
| Markdown | @cangjie-tpc/markdown_hybrid |
| Build / IDE | DevEco Studio, hvigor |
| Target | HarmonyOS 6.1.0 (API 23) |
- DevEco Studio (latest stable)
- HarmonyOS SDK (API 23 / HarmonyOS 6.1+)
- A running Hapi Hub (for integration testing)
npx @twsxtd/hapi hub --relay # start a Hub with an E2E-encrypted relay
# the terminal prints a URL / QR code + CLI_API_TOKENThe Hub listens on 127.0.0.1:3006 by default; for remote access from a HarmonyOS device you need a public address or reverse proxy — see 参考源码/hapi-v0.25.4/docs/guide/installation.md.
- DevEco Studio → Open → select this repo root
- Sync the SDK and wait for the hvigor build to finish
- Fill in the Hub address and
CLI_API_TOKENin the app config - Connect a device / emulator and run
entry
Emulator tip: if the Hub runs on the host at
127.0.0.1:3006, access it ashttp://10.0.2.2:3006from the emulator; on a real device use the host's LAN IP.
hapi-hmos/
├── entry/src/main/ets/
│ ├── entryability/ # EntryAbility (Stage model entry)
│ ├── pages/ # LoginPage / Index (session list) / ChatPage / SettingsPage
│ ├── components/ # ToolCard, MarkdownText, ReasoningBubble, DiffView,
│ │ # SessionActionMenu, CodeBlock, AskUserQuestion, …
│ ├── chat/ # render-pipeline pure logic: Reducer / ChatBlock / ChatSearch /
│ │ # AgentState / NormalizedContent / Diff / Checklist, …
│ ├── api/ # HubClient (REST) + SSEClient (with frame-parser utils)
│ ├── models/ # aligned with upstream shared/src: Types / Message / SyncEvent / Auth / HubConfig
│ ├── theme/ # Palette / ThemeService / ThemeState (JS palette + light/dark sets)
│ ├── services/ # Connection / Preferences / Share
│ └── utils/ # DateFormatUtils, …
├── AppScope/ # app-wide config (app.json5, icons)
├── entry/src/test/ # pure-logic unit tests (LocalUnit)
├── docs/ # porting notes, reference-project notes
├── .claude/skills/ # HarmonyOS doc-retrieval skills (ArkTS / ArkUI retriever)
└── 参考源码/ (Reference/) # local read-only references (NOT committed, see below)
参考源码/ keeps two local clones of the official repo as a read-only porting reference (not committed, see below). The folder name carries the version, so they sit side by side for comparison:
| Directory | Version | commit | Notes |
|---|---|---|---|
参考源码/hapi-v0.25.4/ |
0.25.4 (current, primary) | 2d7115f (tag v0.25.4, 2026-08-03) |
Latest stable release — the authoritative reference for all porting |
参考源码/hapi-v0.18.4/ |
0.18.4 series (legacy snapshot) | ec3722a (2026-05-29) |
Early porting baseline; kept for historical comparison only |
| Field | Value |
|---|---|
| Repo | https://github.com/tiann/hapi |
| Git URL | https://github.com/tiann/hapi.git |
| npm package | @twsxtd/hapi |
| Current reference version | 0.27.2 (pinned to tag v0.27.2) |
| License | AGPL-3.0-only |
| Authors | Kirill Dubovitskiy & weishu |
| Project | Role | Reference scope |
|---|---|---|
| chatcube (MIT) | 🥇 Primary | Layout, styling, streaming chat, session management (business / architecture / UX across the board) |
| berry3 | 🥈 Secondary | Low-level code only (system-capability calls, specific low-level impls); license unknown → reference only, do not copy code |
When unsure about ArkUI patterns / page layout / chat / session management → check chatcube first; only consult berry3 for low-level / system capabilities.
The primary reference 参考源码/hapi-v0.25.4/ is a standalone git clone (not a submodule), pinned to tag v0.25.4 (detached HEAD, so it doesn't drift with main) to keep the porting reference stable. To move to a newer version:
cd 参考源码/hapi-v0.27.2
git fetch origin --tags
git tag --sort=-creatordate | head -5 # see the latest tags
git checkout <new-tag> # switch to the new stable release (detached)
git rev-parse HEAD # take the new commit, fill it into the table above
# after updating, rename the folder hapi-v0.27.2 → hapi-v<new-version> and update doc pathsWhy
参考源码/isn't committed: it holds local reference clones of upstream (multiple version snapshots) + chatcube (each with its own.git), kept only for reading; a plain directory is simpler than a submodule, and version pinning is tracked by "versioned folder name + recorded commit". If you clone this repo and want the reference, justgit clone tiann/hapi && git checkout v0.27.2yourself.
- CLAUDE.md — AI assistant working guide, porting conventions, command cheatsheet
- docs/官方仓库对照.md — upstream module mapping + Hub API cheatsheet + sync method
- docs/参考项目.md — HarmonyOS reference projects (chatcube primary, berry3 secondary) + doc-retrieval skill notes
Official Hapi is AGPL-3.0-only. As a derived client port, this project is likewise released under AGPL-3.0 (see LICENSE).
⚠️ AGPL requires: derivative works offered over a network must disclose their source. If you build on this and offer it as a service, you must comply with AGPL's open-source obligations.
- Upstream: tiann/hapi (authors Kirill Dubovitskiy & weishu)
- Hapi is a local-first fork of Happy; "HAPI" is a transliteration of 哈皮 (Chinese for "happy")
- HarmonyOS reference: chatcube (MIT — layout / chat / session UX reference)