Files
tiptoi-sync/.github/copilot-instructions.md
T
arnef 8ef7b9ce8c
CI / Type-Check (push) Successful in 16s
CI / Build Android APK (push) Successful in 5m20s
Flatten repo: move client/ contents to repo root
The project is no longer a monorepo/workspace - there is only a single
app package. Remove the redundant client/ nesting: all source, the
Capacitor Android project, config files and package.json/tsconfig now
live directly at the repo root.

- Merge client/package.json into root package.json (drop the
  workspaces field and the now-unnecessary bun --cwd client wrappers).
- Merge client/bun.lock (the actual dependency lockfile) into the
  root, replacing the stale workspace-only root lockfile.
- Move src/, public/, android/, index.html, vite.config.ts,
  capacitor.config.ts, tsconfig.{app,node}.json to the repo root.
- Update Dockerfile.android to build from the repo root instead of
  cd'ing into client/.
- Update .github/workflows/ci.yml type-check step to run bun run build
  directly instead of bun --cwd client run build.
- Update README.md and .github/copilot-instructions.md to drop
  references to the client/ subdirectory.
- Drop the stale server/downloads/ entry from .gitignore (leftover
  from an old server-based architecture that no longer exists).
2026-08-13 21:52:32 +02:00

4.0 KiB

tiptoi-sync

Android app (Capacitor + SolidJS) for searching, downloading, and syncing tiptoi books onto a tiptoi pen. All book search/download and pen file access happens natively on-device — there is no backend server in this repo despite what README.md's architecture diagram describes (that README is stale/aspirational for a self-hosted server variant; the current implementation is Android-only).

Repository layout

This is a single SolidJS + Vite + Capacitor project (no monorepo/workspace) — all app code lives directly at the repo root.

  • src/api.ts — all "business logic": scraping Ravensburger's search API/HTML for .gme download links, orchestrating download + sync, calling the native plugin.
  • src/native/TiptoiPlugin.ts + src/native/DevPlugin.ts — TypeScript interfaces for Capacitor native plugins (registerPlugin). Any change to the native Kotlin plugin's method signatures must be mirrored here.
  • src/pages/ScanPage.tsx (barcode/text search) and DownloadsPage.tsx (library + pen sync UI).
  • android/ — Capacitor Android project, checked into the repo (not generated on demand). android/app/src/main/java/com/tiptoisync/app/ contains the actual native implementation:
    • TiptoiPlugin.kt — SAF (Storage Access Framework) directory picker for the pen, listing/copying/deleting .gme files on the pen, downloading GME/cover files into app-private storage via HttpURLConnection.
    • DevPlugin.kt — enables Capacitor live-reload against a Vite dev server (see DEV_URL below).
  • Dockerfile.android, build-apk.sh — reproducible APK build via Docker/Podman (no local Android SDK needed). Output APK lands in apk-output/tiptoi-sync.apk.

Build & dev commands

Run from repo root (uses bun):

bun install            # installs deps
bun run dev             # starts Vite dev server with --host
bun run build            # tsc -b && vite build
bun run cap:sync           # copies web build into android/ project
bun run cap:android          # builds & runs on connected device/emulator

There are no unit/integration tests or linters configured in this repo — only TypeScript's compiler (tsc -b, run as part of build) enforces correctness. Validate changes with bun run build, or bunx tsc -b --noEmit for a faster type-only check.

Building the Android APK

./build-apk.sh

Wraps a multi-stage Dockerfile.android build (Bun + Android SDK + Gradle) using Podman or Docker, with --no-cache to avoid stale layers. No local Android SDK/Gradle install required. Result: apk-output/tiptoi-sync.apk.

Live-reload against Vite dev server on a device

DEV_URL=http://<host-ip>:5173 bun run cap:android

capacitor.config.ts reads DEV_URL and switches Capacitor's webview to load from the dev server (with cleartext: true) instead of the bundled dist/ output. DevPlugin.kt/DevPlugin.ts support activating/deactivating this from within the running app (see DevMenu.tsx, triggered by 5 taps on the app title within 2 seconds — see App.tsx).

Key conventions

  • UI copy is German. Keep user-facing strings, comments in api.ts, and section-divider comments (e.g. // ── Suche ──...) in German to match the existing style.
  • Native plugin contract: TypeScript interfaces in src/native/*.ts must stay in sync with @PluginMethod/@CapacitorPlugin definitions in the corresponding Kotlin files — there's no code generation, it's manually kept in sync.
  • All book search scraping logic lives in api.ts (regex-based HTML parsing of Ravensburger's site, HTML entity decoding). If Ravensburger changes their markup, this is the place to fix it.
  • Filenames for downloaded books derive from the last path segment of the GME URL (decoded, .gme stripped); covers reuse the same base name with the cover's own extension.
  • syncAll in api.ts is the single source of truth for "what needs copying to the pen": it diffs local downloads against listPenFiles.