Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
52 commits
Select commit Hold shift + click to select a range
b463a5a
docs: add Tailwind v4 migration design spec
pavi2410 May 7, 2026
de95ee3
docs: add tailwind v4 migration implementation plan
pavi2410 May 7, 2026
a877ed5
chore: replace app icons with Kodular squircle icon
pavi2410 May 7, 2026
4e70b33
feat: install tailwindcss v4 with vite plugin
pavi2410 May 7, 2026
c5bb037
feat: replace main.css with tailwind v4 imports and theme tokens
pavi2410 May 7, 2026
32cd652
feat: migrate App.tsx to tailwind v4 utility classes
pavi2410 May 7, 2026
c1969f0
feat: migrate SettingsPanel.tsx to tailwind v4 utility classes
pavi2410 May 7, 2026
1106428
feat: apply MDL 2 minimal style to settings panel
pavi2410 May 7, 2026
25edf83
fix: disable overscroll effect globally
pavi2410 May 7, 2026
95a49b1
fix: done button gray outline with gray hover background
pavi2410 May 7, 2026
48935da
fix: make settings toggle button square
pavi2410 May 7, 2026
dd5d0bd
fix: reduce button and input height to py-1.5
pavi2410 May 7, 2026
d722f6f
refactor: extract Button, Field, Input, Select into src/components
pavi2410 May 7, 2026
0cbcff2
refactor: extract IconButton component, use in App.tsx
pavi2410 May 7, 2026
45827dc
fix: visible outlined button border; group Save+Done on right; async …
pavi2410 May 7, 2026
4b4cdc6
docs: add CLAUDE.md with architecture overview and dev commands
pavi2410 May 7, 2026
4613c78
fix: add cn util, move border-none to primary variant so outlined bor…
pavi2410 May 7, 2026
83d92c0
chore: remove unused Android and iOS icon files
pavi2410 May 7, 2026
a338f68
chore: remove legacy migration design and implementation plan for Tai…
pavi2410 May 7, 2026
0147861
feat: add ADB service status badge alongside local server status
pavi2410 May 7, 2026
522d002
refactor: move refreshDetectedPath above useEffect that calls it
pavi2410 May 7, 2026
b7729d5
refactor: remove TCP/WiFi transport — USB only for now
pavi2410 May 7, 2026
d9b3b25
feat: add tauri-plugin-single-instance for single instance applicatio…
pavi2410 May 8, 2026
fb09ba0
fix: bind TCP listener to localhost instead of all interfaces
pavi2410 May 9, 2026
993d46f
feat: restructure ADB settings with smart detection chain and validit…
pavi2410 May 9, 2026
0f8fa6d
ci: add CI workflow and update actions/checkout to v6
pavi2410 May 9, 2026
0ada0db
docs: update CLAUDE.md to reflect current codebase state
pavi2410 May 9, 2026
d6f1e8d
fix: improve settings robustness and ADB path detection correctness
pavi2410 May 9, 2026
e7e97fd
feat: integrate tauri-plugin-log and rename package to kodular-starter
pavi2410 May 9, 2026
fb212e1
feat: replace settings gear emoji with SVG icon using CSS mask
pavi2410 May 9, 2026
64b30f7
refactor: idiomatic Rust cleanup across Rust backend
pavi2410 May 9, 2026
d9f2ed5
refactor: extract route handlers into server_routes module
pavi2410 May 9, 2026
b3df150
refactor: extract Tauri command handlers into tauri_commands module
pavi2410 May 9, 2026
1a65898
refactor: simplify command usage and improve module imports in ADB ha…
pavi2410 May 9, 2026
8890e37
fix: correct package name from starter to kodular-starter in CI and docs
pavi2410 May 9, 2026
3e5192f
perf: collapse 4 getprop shell round trips into 1 in get_device_info
pavi2410 May 9, 2026
43297af
feat: show companion app installation status and version in device info
pavi2410 May 9, 2026
9218b1a
refactor: replace magic addresses with typed const SocketAddrV4 values
pavi2410 May 9, 2026
224b697
refactor: encapsulate useDeviceInfo hook within DeviceInfo component
pavi2410 May 9, 2026
ea0c023
refactor: extract hooks and components from SettingsPanel
pavi2410 May 9, 2026
342d26b
refactor: reorganise components into views/, add #/ import alias
pavi2410 May 9, 2026
39bc405
refactor: replace React Query with nanostores, add app state and ADB …
pavi2410 May 9, 2026
628fa98
refactor: add AdbState::Initialising and replace StatusBadge tristate…
pavi2410 May 9, 2026
241aff5
chore: add lifecycle log statements and minor server cleanup
pavi2410 May 9, 2026
a926b1f
refactor: resolve ADB mode once on startup instead of per-poll
pavi2410 May 9, 2026
2cf0f32
refactor: rename check_adb_validity to test_adb_path
pavi2410 May 9, 2026
cb5f446
refactor: serialize ResolvedAdbMode and remove skip from AppStateInner
pavi2410 May 9, 2026
712ec34
refactor: extract AppStateInner::init and remove redundant store open
pavi2410 May 9, 2026
6fb1c3d
refactor: serve /utest and /replstart from AppState instead of live ADB
pavi2410 May 9, 2026
abd9e35
refactor: simplify poll_adb_state using get_connected_device
pavi2410 May 9, 2026
bcf0aa1
chore: restrict ADB_SERVER_ADDR and try_system_adb visibility to module
pavi2410 May 9, 2026
0bdab36
fix: forward tcp:8001 and use VIEW intent in start_companion
pavi2410 May 9, 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
49 changes: 49 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
name: CI

