{"id":35196812,"url":"https://github.com/tonimadev/kairos-android-app","last_synced_at":"2026-04-01T16:45:08.530Z","repository":{"id":315696372,"uuid":"1060461448","full_name":"tonimadev/kairos-android-app","owner":"tonimadev","description":"Kairós is a modern Android application designed to ensure you never miss a calendar event again. It intelligently syncs with your device's calendar and turns your appointments into unmissable, full-screen alarms, similar to a native alarm clock.","archived":false,"fork":false,"pushed_at":"2026-03-25T14:37:52.000Z","size":5577,"stargazers_count":6,"open_issues_count":5,"forks_count":1,"subscribers_count":0,"default_branch":"master","last_synced_at":"2026-03-26T05:09:20.054Z","etag":null,"topics":["alarmmanager","android","artificial-intelligence","calendar","jetpack-compose","kotlin","material-design","mvvm-architecture","wear-os","wearable","wearable-devices","wearos","workmanager"],"latest_commit_sha":null,"homepage":"","language":"Kotlin","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/tonimadev.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2025-09-20T00:48:18.000Z","updated_at":"2026-03-26T04:45:19.000Z","dependencies_parsed_at":"2025-09-20T06:22:19.340Z","dependency_job_id":"f9688c5b-0fcb-4c4c-9d7d-846f8090cdd6","html_url":"https://github.com/tonimadev/kairos-android-app","commit_stats":null,"previous_names":["ipirangad3v/kairos-android-app","tonimadev/kairos-android-app"],"tags_count":53,"template":false,"template_full_name":null,"purl":"pkg:github/tonimadev/kairos-android-app","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/tonimadev%2Fkairos-android-app","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/tonimadev%2Fkairos-android-app/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/tonimadev%2Fkairos-android-app/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/tonimadev%2Fkairos-android-app/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/tonimadev","download_url":"https://codeload.github.com/tonimadev/kairos-android-app/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/tonimadev%2Fkairos-android-app/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":31290538,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-04-01T13:12:26.723Z","status":"ssl_error","status_checked_at":"2026-04-01T13:12:25.102Z","response_time":53,"last_error":"SSL_read: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["alarmmanager","android","artificial-intelligence","calendar","jetpack-compose","kotlin","material-design","mvvm-architecture","wear-os","wearable","wearable-devices","wearos","workmanager"],"created_at":"2025-12-29T07:40:09.654Z","updated_at":"2026-04-01T16:45:08.525Z","avatar_url":"https://github.com/tonimadev.png","language":"Kotlin","funding_links":[],"categories":[],"sub_categories":[],"readme":"\u003cimg src=\"/images/kairos-banner.png\" width=\"1024\" height=\"500\"\u003e\n\n[![Android CI - Kairos Multi-Module](https://github.com/tonimadev/kairos-android-app/actions/workflows/android-ci.yaml/badge.svg)](https://github.com/tonimadev/kairos-android-app/actions/workflows/android-ci.yaml) [![codecov](https://codecov.io/gh/tonimadev/kairos-android-app/graph/badge.svg?token=TKC92HM5VY)](https://codecov.io/gh/tonimadev/kairos-android-app)\n\n# Kairós - Calendar Alarms for Android \u0026 Wear OS powered by Gemini AI\n\nKairós is a modern application that transforms your calendar appointments into unmissable full-screen alarms, both on your smartphone and on your wrist with **Wear OS**. It intelligently synchronizes with the device's calendar and ensures you never miss an important event.\n\n## 🚀 Download\n\n\u003ca href='https://play.google.com/store/apps/details?id=digital.tonima.kairos' target=\"_blank\" rel=\"noopener noreferrer\"\u003e\u003cimg alt='Get it on Google Play' src='https://play.google.com/intl/en_us/badges/static/images/badges/en_badge_web_generic.png' width='200'/\u003e\u003c/a\u003e\n\n---\n\n## ✨ Key Features\n\n- **Full-Screen Alarms**: Wakes the device even when locked with visual and sound alerts (Smartphone and Wear OS).\n- **Full Wear OS Integration**:\n  - **Complications**: View the next event directly on the watch face.\n  - **Tiles**: Instant access to event information with a side swipe.\n- **Smart Synchronization**: Uses WorkManager for efficient background scheduling without draining the battery.\n- **Native Integration**: Reads events from any calendar account configured on the device (e.g., Google Calendar).\n- **Total Control**: Enable or disable alarms globally or for specific events.\n\n\u003cp align=\"center\"\u003e\n  \u003cimg src=\"/images/watch1.png\" width=\"200\"\u003e\n  \u003cimg src=\"/images/watch2.png\" width=\"200\"\u003e\n  \u003cimg src=\"/images/tile.gif\" width=\"300\"\u003e\n\u003c/p\u003e\n\n---\n\n## 🛠 Tech Stack\n\nThis project follows modern Android development principles with MVVM + MVI architecture.\n\n- **Language**: 100% Kotlin\n- **UI**: Jetpack Compose (Phone \u0026 Wear OS)\n- **Architecture**: MVVM + MVI, Clean Architecture, Multi-module\n- **Async**: Kotlin Coroutines + Flow\n- **Persistence \u0026 Background**: DataStore, WorkManager, AlarmManager\n- **DI**: Hilt\n- **AI**: Firebase AI (Gemini) with Function Calling\n- **Sync**: Wearable Data Layer (Play Services)\n- **Testing**: JUnit4, Robolectric, Turbine, MockK\n\n---\n\n## 🏗 Architecture\n\n### Multi-Module Structure\n\n```\nkairos-android-app/\n├── app/          → Phone UI (Compose), Activity, Receivers\n├── core/         → Shared business logic, ViewModels, UseCases, Repositories\n├── wear/         → Wear OS UI, Tiles, Complications\n├── build-logic/  → Convention plugins (Jacoco, etc.)\n└── gradle/       → Version catalog (libs.versions.toml)\n```\n\n### MVVM + MVI Pattern\n\nThe app uses **unidirectional data flow** across all features:\n\n```\nView (Compose) ──EventIntent──▶ ViewModel ──▶ UseCases / Repositories\n       ▲                            │\n       │                            ▼\n       └──── UiState (StateFlow) ───┘\n             SideEffect (Channel)\n```\n\n- **`EventIntent`** — sealed class representing every user action.\n- **`EventScreenUiState`** — single immutable state driving the UI.\n- **`EventSideEffect`** — one-shot events (snackbar, navigation, confirmation dialogs).\n- **`EventViewModel`** — processes intents, delegates to UseCases, emits state \u0026 effects.\n\n### Core Module Packages\n\n| Package | Responsibility |\n|---|---|\n| `viewmodel` | ViewModels, Intents, UiState, SideEffects, UiText |\n| `usecases` | Business logic (one class per action) |\n| `repository` | Data access (Calendar, Weather, Preferences, etc.) |\n| `model` | Domain entities (Event, AlarmOffset, Weather, etc.) |\n| `service` | AlarmScheduler, Workers |\n| `ai` | AI Agent architecture (see below) |\n| `analytics` | Firebase Analytics abstraction |\n\n---\n\n## 🤖 AI Agent Architecture\n\nThe app integrates an **AI Agent** powered by Gemini (Firebase AI) that can **execute actions** in the app via Function Calling. Instead of modifying the UI or database directly, the AI dispatches **MVI Intents** — exactly as if the user had tapped a button.\n\n### How It Works\n\n```\nUser question ──▶ AskAiAgentUseCase (Gemini + Tool declarations)\n                        │\n              ┌─────────┴─────────┐\n              ▼                   ▼\n        Text response      FunctionCall response\n        (show to user)            │\n                                  ▼\n                        onAIFunctionCalled()\n                                  │\n                                  ▼\n                        ActionRegistry.processAIToolCall()\n                                  │\n                    ┌─────────────┼─────────────┐\n                    ▼             ▼              ▼\n                  SAFE        MODERATE       CRITICAL\n               (execute)   (execute +     (pause, ask\n                           snackbar)      user to confirm)\n```\n\n### Risk Levels\n\n| Level | Behavior | Example |\n|---|---|---|\n| `SAFE` | Executes immediately, no feedback | `SearchTool` → search events |\n| `MODERATE` | Executes immediately + snackbar notification | `ToggleGlobalAlarmsTool` → toggle alarms |\n| `CRITICAL` | Pauses, saves intent in `pendingAIAction`, requires explicit user confirmation | `CreateEventTool` → create calendar event |\n\n### Key Components\n\n| Component | Role |\n|---|---|\n| `AITool` | Interface — each tool maps an LLM function call to an `EventIntent` |\n| `ActionRegistry` | Singleton — discovers tools, dispatches function calls |\n| `AskAiAgentUseCase` | Sends the prompt + tool declarations to Gemini, returns `Text` or `FunctionCall` |\n| `RiskLevel` | Enum controlling execution policy (`SAFE`, `MODERATE`, `CRITICAL`) |\n| `AIToolResult` | Sealed class wrapping dispatch results (`Success`, `ToolNotFound`, `InvalidArguments`) |\n\n### How to Create a New AI Tool\n\n**Step 1 —** Create a class implementing `AITool` in `core/.../ai/tools/`:\n\n```kotlin\nclass MyNewTool @Inject constructor() : AITool {\n\n    override val name = \"my_new_action\"\n\n    override val description = \"Describe when the LLM should call this tool.\"\n\n    override val riskLevel = RiskLevel.SAFE // or MODERATE / CRITICAL\n\n    override val parametersSchema = mapOf(\n        \"type\" to \"object\",\n        \"properties\" to mapOf(\n            \"param1\" to mapOf(\"type\" to \"string\", \"description\" to \"…\"),\n        ),\n        \"required\" to listOf(\"param1\"),\n    )\n\n    override fun parseArguments(args: Map\u003cString, Any?\u003e): EventIntent? {\n        val value = args[\"param1\"]?.toString() ?: return null\n        return EventIntent.SomeExistingIntent(value)   // reuse an MVI intent\n    }\n}\n```\n\n**Step 2 —** Register it in `AIToolsModule` (`core/.../ai/di/`):\n\n```kotlin\n@Provides @IntoSet @Singleton\nfun provideMyNewTool(): AITool = MyNewTool()\n```\n\n**Step 3 —** Done. `ActionRegistry` discovers it automatically via Hilt multibinding, includes it in the Gemini tool declarations, and routes function calls through `onAIFunctionCalled()`.\n\n\u003e **Tip:** Choose `RiskLevel` carefully — `SAFE` executes silently, `MODERATE` shows a snackbar, and `CRITICAL` pauses for user confirmation.\n\n---\n\n## 🏁 Getting Started\n\n### Prerequisites\n- Android Studio Jellyfish+\n- JDK 21\n- Android SDK 36 (Compile/Target)\n\n### Installation and Execution\n1. Clone the repository:\n   ```bash\n   git clone https://github.com/tonimadev/kairos-android-app.git\n   ```\n2. Open in Android Studio and wait for Gradle synchronization.\n3. To run via CLI:\n   - **Phone**: `./gradlew :app:installDebug`\n   - **Wear OS**: `./gradlew :wear:installDebug`\n\n### Testing and Quality\n- Run all unit tests: `./gradlew testDebugUnitTest`\n- Generate coverage report (Jacoco): `./gradlew createJacocoMergedCoverageReport`\n- Apply code style: `./gradlew spotlessApply`\n\n---\n\n## ⚙️ Additional Configuration\n\nFor **Release** builds or full **Firebase/AdMob** integration, it is necessary:\n1. Add `google-services.json` in `app/` and `wear/` folders.\n2. Configure signing keys and ad IDs in `local.properties` or environment variables. See `build.gradle.kts` for details on expected properties.\n\n---\n\n## 🤝 Contributing\nContributions are welcome! Make sure to run `./gradlew spotlessApply` before opening a Pull Request.\n\n---\nDeveloped by **tonimadev**\n\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ftonimadev%2Fkairos-android-app","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Ftonimadev%2Fkairos-android-app","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ftonimadev%2Fkairos-android-app/lists"}