Wenlan
Wenlan is a source-backed AI knowledge base and LLM wiki for AI work: organize documents and decisions into pages you can find, inspect, and review.
Protect your morning window. Finish your goal first, then catch up on notifications in one digest.
Translation pending
ProductivityKotlin · SwiftGitHub @kennethteh90Availability needs another checkOwner unconfirmed
Have you tried it? One tap is enough. No sign-in needed.
Open-source phone morning gate: notification digest, app shields, verifiable goals, emergency bypass
Translation pending
Loading the full README.
Read the full README ↗Open-source morning routine app for Android and iOS. Android holds non-alarm notifications in a single digest until you complete a verifiable goal; iOS shields apps you choose via Screen Time APIs (see platform notes below). Both support optional alarm, emergency bypass, and morning goals (Bible, focus, steps).
Architecture: Android :core:domain (pure Kotlin) + :core:data / :app; iOS MorningGuardCore Swift package mirrors domain rules — see docs/PLAN-IOS.md. iOS uses Screen Time shields (no notification digest). Store privacy: docs/app-store-privacy-labels.md. Android notification listener: docs/play-notification-listener-compliance.md.
SwiftUI app and Screen Time extensions live under ios/. See ios/README.md for XcodeGen, signing, and device testing.
Install Android SDK 35 and JDK 17.
Copy local.properties.example to local.properties and set sdk.dir.
Optional: SUPABASE_URL, SUPABASE_ANON_KEY, SENTRY_DSN, GOOGLE_WEB_CLIENT_ID.
Bible chapters: deploy workers/bible-cache, set worker secrets (API_BIBLE_KEY, Play Integrity / App Attest config, optional legacy BIBLE_PROXY_TOKEN during rollout). In local.properties set BIBLE_PROXY_BASE_URL and PLAY_CLOUD_PROJECT_NUMBER (Android). The app never embeds API_BIBLE_KEY. Open translations (WEB/KJV) use the proxy without client secrets; NIV/NKJV/NLT require Play Integrity (Android) or App Attest on device (iOS). Without the proxy, only free bible-api.com translations work from the phone.
Verse numbering gaps: Some licensed translations (e.g. NIV) omit verses that are not in their base text (John 5:4 is a common example). API.Bible supplies a verse marker with no body; the app skips empty verses, so chapter view may jump (e.g. 3 → 5). That matches the translation, not a sync bug. Open translations such as WEB/KJV may still show those verses.
Open in Android Studio or run:
./gradlew test lint detekt assembleFullDebug
**Demo presenter app** (separate package `com.morningguard.app.demo`, scenario picker): `./gradlew :app:assembleDemoDebug` then `./scripts/serve-phone-apk.sh --demo` to install over Wi‑Fi.
Grant Notification access in system settings for the listener service.
keytool -genkey -v \
-keystore "$HOME/morning-guard-release.keystore" \
-alias morning-guard \
-keyalg RSA -keysize 2048 -validity 10000 \
-dname "CN=Morning Guard, OU=Dev, O=You, L=City, ST=State, C=US"
Add to local.properties (see local.properties.example): RELEASE_STORE_FILE, RELEASE_STORE_PASSWORD, RELEASE_KEY_ALIAS, RELEASE_KEY_PASSWORD.
Build a signed release APK:
./gradlew assembleRelease
Output: app/build/outputs/apk/release/app-release.apk (signed when the four RELEASE_* properties are set).
Install: adb install -r app/build/outputs/apk/release/app-release.apk, or copy the APK to the phone and allow installs from that source.
Back up the keystore and passwords. You need the same key for Play Store updates later.
morningguard://auth (required; matches the app manifest).https://morning-guard.codingagents.cc after deploying site/auth-landing.local.properties as SUPABASE_URL and SUPABASE_ANON_KEY.The app requests OTP with redirectUrl = morningguard://auth so links prefer opening the app directly.
Cloud schema (stats/highlights sync): see docs/supabase/SETUP.md and supabase/migrations/.
Launch checklist: site/play-store-launch/index.html (markdown). Play Console fill-in: docs/play-console-fill-in.md. Agent handoff (Grok): docs/grok-play-console-handoff.md. Public site + privacy policy: deploy site/auth-landing to https://morning-guard.codingagents.cc (PRIVACY_POLICY_URL=https://morning-guard.codingagents.cc/privacy/).
Store screenshots (plan → screenshot build capture → screenshot-studio): docs/store-screenshots.md — run ./scripts/store-screenshots/orchestrate.sh with a device connected (--ai optional).
Upload AAB from app/build/outputs/bundle/fullRelease/ (see checklist). Store releases are built via the Release workflow (see below).
.github/workflows/ci.yml): test, detekt, lint on PRs and pushes to main..github/workflows/release.yml): signed bundleFullRelease when version.properties changes on main (Play internal completed) or manual dispatch — see docs/cloud-release.md.Push secrets from your Mac local.properties (never commit values):
./scripts/push-github-secrets.sh --dry-run
./scripts/push-github-secrets.sh
Full secret list, Play service account setup, and triggers: docs/cloud-release.md.
CI builds work without secrets (Supabase shows as unconfigured in those APKs). Add secrets before you need signed release bundles or Play upload in Actions.
Magic-link browser fallback: deploy site/auth-landing with ./site/auth-landing/deploy.sh (Cloudflare Pages).
Semantic version in version.properties → versionName / versionCode.
Apache-2.0 — see LICENSE.