Make a detected nap visible on the Sleep screen - #205
Conversation
|
Note Reviews pausedIt looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the Use the following commands to manage reviews:
Use the checkboxes below for quick actions:
📝 WalkthroughWalkthroughSleep period data now uses canonical fields, validates windows, and bounds durations. Sleep detail screens preserve and display daytime naps, including nap-only days, with shared navigation to the periods breakdown. Tests cover normalization, totals, nap visibility, and navigation. ChangesSleep period display
Estimated code review effort: 4 (Complex) | ~45 minutes Possibly related PRs
Suggested labels: Suggested reviewers: Sequence Diagram(s)sequenceDiagram
participant SleepRepository
participant SleepNightContent
participant SleepPeriodsScreen
SleepRepository->>SleepNightContent: Provide normalized sleep periods
SleepNightContent->>SleepNightContent: Parse non-main periods as naps
SleepNightContent->>SleepPeriodsScreen: Open periods for the current date
SleepPeriodsScreen-->>SleepNightContent: Render the period breakdown
🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
147bf3b to
7c38e28
Compare
There was a problem hiding this comment.
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 `@lib/data/local_repository_impl.dart`:
- Around line 2695-2701: Validate the parsed asleep_min in the duration
calculation around asleepMin, accepting it only when it falls within
0..windowMinutes derived from end and start; otherwise use the period span as
the fallback. Ensure both main and nap duration paths use this bounded value,
and add regression cases in sleep_naps_visible_test.dart for negative and
oversized asleep_min values.
🪄 Autofix
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: Organization UI
Review profile: ASSERTIVE
Plan: Pro Plus
Run ID: 93bc9857-0e6b-4c58-913b-760bfbbade28
📒 Files selected for processing (4)
lib/data/local_repository_impl.dartlib/ui/sleep/sleep_detail_screen.dartlib/ui/sleep/sleep_periods_screen.darttest/sleep_naps_visible_test.dart
There was a problem hiding this comment.
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)
test/sleep_naps_visible_test.dart (1)
625-640: 📐 Maintainability & Code Quality | 🟠 Major | ⚡ Quick winAdd regression coverage for the recomputed day total.
The new path derives
total_asleep_minfrom mapped period durations, but the supplied tests assert individual period fields and nap-row behavior only. Add an assertion for the existing fixture total:400minutes of main sleep plus101minutes of nap sleep equals501minutes. Also cover the no-period fallback if that fallback remains part of the contract.As per coding guidelines: “Behavior changes, especially regressions involving readiness, abstention, idempotence, synchronization, migrations, and lifecycle safety, must include regression tests.”
🤖 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 `@test/sleep_naps_visible_test.dart` around lines 625 - 640, Add regression coverage in the existing sleep/naps test near the mapped period assertions, verifying the fixture’s recomputed total_asleep_min is 501 minutes from 400 main-sleep plus 101 nap-sleep minutes. If the no-period fallback remains supported, add a case asserting its expected total as well.Source: Coding guidelines
🤖 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 `@lib/data/local_repository_impl.dart`:
- Around line 2698-2702: Validate the main period’s night['duration_min']
against windowMin using the same non-negative, upper-bound checks applied to
p['asleep_min']; when invalid, fall back to the already validated asleepMin
value before assigning duration_min. Add regression coverage for negative and
oversized main duration values.
In `@test/sleep_naps_visible_test.dart`:
- Around line 93-100: Update the test “a length outside its own window falls
back to the window” to assert that the result collection p contains exactly
three elements before checking mapped duration_min values, ensuring
everyElement(101) cannot pass for an empty iterable.
---
Outside diff comments:
In `@test/sleep_naps_visible_test.dart`:
- Around line 625-640: Add regression coverage in the existing sleep/naps test
near the mapped period assertions, verifying the fixture’s recomputed
total_asleep_min is 501 minutes from 400 main-sleep plus 101 nap-sleep minutes.
If the no-period fallback remains supported, add a case asserting its expected
total as well.
🪄 Autofix
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: Organization UI
Review profile: ASSERTIVE
Plan: Pro Plus
Run ID: 73855007-bddc-45cb-a8ba-da6e4ca0f51c
📒 Files selected for processing (2)
lib/data/local_repository_impl.darttest/sleep_naps_visible_test.dart
There was a problem hiding this comment.
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 `@lib/data/local_repository_impl.dart`:
- Around line 2706-2710: Update the duration parsing around tstMin and
durationMin to range-check the raw numeric duration before calling toInt(),
rejecting fractional values such as -0.5 and 0.5 so both main-duration and nap
asleepMin fallbacks are preserved. Add regression coverage for fractional inputs
in both paths.
🪄 Autofix
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: Organization UI
Review profile: ASSERTIVE
Plan: Pro Plus
Run ID: 09176f3b-fa41-48a6-8291-d7508549290c
📒 Files selected for processing (2)
lib/data/local_repository_impl.darttest/sleep_naps_visible_test.dart
A daytime nap is detected, stored, and drawn as a band on the day timeline, but the Sleep screen only ever showed the main night. The screen that does list every sleep of the day was unreachable: its only entry point is an AppScaffold action, and the Sleep tab embeds SleepNightContent (embedded: true), so that scaffold never builds. The periods payload was also keyed wrong. The engine writes is_main / start / end / asleep_min; SleepPeriodsScreen reads onset_ts / wake_ts / duration_min, so every card would have rendered as "0m" with no time range under it. - map sleep_periods onto the keys the screen reads, and give the main period the night's TST, efficiency, stage minutes and hypnogram so the two sleep screens can't print different numbers for the same night - the day total is now the sum of what the cards show - add a naps row under the night summary; tapping it opens the breakdown, and it says the nap is not part of the numbers above - a nap carries no confidence instead of a literal 0, and the confidence dot is hidden when there is none - test/sleep_naps_visible_test.dart pins the mapping and the row No stored analytics output changed, so kAlgoVersion stays put.
CodeRabbit review: sleepPeriodsForScreen took asleep_min at face value, so a negative or larger-than-window value would print a negative duration on the card and skew the day total. The engine never writes one today (a nap's asleep_min is exactly its window), but this function parses defensively everywhere else, so it should here too. Falls back to the window, which the period's own start/end already vouch for.
CodeRabbit review, second pass: - the window check covered a nap's asleep_min but not the main period, which took night['duration_min'] straight through. Same bound now: nobody sleeps longer than the window they slept in. - the fallback test asserted everyElement on a list it never sized, so it would have passed if the mapper dropped all three inputs. It checks the length first now. Adds a TST regression case for the negative and oversized values.
…eep the invariants Rebased onto main (kAlgoVersion 59). The data-layer half of this PR is now obsolete and actively harmful; the UI half is the part that still matters and is untouched. WHAT CHANGED AND WHY. This branch fixed the writer/reader key mismatch at the SCREEN end, via `sleepPeriodsForScreen`, which translated the producer's `start`/`end`/`asleep_min` onto `onset_ts`/`wake_ts`/`duration_min`. OpenStrap#204 fixed the same mismatch at the WRITER end -- the producer now emits the screen's vocabulary directly, and `_periodsWithMainStages` translates any legacy payload on read, so old finalized days still render. Left as-is, the rebase was silently broken: `night['periods'] = periods` unconditionally overwrote the enriched list with the translator's output, and the translator reads `p['start']`, which no longer exists. Every period would have been skipped -- main sleep included -- leaving an EMPTY periods list under a hero total that still rendered. No error, no log. So the overwrite and the translator are removed; one source per concern, and it is the writer. WHAT WAS KEPT. The later commits on this branch added real defensive invariants at the translator, and those are not obsolete -- they are ported to `_boundedPeriod` at the surviving seam: * a period cannot report more asleep minutes than its own window (clamped to the window, which is the trustworthy half -- `duration_min` and the bounds come from different producers, so nothing else stops a card claiming more sleep than the period it sits in); * a degenerate window is dropped rather than rendered as a zero-length card. Both re-pinned in sleep_periods_legacy_keys_test.dart. The UI half is untouched and is the reason to merge this: the periods screen was UNREACHABLE in the shipped app (its only entry point was an AppScaffold action, and the Sleep tab embeds SleepNightContent, so that scaffold never builds), plus a naps row on the night screen. Those read `data['periods']`, which main now populates correctly. Its test file kept the widget coverage and rebuilt the fixture in the current vocabulary; the six tests that only exercised the deleted translator are gone. flutter analyze clean; full suite 1328 passing, 0 failing. STILL NOT ADDRESSED, and it is this PR's own stated goal: `_daySleep` returns early on `tst == null` BEFORE the periods mapping, so a nap-only / night-shift day still shows "No sleep recorded" with no nap row. Flagged rather than fixed here -- it changes what the Sleep screen claims on a day with no night sleep, which is a product decision.
0d95f06 to
478e29f
Compare
There was a problem hiding this comment.
Actionable comments posted: 1
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (1)
lib/data/local_repository_impl.dart (1)
615-630: 🗄️ Data Integrity & Integration | 🟡 Minor | ⚡ Quick winDerive
total_asleep_minfrom the normalized periods.
_periodsWithMainStagesdrops invalid windows and clamps excessive durations. Line 630 still exports the raw engine total. A period clamped from 101 minutes to 30 minutes can therefore leave the day total inconsistent with the displayed cards.Compute the total after normalization. Preserve
nullwhen a displayed duration is unknown. Add an assertion to the clamping case intest/sleep_periods_legacy_keys_test.dartthat expectstotal_asleep_minto equal 30.As per coding guidelines, “Behavior changes, especially regressions involving … synchronization … must include regression tests.”
🤖 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 `@lib/data/local_repository_impl.dart` around lines 615 - 630, Update the normalized periods mapping around _periodsWithMainStages so total_asleep_min is derived from the displayed, normalized durations rather than the raw engine total, summing known durations while preserving null when no displayed duration is known. Add a regression assertion in the clamping case of sleep_periods_legacy_keys_test.dart verifying total_asleep_min equals 30 for the 101-to-30-minute clamp.Source: Coding guidelines
🤖 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 `@lib/data/local_repository_impl.dart`:
- Around line 750-752: Update the duration normalization logic around dur so
negative duration_min values are clamped to windowMin rather than returned
unchanged; preserve null only for absent durations and retain existing handling
for valid values. Add a regression case covering a negative current-schema
duration_min.
---
Outside diff comments:
In `@lib/data/local_repository_impl.dart`:
- Around line 615-630: Update the normalized periods mapping around
_periodsWithMainStages so total_asleep_min is derived from the displayed,
normalized durations rather than the raw engine total, summing known durations
while preserving null when no displayed duration is known. Add a regression
assertion in the clamping case of sleep_periods_legacy_keys_test.dart verifying
total_asleep_min equals 30 for the 101-to-30-minute clamp.
🪄 Autofix
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: Organization UI
Review profile: ASSERTIVE
Plan: Pro Plus
Run ID: ba58d482-e5ac-407f-bb1a-7807884da557
📒 Files selected for processing (3)
lib/data/local_repository_impl.darttest/sleep_naps_visible_test.darttest/sleep_periods_legacy_keys_test.dart
|
Rebased onto main ( The data-layer half became obsolete — and would have silently broken the screenThis branch fixed the writer/reader key mismatch at the screen end ( Left as-is, the rebase was silently broken. So the overwrite and the translator are gone. One source per concern, and it's the writer. What I kept, because it wasn't obsoleteYour later commits added real defensive invariants at the translator. Those are ported to
Both re-pinned in The UI half is untouched, and it's the reason to merge thisThe periods screen was unreachable in the shipped app — its only entry point was an AppScaffold action, and the Sleep tab embeds Your test file keeps the widget coverage with the fixture rebuilt in the current vocabulary; the six tests that only exercised the deleted translator are gone.
Still not addressed — this PR's own stated goal
|
Found reviewing my own rebase commit. Porting this branch's clamp to
`_boundedPeriod` kept the correction but DROPPED the mechanism that kept the
total consistent with it -- the original translator recomputed
`total_asleep_min` from the mapped periods for exactly this reason, and I did
not carry that over.
Reproduced: a nap claiming 101 min inside a 30-min window renders as 30, while
the hero kept the producer's pre-clamp 521.
card durations : [420, 30]
sum of cards : 450
hero total : 521 <- a user can add the cards up and see this is wrong
`_totalAsleepMin` now recomputes from the RENDERED periods, so a read-side
correction can never leave the hero contradicting the cards under it.
ABSENT STILL STAYS ABSENT, which is the part that needed care. A null stored
total means the producer refused to state one -- usually because nap detection
abstained, so the day holds an unknown NUMBER of unmeasured naps (OpenStrap#204).
Summing the periods we happen to have would convert that honest "-" into a
confident figure that silently omits them. So: null in, null out; and a period
whose own duration is unknown makes the sum unknown again, for the same reason
it does at the writer.
3 tests added covering all three paths (clamped, absent, unknown-duration).
Full suite 1331 passing.
|
Reviewed this against merged #204, including my own rebase commit. Verdict: yes, it still makes sense — but for different reasons than when it was opened, and one of its two stated goals is still unmet. I also found and fixed a defect I introduced. Details below, with the checks I actually ran. 1. A defect in my own rebase — fixed in
|
| scenario | result |
|---|---|
| normal night + nap | has_sleep=true, naps=1 — nap visible ✅ |
| nap-only day (no night sleep) | has_sleep=false, periods=null ❌ |
So the data layer works, and your UI half is the reason to merge this: the periods screen was unreachable in the shipped app (its only entry point was an AppScaffold action, and the Sleep tab embeds SleepNightContent, so that scaffold never builds). That fix is entirely yours and is untouched by the rebase.
What #204 made redundant was only the translator — and leaving it in would have been actively harmful, since it read p['start'] after the producer stopped emitting it.
3. The unmet goal, with the exact mechanism
A nap-only / night-shift day still shows "No sleep recorded" — the case this PR is named for. It needs two changes, not one:
_daySleepreturns early ontst == nullbefore the periods mapping, soperiodsis never even attached.- Even if it were,
sleep_detail_screen.dart:114-117sets_Phase.emptywhenhas_sleepis false, soSleepNightContent— and your_napsRow()with it — never builds.
I've left this alone because it changes what the Sleep screen claims on a day with no night sleep, which is a product decision rather than a mechanical fix. Happy to implement it if you want it in this PR — it's small now that the data layer is sorted, and it's the difference between this PR meeting its title or not.
flutter analyze clean, full suite 1331 passing. Mergeable against main (6d37606, kAlgoVersion 59).
The title case -- a daytime sleep being invisible on the Sleep screen -- was
still unmet after the rebase, because it needed TWO changes and only the data
half had been discussed:
1. `_daySleep` returned early on `tst == null` BEFORE the periods mapping, so
the naps were dropped on the floor.
2. Even with them attached, `sleep_detail_screen` sets `_Phase.empty` when
`has_sleep` is false, so `SleepNightContent` -- and the naps row with it --
never builds.
Verified end-to-end against a seeded bundle before and after:
before: has_sleep=false periods=null
after: has_sleep=false periods=1 total=38
`has_sleep` deliberately stays FALSE. It means what it says: there is no NIGHT
to render a hypnogram, stages or efficiency for, and promoting a nap into one
would be exactly the conflation this file avoids everywhere else. What changes
is that the screen stops claiming nothing happened while the same nap is
credited against sleep need and drawn as a band on the Timeline -- three
surfaces, two answers.
The empty state now keeps its honest "No sleep recorded for this night" card
(with copy that says why there is no breakdown) and lists the daytime sleep
beside it, tapping through to the periods screen. Its total obeys the same
absent-is-not-zero rule as the rest: one nap with an unknown duration renders
the total as "-" rather than a partial sum presented as complete.
A day with neither a night nor naps is untouched -- no periods key, same empty
card as before.
4 tests added, mutation-verified (reverting the attach fails exactly the
nap-only test). Full suite 1333 passing.
|
Pushed The nap-only case needed two changes, and only the data half had come up before:
Verified against a seeded bundle, before and after:
The empty state keeps its honest "No sleep recorded for this night" card (with copy explaining why there's no breakdown) and lists the daytime sleep beside it, tapping through to the periods screen. Its total obeys the same absent-is-not-zero rule as everything else: one nap with an unknown duration renders "—" rather than a partial sum dressed up as complete. A day with neither a night nor naps is untouched. 4 tests, mutation-verified. Full suite 1333 passing, analyze clean. Summary of where this PR landed, since it changed shape a lot:
Ready to merge from my side. |
CodeRabbit found a real gap in the clamp I ported: `dur <= windowMin` accepts
NEGATIVE values, so a malformed duration passed straight through to both the
card and the hero. Reproduced -- a stored `duration_min: -50` rendered as -50
and summed into the total as -50, understating the day.
FIXED, but NOT the way the bot proposed. Its patch was
`(dur >= 0 && dur <= windowMin)`, which falls through to the existing
`return {...m, 'duration_min': windowMin}` -- so a corrupt -50 would be clamped
UP to the FULL WINDOW, inventing a whole night of sleep out of garbage. That is
a worse claim than the bug it fixes.
A negative duration is not a small measurement, it is not a measurement at all.
It becomes UNKNOWN: clamping down to 0 would assert "you did not sleep", which
we also do not know. Unknown then propagates through `_totalAsleepMin`, so the
hero reads "-" rather than a total built on a value we know is nonsense --
consistent with how absence is handled everywhere else on this seam.
1 test added, asserting both that the duration is null AND that it is not the
window length, so a future "fix" toward the bot's version fails loudly.
Full suite 1334 passing.
There was a problem hiding this comment.
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 `@lib/ui/sleep/sleep_detail_screen.dart`:
- Around line 221-237: Use the authoritative _data['total_asleep_min'] in
_emptyStateNapsCard instead of summing rendered naps, displaying — when it is
null. In lib/ui/sleep/sleep_detail_screen.dart lines 438-451, propagate this
unknown-total state into SleepNightContent; at lines 645-662, suppress numeric
nap duration and count when the aggregate is unknown. Add a widget regression
test covering a nap-only payload with total_asleep_min: null.
🪄 Autofix
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: Organization UI
Review profile: ASSERTIVE
Plan: Pro Plus
Run ID: 37344cc5-ab22-4d32-bffb-35a947922ad9
📒 Files selected for processing (3)
lib/data/local_repository_impl.dartlib/ui/sleep/sleep_detail_screen.darttest/sleep_periods_legacy_keys_test.dart
|
@coderabbitai — valid, fixed in You're right that Why I diverged from the suggested diff. A negative duration isn't a small measurement; it isn't a measurement. It now becomes unknown. Clamping down to The test asserts both that the duration is null and that it is not the window length, so a future "fix" toward the clamp-up version fails loudly. Full suite 1334 passing. |
|
Tip For best results, initiate chat on the files or code changes.
This prevents a corrupt value from becoming either a full-window duration or a zero-duration assertion. Propagating the unknown value through Thank you for adding the regression assertion that rejects the clamp-up outcome. 🐇 ✅ ✏️ Learnings added
If you found this review helpful, would you consider giving us a shout-out on X? Thank you for using CodeRabbit! You are interacting with an AI system. |
…zero CodeRabbit, valid on both counts, and both are the SAME rule I had just applied one layer down reappearing in the UI. 1. `_emptyStateNapsCard` computed its own total by summing the rendered periods, ignoring `_data['total_asleep_min']`. The repository already decides that (`_totalAsleepMin`) and deliberately returns NULL when the producer could not state a complete figure -- usually because nap detection abstained, so the day holds an unknown NUMBER of naps. Re-summing whatever periods happen to be present presented a partial figure as the day's total, which is exactly the claim the layer below refused to make. Now reads the authoritative value and renders "-" when it is absent. 2. `_napMin` (pre-existing) folded with `?? 0`, so a nap whose duration is unknown counted as ZERO and the row showed the remainder as if it were the full nap total -- under-reporting by exactly the part we could not measure. Now returns null if any nap's duration is unknown; `_hm` already renders null as "-", so the row degrades honestly with no call-site change. Both are the absent-is-not-zero rule this seam follows everywhere else. Worth noting the shape of the mistake: I fixed hero-vs-cards at the repository layer earlier in this branch, then introduced the same duplicate-aggregate at the widget layer in the very next commit. 1 widget test added, mutation-verified (restoring `?? 0` fails it). Full suite 1335 passing.
|
@coderabbitai — valid on both counts, fixed in 1. Duplicate aggregate. 2. Worth naming the shape of the mistake, since it's instructive: I fixed hero-vs-cards at the repository layer earlier in this branch, then introduced the same duplicate-aggregate at the widget layer in the very next commit. Your catch. 1 widget test, mutation-verified (restoring |
|
Tip For best results, initiate chat on the files or code changes.
Good regression coverage. Thank you for the mutation check. 🐇 ✅ ✏️ Learnings added
You are interacting with an AI system. |
I napped for ~1h40m this afternoon, synced, and the nap was nowhere in the app. It turned out the detection is fine (the nap shows as a band under Your day), but two things kept it off the Sleep screen.
1. The periods screen is unreachable.
SleepPeriodsScreenis only pushed from anAppScaffoldaction inSleepDetailScreen, and the Sleep tab always builds that screen withembedded: true(screens.dart:50,55), which returns the bareColumnwithout the scaffold.SleepDetailScreen.today()is never called either, so nothing in the shipped app can open it.2. The periods payload is keyed wrong. The engine writes each period as
is_main/start/end/asleep_min(derivation_engine.dart:3626), while the screen readsonset_ts/wake_ts/duration_min. Even if you reached the screen, every card would say "0m" with no time range.Before: Sleep tab shows the night only, 6h40m, no sign of the nap anywhere.
After: a row under the night summary, "Daytime nap, 1h 41m, not included in the night above", which opens the per-period breakdown with real times and durations.
Also in here:
0and the confidence dot is hidden insteadtest/sleep_naps_visible_test.dartcovers the mapping and the row (visible with a nap, absent without, tap fires)Nothing about how a nap is computed changed, so
kAlgoVersionstays put.Left alone deliberately, happy to do either in a follow-up: naps still don't enter TST or readiness (they only credit tonight's need via
nap_min), and_daySleepreturnshas_sleep: falsewhen there's no night, so a nap-only day still shows nothing.Verified on Flutter 3.41.6 (the pinned version):
flutter analyzeclean,flutter test --concurrency=1gives 1205 passed / 2 skipped, the two skips being thewhoop_hist.jsonlreplays that need the capture file.Summary by CodeRabbit
New Features
Bug Fixes
Tests