Skip to content
Merged
Show file tree
Hide file tree
Changes from 34 commits
Commits
Show all changes
154 commits
Select commit Hold shift + click to select a range
e9f80a2
chore(app): bootstrap android modular project
ayagmar Feb 14, 2026
bd8a0a0
chore(quality): configure ktlint detekt and ci
ayagmar Feb 14, 2026
2817cf5
docs(spike): validate rpc and cwd behavior
ayagmar Feb 14, 2026
0624eb8
feat(bridge): bootstrap typescript service
ayagmar Feb 14, 2026
2c3c269
feat(bridge): add websocket envelope protocol and auth
ayagmar Feb 14, 2026
dc89183
feat(bridge): forward pi rpc over websocket
ayagmar Feb 14, 2026
eff1bdf
feat(bridge): manage per-cwd pi processes with locking
ayagmar Feb 14, 2026
6538df2
feat(bridge): add session indexing api from jsonl files
ayagmar Feb 14, 2026
b39cec9
feat(bridge): add resilience and health management
ayagmar Feb 14, 2026
95b0489
feat(rpc): add protocol models and parser
ayagmar Feb 14, 2026
62f16bd
feat(rpc): add streaming assembler and ui throttler
ayagmar Feb 14, 2026
389d46e
feat(net): add websocket transport with reconnect support
ayagmar Feb 14, 2026
aa5f6af
feat(net): implement rpc connection orchestration
ayagmar Feb 14, 2026
74db836
feat(hosts): add host profiles and secure token storage
ayagmar Feb 14, 2026
7e6e72f
perf(sessions): implement cached indexed session repository
ayagmar Feb 14, 2026
2a3389e
feat(ui): add grouped sessions browser by cwd
ayagmar Feb 14, 2026
f7957fc
feat(sessions): add rename fork export and compact actions
ayagmar Feb 14, 2026
b2fac50
feat(chat): implement streaming timeline ui
ayagmar Feb 14, 2026
d0545cf
feat(chat): add abort, steer, and follow-up controls
ayagmar Feb 14, 2026
7d0e0ab
docs(progress): mark task 5.2 as complete
ayagmar Feb 14, 2026
cf3cfbb
feat(chat): add model and thinking controls
ayagmar Feb 14, 2026
cb7e1ae
feat(extensions): implement extension ui protocol support
ayagmar Feb 14, 2026
328b950
perf(chat): add backpressure and bounded buffering
ayagmar Feb 14, 2026
26bb726
docs(progress): update task 6.1 status and commit hash
ayagmar Feb 14, 2026
9232795
perf(app): add instrumentation and baseline metrics
ayagmar Feb 14, 2026
ee7019a
docs(progress): update task 6.2 status and commit hash
ayagmar Feb 14, 2026
50c7268
docs: add README and final acceptance report
ayagmar Feb 14, 2026
bf907d7
docs(progress): mark all tasks complete
ayagmar Feb 14, 2026
e7bf680
docs: reorganize documentation structure
ayagmar Feb 14, 2026
2142ac7
docs: add testing guide for emulator
ayagmar Feb 14, 2026
c55f8fe
docs: fix documentation structure
ayagmar Feb 14, 2026
0cf03ce
fix: address review feedback - permissions, settings, extension UI
ayagmar Feb 14, 2026
0583f23
chore: remove bin and some fixes
ayagmar Feb 14, 2026
d2e1b29
feat: connection diagnostics, fork picker, metrics abstraction
ayagmar Feb 14, 2026
aeda764
feat(sessions): add fork picker dialog and improve connection diagnos…
ayagmar Feb 14, 2026
a5b5611
feat(rpc,ui): add thinking block display for assistant messages
ayagmar Feb 15, 2026
51da6e4
feat(rpc,ui): add slash commands palette
ayagmar Feb 15, 2026
b7affd1
feat(rpc,ui): add auto-compaction/retry event notifications
ayagmar Feb 15, 2026
486e9ef
docs: update progress tracker for Phase 1 completion
ayagmar Feb 15, 2026
653cfe6
feat(ui): add file edit diff viewer
ayagmar Feb 15, 2026
1b4cc72
feat(rpc,session): add bash command execution support
ayagmar Feb 15, 2026
4821a02
feat(ui): add bash dialog and enhanced tool argument display
ayagmar Feb 15, 2026
f95e729
feat(rpc,ui): add session stats and model picker (Phase 3)
ayagmar Feb 15, 2026
6c2153d
feat(settings): add auto-compaction and auto-retry toggles
ayagmar Feb 15, 2026
4db9685
feat(chat): add image attachment support with photo picker
ayagmar Feb 15, 2026
fbf5aed
feat(rpc): enhance model parsing and state management; improve token …
ayagmar Feb 15, 2026
1f90b3f
test(session): add rpc mapping conformance tests
ayagmar Feb 15, 2026
1f57a2a
feat(rpc): parse lifecycle and extension error events
ayagmar Feb 15, 2026
09e2b27
feat(chat): surface lifecycle and extension errors
ayagmar Feb 15, 2026
948ace3
feat(settings): add steering and follow-up mode controls
ayagmar Feb 15, 2026
4472f89
docs(spike): assess tree navigation rpc vs bridge
ayagmar Feb 15, 2026
360aa4f
feat(tree): add bridge-backed session tree navigation MVP
ayagmar Feb 15, 2026
5ca89ce
feat(settings): add chat actions and gestures help
ayagmar Feb 15, 2026
5dd4b48
docs(readme): sync implemented chat and tree features
ayagmar Feb 15, 2026
7869fe9
docs(progress): record rpc enhancement completion
ayagmar Feb 15, 2026
918ace7
docs(tasks): mark rpc enhancement queue complete
ayagmar Feb 15, 2026
e56db90
test(tree): add session tree endpoint coverage
ayagmar Feb 15, 2026
43946c4
docs(progress): track post-parity hardening backlog
ayagmar Feb 15, 2026
09fa47d
fix(chat): throttle noisy lifecycle notifications
ayagmar Feb 15, 2026
777c56c
test(settings): cover steering and follow-up mode updates
ayagmar Feb 15, 2026
1dbaaf2
docs(progress): mark hardening queue complete
ayagmar Feb 15, 2026
fd1175f
refactor: improve session handling and validation, enhance UI respons…
ayagmar Feb 15, 2026
c362b1f
fix(chat): preserve thinking expansion state during streaming
ayagmar Feb 15, 2026
9a48276
feat(rpc): add abort_retry set_thinking_level and get_last_assistant_…
ayagmar Feb 15, 2026
aa0bf89
perf(chat): wire backpressure and throttling into runtime event pipeline
ayagmar Feb 15, 2026
24d5653
feat(tree): add filters labels and jump-continue flow
ayagmar Feb 15, 2026
fd33b62
feat(chat): auto-open slash command palette on slash input
ayagmar Feb 15, 2026
e0fee4e
feat(chat): improve diff viewer with line numbers highlighting and ro…
ayagmar Feb 15, 2026
e856837
refactor(chat): use java-diff-utils for diff rendering
ayagmar Feb 15, 2026
6c22a58
refactor(chat): harden diff viewer config async and prism highlighting
ayagmar Feb 15, 2026
4315e08
perf(chat): precompute and cache syntax spans for diff lines
ayagmar Feb 15, 2026
3604829
perf(chat): limit prism grammar bundle to required languages
ayagmar Feb 15, 2026
caaefe0
perf(chat): remove diff tail allocations in remaining line merge
ayagmar Feb 15, 2026
f5d67a3
test(chat): add prism highlight coverage and span precompute helper
ayagmar Feb 15, 2026
fb3acf1
perf(chat): hash prism highlight cache keys for memory stability
ayagmar Feb 15, 2026
1c2f6a0
feat(chat): show async diff loading state and optimize highlight caching
ayagmar Feb 15, 2026
06d5431
perf(chat): remove kapt prism bundler from runtime build
ayagmar Feb 15, 2026
2b7eb11
fix(network): harden rpc envelope handling and bridge safety
ayagmar Feb 15, 2026
47c6dc9
fix(bridge): block symlink escapes in session tree lookup
ayagmar Feb 15, 2026
4176ca0
fix(security): scope cleartext policy by build type
ayagmar Feb 15, 2026
76224fb
refactor(chat): extract timeline toggle reducer helpers
ayagmar Feb 15, 2026
d20c653
perf(chat): cap in-memory timeline window size
ayagmar Feb 15, 2026
fac661e
refactor(sessions): move transient status to one-shot events
ayagmar Feb 15, 2026
787dab6
perf(sessions): debounce search observer refreshes
ayagmar Feb 15, 2026
8c36849
test(ui): add compose coverage for fork picker dialog
ayagmar Feb 15, 2026
e9c5598
chore(quality): gate app check on lint with baseline
ayagmar Feb 15, 2026
b326a2d
refactor(chat): extract timeline merge/upsert reducer logic
ayagmar Feb 15, 2026
faa1509
refactor(settings): emit one-shot status messages
ayagmar Feb 15, 2026
1c29306
perf(chat): add paged transcript windowing in timeline
ayagmar Feb 15, 2026
9c46ea4
ci: gate android workflow on full app check
ayagmar Feb 15, 2026
0916bd4
fix(sessions): refresh hosts on resume and navigate to chat after ses…
ayagmar Feb 15, 2026
2e41bec
feat(chat): distinct message colors and auto-dismiss notifications
ayagmar Feb 15, 2026
a70d247
feat(chat): improved model selector with dropdown UI
ayagmar Feb 15, 2026
b966aff
feat(env): add dotenv for environment variable management and update …
ayagmar Feb 15, 2026
61061b2
fix(chat): strip ANSI codes and fix tree layout overflow
ayagmar Feb 15, 2026
2cc0480
fix(nav): allow returning to Sessions after resume
ayagmar Feb 15, 2026
e8ac20f
fix(chat): reload messages when connection becomes active
ayagmar Feb 15, 2026
88d1324
refactor: move New Session to Sessions tab + add chat auto-scroll
ayagmar Feb 15, 2026
ef1e973
docs: add UX analysis and updated task plan
ayagmar Feb 15, 2026
e81d27f
fix(sessions): make New Session work + add flat view toggle
ayagmar Feb 15, 2026
cbc1e74
docs: update plan with C4 persistent connection task
ayagmar Feb 15, 2026
08430c1
docs: add FIXME comments for C4 persistent bridge connection
ayagmar Feb 15, 2026
37fd555
feat(sessions): reuse bridge connection across new and resume
ayagmar Feb 15, 2026
6e4bdd6
feat(chat): compact header while streaming
ayagmar Feb 15, 2026
182d80d
fix(chat): allow image-only prompts to send
ayagmar Feb 15, 2026
31e4e42
docs(ai): update final adjustments plan and progress
ayagmar Feb 15, 2026
1028ed5
feat(tree): add all session-tree filter end-to-end
ayagmar Feb 15, 2026
8d9159c
feat(chat): add built-in command parity in palette
ayagmar Feb 15, 2026
48b7157
feat(chat): add global collapse and expand controls
ayagmar Feb 15, 2026
0e916c7
feat(perf): enable live frame metrics in chat streaming
ayagmar Feb 15, 2026
b64a200
feat(settings): add transport preference parity with ws fallback
ayagmar Feb 15, 2026
1440df6
feat(chat): add streaming queue inspector for steer/follow-up
ayagmar Feb 15, 2026
f679732
fix(bridge): isolate rpc events to control owner per cwd
ayagmar Feb 15, 2026
339029a
fix(core-net): harden reconnect resync epochs and pending requests
ayagmar Feb 15, 2026
e11f9af
fix(bridge): harden token auth and exposure defaults
ayagmar Feb 15, 2026
d5d0629
fix(android): tighten cleartext policy to tailscale hostnames
ayagmar Feb 15, 2026
8b4fd8e
perf(bridge): cache session metadata by stat signature
ayagmar Feb 15, 2026
2805b0d
refactor(di): replace app service locator with explicit graph
ayagmar Feb 15, 2026
b2af260
refactor(chat): extract overlay and command palette components
ayagmar Feb 15, 2026
cd459d8
refactor(core-rpc): remove unused backpressure pipeline abstractions
ayagmar Feb 15, 2026
9e957e2
chore(detekt): tighten complexity config and drop broad file suppress…
ayagmar Feb 15, 2026
f95d567
feat(theme): add PiMobileTheme with system/light/dark preference
ayagmar Feb 15, 2026
5d34f63
feat(ui): introduce reusable Pi design system primitives
ayagmar Feb 15, 2026
4b71090
feat(tree): add bridge-backed in-place tree navigation parity
ayagmar Feb 15, 2026
c7127bf
refactor(bridge): align session index parsing with pi metadata semantics
ayagmar Feb 15, 2026
91a4d9b
perf(chat): incrementally parse resume history with paged windows
ayagmar Feb 15, 2026
1fc6b7f
feat(extensions): route mobile stats workflow through internal command
ayagmar Feb 15, 2026
28ba8c0
docs(progress): record heavy-hitter commit hashes
ayagmar Feb 15, 2026
3fe9bdd
fix(review): harden workflow command dispatch and leaf resolution
ayagmar Feb 15, 2026
43bcdd0
fix(ui): remove redundant top bar with NoActionBar theme
ayagmar Feb 15, 2026
86d7c42
feat(sessions): add expand/collapse-all controls and default flat view
ayagmar Feb 15, 2026
c85b1cf
refactor(core): remove unused SessionSummary, RpcEnvelope, and SlashC…
ayagmar Feb 15, 2026
fab7c3b
fix(chat): handle cancelled responses, prevent race conditions, fix s…
ayagmar Feb 15, 2026
0964121
refactor(test): extract FakeSessionController to shared test fixture
ayagmar Feb 15, 2026
2c79fc4
fix(chat): remove RpcResponse from event flow, add user messages, fix…
ayagmar Feb 15, 2026
87fd1ff
fix(session): add session change notification and fix duplicate messages
ayagmar Feb 15, 2026
7f6e1f7
refactor(ui): simplify chat header and remove clutter
ayagmar Feb 15, 2026
6aa183d
fix(chat): remove lifecycle notification spam, add bash/tree buttons
ayagmar Feb 15, 2026
7cebcc7
fix(review): harden prompt errors, reduce chat noise, and remove dead…
ayagmar Feb 15, 2026
7652f15
fix(chat): reset stream state and preserve tool expansion
ayagmar Feb 15, 2026
454cb00
fix(ui): support CRLF fenced code blocks
ayagmar Feb 15, 2026
ad1912d
refactor(session): make rpc client id immutable
ayagmar Feb 15, 2026
a603c51
docs(readme): add docs index and architecture guides
ayagmar Feb 15, 2026
b1de72a
fix(bridge): normalize cwd handling and release stale locks
ayagmar Feb 15, 2026
e090583
fix(rpc): handle cancelled session ops and release bridge locks
ayagmar Feb 15, 2026
22d0004
fix(rpc): reacquire control and clear stale session locks
ayagmar Feb 15, 2026
9d513c4
fix(ui): smooth chat interactions and update launcher icon
ayagmar Feb 15, 2026
dbc5761
fix(chat): harden optimistic user sync and scroll behavior
ayagmar Feb 15, 2026
967d2d3
feat(sessions): add cwd chips and selected-dir new session
ayagmar Feb 16, 2026
233c121
fix(chat): reduce keyboard jank after prompt send
ayagmar Feb 16, 2026
5836677
feat(sessions): persist preferred cwd per host
ayagmar Feb 16, 2026
a06ab6f
test(sessions): add cwd chip selector compose tests
ayagmar Feb 16, 2026
394748a
fix(ui): smooth prompt controls transitions
ayagmar Feb 16, 2026
cad86f3
fix(quality): resolve detekt and lint violations
ayagmar Feb 16, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 16 additions & 0 deletions .editorconfig
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
root = true

