diff --git a/CHANGELOG.md b/CHANGELOG.md index d66be24..596c4ee 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -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 diff --git a/CLAUDE.md b/CLAUDE.md index b6e8cf5..e4c538e 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -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 @@ -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 diff --git a/README.md b/README.md index d56237e..3448776 100644 --- a/README.md +++ b/README.md @@ -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 diff --git a/doc/api_1_0_0.md b/doc/api_1_0_0.md index 9e9eb42..8a72886 100644 --- a/doc/api_1_0_0.md +++ b/doc/api_1_0_0.md @@ -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/`. diff --git a/doc/release_notes/1.0.0.md b/doc/release_notes/1.0.0.md index 639dc89..5329379 100644 --- a/doc/release_notes/1.0.0.md +++ b/doc/release_notes/1.0.0.md @@ -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`,