The note app that remembers for you.
Capture anything. Let AI organize it. Watch the right notes resurface at the right time.
- Philosophy
- Features
- How It Works
- Tech Stack
- Getting Started
- Configuration
- Project Structure
- Architecture
- Testing
- Troubleshooting
- Contributing
- License
Information should fade by default — only ideas that prove their value deserve permanence.
| Traditional Note Apps | Recall |
|---|---|
| Everything is equally important forever | Most thoughts are temporary — the system decides what survives |
| You organize everything manually | AI organizes, you just capture |
| Notes sit forgotten in folders | Important ideas resurface automatically |
| Filing cabinet | Living memory |
That philosophical difference is everything.
| Mode | Description |
|---|---|
| Text | Type with auto-save (600ms debounce) |
| Voice | Record audio → automatic transcription |
| Camera | Take photos → ML Kit OCR extracts text |
| Share | Share from any app directly into Recall |
When you save a note, it flows through an intelligent pipeline:
Input (text/voice/image)
↓
Transcription (audio → text)
↓
OCR (image → text via ML Kit)
↓
LLM Analysis (Claude Haiku)
↓
Summary + Type + Topics + Entities + Action Items
↓
Stored & Indexed
Notes are auto-categorized as:
- Task — Action items detected
- Idea — Creative thoughts (boosted after 21 days for incubation)
- Reference — Information to look up later
- Journal — Personal reflections
- Question — Things to explore
- Quote — Words from others
Every note moves through four cognitive states over time:
| State | Memory Strength | What User Sees |
|---|---|---|
| Fresh | > 3.0 | Full note + transcript + OCR |
| Condensed | 2.0 – 3.0 | Summary + key entities |
| Faded | 1.0 – 2.0 | Title + 1-line essence |
| Dormant | < 1.0 | Invisible unless searched |
Memory Strength Formula:
memory_strength = resurfacing_score - decay_pressure(time)
decay_pressure = days_since_last_interaction × 0.03
Notes earn their way upward through:
- User opens/edits note
- User pins or promotes
- AI detects relevance to recent notes
- Appears in Daily Recall and isn't dismissed
Notes fade faster when:
- Ignored when resurfaced
- Explicitly dismissed
- No semantic connections over time
A calm, non-intrusive way to reconnect with your past thoughts:
┌─────────────────────────────────────────────┐
│ "An idea from 6 weeks ago (fading)" │
│ │
│ You once wrote about teaching creativity │
│ through constraints. │
│ │
│ [ Revisit ] [ Let fade ] [ This matters ]│
└─────────────────────────────────────────────┘
- Full-text search (Room FTS4)
- Semantic search via embeddings
- Filters: type, attachments, date range, archived
- TXT or Markdown format
- Includes all metadata, transcripts, OCR text
- Share directly to other apps
- No hardcoded API keys — loaded from
local.propertiesvia BuildConfig - Rate limiting — Token bucket algorithm for all API calls
- Input validation — OWASP-compliant sanitization
- Secure logging — No PII or secrets logged
A nightly job (2:30 AM) calculates a resurfacing score for each note:
Base: random(0..1)
Modifiers:
+2.0 if pinned
+1.5 if task with unfinished items
+1.0 if idea older than 21 days (incubation boost)
+1.0 if importance ≥ 2
+0.5 if AI processed
-1.0 if shown in last 3 days
-0.5 if archived
-∞ if marked "never resurface"
Top 3-7 notes shown daily. Dormant notes (memory_strength < 1.0) are excluded.
At any time, the user can:
- Search for any note (including dormant)
- Restore full note detail
- Pin permanently
- Export everything
Nothing is ever destroyed without consent.
| Technology | Purpose |
|---|---|
| Kotlin | Language |
| Jetpack Compose | UI Framework |
| Material 3 | Design System |
| Hilt | Dependency Injection |
| Room | Local Database |
| DataStore | Preferences |
| WorkManager | Background Jobs |
| OkHttp/Retrofit | Networking |
| ML Kit | On-device OCR |
| Technology | Purpose |
|---|---|
| Supabase | Auth, Database, Storage |
| PostgreSQL | Primary Database |
| Row Level Security | Data Protection |
| pgvector | Embeddings Storage |
| Technology | Purpose |
|---|---|
| Anthropic Claude (Haiku) | Classification, Summarization |
| Google ML Kit | On-device OCR |
| Embeddings | Semantic Search |
- Android Studio Hedgehog (2023.1.1) or later
- JDK 17+
- Android SDK 26+ (min), 34 (target)
-
Clone the repository
git clone https://github.com/your-username/Memory-App.git cd Memory-App -
Configure API keys
cp local.properties.example local.properties
-
Edit
local.propertieswith your credentials (see Configuration) -
Open in Android Studio and sync Gradle
-
Run the app (
▶️ orShift+F10)
Create a local.properties file in the project root with the following:
| Variable | Required | Description | Source |
|---|---|---|---|
SUPABASE_URL |
Yes | Your Supabase project URL | Supabase Dashboard → Settings → API |
SUPABASE_ANON_KEY |
Yes | Supabase anonymous key | Same as above |
ANTHROPIC_API_KEY |
No* | Anthropic API key for AI features | Anthropic Console |
POSTHOG_API_KEY |
No | PostHog analytics key | PostHog |
SENTRY_DSN |
No | Sentry error tracking DSN | Sentry |
*Without Anthropic API key, AI features (auto-categorization, summaries) will be disabled but the app remains fully functional.
Example local.properties:
sdk.dir=/path/to/android/sdk
SUPABASE_URL=https://your-project.supabase.co
SUPABASE_ANON_KEY=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...
ANTHROPIC_API_KEY=sk-ant-api03-...app/src/main/java/com/recall/app/
├── core/
│ ├── auth/ # Supabase authentication (AuthManager)
│ ├── security/ # Rate limiter, input validator, config
│ ├── analytics/ # PostHog + Sentry integration
│ ├── export/ # Note export functionality
│ ├── media/ # Audio recording, image handling
│ ├── ocr/ # ML Kit OCR processing
│ ├── share/ # Share intent handling
│ └── util/ # Extensions, constants, Result type
├── data/
│ ├── local/ # Room database, DAOs, entities
│ ├── remote/ # Supabase data sources, DTOs
│ ├── repository/ # Repository implementations
│ ├── mapper/ # Entity ↔ Domain mappers
│ └── preferences/ # DataStore preferences
├── domain/
│ ├── model/ # Note, Attachment, AiMetadata, MemoryState
│ ├── repository/ # Repository interfaces
│ └── usecase/ # Business logic (ResurfaceScore, MemoryStrength, Search)
├── ai/
│ ├── client/ # LLM clients (Anthropic, Embeddings, Transcription)
│ ├── config/ # API configuration
│ ├── processor/ # Note processing pipeline
│ └── prompts/ # AI prompt templates
├── sync/
│ ├── workers/ # WorkManager jobs (Sync, Upload, AI, Resurface)
│ └── SyncScheduler # Job scheduling
├── ui/
│ ├── screens/ # Compose screens (Home, Capture, Detail, DailyRecall, Search, Settings)
│ ├── components/ # Reusable UI components
│ ├── theme/ # Material 3 theming
│ └── navigation/ # Navigation graph
├── di/ # Hilt dependency injection modules
├── MainActivity.kt
└── RecallApplication.kt
Recall follows Clean Architecture with MVVM pattern:
┌─────────────────────────────────────────────────────────┐
│ UI Layer │
│ (Compose Screens, ViewModels, Navigation) │
└─────────────────────────────────────────────────────────┘
│
▼
┌─────────────────────────────────────────────────────────┐
│ Domain Layer │
│ (Use Cases, Repository Interfaces, Domain Models) │
└─────────────────────────────────────────────────────────┘
│
▼
┌─────────────────────────────────────────────────────────┐
│ Data Layer │
│ (Repository Impl, Room DB, Supabase, DataStore) │
└─────────────────────────────────────────────────────────┘
Key Principles:
- Unidirectional Data Flow — State flows down, events flow up
- Single Source of Truth — Room database for local data
- Offline-First — Full functionality without network
- Dependency Injection — Hilt for testability
./gradlew assembleDebug./gradlew test./gradlew connectedAndroidTestContributions are welcome! Please follow these guidelines:
- Fork the repository
- Create a feature branch:
git checkout -b feature/your-feature - Make your changes
- Run tests:
./gradlew test - Commit with clear messages:
git commit -m "feat: Add your feature" - Push to your fork:
git push origin feature/your-feature - Open a Pull Request
We use Conventional Commits:
| Type | Description |
|---|---|
feat: |
New feature |
fix: |
Bug fix |
docs: |
Documentation |
style: |
Formatting (no code change) |
refactor: |
Code restructuring |
test: |
Adding tests |
chore: |
Maintenance |
- Follow Kotlin Coding Conventions
- Use meaningful variable/function names
- Keep functions small and focused
- Add KDoc for public APIs
This project is licensed under the MIT License - see the LICENSE file for details.
- Jetpack Compose — Modern Android UI
- Supabase — Open source Firebase alternative
- Anthropic — Claude AI models
- Google ML Kit — On-device ML
Built with ❤️ using Kotlin & Jetpack Compose
You don't manage your notes. Your notes manage themselves.