[*]
charset = utf-8
end_of_line = lf
indent_style = space
indent_size = 4
insert_final_newline = true
max_line_length = 120
trim_trailing_whitespace = true

[*.{kt,kts}]
ktlint_code_style = ktlint_official
ij_kotlin_allow_trailing_comma = true
ij_kotlin_allow_trailing_comma_on_call_site = true
ktlint_function_naming_ignore_when_annotated_with = Composable
51 changes: 51 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
name: ci

on:
pull_request:
push:
branches:
- master

jobs:
android:
name: Android
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4

- name: Setup JDK 21
uses: actions/setup-java@v4
with:
distribution: temurin
java-version: 21
cache: gradle

- name: Lint & Test
run: ./gradlew ktlintCheck detekt test

bridge:
name: Bridge
runs-on: ubuntu-latest
defaults:
run:
working-directory: bridge
steps:
- uses: actions/checkout@v4

- name: Setup pnpm
uses: pnpm/action-setup@v4
with:
version: 9

- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version: 22
cache: pnpm
cache-dependency-path: bridge/pnpm-lock.yaml

- name: Install dependencies
run: pnpm install --frozen-lockfile

- name: Lint, Typecheck & Test
run: pnpm check
15 changes: 14 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -24,4 +24,17 @@ hs_err_pid*
replay_pid*

