The global receiveTimeout is 30s but quick capture runs LLM inference that can take much longer. receiveTimeout fired, fell through to the NetworkException fallback in dioToApp, and the work queue queued it as an offline item. - quick_capture_api.dart: override receiveTimeout to 120s for the /api/quick-capture request - api_client.dart: handle receiveTimeout/sendTimeout explicitly in the error interceptor, converting them to AppException (not NetworkException) so slow responses are never mistaken for being offline Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
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.
- Library — unified browsable list of notes, tasks, and projects with filter pills (All · Notes · Tasks · Projects). Tasks have a secondary status sub-filter and a tappable status icon to cycle todo → in progress → done without opening the editor. Inline search filters results live.
- Chat — streaming AI conversations with real-time SSE display. Tap + to start a new conversation or open an existing one.
- 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-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
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 + 3-tab shell
├── 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)
│ ├── models/ # Plain Dart models with fromJson/toJson
│ └── repositories/ # Thin wrappers over API classes
├── providers/ # Riverpod providers (state + dependency wiring)
│ ├── briefing_provider.dart # Today's briefing — optimistic UI, SSE, polling
│ └── capture_work_queue_provider.dart # Sequential in-memory capture queue
├── screens/
│ ├── briefing/ # BriefingScreen + BriefingHistoryScreen
│ ├── library/ # LibraryScreen (unified notes/tasks/projects)
│ ├── chat/ # ConversationsTabScreen + ChatScreen
│ ├── notes/ # NoteDetailScreen + NoteEditScreen
│ ├── tasks/ # TaskEditScreen
│ └── settings/ auth/ setup/ splash/
└── widgets/
├── chat_message_bubble.dart # Shared bubble (used by Chat + Briefing)
├── briefing_digest_card.dart # Expandable first-message card
└── library_item_card.dart # Note / task / project row widgets
Key packages: flutter_riverpod, go_router, dio + cookie_jar, google_fonts, flutter_markdown_plus
Building a Release APK
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-<sha>) |
— |
Push main |
✓ | — | — |
Tag v* |
✓ | ✓ (artifact fabledapp-<sha>) |
✓ Forgejo Release + APK attached |
The build job has needs: [analyze] — a failed analyze or test blocks the APK build.
To cut a release:
git tag v26.03.11 && git push origin v26.03.11
Requires a RELEASE_TOKEN secret (Forgejo PAT with write:repository scope) set in repo Settings → Secrets → Actions.