Skip to content

test(integration): add integration test support with basic messaging flow test#666

Merged
pepina-dev merged 2 commits into
masterfrom
test/integration
May 18, 2026
Merged

test(integration): add integration test support with basic messaging flow test#666
pepina-dev merged 2 commits into
masterfrom
test/integration

Conversation

@jgmontoya
Copy link
Copy Markdown
Contributor

@jgmontoya jgmontoya commented May 15, 2026

Description

Type of Change

  • ✨ New feature (non-breaking change which adds functionality)
  • 🛠️ Bug fix (non-breaking change which fixes an issue)
  • ❌ Breaking change (fix or feature that would cause existing functionality to change)
  • 🧹 Code refactor
  • ✅ Build configuration change
  • 📝 Documentation
  • 🗑️ Chore
  • 🧪 Tests

How I Tested This

Screenshots

Before After
Screen.Recording.2026-05-15.at.19.59.26.mov

Checklist

  • just precommit passes
  • Related issue linked (Closes #NNN)
  • CHANGELOG.md updated (if user-visible change)
  • Screenshots added (for UI changes)

Summary by CodeRabbit

  • New Features

    • Added an end-to-end integration test exercising multi-profile group invites and message delivery.
  • Refactor

    • Centralized relay configuration with URI/port-aware handling and single-point default overrides.
    • Added stable widget Keys across multiple screens for more reliable UI identity.
  • Tests

    • Added tests for relay URL parsing/port preservation and updated integration-test inclusion.
  • Chores

    • Exposed optional default relay URLs in native bridge, added local relay dev configs and docker compose, and normalized build/test recipes.

Review Change Stack

@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented May 15, 2026

📝 Walkthrough

Walkthrough

Centralizes relay defaults into a configurable Rust API applied during Whitenoise initialization, exposes optional default relay URLs through the Flutter Rust bridge, updates offline reachability to use parsed URIs, instruments UI widgets with stable Keys for tests, and adds a two-identity integration test for group invites and messaging.

Changes

Relay URL Configurability & E2E Integration Testing

Layer / File(s) Summary
Relay defaults module refactoring
rust/src/api/relay_defaults.rs
Introduces PRODUCTION_RELAY_URLS/BUG_REPORT_RELAY_URLS, adds OnceLock override store, configure_default_relay_urls, parse_relay_urls, and helpers so exported defaults resolve from an override or production list; adds tests for override validation and bug-report alias.
Whitenoise config & relay initialization
rust/src/api/mod.rs, rust/src/api/accounts.rs, rust/src/api/bug_report.rs
Exports optional default_relay_urls in bridged WhitenoiseConfig; create_whitenoise_config accepts/stores this option; initialize_whitenoise applies configure_default_relay_urls(...) during initialization; accounts/bug-report modules use resolved defaults.
Flutter Rust bridge API & generated files
lib/src/rust/api.dart, lib/src/rust/api/*.dart
Adds defaultRelayUrls parameter to createWhitenoiseConfig; extends Dart WhitenoiseConfig with nullable defaultRelayUrls and updates constructor/equality/hash; regenerates API comments to match current Rust trait set.
Offline provider relay URI-based reachability
lib/providers/offline_provider.dart
Changes ReachAnyRelayFunction to List<Uri>, parses default relay URLs into Uris once, computes TCP port per Uri (explicit or scheme default), and connects via uri.host:port; _tryReachAnyRelay accepts List<Uri>?.
UI widget key instrumentation
lib/screens/*.dart, lib/widgets/wn_auth_buttons_container.dart
Adds stable Flutter Keys to multiple interactive widgets (signup, settings, profile keys, group setup, chat-invite, switch-profile, user-selection, auth buttons) and forwards keys where appropriate to stabilize tests.
End-to-end integration test implementation
integration_test/basic_messaging_flow_test.dart
New integration test boots Rust backend (temp dirs), creates two profiles via UI flows, copies npub, creates invited group, sends messages from both profiles, and asserts message propagation; includes Riverpod overrides, keyed UI helpers, polling utilities, message debug failure summaries, and local relay TCP preflight checks.
Test infra & build configuration
pubspec.yaml, justfile, test/*
Adds integration_test dev dependency; updates justfile recipes to include integration_test/ in Dart formatting checks and standardizes templating/quoting; updates mocks/tests to accept defaultRelayUrls and assert relay URIs in offline-provider tests.
Rust builder environment setup
rust_builder/cargokit/build_tool/lib/src/rustup.dart, .../builder.dart
Adds Rustup.environmentWithRustupFirst to prefer rustup's directory in PATH and updates RustBuilder to wrap the build environment with that helper before running commands.

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~60 minutes

Possibly related PRs

Suggested reviewers

  • erskingardner
  • mubarakcoded
  • dannym-arx
  • cypherpinkdev
🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title follows the preferred format (type(scope): description) with 'test' as the type and 'integration' as the scope, clearly describing the addition of integration test support and a basic messaging flow test.
Docstring Coverage ✅ Passed Docstring coverage is 100.00% which is sufficient. The required threshold is 80.00%.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch test/integration

Comment @coderabbitai help to get the list of available commands and usage tips.

@jgmontoya jgmontoya changed the title test(integration): add integration test support with basic messaging … test(integration): add integration test support with basic messaging flow test May 15, 2026
Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
rust/src/api/mod.rs (1)

67-77: ⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

Update the example call to match the new function signature.

The doc example still calls create_whitenoise_config with 2 arguments, but Line 80-Line 84 now require default_relay_urls too.

Proposed doc fix
 /// let config = create_whitenoise_config(
 ///     "/path/to/data".to_string(),
-///     "/path/to/logs".to_string()
+///     "/path/to/logs".to_string(),
+///     None
 /// );
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@rust/src/api/mod.rs` around lines 67 - 77, The doc example for
create_whitenoise_config is out of date: it shows a 2-argument call but the
function signature now requires the third parameter default_relay_urls; update
the example invocation in the documentation to pass a suitable value for
default_relay_urls (e.g., an empty Vec or a Vec of sample URLs) so the example
matches the create_whitenoise_config function signature and compiles.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@integration_test/basic_messaging_flow_test.dart`:
- Around line 306-311: The global text finder in _expectMessageVisible can match
the composer input instead of an actual message bubble; restrict the search
scope to the message list widget (or a specific message widget) so the assertion
only succeeds when a rendered message appears. Update _expectMessageVisible to
use a scoped finder (e.g., find.descendant(of: find.byKey(/* message list key
*/), matching: find.textContaining(message, findRichText: true)) or match a
specific message widget type like find.descendant(of: find.byType(MessageList or
MessageBubble), matching: ...)) and keep using _pumpUntilFound for polling.

In `@lib/src/rust/api.dart`:
- Around line 94-104: WhitenoiseConfig's hashCode and operator== currently
compare defaultRelayUrls by identity, causing unequal but value-equal Lists to
break hash contract; update the flutter_rust_bridge generation template/config
so List fields use deep equality and deep hashing instead of identity (e.g.,
generate equals/hashCode using a deep collection equality helper for
defaultRelayUrls), ensuring the generated WhitenoiseConfig implementations
compute hashCode and operator== with element-wise comparison for
defaultRelayUrls.

---

Outside diff comments:
In `@rust/src/api/mod.rs`:
- Around line 67-77: The doc example for create_whitenoise_config is out of
date: it shows a 2-argument call but the function signature now requires the
third parameter default_relay_urls; update the example invocation in the
documentation to pass a suitable value for default_relay_urls (e.g., an empty
Vec or a Vec of sample URLs) so the example matches the create_whitenoise_config
function signature and compiles.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Pro

Run ID: 789e1cf5-389f-4c56-8e35-0bd7a07a0776

📥 Commits

Reviewing files that changed from the base of the PR and between 594f58a and 3023d37.

⛔ Files ignored due to path filters (4)
  • ios/Podfile.lock is excluded by !**/*.lock
  • lib/src/rust/frb_generated.dart is excluded by !lib/src/rust/frb_generated.dart
  • pubspec.lock is excluded by !**/*.lock, !pubspec.lock
  • rust/src/frb_generated.rs is excluded by !rust/src/frb_generated.rs
📒 Files selected for processing (30)
  • integration_test/basic_messaging_flow_test.dart
  • justfile
  • lib/providers/offline_provider.dart
  • lib/screens/chat_invite_screen.dart
  • lib/screens/profile_keys_screen.dart
  • lib/screens/set_up_group_screen.dart
  • lib/screens/settings_screen.dart
  • lib/screens/signup_screen.dart
  • lib/screens/switch_profile_screen.dart
  • lib/screens/user_selection_screen.dart
  • lib/src/rust/api.dart
  • lib/src/rust/api/accounts.dart
  • lib/src/rust/api/chat_list.dart
  • lib/src/rust/api/group_state.dart
  • lib/src/rust/api/groups.dart
  • lib/src/rust/api/messages.dart
  • lib/src/rust/api/notifications.dart
  • lib/src/rust/api/relay_defaults.dart
  • lib/src/rust/api/user_search.dart
  • lib/src/rust/api/users.dart
  • lib/widgets/wn_auth_buttons_container.dart
  • pubspec.yaml
  • rust/src/api/accounts.rs
  • rust/src/api/bug_report.rs
  • rust/src/api/mod.rs
  • rust/src/api/relay_defaults.rs
  • rust_builder/cargokit/build_tool/lib/src/builder.dart
  • rust_builder/cargokit/build_tool/lib/src/rustup.dart
  • test/main_test.dart
  • test/providers/offline_provider_test.dart
📜 Review details
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (5)
  • GitHub Check: Test (1/4)
  • GitHub Check: Test (3/4)
  • GitHub Check: Test (4/4)
  • GitHub Check: Test (2/4)
  • GitHub Check: Check
🧰 Additional context used
📓 Path-based instructions (14)
**/*.dart

📄 CodeRabbit inference engine (AGENTS.md)

**/*.dart: Use single quotes for strings in Dart/Flutter code
Enable and respect prefer_const_constructors lint rule in Dart/Flutter code
Enable and respect prefer_final_locals lint rule in Dart/Flutter code
Set line width to 100 characters in Dart/Flutter code
Preserve trailing commas in Dart/Flutter code
Maintain minimum test coverage of 99%; never submit a PR that reduces test coverage
Avoid using // coverage:ignore, // coverage:ignore-line, // coverage:ignore-start, or // coverage:ignore-end to bypass coverage requirements; write tests instead (only exception: truly unreachable code)

Files:

  • lib/src/rust/api/users.dart
  • lib/widgets/wn_auth_buttons_container.dart
  • lib/src/rust/api/groups.dart
  • lib/src/rust/api/notifications.dart
  • lib/src/rust/api/relay_defaults.dart
  • lib/src/rust/api/user_search.dart
  • test/providers/offline_provider_test.dart
  • lib/screens/profile_keys_screen.dart
  • lib/src/rust/api.dart
  • lib/src/rust/api/group_state.dart
  • lib/src/rust/api/chat_list.dart
  • lib/src/rust/api/messages.dart
  • lib/screens/user_selection_screen.dart
  • lib/screens/switch_profile_screen.dart
  • rust_builder/cargokit/build_tool/lib/src/builder.dart
  • lib/screens/signup_screen.dart
  • test/main_test.dart
  • lib/screens/settings_screen.dart
  • rust_builder/cargokit/build_tool/lib/src/rustup.dart
  • lib/screens/set_up_group_screen.dart
  • lib/src/rust/api/accounts.dart
  • lib/screens/chat_invite_screen.dart
  • integration_test/basic_messaging_flow_test.dart
  • lib/providers/offline_provider.dart
**/*.{dart,rs}

📄 CodeRabbit inference engine (AGENTS.md)

Do not add comments except for code that is really complex or hard to understand

Files:

  • lib/src/rust/api/users.dart
  • lib/widgets/wn_auth_buttons_container.dart
  • lib/src/rust/api/groups.dart
  • lib/src/rust/api/notifications.dart
  • lib/src/rust/api/relay_defaults.dart
  • lib/src/rust/api/user_search.dart
  • test/providers/offline_provider_test.dart
  • lib/screens/profile_keys_screen.dart
  • lib/src/rust/api.dart
  • lib/src/rust/api/group_state.dart
  • lib/src/rust/api/chat_list.dart
  • lib/src/rust/api/messages.dart
  • rust/src/api/accounts.rs
  • lib/screens/user_selection_screen.dart
  • rust/src/api/bug_report.rs
  • lib/screens/switch_profile_screen.dart
  • rust_builder/cargokit/build_tool/lib/src/builder.dart
  • lib/screens/signup_screen.dart
  • test/main_test.dart
  • lib/screens/settings_screen.dart
  • rust_builder/cargokit/build_tool/lib/src/rustup.dart
  • lib/screens/set_up_group_screen.dart
  • lib/src/rust/api/accounts.dart
  • lib/screens/chat_invite_screen.dart
  • integration_test/basic_messaging_flow_test.dart
  • lib/providers/offline_provider.dart
  • rust/src/api/relay_defaults.rs
  • rust/src/api/mod.rs
lib/**/*.dart

📄 CodeRabbit inference engine (AGENTS.md)

lib/**/*.dart: Use flutter_screenutil for all size values (padding, margins, gaps, icon sizes, font sizes, border radius, container dimensions) to ensure responsive layouts. Use .w for width, .h for height, .sp for font size/letter spacing, and .r for radius
Avoid StatefulWidget; prefer providers (for shared app-wide state) or hooks (for widget-local state) instead

Files:

  • lib/src/rust/api/users.dart
  • lib/widgets/wn_auth_buttons_container.dart
  • lib/src/rust/api/groups.dart
  • lib/src/rust/api/notifications.dart
  • lib/src/rust/api/relay_defaults.dart
  • lib/src/rust/api/user_search.dart
  • lib/screens/profile_keys_screen.dart
  • lib/src/rust/api.dart
  • lib/src/rust/api/group_state.dart
  • lib/src/rust/api/chat_list.dart
  • lib/src/rust/api/messages.dart
  • lib/screens/user_selection_screen.dart
  • lib/screens/switch_profile_screen.dart
  • lib/screens/signup_screen.dart
  • lib/screens/settings_screen.dart
  • lib/screens/set_up_group_screen.dart
  • lib/src/rust/api/accounts.dart
  • lib/screens/chat_invite_screen.dart
  • lib/providers/offline_provider.dart
lib/src/rust/**/*.dart

📄 CodeRabbit inference engine (AGENTS.md)

Do not manually edit files in lib/src/rust/ as they are auto-generated by flutter_rust_bridge

Files:

  • lib/src/rust/api/users.dart
  • lib/src/rust/api/groups.dart
  • lib/src/rust/api/notifications.dart
  • lib/src/rust/api/relay_defaults.dart
  • lib/src/rust/api/user_search.dart
  • lib/src/rust/api.dart
  • lib/src/rust/api/group_state.dart
  • lib/src/rust/api/chat_list.dart
  • lib/src/rust/api/messages.dart
  • lib/src/rust/api/accounts.dart
lib/widgets/wn_*.dart

📄 CodeRabbit inference engine (AGENTS.md)

lib/widgets/wn_*.dart: Design system widgets should be prefixed with wn_ in filename and Wn in class name (e.g., wn_filled_button.dart / WnFilledButton)
Design system widgets must have Widgetbook stories and should not contain translations or Rust API calls

Files:

  • lib/widgets/wn_auth_buttons_container.dart
lib/widgets/*.dart

📄 CodeRabbit inference engine (AGENTS.md)

Screen-scoped widgets extracted from a single screen should be prefixed with the screen name and only used in that one screen

Files:

  • lib/widgets/wn_auth_buttons_container.dart
lib/widgets/**

⚙️ CodeRabbit configuration file

lib/widgets/**: This is a reusable widget.
There are two kinds of reusable widgets:

  1. Design system widgets — simple, presentational widgets that match
    the Figma design system in name and structure. They have Widgetbook
    stories, contain only presentational logic, and do NOT have
    translations or Rust API calls.

    • File MUST be prefixed with wn_ (e.g. wn_filled_button.dart)
    • Class MUST be prefixed with Wn (e.g. WnFilledButton)
  2. Complex reusable widgets — used across multiple screens but contain
    translations, hooks with Rust API calls, or other complex logic
    that makes them harder to display in Widgetbook.

    • These do NOT use the wn_/Wn prefix
    • Example: OnboardingCarousel (used in multiple screens, has
      translations and a page controller inside)

General rules for all widgets in this directory:

  • Use const constructors where possible
  • Use flutter_screenutil (.w, .h, .sp, .r) for all dimensions
  • Avoid StatefulWidget — prefer hooks for local state
  • No comments except for truly complex logic

Files:

  • lib/widgets/wn_auth_buttons_container.dart
test/**/*_test.dart

📄 CodeRabbit inference engine (AGENTS.md)

