Markdown Converter
Agent skill for markdown-converter
> **Note:** Essential information only. Keep context window lean.
Sign in to like and favorite skills
Note: Essential information only. Keep context window lean. Updates to this file: Concise prose only. Weave new information into existing sections—don't append new sections. Include code examples only when high-impact and necessary. No verbose explanations or unnecessary bulleted lists. End every conversation by updating this file with lessons learned.
Daily Manna is a Flutter app for building strong daily habits in interacting with the Word of God. Primary feature: Bible verse memorization.
lib/ ├── main.dart ├── home_page.dart # Feature cards registered here ├── settings_page.dart # API keys config ├── prompts.dart # LLM prompts │ ├── models/ # Freezed classes only │ ├── services/ # Business logic & integrations │ ├── database/database.dart # Drift ORM │ ├── bible_service.dart │ ├── results_service.dart │ ├── settings_service.dart │ ├── spaced_repetition_service.dart │ └── openrouter_service.dart # LLM transcription & passage recognition │ ├── utils/ │ └── date_utils.dart # DateOnlyExtension │ ├── ui/ │ ├── app_scaffold.dart # Standard page wrapper │ ├── theme_card.dart # Shared container │ ├── empty_state.dart # Shared empty state │ ├── action_button_row.dart # Cancel/Submit button pair │ ├── loading_section.dart # Shared loading indicator │ ├── memorization/ │ ├── recitation/ │ ├── verse_selection/ │ ├── history/ │ ├── review/ │ ├── practice/ │ └── study/ │ └── passage_range_selector.dart assets/ └── kjv.xml # ~5MB web/ # Flutter web support android/ # Android platform
just gen # Code generation (freezed) just web # Local debug server (port 8000) just android # Run on device/emulator just build-web # Production web build just start-web-prod # Build & serve production (0.0.0.0:8000) just stop-web-prod # Stop production server just logs-web-prod # View production logs just build-apk-prod # Android release APK just test # Run tests just analyze # Lint analysis (must pass before commit) just fix # Auto-fix lint issues just format # Format code just clean # Clean build artifacts
One question at a time. Ask design questions sequentially rather than overwhelming with multiple options. Use mockups (iframe tool) for UI decisions.
Verify package compatibility before adding. Check pub.dev for recent activity, GitHub issues, and Flutter/Kotlin version compatibility. Prefer simpler solutions that avoid extra platform-specific packages.
For scheduled/background work: Use
workmanager for tasks that must run even when the app is closed (e.g., daily notifications). Scheduled notifications via flutter_local_notifications alone won't reliably fire if the user doesn't open the app—the content is computed at schedule time, not fire time.
Verb-first format:
verb-noun. Simple verbs stand alone: format, test.
Always use conventional commit format. Every commit message must start with a type prefix. Make new commits for fixes—don't use
--amend + force push to rewrite history.
Never rebase pushed branches. Once a branch is pushed, use
git merge origin/main to incorporate upstream changes, not rebase. Rebase requires force push, which rewrites public history.
Format:
type(scope): description or type: description
Types:
feat: - New featurefix: - Bug fixrefactor: - Code change that neither fixes a bug nor adds a featurechore: - Build, config, or tooling changesdocs: - Documentation onlystyle: - Formatting, whitespace (no code change)test: - Adding or updating testsOptional scope in parentheses:
feat(web):, fix(android):
Organize by importance: Public APIs first, then supporting code.
File structure:
computeWordDiff(), MyWidget)WordDiff, DiffWord)Within classes: Public methods → methods they call → private utilities.
Always
abstract class X with _$X. Place in /lib/models/. Use domain-specific names, not UI context.
@freezed abstract class ResultItem with _$ResultItem { const factory ResultItem({ required String score, required String reference, }) = _ResultItem; }
After modifying:
just gen
Prefer extension methods on enums over standalone utility functions:
extension DiffStatusColors on DiffStatus { MaterialColor get primaryColor => switch (this) { DiffStatus.correct => Colors.green, DiffStatus.missing => Colors.red, DiffStatus.extra => Colors.yellow, }; }
Call as
status.primaryColor instead of getPrimaryColor(status).
Format and transform data in service classes, not widgets. Example:
ResultsService.getSections() returns display-ready sections rather than raw data.
Reuse existing widgets before creating new ones. Check
lib/ui/ for shared components like ThemeCard, VerseSelector, LoadingSection.
Critical: Prefer separate widgets over helper methods.
Why: Helper methods create new widget instances on every parent rebuild, bypassing Flutter's widget tree diffing. Actual Widget classes enable the framework to skip unnecessary rebuilds—fundamental to rendering performance.
Extract a widget if it:
RecordingCard, LoadingSection)When NOT to extract: Single widgets (
Text('Hello')).
Use spacing parameters. Prefer
Column(spacing: 12) or Row(spacing: 8) over SizedBox for consistent spacing between children.
File organization:
lib/ui/widget_name.dartlib/ui/feature_name/widget_name.dartlib/ui/feature_name/*_section.dartWidget structure:
Widget build(BuildContext context) => Container(...);final fieldsState class, not widget classWidget naming:
_PrivateWidget prefix for internal-only widgets (used only in their own file or within a parent widget)PublicWidgetAlways use
(not AppScaffold
directly). It provides consistent AppBar and share button. Set Scaffold
showShareButton: false only on Settings page.
Prefer existing navigation patterns. Use push/pop with return values rather than adding callbacks to existing pages.
lib/features list in home_page.dartAppScaffold for page structureBible service:
final bibleService = context.read<BibleService>(); final verse = bibleService.getVerse('Gen', 1, 1);
Scripture references:
final ref = ScriptureRef(bookId: 'Gen', chapterNumber: 1, verseNumber: 1); if (ref.complete) { /* all fields set */ }
Always show helpful feedback when data is empty. Don't leave views blank.
Examples: "No results to share yet", loading indicators, error messages.
Update version in
pubspec.yaml, merge to main to trigger automatic workflow: creates git tag, builds APK, and creates GitHub Release.
Custom Python server with CORS headers.
Local dev:
just web → http://localhost:8000
Headless browser gotcha: Locale strings like
en-US@posix break Flutter's parser, causing silent white-screen failures. Normalization is handled in web/index.html.
Production (exe.dev VM):
just start-web-prod - Build & serve on 0.0.0.0:8000 (background)just stop-web-prod - Stop serverjust logs-web-prod - View logsWhen testing changes to database behavior in the browser, clear IndexedDB storage first. Old persisted data will mask whether your fix works. Use browser devtools or JS to clear storage before testing.
sqlite3.wasm and drift_worker.js in web/share_plus handles mobile/web sharingword_tools for memorization scoringStudy existing patterns first. Before adding new functions or methods, read the surrounding code to understand existing patterns. Reuse existing helpers instead of creating new ones.
Goal: Write code that is maintainable long-term. Avoid unnecessary couplings (dependencies between components) that make future changes expensive.
Apply Kent Beck's "Tidy First?" concepts at all times:
Tidyings - Small, reversible structural changes that don't alter behavior:
When to tidy:
Commit discipline: Each tidying is one small commit. Don't mix tidyings with behavior changes.
When using subagents for parallel work:
Two-phase approach:
Editing subagent rules:
just analyze after each batchSubagents are workers, not planners. Do planning yourself, give them precise tasks.