Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
120 changes: 52 additions & 68 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,99 +1,83 @@
## 1.0.0

A redesigned overlay, issues that carry the number behind them, and a
public API that follows semantic versioning from this release. The
matching sidecar is `sleuth_mcp` 0.10.0. Publish both together, because
sidecar 0.9.0 refuses 1.0.0 apps. The
public API under semantic versioning. Use it with `sleuth_mcp` 0.10.0,
because sidecar 0.9.0 refuses 1.0.0 apps. The
[full release notes](https://github.com/Harrys76/sleuth/blob/main/doc/release_notes/1.0.0.md)
list every change.

### Breaking

After upgrading, run `dart fix --apply`. It adds the `validation.dart`
import for the names that moved there and deletes the removed
`SleuthThemeData` arguments. Before Flutter 3.35 it adds the import only
for `kSleuthPackageVersion`.

- `package:sleuth/sleuth.dart` exports only the names listed in
`doc/api_1_0_0.md`, each through a `show` list, and follows semantic
versioning.
- Capture and validation tooling moved to the new
`package:sleuth/validation.dart`, which is outside the semver promise.
Import it for `DetectorMetadata`, `BracketSpec`, `EvidenceTier`,
`ProfileCaptureSchema`, `PollTimings`, `kSleuthPackageVersion` and the
detector types the capture screens use, such as `RepaintDetector`.
- Fifteen internal names are no longer exported, among them
`FixHintBuilder`, `SessionMarkdownExporter`, `JankCaptureBuffer`,
`FrameBudget` and `ConnectionMode`. `Sleuth.enrichStartupWithVmData`,
`Sleuth.dartEntryMonotonicUs` and `Sleuth.notifyControllerDisposed` are
gone, and the capture statics on `Sleuth` are `@experimental`.
- `RouteSession.endedAt` and `scanCycleCount` are read-only, and
`SleuthThemeData` drops 29 tokens and 3 helpers the overlay no longer
draws.
`doc/api_1_0_0.md`. It no longer exports fifteen internal names, among
them `FixHintBuilder`, `SessionMarkdownExporter` and `ConnectionMode`.
- Capture and validation tooling moved to `package:sleuth/validation.dart`,
which is `@experimental` and outside the semver promise. Import it for
`DetectorMetadata`, `BracketSpec`, `EvidenceTier`, `ProfileCaptureSchema`,
`PollTimings` and `kSleuthPackageVersion`. It also exports seven detector
types for the capture screens, such as `RepaintDetector`.
- `Sleuth.enrichStartupWithVmData`, `Sleuth.dartEntryMonotonicUs` and
`Sleuth.notifyControllerDisposed` are gone.
`StartupMetrics.dartEntryMonotonicUs` still has the Dart entry time. The
capture statics on `Sleuth` are `@experimental`.
- `RouteSession.endedAt` and `scanCycleCount` are read-only.
`SleuthThemeData` drops 29 tokens the overlay no longer draws and the
`confidenceColor`, `effortColor` and `sourceAccentColor` helpers.
- A minor release can add values to `DetectorType`, `IssueCategory`,
`ObservationSource`, `PipelinePhase`, `InteractionContext` and
`FixEffort`, so a `switch` over them needs a default branch.
- `FrameVerdict.relatedIssues` lists only the issues that can explain the
verdict's phase.
- Highlighting an issue outlines only its own widget, never another
widget of the same category.

### Added

- `PerformanceIssue.measurement` (`IssueMeasurement`, `MeasurementUnit`)
holds the number a detector reported, with its warning and critical
lines, on 43 issue families. Issue JSON gains an optional
`measurement`.
- `PerformanceIssue.measurement`, an `IssueMeasurement`, holds the number
a detector reported, with its warning and critical lines, on 43 issue
families. Issue JSON gains an optional `measurement`.
- The overlay's Not useful button marks an issue for the session, and
snapshots and `ext.sleuth.issues` list the marks in `notUsefulMarks`.
- `DebugSnapshot.forcedRebuildsOf`, `WidgetHighlight.occurrenceId` and
`WidgetHighlight.stableId`, `SleuthThemeData.cardDivider` and
`SleuthThemeData.severityGraphicColor`.
- A test that pins the public names, and a CI job that diffs the API
against the latest published 1.x release and fails on a breaking change
without a major version bump.
- `DebugSnapshot` gains `forcedRebuildsOf`, `WidgetHighlight` gains
`occurrenceId` and `stableId`, and `SleuthThemeData` gains `cardDivider`
and `severityGraphicColor`.
- A CI job fails a breaking API change that lacks a major version bump.

### Overlay

- A run label ("Profile · VM") replaces the VM+, FRAME and DBG badges.
A More menu holds Startup, Rebuild stats, Hidden issues, Encyclopedia,
Guide, Copy snapshot and Theme, and the footer and banners it replaced
are gone.
- The collapsed card has a severity mark, a title of up to two lines
(three at large text sizes) and one meta line. The expanded card shows the measured value on a gauge,
Where, Route, When, Evidence and Check in rows, the fix with copyable
code, Why it rebuilds in debug runs, and labelled buttons including
Not useful.
- Status lines replace "No issues detected": Starting, Warming up, No VM
link, No issues found and VM link lost. One debug banner replaces two.
- The crosshair outlines a card's widget and shrinks the card to a bar.
On a card that lists several widgets, Next steps through them.
- Keyboard navigation inside the card, a 320 px minimum width, toasts in
the theme's inverted colours, and outlined warning and OK marks in the
light themes.
- An app's own `AnimatedBuilder`, `TweenAnimationBuilder`, `Checkbox` and
`ShaderMask` rebuilds count in the per-route rebuild counts again. The
overlay no longer uses them, so they left the framework denylist.
- A new issue list rebuilds only the cards it changes.
- A run label such as "Profile · VM" replaces the VM+, FRAME and DBG
badges, and a More menu replaces the footer and banners.
- A collapsed card shows a severity mark, the title and one meta line. An
expanded card adds the measured value on a gauge, where and when Sleuth
saw the issue, its evidence, the fix with copyable code, and Why it
rebuilds in debug runs.
- Status lines such as Warming up, No VM link and No issues found replace
"No issues detected".
- The crosshair outlines only the issue's own widget and shrinks the card
to a bar. On a card that lists several widgets, the Next button steps
through them.
- Per-route rebuild counts include an app's own `AnimatedBuilder`,
`TweenAnimationBuilder`, `Checkbox` and `ShaderMask` again, because the
overlay no longer uses them.
- Cards hidden under 0.38 stay hidden. The stored overlay state moves to
`schemaVersion` 2, which 0.38 reads as empty and leaves as it is. The
Hidden page names each key by its id and widget.
- An issue keeps the Jank tag for 10 s after the last late frame that
named it on the current route, instead of following only the latest
frame.
`schemaVersion` 2, which 0.38 reads as empty and does not overwrite.
- The Jank tag stays on an issue for 10 s after the last late frame that
named it on the current route.

### Fixed

- Ancestor chains, fix hints and the card's Where row name each widget's
own `file:line`. A widget type built in several places reported the
first place Sleuth saw.
- Widgets on a kept-alive page that is not showing, such as another tab
of a `TabBarView`, get no outline or marker. Their position read as NaN,
so stepping through a card's widgets could start on one, say "Showing",
and count every tab's widgets.
- A widget that a scroll view clips away, such as a list row scrolled
under the app bar, gets no outline or marker, and an outline covers only
the part of a widget that shows. A list builds rows past its edge, so a
card's outline could start on a hidden row and count rows the screen did
not show. A flipped or scaled widget is outlined where it shows.
own `file:line`, not the first place Sleuth saw its type.
- Widgets on a kept-alive page that is not showing, such as another
`TabBarView` tab, get no outline. Neither do widgets a scroll view clips
away, and an outline covers only the part of a widget that shows.
Before, stepping through a card's widgets could start on a hidden one
and count widgets the screen did not show.
- `Sleuth.track` adds nothing to a release build. Its early `return child`
left about 0.6 MB of Flutter framework code in release apps on Android
and iOS, although none of it ran.
kept about 0.6 MB of unused Flutter framework code in release apps.

## 0.38.0

Expand Down
2 changes: 2 additions & 0 deletions CLAUDE.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ fvm flutter test test/detectors/ # Run detector tests only
fvm flutter analyze # Static analysis (must be 0 issues)
fvm flutter pub publish --dry-run # Verify publish readiness
fvm dart doc --dry-run # Dartdoc gate (must report 0 warnings, 0 errors)
fvm dart fix test_fixes --compare-to-golden # Fix-data goldens (lib/fix_data.yaml)
fvm dart format --output=none --set-exit-if-changed lib test tool example/lib example/test packages/sleuth_mcp/lib packages/sleuth_mcp/test packages/sleuth_mcp/bin # Format check (CI)

# Floor lane (Flutter 3.32.8, as CI runs it); restore the dev pin afterwards
Expand Down Expand Up @@ -73,6 +74,7 @@ test/
- Issues use `IssueConfidence`: confirmed (directly observed), likely (runtime + structural), possible (structural only).
- Fix hints use `FixHintBuilder` (in `utils/fix_hint_builder.dart`); never hardcode fixHint strings in detectors.
- All public API goes through `lib/sleuth.dart` barrel file.
- When you rename, move or remove a public name and the old code has a direct replacement, add a `rename`, `replacedBy` or `removeParameter` transform to `lib/fix_data.yaml` and a golden pair in `test_fixes/`. Give each import-adding golden its own file, because one added import resolves every moved name in a file. Keep one other use of `sleuth.dart` in that file, because `dart fix` also drops an import the change leaves unused. Class, enum and mixin `replacedBy` needs Dart 3.9. The 3.8 analyzer rejects it, so only the dev pin runs the goldens. Prefer deprecating with a transform in a minor release before removing in a major one.
- Package is completely disabled in release mode (`kReleaseMode` guard). `Sleuth.track` keeps its overlay path inside `if (!kReleaseMode) { ... }`: after an early `if (kReleaseMode) return child;` the AOT compiler kept the Flutter framework code the overlay uses (~0.6 MB in release apps). The other `Sleuth` statics reach the package only through the controller `track` creates, so their early returns cost nothing.

## Current state
Expand Down
2 changes: 2 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -257,6 +257,8 @@ cd example && flutter run --profile --no-dds

`ParsedTimelineData` carries `vm_service` types, so a `vm_service` major release means a Sleuth major release. [The API list](https://github.com/Harrys76/sleuth/blob/main/doc/api_1_0_0.md) lists every public name and its library.

After upgrading to a new major release, run `dart fix --apply`. `lib/fix_data.yaml` covers the changes that have a direct replacement. For 1.0.0, `dart fix` adds the `validation.dart` import for the names that moved there and deletes the removed `SleuthThemeData` arguments.

## License

MIT
2 changes: 2 additions & 0 deletions doc/api_1_0_0.md
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,8 @@ Each of these is marked `@experimental`, as are the `validationMetadata` getters
| `StreamResourcePollResult` | class | `StreamResourceDetector` capture polls |
| `RepaintDetector`, `MemoryPressureDetector`, `StartupDetector`, `TrackedResourceDetector`, `ImageMemoryDetector`, `GpuPressureDetector`, `FrameTimingDetector` | class | Example capture screens |

0.38 did not export the seven detector types. For the other ten names, which 0.38 exported from `sleuth.dart`, `dart fix --apply` adds the `validation.dart` import.

## No longer exported

Nothing outside `lib/` and its own tests uses these. Their tests import `src/`.
Expand Down
14 changes: 12 additions & 2 deletions doc/release_notes/1.0.0.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,10 +11,20 @@ The full list of changes in sleuth 1.0.0. [CHANGELOG.md](../../CHANGELOG.md) has
and whose declarations are `@experimental`:
`EvidenceTier`, `DetectorMetadata`, `DetectorMetadataProvider`,
`BracketSpec`, `ComponentMetadata`, `ComponentMetadataProvider`,
`ProfileCaptureSchema`, `kSleuthPackageVersion`, `PollTimings`,
`StreamResourcePollResult`, and the detector types `RepaintDetector`,
`ProfileCaptureSchema`, `kSleuthPackageVersion`, `PollTimings` and
`StreamResourcePollResult`. It also exports the detector types the
capture screens use, which 0.38 did not export: `RepaintDetector`,
`MemoryPressureDetector`, `StartupDetector`, `TrackedResourceDetector`,
`ImageMemoryDetector`, `GpuPressureDetector` and `FrameTimingDetector`.
- `lib/fix_data.yaml` lets `dart fix --apply` and IDE quick fixes update
code written against 0.38. They add the `validation.dart` import for the
ten moved names and delete the 29 removed `SleuthThemeData` arguments
from constructor and `copyWith` calls. On Flutter 3.32, whose Dart 3.8
analyzer rejects a moved class, enum or mixin, `dart fix` adds the import
only for `kSleuthPackageVersion`. Reads of a removed token, the three
removed theme helpers and the removed `Sleuth` statics have no direct
replacement and stay manual. CI checks the goldens in `test_fixes/` with
`dart fix test_fixes --compare-to-golden`.
- No longer exported: `ServiceExtensionRegistry`, `FixHintBuilder`,
`SessionMarkdownExporter`, `JankCaptureBuffer`, `FrameBudget`,
`FrameRateSource`, `resolveFrameBudget`, `RecurrenceTrend`,
Expand Down
Loading