test/**/*_test.dart: Test files should mirror source structure with _test.dart suffix
Use helpers from test/test_helpers.dart in tests: setUpTestView(), mountTestApp(), mountHook(), mountWidget(), mountStackedWidget()
Mock Rust API by extending MockWnApi from test/mocks/mock_wn_api.dart instead of implementing RustLibApi directly
Prefer find.byKey() over find.byIcon() in tests; add keys to icons in widgets and use find.byKey(const Key('icon_name')) in tests
Use valid 64-character hex strings for pubkeys in tests, not dummy values like 'abc' or 'test-pubkey'

Files:

  • test/providers/offline_provider_test.dart
  • test/main_test.dart
test/**

⚙️ CodeRabbit configuration file

test/**: IMPORTANT: CI enforces coverage regression (coverage must never decrease). It does not enforce a fixed 95% minimum threshold.
Rules:

  • Test files mirror source structure with _test.dart suffix
  • Use helpers from test/test_helpers.dart (setUpTestView, mountTestApp, etc.)
  • Mock Rust API using RustLib.initMock(api: mockApi)
  • Always extend MockWnApi from test/mocks/mock_wn_api.dart
  • Prefer find.byKey() over find.byIcon() for widget testing
  • Use valid 64-char hex strings for pubkeys, not dummy values like 'abc'
  • Tests must be deterministic — no external service dependencies

Files:

  • test/providers/offline_provider_test.dart
  • test/main_test.dart
lib/screens/**

⚙️ CodeRabbit configuration file

lib/screens/**: This is a Flutter screen (full-page widget).
Architecture rules:

  • Screens should WATCH Riverpod providers for shared state
  • Use flutter_hooks for ephemeral/local state (NOT StatefulWidget)
  • Pass data to hooks, not refs
  • Use flutter_screenutil (.w, .h, .sp, .r) for all size values
  • Widgets should use const constructors where possible
  • No comments except for truly complex logic
  • When a widget is extracted from a screen and only used in that one
    screen, it should be prefixed with the screen name (e.g.
    ChatListTile for a widget only used in the chat list screen).
    These are screen-scoped widgets and do NOT use the Wn prefix.

Files:

  • lib/screens/profile_keys_screen.dart
  • lib/screens/user_selection_screen.dart
  • lib/screens/switch_profile_screen.dart
  • lib/screens/signup_screen.dart
  • lib/screens/settings_screen.dart
  • lib/screens/set_up_group_screen.dart
  • lib/screens/chat_invite_screen.dart
rust/src/api/**/*.rs

📄 CodeRabbit inference engine (AGENTS.md)

rust/src/api/**/*.rs: Rust API modules in rust/src/api/ must be exposed to Flutter with #[frb] attribute on functions
Rust structs exposed to Flutter must use #[frb(non_opaque)] attribute for Flutter compatibility
Wrap Rust API errors in ApiError enum using thiserror crate

Files:

  • rust/src/api/accounts.rs
  • rust/src/api/bug_report.rs
  • rust/src/api/relay_defaults.rs
  • rust/src/api/mod.rs
