Skip to content

feat(mobile): add encrypted Android companion and self-hosted Relay#351

Open
Crain99 wants to merge 24 commits into
xintaofei:mainfrom
Crain99:feat/relay-v1
Open

feat(mobile): add encrypted Android companion and self-hosted Relay#351
Crain99 wants to merge 24 commits into
xintaofei:mainfrom
Crain99:feat/relay-v1

Conversation

@Crain99

@Crain99 Crain99 commented Jul 16, 2026

Copy link
Copy Markdown

Summary

This PR adds an installable Android companion for Codeg, with two remote
connection modes:

  • Relay (recommended): the phone and desktop make outbound WebSocket
    connections to a blind Relay and exchange end-to-end encrypted envelopes.
    The desktop does not need a public IP or inbound port.
  • Direct: the phone connects to an existing HTTPS Codeg Web Service with
    its normal Web Service token.

It also adds the desktop pairing/revocation workflow, a standalone Relay and
desktop bridge, self-hosting templates, mobile-oriented workspace layouts, and
Android build/release automation.

Android download

The complete signed review package is available before merge:

Package metadata:

  • Application ID: cn.crain.codeg.mobile
  • Version: 0.20.3 (versionCode=20003)
  • Minimum Android: API 24 / Android 7.0
  • Target SDK: 36
  • ABIs: arm64-v8a, armeabi-v7a, x86, x86_64
  • SHA-256: b52ea281cc8a335ea3bd9f7c0aef752acd6bcfb1b3b08fa59a65c6ac599aa00a
  • APK Signature Scheme v2 verified; release manifest is not debuggable

The release workflow now builds the same four-ABI universal APK instead of an
arm64-only artifact.

Desktop Codeg changes

The mobile client is intentionally thin: Agents, ACP connections, terminals,
Git operations and project files continue to run on desktop Codeg. The desktop
changes in this PR are:

  • add Mobile Relay settings, secure token storage, bridge lifecycle management,
    one-time QR pairing, six-digit safety-code confirmation and device revocation;
  • add a local encrypted Relay bridge that proxies the existing Codeg API and
    event stream without exposing the Codeg Web Service token to the Relay;
  • add mobile transport/pairing/crypto support to the shared frontend while
    preserving the existing Tauri and browser transports;
  • refine compact layouts for the title bar, folder/branch controls, command
    manager, sidebar, task/status surfaces, settings navigation, welcome screen
    and composer without changing desktop breakpoints;
  • keep Direct mode available for users who already expose Codeg through HTTPS.

Mobile access remains opt-in. Existing desktop and server behavior is unchanged
until a Relay endpoint is configured and enabled.

Relay and self-hosting

The Relay is an independent Rust WebSocket router. It authenticates routing
credentials, applies limits and forwards opaque encrypted frames; it does not
receive the Codeg token or decrypt chats, code, commands or attachments.

  • Relay URLs are supplied by desktop settings and embedded in one-time pairing
    QR codes; the APK does not hard-code a Relay operator or domain.
  • Public endpoints must use wss://; plaintext ws:// is accepted only for
    loopback development.
  • Docker Compose, Nginx, Caddy and optional FRP examples are included.
  • A public VPS can run Relay directly. FRP is only needed when the Relay process
    itself remains on a private network; Codeg port 3080 should not be exposed for
    Relay mode.

See docs/relay/self-hosting-zh-CN.md, docs/relay/protocol-v1.md and
docs/relay/threat-model.md.

iOS status

The iOS project and simulator compile-smoke path are included, but this PR does
not provide an IPA or TestFlight build. An Apple Developer distribution
certificate and provisioning profile are not currently available. Android is
therefore the only installable mobile package attached to this PR.

Validation

Executed locally:

pnpm eslint .
pnpm test                         # 192 files, 2,348 tests passed
pnpm build

cargo test --manifest-path relay/Cargo.toml
                                    # 9 passed
cargo test --manifest-path relay-bridge/Cargo.toml
                                    # 10 passed
cargo test --manifest-path src-tauri/Cargo.toml --features test-utils \
  normalizes_relay_url_and_rejects_embedded_credentials
                                    # passed
git diff --check

Android release verification:

  • signed universal Release APK built successfully;
  • apksigner verify --verbose passed;
  • all four native libraries were inspected inside the APK;
  • API 24 minimum and Target SDK 36 confirmed with aapt;
  • no android:debuggable marker in the release manifest;
  • public Release asset digest matches the documented SHA-256.

The Relay/Bridge tests cover multi-device isolation, revocation, one-time
pairing, replay rejection, long ordered encrypted streams, multipart attachment
upload, cancellation, idempotency and reconnect-backoff reset.

Known limits and rollout notes

  • Relay attachments are currently limited to 2 MiB per file.
  • FCM background push is not included; a heavily suspended Android app may need
    to be brought back to the foreground.
  • Relay metadata such as IP address, connection time, routing identifiers and
    ciphertext size remains observable even though payloads are end-to-end
    encrypted.
  • Earlier local debug/candidate APKs may use a different signing certificate;
    those test packages must be uninstalled before installing this PR candidate.
  • The linked APK is a review candidate, not an official upstream Codeg release.

Commit structure

The history follows the repository's existing Conventional Commit style and is
kept in reviewable layers: mobile shell foundation, Relay protocol/router,
desktop bridge and pairing, deployment hardening, reconnect/attachment fixes,
mobile UI refinements, self-hosted Relay support, and universal Android release
packaging. The final review-polish commits include:

  • fix(mobile): refine compact workspace layouts
  • feat(relay): support self-hosted mobile endpoints
  • chore(mobile): publish universal Android packages
  • docs(mobile): remove deployment-specific references

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant