- binder is a Flutter-based Nostr Reader/Writer where Books are nostr lists (kind 30004) and chapters are long-form NIP-23 events (kind 30023). The app targets web + Android and leans on nodal services (
AuthService,NostrService,RelayClient) plus the tracker to document decisions. - The UI doubles as a polished reader (carousel + grid, brand hero) and a writer dashboard (manuscript grid with launch points to drafting flows and Markdown research).
- Document repository expectations and tracking instructions (
README.md,AGENTS.md,PROGRESS.md). - Lay out Reader/Writer screens, sample data, and brand assets (logo, cover) per design direction.
- Capture writing/publishing research in
docs/feature-research.mdand tie it back to the UI via insights cards. - Surface modern publishing/reader best practices (D2C, serialization, analytics) through documentation and the Reader insights section.
- Build relay interactions (nip-51 list fetches, chapter resolution, relay persistence) plus event wiring for books (kind 30004) and chapters (kind 30023).
- Replace placeholder signatures with live nip-07/remote signer flows so events always carry authentic sigs.
- Restrict nip-07 to web, enable remote signer discovery/launch on Android, and capture platform-specific auth guidance in the UI.
- Detect user-specific NIP-65 relay lists on sign-in and prefer them over the default relay set.
- Ask the real NIP-07 provider for the logged-in pubkey so the signer owns the session;
SigningServicenow surfacesrequestNip07Pubkey. - Added the book tag input helper plus the RelayAnalyticsSignal model import so the drafting screen and analytics cards compile cleanly.
- Rebuilt the drafting workflow around
ChapterEditorScreen, adding toolbar shortcuts, tag chips, release date pickers, toggle chips, and saved preview snapshots for each book-scoped draft (per the research requirements). - Finalized the metadata stage, surfaced focus/preview reminders, and added quick book-to-draft navigation from the Writer grid.
- Hardened
RelayClientso WebSocket failures during fetch/publish are caught, logged, and safely ignored instead of bubbling to the UI when relays drop. - Enlarged the Markdown writing area and wrapped the editor in a responsive LayoutBuilder/ConstrainedBox so wide screens give authors more horizontal breathing room.
- Grew the writer grid refresh path so sign-in state changes reload
_bookFutureand surface live manuscripts instead of the placeholder dataset. - Added reordering and status badges to the chapter queue plus sequence recalculation so Markdown staging stays ordered and preview/focus metadata persist across the draft list.
- Expanded the experience-phase reader view by adding focus/typewriter controls, adjustable typography, summary analytics cards, and relay provenance inside
ChapterDetailPage. - Added reader grouping controls (hashtags/authors/date) with a sort toggle + single-chapter view; books now render in grouped sections, and there’s a dedicated list of long-form chapters when the toggle is on.
- Added autosave/history caching plus a Save Draft button and encrypted staging (NIP-44) so drafts stay local until the user explicitly saves, and any relay staging happens with ciphertext.
- Implemented encrypted draft relay sync for books + chapters using NIP-44 self-encryption, plus writer/draft workspace restoration from relay-staged drafts.
- Added media server settings with Blossom defaults, plus local image staging and upload on draft relay save/publish (cover + chapter images).
- Enhanced the single-chapter toggle so those entries are treated as Book cards (from
single_chapters.dart) and only surface chapters that aren’t already grouped with a book. - Logged relay fetch activity in
NostrService.fetchBooksso you can verify whether real relay events arrive before the UI falls back to sample data. - Awaited relay list refresh during
_updateAuthStateso signing in immediately reconfigures relays/profile data instead of continuing to use the defaults. - Tagged books with a binder-only marker so Books are distinguishable from other NIP-51 lists on relays.
- Swapped book card author text for profile name/avatar and added an author action modal (follow/block/copy).
- Added book-level engagement counters (reactions, boosts, zaps, comments) plus popularity sorting in the Reader grid.
- When no Books are available, auto-load standalone NIP-23 chapters from followings instead of sample data.
- Local drafts now persist across restarts via a draft index and restored metadata/chapters in the Writer tab.
- Wired live analytics counts for reactions/reposts/comments/zaps on book cards and popularity sorting now reflects relay activity.
- Added metadata autosave for draft books and opened local drafts directly from the Writer grid.
- Moved chapter analytics into the reading-aids drawer and added chapter-level engagement actions/counts (reactions/boosts/zaps/comments).
- Added active styling for engagement actions so prior reactions/boosts/zaps/comments are visibly highlighted.
- Updated Android remote signer launch flow to try bunker/nostrconnect schemes with external app mode.
- Integrated NDK-based signing (nip-07, Amber, NIP-46) with NostrConnect handshakes, bunker session persistence, and signer restoration on restart.
- Added a NostrConnect QR dialog using
qr_flutterfor easy remote signer onboarding. - Added NWC wallet management with LNURL support and wired zap payments to use the saved wallet connection.
- Added launcher icon config (binder logo) for Android via
flutter_launcher_icons; manifest now points at@mipmap/launcher_icon. - Updated Reader grouping sort so non-date groups (hashtags/authors) respect the active sort selection (date/popularity/title).
- Standardized in-app iconography to outlined variants so Reader/Writer, cards, and drafting controls share a consistent style.
- Finish the writer drafting workflow: chapter metadata, markdown staging per book, focus/preview toggles, and post-book editing navigation.
- Added relay retry/backoff handling with timeout-aware fetches and publish retries for flaky relays.
- Replaced NIP-07 signing with a window-based signer for web/wasm and added NostrConnect QR completion handling.
- Updated grouped Reader grids to use multi-column group layouts on wide screens (including followed chapters).
- Added VPS install/update/remove script to build wasm web assets and configure Caddy/Nginx for self-hosting.
- Reduced relay/network load with caching + inflight dedupe (books, profiles, engagement) plus batch profile prefetching.
- Added relay health tracking with cooldown skips after repeated failures to avoid hammering flaky relays.
- Fixed Caddy installer snippet generation to avoid invalid global options blocks and to clean legacy inline blocks.
- Installer now detects existing Flutter installs in common paths before prompting to install again.
- Reordered the new-book draft layout so metadata leads, chapters follow, and steps are clearly labeled.
- Draft books reopened from the Writer view now keep metadata editable while published books remain read-only.
- Reader/Writer tabs now keep their scroll state and avoid full rebuilds by using an IndexedStack + PageStorage keys.
- Added native splash configuration (binder logo + dark background) using
flutter_native_splash. - Split chapter drafting into metadata + writing steps with a step switcher and summaries.
- Added NIP-46 auth-challenge handling so remote signers can complete browser-based approvals.
- Added default NIP-46 permission requests (including NIP-44) and clearer draft encryption error messaging.
- Refreshed the base UI theme (colors, typography, cards, inputs) for a more modern dark aesthetic.
- Reduced post-sign-in latency by allowing relay fetches to return early with a max wait timeout.
- Relay metrics are now a modal showing connected relay statuses, and NIP-65 lists parse
rtags. - Refactored
RelayClientto use a persistent connection pool with message multiplexing, reducing handshake overhead and network chatter.
- Foundational Phase (complete)
- Finalized Book/Chapter models, sample data, and service stubs for readers and writers.
- Delivered the hero cover header, horizontal carousel, and book grid; top bar now shows Reader/Writer icons plus the signed-in user dropdown.
- Captured contributor expectations, commands, and publishing research in
docs/feature-research.mdandAGENTS.mdso everyone shares the same context.
- Integration Phase (complete)
- Reworked the Reader view into the requested layout (hero, carousel, grid) and anchored relay/media configuration in the user dropdown.
- Simplified the Writer tab to a grid of manuscripts and moved NIP-23 chapter drafting to the separate workspace that launches from each book.
- Wired the Nostr service through book lists (kind 30004) plus chapter (kind 30023) events, including publishing helpers and staging drafts.
- Implemented application-aware relays: detect NIP-65 lists on sign-in, persist user relays, and fall back to defaults when signed out.
- Built the signing stack so nip-07 (web) and remote signers/launchers (Android) deliver real publikeys/signatures and preferences capture signer URLs.
- Polish the drafting workflow (metadata, per-book chapter queuing, focus mode reminders) and hook up the Markdown workspace to finalize chapters.
- Experience Phase (pending)
- Build chapter reader/detail views with relay provenance, error states, and reading aids (dark mode, typewriter).
- Added chapter reader navigation (prev/next), scroll progress indicator, and scroll-to-top control.
- Added draft export actions to copy Markdown and metadata summaries from the chapter queue.
- Added chapter comments list with profile lookups, empty/error states, and refresh control.
- Added comment threading with reply actions and NIP-10 reply/root tagging.
- Added comment pagination (“load more”) for long threads.
- Added chapter ordering controls (move up/down) alongside drag handle in the draft queue.
- Expand writer tools with chapter ordering, preview exports, and simple Markdown toolbar actions.
- Moved chapter metadata into a drawer and restored in-editor toolbar + live preview for the writing step.
- Stability Phase (complete)
- Harden relay resilience, add integration tests for key flows, and document release steps for web/Android builds.
- Guard relay connection failures, avoid penalizing relays that return data without EOSE, and fix relay failure counting.
- Implemented NIP-07 nip44 encrypt/decrypt support so draft encryption can prompt for permissions in browsers.
- Memoized followed chapter fetches in the Reader view to prevent spinner reloads on tab return.
- Compressed the chapter writing header to free vertical space while keeping metadata accessible.
- Replaced relay metrics placeholder cards with live relay health aggregates (coverage, success rate, last failure).
- Added stale-while-revalidate profile caching + short-lived negative cache to speed up profile loads.
- Matched Markdown preview styling to the reader theme in the chapter editor.
- Seed published books into the local cache so Writer/Reader don’t flicker after publishing.
- Restored draft metadata hydration when reopening a draft workspace.
- Added build-time version stamping to refresh web assets after updates.
- Added DraftService tests plus a release checklist for web + Android releases.
- Added profile cache unit tests and updated release checklist for wasm + version stamping.
- Added source badges for local vs relay books and a fallback fetch for published books.
- Clarified chapter selection affordance in book detail list.
- Adjusted user menu offset and added About modal with version + GitHub link.
-
Added book deletion flow (NIP-09) with optional chapter and local draft cleanup.
-
Allow adding existing published NIP-23 chapters to a book draft from the writer workflow.
-
Prevent delete events for externally linked chapters when removing a book.
-
Timeout draft relay decrypts to keep the writer view responsive even when remote signers hang.
-
Zaps now display zap counts (not sats) across book cards and chapter engagement.
-
Book card engagement actions now reflect user state (highlight when previously reacted/boosted/zapped/commented).
-
Reader refresh now surfaces cached book/draft lists immediately and only updates when relay fetches complete.
-
Auto-retry chapter comment loading once to avoid manual refresh when relays respond late.
-
Speed up initial reader load by showing cached/sample data immediately and using shorter relay waits when signed out.
-
Prevent writer reload on return unless a draft actually changed.
-
Added delete actions on writer book cards (drafts + published) with relay/local cleanup.
-
Rehydrate chapter drafts from local history if publish is triggered after state loss.
-
Added progress state for saving drafts to relays with disabled button + spinner.
-
Hide local drafts on sign-out and refresh writer lists after signing out.
-
Use NDK default bootstrap relays for remote signer handshakes; add error handling for NIP-46 flows.
-
Added
fetchUserAnalyticstoNostrServiceto aggregate engagement metrics (reactions, boosts, zaps, comments) across all of a user's published books. -
Integrated live user analytics into the
_buildRelaySignalsdashboard, surfacing "Insights & Metrics" for signed-in authors in the Writer tab and Relay modal. -
Refined
ChapterEditorScreenwith an immersive Focus mode (hiding chrome), centered Typewriter mode with vertical padding, and a quick "Export Markdown" action. -
Fixed a bug where deleting a book could clear the entire Writer list if the subsequent relay fetch failed.
fetchBooksandfetchDraftBooksnow return cached data on error. -
Optimized
NostrServicenetwork performance by parallelizing analytics fetches (splitting by event kind and tag type) and concurrent profile prefetching. -
Further parallelized
_fetchBookEngagementEventsand_fetchEngagementEventsto fetch by event ID and address tag concurrently. -
Implemented persistent profile caching using
PreferencesServiceto reduce network load on startup.NostrServicenow loads the cache on init and saves updates. -
Fixed NIP-46 race condition where
launchUrlwas called before the app started listening for the connection event, causing missed authorizations on mobile app switches. -
Implemented subscription queueing in
RelayClientto limit concurrent subscriptions per relay connection (max 10), preventing relay bans and WebSocket bursts during heavy analytics fetches. -
Fixed WebSocket connection leaks and hanging requests in
RelayClientby clearing the request queue on closure and ensuring proper slot accounting during failures. -
Begin collecting relay analytics signals from nostr reactions/reposts/comments/zaps and reflect them in the insights cards. (Completed)
-
Surface reader-focused analytics (reaction rates, zap totals) within
_buildRelaySignalsso the dashboard mirrors real Nostr activity. (Completed) -
Continue refining the drafting experience (focus modes, layout tweaks, meta tags) so chapter staging matches the research notes. (Completed)
flutter analyze(Jan 26, 2026) — success; user analytics + drafting refinements introduce no new lints.flutter test(Jan 26, 2026) — success; widget + service tests pass after analytics/drafting updates.flutter analyze(Jan 26, 2026) — success; auth-state relay/profile change uses no new lints.flutter test(Jan 25, 2026) — success; widget test still passes after the auth/relay refresh fix.flutter analyze(Jan 25, 2026) — success; NDK signer integration introduces no new analyzer warnings.flutter test(Jan 25, 2026) — success; reader header widget test passes with the new signer flow.flutter analyze(Jan 25, 2026) — success; NostrConnect QR dialog compiles cleanly.flutter test(Jan 25, 2026) — success; widget test still passes after QR onboarding updates.flutter pub run flutter_launcher_icons(Jan 25, 2026) — failed in sandbox (permission denied writing Flutter cache). Run locally to generate launcher assets.flutter pub run flutter_launcher_icons(Jan 25, 2026) — failed locally because/iosdoes not exist; iOS icon generation disabled until an iOS target is added.flutter analyze(Jan 25, 2026) — success; icon config changes introduce no new lints.flutter test(Jan 25, 2026) — success; widget test still passes after icon wiring.flutter analyze(Jan 25, 2026) — success; grouping sort updates introduce no new lints.flutter test(Jan 25, 2026) — success; widget test still passes after grouping sort updates.flutter analyze(Jan 25, 2026) — success; icon standardization introduces no new lints.flutter test(Jan 25, 2026) — success; widget test still passes after icon standardization.flutter analyze(Jan 25, 2026) — success; launcher icon config update introduces no new lints.flutter test(Jan 25, 2026) — success; widget test still passes after launcher icon config update.flutter analyze(Jan 25, 2026) — success; Phase 2 completion update introduces no new lints.flutter test(Jan 25, 2026) — success; widget test still passes after Phase 2 tracker update.flutter analyze(Jan 25, 2026) — success; chapter reader polish (error states + reading aids reset) introduces no new lints.flutter test(Jan 25, 2026) — success; widget test still passes after chapter reader polish.flutter analyze(Jan 25, 2026) — success; chapter navigation/progress updates introduce no new lints.flutter test(Jan 25, 2026) — success; widget test still passes after chapter navigation/progress updates.flutter analyze(Jan 25, 2026) — success; draft export actions introduce no new lints.flutter test(Jan 25, 2026) — success; widget test still passes after draft export actions.flutter analyze(Jan 25, 2026) — success; chapter comments UI introduces no new lints.flutter test(Jan 25, 2026) — success; widget test still passes after chapter comments UI.flutter analyze(Jan 25, 2026) — success; comment threading/reply actions introduce no new lints.flutter test(Jan 25, 2026) — success; widget test still passes after comment threading/reply actions.flutter analyze(Jan 25, 2026) — success; comment pagination introduces no new lints.flutter test(Jan 25, 2026) — success; widget test still passes after comment pagination.flutter analyze(Jan 25, 2026) — success; chapter ordering controls introduce no new lints.flutter test(Jan 25, 2026) — success; widget test still passes after chapter ordering controls.flutter analyze(Jan 25, 2026) — success;flutter_markdown_plusmigration introduces no new lints.flutter test(Jan 25, 2026) — success; widget test still passes afterflutter_markdown_plusmigration.flutter analyze(Jan 25, 2026) — success; draft relay sync updates introduce no new lints.flutter test(Jan 25, 2026) — success; widget test still passes after draft relay sync updates.flutter analyze(Jan 25, 2026) — success; NIP-44-only draft relay save adjustments introduce no new lints.flutter test(Jan 25, 2026) — success; widget test still passes after NIP-44-only draft relay save adjustments.flutter analyze(Jan 25, 2026) — success; author grouping header uses profile metadata without new lints.flutter test(Jan 25, 2026) — success; widget test still passes after author grouping header update.flutter analyze(Jan 25, 2026) — success; writer draft refresh after draft workspace introduces no new lints.flutter test(Jan 25, 2026) — success; widget test still passes after writer draft refresh update.flutter analyze(Jan 25, 2026) — success; drafting UX layout refinements introduce no new lints.flutter test(Jan 25, 2026) — success; widget test still passes after drafting UX layout refinements.flutter analyze(Jan 25, 2026) — success; mobile drafting accordions and sticky toolbar introduce no new lints.flutter test(Jan 25, 2026) — success; widget test still passes after mobile drafting accordions and sticky toolbar.flutter analyze(Jan 25, 2026) — success; media server settings + image staging introduce no new lints.flutter test(Jan 25, 2026) — success; widget test still passes after media server settings + image staging.flutter analyze(Jan 25, 2026) — success; book terminology updates introduce no new lints.flutter test(Jan 25, 2026) — success; widget test still passes after book terminology updates.flutter analyze(Jan 25, 2026) — success; relay editor prefills user relay list without new lints.flutter test(Jan 25, 2026) — success; widget test still passes after relay editor prefill update.flutter analyze(Jan 26, 2026) — success; NWC wallet + zap wiring introduces no new lints.flutter test(Jan 26, 2026) — success; widget test still passes after NWC wallet + zap wiring.flutter analyze(Jan 26, 2026) — success; engagement state styling introduces no new lints.flutter test(Jan 26, 2026) — success; widget test still passes after engagement state styling.flutter analyze(Jan 26, 2026) — success; DraftService tests + release checklist introduce no new lints.flutter test(Jan 26, 2026) — success; DraftService tests pass alongside the widget test.flutter analyze(Jan 26, 2026) — success; relay retry/backoff handling introduces no new lints.flutter test(Jan 26, 2026) — success; widget test still passes after relay retry/backoff handling.flutter analyze(Jan 26, 2026) — success; NIP-07 window signer + QR completion flow introduces no new lints.flutter test(Jan 26, 2026) — success; widget test still passes after NIP-07 window signer + QR completion flow.flutter analyze(Jan 26, 2026) — success; grouped Reader grid layout updates introduce no new lints.flutter test(Jan 26, 2026) — success; widget test still passes after grouped Reader grid layout updates.flutter analyze(Jan 26, 2026) — success; VPS installer script introduces no new lints.flutter test(Jan 26, 2026) — success; widget test still passes after VPS installer script updates.flutter analyze(Jan 26, 2026) — success; dart:js_interop migration for NIP-07 introduces no new lints.flutter test(Jan 26, 2026) — success; widget test still passes after dart:js_interop migration for NIP-07.flutter analyze(Jan 26, 2026) — success; installer script Flutter check introduces no new lints.flutter test(Jan 26, 2026) — success; widget test still passes after installer script Flutter check.flutter analyze(Jan 26, 2026) — success; installer script Flutter auto-install introduces no new lints.flutter test(Jan 26, 2026) — success; widget test still passes after installer script Flutter auto-install.flutter analyze(Jan 26, 2026) — success; installer script resilience upgrades introduce no new lints.flutter test(Jan 26, 2026) — success; widget test still passes after installer script resilience upgrades.flutter analyze(Jan 26, 2026) — success; installer script Caddy include safety introduces no new lints.flutter analyze(Jan 26, 2026) — success; book card engagement state + zap count adjustments introduce no new lints.flutter test(Jan 26, 2026) — success; widget test still passes after engagement state + zap count adjustments.flutter test(Jan 26, 2026) — success; widget test still passes after installer script Caddy include safety.flutter analyze(Jan 26, 2026) — success; installer script Caddy cleanup introduces no new lints.flutter test(Jan 26, 2026) — success; widget test still passes after installer script Caddy cleanup.flutter analyze(Jan 26, 2026) — success; relay error handling updates introduce no new lints.flutter test(Jan 26, 2026) — success; widget test still passes after relay error handling updates.flutter analyze(Jan 26, 2026) — success; mobile-web sign-in filtering + NostrConnect timeout handling introduces no new lints.flutter test(Jan 26, 2026) — success; widget test still passes after mobile-web sign-in filtering + NostrConnect timeout handling.flutter analyze(Jan 26, 2026) — success; reader group carousel layout introduces no new lints.flutter test(Jan 26, 2026) — success; widget test still passes after reader group carousel layout.flutter analyze(Jan 26, 2026) — success; README rewrite introduces no new lints.flutter test(Jan 26, 2026) — success; widget test still passes after README rewrite.flutter analyze(Jan 26, 2026) — success; README cover image update introduces no new lints.flutter analyze(Jan 26, 2026) — success; existing chapter add workflow introduces no new lints.flutter test(Jan 26, 2026) — success; widget + service tests pass after existing chapter add workflow.flutter analyze(Jan 26, 2026) — success; external chapter delete filter introduces no new lints.flutter test(Jan 26, 2026) — success; widget + service tests pass after external chapter delete filter.flutter analyze(Jan 26, 2026) — success; draft decrypt timeout introduces no new lints.flutter test(Jan 26, 2026) — success; widget + service tests pass after draft decrypt timeout.flutter analyze(Jan 26, 2026) — success; reader refresh caching updates introduce no new lints.flutter test(Jan 26, 2026) — success; widget + service tests pass after reader refresh caching updates.flutter analyze(Jan 26, 2026) — success; zap sats display introduces no new lints.flutter test(Jan 26, 2026) — success; widget + service tests pass after zap sats display updates.flutter analyze(Jan 26, 2026) — success; comment auto-retry introduces no new lints.flutter test(Jan 26, 2026) — success; widget + service tests pass after comment auto-retry updates.flutter analyze(Jan 26, 2026) — success; initial reader load optimizations introduce no new lints.flutter test(Jan 26, 2026) — success; widget + service tests pass after initial reader load optimizations.flutter analyze(Jan 26, 2026) — success; writer return reload guard introduces no new lints.flutter test(Jan 26, 2026) — success; widget + service tests pass after writer return reload guard.flutter analyze(Jan 26, 2026) — success; writer delete actions introduce no new lints.flutter test(Jan 26, 2026) — success; widget + service tests pass after writer delete actions.flutter analyze(Jan 26, 2026) — success; publish rehydration introduces no new lints.flutter test(Jan 26, 2026) — success; widget + service tests pass after publish rehydration.flutter analyze(Jan 26, 2026) — success; draft relay save progress introduces no new lints.flutter test(Jan 26, 2026) — success; widget + service tests pass after draft relay save progress.flutter analyze(Jan 26, 2026) — success; sign-out draft visibility fix introduces no new lints.flutter test(Jan 26, 2026) — success; widget + service tests pass after sign-out draft visibility fix.flutter analyze(Jan 26, 2026) — success; remote signer bootstrap relays + error handling introduces no new lints.flutter test(Jan 26, 2026) — success; widget + service tests pass after remote signer bootstrap relays + error handling.flutter test(Jan 26, 2026) — success; widget test still passes after README cover image update.flutter analyze(Jan 26, 2026) — success; network caching + prefetch updates introduce no new lints.flutter test(Jan 26, 2026) — success; widget test still passes after network caching + prefetch updates.flutter analyze(Jan 26, 2026) — success; relay health cooldown logic introduces no new lints.flutter test(Jan 26, 2026) — success; widget test still passes after relay health cooldown logic.flutter analyze(Jan 26, 2026) — success; installer Caddy snippet cleanup introduces no new lints.flutter test(Jan 26, 2026) — success; widget test still passes after installer Caddy snippet cleanup.flutter analyze(Jan 26, 2026) — success; installer Flutter path detection introduces no new lints.flutter test(Jan 26, 2026) — success; widget test still passes after installer Flutter path detection.flutter analyze(Jan 26, 2026) — success; draft workspace layout reorder introduces no new lints.flutter test(Jan 26, 2026) — success; widget test still passes after draft workspace layout reorder.flutter analyze(Jan 26, 2026) — success; draft metadata edit toggle introduces no new lints.flutter test(Jan 26, 2026) — success; widget test still passes after draft metadata edit toggle.flutter analyze(Jan 26, 2026) — success; Reader/Writer IndexedStack keeps state without new lints.flutter test(Jan 26, 2026) — success; widget test still passes after Reader/Writer IndexedStack update.dart run flutter_native_splash(Jan 26, 2026) — failed in sandbox due to Flutter cache permissions; rerun locally to generate splash assets.flutter analyze(Jan 26, 2026) — success; splash config introduces no new lints.flutter test(Jan 26, 2026) — success; widget test still passes after splash config update.flutter analyze(Jan 26, 2026) — success; chapter drafting step split introduces no new lints.flutter test(Jan 26, 2026) — success; widget test still passes after chapter drafting step split.flutter analyze(Jan 26, 2026) — success; NIP-46 auth challenge handling introduces no new lints.flutter test(Jan 26, 2026) — success; widget test still passes after NIP-46 auth challenge handling.flutter analyze(Jan 26, 2026) — success; NIP-46 permission defaults for NIP-44 introduce no new lints.flutter test(Jan 26, 2026) — success; widget test still passes after NIP-46 permission defaults update.flutter analyze(Jan 26, 2026) — success; theme polish updates introduce no new lints.flutter test(Jan 26, 2026) — success; widget test still passes after theme polish updates.flutter analyze(Jan 26, 2026) — success; relay fetch max-wait optimization introduces no new lints.flutter test(Jan 26, 2026) — success; widget test still passes after relay fetch max-wait optimization.flutter analyze(Jan 26, 2026) — success; relay metrics modal + NIP-65 parsing updates introduce no new lints.flutter test(Jan 26, 2026) — success; widget test still passes after relay metrics modal + NIP-65 parsing updates.flutter analyze(Jan 26, 2026) — success; chapter drafting metadata drawer + preview fixes introduce no new lints.flutter test(Jan 26, 2026) — success; widget test still passes after chapter drafting metadata drawer + preview fixes.flutter analyze(Jan 26, 2026) — success; relay resilience guards introduce no new lints.flutter test(Jan 26, 2026) — success; widget test still passes after relay resilience guards.flutter analyze(Jan 26, 2026) — success; NIP-07 nip44 interop introduces no new lints.flutter test(Jan 26, 2026) — success; widget test still passes after NIP-07 nip44 interop updates.flutter analyze(Jan 26, 2026) — success; reader single-chapter memoization introduces no new lints.flutter test(Jan 26, 2026) — success; widget test still passes after reader single-chapter memoization.flutter analyze(Jan 26, 2026) — success; chapter header compression introduces no new lints.flutter test(Jan 26, 2026) — success; widget test still passes after chapter header compression.flutter analyze(Jan 26, 2026) — success; relay metrics live aggregates introduce no new lints.flutter test(Jan 26, 2026) — success; widget test still passes after relay metrics live aggregates.flutter analyze(Jan 26, 2026) — success; profile cache revalidation introduces no new lints.flutter test(Jan 26, 2026) — success; widget test still passes after profile cache revalidation.flutter analyze(Jan 26, 2026) — success; Markdown preview theming alignment introduces no new lints.flutter test(Jan 26, 2026) — success; widget test still passes after Markdown preview theming alignment.flutter analyze(Jan 26, 2026) — success; publish cache seeding introduces no new lints.flutter test(Jan 26, 2026) — success; widget test still passes after publish cache seeding.flutter analyze(Jan 26, 2026) — success; draft metadata hydration introduces no new lints.flutter test(Jan 26, 2026) — success; widget test still passes after draft metadata hydration.flutter analyze(Jan 26, 2026) — success; web version stamping introduces no new lints.flutter test(Jan 26, 2026) — success; widget test still passes after web version stamping.flutter analyze(Jan 26, 2026) — success; profile cache tests + release checklist update introduce no new lints.flutter test(Jan 26, 2026) — success; widget and profile cache tests pass after stability updates.flutter analyze(Jan 26, 2026) — success; book source badges + fallback fetch introduce no new lints.flutter test(Jan 26, 2026) — success; widget and service tests still pass after book source + fallback updates.flutter analyze(Jan 26, 2026) — success; chapter list affordance update introduces no new lints.flutter test(Jan 26, 2026) — success; widget tests pass after chapter list affordance update.flutter analyze(Jan 26, 2026) — success; user menu offset + about modal introduce no new lints.flutter test(Jan 26, 2026) — success; widget and service tests pass after user menu/about updates.flutter analyze(Jan 26, 2026) — success; book delete flow introduces no new lints.flutter test(Jan 26, 2026) — success; widget and service tests pass after book delete flow.
- Should the Draft workspace persist chapter drafts per book (versus the current transient list) before pushing to relays?