rust/src/api/**

⚙️ CodeRabbit configuration file

rust/src/api/**: This is the Rust API layer exposed to Flutter via flutter_rust_bridge.
Rules:

  • Functions use #[frb] attribute for bridge generation
  • Structs use #[frb(non_opaque)] for Flutter compatibility
  • Errors must be wrapped in the ApiError enum using thiserror
  • This is a thin wrapper around the whitenoise crate — keep it thin
  • No unwrap() in non-test code; use proper error handling
  • Check for correct async patterns

Files:

  • rust/src/api/accounts.rs
  • rust/src/api/bug_report.rs
  • rust/src/api/relay_defaults.rs
  • rust/src/api/mod.rs
lib/providers/*_provider.dart

📄 CodeRabbit inference engine (AGENTS.md)

lib/providers/*_provider.dart: Provider files should end with _provider.dart (e.g., auth_provider.dart)
Provider variables should end with Provider (e.g., authProvider)

Files:

  • lib/providers/offline_provider.dart
lib/providers/**

⚙️ CodeRabbit configuration file

lib/providers/**: This is a Riverpod provider (shared app-wide state).
Rules:

  • Files must end with _provider.dart
  • Provider variables must end with Provider (e.g. authProvider)
  • Don't duplicate logic from the Rust crate — whitenoise is source of truth
  • Don't cache data that whitenoise already persists in its local DB

Files:

  • lib/providers/offline_provider.dart
🧠 Learnings (32)
📚 Learning: 2026-01-05T20:05:32.918Z
Learnt from: untreu2
Repo: marmot-protocol/sloth PR: 22
File: lib/screens/settings_screen.dart:76-88
Timestamp: 2026-01-05T20:05:32.918Z
Learning: In the Sloth project, tooltips should not be used for UI elements. During code reviews, verify that UI components do not include Tooltip widgets and replace them with accessible alternatives (e.g., long-press hints, labels, or interactive guidance). Apply this guidance across Dart UI files under lib (not just settings_screen.dart) to maintain a consistent design approach.

Applied to files:

  • lib/src/rust/api/users.dart
  • lib/widgets/wn_auth_buttons_container.dart
  • lib/src/rust/api/groups.dart
  • lib/src/rust/api/notifications.dart
  • lib/src/rust/api/relay_defaults.dart
  • lib/src/rust/api/user_search.dart
  • lib/screens/profile_keys_screen.dart
  • lib/src/rust/api.dart
  • lib/src/rust/api/group_state.dart
  • lib/src/rust/api/chat_list.dart
  • lib/src/rust/api/messages.dart
  • lib/screens/user_selection_screen.dart
  • lib/screens/switch_profile_screen.dart
  • lib/screens/signup_screen.dart
  • lib/screens/settings_screen.dart
  • lib/screens/set_up_group_screen.dart
  • lib/src/rust/api/accounts.dart
  • lib/screens/chat_invite_screen.dart
  • lib/providers/offline_provider.dart
📚 Learning: 2026-01-09T13:25:18.531Z
Learnt from: josefinalliende
Repo: marmot-protocol/sloth PR: 33
File: lib/services/message_service.dart:14-26
Timestamp: 2026-01-09T13:25:18.531Z
Learning: When errors are presented to users in the Sloth codebase (UI layers such as snackbars, dialogs, toasts), show friendly, user-facing messages instead of raw Rust error messages. Implement a mapping from internal error types or codes to clear, non-technical messages, and surface actionable guidance for end users where appropriate. Avoid exposing internal stack traces or language runtime details; centralize common user-facing error wording in a dedicated utility or service and translate backend errors into concise, helpful UI messages.

Applied to files:

  • lib/src/rust/api/users.dart
  • lib/widgets/wn_auth_buttons_container.dart
  • lib/src/rust/api/groups.dart
  • lib/src/rust/api/notifications.dart
  • lib/src/rust/api/relay_defaults.dart
  • lib/src/rust/api/user_search.dart
  • lib/screens/profile_keys_screen.dart
  • lib/src/rust/api.dart
  • lib/src/rust/api/group_state.dart
  • lib/src/rust/api/chat_list.dart
  • lib/src/rust/api/messages.dart
  • lib/screens/user_selection_screen.dart
  • lib/screens/switch_profile_screen.dart
  • lib/screens/signup_screen.dart
  • lib/screens/settings_screen.dart
  • lib/screens/set_up_group_screen.dart
  • lib/src/rust/api/accounts.dart
  • lib/screens/chat_invite_screen.dart
  • lib/providers/offline_provider.dart
📚 Learning: 2026-04-06T09:40:41.044Z
Learnt from: untreu2
Repo: marmot-protocol/whitenoise PR: 552
File: lib/screens/profile_keys_screen.dart:71-71
Timestamp: 2026-04-06T09:40:41.044Z
Learning: In this Flutter/Dart codebase, when using flutter_screenutil (e.g., ScreenUtil or ScreenUtil-based sizing like `w`, `h`), do not require scaled units for literal zero values. Specifically, in EdgeInsets (and similar sizing/padding/margin/gap APIs), bare numeric `0` should be allowed (e.g., `EdgeInsets.all(0)`, `EdgeInsets.symmetric(vertical: 0)`, `SizedBox(width: 0)`), because scaling `0` remains `0`. Only flag ScreenUtil violations when a non-zero literal needs to be expressed via `0.w`/`0.h` equivalents; do not flag bare `0`.

Applied to files:

  • lib/src/rust/api/users.dart
  • lib/widgets/wn_auth_buttons_container.dart
  • lib/src/rust/api/groups.dart
  • lib/src/rust/api/notifications.dart
  • lib/src/rust/api/relay_defaults.dart
  • lib/src/rust/api/user_search.dart
  • lib/screens/profile_keys_screen.dart
  • lib/src/rust/api.dart
  • lib/src/rust/api/group_state.dart
  • lib/src/rust/api/chat_list.dart
  • lib/src/rust/api/messages.dart
  • lib/screens/user_selection_screen.dart
  • lib/screens/switch_profile_screen.dart
  • lib/screens/signup_screen.dart
  • lib/screens/settings_screen.dart
  • lib/screens/set_up_group_screen.dart
  • lib/src/rust/api/accounts.dart
  • lib/screens/chat_invite_screen.dart
  • lib/providers/offline_provider.dart
📚 Learning: 2026-01-06T01:08:41.552Z
Learnt from: untreu2
Repo: marmot-protocol/sloth PR: 22
File: lib/widgets/wn_warning_box.dart:28-79
Timestamp: 2026-01-06T01:08:41.552Z
Learning: In reviews for the marmot-protocol/sloth repository, avoid suggesting accessibility, design, or general improvements unless they are strictly relevant to the PR description and its stated goals. Focus feedback on the specific PR objectives and requirements; ignore unrelated stylistic or broad improvement suggestions.

Applied to files:

  • lib/src/rust/api/users.dart
  • lib/widgets/wn_auth_buttons_container.dart
  • lib/src/rust/api/groups.dart
  • lib/src/rust/api/notifications.dart
  • lib/src/rust/api/relay_defaults.dart
  • lib/src/rust/api/user_search.dart
  • test/providers/offline_provider_test.dart
  • lib/screens/profile_keys_screen.dart
  • lib/src/rust/api.dart
  • lib/src/rust/api/group_state.dart
  • lib/src/rust/api/chat_list.dart
  • lib/src/rust/api/messages.dart
  • lib/screens/user_selection_screen.dart
  • lib/screens/switch_profile_screen.dart
  • rust_builder/cargokit/build_tool/lib/src/builder.dart
  • lib/screens/signup_screen.dart
  • test/main_test.dart
  • lib/screens/settings_screen.dart
  • rust_builder/cargokit/build_tool/lib/src/rustup.dart
  • lib/screens/set_up_group_screen.dart
  • lib/src/rust/api/accounts.dart
  • lib/screens/chat_invite_screen.dart
  • integration_test/basic_messaging_flow_test.dart
  • lib/providers/offline_provider.dart
📚 Learning: 2026-01-15T14:42:54.111Z
Learnt from: josefinalliende
Repo: marmot-protocol/sloth PR: 39
File: lib/hooks/use_user_search.dart:47-53
Timestamp: 2026-01-15T14:42:54.111Z
Learning: When using npubFromHex(String hexPubkey) from lib/utils/formatting.dart, it already handles errors internally and returns null on failure. Do not wrap calls to this function in try/catch blocks. Instead, check for a null return and handle accordingly (e.g., treat as invalid hex). This guideline applies to all Dart files in the repository that may call this function.

Applied to files:

  • lib/src/rust/api/users.dart
  • lib/widgets/wn_auth_buttons_container.dart
  • lib/src/rust/api/groups.dart
  • lib/src/rust/api/notifications.dart
  • lib/src/rust/api/relay_defaults.dart
  • lib/src/rust/api/user_search.dart
  • test/providers/offline_provider_test.dart
  • lib/screens/profile_keys_screen.dart
  • lib/src/rust/api.dart
  • lib/src/rust/api/group_state.dart
  • lib/src/rust/api/chat_list.dart
  • lib/src/rust/api/messages.dart
  • lib/screens/user_selection_screen.dart
  • lib/screens/switch_profile_screen.dart
  • rust_builder/cargokit/build_tool/lib/src/builder.dart
  • lib/screens/signup_screen.dart
  • test/main_test.dart
  • lib/screens/settings_screen.dart
  • rust_builder/cargokit/build_tool/lib/src/rustup.dart
  • lib/screens/set_up_group_screen.dart
  • lib/src/rust/api/accounts.dart
  • lib/screens/chat_invite_screen.dart
  • integration_test/basic_messaging_flow_test.dart
  • lib/providers/offline_provider.dart
📚 Learning: 2026-01-16T17:35:32.431Z
Learnt from: untreu2
Repo: marmot-protocol/sloth PR: 43
File: lib/hooks/use_network_relays.dart:155-184
Timestamp: 2026-01-16T17:35:32.431Z
Learning: In Dart/Flutter code, prefer void as the return type for fire-and-forget async functions that are intended to run in the background without blocking the caller. Using Future or Future<void> would allow callers to accidentally await, which could block for long periods. This pattern makes the call fire-and-forget by design. Apply to functions that intentionally should not be awaited; document the intent where appropriate. (Example context: pollRelayStatus in lib/hooks/use_network_relays.dart uses void to prevent callers from awaiting a potentially long-running background task.)

Applied to files:

  • lib/src/rust/api/users.dart
  • lib/widgets/wn_auth_buttons_container.dart
  • lib/src/rust/api/groups.dart
  • lib/src/rust/api/notifications.dart
  • lib/src/rust/api/relay_defaults.dart
  • lib/src/rust/api/user_search.dart
  • test/providers/offline_provider_test.dart
  • lib/screens/profile_keys_screen.dart
  • lib/src/rust/api.dart
  • lib/src/rust/api/group_state.dart
  • lib/src/rust/api/chat_list.dart
  • lib/src/rust/api/messages.dart
  • lib/screens/user_selection_screen.dart
  • lib/screens/switch_profile_screen.dart
  • rust_builder/cargokit/build_tool/lib/src/builder.dart
  • lib/screens/signup_screen.dart
  • test/main_test.dart
  • lib/screens/settings_screen.dart
  • rust_builder/cargokit/build_tool/lib/src/rustup.dart
  • lib/screens/set_up_group_screen.dart
  • lib/src/rust/api/accounts.dart
  • lib/screens/chat_invite_screen.dart
  • integration_test/basic_messaging_flow_test.dart
  • lib/providers/offline_provider.dart
📚 Learning: 2026-01-19T15:50:56.684Z
Learnt from: erskingardner
Repo: marmot-protocol/sloth PR: 52
File: lib/screens/app_settings_screen.dart:30-40
Timestamp: 2026-01-19T15:50:56.684Z
Learning: Target the Flutter SDK version >= 3.27 across the repo. Since features like Column.spacing and Row.spacing were added in Flutter 3.27, you can safely use them in Dart files (e.g., lib/screens/app_settings_screen.dart) as long as the pubspec.yaml environment specifies Flutter >= 3.27. If needed, enforce this by validating the environment constraint (e.g., flutter, sdk: flutter) in pubspec.yaml.

Applied to files:

  • lib/src/rust/api/users.dart
  • lib/widgets/wn_auth_buttons_container.dart
  • lib/src/rust/api/groups.dart
  • lib/src/rust/api/notifications.dart
  • lib/src/rust/api/relay_defaults.dart
  • lib/src/rust/api/user_search.dart
  • test/providers/offline_provider_test.dart
  • lib/screens/profile_keys_screen.dart
  • lib/src/rust/api.dart
  • lib/src/rust/api/group_state.dart
  • lib/src/rust/api/chat_list.dart
  • lib/src/rust/api/messages.dart
  • lib/screens/user_selection_screen.dart
  • lib/screens/switch_profile_screen.dart
  • rust_builder/cargokit/build_tool/lib/src/builder.dart
  • lib/screens/signup_screen.dart
  • test/main_test.dart
  • lib/screens/settings_screen.dart
  • rust_builder/cargokit/build_tool/lib/src/rustup.dart
  • lib/screens/set_up_group_screen.dart
  • lib/src/rust/api/accounts.dart
  • lib/screens/chat_invite_screen.dart
  • integration_test/basic_messaging_flow_test.dart
  • lib/providers/offline_provider.dart
📚 Learning: 2026-01-29T03:02:34.290Z
Learnt from: josefinalliende
Repo: marmot-protocol/sloth PR: 100
File: lib/widgets/wn_dropdown_selector.dart:126-139
Timestamp: 2026-01-29T03:02:34.290Z
Learning: Global font-family usage guideline: Since Manrope is configured in lib/theme.dart for both light and dark themes, individual TextStyle declarations should not specify fontFamily: 'Manrope'. During reviews, verify that no TextStyle instances override fontFamily unnecessarily; rely on theme inheritance instead. If a TextStyle must specify a font for a specific case, ensure it is clearly justified and localized, and document why the override is needed. This guideline applies across Dart files in the project (e.g., lib/widgets/wn_dropdown_selector.dart and related components).

Applied to files:

  • lib/src/rust/api/users.dart
  • lib/widgets/wn_auth_buttons_container.dart
  • lib/src/rust/api/groups.dart
  • lib/src/rust/api/notifications.dart
  • lib/src/rust/api/relay_defaults.dart
  • lib/src/rust/api/user_search.dart
  • test/providers/offline_provider_test.dart
  • lib/screens/profile_keys_screen.dart
  • lib/src/rust/api.dart
  • lib/src/rust/api/group_state.dart
  • lib/src/rust/api/chat_list.dart
  • lib/src/rust/api/messages.dart
  • lib/screens/user_selection_screen.dart
  • lib/screens/switch_profile_screen.dart
  • rust_builder/cargokit/build_tool/lib/src/builder.dart
  • lib/screens/signup_screen.dart
  • test/main_test.dart
  • lib/screens/settings_screen.dart
  • rust_builder/cargokit/build_tool/lib/src/rustup.dart
  • lib/screens/set_up_group_screen.dart
  • lib/src/rust/api/accounts.dart
  • lib/screens/chat_invite_screen.dart
  • integration_test/basic_messaging_flow_test.dart
  • lib/providers/offline_provider.dart
📚 Learning: 2026-01-29T16:02:52.588Z
Learnt from: erskingardner
Repo: marmot-protocol/sloth PR: 129
File: test/widgets/wn_overlay_test.dart:84-91
Timestamp: 2026-01-29T16:02:52.588Z
Learning: In Dart/Flutter code, when constructing widgets inside an already-const context (for example, within a const Scaffold with a child that is a collection of widgets), avoid adding explicit const keywords to the children. The Dart analyzer treats these as implicitly const, and adding explicit const can trigger the unnecessary_const lint. Review test files and general Dart files to ensure you do not redundantly prefix children with const in const contexts; rely on the implicit const behavior instead.

Applied to files:

  • lib/src/rust/api/users.dart
  • lib/widgets/wn_auth_buttons_container.dart
  • lib/src/rust/api/groups.dart
  • lib/src/rust/api/notifications.dart
  • lib/src/rust/api/relay_defaults.dart
  • lib/src/rust/api/user_search.dart
  • test/providers/offline_provider_test.dart
  • lib/screens/profile_keys_screen.dart
  • lib/src/rust/api.dart
  • lib/src/rust/api/group_state.dart
  • lib/src/rust/api/chat_list.dart
  • lib/src/rust/api/messages.dart
  • lib/screens/user_selection_screen.dart
  • lib/screens/switch_profile_screen.dart
  • rust_builder/cargokit/build_tool/lib/src/builder.dart
  • lib/screens/signup_screen.dart
  • test/main_test.dart
  • lib/screens/settings_screen.dart
  • rust_builder/cargokit/build_tool/lib/src/rustup.dart
  • lib/screens/set_up_group_screen.dart
  • lib/src/rust/api/accounts.dart
  • lib/screens/chat_invite_screen.dart
  • integration_test/basic_messaging_flow_test.dart
  • lib/providers/offline_provider.dart
📚 Learning: 2026-02-07T03:58:22.587Z
Learnt from: josefinalliende
Repo: marmot-protocol/sloth PR: 193
File: lib/services/android_signer_service.dart:13-13
Timestamp: 2026-02-07T03:58:22.587Z
Learning: In Dart files across the repository, retain NIP (Nostr Implementation Possibilities) and MIP (Marmot Implementation Possibilities) protocol reference comments that link code to their specifications. While general guidance discourages extraneous comments, these references improve traceability and maintainability by documenting the protocol context for related implementation details. Keep them in Dart sources (e.g., lib/services/android_signer_service.dart) and ensure they are kept up-to-date.

Applied to files:

  • lib/src/rust/api/users.dart
  • lib/widgets/wn_auth_buttons_container.dart
  • lib/src/rust/api/groups.dart
  • lib/src/rust/api/notifications.dart
  • lib/src/rust/api/relay_defaults.dart
  • lib/src/rust/api/user_search.dart
  • test/providers/offline_provider_test.dart
  • lib/screens/profile_keys_screen.dart
  • lib/src/rust/api.dart
  • lib/src/rust/api/group_state.dart
  • lib/src/rust/api/chat_list.dart
  • lib/src/rust/api/messages.dart
  • lib/screens/user_selection_screen.dart
  • lib/screens/switch_profile_screen.dart
  • rust_builder/cargokit/build_tool/lib/src/builder.dart
  • lib/screens/signup_screen.dart
  • test/main_test.dart
  • lib/screens/settings_screen.dart
  • rust_builder/cargokit/build_tool/lib/src/rustup.dart
  • lib/screens/set_up_group_screen.dart
  • lib/src/rust/api/accounts.dart
  • lib/screens/chat_invite_screen.dart
  • integration_test/basic_messaging_flow_test.dart
  • lib/providers/offline_provider.dart
📚 Learning: 2026-02-11T17:29:43.985Z
Learnt from: untreu2
Repo: marmot-protocol/whitenoise PR: 225
File: lib/screens/app_settings_screen.dart:64-69
Timestamp: 2026-02-11T17:29:43.985Z
Learning: In the whitenoise Flutter app, after deleting all data and resetting auth, use Routes.goToHome(context) instead of Routes.goToLogin(context) because the home screen is the app entry point and will manage authentication routing. Apply this change to navigation calls that should land on the home screen after a data reset or auth reset. Update lib/screens/app_settings_screen.dart and any similar navigation points accordingly.

Applied to files:

  • lib/src/rust/api/users.dart
  • lib/widgets/wn_auth_buttons_container.dart
  • lib/src/rust/api/groups.dart
  • lib/src/rust/api/notifications.dart
  • lib/src/rust/api/relay_defaults.dart
  • lib/src/rust/api/user_search.dart
  • test/providers/offline_provider_test.dart
  • lib/screens/profile_keys_screen.dart
  • lib/src/rust/api.dart
  • lib/src/rust/api/group_state.dart
  • lib/src/rust/api/chat_list.dart
  • lib/src/rust/api/messages.dart
  • lib/screens/user_selection_screen.dart
  • lib/screens/switch_profile_screen.dart
  • rust_builder/cargokit/build_tool/lib/src/builder.dart
  • lib/screens/signup_screen.dart
  • test/main_test.dart
  • lib/screens/settings_screen.dart
  • rust_builder/cargokit/build_tool/lib/src/rustup.dart
  • lib/screens/set_up_group_screen.dart
  • lib/src/rust/api/accounts.dart
  • lib/screens/chat_invite_screen.dart
  • integration_test/basic_messaging_flow_test.dart
  • lib/providers/offline_provider.dart
📚 Learning: 2026-02-18T18:36:13.394Z
Learnt from: untreu2
Repo: marmot-protocol/whitenoise PR: 315
File: lib/screens/edit_group_screen.dart:45-47
Timestamp: 2026-02-18T18:36:13.394Z
Learning: Whitenoise uses automated code formatting through the precommit workflow (just precommit). Do not tweak line wrapping or formatting manually; follow the formatter's output. Run the precommit formatter locally and ensure the code matches its styling decisions, and only deviate if the formatter cannot express the intended style (in which case adjust the code to satisfy the formatter).

Applied to files:

  • lib/src/rust/api/users.dart
  • lib/widgets/wn_auth_buttons_container.dart
  • lib/src/rust/api/groups.dart
  • lib/src/rust/api/notifications.dart
  • lib/src/rust/api/relay_defaults.dart
  • lib/src/rust/api/user_search.dart
  • test/providers/offline_provider_test.dart
  • lib/screens/profile_keys_screen.dart
  • lib/src/rust/api.dart
  • lib/src/rust/api/group_state.dart
  • lib/src/rust/api/chat_list.dart
  • lib/src/rust/api/messages.dart
  • lib/screens/user_selection_screen.dart
  • lib/screens/switch_profile_screen.dart
  • rust_builder/cargokit/build_tool/lib/src/builder.dart
  • lib/screens/signup_screen.dart
  • test/main_test.dart
  • lib/screens/settings_screen.dart
  • rust_builder/cargokit/build_tool/lib/src/rustup.dart
  • lib/screens/set_up_group_screen.dart
  • lib/src/rust/api/accounts.dart
  • lib/screens/chat_invite_screen.dart
  • integration_test/basic_messaging_flow_test.dart
  • lib/providers/offline_provider.dart
📚 Learning: 2026-04-06T09:36:06.726Z
Learnt from: untreu2
Repo: marmot-protocol/whitenoise PR: 553
File: lib/widgets/wn_copyable_field.dart:38-40
Timestamp: 2026-04-06T09:36:06.726Z
Learning: In Dart, `String.operator*` is a valid built-in operator for repeating strings (e.g., `'⬤' * 16`). In code reviews of Dart (`.dart`) files, do not treat expressions like `'text' * n` as invalid syntax and do not recommend replacing them with alternatives such as `List.filled(...).join()`; the operator is supported by `dart:core`.

Applied to files:

  • lib/src/rust/api/users.dart
  • lib/widgets/wn_auth_buttons_container.dart
  • lib/src/rust/api/groups.dart
  • lib/src/rust/api/notifications.dart
  • lib/src/rust/api/relay_defaults.dart
  • lib/src/rust/api/user_search.dart
  • test/providers/offline_provider_test.dart
  • lib/screens/profile_keys_screen.dart
  • lib/src/rust/api.dart
  • lib/src/rust/api/group_state.dart
  • lib/src/rust/api/chat_list.dart
  • lib/src/rust/api/messages.dart
  • lib/screens/user_selection_screen.dart
  • lib/screens/switch_profile_screen.dart
  • rust_builder/cargokit/build_tool/lib/src/builder.dart
  • lib/screens/signup_screen.dart
  • test/main_test.dart
  • lib/screens/settings_screen.dart
  • rust_builder/cargokit/build_tool/lib/src/rustup.dart
  • lib/screens/set_up_group_screen.dart
  • lib/src/rust/api/accounts.dart
  • lib/screens/chat_invite_screen.dart
  • integration_test/basic_messaging_flow_test.dart
  • lib/providers/offline_provider.dart
📚 Learning: 2026-05-13T13:46:32.612Z
Learnt from: dannym-arx
Repo: marmot-protocol/whitenoise PR: 656
File: lib/hooks/use_block_actions.dart:3-3
Timestamp: 2026-05-13T13:46:32.612Z
Learning: In marmot-protocol/whitenoise code reviews, do not flag imports that reference FRB-generated bindings under `package:rust_lib_whitenoise/src/rust/...` as private-internals violations. In `rust_lib_whitenoise`, Dart bindings are intentionally generated into `lib/src/rust/`, and `analysis_options.yaml` sets `implementation_imports: false` to suppress the related Dart lint—so `package:rust_lib_whitenoise/src/rust/...` imports are the correct/only way to consume that FRB-generated API.

Applied to files:

  • lib/src/rust/api/users.dart
  • lib/widgets/wn_auth_buttons_container.dart
  • lib/src/rust/api/groups.dart
  • lib/src/rust/api/notifications.dart
  • lib/src/rust/api/relay_defaults.dart
  • lib/src/rust/api/user_search.dart
  • test/providers/offline_provider_test.dart
  • lib/screens/profile_keys_screen.dart
  • lib/src/rust/api.dart
  • lib/src/rust/api/group_state.dart
  • lib/src/rust/api/chat_list.dart
  • lib/src/rust/api/messages.dart
  • lib/screens/user_selection_screen.dart
  • lib/screens/switch_profile_screen.dart
  • rust_builder/cargokit/build_tool/lib/src/builder.dart
  • lib/screens/signup_screen.dart
  • test/main_test.dart
  • lib/screens/settings_screen.dart
  • rust_builder/cargokit/build_tool/lib/src/rustup.dart
  • lib/screens/set_up_group_screen.dart
  • lib/src/rust/api/accounts.dart
  • lib/screens/chat_invite_screen.dart
  • integration_test/basic_messaging_flow_test.dart
  • lib/providers/offline_provider.dart
📚 Learning: 2026-05-13T13:46:39.250Z
Learnt from: dannym-arx
Repo: marmot-protocol/whitenoise PR: 656
File: lib/services/foreground_service.dart:13-16
Timestamp: 2026-05-13T13:46:39.250Z
Learning: In this repo (marmot-protocol/whitenoise), `rust_lib_whitenoise` is an FRB-generated Flutter package where the generated Dart bindings are intentionally exposed under `lib/src/rust/` as the public API surface. Do not treat imports like `package:rust_lib_whitenoise/src/rust/...` as breaking package API boundaries in code reviews (the project also sets `implementation_imports: false` in `analysis_options.yaml` to opt into this). Never raise concerns about `src/` imports from `rust_lib_whitenoise`.

Applied to files:

  • lib/src/rust/api/users.dart
  • lib/widgets/wn_auth_buttons_container.dart
  • lib/src/rust/api/groups.dart
  • lib/src/rust/api/notifications.dart
  • lib/src/rust/api/relay_defaults.dart
  • lib/src/rust/api/user_search.dart
  • test/providers/offline_provider_test.dart
  • lib/screens/profile_keys_screen.dart
  • lib/src/rust/api.dart
  • lib/src/rust/api/group_state.dart
  • lib/src/rust/api/chat_list.dart
  • lib/src/rust/api/messages.dart
  • lib/screens/user_selection_screen.dart
  • lib/screens/switch_profile_screen.dart
  • rust_builder/cargokit/build_tool/lib/src/builder.dart
  • lib/screens/signup_screen.dart
  • test/main_test.dart
  • lib/screens/settings_screen.dart
  • rust_builder/cargokit/build_tool/lib/src/rustup.dart
  • lib/screens/set_up_group_screen.dart
  • lib/src/rust/api/accounts.dart
  • lib/screens/chat_invite_screen.dart
  • integration_test/basic_messaging_flow_test.dart
  • lib/providers/offline_provider.dart
📚 Learning: 2026-01-05T22:40:27.888Z
Learnt from: untreu2
Repo: marmot-protocol/sloth PR: 22
File: lib/widgets/wn_image_picker.dart:127-143
Timestamp: 2026-01-05T22:40:27.888Z
Learning: In marmot-protocol's Sloth project (lib/widgets/...): image hosting URLs returned by blossom servers are always lowercase (http:// or https://). Do not implement or rely on case-insensitive URL protocol detection in WN image picker code; assume the protocol is lowercase. If URL protocol checks are needed, compare against the exact literals 'http://' and 'https://'. Add tests that assert URLs use lowercase protocols. This guideline applies to all Dart files under lib/widgets that handle image URLs.

Applied to files:

  • lib/widgets/wn_auth_buttons_container.dart
📚 Learning: 2026-02-04T10:35:43.112Z
Learnt from: erskingardner
Repo: marmot-protocol/sloth PR: 170
File: lib/widgets/wn_list_item.dart:232-234
Timestamp: 2026-02-04T10:35:43.112Z
Learning: In this repository ( marmot-protocol/sloth ), when writing widget build methods in Dart files under lib/widgets, only extract a local typography variable if context.typographyScaled or context.typography is used multiple times within the same build method. If typography is used only once, keep the inline access to avoid an unnecessary extra line. This guideline helps maintain readability and avoids premature refactoring.

Applied to files:

  • lib/widgets/wn_auth_buttons_container.dart
📚 Learning: 2026-02-14T05:09:20.007Z
Learnt from: josefinalliende
Repo: marmot-protocol/whitenoise PR: 260
File: lib/widgets/wn_message_quote.dart:32-88
Timestamp: 2026-02-14T05:09:20.007Z
Learning: In Dart widget files under lib/widgets (matching lib/widgets/**/*.dart), spacing literals such as padding, gap values, and border radii should not be extracted into constants based on josefinalliende's preference. Apply this rule consistently across widget files to improve readability and avoid over-abstracting simple literals.

Applied to files:

  • lib/widgets/wn_auth_buttons_container.dart
📚 Learning: 2026-01-05T21:28:05.652Z
Learnt from: untreu2
Repo: marmot-protocol/sloth PR: 22
File: test/screens/profile_keys_screen_test.dart:14-23
Timestamp: 2026-01-05T21:28:05.652Z
Learning: In test mocks for the marmot-protocol/sloth project, allow skipping bounds checking for substring operations when test inputs are controlled and have proven sufficient length (e.g., 'test_pubkey' is always 12 characters). Favor simpler, deterministic mock implementations in such controlled test contexts, but avoid relaxing bounds checks in production code or tests with variable inputs. Apply this guideline primarily to test files under the test/ directory.

Applied to files:

  • test/providers/offline_provider_test.dart
  • test/main_test.dart
📚 Learning: 2026-01-07T16:49:18.694Z
Learnt from: josefinalliende
Repo: marmot-protocol/sloth PR: 33
File: test/screens/chat_screen_test.dart:245-282
Timestamp: 2026-01-07T16:49:18.694Z
Learning: In the marmot-protocol/sloth repository, it is acceptable to use force-unwrapping (!) in Dart test files as an implicit assertion: if a value is unexpectedly null, the test will fail. This guideline applies only to test code under the test/ directory and should not be used in production code.

Applied to files:

  • test/providers/offline_provider_test.dart
  • test/main_test.dart
