proxy/docs
2026-06-16 12:45:21 +03:00
..
architecture.md docs: add agent onboarding guide (architecture, build/test, conventions, invariants) 2026-06-16 12:45:21 +03:00
building-testing.md docs: add agent onboarding guide (architecture, build/test, conventions, invariants) 2026-06-16 12:45:21 +03:00
conventions.md docs: add agent onboarding guide (architecture, build/test, conventions, invariants) 2026-06-16 12:45:21 +03:00
README.md docs: add agent onboarding guide (architecture, build/test, conventions, invariants) 2026-06-16 12:45:21 +03:00

vojo proxy — agent onboarding

Native Android proxy client. App traffic is captured by a VpnService tun, fed through a vendored native tun2socks engine into a local SOCKS5 server, then out to a real upstream proxy (SOCKS5 / HTTP(S) / Shadowsocks). UI is Jetpack Compose; persistence is DataStore.

The repo-root README.md is the product / Russian overview; this docs/ set is the agent map. It exists so an agent session can load context fast. Read in this order:

  1. architecture.md — the data path, the component map, and why the design is shaped this way (the local-SOCKS5-bridge, what runs native vs Kotlin).
  2. building-testing.md — how to build the APK and run the three test layers (JVM unit tests, the interop harness, on-device QA).
  3. conventions.md — code style, commit rules, and the load-bearing invariants — choices that look wrong but are deliberate. Read this before "fixing" the data path; several obvious-looking changes have already been tried and reverted.

60-second orientation

  • Language/stack: Kotlin + Compose (Material3), coroutines, kotlinx-serialization, DataStore Preferences. Native C: a vendored hev-socks5-tunnel + a thin JNI bridge.
  • Modules: single Gradle module :app. minSdk 28, compileSdk 35, arm64-v8a only.
  • Package root: chat.vojo.proxy (debug app id chat.vojo.proxy.debug).
  • Entry points: MainActivityui/MainScreen (4 tabs: Туннель / Серверы / Приложения / Опции). service/ProxyVpnService is the VpnService. service/ProxyTileService is the quick-settings tile.
  • Single source of truth for state: data/ConfigStore (persisted ProxyState) and service/VpnState (live tunnel status/journal as StateFlows).
  • No upstream "universal core". sing-box / xray / clash are GPLv3 and would force open-sourcing this closed app (and bloat the APK). The engine is hev-socks5-tunnel (MIT); the Shadowsocks crypto and proxy clients are our own Kotlin, verified against canon. See conventions.md before proposing a core swap.

Where things live

Area Path
VpnService lifecycle, tun builder, probe, reaper app/src/main/java/chat/vojo/proxy/service/ProxyVpnService.kt
Local loopback SOCKS5 server (hev talks to this) core/socks/LocalSocks5Server.kt
Upstream clients core/upstream/{Socks5,Http,Shadowsocks}Upstream.kt, Upstream.kt
Shadowsocks AEAD (SIP004) core/crypto/{ShadowsocksCrypto,ShadowsocksStream}.kt
SOCKS address codec / stream utils core/net/{SocksAddress,StreamUtils}.kt
Config model + share-link import core/ProxyConfig.kt, core/ConfigImport.kt
Persistence / app list data/{ConfigStore,AppRepository}.kt
UI ui/ (MainScreen, ConnectionScreen, ServersScreen, AppsScreen, SettingsScreen, MainViewModel)
Native (JNI bridge + engine) core/Tun2Socks.kt, app/src/main/jni/tun2socks.c, app/src/main/jni/hev-socks5-tunnel/
Unit tests app/src/test/