# Kotlin Gradle plugin data, see https://kotlinlang.org/docs/whatsnew20.html#new-directory-for-kotlin-data-in-gradle-projects
.kotlin/
.kotlin/

# Gradle
.gradle/
**/build/
**/bin/

# Android
local.properties
.idea/
*.iml

# Keep Gradle wrapper binary
!gradle/wrapper/gradle-wrapper.jar
208 changes: 208 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,208 @@
# Pi Mobile

An Android client for the [Pi coding agent](https://github.com/badlogic/pi-mono). Control your coding sessions from your phone over Tailscale.

## What This Does

Pi runs on your laptop. This app lets you:
- Browse and resume coding sessions from anywhere
- Chat with the agent, send prompts, abort, steer
- Switch between projects (different working directories)
- Manage models and thinking levels
- Handle extension dialogs (confirmations, inputs, selections)

The connection goes over Tailscale, so it works anywhere without port forwarding.

## Architecture

```
Phone (this app) <--Tailscale--> Laptop (bridge) <--local--> pi --mode rpc
```

The bridge is a small Node.js service that translates WebSocket to pi's stdin/stdout JSON protocol. The app connects to the bridge, not directly to pi.

## Setup

### 1. Laptop Setup

Install pi if you haven't:
```bash
npm install -g @mariozechner/pi-coding-agent
```

Clone and start the bridge:
```bash
git clone https://github.com/yourusername/pi-mobile.git
cd pi-mobile/bridge
pnpm install
pnpm start
```

The bridge binds to `127.0.0.1:8787` by default. Set `BRIDGE_HOST` to your laptop Tailscale IP (or `0.0.0.0`) to allow phone access. It spawns pi processes on demand per working directory.

### 2. Phone Setup

Install the APK or build from source:
```bash
./gradlew :app:assembleDebug
adb install app/build/outputs/apk/debug/app-debug.apk
```

### 3. Connect

1. Add a host in the app:
- Host: your laptop's Tailscale IP (100.x.x.x)
- Port: 8787 (or whatever the bridge uses)
- Token: set this in bridge/.env as `BRIDGE_AUTH_TOKEN`

2. The app will fetch your sessions from `~/.pi/agent/sessions/`

3. Tap a session to resume it

## How It Works

### Sessions

Sessions are grouped by working directory (cwd). Each session is a JSONL file in `~/.pi/agent/sessions/--path--/`. The bridge reads these files directly since pi's RPC doesn't have a list-sessions command.

### Process Management

The bridge manages one pi process per cwd:
- First connection to a project spawns pi
- Process stays alive with idle timeout
- Reconnecting reuses the existing process
- Crash restart with exponential backoff

### Message Flow

```
User types prompt
App sends WebSocket → Bridge
Bridge writes to pi stdin (JSON line)
pi processes, writes events to stdout
Bridge forwards events → App
App renders streaming text/tools
```

## Troubleshooting

### Can't connect

1. Check Tailscale is running on both devices
2. Verify the bridge is running: `curl http://100.x.x.x:8787/health`
3. Check the token matches exactly (BRIDGE_AUTH_TOKEN)
4. Try the laptop's Tailscale IP, not hostname

### Sessions don't appear

1. Check `~/.pi/agent/sessions/` exists on laptop
2. Verify the bridge has read permissions
3. Check bridge logs for errors

### Streaming is slow/choppy

1. Check logcat for `PerfMetrics` - see actual timing numbers
2. Look for `FrameMetrics` jank warnings
3. Verify WiFi/cellular connection is stable
4. Try closer to the laptop (same room)

### App crashes on resume

1. Check logcat for out-of-memory errors
2. Large session histories can cause issues
3. Try compacting the session first: `/compact` in pi, then resume

## Development

### Project Structure

```
app/ - Android app (Compose UI, ViewModels)
core-rpc/ - RPC protocol models and parsing
core-net/ - WebSocket transport and connection management
core-sessions/ - Session caching and repository
bridge/ - Node.js bridge service
```

### Running Tests

```bash
# Android tests
./gradlew test

# Bridge tests
cd bridge && pnpm test

# All quality checks
./gradlew ktlintCheck detekt test
```

### Logs to Watch

```bash
# Performance metrics
adb logcat | grep "PerfMetrics"

# Frame jank during streaming
adb logcat | grep "FrameMetrics"

# General app logs
adb logcat | grep "PiMobile"

# Bridge logs (on laptop)
pnpm start 2>&1 | tee bridge.log
```

## Configuration

### Bridge Environment Variables

Create `bridge/.env`:

```env
BRIDGE_HOST=0.0.0.0 # Use 0.0.0.0 to accept Tailscale connections
BRIDGE_PORT=8787 # Port to listen on
BRIDGE_AUTH_TOKEN=your-secret # Required authentication token
BRIDGE_PROCESS_IDLE_TTL_MS=300000 # 5 minutes idle timeout
BRIDGE_LOG_LEVEL=info # debug, info, warn, error, silent
```

### App Build Variants

Debug builds include logging and assertions. Release builds (if you make them) strip these for smaller size.

## Security Notes

- Token auth is required - don't expose the bridge without it
- The bridge binds to localhost by default; explicitly set `BRIDGE_HOST` to your Tailscale IP for remote access
- All traffic goes over Tailscale's encrypted mesh
- Session data stays on the laptop; the app only displays it

## Limitations

- No offline mode - requires live connection to laptop
- Large tool outputs are truncated (400+ chars collapsed by default)
- Session history loads once on resume, not incrementally
- Image attachments not supported (text only)

## Testing

See [docs/testing.md](docs/testing.md) for emulator setup and testing procedures.

Quick start:
```bash
# Start emulator, build, install
./gradlew :app:installDebug

# Watch logs
adb logcat | grep -E "PiMobile|PerfMetrics"
```

## License

MIT
77 changes: 77 additions & 0 deletions app/build.gradle.kts
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
plugins {
id("com.android.application")
id("org.jetbrains.kotlin.android")
id("org.jetbrains.kotlin.plugin.serialization")
}

android {
namespace = "com.ayagmar.pimobile"
compileSdk = 34

defaultConfig {
applicationId = "com.ayagmar.pimobile"
minSdk = 26
targetSdk = 34
versionCode = 1
versionName = "1.0"

testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner"
}

buildTypes {
release {
isMinifyEnabled = false
proguardFiles(
getDefaultProguardFile("proguard-android-optimize.txt"),
"proguard-rules.pro",
)
}
}

compileOptions {
sourceCompatibility = JavaVersion.VERSION_17
targetCompatibility = JavaVersion.VERSION_17
}

kotlinOptions {
jvmTarget = "17"
}

buildFeatures {
compose = true
}

composeOptions {
kotlinCompilerExtensionVersion = "1.5.14"
}

packaging {
resources {
excludes += "/META-INF/{AL2.0,LGPL2.1}"
}
}
}

dependencies {
implementation(project(":core-rpc"))
implementation(project(":core-net"))
implementation(project(":core-sessions"))

implementation(platform("androidx.compose:compose-bom:2024.06.00"))
implementation("androidx.core:core-ktx:1.13.1")
implementation("androidx.activity:activity-compose:1.9.1")
implementation("androidx.lifecycle:lifecycle-runtime-ktx:2.8.4")
implementation("androidx.lifecycle:lifecycle-runtime-compose:2.8.4")
implementation("androidx.lifecycle:lifecycle-viewmodel-compose:2.8.4")
implementation("androidx.navigation:navigation-compose:2.7.7")
implementation("androidx.security:security-crypto:1.1.0-alpha06")
implementation("androidx.compose.material3:material3")
implementation("androidx.compose.ui:ui")
implementation("androidx.compose.ui:ui-tooling-preview")
implementation("org.jetbrains.kotlinx:kotlinx-serialization-json:1.6.3")
implementation("com.squareup.okhttp3:okhttp:4.12.0")

debugImplementation("androidx.compose.ui:ui-tooling")

testImplementation("junit:junit:4.13.2")
}
1 change: 1 addition & 0 deletions app/proguard-rules.pro
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
# Project specific ProGuard rules.
Loading