📚 Learning: 2026-01-11T22:43:09.610Z
Learnt from: josefinalliende
Repo: marmot-protocol/sloth PR: 36
File: test/screens/chat_list_screen_test.dart:74-76
Timestamp: 2026-01-11T22:43:09.610Z
Learning: In Dart tests (e.g., test/screens/chat_list_screen_test.dart and related files), use setUp() to call _api.reset() to clean up StreamController resources. Do not suggest or rely on tearDownAll for this cleanup.

Applied to files:

  • test/providers/offline_provider_test.dart
  • test/main_test.dart
📚 Learning: 2026-04-14T03:52:37.716Z
Learnt from: josefinalliende
Repo: marmot-protocol/whitenoise PR: 565
File: test/providers/offline_provider_test.dart:63-177
Timestamp: 2026-04-14T03:52:37.716Z
Learning: In this repository, it’s acceptable to use fixed-time waits for test timing using `Future.delayed` (e.g., `await Future.delayed(const Duration(milliseconds: 10))`) inside test files. During code reviews, don’t recommend replacing these fixed sleeps with event-based or poll-based synchronization when the change is localized to Dart test files under the `test/` directory.

Applied to files:

  • test/providers/offline_provider_test.dart
  • test/main_test.dart
📚 Learning: 2026-02-05T11:59:09.400Z
Learnt from: erskingardner
Repo: marmot-protocol/sloth PR: 189
File: test/widgets/wn_filter_chip_test.dart:1-3
Timestamp: 2026-02-05T11:59:09.400Z
Learning: In Dart/Flutter test files, Offset is exported by package:flutter_test/flutter_test.dart. If you already import flutter_test, you do not need to import dart:ui for Offset. Ensure there are no conflicting Offset symbols when both imports occur.

Applied to files:

  • test/providers/offline_provider_test.dart
  • test/main_test.dart
  • integration_test/basic_messaging_flow_test.dart
📚 Learning: 2026-04-28T17:39:39.941Z
Learnt from: pepina-dev
Repo: marmot-protocol/whitenoise PR: 600
File: test/hooks/use_leave_group_test.dart:67-78
Timestamp: 2026-04-28T17:39:39.941Z
Learning: In this repo’s Dart test files under `test/` (e.g., `test/hooks/use_leave_group_test.dart`), it’s acceptable to avoid calling `mockApi.reset()` at the start of `setUp()` when the test suite already manually resets all relevant individual mock fields in `setUp()`. Reviewers should not flag the absence of a `reset()` call as long as every field that could leak state between tests is explicitly reinitialized and the tests are passing.

Applied to files:

  • test/providers/offline_provider_test.dart
  • test/main_test.dart
📚 Learning: 2026-01-15T15:00:17.356Z
Learnt from: josefinalliende
Repo: marmot-protocol/sloth PR: 39
File: lib/screens/user_search_screen.dart:50-75
Timestamp: 2026-01-15T15:00:17.356Z
Learning: In lib/screens/user_search_screen.dart and similar screen widgets in the sloth repository, prefer using inline ternary expressions for conditional rendering (e.g., isLoading → empty state → list) over extracting into separate widget classes when the conditional UI is simple. This improves readability by keeping the render logic in a single place. Reserve extracting to a separate widget only when the conditional UI becomes sufficiently complex or is reused across multiple screens.

Applied to files:

  • lib/screens/profile_keys_screen.dart
  • lib/screens/user_selection_screen.dart
  • lib/screens/switch_profile_screen.dart
  • lib/screens/signup_screen.dart
  • lib/screens/settings_screen.dart
  • lib/screens/set_up_group_screen.dart
  • lib/screens/chat_invite_screen.dart
📚 Learning: 2026-02-10T04:57:31.475Z
Learnt from: josefinalliende
Repo: marmot-protocol/sloth PR: 208
File: lib/screens/signup_screen.dart:66-70
Timestamp: 2026-02-10T04:57:31.475Z
Learning: In Dart/Flutter using flutter_hooks, a ValueNotifier (from useState) is disposed when the widget unmounts. Async callbacks (e.g., .then() on animations) may still run after disposal and throw 'A ValueNotifier was used after being disposed'. Reviewers should ensure that state updates in async callbacks are guarded by a mounted check (e.g., if (mounted) { notifier.value = ... } or cancel/avoid updating after disposal). This guideline applies to screen widgets under lib/screens and similar Dart files using hooks that manage widget lifecycle. Update code patterns to prevent post-disposal state updates, and document the rationale in comments where necessary.

Applied to files:

  • lib/screens/profile_keys_screen.dart
  • lib/screens/user_selection_screen.dart
  • lib/screens/switch_profile_screen.dart
  • lib/screens/signup_screen.dart
  • lib/screens/settings_screen.dart
  • lib/screens/set_up_group_screen.dart
  • lib/screens/chat_invite_screen.dart
📚 Learning: 2026-02-19T10:33:16.889Z
Learnt from: untreu2
Repo: marmot-protocol/whitenoise PR: 315
File: lib/screens/group_info_screen.dart:146-149
Timestamp: 2026-02-19T10:33:16.889Z
Learning: Pubkey validation (length/format) is performed by the Rust crate before data reaches Dart. Do not add defensive substring guards in Dart for pubkeys in lib/screens/**/*.dart or other Flutter code consuming group member pubkeys, as this would duplicate validation and be unnecessary. If any validation is needed in Dart, keep it to lightweight sanity checks only after data enters Dart and ensure it aligns with the Rust validation rules.

Applied to files:

  • lib/screens/profile_keys_screen.dart
  • lib/screens/user_selection_screen.dart
  • lib/screens/switch_profile_screen.dart
  • lib/screens/signup_screen.dart
  • lib/screens/settings_screen.dart
  • lib/screens/set_up_group_screen.dart
  • lib/screens/chat_invite_screen.dart
📚 Learning: 2026-04-06T09:40:51.965Z
Learnt from: untreu2
Repo: marmot-protocol/whitenoise PR: 552
File: lib/screens/sign_out_screen.dart:86-86
Timestamp: 2026-04-06T09:40:51.965Z
Learning: When reviewing Flutter/Dart code that uses ScreenUtil (e.g., ScreenUtil `.h`/`.w`/`.sp`), do not require converting a literal `0` used for padding/margin/sizing to a ScreenUtil expression. In sizing contexts like `EdgeInsets` (or other `EdgeInsets`/layout parameters), raw `0` is mathematically invariant (`0 * scale = 0`) and should not be flagged as a ScreenUtil violation. Only non-zero literal size values should be checked for ScreenUtil usage.

Applied to files:

  • lib/screens/profile_keys_screen.dart
  • lib/screens/user_selection_screen.dart
  • lib/screens/switch_profile_screen.dart
  • lib/screens/signup_screen.dart
  • lib/screens/settings_screen.dart
  • lib/screens/set_up_group_screen.dart
  • lib/screens/chat_invite_screen.dart
📚 Learning: 2026-01-15T23:30:10.907Z
Learnt from: jgmontoya
Repo: marmot-protocol/sloth PR: 42
File: rust/src/api/account_groups.rs:107-123
Timestamp: 2026-01-15T23:30:10.907Z
Learning: In the Rust API layer under rust/src/api/, ensure functions remain thin translation wrappers that delegate business logic to the whitenoise-rs crate. Do not implement business logic or fixes in the sloth API layer; instead, move such changes to whitenoise-rs and keep the API layer focused on request/response translation and orchestration.

Applied to files:

  • rust/src/api/accounts.rs
  • rust/src/api/bug_report.rs
  • rust/src/api/relay_defaults.rs
  • rust/src/api/mod.rs
📚 Learning: 2026-01-15T23:30:10.907Z
Learnt from: jgmontoya
Repo: marmot-protocol/sloth PR: 42
File: rust/src/api/account_groups.rs:107-123
Timestamp: 2026-01-15T23:30:10.907Z
Learning: Maintain a consistent function start-up order in the Rust module: for functions like accept_account_group, decline_account_group, and mark_message_read in rust/src/api/account_groups.rs (and other files in rust/src/api), call Whitenoise::get_instance() first, then parse input parameters. This pattern should be applied across the entire module to improve readability and consistency.

Applied to files:

  • rust/src/api/accounts.rs
  • rust/src/api/bug_report.rs
  • rust/src/api/relay_defaults.rs
  • rust/src/api/mod.rs
📚 Learning: 2026-01-19T10:45:49.603Z
Learnt from: erskingardner
Repo: marmot-protocol/sloth PR: 52
File: rust/src/api/utils.rs:62-83
Timestamp: 2026-01-19T10:45:49.603Z
Learning: In rust/src/api, ensure that FFI glue code for flutter_rust_bridge (e.g., callable functions exposing enum variants or wrapping Display/FromStr) lives in the bridge layer, not in whitenoise-rs. Only business logic should be delegated to whitenoise-rs. Simple enum variant constructors and FFI-specific wrappers belong in the bridge layer.

Applied to files:

  • rust/src/api/accounts.rs
  • rust/src/api/bug_report.rs
  • rust/src/api/relay_defaults.rs
  • rust/src/api/mod.rs
📚 Learning: 2026-02-10T23:51:16.714Z
Learnt from: jgmontoya
Repo: marmot-protocol/whitenoise PR: 209
File: rust/src/api/user_search.rs:51-111
Timestamp: 2026-02-10T23:51:16.714Z
Learning: In Rust code reviews, treat usize to u64 as a safe widening on all supported platforms (usize <= 64 bits). Do not suggest try_from for usize -> u64 conversions. Be cautious about the reverse direction (u64 -> usize) on 32-bit platforms where truncation can occur. When reviewing, prefer direct as-casting or explicit type as appropriate for usize to u64; avoid try_from for this specific conversion.

Applied to files:

  • rust/src/api/accounts.rs
  • rust/src/api/bug_report.rs
  • rust/src/api/relay_defaults.rs
  • rust/src/api/mod.rs
🔇 Additional comments (37)
rust_builder/cargokit/build_tool/lib/src/builder.dart (1)

161-161: LGTM!

rust_builder/cargokit/build_tool/lib/src/rustup.dart (1)

138-156: LGTM!

rust/src/api/relay_defaults.rs (1)

7-13: LGTM!

Also applies to: 15-42, 44-67, 71-71, 76-79, 102-119

rust/src/api/mod.rs (1)

45-46: LGTM!

Also applies to: 54-55, 80-90, 142-151

rust/src/api/accounts.rs (1)

1-3: LGTM!

Also applies to: 268-269

rust/src/api/bug_report.rs (1)

3-3: LGTM!

Also applies to: 92-93, 127-127, 192-194

lib/src/rust/api.dart (1)

22-23: LGTM!

Also applies to: 37-42, 84-91

lib/src/rust/api/accounts.dart (1)

14-14: LGTM!

lib/src/rust/api/chat_list.dart (1)

17-17: LGTM!

lib/src/rust/api/group_state.dart (1)

11-11: LGTM!

lib/src/rust/api/groups.dart (1)

13-13: LGTM!

lib/src/rust/api/messages.dart (1)

15-15: LGTM!

lib/src/rust/api/notifications.dart (1)

11-11: LGTM!

lib/src/rust/api/relay_defaults.dart (1)

11-12: LGTM!

lib/src/rust/api/user_search.dart (1)

15-15: LGTM!

lib/src/rust/api/users.dart (1)

18-18: LGTM!

lib/providers/offline_provider.dart (1)

6-6: LGTM!

Also applies to: 9-21, 23-51, 69-79, 84-85, 90-90, 97-97

lib/screens/signup_screen.dart (1)

77-79: LGTM!

Also applies to: 152-157, 244-246, 298-300, 323-325

lib/screens/chat_invite_screen.dart (2)

250-250: LGTM!

Also applies to: 258-258


319-322: LGTM!

Also applies to: 387-393, 417-417

lib/screens/profile_keys_screen.dart (2)

34-40: LGTM!


81-81: LGTM!

Also applies to: 97-97

lib/screens/set_up_group_screen.dart (3)

26-26: LGTM!

Also applies to: 45-51


99-99: LGTM!

Also applies to: 159-159


189-210: LGTM!

Also applies to: 224-248

lib/screens/settings_screen.dart (2)

83-83: LGTM!


111-111: LGTM!

Also applies to: 129-129

lib/screens/switch_profile_screen.dart (2)

28-32: LGTM!


111-113: LGTM!

Also applies to: 143-143

lib/screens/user_selection_screen.dart (2)

58-58: LGTM!

Also applies to: 77-77


145-147: LGTM!

Also applies to: 153-155, 164-166

lib/widgets/wn_auth_buttons_container.dart (1)

26-26: LGTM!

Also applies to: 34-34

pubspec.yaml (1)

80-81: LGTM!

justfile (1)

55-57: LGTM!

Also applies to: 147-153, 171-207, 211-218, 300-305, 328-388, 420-420, 432-432, 444-446

test/main_test.dart (1)

102-113: LGTM!

test/providers/offline_provider_test.dart (1)

206-230: LGTM!

Also applies to: 232-254

integration_test/basic_messaging_flow_test.dart (1)

1-305: LGTM!

Also applies to: 314-435

Comment thread integration_test/basic_messaging_flow_test.dart
Comment thread lib/src/rust/api.dart
@github-actions
Copy link
Copy Markdown

github-actions Bot commented May 15, 2026

❌ Coverage: 99.39% → 99.35% (-0.04%)

History
  • 82fdb72 2026-05-15 23:53:46 UTC — 99.35% (-0.03% vs base)
  • 23a57c0 2026-05-16 00:26:16 UTC — 99.35% (-0.03% vs base)
  • a0917ff 2026-05-17 22:32:24 UTC — 99.35% (-0.04% vs base)

Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
rust/src/api/mod.rs (1)

67-78: ⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

Update the create_whitenoise_config example to match the new signature.

The example still calls create_whitenoise_config with two arguments, but the function now requires default_relay_urls as a third parameter.

Suggested doc fix
 /// let config = create_whitenoise_config(
 ///     "/path/to/data".to_string(),
