Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 9 additions & 7 deletions CLAUDE.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,12 @@
This file provides guidance to Claude Code (claude.ai/code) when working with code in this
repository.

## Project status: Phase 0–3 on `main`; Phase 5–6 spikes on `main`; Phase 7 (Bluetooth offline connectivity) started 2026-10-28, BLE L2CAP pairing/control channel on `main`, release `v0.2.0` pending the owner's tag (Wi-Fi Direct and relay bulk dropped from this phase's scope); latest tagged release `v0.1.1` (2026-10-22); G1/G2/G5/G6 open; G4 closed (Phase 4 stopped, owner decision 2026-10-12)
## Project status: Phase 0–3 on `main`; Phase 5–6 spikes on `main`; Phase 7 (Bluetooth offline connectivity) released in `v0.2.0` (2026-10-30), BLE L2CAP pairing/control channel on `main` (Wi-Fi Direct and relay bulk dropped from this phase's scope); latest tagged release `v0.2.0` (2026-10-30); G1/G2/G5/G6 open; G4 closed (Phase 4 stopped, owner decision 2026-10-12)

Phase 0–3 product code is on `main` (clipboard, SMS, iOS shell, Rust relay, call metadata/control). Phase 4–6
**spike probes** are also on `main` (merged 2026-09-30): `HFPSpike`, `CameraSpike`, Android `tools/web-spike`,
Apple `Tools/WebSpike`. Coordinated public betas: **`v0.1.0-beta.1`**, **`v0.1.0-beta.2`** (2026-10-04, the first with installable files) and **`v0.1.0-beta.3`** (2026-10-07) on hub/android/apple/shared/relay
(not a store release), then **`v0.1.1`** (2026-10-22), the first tag without a pre-release suffix (still not a store release; Google Play readiness on Android, paid-team identifiers on iOS). Live progress board: hub `README.md` / `README.vi.md` (Roadmap and progress). Still
(not a store release), then **`v0.1.1`** (2026-10-22), the first tag without a pre-release suffix (still not a store release; Google Play readiness on Android, paid-team identifiers on iOS), then **`v0.2.0`** (2026-10-30), Phase 7 Bluetooth offline pairing (still not a store release). Live progress board: hub `README.md` / `README.vi.md` (Roadmap and progress). Still
required before 1.0: gates **G1** (device matrix, TalkBack/VoiceOver) and **G2** (Play Console), Phase 2/3 checks
on a real relay / APNs / FCM, and spike gates **G5** (paid Apple Developer team), **G6** (browser go/no-go). Owner
decision 2026-09-28: Phases 5 and 6 proceed before Phase 4. Owner decision 2026-10-12 stops Phase 4 itself and
Expand Down Expand Up @@ -61,7 +61,7 @@ project owner in Vietnamese with diacritics.

**Commit identity:** always `Hồ Xuân Dũng <me@hxd.vn>` (GitHub `xuandung38`). Never `dunghx1@viettel.com.vn` or any Viettel email in author/committer/`Signed-off-by`. Use `env -u CURSOR_AGENT git commit` so Cursor does not inject Co-authored-by trailers.

**Workspace tips to treat as current `main`** (ahead of tag `v0.1.1`; release `v0.2.0` pending the owner's tag, Phase 7 Bluetooth offline connectivity): shared `5cbe4aa`, relay `17f367b` (unchanged since `v0.1.1`), android `ed8e41f`, apple `7d3ce0b`, hub `main` tip. Confirm with `tools/workspace.sh status` before coding. **Local JDK:** Gradle needs `JAVA_HOME=/opt/homebrew/opt/openjdk@21/libexec/openjdk.jdk/Contents/Home` in a non-login shell, else `gradlew` prints "Unable to locate a Java Runtime" and a piped command still exits 0.
**Workspace tips to treat as current `main`:** tagged `v0.2.0` (2026-10-30) at hub `a9c7193`, shared `6e44aa1`, android `cd4527a`, apple `36f8cc8`, relay `17f367b` (unchanged since `v0.1.1`). Confirm with `tools/workspace.sh status` before coding. **Local JDK:** Gradle needs `JAVA_HOME=/opt/homebrew/opt/openjdk@21/libexec/openjdk.jdk/Contents/Home` in a non-login shell, else `gradlew` prints "Unable to locate a Java Runtime" and a piped command still exits 0.

### In progress / blocked (owner or gate)

Expand Down Expand Up @@ -95,10 +95,12 @@ project owner in Vietnamese with diacritics.
logs nothing for the bench) and keep HandLive's Notification access on. Then the Mac
must show "Telegram Call"; swiping Telegram's in-call notification must keep the Mac panel in-call with End hidden,
and hanging up must close it. Then run `call_latency.py` on a real app call for T3.3.
9. **Next release:** follow `docs/deployment-guide.md` (Cutting a release) and the 0.1.1 scan report: security scan of
everything since the last tag first, then versions, changelogs, website link and badge, tags (hub and shared first).
Open from the 0.1.1 scan: wrap the iOS UI-test seams (`-HLUITest*` launch arguments) and their `/tmp` debug writes
in `#if DEBUG`, fix the `project.yml` comment that calls `HandLiveiOSUITests` uncommitted.
9. **Next release:** follow `docs/deployment-guide.md` (Cutting a release) and the 0.2.0 scan report
(`reports/security-scan-0.2.0-2026-10-30.md`): security scan of everything since the last tag first, then versions,
changelogs, website link and badge, tags (hub and shared first). The 0.2.0 scan found nothing: 0 critical, 0 high,
0 medium, 0 low. Still open, carried over from the 0.1.1 scan (untouched by Phase 7): wrap the iOS UI-test seams
(`-HLUITest*` launch arguments) and their `/tmp` debug writes in `#if DEBUG`, fix the `project.yml` comment that
calls `HandLiveiOSUITests` uncommitted (it is tracked in git).
10. **Open follow-ups** (no gate): `ManualClock` review debt, apple #5 being merged (`waitForSleepers` ignores
cancellation; test helpers' `clock:`/`timer:` swapped); keep `-parallel-testing-enabled NO` (parallel saves ~0 s);
measure the app-call label on Android 11–14 to know whether the launcher query matters there. The e2e `setup` check of
Expand Down
6 changes: 3 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,13 +8,13 @@ English | [Tiếng Việt](README.vi.md)

