# Fabled — Android App Native Android client for FabledAssistant, a self-hosted AI second-brain and productivity assistant. ## Features - **Daily Briefing** — the primary screen; opens on launch. Shows your AI-compiled morning digest (tasks, calendar, weather, RSS) with a full conversation you can reply to inline. Refresh manually or browse past briefings from the overflow menu. - **Quick Capture** — always-visible input bar above all tabs. Type a note or task and submit; multiple captures queue sequentially so the input is never blocked. Falls back to offline persistence when the server is unreachable. - **Knowledge** — unified browsable feed of notes, people, places, lists, and tasks across six filter tabs. Tag filters, inline search (debounced), and two-tier pagination (ID list → batch hydration). Tasks load from `/api/tasks` directly and are fully integrated with the knowledge feed. - **Chat** — streaming AI conversations with real-time SSE display, including live tool-use status notifications (e.g. "Calling create_note…"). Tap + to start a new conversation or open an existing one. - **Calendar** — month strip + daily agenda view backed by the server's internal event store. Full event CRUD with a modal form: title, all-day toggle, start/end date+time pickers, repeat (None/Daily/Weekly/Monthly/Yearly), description, location, and colour chips. Custom RRULE strings are preserved read-only. - **News** — RSS article feed with per-feed filtering and reactions. Tap "Discuss" to open any article in a new chat conversation. - **Projects** — browse and edit projects; tap a project to see its milestone-grouped task list. - **Voice I/O** — tap the microphone in the capture bar or chat to dictate. Server-side STT transcribes audio; TTS reads assistant replies aloud in voice mode. - **Note & task editing** — full Markdown editor for notes, task editor with due date, priority, project, and milestone assignment. - **OAuth / SSO** — authenticates via your server's OIDC provider; local username/password login also supported if enabled server-side. - **Session persistence** — stays logged in across restarts via a persistent cookie jar. - **Auto-refresh** — data refreshes automatically when the app returns to the foreground (throttled to once per 5 minutes) and when switching between shell tabs. - **Auto-update** — checks your Forgejo releases on launch and prompts to download and install new APKs in-app. ## Requirements - A running FabledAssistant server (self-hosted) - Android 5.0+ (API 21) ## Getting Started ### Prerequisites - Flutter 3.x SDK - Android Studio (for Android SDK and emulator) - JDK 17 ### Setup ```bash flutter pub get flutter run ``` On first launch, enter your FabledAssistant server URL (e.g. `https://fabled.example.com`) and sign in. ## Architecture ``` lib/ ├── main.dart # Entry point; resolves async deps before runApp ├── app.dart # GoRouter + auth guards + 3-tab shell + auto-refresh ├── core/ │ ├── constants.dart # Route name constants │ ├── exceptions.dart # AppException hierarchy │ └── theme.dart # Custom slate-indigo ColorScheme + Fraunces typography ├── data/ │ ├── api/ # Dio HTTP layer (one class per resource) │ │ ├── chat_api.dart # SSE streaming; typed ChatStreamEvent (text/status) │ │ ├── events_api.dart # Calendar event CRUD │ │ ├── knowledge_api.dart # Two-tier paginated knowledge feed │ │ ├── news_api.dart # RSS feed + reactions │ │ └── voice_api.dart # STT + TTS endpoints │ ├── models/ # Plain Dart models with fromJson/toJson │ │ ├── calendar_event.dart # CalendarEvent + dateOnly() helper │ │ ├── knowledge_item.dart # KnowledgeItem (notes/tasks unified) │ │ └── message.dart # Chat message with streaming status │ └── repositories/ # Thin wrappers over API classes ├── providers/ # Riverpod providers (state + dependency wiring) │ ├── briefing_provider.dart # Today's briefing — optimistic UI, SSE, polling │ ├── calendar_provider.dart # CalendarNotifier: month navigation + event CRUD │ ├── chat_provider.dart # Conversations + streaming messages + status │ ├── knowledge_provider.dart # Two-tier pagination; delegates tasks to TasksApi │ ├── news_provider.dart # NewsNotifier + FeedsNotifier │ └── capture_work_queue_provider.dart # Sequential in-memory capture queue ├── screens/ │ ├── briefing/ # BriefingScreen + BriefingHistoryScreen │ ├── calendar/ # CalendarScreen (TableCalendar) + EventFormSheet │ ├── chat/ # ConversationsTabScreen + ChatScreen │ ├── knowledge/ # KnowledgeScreen (6-tab feed + search + tag filters) │ ├── library/ # ProjectTasksScreen (milestone-grouped task list) │ ├── news/ # NewsScreen (feed filter + reactions + discuss) │ ├── notes/ # NoteDetailScreen + NoteEditScreen │ ├── projects/ # ProjectsScreen + ProjectEditScreen │ ├── tasks/ # TaskEditScreen │ └── settings/ auth/ setup/ splash/ └── widgets/ ├── chat_message_bubble.dart # Shared bubble (Chat + Briefing); shows tool status ├── knowledge_item_card.dart # Card for notes, people, places, lists, tasks ├── news_card.dart # RSS article card with reactions └── voice_mic_button.dart # Animated mic button (capture bar + chat) ``` **Key packages:** `flutter_riverpod`, `go_router`, `dio` + `cookie_jar`, `google_fonts`, `flutter_markdown_plus`, `table_calendar`, `record`, `just_audio` ## Building a Release APK ```bash flutter build apk --release ``` The APK will be at `build/app/outputs/flutter-apk/app-release.apk`. ## CI / CD CI and build are defined in a single workflow (`.forgejo/workflows/ci.yml`) running on the shared `py3.12-node22` act runner with the `ghcr.io/cirruslabs/flutter:stable` container. | Trigger | Analyze + Test | Build APK | Release | |---------|---------------|-----------|---------| | PR | ✓ | — | — | | Push `dev` | ✓ | ✓ (artifact `fabledapp-dev-`) | — | | Push `main` | ✓ | — | — | | Tag `v*` | ✓ | ✓ (artifact `fabledapp-`) | ✓ Forgejo Release + APK attached | The build job has `needs: [analyze]` — a failed analyze or test blocks the APK build. To cut a release: ```bash git tag v26.04.06 && git push origin v26.04.06 ``` Requires a `RELEASE_TOKEN` secret (Forgejo PAT with `write:repository` scope) set in repo Settings → Secrets → Actions.