-///     "/path/to/logs".to_string()
+///     "/path/to/logs".to_string(),
+///     None,
 /// );
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@rust/src/api/mod.rs` around lines 67 - 78, Update the code example for
create_whitenoise_config to pass the new third parameter default_relay_urls
(e.g., Some(Vec<String>) or None as appropriate) so it matches the current
function signature; locate the example block in the doc comment around
create_whitenoise_config and add the third argument (default_relay_urls) when
calling create_whitenoise_config to reflect the updated API.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Outside diff comments:
In `@rust/src/api/mod.rs`:
- Around line 67-78: Update the code example for create_whitenoise_config to
pass the new third parameter default_relay_urls (e.g., Some(Vec<String>) or None
as appropriate) so it matches the current function signature; locate the example
block in the doc comment around create_whitenoise_config and add the third
argument (default_relay_urls) when calling create_whitenoise_config to reflect
the updated API.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Pro

Run ID: 74e5f0cd-96a5-438e-98f6-94610eb05b70

📥 Commits

Reviewing files that changed from the base of the PR and between 3023d37 and af047db.

⛔ Files ignored due to path filters (4)
  • ios/Podfile.lock is excluded by !**/*.lock
  • lib/src/rust/frb_generated.dart is excluded by !lib/src/rust/frb_generated.dart
  • pubspec.lock is excluded by !**/*.lock, !pubspec.lock
  • rust/src/frb_generated.rs is excluded by !rust/src/frb_generated.rs
📒 Files selected for processing (30)
  • integration_test/basic_messaging_flow_test.dart
  • justfile
  • lib/providers/offline_provider.dart
  • lib/screens/chat_invite_screen.dart
  • lib/screens/profile_keys_screen.dart
  • lib/screens/set_up_group_screen.dart
  • lib/screens/settings_screen.dart
  • lib/screens/signup_screen.dart
  • lib/screens/switch_profile_screen.dart
  • lib/screens/user_selection_screen.dart
  • lib/src/rust/api.dart
  • lib/src/rust/api/accounts.dart
  • lib/src/rust/api/chat_list.dart
  • lib/src/rust/api/group_state.dart
  • lib/src/rust/api/groups.dart
  • lib/src/rust/api/messages.dart
  • lib/src/rust/api/notifications.dart
  • lib/src/rust/api/relay_defaults.dart
  • lib/src/rust/api/user_search.dart
  • lib/src/rust/api/users.dart
  • lib/widgets/wn_auth_buttons_container.dart
  • pubspec.yaml
  • rust/src/api/accounts.rs
  • rust/src/api/bug_report.rs
  • rust/src/api/mod.rs
  • rust/src/api/relay_defaults.rs
  • rust_builder/cargokit/build_tool/lib/src/builder.dart
  • rust_builder/cargokit/build_tool/lib/src/rustup.dart
  • test/main_test.dart
  • test/providers/offline_provider_test.dart
📜 Review details
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (5)
  • GitHub Check: Test (2/4)
  • GitHub Check: Test (3/4)
  • GitHub Check: Test (4/4)
  • GitHub Check: Test (1/4)
  • GitHub Check: Check
🧰 Additional context used
📓 Path-based instructions (14)
**/*.dart

📄 CodeRabbit inference engine (AGENTS.md)

**/*.dart: Use single quotes for strings in Dart/Flutter code
Enable and respect prefer_const_constructors lint rule in Dart/Flutter code
Enable and respect prefer_final_locals lint rule in Dart/Flutter code
Set line width to 100 characters in Dart/Flutter code
Preserve trailing commas in Dart/Flutter code
Maintain minimum test coverage of 99%; never submit a PR that reduces test coverage
Avoid using // coverage:ignore, // coverage:ignore-line, // coverage:ignore-start, or // coverage:ignore-end to bypass coverage requirements; write tests instead (only exception: truly unreachable code)

Files:

  • lib/src/rust/api/user_search.dart
  • lib/src/rust/api/users.dart
  • lib/src/rust/api/accounts.dart
  • lib/src/rust/api/groups.dart
  • lib/src/rust/api/relay_defaults.dart
  • lib/screens/settings_screen.dart
  • lib/screens/user_selection_screen.dart
  • lib/screens/chat_invite_screen.dart
  • lib/src/rust/api/group_state.dart
  • rust_builder/cargokit/build_tool/lib/src/builder.dart
  • lib/src/rust/api.dart
  • lib/screens/profile_keys_screen.dart
  • lib/widgets/wn_auth_buttons_container.dart
  • test/providers/offline_provider_test.dart
  • lib/src/rust/api/messages.dart
  • lib/src/rust/api/notifications.dart
  • lib/screens/switch_profile_screen.dart
  • rust_builder/cargokit/build_tool/lib/src/rustup.dart
  • lib/screens/set_up_group_screen.dart
  • test/main_test.dart
  • lib/providers/offline_provider.dart
  • lib/screens/signup_screen.dart
  • lib/src/rust/api/chat_list.dart
  • integration_test/basic_messaging_flow_test.dart
**/*.{dart,rs}

📄 CodeRabbit inference engine (AGENTS.md)

Do not add comments except for code that is really complex or hard to understand

Files:

  • lib/src/rust/api/user_search.dart
  • lib/src/rust/api/users.dart
  • lib/src/rust/api/accounts.dart
  • lib/src/rust/api/groups.dart
  • lib/src/rust/api/relay_defaults.dart
  • lib/screens/settings_screen.dart
  • lib/screens/user_selection_screen.dart
  • lib/screens/chat_invite_screen.dart
  • lib/src/rust/api/group_state.dart
  • rust_builder/cargokit/build_tool/lib/src/builder.dart
  • rust/src/api/accounts.rs
  • lib/src/rust/api.dart
  • lib/screens/profile_keys_screen.dart
  • lib/widgets/wn_auth_buttons_container.dart
  • test/providers/offline_provider_test.dart
  • lib/src/rust/api/messages.dart
  • lib/src/rust/api/notifications.dart
  • lib/screens/switch_profile_screen.dart
  • rust/src/api/bug_report.rs
  • rust/src/api/mod.rs
  • rust_builder/cargokit/build_tool/lib/src/rustup.dart
  • lib/screens/set_up_group_screen.dart
  • test/main_test.dart
  • rust/src/api/relay_defaults.rs
  • lib/providers/offline_provider.dart
  • lib/screens/signup_screen.dart
  • lib/src/rust/api/chat_list.dart
  • integration_test/basic_messaging_flow_test.dart
lib/**/*.dart

📄 CodeRabbit inference engine (AGENTS.md)

lib/**/*.dart: Use flutter_screenutil for all size values (padding, margins, gaps, icon sizes, font sizes, border radius, container dimensions) to ensure responsive layouts. Use .w for width, .h for height, .sp for font size/letter spacing, and .r for radius
Avoid StatefulWidget; prefer providers (for shared app-wide state) or hooks (for widget-local state) instead

Files:

  • lib/src/rust/api/user_search.dart
  • lib/src/rust/api/users.dart
  • lib/src/rust/api/accounts.dart
  • lib/src/rust/api/groups.dart
  • lib/src/rust/api/relay_defaults.dart
  • lib/screens/settings_screen.dart
  • lib/screens/user_selection_screen.dart
  • lib/screens/chat_invite_screen.dart
  • lib/src/rust/api/group_state.dart
  • lib/src/rust/api.dart
  • lib/screens/profile_keys_screen.dart
  • lib/widgets/wn_auth_buttons_container.dart
  • lib/src/rust/api/messages.dart
  • lib/src/rust/api/notifications.dart
  • lib/screens/switch_profile_screen.dart
  • lib/screens/set_up_group_screen.dart
  • lib/providers/offline_provider.dart
  • lib/screens/signup_screen.dart
  • lib/src/rust/api/chat_list.dart
lib/src/rust/**/*.dart

📄 CodeRabbit inference engine (AGENTS.md)

Do not manually edit files in lib/src/rust/ as they are auto-generated by flutter_rust_bridge

Files:

  • lib/src/rust/api/user_search.dart
  • lib/src/rust/api/users.dart
  • lib/src/rust/api/accounts.dart
  • lib/src/rust/api/groups.dart
  • lib/src/rust/api/relay_defaults.dart
  • lib/src/rust/api/group_state.dart
  • lib/src/rust/api.dart
  • lib/src/rust/api/messages.dart
  • lib/src/rust/api/notifications.dart
  • lib/src/rust/api/chat_list.dart
lib/screens/**

⚙️ CodeRabbit configuration file

lib/screens/**: This is a Flutter screen (full-page widget).
Architecture rules:

  • Screens should WATCH Riverpod providers for shared state
  • Use flutter_hooks for ephemeral/local state (NOT StatefulWidget)
  • Pass data to hooks, not refs
  • Use flutter_screenutil (.w, .h, .sp, .r) for all size values
  • Widgets should use const constructors where possible
  • No comments except for truly complex logic
  • When a widget is extracted from a screen and only used in that one
    screen, it should be prefixed with the screen name (e.g.
    ChatListTile for a widget only used in the chat list screen).
    These are screen-scoped widgets and do NOT use the Wn prefix.

Files:

  • lib/screens/settings_screen.dart
  • lib/screens/user_selection_screen.dart
  • lib/screens/chat_invite_screen.dart
  • lib/screens/profile_keys_screen.dart
  • lib/screens/switch_profile_screen.dart
  • lib/screens/set_up_group_screen.dart
  • lib/screens/signup_screen.dart
rust/src/api/**/*.rs

📄 CodeRabbit inference engine (AGENTS.md)

rust/src/api/**/*.rs: Rust API modules in rust/src/api/ must be exposed to Flutter with #[frb] attribute on functions
Rust structs exposed to Flutter must use #[frb(non_opaque)] attribute for Flutter compatibility
Wrap Rust API errors in ApiError enum using thiserror crate

Files:

  • rust/src/api/accounts.rs
  • rust/src/api/bug_report.rs
  • rust/src/api/mod.rs
  • rust/src/api/relay_defaults.rs
rust/src/api/**

⚙️ CodeRabbit configuration file

rust/src/api/**: This is the Rust API layer exposed to Flutter via flutter_rust_bridge.
Rules:

  • Functions use #[frb] attribute for bridge generation
  • Structs use #[frb(non_opaque)] for Flutter compatibility
  • Errors must be wrapped in the ApiError enum using thiserror
  • This is a thin wrapper around the whitenoise crate — keep it thin
  • No unwrap() in non-test code; use proper error handling
  • Check for correct async patterns

Files:

  • rust/src/api/accounts.rs
  • rust/src/api/bug_report.rs
  • rust/src/api/mod.rs
  • rust/src/api/relay_defaults.rs
lib/widgets/wn_*.dart

📄 CodeRabbit inference engine (AGENTS.md)

lib/widgets/wn_*.dart: Design system widgets should be prefixed with wn_ in filename and Wn in class name (e.g., wn_filled_button.dart / WnFilledButton)
Design system widgets must have Widgetbook stories and should not contain translations or Rust API calls

Files:

  • lib/widgets/wn_auth_buttons_container.dart
lib/widgets/*.dart

📄 CodeRabbit inference engine (AGENTS.md)

Screen-scoped widgets extracted from a single screen should be prefixed with the screen name and only used in that one screen

Files:

  • lib/widgets/wn_auth_buttons_container.dart
lib/widgets/**

⚙️ CodeRabbit configuration file

lib/widgets/**: This is a reusable widget.
There are two kinds of reusable widgets:

  1. Design system widgets — simple, presentational widgets that match
    the Figma design system in name and structure. They have Widgetbook
    stories, contain only presentational logic, and do NOT have
    translations or Rust API calls.

    • File MUST be prefixed with wn_ (e.g. wn_filled_button.dart)
    • Class MUST be prefixed with Wn (e.g. WnFilledButton)
  2. Complex reusable widgets — used across multiple screens but contain
    translations, hooks with Rust API calls, or other complex logic
    that makes them harder to display in Widgetbook.

    • These do NOT use the wn_/Wn prefix
    • Example: OnboardingCarousel (used in multiple screens, has
      translations and a page controller inside)

General rules for all widgets in this directory:

  • Use const constructors where possible
  • Use flutter_screenutil (.w, .h, .sp, .r) for all dimensions
  • Avoid StatefulWidget — prefer hooks for local state
  • No comments except for truly complex logic

Files:

  • lib/widgets/wn_auth_buttons_container.dart
test/**/*_test.dart

📄 CodeRabbit inference engine (AGENTS.md)

test/**/*_test.dart: Test files should mirror source structure with _test.dart suffix
Use helpers from test/test_helpers.dart in tests: setUpTestView(), mountTestApp(), mountHook(), mountWidget(), mountStackedWidget()
Mock Rust API by extending MockWnApi from test/mocks/mock_wn_api.dart instead of implementing RustLibApi directly
Prefer find.byKey() over find.byIcon() in tests; add keys to icons in widgets and use find.byKey(const Key('icon_name')) in tests
Use valid 64-character hex strings for pubkeys in tests, not dummy values like 'abc' or 'test-pubkey'

Files:

  • test/providers/offline_provider_test.dart
  • test/main_test.dart
test/**

⚙️ CodeRabbit configuration file

test/**: IMPORTANT: CI enforces coverage regression (coverage must never decrease). It does not enforce a fixed 95% minimum threshold.
Rules:

  • Test files mirror source structure with _test.dart suffix
  • Use helpers from test/test_helpers.dart (setUpTestView, mountTestApp, etc.)
  • Mock Rust API using RustLib.initMock(api: mockApi)
  • Always extend MockWnApi from test/mocks/mock_wn_api.dart
  • Prefer find.byKey() over find.byIcon() for widget testing
  • Use valid 64-char hex strings for pubkeys, not dummy values like 'abc'
  • Tests must be deterministic — no external service dependencies

Files:

  • test/providers/offline_provider_test.dart
  • test/main_test.dart
lib/providers/*_provider.dart

📄 CodeRabbit inference engine (AGENTS.md)

lib/providers/*_provider.dart: Provider files should end with _provider.dart (e.g., auth_provider.dart)
Provider variables should end with Provider (e.g., authProvider)

Files:

  • lib/providers/offline_provider.dart
lib/providers/**

⚙️ CodeRabbit configuration file

lib/providers/**: This is a Riverpod provider (shared app-wide state).
Rules:

  • Files must end with _provider.dart
  • Provider variables must end with Provider (e.g. authProvider)
  • Don't duplicate logic from the Rust crate — whitenoise is source of truth
  • Don't cache data that whitenoise already persists in its local DB

Files:

  • lib/providers/offline_provider.dart
🧠 Learnings (32)
📚 Learning: 2026-01-05T20:05:32.918Z
Learnt from: untreu2
Repo: marmot-protocol/sloth PR: 22
File: lib/screens/settings_screen.dart:76-88
Timestamp: 2026-01-05T20:05:32.918Z
Learning: In the Sloth project, tooltips should not be used for UI elements. During code reviews, verify that UI components do not include Tooltip widgets and replace them with accessible alternatives (e.g., long-press hints, labels, or interactive guidance). Apply this guidance across Dart UI files under lib (not just settings_screen.dart) to maintain a consistent design approach.

Applied to files:

  • lib/src/rust/api/user_search.dart
  • lib/src/rust/api/users.dart
  • lib/src/rust/api/accounts.dart
  • lib/src/rust/api/groups.dart
  • lib/src/rust/api/relay_defaults.dart
  • lib/screens/settings_screen.dart
  • lib/screens/user_selection_screen.dart
  • lib/screens/chat_invite_screen.dart
  • lib/src/rust/api/group_state.dart
  • lib/src/rust/api.dart
  • lib/screens/profile_keys_screen.dart
  • lib/widgets/wn_auth_buttons_container.dart
  • lib/src/rust/api/messages.dart
  • lib/src/rust/api/notifications.dart
  • lib/screens/switch_profile_screen.dart
  • lib/screens/set_up_group_screen.dart
  • lib/providers/offline_provider.dart
  • lib/screens/signup_screen.dart
  • lib/src/rust/api/chat_list.dart
📚 Learning: 2026-01-09T13:25:18.531Z
Learnt from: josefinalliende
Repo: marmot-protocol/sloth PR: 33
File: lib/services/message_service.dart:14-26
Timestamp: 2026-01-09T13:25:18.531Z
Learning: When errors are presented to users in the Sloth codebase (UI layers such as snackbars, dialogs, toasts), show friendly, user-facing messages instead of raw Rust error messages. Implement a mapping from internal error types or codes to clear, non-technical messages, and surface actionable guidance for end users where appropriate. Avoid exposing internal stack traces or language runtime details; centralize common user-facing error wording in a dedicated utility or service and translate backend errors into concise, helpful UI messages.

Applied to files:

  • lib/src/rust/api/user_search.dart
  • lib/src/rust/api/users.dart
  • lib/src/rust/api/accounts.dart
  • lib/src/rust/api/groups.dart
  • lib/src/rust/api/relay_defaults.dart
  • lib/screens/settings_screen.dart
  • lib/screens/user_selection_screen.dart
  • lib/screens/chat_invite_screen.dart
  • lib/src/rust/api/group_state.dart
  • lib/src/rust/api.dart
  • lib/screens/profile_keys_screen.dart
  • lib/widgets/wn_auth_buttons_container.dart
  • lib/src/rust/api/messages.dart
  • lib/src/rust/api/notifications.dart
  • lib/screens/switch_profile_screen.dart
  • lib/screens/set_up_group_screen.dart
  • lib/providers/offline_provider.dart
  • lib/screens/signup_screen.dart
  • lib/src/rust/api/chat_list.dart
📚 Learning: 2026-04-06T09:40:41.044Z
Learnt from: untreu2
Repo: marmot-protocol/whitenoise PR: 552
File: lib/screens/profile_keys_screen.dart:71-71
Timestamp: 2026-04-06T09:40:41.044Z
Learning: In this Flutter/Dart codebase, when using flutter_screenutil (e.g., ScreenUtil or ScreenUtil-based sizing like `w`, `h`), do not require scaled units for literal zero values. Specifically, in EdgeInsets (and similar sizing/padding/margin/gap APIs), bare numeric `0` should be allowed (e.g., `EdgeInsets.all(0)`, `EdgeInsets.symmetric(vertical: 0)`, `SizedBox(width: 0)`), because scaling `0` remains `0`. Only flag ScreenUtil violations when a non-zero literal needs to be expressed via `0.w`/`0.h` equivalents; do not flag bare `0`.

Applied to files:

  • lib/src/rust/api/user_search.dart
  • lib/src/rust/api/users.dart
  • lib/src/rust/api/accounts.dart
  • lib/src/rust/api/groups.dart
  • lib/src/rust/api/relay_defaults.dart
  • lib/screens/settings_screen.dart
  • lib/screens/user_selection_screen.dart
  • lib/screens/chat_invite_screen.dart
  • lib/src/rust/api/group_state.dart
  • lib/src/rust/api.dart
  • lib/screens/profile_keys_screen.dart
  • lib/widgets/wn_auth_buttons_container.dart
  • lib/src/rust/api/messages.dart
  • lib/src/rust/api/notifications.dart
  • lib/screens/switch_profile_screen.dart
  • lib/screens/set_up_group_screen.dart
  • lib/providers/offline_provider.dart
  • lib/screens/signup_screen.dart
  • lib/src/rust/api/chat_list.dart
📚 Learning: 2026-01-06T01:08:41.552Z
Learnt from: untreu2
Repo: marmot-protocol/sloth PR: 22
File: lib/widgets/wn_warning_box.dart:28-79
Timestamp: 2026-01-06T01:08:41.552Z
Learning: In reviews for the marmot-protocol/sloth repository, avoid suggesting accessibility, design, or general improvements unless they are strictly relevant to the PR description and its stated goals. Focus feedback on the specific PR objectives and requirements; ignore unrelated stylistic or broad improvement suggestions.

Applied to files:

  • lib/src/rust/api/user_search.dart
  • lib/src/rust/api/users.dart
  • lib/src/rust/api/accounts.dart
  • lib/src/rust/api/groups.dart
  • lib/src/rust/api/relay_defaults.dart
  • lib/screens/settings_screen.dart
  • lib/screens/user_selection_screen.dart
  • lib/screens/chat_invite_screen.dart
  • lib/src/rust/api/group_state.dart
  • rust_builder/cargokit/build_tool/lib/src/builder.dart
  • lib/src/rust/api.dart
  • lib/screens/profile_keys_screen.dart
  • lib/widgets/wn_auth_buttons_container.dart
  • test/providers/offline_provider_test.dart
  • lib/src/rust/api/messages.dart
  • lib/src/rust/api/notifications.dart
  • lib/screens/switch_profile_screen.dart
  • rust_builder/cargokit/build_tool/lib/src/rustup.dart
  • lib/screens/set_up_group_screen.dart
  • test/main_test.dart
  • lib/providers/offline_provider.dart
  • lib/screens/signup_screen.dart
  • lib/src/rust/api/chat_list.dart
  • integration_test/basic_messaging_flow_test.dart
📚 Learning: 2026-01-15T14:42:54.111Z
Learnt from: josefinalliende
Repo: marmot-protocol/sloth PR: 39
File: lib/hooks/use_user_search.dart:47-53
Timestamp: 2026-01-15T14:42:54.111Z
Learning: When using npubFromHex(String hexPubkey) from lib/utils/formatting.dart, it already handles errors internally and returns null on failure. Do not wrap calls to this function in try/catch blocks. Instead, check for a null return and handle accordingly (e.g., treat as invalid hex). This guideline applies to all Dart files in the repository that may call this function.

Applied to files:

  • lib/src/rust/api/user_search.dart
  • lib/src/rust/api/users.dart
  • lib/src/rust/api/accounts.dart
  • lib/src/rust/api/groups.dart
  • lib/src/rust/api/relay_defaults.dart
  • lib/screens/settings_screen.dart
  • lib/screens/user_selection_screen.dart
  • lib/screens/chat_invite_screen.dart
  • lib/src/rust/api/group_state.dart
  • rust_builder/cargokit/build_tool/lib/src/builder.dart
  • lib/src/rust/api.dart
  • lib/screens/profile_keys_screen.dart
  • lib/widgets/wn_auth_buttons_container.dart
  • test/providers/offline_provider_test.dart
  • lib/src/rust/api/messages.dart
  • lib/src/rust/api/notifications.dart
  • lib/screens/switch_profile_screen.dart
  • rust_builder/cargokit/build_tool/lib/src/rustup.dart
  • lib/screens/set_up_group_screen.dart
  • test/main_test.dart
  • lib/providers/offline_provider.dart
  • lib/screens/signup_screen.dart
  • lib/src/rust/api/chat_list.dart
  • integration_test/basic_messaging_flow_test.dart
📚 Learning: 2026-01-16T17:35:32.431Z
Learnt from: untreu2
Repo: marmot-protocol/sloth PR: 43
File: lib/hooks/use_network_relays.dart:155-184
Timestamp: 2026-01-16T17:35:32.431Z
Learning: In Dart/Flutter code, prefer void as the return type for fire-and-forget async functions that are intended to run in the background without blocking the caller. Using Future or Future<void> would allow callers to accidentally await, which could block for long periods. This pattern makes the call fire-and-forget by design. Apply to functions that intentionally should not be awaited; document the intent where appropriate. (Example context: pollRelayStatus in lib/hooks/use_network_relays.dart uses void to prevent callers from awaiting a potentially long-running background task.)

Applied to files:

  • lib/src/rust/api/user_search.dart
  • lib/src/rust/api/users.dart
  • lib/src/rust/api/accounts.dart
  • lib/src/rust/api/groups.dart
  • lib/src/rust/api/relay_defaults.dart
  • lib/screens/settings_screen.dart
  • lib/screens/user_selection_screen.dart
  • lib/screens/chat_invite_screen.dart
  • lib/src/rust/api/group_state.dart
  • rust_builder/cargokit/build_tool/lib/src/builder.dart
  • lib/src/rust/api.dart
  • lib/screens/profile_keys_screen.dart
  • lib/widgets/wn_auth_buttons_container.dart
  • test/providers/offline_provider_test.dart
  • lib/src/rust/api/messages.dart
  • lib/src/rust/api/notifications.dart
  • lib/screens/switch_profile_screen.dart
  • rust_builder/cargokit/build_tool/lib/src/rustup.dart
  • lib/screens/set_up_group_screen.dart
  • test/main_test.dart
  • lib/providers/offline_provider.dart
  • lib/screens/signup_screen.dart
  • lib/src/rust/api/chat_list.dart
  • integration_test/basic_messaging_flow_test.dart
📚 Learning: 2026-01-19T15:50:56.684Z
Learnt from: erskingardner
Repo: marmot-protocol/sloth PR: 52
File: lib/screens/app_settings_screen.dart:30-40
Timestamp: 2026-01-19T15:50:56.684Z
Learning: Target the Flutter SDK version >= 3.27 across the repo. Since features like Column.spacing and Row.spacing were added in Flutter 3.27, you can safely use them in Dart files (e.g., lib/screens/app_settings_screen.dart) as long as the pubspec.yaml environment specifies Flutter >= 3.27. If needed, enforce this by validating the environment constraint (e.g., flutter, sdk: flutter) in pubspec.yaml.

Applied to files:

  • lib/src/rust/api/user_search.dart
  • lib/src/rust/api/users.dart
  • lib/src/rust/api/accounts.dart
  • lib/src/rust/api/groups.dart
  • lib/src/rust/api/relay_defaults.dart
  • lib/screens/settings_screen.dart
  • lib/screens/user_selection_screen.dart
  • lib/screens/chat_invite_screen.dart
  • lib/src/rust/api/group_state.dart
  • rust_builder/cargokit/build_tool/lib/src/builder.dart
  • lib/src/rust/api.dart
  • lib/screens/profile_keys_screen.dart
  • lib/widgets/wn_auth_buttons_container.dart
  • test/providers/offline_provider_test.dart
  • lib/src/rust/api/messages.dart
  • lib/src/rust/api/notifications.dart
  • lib/screens/switch_profile_screen.dart
  • rust_builder/cargokit/build_tool/lib/src/rustup.dart
  • lib/screens/set_up_group_screen.dart
  • test/main_test.dart
  • lib/providers/offline_provider.dart
  • lib/screens/signup_screen.dart
  • lib/src/rust/api/chat_list.dart
  • integration_test/basic_messaging_flow_test.dart
📚 Learning: 2026-01-29T03:02:34.290Z
Learnt from: josefinalliende
Repo: marmot-protocol/sloth PR: 100
File: lib/widgets/wn_dropdown_selector.dart:126-139
Timestamp: 2026-01-29T03:02:34.290Z
Learning: Global font-family usage guideline: Since Manrope is configured in lib/theme.dart for both light and dark themes, individual TextStyle declarations should not specify fontFamily: 'Manrope'. During reviews, verify that no TextStyle instances override fontFamily unnecessarily; rely on theme inheritance instead. If a TextStyle must specify a font for a specific case, ensure it is clearly justified and localized, and document why the override is needed. This guideline applies across Dart files in the project (e.g., lib/widgets/wn_dropdown_selector.dart and related components).

Applied to files:

  • lib/src/rust/api/user_search.dart
  • lib/src/rust/api/users.dart
  • lib/src/rust/api/accounts.dart
  • lib/src/rust/api/groups.dart
  • lib/src/rust/api/relay_defaults.dart
  • lib/screens/settings_screen.dart
  • lib/screens/user_selection_screen.dart
  • lib/screens/chat_invite_screen.dart
  • lib/src/rust/api/group_state.dart
  • rust_builder/cargokit/build_tool/lib/src/builder.dart
  • lib/src/rust/api.dart
  • lib/screens/profile_keys_screen.dart
  • lib/widgets/wn_auth_buttons_container.dart
  • test/providers/offline_provider_test.dart
  • lib/src/rust/api/messages.dart
  • lib/src/rust/api/notifications.dart
  • lib/screens/switch_profile_screen.dart
  • rust_builder/cargokit/build_tool/lib/src/rustup.dart
  • lib/screens/set_up_group_screen.dart
  • test/main_test.dart
  • lib/providers/offline_provider.dart
  • lib/screens/signup_screen.dart
  • lib/src/rust/api/chat_list.dart
  • integration_test/basic_messaging_flow_test.dart
📚 Learning: 2026-01-29T16:02:52.588Z
Learnt from: erskingardner
Repo: marmot-protocol/sloth PR: 129
File: test/widgets/wn_overlay_test.dart:84-91
Timestamp: 2026-01-29T16:02:52.588Z
Learning: In Dart/Flutter code, when constructing widgets inside an already-const context (for example, within a const Scaffold with a child that is a collection of widgets), avoid adding explicit const keywords to the children. The Dart analyzer treats these as implicitly const, and adding explicit const can trigger the unnecessary_const lint. Review test files and general Dart files to ensure you do not redundantly prefix children with const in const contexts; rely on the implicit const behavior instead.

Applied to files:

  • lib/src/rust/api/user_search.dart
  • lib/src/rust/api/users.dart
  • lib/src/rust/api/accounts.dart
  • lib/src/rust/api/groups.dart
  • lib/src/rust/api/relay_defaults.dart
  • lib/screens/settings_screen.dart
  • lib/screens/user_selection_screen.dart
  • lib/screens/chat_invite_screen.dart
  • lib/src/rust/api/group_state.dart
  • rust_builder/cargokit/build_tool/lib/src/builder.dart
  • lib/src/rust/api.dart
  • lib/screens/profile_keys_screen.dart
  • lib/widgets/wn_auth_buttons_container.dart
  • test/providers/offline_provider_test.dart
  • lib/src/rust/api/messages.dart
  • lib/src/rust/api/notifications.dart
  • lib/screens/switch_profile_screen.dart
  • rust_builder/cargokit/build_tool/lib/src/rustup.dart
  • lib/screens/set_up_group_screen.dart
  • test/main_test.dart
  • lib/providers/offline_provider.dart
  • lib/screens/signup_screen.dart
  • lib/src/rust/api/chat_list.dart
  • integration_test/basic_messaging_flow_test.dart
📚 Learning: 2026-02-07T03:58:22.587Z
Learnt from: josefinalliende
Repo: marmot-protocol/sloth PR: 193
File: lib/services/android_signer_service.dart:13-13
Timestamp: 2026-02-07T03:58:22.587Z
Learning: In Dart files across the repository, retain NIP (Nostr Implementation Possibilities) and MIP (Marmot Implementation Possibilities) protocol reference comments that link code to their specifications. While general guidance discourages extraneous comments, these references improve traceability and maintainability by documenting the protocol context for related implementation details. Keep them in Dart sources (e.g., lib/services/android_signer_service.dart) and ensure they are kept up-to-date.

Applied to files:

  • lib/src/rust/api/user_search.dart
  • lib/src/rust/api/users.dart
  • lib/src/rust/api/accounts.dart
  • lib/src/rust/api/groups.dart
  • lib/src/rust/api/relay_defaults.dart
  • lib/screens/settings_screen.dart
  • lib/screens/user_selection_screen.dart
  • lib/screens/chat_invite_screen.dart
  • lib/src/rust/api/group_state.dart
  • rust_builder/cargokit/build_tool/lib/src/builder.dart
  • lib/src/rust/api.dart
  • lib/screens/profile_keys_screen.dart
  • lib/widgets/wn_auth_buttons_container.dart
  • test/providers/offline_provider_test.dart
  • lib/src/rust/api/messages.dart
  • lib/src/rust/api/notifications.dart
  • lib/screens/switch_profile_screen.dart
  • rust_builder/cargokit/build_tool/lib/src/rustup.dart
  • lib/screens/set_up_group_screen.dart
  • test/main_test.dart
  • lib/providers/offline_provider.dart
  • lib/screens/signup_screen.dart
  • lib/src/rust/api/chat_list.dart
  • integration_test/basic_messaging_flow_test.dart
📚 Learning: 2026-02-11T17:29:43.985Z
Learnt from: untreu2
Repo: marmot-protocol/whitenoise PR: 225
File: lib/screens/app_settings_screen.dart:64-69
Timestamp: 2026-02-11T17:29:43.985Z
Learning: In the whitenoise Flutter app, after deleting all data and resetting auth, use Routes.goToHome(context) instead of Routes.goToLogin(context) because the home screen is the app entry point and will manage authentication routing. Apply this change to navigation calls that should land on the home screen after a data reset or auth reset. Update lib/screens/app_settings_screen.dart and any similar navigation points accordingly.

Applied to files:

  • lib/src/rust/api/user_search.dart
  • lib/src/rust/api/users.dart
  • lib/src/rust/api/accounts.dart
  • lib/src/rust/api/groups.dart
  • lib/src/rust/api/relay_defaults.dart
  • lib/screens/settings_screen.dart
  • lib/screens/user_selection_screen.dart
  • lib/screens/chat_invite_screen.dart
  • lib/src/rust/api/group_state.dart
  • rust_builder/cargokit/build_tool/lib/src/builder.dart
  • lib/src/rust/api.dart
  • lib/screens/profile_keys_screen.dart
  • lib/widgets/wn_auth_buttons_container.dart
  • test/providers/offline_provider_test.dart
  • lib/src/rust/api/messages.dart
  • lib/src/rust/api/notifications.dart
  • lib/screens/switch_profile_screen.dart
  • rust_builder/cargokit/build_tool/lib/src/rustup.dart
  • lib/screens/set_up_group_screen.dart
  • test/main_test.dart
  • lib/providers/offline_provider.dart
  • lib/screens/signup_screen.dart
  • lib/src/rust/api/chat_list.dart
  • integration_test/basic_messaging_flow_test.dart
📚 Learning: 2026-02-18T18:36:13.394Z
Learnt from: untreu2
Repo: marmot-protocol/whitenoise PR: 315
File: lib/screens/edit_group_screen.dart:45-47
Timestamp: 2026-02-18T18:36:13.394Z
Learning: Whitenoise uses automated code formatting through the precommit workflow (just precommit). Do not tweak line wrapping or formatting manually; follow the formatter's output. Run the precommit formatter locally and ensure the code matches its styling decisions, and only deviate if the formatter cannot express the intended style (in which case adjust the code to satisfy the formatter).

Applied to files:

  • lib/src/rust/api/user_search.dart
  • lib/src/rust/api/users.dart
  • lib/src/rust/api/accounts.dart
  • lib/src/rust/api/groups.dart
  • lib/src/rust/api/relay_defaults.dart
  • lib/screens/settings_screen.dart
  • lib/screens/user_selection_screen.dart
  • lib/screens/chat_invite_screen.dart
  • lib/src/rust/api/group_state.dart
  • rust_builder/cargokit/build_tool/lib/src/builder.dart
  • lib/src/rust/api.dart
  • lib/screens/profile_keys_screen.dart
  • lib/widgets/wn_auth_buttons_container.dart
  • test/providers/offline_provider_test.dart
  • lib/src/rust/api/messages.dart
  • lib/src/rust/api/notifications.dart
  • lib/screens/switch_profile_screen.dart
  • rust_builder/cargokit/build_tool/lib/src/rustup.dart
  • lib/screens/set_up_group_screen.dart
  • test/main_test.dart
  • lib/providers/offline_provider.dart
  • lib/screens/signup_screen.dart
  • lib/src/rust/api/chat_list.dart
  • integration_test/basic_messaging_flow_test.dart
📚 Learning: 2026-04-06T09:36:06.726Z
Learnt from: untreu2
Repo: marmot-protocol/whitenoise PR: 553
File: lib/widgets/wn_copyable_field.dart:38-40
Timestamp: 2026-04-06T09:36:06.726Z
Learning: In Dart, `String.operator*` is a valid built-in operator for repeating strings (e.g., `'⬤' * 16`). In code reviews of Dart (`.dart`) files, do not treat expressions like `'text' * n` as invalid syntax and do not recommend replacing them with alternatives such as `List.filled(...).join()`; the operator is supported by `dart:core`.

Applied to files:

  • lib/src/rust/api/user_search.dart
  • lib/src/rust/api/users.dart
  • lib/src/rust/api/accounts.dart
  • lib/src/rust/api/groups.dart
  • lib/src/rust/api/relay_defaults.dart
  • lib/screens/settings_screen.dart
  • lib/screens/user_selection_screen.dart
  • lib/screens/chat_invite_screen.dart
  • lib/src/rust/api/group_state.dart
  • rust_builder/cargokit/build_tool/lib/src/builder.dart
  • lib/src/rust/api.dart
  • lib/screens/profile_keys_screen.dart
  • lib/widgets/wn_auth_buttons_container.dart
  • test/providers/offline_provider_test.dart
  • lib/src/rust/api/messages.dart
  • lib/src/rust/api/notifications.dart
  • lib/screens/switch_profile_screen.dart
  • rust_builder/cargokit/build_tool/lib/src/rustup.dart
  • lib/screens/set_up_group_screen.dart
  • test/main_test.dart
  • lib/providers/offline_provider.dart
  • lib/screens/signup_screen.dart
  • lib/src/rust/api/chat_list.dart
  • integration_test/basic_messaging_flow_test.dart
📚 Learning: 2026-05-13T13:46:32.612Z
Learnt from: dannym-arx
Repo: marmot-protocol/whitenoise PR: 656
File: lib/hooks/use_block_actions.dart:3-3
Timestamp: 2026-05-13T13:46:32.612Z
Learning: In marmot-protocol/whitenoise code reviews, do not flag imports that reference FRB-generated bindings under `package:rust_lib_whitenoise/src/rust/...` as private-internals violations. In `rust_lib_whitenoise`, Dart bindings are intentionally generated into `lib/src/rust/`, and `analysis_options.yaml` sets `implementation_imports: false` to suppress the related Dart lint—so `package:rust_lib_whitenoise/src/rust/...` imports are the correct/only way to consume that FRB-generated API.

Applied to files:

  • lib/src/rust/api/user_search.dart
  • lib/src/rust/api/users.dart
  • lib/src/rust/api/accounts.dart
  • lib/src/rust/api/groups.dart
  • lib/src/rust/api/relay_defaults.dart
  • lib/screens/settings_screen.dart
  • lib/screens/user_selection_screen.dart
  • lib/screens/chat_invite_screen.dart
  • lib/src/rust/api/group_state.dart
  • rust_builder/cargokit/build_tool/lib/src/builder.dart
  • lib/src/rust/api.dart
  • lib/screens/profile_keys_screen.dart
  • lib/widgets/wn_auth_buttons_container.dart
  • test/providers/offline_provider_test.dart
  • lib/src/rust/api/messages.dart
  • lib/src/rust/api/notifications.dart
  • lib/screens/switch_profile_screen.dart
  • rust_builder/cargokit/build_tool/lib/src/rustup.dart
  • lib/screens/set_up_group_screen.dart
  • test/main_test.dart
  • lib/providers/offline_provider.dart
  • lib/screens/signup_screen.dart
  • lib/src/rust/api/chat_list.dart
  • integration_test/basic_messaging_flow_test.dart
📚 Learning: 2026-05-13T13:46:39.250Z
Learnt from: dannym-arx
Repo: marmot-protocol/whitenoise PR: 656
File: lib/services/foreground_service.dart:13-16
Timestamp: 2026-05-13T13:46:39.250Z
Learning: In this repo (marmot-protocol/whitenoise), `rust_lib_whitenoise` is an FRB-generated Flutter package where the generated Dart bindings are intentionally exposed under `lib/src/rust/` as the public API surface. Do not treat imports like `package:rust_lib_whitenoise/src/rust/...` as breaking package API boundaries in code reviews (the project also sets `implementation_imports: false` in `analysis_options.yaml` to opt into this). Never raise concerns about `src/` imports from `rust_lib_whitenoise`.

Applied to files:

  • lib/src/rust/api/user_search.dart
  • lib/src/rust/api/users.dart
  • lib/src/rust/api/accounts.dart
  • lib/src/rust/api/groups.dart
  • lib/src/rust/api/relay_defaults.dart
  • lib/screens/settings_screen.dart
  • lib/screens/user_selection_screen.dart
  • lib/screens/chat_invite_screen.dart
  • lib/src/rust/api/group_state.dart
  • rust_builder/cargokit/build_tool/lib/src/builder.dart
  • lib/src/rust/api.dart
  • lib/screens/profile_keys_screen.dart
  • lib/widgets/wn_auth_buttons_container.dart
  • test/providers/offline_provider_test.dart
  • lib/src/rust/api/messages.dart
  • lib/src/rust/api/notifications.dart
  • lib/screens/switch_profile_screen.dart
  • rust_builder/cargokit/build_tool/lib/src/rustup.dart
  • lib/screens/set_up_group_screen.dart
  • test/main_test.dart
  • lib/providers/offline_provider.dart
  • lib/screens/signup_screen.dart
  • lib/src/rust/api/chat_list.dart
  • integration_test/basic_messaging_flow_test.dart
📚 Learning: 2026-01-15T15:00:17.356Z
Learnt from: josefinalliende
Repo: marmot-protocol/sloth PR: 39
File: lib/screens/user_search_screen.dart:50-75
Timestamp: 2026-01-15T15:00:17.356Z
Learning: In lib/screens/user_search_screen.dart and similar screen widgets in the sloth repository, prefer using inline ternary expressions for conditional rendering (e.g., isLoading → empty state → list) over extracting into separate widget classes when the conditional UI is simple. This improves readability by keeping the render logic in a single place. Reserve extracting to a separate widget only when the conditional UI becomes sufficiently complex or is reused across multiple screens.

Applied to files:

  • lib/screens/settings_screen.dart
  • lib/screens/user_selection_screen.dart
  • lib/screens/chat_invite_screen.dart
  • lib/screens/profile_keys_screen.dart
  • lib/screens/switch_profile_screen.dart
  • lib/screens/set_up_group_screen.dart
  • lib/screens/signup_screen.dart
📚 Learning: 2026-02-10T04:57:31.475Z
Learnt from: josefinalliende
Repo: marmot-protocol/sloth PR: 208
File: lib/screens/signup_screen.dart:66-70
Timestamp: 2026-02-10T04:57:31.475Z
Learning: In Dart/Flutter using flutter_hooks, a ValueNotifier (from useState) is disposed when the widget unmounts. Async callbacks (e.g., .then() on animations) may still run after disposal and throw 'A ValueNotifier was used after being disposed'. Reviewers should ensure that state updates in async callbacks are guarded by a mounted check (e.g., if (mounted) { notifier.value = ... } or cancel/avoid updating after disposal). This guideline applies to screen widgets under lib/screens and similar Dart files using hooks that manage widget lifecycle. Update code patterns to prevent post-disposal state updates, and document the rationale in comments where necessary.

Applied to files:

  • lib/screens/settings_screen.dart
  • lib/screens/user_selection_screen.dart
  • lib/screens/chat_invite_screen.dart
  • lib/screens/profile_keys_screen.dart
  • lib/screens/switch_profile_screen.dart
  • lib/screens/set_up_group_screen.dart
  • lib/screens/signup_screen.dart
📚 Learning: 2026-02-19T10:33:16.889Z
Learnt from: untreu2
Repo: marmot-protocol/whitenoise PR: 315
File: lib/screens/group_info_screen.dart:146-149
Timestamp: 2026-02-19T10:33:16.889Z
Learning: Pubkey validation (length/format) is performed by the Rust crate before data reaches Dart. Do not add defensive substring guards in Dart for pubkeys in lib/screens/**/*.dart or other Flutter code consuming group member pubkeys, as this would duplicate validation and be unnecessary. If any validation is needed in Dart, keep it to lightweight sanity checks only after data enters Dart and ensure it aligns with the Rust validation rules.

Applied to files:

  • lib/screens/settings_screen.dart
  • lib/screens/user_selection_screen.dart
  • lib/screens/chat_invite_screen.dart
  • lib/screens/profile_keys_screen.dart
  • lib/screens/switch_profile_screen.dart
  • lib/screens/set_up_group_screen.dart
  • lib/screens/signup_screen.dart
📚 Learning: 2026-04-06T09:40:51.965Z
Learnt from: untreu2
Repo: marmot-protocol/whitenoise PR: 552
File: lib/screens/sign_out_screen.dart:86-86
Timestamp: 2026-04-06T09:40:51.965Z
Learning: When reviewing Flutter/Dart code that uses ScreenUtil (e.g., ScreenUtil `.h`/`.w`/`.sp`), do not require converting a literal `0` used for padding/margin/sizing to a ScreenUtil expression. In sizing contexts like `EdgeInsets` (or other `EdgeInsets`/layout parameters), raw `0` is mathematically invariant (`0 * scale = 0`) and should not be flagged as a ScreenUtil violation. Only non-zero literal size values should be checked for ScreenUtil usage.

Applied to files:

  • lib/screens/settings_screen.dart
  • lib/screens/user_selection_screen.dart
  • lib/screens/chat_invite_screen.dart
  • lib/screens/profile_keys_screen.dart
  • lib/screens/switch_profile_screen.dart
  • lib/screens/set_up_group_screen.dart
  • lib/screens/signup_screen.dart
📚 Learning: 2026-01-15T23:30:10.907Z
Learnt from: jgmontoya
Repo: marmot-protocol/sloth PR: 42
File: rust/src/api/account_groups.rs:107-123
Timestamp: 2026-01-15T23:30:10.907Z
Learning: In the Rust API layer under rust/src/api/, ensure functions remain thin translation wrappers that delegate business logic to the whitenoise-rs crate. Do not implement business logic or fixes in the sloth API layer; instead, move such changes to whitenoise-rs and keep the API layer focused on request/response translation and orchestration.

Applied to files:

  • rust/src/api/accounts.rs
  • rust/src/api/bug_report.rs
  • rust/src/api/mod.rs
  • rust/src/api/relay_defaults.rs
📚 Learning: 2026-01-15T23:30:10.907Z
Learnt from: jgmontoya
Repo: marmot-protocol/sloth PR: 42
File: rust/src/api/account_groups.rs:107-123
Timestamp: 2026-01-15T23:30:10.907Z
Learning: Maintain a consistent function start-up order in the Rust module: for functions like accept_account_group, decline_account_group, and mark_message_read in rust/src/api/account_groups.rs (and other files in rust/src/api), call Whitenoise::get_instance() first, then parse input parameters. This pattern should be applied across the entire module to improve readability and consistency.

Applied to files:

  • rust/src/api/accounts.rs
  • rust/src/api/bug_report.rs
  • rust/src/api/mod.rs
  • rust/src/api/relay_defaults.rs
📚 Learning: 2026-01-19T10:45:49.603Z
Learnt from: erskingardner
Repo: marmot-protocol/sloth PR: 52
File: rust/src/api/utils.rs:62-83
Timestamp: 2026-01-19T10:45:49.603Z
Learning: In rust/src/api, ensure that FFI glue code for flutter_rust_bridge (e.g., callable functions exposing enum variants or wrapping Display/FromStr) lives in the bridge layer, not in whitenoise-rs. Only business logic should be delegated to whitenoise-rs. Simple enum variant constructors and FFI-specific wrappers belong in the bridge layer.

Applied to files:

  • rust/src/api/accounts.rs
  • rust/src/api/bug_report.rs
  • rust/src/api/mod.rs
  • rust/src/api/relay_defaults.rs
📚 Learning: 2026-02-10T23:51:16.714Z
Learnt from: jgmontoya
Repo: marmot-protocol/whitenoise PR: 209
File: rust/src/api/user_search.rs:51-111
Timestamp: 2026-02-10T23:51:16.714Z
Learning: In Rust code reviews, treat usize to u64 as a safe widening on all supported platforms (usize <= 64 bits). Do not suggest try_from for usize -> u64 conversions. Be cautious about the reverse direction (u64 -> usize) on 32-bit platforms where truncation can occur. When reviewing, prefer direct as-casting or explicit type as appropriate for usize to u64; avoid try_from for this specific conversion.

Applied to files:

  • rust/src/api/accounts.rs
  • rust/src/api/bug_report.rs
  • rust/src/api/mod.rs
  • rust/src/api/relay_defaults.rs
📚 Learning: 2026-01-05T22:40:27.888Z
Learnt from: untreu2
Repo: marmot-protocol/sloth PR: 22
File: lib/widgets/wn_image_picker.dart:127-143
Timestamp: 2026-01-05T22:40:27.888Z
Learning: In marmot-protocol's Sloth project (lib/widgets/...): image hosting URLs returned by blossom servers are always lowercase (http:// or https://). Do not implement or rely on case-insensitive URL protocol detection in WN image picker code; assume the protocol is lowercase. If URL protocol checks are needed, compare against the exact literals 'http://' and 'https://'. Add tests that assert URLs use lowercase protocols. This guideline applies to all Dart files under lib/widgets that handle image URLs.

Applied to files:

  • lib/widgets/wn_auth_buttons_container.dart
📚 Learning: 2026-02-04T10:35:43.112Z
Learnt from: erskingardner
Repo: marmot-protocol/sloth PR: 170
File: lib/widgets/wn_list_item.dart:232-234
Timestamp: 2026-02-04T10:35:43.112Z
Learning: In this repository ( marmot-protocol/sloth ), when writing widget build methods in Dart files under lib/widgets, only extract a local typography variable if context.typographyScaled or context.typography is used multiple times within the same build method. If typography is used only once, keep the inline access to avoid an unnecessary extra line. This guideline helps maintain readability and avoids premature refactoring.

Applied to files:

  • lib/widgets/wn_auth_buttons_container.dart
📚 Learning: 2026-02-14T05:09:20.007Z
Learnt from: josefinalliende
Repo: marmot-protocol/whitenoise PR: 260
File: lib/widgets/wn_message_quote.dart:32-88
Timestamp: 2026-02-14T05:09:20.007Z
Learning: In Dart widget files under lib/widgets (matching lib/widgets/**/*.dart), spacing literals such as padding, gap values, and border radii should not be extracted into constants based on josefinalliende's preference. Apply this rule consistently across widget files to improve readability and avoid over-abstracting simple literals.

Applied to files:

  • lib/widgets/wn_auth_buttons_container.dart
📚 Learning: 2026-01-05T21:28:05.652Z
Learnt from: untreu2
Repo: marmot-protocol/sloth PR: 22
File: test/screens/profile_keys_screen_test.dart:14-23
Timestamp: 2026-01-05T21:28:05.652Z
Learning: In test mocks for the marmot-protocol/sloth project, allow skipping bounds checking for substring operations when test inputs are controlled and have proven sufficient length (e.g., 'test_pubkey' is always 12 characters). Favor simpler, deterministic mock implementations in such controlled test contexts, but avoid relaxing bounds checks in production code or tests with variable inputs. Apply this guideline primarily to test files under the test/ directory.

Applied to files:

  • test/providers/offline_provider_test.dart
  • test/main_test.dart
📚 Learning: 2026-01-07T16:49:18.694Z
Learnt from: josefinalliende
Repo: marmot-protocol/sloth PR: 33
File: test/screens/chat_screen_test.dart:245-282
Timestamp: 2026-01-07T16:49:18.694Z
Learning: In the marmot-protocol/sloth repository, it is acceptable to use force-unwrapping (!) in Dart test files as an implicit assertion: if a value is unexpectedly null, the test will fail. This guideline applies only to test code under the test/ directory and should not be used in production code.

Applied to files:

  • test/providers/offline_provider_test.dart
  • test/main_test.dart
📚 Learning: 2026-01-11T22:43:09.610Z
Learnt from: josefinalliende
Repo: marmot-protocol/sloth PR: 36
File: test/screens/chat_list_screen_test.dart:74-76
Timestamp: 2026-01-11T22:43:09.610Z
Learning: In Dart tests (e.g., test/screens/chat_list_screen_test.dart and related files), use setUp() to call _api.reset() to clean up StreamController resources. Do not suggest or rely on tearDownAll for this cleanup.

Applied to files:

  • test/providers/offline_provider_test.dart
  • test/main_test.dart
📚 Learning: 2026-04-14T03:52:37.716Z
Learnt from: josefinalliende
Repo: marmot-protocol/whitenoise PR: 565
File: test/providers/offline_provider_test.dart:63-177
Timestamp: 2026-04-14T03:52:37.716Z
Learning: In this repository, it’s acceptable to use fixed-time waits for test timing using `Future.delayed` (e.g., `await Future.delayed(const Duration(milliseconds: 10))`) inside test files. During code reviews, don’t recommend replacing these fixed sleeps with event-based or poll-based synchronization when the change is localized to Dart test files under the `test/` directory.

Applied to files:

  • test/providers/offline_provider_test.dart
  • test/main_test.dart
📚 Learning: 2026-02-05T11:59:09.400Z
Learnt from: erskingardner
Repo: marmot-protocol/sloth PR: 189
File: test/widgets/wn_filter_chip_test.dart:1-3
Timestamp: 2026-02-05T11:59:09.400Z
Learning: In Dart/Flutter test files, Offset is exported by package:flutter_test/flutter_test.dart. If you already import flutter_test, you do not need to import dart:ui for Offset. Ensure there are no conflicting Offset symbols when both imports occur.

Applied to files:

  • test/providers/offline_provider_test.dart
  • test/main_test.dart
  • integration_test/basic_messaging_flow_test.dart
📚 Learning: 2026-04-28T17:39:39.941Z
Learnt from: pepina-dev
Repo: marmot-protocol/whitenoise PR: 600
File: test/hooks/use_leave_group_test.dart:67-78
Timestamp: 2026-04-28T17:39:39.941Z
Learning: In this repo’s Dart test files under `test/` (e.g., `test/hooks/use_leave_group_test.dart`), it’s acceptable to avoid calling `mockApi.reset()` at the start of `setUp()` when the test suite already manually resets all relevant individual mock fields in `setUp()`. Reviewers should not flag the absence of a `reset()` call as long as every field that could leak state between tests is explicitly reinitialized and the tests are passing.

Applied to files:

  • test/providers/offline_provider_test.dart
  • test/main_test.dart
🔇 Additional comments (31)
lib/screens/signup_screen.dart (1)

77-79: LGTM!

Also applies to: 152-157, 244-246, 298-300, 323-325

lib/screens/chat_invite_screen.dart (1)

250-250: LGTM!

Also applies to: 258-258, 319-322, 387-393, 417-417

lib/screens/profile_keys_screen.dart (1)

34-40: LGTM!

Also applies to: 81-81, 97-97

lib/screens/set_up_group_screen.dart (1)

26-26: LGTM!

Also applies to: 45-51, 99-99, 159-159, 189-191, 203-205, 217-217, 224-226, 240-242

lib/screens/settings_screen.dart (1)

83-83: LGTM!

Also applies to: 111-111, 129-129

lib/screens/switch_profile_screen.dart (1)

28-32: LGTM!

Also applies to: 111-113, 143-143

lib/screens/user_selection_screen.dart (1)

58-58: LGTM!

Also applies to: 77-77, 145-147, 153-155, 164-166

lib/widgets/wn_auth_buttons_container.dart (1)

26-26: LGTM!

Also applies to: 34-34

rust_builder/cargokit/build_tool/lib/src/builder.dart (1)

161-161: LGTM!

rust_builder/cargokit/build_tool/lib/src/rustup.dart (1)

138-156: LGTM!

integration_test/basic_messaging_flow_test.dart (2)

307-316: Past concern addressed: search now scoped to message bubbles.

The _expectMessageVisible helper now searches within WnMessageBubble widgets, which prevents false positives from matching text still present in the composer input field.


1-77: LGTM!

Also applies to: 79-118, 120-173, 175-245, 247-305, 318-438

lib/providers/offline_provider.dart (1)

6-6: LGTM!

Also applies to: 9-26, 28-51, 69-78, 84-97

justfile (1)

55-56: LGTM!

Also applies to: 147-152, 171-206, 208-218, 290-304, 309-311, 327-388, 419-432, 440-452

test/main_test.dart (1)

102-114: LGTM!

test/providers/offline_provider_test.dart (1)

206-254: LGTM!

pubspec.yaml (1)

80-81: LGTM!

rust/src/api/relay_defaults.rs (1)

7-13: LGTM!

Also applies to: 15-42, 44-67, 71-72, 76-119

rust/src/api/mod.rs (1)

45-46: LGTM!

Also applies to: 54-54, 80-90, 142-142, 149-151

rust/src/api/accounts.rs (1)

2-3: LGTM!

Also applies to: 268-268

rust/src/api/bug_report.rs (1)

3-3: LGTM!

Also applies to: 92-92, 127-127, 192-194

lib/src/rust/api.dart (1)

22-22: LGTM!

Also applies to: 37-37, 41-41, 84-85, 90-90, 94-94, 102-103

lib/src/rust/api/accounts.dart (1)

14-14: LGTM!

lib/src/rust/api/chat_list.dart (1)

17-17: LGTM!

lib/src/rust/api/group_state.dart (1)

11-11: LGTM!

lib/src/rust/api/groups.dart (1)

13-13: LGTM!

lib/src/rust/api/messages.dart (1)

15-15: LGTM!

lib/src/rust/api/notifications.dart (1)

11-11: LGTM!

lib/src/rust/api/relay_defaults.dart (1)

11-12: LGTM!

lib/src/rust/api/user_search.dart (1)

15-15: LGTM!

lib/src/rust/api/users.dart (1)

18-18: LGTM!

@jgmontoya jgmontoya marked this pull request as ready for review May 16, 2026 00:25
Copy link
Copy Markdown
Collaborator

@pepina-dev pepina-dev left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for adding this 🫶

I get a docker error that I have to fix to be able to run local relay again :/ All the times I've tried docker-compose up -d in the rust crate I get a "context deadline exceeded" error. 🐳

So I'm not approving yet cause I can't run them yet.

Comment thread lib/providers/offline_provider.dart
Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@integration_test/basic_messaging_flow_test.dart`:
- Line 25: The test uses 'localhost' in the _relayUrls constant while preflight
checks validate '127.0.0.1', causing possible IPv4/IPv6 resolution mismatches;
update the _relayUrls constant (and the other occurrences around lines
referenced) to use the same loopback host form as the preflight (e.g., replace
'localhost' with '127.0.0.1') so relay checks and runtime URLs are
consistent—modify the declaration of _relayUrls and the two other relay URL
occurrences mentioned (lines ~426-427) to the chosen loopback address.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Pro

