diff --git a/.github/workflows/companion.yml b/.github/workflows/companion.yml new file mode 100644 index 0000000..3870d5a --- /dev/null +++ b/.github/workflows/companion.yml @@ -0,0 +1,39 @@ +name: companion + +# Guards the shared P2P contract: the companion is the only app with a headless +# test suite, so it runs on every push/PR that touches it. The watch apps have no +# CI-runnable build (DevEco/JerryScript, device-only) — see their AGENTS.md. +on: + push: + paths: + - 'apps/phone-android/**' + - 'docs/p2p-protocol.md' + - '.github/workflows/companion.yml' + pull_request: + paths: + - 'apps/phone-android/**' + - 'docs/p2p-protocol.md' + - '.github/workflows/companion.yml' + +jobs: + test: + runs-on: ubuntu-latest + defaults: + run: + working-directory: apps/phone-android + steps: + - uses: actions/checkout@v4 + + - uses: actions/setup-java@v4 + with: + distribution: temurin + java-version: '17' + + - name: Set up Gradle + uses: gradle/actions/setup-gradle@v4 + + - name: Unit tests + run: ./gradlew test --no-daemon + + - name: Assemble debug APK + run: ./gradlew assembleDebug --no-daemon diff --git a/AGENTS.md b/AGENTS.md index 2f96120..1fd46c8 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -21,7 +21,7 @@ incompatible developer platforms, so there are two watch apps sharing one design contract ([docs/platform-constraints.md](docs/platform-constraints.md)). Maturity: real-HA-integration in progress ([docs/specs/01-real-ha-integration.md](docs/specs/01-real-ha-integration.md)). -Domains: `light`, `switch`, `lock`. Localization: EN + RU. +Domains: `light`, `switch`, `lock`, `cover`, `scene`, `sensor` (sensor read-only). Localization: EN + RU. ## The three apps — read the right rules diff --git a/CLAUDE.md b/CLAUDE.md index a881435..97c6a3d 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -32,8 +32,9 @@ Claude-specific guidance. Mock run + Code Linter; watch-lite = builds/installs on a real GT; companion = `./gradlew test`. State the evidence; if you couldn't run a check, say so instead of asserting it passed. - **Scope discipline.** Touch only what the task needs, and don't carry one app's conventions into - another. Don't remove deliberate placeholders (`setRemoteApp`, `PEER_FINGERPRINT`, `module.json5` - metadata) — see the per-app gotchas. + another. `setRemoteApp` / `PEER_FINGERPRINT` are now filled with the real companion bundle + + debug-cert fingerprint; the remaining deliberate placeholder is `module.json5`'s `client_id` + (`PUT_YOUR_CLIENT_ID_HERE`) — don't remove it. See the per-app gotchas. - **Surface assumptions and ask** when requirements are ambiguous — the repo author prefers an extra question over a wrong inference. diff --git a/DEVELOPMENT.md b/DEVELOPMENT.md index baedf3d..f0bd93c 100644 --- a/DEVELOPMENT.md +++ b/DEVELOPMENT.md @@ -42,8 +42,9 @@ The human owns decisions; agents own execution. Stop and get a human decision be - Reversing or adding an **ADR** (architecture, transport, protocol). - A **breaking P2P protocol change** (`v` bump) — it commits the future companion repo to a contract. -- Filling in real secrets/identity: `setRemoteApp(...)` / `PEER_FINGERPRINT` / `client_id` / - `supportLists` / `agconnect-services.json` (today intentional placeholders). +- Filling in real secrets/identity: `setRemoteApp(...)` / `PEER_FINGERPRINT` / `supportLists` are + filled (real companion bundle + debug-cert fingerprint); still placeholders: `module.json5`'s + `client_id` and `agconnect-services.json` (git-ignored, local-only). - Adding a **production dependency** to a watch app (they are intentionally dependency-free). - Anything where the spec is ambiguous — the author prefers an extra question over a wrong inference. diff --git a/README.md b/README.md index f50f640..1186815 100644 --- a/README.md +++ b/README.md @@ -13,7 +13,7 @@ sharing one design and one wire contract — see [docs/platform-constraints.md]( |------|------|--------|-------| | [`apps/watch-arkts/`](apps/watch-arkts/) | Full-wearable watch app | **Watch 4/5/Ultimate** | ArkTS + ArkUI (Stage), `ArcList` | | [`apps/watch-lite/`](apps/watch-lite/) | Lite-wearable watch app | **Watch GT 4/5/6** | JS (FA), HML/CSS, JerryScript (ES5.1) | -| [`apps/phone-android/`](apps/phone-android/) | Phone companion (P2P ↔ HA REST) | Android | Kotlin + Compose — *not written yet* | +| [`apps/phone-android/`](apps/phone-android/) | Phone companion (P2P ↔ HA REST) | Android | Kotlin + Compose | The two watch apps are **mirror architectures in different runtimes** — they share the [P2P protocol](docs/p2p-protocol.md), the domain model, and the layering, but **no code** diff --git a/apps/phone-android/AGENTS.md b/apps/phone-android/AGENTS.md index 8a1063c..c3fc0b2 100644 --- a/apps/phone-android/AGENTS.md +++ b/apps/phone-android/AGENTS.md @@ -9,7 +9,7 @@ Different stack from the watches (Kotlin, not ArkTS/JS). Open `apps/phone-androi | | | |---|---| | Language / UI | Kotlin, Jetpack Compose (Material3) | -| Build | Gradle (version catalog `gradle/libs.versions.toml`), AGP 8.7, JDK 17 | +| Build | Gradle (version catalog `gradle/libs.versions.toml`), AGP 8.13.2, JDK 17 | | SDK | compileSdk 35, minSdk 26, targetSdk 35 | | App id | `ru.gentslava.homeassistant.companion` (companion). The watch peer is `ru.gentslava.homeassistant` | | HA | OkHttp + kotlinx-serialization (`Bearer` token) | diff --git a/apps/phone-android/app/src/main/AndroidManifest.xml b/apps/phone-android/app/src/main/AndroidManifest.xml index 53e9280..eb7a5d7 100644 --- a/apps/phone-android/app/src/main/AndroidManifest.xml +++ b/apps/phone-android/app/src/main/AndroidManifest.xml @@ -9,6 +9,13 @@ + + + + +