RIPDPI's own Compose conventions: ViewModel pattern, Route/Screen split, DataStore->StateFlow, RipDpiThemeTokens. Use for how this app does Compose, not generic Compose API questions (see compose).
日本語の概要は準備中です。原文の説明を表示しています。
Kotlin mapping for the AppSettings proto-backed DataStore: UI-state and native-preferences conversion. Use when adding or reading an app-settings field. Removing a field: use protobuf-schema-evolution first.
インストールする前に、エージェントに与えられる指示の中身を確認できます。
RIPDPI persists all app settings as a single Protobuf message (AppSettings) stored via Jetpack DataStore. The schema is the source of truth for all configurable values.
| File | Purpose |
|---|---|
core/data/model/src/main/proto/app_settings.proto | Schema definition for persisted app settings |
core/data/settings/src/main/kotlin/com/poyka/ripdpi/data/AppSettingsSerializer.kt | Serializer with default values |
core/data/settings/src/main/kotlin/com/poyka/ripdpi/data/AppDataStore.kt | DataStore extension property |
core/engine/.../core/RipDpiProxyPreferences.kt | Proto -> native preferences conversion |
app/.../activities/SettingsViewModel.kt | Proto -> UI state conversion |
app/.../activities/ConfigViewModel.kt | Config draft validation and persistence |
Add field to proto schema (app_settings.proto):
bool your_new_setting = <next_field_number>;
Use next available field number. Never reuse or renumber existing fields.
Set default in serializer (AppSettingsSerializer.kt):
override val defaultValue: AppSettings = AppSettings.newBuilder()
// ... existing defaults ...
.setYourNewSetting(false)
.build()
Expose in UI state (SettingsUiState or ConfigDraft):
data class SettingsUiState(
// ... existing fields ...
val yourNewSetting: Boolean = false,
)
Map in conversion function (AppSettings.toUiState() or toConfigDraft()):
fun AppSettings.toUiState() = SettingsUiState(
// ... existing mappings ...
yourNewSetting = this.yourNewSetting,
)
Persist changes via DataStore:
context.settingsStore.updateData { current ->
current.toBuilder().setYourNewSetting(value).build()
}
// Reactive (preferred): Flow<AppSettings>
context.settingsStore.data.collect { settings ->
val value = settings.yourSetting
}
// In ViewModel: combine with other flows
val uiState = combine(application.settingsStore.data, otherFlow) { settings, other ->
UiState(setting = settings.yourSetting, /* ... */)
}.stateIn(viewModelScope, SharingStarted.WhileSubscribed(5_000), UiState())
| Group | Fields | Notes |
|---|---|---|
| General | app_theme, ripdpi_mode, dns_ip, ipv6_enable | Mode is "vpn" or "proxy" |
| Command mode | enable_cmd_settings, cmd_args | Raw CLI args for command-line mode of the native RIPDPI proxy |
| Proxy | proxy_ip, proxy_port, max_connections, buffer_size | Defaults: 127.0.0.1:1080 |
| Desync | default_ttl, custom_ttl, fake_ttl, fake_sni, fake_offset, oob_data, drop_sack, etc. | desync_method and split_position are reserved/removed; grep app_settings.proto for the current field list |
| Protocols | desync_http, desync_https, desync_udp | Bool flags for which protocols to desync |
| Hosts | hosts_mode, hosts_blacklist, hosts_whitelist | Mode: disable/blacklist/whitelist |
| TLS | tls_minor_enabled, etc. | tlsrec_* names are reserved/removed (TLS record splitting is a desync chain step now); grep app_settings.proto for the current field list |
| App | onboarding_complete, biometric_enabled, backup_pin | App lifecycle settings |
RipDpiProxyPreferences.fromSettingsStore(context) reads the proto and creates either:
RipDpiProxyCmdPreferences(args) if enable_cmd_settings is trueRipDpiProxyUIPreferences(...) mapping all 27 proxy parametersenable_cmd_settings = true is a hard stop for automatic probing/audit. Those workflows require UI-config JSON so they can launch isolated strategy trials.core:diagnostics and the diagnostics UI layer. The proto flag alone is not the whole behavior.| Mistake | Fix |
|---|---|
| Reusing proto field numbers | Always use next available number; old numbers are reserved forever |
| Forgetting default in serializer | Every field needs an explicit default in AppSettingsSerializer.defaultValue |
| Reading DataStore on main thread | Always use Flow.collect or updateData (both suspend) |
Not updating toUiState() mapping | New fields must be mapped in all conversion functions |
| String enums without validation | Proto stores strings ("vpn", "proxy") -- validate on read |
まだレビューはありません。使ってみた感想をお寄せください。
概要と使いどころ
RIPDPI's own Compose conventions: ViewModel pattern, Route/Screen split, DataStore->StateFlow, RipDpiThemeTokens. Use for how this app does Compose, not generic Compose API questions (see compose).
日本語の概要は準備中です。原文の説明を表示しています。
ADB-based RIPDPI device/emulator debugging: build/install/launch, logcat filtering, fixture port-forwarding, instrumented tests, crash/ANR triage. Use when debugging on a real device or emulator.
日本語の概要は準備中です。原文の説明を表示しています。
RIPDPI Appium launch-contract reference: start routes and permission/service/data presets. Use when a test launches to the wrong screen or a new automation route is added. General flakiness: appium-test-debug.
日本語の概要は準備中です。原文の説明を表示しています。
RIPDPI Appium test authoring: page objects, resource-id locators, assertions, wait tiers. Use when writing a new Appium test or page object, or adding coverage for a new screen.
日本語の概要は準備中です。原文の説明を表示しています。
RIPDPI Appium failure triage: flaky tests, locator/session/wait issues, screenshot and element-tree debugging. Use when an Appium test fails or is flaky.
日本語の概要は準備中です。原文の説明を表示しています。
Add or modify a GitHub Actions job. Use when editing a file under .github/workflows/. Not for running a workflow locally (local-ci-act) or release signing (release-signing).
日本語の概要は準備中です。原文の説明を表示しています。