Run ID: cd4d791e-ff2f-4db2-908e-c44152649536

📥 Commits

Reviewing files that changed from the base of the PR and between af047db and 66b4ce7.

📒 Files selected for processing (5)
  • .gitignore
  • dev/nostr-rs-relay-config.toml
  • dev/strfry.conf
  • docker-compose.yml
  • integration_test/basic_messaging_flow_test.dart
📜 Review details
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (5)
  • GitHub Check: Test (2/4)
  • GitHub Check: Test (4/4)
  • GitHub Check: Test (3/4)
  • GitHub Check: Test (1/4)
  • GitHub Check: Check
🧰 Additional context used
📓 Path-based instructions (2)
**/*.dart

📄 CodeRabbit inference engine (AGENTS.md)

**/*.dart: Use single quotes for strings in Dart/Flutter code
Enable and respect prefer_const_constructors lint rule in Dart/Flutter code
Enable and respect prefer_final_locals lint rule in Dart/Flutter code
Set line width to 100 characters in Dart/Flutter code
Preserve trailing commas in Dart/Flutter code
Maintain minimum test coverage of 99%; never submit a PR that reduces test coverage
Avoid using // coverage:ignore, // coverage:ignore-line, // coverage:ignore-start, or // coverage:ignore-end to bypass coverage requirements; write tests instead (only exception: truly unreachable code)

