This repository has been archived on 2026-06-02 . You can view files and clone it. You cannot open issues or pull requests or push a commit.
98ad9a255753e1feabb821d919012ff91cc0911d
Root cause: when SSE delivered any chunk, maxAttempts was set to 1 with no delay. That single immediate poll hit the server before it finished writing to the DB, received status='generating' with empty content, then overwrote the SSE-streamed text with the stale empty row and exited. isStreaming went false and the UI was stuck showing '...'. Two fixes: 1. Always poll up to 20 times regardless of SSE success. SSE closing does not mean the server has committed the final row to the DB. 2. When SSE delivered content, only replace state with polled data if the polled assistant message is complete or has content — this prevents clobbering streamed text with a stale empty DB row while the server is still writing. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Fabled — Android App
Native Android client for FabledAssistant, a self-hosted AI productivity assistant.
Features
- Notes — create, edit, and browse markdown notes
- Tasks — manage tasks with status (To Do / In Progress / Done) and priority
- Chat — streaming AI conversations with real-time SSE response display
- Quick Capture — FAB shortcut to create a note or task from anywhere
- OAuth / SSO — authenticates via your server's configured OIDC provider; local username/password login also supported if enabled on the server
- Session persistence — stays logged in across app restarts via a persistent cookie jar
- Home screen widget — tap to open the chat screen directly from the Android launcher
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
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 redirect guards + shell nav
├── core/
│ ├── constants.dart # Route name constants
│ └── exceptions.dart # AppException hierarchy
├── data/
│ ├── api/ # Dio HTTP layer (one class per resource)
│ ├── models/ # Plain Dart models with fromJson/toJson
│ └── repositories/ # Thin wrappers over API classes
└── providers/ # Riverpod providers (state + dependency wiring)
screens/ # Flutter UI screens
Key packages: flutter_riverpod, go_router, dio + cookie_jar, flutter_inappwebview, flutter_markdown
Building a Release APK
flutter build apk --release
The signed APK will be at build/app/outputs/flutter-apk/app-release.apk.
Description
Releases
32
Languages
Dart
87.9%
C++
5.7%
CMake
4.2%
Swift
0.7%
Shell
0.5%
Other
1%