[![ci-docs](https://github.com/HandLive/handlive/actions/workflows/ci-docs.yml/badge.svg)](https://github.com/HandLive/handlive/actions/workflows/ci-docs.yml)
[![License: Apache-2.0](https://img.shields.io/badge/License-Apache_2.0-blue.svg)](LICENSE)
[![Release](https://img.shields.io/badge/release-v0.1.1-orange.svg)](https://github.com/HandLive/handlive/releases/tag/v0.1.1)
[![Release](https://img.shields.io/badge/release-v0.2.0-orange.svg)](https://github.com/HandLive/handlive/releases/tag/v0.2.0)

HandLive connects Android devices with macOS, iOS, and iPadOS. It syncs your clipboard, bridges SMS conversations, and delivers call notifications with action controls—without cloud lock-in. End-to-end encryption is always on, and the entire project is open source under Apache-2.0.

## Get the beta

Download the latest release [`v0.1.1`](https://github.com/HandLive/handlive/releases/tag/v0.1.1) (2026-10-22):
Download the latest release [`v0.2.0`](https://github.com/HandLive/handlive/releases/tag/v0.2.0) (2026-10-30):
- **macOS:** Ad-hoc signed DMG (choose *Open Anyway* on first run).
- **Android:** Signed `foss` APK. Its application id is new (`com.handlive.android`): remove a beta install first, then pair again.
- **iOS / iPadOS:** Unsigned IPA for sideloading. A beta install updated to this build must pair again (new App Group).
Expand Down Expand Up @@ -67,7 +67,7 @@ Phases ship in order, each as a usable slice. One exception (owner, 2026-09-28):
| **4** Call audio | Bluetooth HFP/SCO and Opus fallback | **Stopped** (owner decision, 2026-10-12) · G4 closed: only macOS 27 is available, so calls stay notification + answer/decline/end, no audio |
| **5** Virtual camera / mic | CMIOExtension and AudioServerPlugin | **Spike on `main`** (`CameraSpike`) · G5 needs a paid Apple Developer team |
| **6** Continue Browsing | Foreground URL handover across devices | **Spike on `main`** · Chrome and Samsung Internet measured; browser go/no-go pending |
| **7** Connect anywhere | Auto link without a shared Wi-Fi network | **Started** (owner decision, 2026-10-28), no wait on G4/G5/G6 · spike G7 done; Bluetooth L2CAP pairing and control channel on `main`, Wi-Fi Direct and relay bulk dropped from this phase's scope |
| **7** Connect anywhere | Auto link without a shared Wi-Fi network | **Released in `v0.2.0`** (2026-10-30) · Bluetooth offline pairing (QR flow B, PIN flow C via CPace-X25519-SHA512) shipped on `main`; Wi-Fi Direct and relay bulk specced but dropped from this phase's scope |
| **G0** Vectors | Shared cross-platform crypto test vectors | **Done** |
| **G1** Real devices | Real-device Phase 1 matrix validation | **Open** (before 1.0) · App Store Connect screenshots recaptured at native 1320×2868 (2026-10-12) |
| **G2** Play Console | SMS and call log permissions declaration | **Open** (before 1.0; Plan B: F-Droid/APK) · Play Console screenshots recaptured at 1080×1920 (2026-10-12) |
Expand Down
6 changes: 3 additions & 3 deletions README.vi.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,13 +8,13 @@

[![ci-docs](https://github.com/HandLive/handlive/actions/workflows/ci-docs.yml/badge.svg)](https://github.com/HandLive/handlive/actions/workflows/ci-docs.yml)
[![License: Apache-2.0](https://img.shields.io/badge/License-Apache_2.0-blue.svg)](LICENSE)
[![Release](https://img.shields.io/badge/release-v0.1.1-orange.svg)](https://github.com/HandLive/handlive/releases/tag/v0.1.1)
[![Release](https://img.shields.io/badge/release-v0.2.0-orange.svg)](https://github.com/HandLive/handlive/releases/tag/v0.2.0)

HandLive kết nối điện thoại Android với các thiết bị macOS, iOS và iPadOS. Ứng dụng đồng bộ bảng nhớ tạm, chuyển tiếp tin nhắn SMS và hiển thị thông báo cuộc gọi kèm nút thao tác—hoàn toàn không phụ thuộc vào đám mây. Mã hóa đầu cuối luôn bật, và toàn bộ dự án là mã nguồn mở theo giấy phép Apache-2.0.

## Tải bản beta

Tải bản phát hành mới nhất [`v0.1.1`](https://github.com/HandLive/handlive/releases/tag/v0.1.1) (22/10/2026):
Tải bản phát hành mới nhất [`v0.2.0`](https://github.com/HandLive/handlive/releases/tag/v0.2.0) (30/10/2026):
- **macOS:** Tệp DMG ký ad-hoc (chọn *Open Anyway* trong lần mở đầu tiên).
- **Android:** Tệp APK `foss` đã ký. Mã ứng dụng đã đổi (`com.handlive.android`): gỡ bản beta cũ trước, rồi ghép đôi lại.
- **iOS / iPadOS:** Tệp IPA chưa ký để sideload. Bản beta cập nhật lên bản này phải ghép đôi lại (App Group mới).
Expand Down Expand Up @@ -67,7 +67,7 @@ HandLive xây lần lượt. Mỗi phase là một phần dùng được. Ngoạ
| **4** Âm thanh cuộc gọi | Bluetooth HFP/SCO và dự phòng Opus | **Dừng** (quyết định của chủ dự án, 12/10/2026) · G4 đóng: chỉ có macOS 27, cuộc gọi chỉ còn thông báo và nút nghe/từ chối/kết thúc, không âm thanh |
| **5** Camera / mic ảo | CMIOExtension và AudioServerPlugin | **Spike trên `main`** (`CameraSpike`) · G5 cần Apple Developer trả phí |
| **6** Duyệt web tiếp | Chuyển tiếp URL đang mở giữa các thiết bị | **Spike trên `main`** · đã đo Chrome và Samsung Internet; còn go/no-go trình duyệt |
| **7** Kết nối mọi nơi | Tự kết nối khi không chung mạng Wi-Fi | **Đã bắt đầu** (quyết định chủ dự án, 28/10/2026), không chờ G4/G5/G6 · spike G7 xong; ghép đôi và kênh điều khiển qua Bluetooth L2CAP đã lên `main`, Wi-Fi Direct và bulk qua relay bị cắt khỏi phạm vi phase này |
| **7** Kết nối mọi nơi | Tự kết nối khi không chung mạng Wi-Fi | **Đã phát hành ở `v0.2.0`** (30/10/2026) · ghép đôi Bluetooth offline (luồng B QR, luồng C PIN qua CPace-X25519-SHA512) đã lên `main`; Wi-Fi Direct và bulk qua relay đã có đặc tả nhưng bị cắt khỏi phạm vi phase này |
| **G0** Vector mã hóa | Vector kiểm thử mã hóa dùng chung giữa các nền tảng | **Xong** |
| **G1** Máy thật | Kiểm thực tế ma trận máy thật Phase 1 | **Mở** (trước 1.0) · ảnh App Store Connect đã chụp lại ở kích thước gốc 1320×2868 (12/10/2026) |
| **G2** Play Console | Tờ khai quyền SMS và nhật ký cuộc gọi | **Mở** (trước 1.0; phương án B: F-Droid/APK) · ảnh Play Console đã chụp lại ở 1080×1920 (12/10/2026) |
Expand Down
8 changes: 4 additions & 4 deletions docs/project-roadmap.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,11 @@ English | [Tiếng Việt](project-roadmap.vi.md)

HandLive brings ecosystem-native features, such as Apple Handoff, to Android. The roadmap below is built **in order**. Each phase is a usable piece. Each later phase stands on the infrastructure of the phase before it. The WebSocket, pairing and encryption from Phase 1 are reused by every later phase. One exception to the order (project owner's decision, 2026-09-28): Phases 5 and 6 are done before Phase 4. Phase 4 itself is stopped (project owner's decision, 2026-10-12): only macOS 27 is available, so calls on the computer stay notification + answer/decline/end only, no audio; gate G4 is closed, reopened only on a later owner decision. Phase 7 started on 2026-10-28 (project owner's decision) without waiting for Phases 4–6 or their gates.

## Progress snapshot (2026-10-12)
## Progress snapshot (2026-10-30)

**Latest release:** [`v0.1.1`](https://github.com/HandLive/handlive/releases/tag/v0.1.1) (2026-10-22): the first tag without a pre-release suffix; Google Play readiness on Android (application id `com.handlive.android`, target API 36, R8 on release, signed Play bundle on CI) and the paid-team identifiers on iPhone and iPad (App Group `group.app.hxd.handlive`), the clipboard URI policy (android #13 fixed), the Mac welcome window returns to the menu bar on close; same three files on one page: Mac DMG signed ad hoc (Open Anyway once), iOS IPA (unsigned, for sideloading), Android APK (`foss`, signed). A beta install on Android must be removed first (new application id) and an iPhone beta install must pair again. Every change since beta.3 passed a security scan ([deployment guide](deployment-guide.md)). Live table: hub [`README.md`](../README.md#status).
**Latest release:** [`v0.2.0`](https://github.com/HandLive/handlive/releases/tag/v0.2.0) (2026-10-30): Phase 7 offline connectivity — when both devices are near each other without a network, they connect over Bluetooth L2CAP (control channel only: clipboard text, SMS and call notifications); first pairing over Bluetooth by QR (flow B) or a PIN through CPace-X25519-SHA512 (flow C); Bluetooth admission policy and pre-auth bans; "Connected via Bluetooth" label on Android and Mac. No relay deployment in this release; Wi-Fi Direct and relay bulk are specced but not implemented (tracked for a later release). Every change since v0.1.1 passed a security scan: 0 critical, 0 high, 0 medium, 0 low ([deployment guide](deployment-guide.md)). Live table: hub [`README.md`](../README.md#status).

**Previous release:** [`v0.1.0-beta.3`](https://github.com/HandLive/handlive/releases/tag/v0.1.0-beta.3) (2026-10-07): calls from other apps keep the app's name and survive a swiped in-call notification, text clips keep their HTML, the Liquid Glass app icon on iPhone, iPad and Mac, the iPhone keeps its session 25 s in the background; same files on that one page as beta.2: Mac DMG signed ad hoc (Open Anyway once), iOS IPA (unsigned, for sideloading), Android APK (`foss`, signed); every change since beta.2 passed a security scan ([deployment guide](deployment-guide.md)). Live table: hub [`README.md`](../README.md#status).
**Previous release:** [`v0.1.1`](https://github.com/HandLive/handlive/releases/tag/v0.1.1) (2026-10-22): the first tag without a pre-release suffix; Google Play readiness on Android (application id `com.handlive.android`, target API 36, R8 on release, signed Play bundle on CI) and the paid-team identifiers on iPhone and iPad (App Group `group.app.hxd.handlive`), the clipboard URI policy (android #13 fixed), the Mac welcome window returns to the menu bar on close; same three files on one page: Mac DMG signed ad hoc (Open Anyway once), iOS IPA (unsigned, for sideloading), Android APK (`foss`, signed). A beta install on Android must be removed first (new application id) and an iPhone beta install must pair again. Every change since beta.3 passed a security scan ([deployment guide](deployment-guide.md)). Live table: hub [`README.md`](../README.md#status).

| Phase | Code on `main` | Gate / blocker |
|-------|----------------|----------------|
Expand All @@ -21,7 +21,7 @@ HandLive brings ecosystem-native features, such as Apple Handoff, to Android. Th
| 4 | Stopped (owner decision, 2026-10-12) | G4 closed: only macOS 27 available, calls stay notification + answer/decline/end, no audio |
| 5 | Spike on `main` (`CameraSpike`, merged 2026-09-30) | G5: need paid Apple Developer team |
| 6 | Spike probes on `main` (Apple+Android merged 2026-09-30); product cards not started | G6: owner browser decisions; Firefox/Edge/Brave rows |
| 7 | Started (owner decision, 2026-10-28) | Spike G7 first, no wait on G4/G5/G6; both-offline case, no relay, no HFP bonding |
| 7 | Released in `v0.2.0` (2026-10-30) | Spike G7 done; Bluetooth offline pairing (QR flow B, PIN flow C via CPace-X25519-SHA512) shipped; Wi-Fi Direct and relay bulk specced, not implemented |
| G0 | Done | Test vectors |
| G1 | Open (before 1.0) | Real-device Phase 1 matrix |
| G2 | Open (before 1.0) | Play Console SMS / call-log (Plan B: F-Droid/APK) |
Expand Down
Loading
Loading