Files:

  • integration_test/basic_messaging_flow_test.dart
**/*.{dart,rs}

📄 CodeRabbit inference engine (AGENTS.md)

Do not add comments except for code that is really complex or hard to understand

Files:

  • integration_test/basic_messaging_flow_test.dart
🧠 Learnings (14)
📚 Learning: 2026-04-01T10:45:51.928Z
Learnt from: dannym-arx
Repo: marmot-protocol/whitenoise PR: 493
File: lib/hooks/use_chat_scroll.dart:273-275
Timestamp: 2026-04-01T10:45:51.928Z
Learning: In lib/hooks/use_chat_scroll.dart, do not flag the scroll-down button visibility logic as a bug. The `showScrollDown` expression `isInitialPositionReady.value && (hasUnseenMessages.value || (!isAtBottom.value && firstUnreadIndex != null))` is intentional: in a fully-read chat where `firstUnreadIndex` is null and there are no unseen messages, the scroll-down button should remain hidden even if the user has scrolled up.

Applied to files:

  • .gitignore
📚 Learning: 2026-01-06T01:08:41.552Z
Learnt from: untreu2
Repo: marmot-protocol/sloth PR: 22
File: lib/widgets/wn_warning_box.dart:28-79
Timestamp: 2026-01-06T01:08:41.552Z
Learning: In reviews for the marmot-protocol/sloth repository, avoid suggesting accessibility, design, or general improvements unless they are strictly relevant to the PR description and its stated goals. Focus feedback on the specific PR objectives and requirements; ignore unrelated stylistic or broad improvement suggestions.

Applied to files:

  • integration_test/basic_messaging_flow_test.dart
📚 Learning: 2026-01-15T14:42:54.111Z
Learnt from: josefinalliende
Repo: marmot-protocol/sloth PR: 39
File: lib/hooks/use_user_search.dart:47-53
Timestamp: 2026-01-15T14:42:54.111Z
Learning: When using npubFromHex(String hexPubkey) from lib/utils/formatting.dart, it already handles errors internally and returns null on failure. Do not wrap calls to this function in try/catch blocks. Instead, check for a null return and handle accordingly (e.g., treat as invalid hex). This guideline applies to all Dart files in the repository that may call this function.

Applied to files:

  • integration_test/basic_messaging_flow_test.dart
📚 Learning: 2026-01-16T17:35:32.431Z
Learnt from: untreu2
Repo: marmot-protocol/sloth PR: 43
File: lib/hooks/use_network_relays.dart:155-184
Timestamp: 2026-01-16T17:35:32.431Z
Learning: In Dart/Flutter code, prefer void as the return type for fire-and-forget async functions that are intended to run in the background without blocking the caller. Using Future or Future<void> would allow callers to accidentally await, which could block for long periods. This pattern makes the call fire-and-forget by design. Apply to functions that intentionally should not be awaited; document the intent where appropriate. (Example context: pollRelayStatus in lib/hooks/use_network_relays.dart uses void to prevent callers from awaiting a potentially long-running background task.)

Applied to files:

  • integration_test/basic_messaging_flow_test.dart
📚 Learning: 2026-01-19T15:50:56.684Z
Learnt from: erskingardner
Repo: marmot-protocol/sloth PR: 52
File: lib/screens/app_settings_screen.dart:30-40
Timestamp: 2026-01-19T15:50:56.684Z
Learning: Target the Flutter SDK version >= 3.27 across the repo. Since features like Column.spacing and Row.spacing were added in Flutter 3.27, you can safely use them in Dart files (e.g., lib/screens/app_settings_screen.dart) as long as the pubspec.yaml environment specifies Flutter >= 3.27. If needed, enforce this by validating the environment constraint (e.g., flutter, sdk: flutter) in pubspec.yaml.

Applied to files:

  • integration_test/basic_messaging_flow_test.dart
📚 Learning: 2026-01-29T03:02:34.290Z
Learnt from: josefinalliende
Repo: marmot-protocol/sloth PR: 100
File: lib/widgets/wn_dropdown_selector.dart:126-139
Timestamp: 2026-01-29T03:02:34.290Z
Learning: Global font-family usage guideline: Since Manrope is configured in lib/theme.dart for both light and dark themes, individual TextStyle declarations should not specify fontFamily: 'Manrope'. During reviews, verify that no TextStyle instances override fontFamily unnecessarily; rely on theme inheritance instead. If a TextStyle must specify a font for a specific case, ensure it is clearly justified and localized, and document why the override is needed. This guideline applies across Dart files in the project (e.g., lib/widgets/wn_dropdown_selector.dart and related components).

Applied to files:

  • integration_test/basic_messaging_flow_test.dart
📚 Learning: 2026-01-29T16:02:52.588Z
Learnt from: erskingardner
Repo: marmot-protocol/sloth PR: 129
File: test/widgets/wn_overlay_test.dart:84-91
Timestamp: 2026-01-29T16:02:52.588Z
Learning: In Dart/Flutter code, when constructing widgets inside an already-const context (for example, within a const Scaffold with a child that is a collection of widgets), avoid adding explicit const keywords to the children. The Dart analyzer treats these as implicitly const, and adding explicit const can trigger the unnecessary_const lint. Review test files and general Dart files to ensure you do not redundantly prefix children with const in const contexts; rely on the implicit const behavior instead.

Applied to files:

  • integration_test/basic_messaging_flow_test.dart
📚 Learning: 2026-02-07T03:58:22.587Z
Learnt from: josefinalliende
Repo: marmot-protocol/sloth PR: 193
File: lib/services/android_signer_service.dart:13-13
Timestamp: 2026-02-07T03:58:22.587Z
Learning: In Dart files across the repository, retain NIP (Nostr Implementation Possibilities) and MIP (Marmot Implementation Possibilities) protocol reference comments that link code to their specifications. While general guidance discourages extraneous comments, these references improve traceability and maintainability by documenting the protocol context for related implementation details. Keep them in Dart sources (e.g., lib/services/android_signer_service.dart) and ensure they are kept up-to-date.

Applied to files:

  • integration_test/basic_messaging_flow_test.dart
📚 Learning: 2026-02-11T17:29:43.985Z
Learnt from: untreu2
Repo: marmot-protocol/whitenoise PR: 225
File: lib/screens/app_settings_screen.dart:64-69
Timestamp: 2026-02-11T17:29:43.985Z
Learning: In the whitenoise Flutter app, after deleting all data and resetting auth, use Routes.goToHome(context) instead of Routes.goToLogin(context) because the home screen is the app entry point and will manage authentication routing. Apply this change to navigation calls that should land on the home screen after a data reset or auth reset. Update lib/screens/app_settings_screen.dart and any similar navigation points accordingly.

Applied to files:

  • integration_test/basic_messaging_flow_test.dart
📚 Learning: 2026-02-18T18:36:13.394Z
Learnt from: untreu2
Repo: marmot-protocol/whitenoise PR: 315
File: lib/screens/edit_group_screen.dart:45-47
Timestamp: 2026-02-18T18:36:13.394Z
Learning: Whitenoise uses automated code formatting through the precommit workflow (just precommit). Do not tweak line wrapping or formatting manually; follow the formatter's output. Run the precommit formatter locally and ensure the code matches its styling decisions, and only deviate if the formatter cannot express the intended style (in which case adjust the code to satisfy the formatter).

Applied to files:

  • integration_test/basic_messaging_flow_test.dart
📚 Learning: 2026-04-06T09:36:06.726Z
Learnt from: untreu2
Repo: marmot-protocol/whitenoise PR: 553
File: lib/widgets/wn_copyable_field.dart:38-40
Timestamp: 2026-04-06T09:36:06.726Z
Learning: In Dart, `String.operator*` is a valid built-in operator for repeating strings (e.g., `'⬤' * 16`). In code reviews of Dart (`.dart`) files, do not treat expressions like `'text' * n` as invalid syntax and do not recommend replacing them with alternatives such as `List.filled(...).join()`; the operator is supported by `dart:core`.

Applied to files:

  • integration_test/basic_messaging_flow_test.dart
📚 Learning: 2026-05-13T13:46:32.612Z
Learnt from: dannym-arx
Repo: marmot-protocol/whitenoise PR: 656
File: lib/hooks/use_block_actions.dart:3-3
Timestamp: 2026-05-13T13:46:32.612Z
Learning: In marmot-protocol/whitenoise code reviews, do not flag imports that reference FRB-generated bindings under `package:rust_lib_whitenoise/src/rust/...` as private-internals violations. In `rust_lib_whitenoise`, Dart bindings are intentionally generated into `lib/src/rust/`, and `analysis_options.yaml` sets `implementation_imports: false` to suppress the related Dart lint—so `package:rust_lib_whitenoise/src/rust/...` imports are the correct/only way to consume that FRB-generated API.

Applied to files:

  • integration_test/basic_messaging_flow_test.dart
📚 Learning: 2026-05-13T13:46:39.250Z
Learnt from: dannym-arx
Repo: marmot-protocol/whitenoise PR: 656
File: lib/services/foreground_service.dart:13-16
Timestamp: 2026-05-13T13:46:39.250Z
Learning: In this repo (marmot-protocol/whitenoise), `rust_lib_whitenoise` is an FRB-generated Flutter package where the generated Dart bindings are intentionally exposed under `lib/src/rust/` as the public API surface. Do not treat imports like `package:rust_lib_whitenoise/src/rust/...` as breaking package API boundaries in code reviews (the project also sets `implementation_imports: false` in `analysis_options.yaml` to opt into this). Never raise concerns about `src/` imports from `rust_lib_whitenoise`.

Applied to files:

  • integration_test/basic_messaging_flow_test.dart
📚 Learning: 2026-02-05T11:59:09.400Z
Learnt from: erskingardner
Repo: marmot-protocol/sloth PR: 189
File: test/widgets/wn_filter_chip_test.dart:1-3
Timestamp: 2026-02-05T11:59:09.400Z
Learning: In Dart/Flutter test files, Offset is exported by package:flutter_test/flutter_test.dart. If you already import flutter_test, you do not need to import dart:ui for Offset. Ensure there are no conflicting Offset symbols when both imports occur.

Applied to files:

  • integration_test/basic_messaging_flow_test.dart
🔇 Additional comments (5)
.gitignore (1)

76-77: LGTM!

dev/nostr-rs-relay-config.toml (1)

1-19: LGTM!

dev/strfry.conf (1)

1-64: LGTM!

integration_test/basic_messaging_flow_test.dart (1)

307-315: LGTM!

docker-compose.yml (1)

3-3: ⚡ Quick win

Pin relay and setup images to immutable versions.

Using :latest tags makes integration runs nondeterministic and can break test stability as upstream images change. Pin these to tested tags or digests.

Suggested change
-    image: busybox:latest
+    image: busybox@sha256:<tested-digest>

-    image: scsibug/nostr-rs-relay:latest
+    image: scsibug/nostr-rs-relay@sha256:<tested-digest>

-    image: dockurr/strfry:latest
+    image: dockurr/strfry@sha256:<tested-digest>

Also applies to: 16-16, 30-30

Comment thread integration_test/basic_messaging_flow_test.dart
@jgmontoya
Copy link
Copy Markdown
Contributor Author

Thanks for adding this 🫶

I get a docker error that I have to fix to be able to run local relay again :/ All the times I've tried docker-compose up -d in the rust crate I get a "context deadline exceeded" error. 🐳

So I'm not approving yet cause I can't run them yet.

I added a docker-compose.yml file to make it easier to run

Copy link
Copy Markdown
Collaborator

@pepina-dev pepina-dev left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

it works! 💯 🎉

@pepina-dev pepina-dev merged commit 418fca8 into master May 18, 2026
8 of 9 checks passed
@pepina-dev pepina-dev deleted the test/integration branch May 18, 2026 16:03
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants