harness-ai-app
Mobile client for Harness AI — follow, answer and approve your hosted agent sessions from your phone. Expo + React Native, talks only to your own server.
- Stars
- 0
- Language
- TypeScript
- Created
- Aug 21, 2026
- Updated
- Aug 25, 2026
Introduction
English · 简体中文
Features · Architecture · Design notes · Run it · Releases · Layout · Roadmap
harness-ai-app is the mobile client of Harness AI. The agent runs on your desktop machine; this app is how the session follows you out of the room — read the trajectory, answer the questions it asks, approve the step it is waiting on, and start the next one.
It is a pure client of harness-ai-server. It never connects to your desktop machine, and there is nothing for it to connect to: the runtime binds loopback only. Everything you see here was pushed out by the desktop client over its own outbound link.
[!IMPORTANT] Developer preview. Android and web are the surfaces built and verified today. A test APK is on the Releases page — signed with the Android debug key, not a store build. See Running it.
What you can do
| Follow a session | Hosted sessions grouped by workspace, with the trajectory folded into something readable on a phone: messages as Markdown, tool calls as rows, images inline. |
| Answer | The runtime's questions — including plan reviews — arrive as native choices rather than as text you have to parse. Plan bodies render as Markdown. |
| Approve | Pending approvals in their own tab. Allowing an irreversible step passes through a confirmation; denying does not — only the side you cannot take back needs a gate. |
| Start work | Open a new session against a workspace the desktop has already synced. If the desktop is offline, the prompt is queued server-side and delivered when it comes back. |
| Attachments | Images the agent produced load on demand, with an "auto-load images" switch and your storage quota shown as it really is. Not-yet-loaded is a normal state with a first-class placeholder, not an error. |
| Devices and account | See your signed-in devices, the server you are pointed at, theme and language. |
Self-hosted by design: the server address is entered on the sign-in screen and persisted per install, because the address of your server is user data, not a constant baked into the build.
Where it sits
flowchart LR
desktop["harness-ai-desktop<br/>runtime on your machine"] -.->|"outbound push"| server["harness-ai-server<br/>account · sessions · approvals"]
app["harness-ai-app<br/>this repository"] <-->|"HTTPS · bearer + device id"| server
app -.->|"never connects"| desktop
style app fill:#0f766e,color:#ffffff,stroke:#0f766e
Design notes
The parts of this app worth knowing before you change it:
- Typography goes through one component.
<Text variant>only — a bare React NativeTextdoes not inherit colour, and one missed instance is black-on-black in dark mode. Machine text (paths, tool names, workspace directories) is always the mono variant. - Surfaces are flat. Hairline borders and zero shadow, identical in both themes; hierarchy comes from the border, not from elevation, because Android dark elevation paints a dirty tint.
- No reanimated, no worklets, no gesture-handler. All three are excluded from autolinking for the local build, so importing one is a runtime crash.
pnpm verifyfails the build if an import appears — or if atransition-*/animate-*class appears without aweb:prefix, which is the case an import scan cannot catch and the one that actually broke a screen. - UI primitives are vendored, not depended on. Components are copied in from react-native-reusables and adapted (
@rn-primitives/*only, touch-sized controls, repository code style). Each vendored file says where it came from. - Feedback is inline, never a toast. In a scrolling screen a toast is a message the user misses.
The cross-surface token vocabulary is shared with the desktop and web clients; lib/theme.tsx is this app's single source of colour.
Running it
Prerequisites — Node 22+, pnpm 11, a reachable harness-ai-server, and for a device build the Android SDK.
The wire contracts this app shares with the desktop client and the server come from npm as @harness-ai/contracts, so a plain clone installs and builds.
pnpm install
pnpm verify # native-import guard + typecheck
pnpm start # Expo dev server (dev client)
| Command | What it does |
|---|---|
pnpm start | Expo dev server against a development build. |
pnpm android | Build and run on a connected device or emulator. |
pnpm prebuild | Regenerate the native Android project from app.json. |
pnpm verify | The guard that must pass: excluded-native scan plus tsc --noEmit. |
pnpm verify:attachments-web | Browser end-to-end pass over the attachment path against a real server. |
pnpm icons | Regenerate the app icons — deterministic, no imaging dependency. |
The server address defaults to http://10.0.2.2:8720 on an emulator and http://localhost:8720 on web; override it at sign-in, or with EXPO_PUBLIC_HARNESS_API_BASE.
Releases
Every push and pull request runs the native-import guard, typecheck and a web bundle build.
A release is a tag. Pushing v<version> runs the same gate, generates the native project and assembles the Android APK onto a GitHub Release:
git tag v0.1.0 && git push origin v0.1.0
The tag must agree with both package.json and app.json, and CHANGELOG.md must carry a section for it — all three are checked before anything is built, and that section becomes the release notes. The APK is signed with the Android debug key — it installs for testing and is not a store artifact; proper signing waits on the platform decision.
Project layout
app/ Routes (expo-router)
(tabs)/ Sessions · Approvals · Me
session/[id].tsx Session detail and the folded trajectory
login.tsx Sign-in and the server address
new-session.tsx Start a session on a synced workspace
components/ Screen furniture and the UI kit (components/ui, partly vendored)
lib/ API client, auth, hosted-session queries, i18n, theme, preferences
scripts/ Icon generation, the native-import guard, the web e2e driver
plugins/ Expo config plugins
Roadmap
| ✅ Shipped | Sign-in and self-hosted server address · session list and trajectory · questions and plan review · approvals · queued prompts · attachments with quota · themes and en/zh |
| 🚧 Open | Whether iOS ships alongside Android is still an open decision, and with it the prebuild and store path |
| 📋 Planned | Store distribution — the tagged APK is a debug-signed test build, which no store will take |
Contributing
Issues and pull requests are welcome — start with CONTRIBUTING.md. If you touch the UI, keep to the design notes above; pnpm verify enforces the two rules that have actually bitten.
License
MIT © harness-home