token + clipper — an unofficial web clipper for Obsidian on Android.
Clip any web page (and Bilibili transcripts) into clean Markdown, straight into your vault.
Unofficial project — not affiliated with Obsidian.
English | 简体中文
- Four capture entry points — type or paste a URL, system share sheet (
SENDtext/html), select-to-clip (PROCESS_TEXT), or open links (VIEWhttp/https) - Clean extraction — pages render in a real System WebView, extracted by the Defuddle bundle into a read-only Markdown preview
- Bilibili transcripts — automatic subtitle pipeline for video pages, login-aware
- Site accounts — per-site login management with cookie probes; Bilibili & Zhihu built in, every site editable/deletable, add your own (WebView login flow, per-site UA)
- History — every clip persisted locally (
clipper_history/*.json), with delete / undo / clear - Save to Obsidian —
obsidian://newwith clipboard handoff, path templates ({{year}} {{month}} {{day}} {{date}} {{date:YYYY/MM/DD}} {{title}}), vault selection, Web Clipper template JSON import - Liquid glass Dock — real backdrop sampling + AGSL edge refraction on API 33+, graceful fallback on older devices
- Dark mode, zh/en bilingual, Android 8.0+ (minSdk 26)
| Kotlin | 2.0.21 (Compose & serialization plugins pinned) |
| AGP / Gradle | 8.6.1 / 8.8 (wrapper auto-downloads) |
| JDK | 17 |
| compileSdk / targetSdk / minSdk | 35 / 35 / 26 |
| Jetpack Compose | BOM 2026.06.01 (material3 1.4.0) |
| kotlinx-serialization-json | 1.7.3 |
⚠️ The toolchain is frozen (docs/DECISION_LOG.md, D13): bumping Kotlin/AGP/Compose breaks the chain (AAR metadata hard-fails). Read the decision log before touching versions.
- Open the repository root in Android Studio (≥ Koala Feature Drop, required by AGP 8.6)
- Wait for Gradle sync (first run downloads Gradle 8.8 + dependencies and generates
local.properties) - Run the
appdebug configuration
Prerequisites: JDK 17 + Android SDK (Platform 35 / Build-Tools 34.0.0 / platform-tools). macOS example:
brew install --cask temurin@17 # any JDK 17 distribution works
brew install --cask android-commandlinetools
sdkmanager "platform-tools" "platforms;android-35" "build-tools;34.0.0"
echo "sdk.dir=$ANDROID_HOME" > local.properties # machine-local, not committed
export JAVA_HOME=$(/usr/libexec/java_home -v 17)
./gradlew :app:assembleDebug # → app/build/outputs/apk/debug/app-debug.apk
adb install -r app/build/outputs/apk/debug/app-debug.apkDebug builds are auto-signed with ~/.android/debug.keystore — installable out of the box. Release signing, version policy and the full publish checklist (incl. GitHub Releases) live in docs/RELEASE.md.
app/src/main/assets/defuddle.full.js is committed — a normal build needs no Node. Rebuild only when changing the extraction engine itself:
# Sibling checkout at ../toklip/defuddle is picked up automatically by copyDefuddleBundle
cd ../toklip/defuddle && npm ci && npm run build:jsdefuddle.full.js and clipper-bridge.js form the two sides of bridge contract v1 and must change in the same commit (see AGENTS.md §2).
./gradlew :app:testDebugUnitTest # JVM logic tests (Robolectric-free)
./gradlew :app:connectedDebugAndroidTest # instrumentation (device required)
./scripts/behavior-compare.sh --install # 24-assertion on-device regression — must be ALL PASS- AGENTS.md — project discipline; read before contributing
- docs/RELEASE.md — build, signing, Debug/Release, versioning, GitHub Releases
- docs/DECISION_LOG.md — decision ledger (why the toolchain is frozen, etc.)
- docs/design/logo/ — logo design sources (SVG)