on:
push:
branches: [main]
pull_request:
branches: [main]

jobs:
ci:
name: Lint, Build & Test
runs-on: ubuntu-latest

steps:
- uses: actions/checkout@v6

- name: Install system dependencies
run: |
sudo apt-get update
sudo apt-get install -y libwebkit2gtk-4.1-dev libappindicator3-dev librsvg2-dev patchelf

- name: Install Rust stable
uses: dtolnay/rust-toolchain@stable
with:
components: clippy

- name: Rust cache
uses: swatinem/rust-cache@v2
with:
workspaces: './src-tauri -> target'

- uses: oven-sh/setup-bun@v2
with:
bun-version: latest

- name: Install frontend dependencies
run: bun install

- name: TypeScript typecheck
run: bun run typecheck

- name: Clippy
run: cargo clippy --manifest-path src-tauri/Cargo.toml -- -D warnings

- name: Build
run: bun run build && cargo build --manifest-path src-tauri/Cargo.toml

- name: Test
run: cargo test --manifest-path src-tauri/Cargo.toml -p kodular-starter
2 changes: 1 addition & 1 deletion .github/workflows/publish.yml
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ jobs:
runs-on: ${{ matrix.platform }}

steps:
- uses: actions/checkout@v4
- uses: actions/checkout@v6

- name: install dependencies (ubuntu only)
if: matrix.platform == 'ubuntu-latest'
Expand Down
75 changes: 75 additions & 0 deletions CLAUDE.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
# CLAUDE.md

This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.

## What This Is

Kodular Starter is a desktop app (Tauri v2 + React) that enables live USB testing of Kodular/MIT App Inventor apps. It exposes a local HTTP server on port 8004 that the Kodular web IDE communicates with, and bridges to an Android device via ADB (system or built-in `adb_client` crate).

## Commands

**Frontend dev (Vite only, no Tauri):**
```
bun run dev
```

**Full Tauri app (frontend + Rust backend):**
```
bunx tauri dev
```

**Build for production:**
```
bunx tauri build
```

**Type-check TypeScript:**
```
bun run typecheck
```

**Run Rust tests (requires a USB-connected Android device):**
```
cargo test -p kodular-starter -- --nocapture
```

## Architecture

### Frontend (`src/`)

- **`hooks.ts`** — Two React Query hooks, both polling every 3 seconds:
- `useServerStatus()` — pings `http://localhost:8004/ping` to check if the local axum server is up
- `useDeviceInfo()` — calls Tauri command `device_info` to get connected Android device details
- **`App.tsx`** — Root component; shows device connection state and a toggleable settings panel
- **`SettingsPanel.tsx`** — Calls Tauri commands `get_settings`, `save_settings`, `detect_adb_path`, and `pick_adb_path` to manage ADB configuration
- **`components/`** — Small UI primitives (Button, Field, Input, Select, IconButton, StatusBadge) with Tailwind v4 styling
- **`lib/cn.ts`** — `cn()` utility combining `clsx` + `tailwind-merge` for conditional class names

### Backend (`src-tauri/src/`)

- **`lib.rs`** — Tauri command handlers exposed to the frontend. Spawns the axum server on startup. Registers `tauri-plugin-single-instance` (refocuses the existing window on duplicate launch). Commands: `device_info`, `adb_status`, `get_settings`, `save_settings`, `pick_adb_path`, `detect_adb_path`, `test_adb_path`.
- **`adb_commands.rs`** — ADB logic. Supports two modes via `AdbMode` enum:
- `Auto`: tries system ADB first (via `ADBServer`), falls back to built-in USB (`ADBUSBDevice`)
- `Builtin`: only uses `ADBUSBDevice` (no system adb required)
- **`adb_resolver.rs`** — ADB binary resolution. `resolve_external_adb_path` walks custom path → `$ANDROID_HOME/platform-tools` → `$ANDROID_SDK_ROOT/platform-tools`, returning `None` to fall back to `$PATH`. `detect_adb_path` extends this with a full `$PATH` search for UI display. `test_adb_path` tests a binary by running `adb version`.
- **`server.rs`** — Axum HTTP server on `0.0.0.0:8004`. Key endpoints:
- `/ping`, `/reset` — liveness check
- `/utest`, `/ucheck` — device connection status (returns serial number)
- `/replstart/{deviceid}` — launches the Kodular companion app on device
- `/settings` — returns current app settings as JSON
- CORS is restricted to `*.kodular.io` origins
- **`settings.rs`** — Reads/writes `AppSettings` (adb_mode + custom_adb_path) using `tauri-plugin-store` (persisted to `settings.json` in the app data directory)

### Key Data Flow

Web IDE (starter.kodular.io) → HTTP to localhost:8004 → axum server → ADB → Android device

Tauri frontend ↔ Tauri commands (invoke) ↔ Rust backend

### Styling

Tailwind CSS v4 via the `@tailwindcss/vite` plugin. Theme tokens are defined in `src/main.css`. No `tailwind.config.js` — configuration is done in CSS using `@theme`.

### Fonts

Uses `Jost` variable font from `@fontsource-variable/jost`.
158 changes: 120 additions & 38 deletions bun.lock

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion index.html
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
<html lang="en">
<head>
<meta charset="UTF-8" />
<link rel="icon" href="/favicon.ico" />
<link rel="icon" href="/icon.ico" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Kodular Starter</title>
<link rel="stylesheet" href="src/main.css" />
Expand Down
18 changes: 15 additions & 3 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,21 +1,33 @@
{
"name": "starter",
"name": "kodular-starter",
"private": true,
"version": "0.1.0",
"type": "module",
"imports": {
"#/*": "./src/*"
},
"scripts": {
"typecheck": "tsc --noEmit",
"dev": "vite",
"build": "tsc && vite build",
"preview": "vite preview",
"tauri": "tauri"
},
"dependencies": {
"@fontsource-variable/jost": "^5.2.8",
"@tanstack/react-query": "^5.100.9",
"@nanostores/react": "^1.1.0",
"@tailwindcss/vite": "^4.2.4",
"@tauri-apps/api": "^2.11.0",
"@tauri-apps/plugin-dialog": "^2.7.1",
"@tauri-apps/plugin-log": "^2.8.0",
"@tauri-apps/plugin-opener": "^2.5.4",
"@tauri-apps/plugin-store": "^2.4.3",
"clsx": "^2.1.1",
"nanostores": "^1.3.0",
"react": "^19.2.5",
"react-dom": "^19.2.5"
"react-dom": "^19.2.5",
"tailwind-merge": "^3.5.0",
"tailwindcss": "^4.2.4"
},
"devDependencies": {
"@types/react": "^19.2.14",
Expand Down
Binary file removed public/favicon.ico
Binary file not shown.
Binary file added public/icon.ico
Binary file not shown.
1 change: 1 addition & 0 deletions public/icons/md-settings.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading