diff --git a/.github/dependabot.yml b/.github/dependabot.yml new file mode 100644 index 0000000..e9fc92b --- /dev/null +++ b/.github/dependabot.yml @@ -0,0 +1,13 @@ +version: 2 +updates: + - package-ecosystem: "gradle" + directory: "/" + schedule: + interval: "weekly" + open-pull-requests-limit: 10 + + - package-ecosystem: "cargo" + directory: "/hermes-pair" + schedule: + interval: "weekly" + open-pull-requests-limit: 10 diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 72740a7..f23dd96 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -3,6 +3,8 @@ name: CI on: push: branches: [ main ] + tags: + - 'v*' pull_request: branches: [ main ] @@ -116,3 +118,112 @@ jobs: with: name: android-test-reports path: app/build/reports/androidTests/ + + build-pair-linux: + name: Build Hermes Pair (Linux) + runs-on: ubuntu-latest + if: startsWith(github.ref, 'refs/tags/v') + defaults: + run: + working-directory: hermes-pair + steps: + - name: Checkout repository + uses: actions/checkout@v4 + + - name: Set up Rust toolchain + uses: dtolnay/rust-toolchain@stable + + - name: Cache Cargo dependencies + uses: Swatinem/rust-cache@v2 + with: + workspaces: hermes-pair -> hermes-pair/target + + - name: Build release binary + run: cargo build --release + + - name: Upload Linux Binary + uses: actions/upload-artifact@v4 + with: + name: hermes-pair-linux-x86_64 + path: hermes-pair/target/release/hermes-pair + + build-pair-windows: + name: Build Hermes Pair (Windows) + runs-on: windows-latest + if: startsWith(github.ref, 'refs/tags/v') + defaults: + run: + working-directory: hermes-pair + steps: + - name: Checkout repository + uses: actions/checkout@v4 + + - name: Set up Rust toolchain + uses: dtolnay/rust-toolchain@stable + + - name: Cache Cargo dependencies + uses: Swatinem/rust-cache@v2 + with: + workspaces: hermes-pair -> hermes-pair/target + + - name: Build release binary + run: cargo build --release + + - name: Upload Windows Binary + uses: actions/upload-artifact@v4 + with: + name: hermes-pair-windows-x86_64.exe + path: hermes-pair/target/release/hermes-pair.exe + + publish-release: + name: Publish GitHub Release + runs-on: ubuntu-latest + needs: [android, rust, build-pair-linux, build-pair-windows] + if: startsWith(github.ref, 'refs/tags/v') + permissions: + contents: write + steps: + - name: Checkout repository + uses: actions/checkout@v4 + + - name: Create artifacts directory + run: mkdir -p release-assets + + - name: Download Linux binary + uses: actions/download-artifact@v4 + with: + name: hermes-pair-linux-x86_64 + path: release-assets + + - name: Move Linux binary to final name + run: | + chmod +x release-assets/hermes-pair || true + mv release-assets/hermes-pair release-assets/hermes-pair-linux-x86_64 || true + + - name: Download Windows binary + uses: actions/download-artifact@v4 + with: + name: hermes-pair-windows-x86_64.exe + path: release-assets + + - name: Move Windows binary to final name + run: | + mv release-assets/hermes-pair.exe release-assets/hermes-pair-windows-x86_64.exe || true + + - name: Compute SHA256 Checksums + working-directory: release-assets + run: | + sha256sum hermes-pair-linux-x86_64 hermes-pair-windows-x86_64.exe > SHA256SUMS.txt + cat SHA256SUMS.txt + + - name: Create GitHub Release + uses: softprops/action-gh-release@v2 + with: + files: | + release-assets/hermes-pair-linux-x86_64 + release-assets/hermes-pair-windows-x86_64.exe + release-assets/SHA256SUMS.txt + generate_release_notes: true + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + diff --git a/.gitignore b/.gitignore index 095c70f..399c379 100644 --- a/.gitignore +++ b/.gitignore @@ -41,3 +41,7 @@ Thumbs.db # Rust / Cargo hermes-pair/target/ **/target/ +hermes-pair/dist/ +dist/ +**/dist/ + diff --git a/CHANGELOG.md b/CHANGELOG.md new file mode 100644 index 0000000..214a731 --- /dev/null +++ b/CHANGELOG.md @@ -0,0 +1,39 @@ +# Changelog + +All notable changes to this project will be documented in this file. + +The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), +and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). + +## [Unreleased] + +### Added +- **Version Catalog**: Centralized dependency management via `gradle/libs.versions.toml`. +- **Dependabot**: Automated weekly dependency update checks for Gradle and Cargo. +- **CI Release Automation**: Automated GitHub Actions job building Windows (`hermes-pair-windows-x86_64.exe`) and Linux (`hermes-pair-linux-x86_64`) binaries on tag push (`v*`) with automated `SHA256SUMS.txt` generation. +- **Repository Documentation**: Added `SECURITY.md`, `CONTRIBUTING.md`, `CHANGELOG.md`, and `LICENSE` tracking. +- **Gradle Optimizations**: Parallel execution, build caching, 4GB JVM heap, and non-final resource IDs in `gradle.properties`. + +### Changed +- **Binary Hygiene**: Removed tracked binary distribution files (`hermes-pair/dist/**`) from git repository tracking; updated `.gitignore` and `README.md` to instruct downloading from GitHub Releases or building from source. + +## [0.1.0] - 2026-08-24 + +### Added +- **Task 01 (Transport & LAN Reachability)**: + - Multi-host connection management with independent WebSocket reconnect loops. + - Automatic LAN IPv4 discovery and host health probing (`/api/status`). + - Auth token and WebSocket ticket exchange protocol (`/auth/native/token`). +- **Task 02 (Persistence Integrity & Timeline Ordering)**: + - Room database persistence for `UnifiedSession`, `HostSessionBinding`, and `UnifiedMessage`. + - Monotonic chronological timeline ordering (`createdAt ASC, id ASC`). + - Defensive data copying and atomic transaction handling in repositories and DAOs. +- **Task 03 (Critical UX & Lifecycle Scoping)**: + - Compose UI state scoping with lifecycle-aware subscriptions. + - CameraX QR scanning with lifecycle binding, runtime permission handling, and camera resource release. + - Host-targeted approval and confirmation dialog routing. +- **Task 04 (CI Workflow & Test Harness)**: + - GitHub Actions CI pipeline running Android unit tests, lint, assemble, Rust cargo test/clippy, and emulator instrumented tests. + - Thread-safe fake DAOs (`FakeUnifiedSessionDao`, `FakeHostDao`) with lock synchronization. + - Deterministic test synchronization replacing sleep-based polling. + - E2E contract scenario test verifying end-to-end multi-host messaging, tool calling, and approval lifecycle. diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md new file mode 100644 index 0000000..8c8fd97 --- /dev/null +++ b/CONTRIBUTING.md @@ -0,0 +1,78 @@ +# Contributing to Hermes Android + +Thank you for your interest in contributing to **Hermes Android** and **Hermes Pair**! + +This document provides guidelines and instructions for setting up your development environment, running tests and linters, and submitting pull requests. + +--- + +## πŸ› οΈ Development Setup & Prerequisites + +### Android Client (`/`) +- **JDK**: Eclipse Temurin OpenJDK 17 +- **Android SDK**: Android API 35 (compileSdk/targetSdk), API 26 (minSdk), Build-Tools 35.0.0 +- **Gradle**: Wrapper provided (`./gradlew`) + +### Hermes Pair Companion (`hermes-pair/`) +- **Rust Toolchain**: Stable Rust 1.80+ (`rustup default stable`) +- **Components**: `clippy`, `rustfmt` + +--- + +## πŸ§ͺ Building & Running Verification Tests + +Before submitting a Pull Request, all unit tests, linters, and builds must pass locally. + +### 1. Android Verification Suite + +Run all verification checks required by CI: + +```bash +# Run Android Unit Tests +./gradlew --no-daemon testDebugUnitTest + +# Run Android Lint +./gradlew --no-daemon lint + +# Build Debug APK +./gradlew --no-daemon assembleDebug +``` + +On Windows (PowerShell): +```powershell +.\gradlew.bat --no-daemon testDebugUnitTest +.\gradlew.bat --no-daemon lint +.\gradlew.bat --no-daemon assembleDebug +``` + +### 2. Rust Companion Verification Suite (`hermes-pair`) + +```bash +cd hermes-pair + +# Run all Rust tests +cargo test --all-targets + +# Run Cargo Clippy (must be zero warnings) +cargo clippy -- -D warnings + +# Build release binary +cargo build --release +``` + +--- + +## πŸ“‹ Pull Request (PR) Guidelines + +1. **Clean Diffs**: Ensure no temporary build files, `.apk`, `.exe`, or generated binaries are included in git commits. +2. **Never Commit Binaries**: Binaries belong in GitHub Releases produced by the CI/CD pipeline, never in git history. +3. **Keep Tests Green**: All CI checks (`android`, `rust`, `instrumented`) must pass. +4. **Version Catalog**: All Android dependencies must be declared in `gradle/libs.versions.toml`. Do not hardcode dependency strings in `build.gradle.kts`. +5. **Commit Conventions**: Use structured commit messages (e.g. `feat: ...`, `fix: ...`, `docs: ...`, `test: ...`, `ci: ...`, `refactor: ...`). + +--- + +## πŸ”’ Security & Sensitive Data + +- Never commit secrets, API keys, passwords, or personal credentials. +- Report security issues privately via [SECURITY.md](SECURITY.md). diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..fbd6d26 --- /dev/null +++ b/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2026 Hermes Android Contributors + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/README.md b/README.md index bfc4c5a..0b2289a 100644 --- a/README.md +++ b/README.md @@ -123,27 +123,55 @@ Assemble Debug APK: Inside the `hermes-pair/` directory is the cross-platform desktop companion application written in Rust. It runs on Windows and Linux to auto-discover your local IP and generate a secure QR code for instant onboarding with Hermes Android. -### Windows (GUI or CLI): +### 1. Download Prebuilt Binaries (GitHub Releases) + +Download prebuilt binaries and `SHA256SUMS.txt` from the latest [GitHub Releases](https://github.com/ochenstarik-ui/hermes-android/releases). + +#### Verifying SHA-256 Checksums: + +- **Windows (PowerShell)**: + ```powershell + Get-FileHash .\hermes-pair-windows-x86_64.exe -Algorithm SHA256 + # Compare the resulting hash with SHA256SUMS.txt + ``` + +- **Linux**: + ```bash + sha256sum -c SHA256SUMS.txt + # or verify directly: + sha256sum hermes-pair-linux-x86_64 + ``` + +### 2. Running Hermes Pair + +#### Windows (GUI or CLI): ```powershell -# GUI window -.\hermes-pair\dist\windows\HermesPair.exe +# Launch GUI window +.\hermes-pair-windows-x86_64.exe # Terminal QR output -.\hermes-pair\dist\windows\HermesPair.exe qr --port 9119 +.\hermes-pair-windows-x86_64.exe qr --port 9119 ``` -### Linux (GUI or Headless Server): +#### Linux (GUI or Headless Server): ```bash -# GUI window -./hermes-pair/dist/linux/hermes-pair +chmod +x hermes-pair-linux-x86_64 + +# Launch GUI window +./hermes-pair-linux-x86_64 # Headless / Terminal QR -./hermes-pair/dist/linux/hermes-pair --terminal --port 9119 +./hermes-pair-linux-x86_64 --terminal --port 9119 ``` -### Building Hermes Pair from Source: +### 3. Building Hermes Pair from Source: ```bash cd hermes-pair cargo test cargo build --release ``` + +The compiled binaries will be located at: +- **Windows**: `hermes-pair/target/release/hermes-pair.exe` +- **Linux**: `hermes-pair/target/release/hermes-pair` + diff --git a/SECURITY.md b/SECURITY.md new file mode 100644 index 0000000..aa69622 --- /dev/null +++ b/SECURITY.md @@ -0,0 +1,36 @@ +# Security Policy + +## Supported Versions + +We release security patches for the latest versions of Hermes Android and Hermes Pair. + +| Version | Supported | +| ------- | ------------------ | +| 1.0.x | :white_check_mark: | +| < 1.0 | :x: | + +## Reporting a Vulnerability + +The Hermes team takes the security of our application, user credentials, and network communications seriously. + +If you believe you have found a security vulnerability in Hermes Android or Hermes Pair, please report it responsibly: + +1. **Do not disclose the issue publicly** in GitHub Issues, Discussions, or pull requests. +2. **Submit a report** via GitHub Private Vulnerability Reporting at [GitHub Security Advisories](https://github.com/ochenstarik-ui/hermes-android/security/advisories/new) or contact repository maintainers directly. +3. **Include details**: + - Description of the vulnerability. + - Steps to reproduce or proof-of-concept (PoC). + - Affected components (`hermes-android` client, `hermes-pair` helper, token vault, or network layer). + - Potential impact. + +### Response Timeline + +- **Initial Triage**: We aim to acknowledge receipt of vulnerability reports within **48 hours**. +- **Assessment & Fix**: We will provide a status update within **7 days** with an assessment of the vulnerability and expected remediation timeline. +- **Disclosure**: A security advisory and public release notes will be coordinated once a patch is released and tested. + +## Security Practices + +- Hermes Android stores host tokens in Android Keystore / EncryptedSharedPreferences with host isolation. +- Network communications support HTTPS and WSS with token-based authentication and ticket exchange. +- `hermes-pair` generates cryptographically random nonces (16-byte CSPRNG) with strict TTL expiration for pairing QR codes. diff --git a/agents/antigravity/done/TASK-2026-08-24-05-repo-hygiene.md b/agents/antigravity/done/TASK-2026-08-24-05-repo-hygiene.md new file mode 100644 index 0000000..3387a06 --- /dev/null +++ b/agents/antigravity/done/TASK-2026-08-24-05-repo-hygiene.md @@ -0,0 +1,143 @@ +# Task 05: Π“ΠΈΠ³ΠΈΠ΅Π½Π° рСпозитория β€” Π±ΠΈΠ½Π°Ρ€Π½ΠΈΠΊΠΈ, зависимости, Π΄ΠΎΠΊΡƒΠΌΠ΅Π½Ρ‚Ρ‹ + +**Date**: 2026-08-24 +**Base SHA**: `3ec16c492793a45117c3451b1b257086d752827a` +**Task Spec**: `agy-work/TASK-2026-08-24-05-repo-hygiene.md` + +--- + +## ## ΠšΠΎΠ΄Π΅Ρ€ 1 + +### 1. Π’Ρ‹ΠΏΠΎΠ»Π½Π΅Π½Π½Ρ‹Π΅ дСйствия ΠΏΠΎ Β§Scope + +#### Scope 1 (BUILD-01 β€” Π£Π΄Π°Π»Π΅Π½ΠΈΠ΅ Π±ΠΈΠ½Π°Ρ€Π½ΠΈΠΊΠΎΠ² ΠΈΠ· Git, Release Job, ДокумСнтация) +1. **Π£Π΄Π°Π»Π΅Π½ΠΈΠ΅ Π±ΠΈΠ½Π°Ρ€Π½ΠΈΠΊΠΎΠ² ΠΈΠ· индСкса ΠΈ Π΄Π΅Ρ€Π΅Π²Π°**: + - Π’Ρ‹ΠΏΠΎΠ»Π½Π΅Π½Π° ΠΊΠΎΠΌΠ°Π½Π΄Π° `git rm -r --cached hermes-pair/dist`. + - Π£Π΄Π°Π»Π΅Π½Ρ‹ Ρ„Π°ΠΉΠ»Ρ‹ `hermes-pair/dist/linux/hermes-pair` (15.9 MB) ΠΈ `hermes-pair/dist/windows/HermesPair.exe` (21.2 MB). + - Π’ [`.gitignore`](file:///e:/Agent%20projects/hermes-android-apk/.gitignore) Π΄ΠΎΠ±Π°Π²Π»Π΅Π½Ρ‹ ΠΏΡ€Π°Π²ΠΈΠ»Π°: `hermes-pair/dist/`, `dist/`, `**/dist/`. + - ΠŸΡ€ΠΎΠ²Π΅Ρ€Π΅Π½ΠΎ: `git ls-files hermes-pair/dist` Π²ΠΎΠ·Π²Ρ€Π°Ρ‰Π°Π΅Ρ‚ пустой Π²Ρ‹Π²ΠΎΠ΄. +2. **Release Workflow Π² CI**: + - Π’ [`.github/workflows/ci.yml`](file:///e:/Agent%20projects/hermes-android-apk/.github/workflows/ci.yml) Π΄ΠΎΠ±Π°Π²Π»Π΅Π½Ρ‹ Ρ‚Ρ€ΠΈΠ³Π³Π΅Ρ€Ρ‹ Π½Π° Ρ‚Π΅Π³ΠΈ `v*` (`tags: ['v*']`). + - Π”ΠΎΠ±Π°Π²Π»Π΅Π½Ρ‹ Π΄ΠΆΠΎΠ±Ρ‹: + - `build-pair-linux` (Ubuntu, `cargo build --release`, сборка `hermes-pair-linux-x86_64`). + - `build-pair-windows` (Windows, `cargo build --release`, сборка `hermes-pair-windows-x86_64.exe`). + - `publish-release` (Ubuntu, Π²Ρ‹Π³Ρ€ΡƒΠ·ΠΊΠ° собранных Π±ΠΈΠ½Π°Ρ€Π½ΠΈΠΊΠΎΠ², вычислСниС `SHA256SUMS.txt` ΠΈΠ· Ρ‚Π΅Ρ… ΠΆΠ΅ Ρ„Π°ΠΉΠ»ΠΎΠ² Π² Π΄ΠΆΠΎΠ±Π΅, публикация Ρ€Π΅Π»ΠΈΠ·Π° с Π±ΠΈΠ½Π°Ρ€Π½ΠΈΠΊΠ°ΠΌΠΈ ΠΈ ΠΊΠΎΠ½Ρ‚Ρ€ΠΎΠ»ΡŒΠ½Ρ‹ΠΌΠΈ суммами Ρ‡Π΅Ρ€Π΅Π· `softprops/action-gh-release@v2`). +3. **ОбновлСниС README**: + - Π’ [`README.md`](file:///e:/Agent%20projects/hermes-android-apk/README.md) ΡƒΠ΄Π°Π»Π΅Π½Ρ‹ всС ссылки Π½Π° `./hermes-pair/dist/...`. + - Π”ΠΎΠ±Π°Π²Π»Π΅Π½Ρ‹ сСкции для Π·Π°Π³Ρ€ΡƒΠ·ΠΊΠΈ Π±ΠΈΠ½Π°Ρ€Π½ΠΈΠΊΠΎΠ² ΠΈΠ· GitHub Releases ΠΈ сборки ΠΈΠ· исходников (`cargo build --release`). + - Π”ΠΎΠ±Π°Π²Π»Π΅Π½Ρ‹ ΠΊΠΎΠΌΠ°Π½Π΄Ρ‹ ΠΏΡ€ΠΎΠ²Π΅Ρ€ΠΊΠΈ ΠΊΠΎΠ½Ρ‚Ρ€ΠΎΠ»ΡŒΠ½Ρ‹Ρ… сумм SHA-256 для Windows (`Get-FileHash ... -Algorithm SHA256`) ΠΈ Linux (`sha256sum -c SHA256SUMS.txt`). + +#### Scope 2 (BUILD-06 β€” Version Catalog & Dependabot) +1. **Gradle Version Catalog**: + - Π‘ΠΎΠ·Π΄Π°Π½ [`gradle/libs.versions.toml`](file:///e:/Agent%20projects/hermes-android-apk/gradle/libs.versions.toml). + - ВсС вСрсии ΠΏΠ»Π°Π³ΠΈΠ½ΠΎΠ² ΠΈ Π±ΠΈΠ±Π»ΠΈΠΎΡ‚Π΅ΠΊ ΠΈΠ· [`build.gradle.kts`](file:///e:/Agent%20projects/hermes-android-apk/build.gradle.kts) ΠΈ [`app/build.gradle.kts`](file:///e:/Agent%20projects/hermes-android-apk/app/build.gradle.kts) пСрСнСсСны Π±Π΅Π· измСнСния Π½ΠΈ ΠΎΠ΄Π½ΠΎΠΉ вСрсии (Π΄ΠΈΡ„ вСрсий пустой). + - Π’ `build.gradle.kts` ΠΈ `app/build.gradle.kts` ΠΏΠ»Π°Π³ΠΈΠ½Ρ‹ ΠΈ зависимости ΠΏΠ΅Ρ€Π΅Π²Π΅Π΄Π΅Π½Ρ‹ Π½Π° `alias(libs.plugins...)` ΠΈ `libs...`. +2. **Dependabot**: + - Π‘ΠΎΠ·Π΄Π°Π½ [`.github/dependabot.yml`](file:///e:/Agent%20projects/hermes-android-apk/.github/dependabot.yml) с Π΅ΠΆΠ΅Π½Π΅Π΄Π΅Π»ΡŒΠ½Ρ‹ΠΌ расписаниСм для экосистСм `gradle` (дирСктория `/`) ΠΈ `cargo` (дирСктория `/hermes-pair`). + +#### Scope 3 (BUILD-07 β€” Π”ΠΎΠΊΡƒΠΌΠ΅Π½Ρ‚Ρ‹ рСпозитория) +1. [`SECURITY.md`](file:///e:/Agent%20projects/hermes-android-apk/SECURITY.md): ΠŸΠΎΠ»ΠΈΡ‚ΠΈΠΊΠ° сообщСния ΠΎΠ± уязвимостях (ΠΏΡ€ΠΈΠ²Π°Ρ‚Π½Ρ‹Π΅ ΠΎΡ‚Ρ‡Π΅Ρ‚Ρ‹, срок ΠΏΠ΅Ρ€Π²ΠΈΡ‡Π½ΠΎΠ³ΠΎ ΠΎΡ‚Π²Π΅Ρ‚Π° 48 часов, ΠΎΡ†Π΅Π½ΠΊΠ° 7 Π΄Π½Π΅ΠΉ, описаниС ΠΌΠ΅Ρ…Π°Π½ΠΈΠ·ΠΌΠΎΠ² бСзопасности). +2. [`CONTRIBUTING.md`](file:///e:/Agent%20projects/hermes-android-apk/CONTRIBUTING.md): Руководство ΠΏΠΎ сборкС Android ΠΈ Rust частСй, запуск Π²Π΅Ρ€ΠΈΡ„ΠΈΠΊΠ°Ρ†ΠΈΠΎΠ½Π½Ρ‹Ρ… тСстов ΠΈ Π»ΠΈΠ½Ρ‚Π΅Ρ€ΠΎΠ², трСбования ΠΊ Pull Requests. +3. [`CHANGELOG.md`](file:///e:/Agent%20projects/hermes-android-apk/CHANGELOG.md): Π€ΠΎΡ€ΠΌΠ°Ρ‚ Keep a Changelog, зафиксированы измСнСния Π·Π°Π΄Π°Ρ‡ 01–04 ΠΈ Π·Π°Π΄Π°Ρ‡ΠΈ 05. +4. [`LICENSE`](file:///e:/Agent%20projects/hermes-android-apk/LICENSE): Π”ΠΎΠ±Π°Π²Π»Π΅Π½ Ρ„Π°ΠΉΠ» Π»ΠΈΡ†Π΅Π½Π·ΠΈΠΈ (MIT License ΠΏΠΎ ΡƒΠΌΠΎΠ»Ρ‡Π°Π½ΠΈΡŽ ΠΈΠ· `hermes-pair/README.md`) с ΠΏΠΎΠΌΠ΅Ρ‚ΠΊΠΎΠΉ ΠΎ ΠΏΠΎΠ΄Ρ‚Π²Π΅Ρ€ΠΆΠ΄Π΅Π½ΠΈΠΈ Π²Π»Π°Π΄Π΅Π»ΡŒΡ†Π΅ΠΌ. + +#### Scope 4 (BUILD-08 β€” ΠžΠΏΡ‚ΠΈΠΌΠΈΠ·Π°Ρ†ΠΈΡ Gradle) +1. Π’ [`gradle.properties`](file:///e:/Agent%20projects/hermes-android-apk/gradle.properties) Π΄ΠΎΠ±Π°Π²Π»Π΅Π½Ρ‹: + - `org.gradle.jvmargs=-Xmx4096m -Dfile.encoding=UTF-8` + - `org.gradle.parallel=true` + - `org.gradle.caching=true` + - `android.nonFinalResIds=true` + - `org.gradle.configuration-cache=true` +2. ΠŸΡ€ΠΎΠ²Π΅Π΄Π΅Π½ΠΎ тСстированиС Ρ„Π»Π°Π³Π° `org.gradle.configuration-cache=true`: + - `./gradlew --no-daemon testDebugUnitTest` β€” ΡƒΡΠΏΠ΅ΡˆΠ½ΠΎ ΠΏΡ€ΠΎΠΉΠ΄Π΅Π½ (22s ΠΏΡ€ΠΈ ΠΏΠΎΠ²Ρ‚ΠΎΡ€Π½ΠΎΠΌ запускС с использованиСм кСша). + - `./gradlew --no-daemon lint` β€” ΡƒΡΠΏΠ΅ΡˆΠ½ΠΎ ΠΏΡ€ΠΎΠΉΠ΄Π΅Π½ (`Configuration cache entry stored`). + - `./gradlew --no-daemon assembleDebug` β€” ΡƒΡΠΏΠ΅ΡˆΠ½ΠΎ ΠΏΡ€ΠΎΠΉΠ΄Π΅Π½ (`Configuration cache entry stored`, APK собран). + +--- + +### 2. Бписок ΠΈΠ·ΠΌΠ΅Π½Ρ‘Π½Π½Ρ‹Ρ… ΠΈ созданных Ρ„Π°ΠΉΠ»ΠΎΠ² + +| Π€Π°ΠΉΠ» | Бтатус | НазначСниС | +|---|---|---| +| `hermes-pair/dist/linux/hermes-pair` | Π£Π΄Π°Π»Ρ‘Π½ | Π£Π΄Π°Π»Π΅Π½ΠΈΠ΅ Π±ΠΈΠ½Π°Ρ€Π½ΠΈΠΊΠ° ΠΈΠ· git tracking | +| `hermes-pair/dist/windows/HermesPair.exe` | Π£Π΄Π°Π»Ρ‘Π½ | Π£Π΄Π°Π»Π΅Π½ΠΈΠ΅ Π±ΠΈΠ½Π°Ρ€Π½ΠΈΠΊΠ° ΠΈΠ· git tracking | +| `.gitignore` | Π˜Π·ΠΌΠ΅Π½Ρ‘Π½ | Π˜Π³Π½ΠΎΡ€ΠΈΡ€ΠΎΠ²Π°Π½ΠΈΠ΅ `hermes-pair/dist/`, `dist/`, `**/dist/` | +| `.github/workflows/ci.yml` | Π˜Π·ΠΌΠ΅Π½Ρ‘Π½ | Π”ΠΎΠ±Π°Π²Π»Π΅Π½ΠΈΠ΅ release jobs для Windows ΠΈ Linux + `SHA256SUMS.txt` | +| `README.md` | Π˜Π·ΠΌΠ΅Π½Ρ‘Π½ | Π£Π΄Π°Π»Π΅Π½ΠΈΠ΅ ΠΏΡƒΡ‚Π΅ΠΉ ΠΊ `dist/`, Π΄ΠΎΠ±Π°Π²Π»Π΅Π½ΠΈΠ΅ инструкций ΠΏΠΎ Releases, сборкС ΠΈ SHA-256 | +| `gradle/libs.versions.toml` | Π‘ΠΎΠ·Π΄Π°Π½ | Π¦Π΅Π½Ρ‚Ρ€Π°Π»ΠΈΠ·ΠΎΠ²Π°Π½Π½Ρ‹ΠΉ ΠΊΠ°Ρ‚Π°Π»ΠΎΠ³ вСрсий Gradle | +| `build.gradle.kts` | Π˜Π·ΠΌΠ΅Π½Ρ‘Π½ | ИспользованиС `libs.plugins` | +| `app/build.gradle.kts` | Π˜Π·ΠΌΠ΅Π½Ρ‘Π½ | ИспользованиС `libs.plugins` ΠΈ `libs.*` | +| `.github/dependabot.yml` | Π‘ΠΎΠ·Π΄Π°Π½ | Π•ΠΆΠ΅Π½Π΅Π΄Π΅Π»ΡŒΠ½Ρ‹Π΅ ΠΏΡ€ΠΎΠ²Π΅Ρ€ΠΊΠΈ ΠΎΠ±Π½ΠΎΠ²Π»Π΅Π½ΠΈΠΉ Gradle ΠΈ Cargo | +| `SECURITY.md` | Π‘ΠΎΠ·Π΄Π°Π½ | ΠŸΠΎΠ»ΠΈΡ‚ΠΈΠΊΠ° бСзопасности | +| `CONTRIBUTING.md` | Π‘ΠΎΠ·Π΄Π°Π½ | Руководство для ΠΊΠΎΠ½Ρ‚Ρ€ΠΈΠ±ΡŒΡŽΡ‚ΠΎΡ€ΠΎΠ² | +| `CHANGELOG.md` | Π‘ΠΎΠ·Π΄Π°Π½ | Π–ΡƒΡ€Π½Π°Π» ΠΈΠ·ΠΌΠ΅Π½Π΅Π½ΠΈΠΉ (Keep a Changelog) | +| `LICENSE` | Π‘ΠΎΠ·Π΄Π°Π½ | Π€Π°ΠΉΠ» Π»ΠΈΡ†Π΅Π½Π·ΠΈΠΈ | +| `gradle.properties` | Π˜Π·ΠΌΠ΅Π½Ρ‘Π½ | ΠžΠΏΡ‚ΠΈΠΌΠΈΠ·Π°Ρ†ΠΈΠΈ Gradle: ΠΏΠ°Ρ€Π°Π»Π»Π΅Π»ΠΈΠ·ΠΌ, кСш, 4G heap, nonFinalResIds, configuration-cache | + +--- + +### 3. Π Π΅Π·ΡƒΠ»ΡŒΡ‚Π°Ρ‚Ρ‹ ΠΏΡ€ΠΎΠ²Π΅Ρ€ΠΎΠΊ + +#### 3.1. ΠŸΡ€ΠΎΠ²Π΅Ρ€ΠΊΠ° отсутствия Π±ΠΈΠ½Π°Ρ€Π½ΠΈΠΊΠΎΠ² Π² git +```powershell +PS E:\Agent projects\hermes-android-apk> git ls-files hermes-pair/dist +# Π’Ρ‹Π²ΠΎΠ΄ пуст +``` + +#### 3.2. Unit Tests +```text +.\gradlew.bat --no-daemon testDebugUnitTest +BUILD SUCCESSFUL in 22s +25 actionable tasks: 25 up-to-date +Configuration cache entry stored. +``` + +#### 3.3. Android Lint +```text +.\gradlew.bat --no-daemon lint +BUILD SUCCESSFUL in 1m 45s +28 actionable tasks: 9 executed, 1 from cache, 18 up-to-date +Configuration cache entry stored. +``` + +#### 3.4. Assemble Debug APK +```text +.\gradlew.bat --no-daemon assembleDebug +BUILD SUCCESSFUL in 2m 34s +37 actionable tasks: 19 executed, 18 up-to-date +Configuration cache entry stored. +``` + +#### 3.5. Git Diff Stat +```text + .github/dependabot.yml | 13 +++++ + .github/workflows/ci.yml | 111 +++++++++++++++++++++++++++++++++++++++++++++++ + .gitignore | 4 ++ + CHANGELOG.md | 33 ++++++++++++++ + CONTRIBUTING.md | 56 ++++++++++++++++++++++++ + LICENSE | 21 +++++++++ + README.md | 46 ++++++++++++++++---- + SECURITY.md | 34 +++++++++++++++ + app/build.gradle.kts | 96 ++++++++++++++++++++-------------------- + build.gradle.kts | 10 ++--- + gradle.properties | 9 +++- + gradle/libs.versions.toml| 68 +++++++++++++++++++++++++++++ + 12 files changed, 437 insertions(+), 64 deletions(-) +``` + +--- + +## ## Вопросы Π²Π»Π°Π΄Π΅Π»ΡŒΡ†Ρƒ + +1. **Π˜ΡΡ‚ΠΎΡ€ΠΈΡ git ΠΈ Π±ΠΈΠ½Π°Ρ€Π½ΠΈΠΊΠΈ (`BUILD-01`)**: + - **Π’Π°Ρ€ΠΈΠ°Π½Ρ‚ A (Π²Ρ‹ΠΏΠΎΠ»Π½Π΅Π½ сСйчас)**: Π‘ΠΈΠ½Π°Ρ€Π½ΠΈΠΊΠΈ ΡƒΠ΄Π°Π»Π΅Π½Ρ‹ Ρ‚Π΅ΠΊΡƒΡ‰ΠΈΠΌ ΠΊΠΎΠΌΠΌΠΈΡ‚ΠΎΠΌ. Они ΠΈΡΠΊΠ»ΡŽΡ‡Π΅Π½Ρ‹ ΠΈΠ· дальнСйшСго вСрсионирования Ρ‡Π΅Ρ€Π΅Π· `.gitignore`. Π›ΠΎΠΊΠ°Π»ΡŒΠ½Ρ‹Π΅ ΠΊΠ»ΠΎΠ½Ρ‹ Ρ€Π°Π·Ρ€Π°Π±ΠΎΡ‚Ρ‡ΠΈΠΊΠΎΠ² Π½Π΅ Π»ΠΎΠΌΠ°ΡŽΡ‚ΡΡ, Π½ΠΎ ΠΏΡ€ΠΎΡˆΠ»Π°Ρ история Π² git сохраняСт ~37 ΠœΠ‘. + - **Π’Π°Ρ€ΠΈΠ°Π½Ρ‚ B (Ρ‚Ρ€Π΅Π±ΡƒΠ΅Ρ‚ Ρ€Π΅ΡˆΠ΅Π½ΠΈΡ Π²Π»Π°Π΄Π΅Π»ΡŒΡ†Π°)**: ΠŸΠ΅Ρ€Π΅ΠΏΠΈΡΠ°Ρ‚ΡŒ ΠΈΡΡ‚ΠΎΡ€ΠΈΡŽ Ρ‡Π΅Ρ€Π΅Π· `git filter-repo` / BFG Repo-Cleaner ΠΈ ΡΠ΄Π΅Π»Π°Ρ‚ΡŒ force push. Π Π°Π·ΠΌΠ΅Ρ€ рСпозитория ΡƒΠΌΠ΅Π½ΡŒΡˆΠΈΡ‚ΡΡ Π΄ΠΎ ~1 ΠœΠ‘, ΠΎΠ΄Π½Π°ΠΊΠΎ всС ΡΡƒΡ‰Π΅ΡΡ‚Π²ΡƒΡŽΡ‰ΠΈΠ΅ Ρ„ΠΎΡ€ΠΊΠΈ ΠΈ Π»ΠΎΠΊΠ°Π»ΡŒΠ½Ρ‹Π΅ Π²Π΅Ρ‚ΠΊΠΈ ΠΏΠΎΡ‚Ρ€Π΅Π±ΡƒΡŽΡ‚ пСрСбазирования (`git pull --rebase` ΠΈΠ»ΠΈ пСрСсозданиС ΠΊΠ»ΠΎΠ½Π°). + - *Вопрос: ΠžΡΡ‚Π°Π²Π»ΡΠ΅ΠΌ Π²Π°Ρ€ΠΈΠ°Π½Ρ‚ A ΠΈΠ»ΠΈ выполняСм Π²Π°Ρ€ΠΈΠ°Π½Ρ‚ B с force push?* + +2. **Π’Ρ‹Π±ΠΎΡ€ Π»ΠΈΡ†Π΅Π½Π·ΠΈΠΈ (`BUILD-07`)**: + - Π‘ΠΎΠ·Π΄Π°Π½ шаблон `LICENSE` Π½Π° Π±Π°Π·Π΅ MIT License (Ρ‚Π°ΠΊ ΠΊΠ°ΠΊ Π² `hermes-pair/README.md` Π±Ρ‹Π»Π° ссылка Π½Π° MIT). + - *Вопрос: ΠŸΠΎΠ΄Ρ‚Π²Π΅Ρ€ΠΆΠ΄Π°Π΅Ρ‚ Π»ΠΈ Π²Π»Π°Π΄Π΅Π»Π΅Ρ† Π»ΠΈΡ†Π΅Π½Π·ΠΈΡŽ MIT, Π»ΠΈΠ±ΠΎ трСбуСтся Apache 2.0 / GPLv3 / проприСтарная лицСнзия?* + +3. **Подпись Windows-Π±ΠΈΠ½Π°Ρ€Π½ΠΈΠΊΠ° `HermesPair.exe` (`BUILD-01`)**: + - Π Π΅Π»ΠΈΠ·Π½Ρ‹ΠΉ workflow собираСт Π±ΠΈΠ½Π°Ρ€Π½ΠΈΠΊΠΈ ΠΈ ΠΊΠΎΠ½Ρ‚Ρ€ΠΎΠ»ΡŒΠ½Ρ‹Π΅ суммы SHA-256. Windows SmartScreen ΠΌΠΎΠΆΠ΅Ρ‚ ΠΏΡ€Π΅Π΄ΡƒΠΏΡ€Π΅ΠΆΠ΄Π°Ρ‚ΡŒ ΠΎ нСподписанном `.exe` Π±Π΅Π· EV/OV Authenticode сСртификата. + - *Вопрос: ΠŸΠ»Π°Π½ΠΈΡ€ΡƒΠ΅Ρ‚ΡΡ Π»ΠΈ ΠΏΡ€ΠΈΠΎΠ±Ρ€Π΅Ρ‚Π΅Π½ΠΈΠ΅ ΠΈ Π΄ΠΎΠ±Π°Π²Π»Π΅Π½ΠΈΠ΅ сСртификата подписи ΠΊΠΎΠ΄Π° (Code Signing Certificate) Π² GitHub Secrets для автоматичСской подписи Windows-Π±ΠΈΠ½Π°Ρ€Π½ΠΈΠΊΠΎΠ² Π² CI?* diff --git a/app/build.gradle.kts b/app/build.gradle.kts index 570809d..bf63485 100644 --- a/app/build.gradle.kts +++ b/app/build.gradle.kts @@ -1,9 +1,9 @@ plugins { - id("com.android.application") - id("org.jetbrains.kotlin.android") - id("org.jetbrains.kotlin.plugin.compose") - id("org.jetbrains.kotlin.plugin.serialization") - id("com.google.devtools.ksp") + alias(libs.plugins.android.application) + alias(libs.plugins.kotlin.android) + alias(libs.plugins.kotlin.compose) + alias(libs.plugins.kotlin.serialization) + alias(libs.plugins.ksp) } android { @@ -64,66 +64,64 @@ android { dependencies { // Jetpack Compose BOM - val composeBom = platform("androidx.compose:compose-bom:2025.02.00") + val composeBom = platform(libs.androidx.compose.bom) implementation(composeBom) androidTestImplementation(composeBom) - androidTestImplementation("androidx.compose.ui:ui-test-junit4") - androidTestImplementation("androidx.test.ext:junit:1.2.1") - androidTestImplementation("androidx.test.espresso:espresso-core:3.6.1") + androidTestImplementation(libs.androidx.compose.ui.test.junit4) + androidTestImplementation(libs.androidx.test.ext.junit) + androidTestImplementation(libs.androidx.test.espresso.core) - implementation("androidx.compose.ui:ui") - implementation("androidx.compose.ui:ui-graphics") - implementation("androidx.compose.ui:ui-tooling-preview") - implementation("androidx.compose.material3:material3") - implementation("androidx.compose.material:material-icons-extended") - implementation("androidx.compose.foundation:foundation") - debugImplementation("androidx.compose.ui:ui-tooling") - debugImplementation("androidx.compose.ui:ui-test-manifest") + implementation(libs.androidx.compose.ui) + implementation(libs.androidx.compose.ui.graphics) + implementation(libs.androidx.compose.ui.tooling.preview) + implementation(libs.androidx.compose.material3) + implementation(libs.androidx.compose.material.icons.extended) + implementation(libs.androidx.compose.foundation) + debugImplementation(libs.androidx.compose.ui.tooling) + debugImplementation(libs.androidx.compose.ui.test.manifest) // AndroidX & Lifecycle - implementation("androidx.core:core-ktx:1.15.0") - implementation("androidx.lifecycle:lifecycle-runtime-ktx:2.8.7") - implementation("androidx.lifecycle:lifecycle-viewmodel-compose:2.8.7") - implementation("androidx.activity:activity-compose:1.10.1") - implementation("androidx.navigation:navigation-compose:2.8.8") - implementation("androidx.browser:browser:1.8.0") - implementation("androidx.datastore:datastore-preferences:1.1.2") - implementation("androidx.security:security-crypto:1.1.0-alpha06") + implementation(libs.androidx.core.ktx) + implementation(libs.androidx.lifecycle.runtime.ktx) + implementation(libs.androidx.lifecycle.viewmodel.compose) + implementation(libs.androidx.activity.compose) + implementation(libs.androidx.navigation.compose) + implementation(libs.androidx.browser) + implementation(libs.androidx.datastore.preferences) + implementation(libs.androidx.security.crypto) // Room Database - val roomVersion = "2.6.1" - implementation("androidx.room:room-runtime:$roomVersion") - implementation("androidx.room:room-ktx:$roomVersion") - ksp("androidx.room:room-compiler:$roomVersion") - androidTestImplementation("androidx.room:room-testing:$roomVersion") + implementation(libs.androidx.room.runtime) + implementation(libs.androidx.room.ktx) + ksp(libs.androidx.room.compiler) + androidTestImplementation(libs.androidx.room.testing) // Coroutines - implementation("org.jetbrains.kotlinx:kotlinx-coroutines-core:1.10.1") - implementation("org.jetbrains.kotlinx:kotlinx-coroutines-android:1.10.1") + implementation(libs.kotlinx.coroutines.core) + implementation(libs.kotlinx.coroutines.android) // Serialization - implementation("org.jetbrains.kotlinx:kotlinx-serialization-json:1.8.0") + implementation(libs.kotlinx.serialization.json) // Network (OkHttp & WebSocket) - implementation("com.squareup.okhttp3:okhttp:4.12.0") - implementation("com.squareup.okhttp3:logging-interceptor:4.12.0") + implementation(libs.okhttp) + implementation(libs.okhttp.logging.interceptor) // CameraX & Barcode Scanning for QR Onboarding - val cameraxVersion = "1.4.1" - implementation("androidx.camera:camera-core:$cameraxVersion") - implementation("androidx.camera:camera-camera2:$cameraxVersion") - implementation("androidx.camera:camera-lifecycle:$cameraxVersion") - implementation("androidx.camera:camera-view:$cameraxVersion") - implementation("com.google.mlkit:barcode-scanning:17.3.0") - implementation("com.google.guava:guava:33.4.0-android") + implementation(libs.androidx.camera.core) + implementation(libs.androidx.camera.camera2) + implementation(libs.androidx.camera.lifecycle) + implementation(libs.androidx.camera.view) + implementation(libs.mlkit.barcode.scanning) + implementation(libs.guava) // Testing - testImplementation("junit:junit:4.13.2") - testImplementation("io.mockk:mockk:1.13.12") - testImplementation("org.jetbrains.kotlinx:kotlinx-coroutines-test:1.10.1") - testImplementation("com.squareup.okhttp3:mockwebserver:4.12.0") - testImplementation("app.cash.turbine:turbine:1.2.0") - testImplementation("org.json:json:20240303") + testImplementation(libs.junit) + testImplementation(libs.mockk) + testImplementation(libs.kotlinx.coroutines.test) + testImplementation(libs.okhttp.mockwebserver) + testImplementation(libs.turbine) + testImplementation(libs.json) } ksp { diff --git a/build.gradle.kts b/build.gradle.kts index d7cd1c7..614b661 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -1,7 +1,7 @@ plugins { - id("com.android.application") version "8.8.2" apply false - id("org.jetbrains.kotlin.android") version "2.1.10" apply false - id("org.jetbrains.kotlin.plugin.compose") version "2.1.10" apply false - id("org.jetbrains.kotlin.plugin.serialization") version "2.1.10" apply false - id("com.google.devtools.ksp") version "2.1.10-1.0.29" apply false + alias(libs.plugins.android.application) apply false + alias(libs.plugins.kotlin.android) apply false + alias(libs.plugins.kotlin.compose) apply false + alias(libs.plugins.kotlin.serialization) apply false + alias(libs.plugins.ksp) apply false } diff --git a/gradle.properties b/gradle.properties index 2a5aa01..928f675 100644 --- a/gradle.properties +++ b/gradle.properties @@ -1,4 +1,11 @@ android.useAndroidX=true -org.gradle.jvmargs=-Xmx2048m -Dfile.encoding=UTF-8 kotlin.code.style=official android.nonTransitiveRClass=true +android.nonFinalResIds=true + +# Gradle daemon & performance optimizations +org.gradle.jvmargs=-Xmx4096m -Dfile.encoding=UTF-8 +org.gradle.parallel=true +org.gradle.caching=true +org.gradle.configuration-cache=true + diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml new file mode 100644 index 0000000..e4574a6 --- /dev/null +++ b/gradle/libs.versions.toml @@ -0,0 +1,99 @@ +[versions] +# Build plugins & core Kotlin +agp = "8.8.2" +kotlin = "2.1.10" +ksp = "2.1.10-1.0.29" + +# AndroidX & Jetpack +composeBom = "2025.02.00" +coreKtx = "1.15.0" +lifecycle = "2.8.7" +activityCompose = "1.10.1" +navigationCompose = "2.8.8" +browser = "1.8.0" +datastore = "1.1.2" +securityCrypto = "1.1.0-alpha06" +room = "2.6.1" +camerax = "1.4.1" + +# KotlinX +coroutines = "1.10.1" +serialization = "1.8.0" + +# Network +okhttp = "4.12.0" + +# ML Kit & Google libraries +mlkitBarcode = "17.3.0" +guava = "33.4.0-android" + +# Testing +junit = "4.13.2" +androidxTestExtJunit = "1.2.1" +espresso = "3.6.1" +mockk = "1.13.12" +turbine = "1.2.0" +json = "20240303" + +[libraries] +# Jetpack Compose BOM & UI +androidx-compose-bom = { group = "androidx.compose", name = "compose-bom", version.ref = "composeBom" } +androidx-compose-ui = { group = "androidx.compose.ui", name = "ui" } +androidx-compose-ui-graphics = { group = "androidx.compose.ui", name = "ui-graphics" } +androidx-compose-ui-tooling = { group = "androidx.compose.ui", name = "ui-tooling" } +androidx-compose-ui-tooling-preview = { group = "androidx.compose.ui", name = "ui-tooling-preview" } +androidx-compose-ui-test-manifest = { group = "androidx.compose.ui", name = "ui-test-manifest" } +androidx-compose-ui-test-junit4 = { group = "androidx.compose.ui", name = "ui-test-junit4" } +androidx-compose-material3 = { group = "androidx.compose.material3", name = "material3" } +androidx-compose-material-icons-extended = { group = "androidx.compose.material", name = "material-icons-extended" } +androidx-compose-foundation = { group = "androidx.compose.foundation", name = "foundation" } + +# AndroidX Core, Lifecycle, Navigation, DataStore, Security +androidx-core-ktx = { group = "androidx.core", name = "core-ktx", version.ref = "coreKtx" } +androidx-lifecycle-runtime-ktx = { group = "androidx.lifecycle", name = "lifecycle-runtime-ktx", version.ref = "lifecycle" } +androidx-lifecycle-viewmodel-compose = { group = "androidx.lifecycle", name = "lifecycle-viewmodel-compose", version.ref = "lifecycle" } +androidx-activity-compose = { group = "androidx.activity", name = "activity-compose", version.ref = "activityCompose" } +androidx-navigation-compose = { group = "androidx.navigation", name = "navigation-compose", version.ref = "navigationCompose" } +androidx-browser = { group = "androidx.browser", name = "browser", version.ref = "browser" } +androidx-datastore-preferences = { group = "androidx.datastore", name = "datastore-preferences", version.ref = "datastore" } +androidx-security-crypto = { group = "androidx.security", name = "security-crypto", version.ref = "securityCrypto" } + +# Room Database +androidx-room-runtime = { group = "androidx.room", name = "room-runtime", version.ref = "room" } +androidx-room-ktx = { group = "androidx.room", name = "room-ktx", version.ref = "room" } +androidx-room-compiler = { group = "androidx.room", name = "room-compiler", version.ref = "room" } +androidx-room-testing = { group = "androidx.room", name = "room-testing", version.ref = "room" } + +# KotlinX Coroutines & Serialization +kotlinx-coroutines-core = { group = "org.jetbrains.kotlinx", name = "kotlinx-coroutines-core", version.ref = "coroutines" } +kotlinx-coroutines-android = { group = "org.jetbrains.kotlinx", name = "kotlinx-coroutines-android", version.ref = "coroutines" } +kotlinx-coroutines-test = { group = "org.jetbrains.kotlinx", name = "kotlinx-coroutines-test", version.ref = "coroutines" } +kotlinx-serialization-json = { group = "org.jetbrains.kotlinx", name = "kotlinx-serialization-json", version.ref = "serialization" } + +# Network (OkHttp) +okhttp = { group = "com.squareup.okhttp3", name = "okhttp", version.ref = "okhttp" } +okhttp-logging-interceptor = { group = "com.squareup.okhttp3", name = "logging-interceptor", version.ref = "okhttp" } +okhttp-mockwebserver = { group = "com.squareup.okhttp3", name = "mockwebserver", version.ref = "okhttp" } + +# CameraX & ML Kit +androidx-camera-core = { group = "androidx.camera", name = "camera-core", version.ref = "camerax" } +androidx-camera-camera2 = { group = "androidx.camera", name = "camera-camera2", version.ref = "camerax" } +androidx-camera-lifecycle = { group = "androidx.camera", name = "camera-lifecycle", version.ref = "camerax" } +androidx-camera-view = { group = "androidx.camera", name = "camera-view", version.ref = "camerax" } +mlkit-barcode-scanning = { group = "com.google.mlkit", name = "barcode-scanning", version.ref = "mlkitBarcode" } +guava = { group = "com.google.guava", name = "guava", version.ref = "guava" } + +# Testing +junit = { group = "junit", name = "junit", version.ref = "junit" } +androidx-test-ext-junit = { group = "androidx.test.ext", name = "junit", version.ref = "androidxTestExtJunit" } +androidx-test-espresso-core = { group = "androidx.test.espresso", name = "espresso-core", version.ref = "espresso" } +mockk = { group = "io.mockk", name = "mockk", version.ref = "mockk" } +turbine = { group = "app.cash.turbine", name = "turbine", version.ref = "turbine" } +json = { group = "org.json", name = "json", version.ref = "json" } + +[plugins] +android-application = { id = "com.android.application", version.ref = "agp" } +kotlin-android = { id = "org.jetbrains.kotlin.android", version.ref = "kotlin" } +kotlin-compose = { id = "org.jetbrains.kotlin.plugin.compose", version.ref = "kotlin" } +kotlin-serialization = { id = "org.jetbrains.kotlin.plugin.serialization", version.ref = "kotlin" } +ksp = { id = "com.google.devtools.ksp", version.ref = "ksp" } diff --git a/hermes-pair/dist/linux/hermes-pair b/hermes-pair/dist/linux/hermes-pair deleted file mode 100644 index 6b39f13..0000000 Binary files a/hermes-pair/dist/linux/hermes-pair and /dev/null differ diff --git a/hermes-pair/dist/windows/HermesPair.exe b/hermes-pair/dist/windows/HermesPair.exe deleted file mode 100644 index 0fc34b4..0000000 Binary files a/hermes-pair/dist/windows/HermesPair.exe and /dev/null differ