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
18 changes: 18 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,23 @@
# Changelog

## 1.11.0

### Added / 新增
- `ZeroInspectorKit.dispose()`:完整释放检查器占用的进程级资源(持久化刷盘 Timer、`FlutterError.onError` 接管、内存 / FPS 定时器、throttle notifier、持久化落盘),集成测试结束或宿主 App 运行时关闭采集(如隐私合规开关)后可彻底停采,再用 `init` 重新启用。 / `ZeroInspectorKit.dispose()` fully releases the inspector's process-wide resources (persistence flush Timer, `FlutterError.onError` hook, memory / FPS timers, throttle notifiers, on-disk persistence) so collection can be switched off entirely at runtime and re-enabled via `init`.
- 可编辑重放编辑器 `InspectorReplayEditor`(`showReplayEditor`)与 `buildReplayRequest` 工具:详情页点 Replay 弹出底部面板,URL / Header / Body 只读,仅查询参数可编辑,重发时用修改后的参数重建 URL,并在面板内预览响应(状态码 / 耗时 / 前 400 字节)。 / An editable replay editor `InspectorReplayEditor` (`showReplayEditor`) plus the `buildReplayRequest` helper: a bottom sheet from the request detail lets you edit only the URL query parameters (URL / headers / body stay read-only), rebuilds the URL from the edited params on send, and previews the response in-panel.
- 新增公开工具:`sensitive_data`、`inspector_version`;`fps_service` 由内部提升为公开导出,便于外部直接引用。 / New exported utilities: `sensitive_data`, `inspector_version`; `fps_service` is promoted to a public export.
- FPS 分相耗时:单帧记录新增 `buildDurationUs` 与 `rasterDurationUs`(GPU 光栅化),掉帧列表项同时展示 build / raster 分项,便于定位是构建还是光栅化卡顿。 / FPS phased timing: each frame record now carries `buildDurationUs` and `rasterDurationUs` (GPU raster), and the janky-frame list shows the build / raster split so you can tell whether build or raster is the bottleneck.
- 自适应卡顿阈值:掉帧阈值改按设备标称刷新率换算(60Hz≈16.7ms、120Hz≈8.3ms),高刷屏同样严格,不再被固定 16ms 放过。 / Adaptive jank threshold: the per-frame budget is now derived from the display refresh rate (≈16.7ms at 60Hz, ≈8.3ms at 120Hz) so high-refresh displays keep a tight bar.
- `PlatformDispatcher.onError` 接入:异常聚合服务现在同时接管 `PlatformDispatcher.onError`(接管 + 还原),捕获 `FlutterError.onError` 漏掉的框架边界外 / 平台通道回包异常,一并聚合进 Errors Tab。 / `PlatformDispatcher.onError` hook: the error aggregator now also hooks `PlatformDispatcher.onError` (with save/restore), catching errors that `FlutterError.onError` misses — those thrown outside the framework boundary or from platform-channel replies — and aggregating them too.
- 告警持久化:告警事件随日志/网络/异常一起异步落盘到 SQLite,崩溃或重启后可在 Alerts 标签回看;会话存档导出也包含 `alerts` 段。新增 `AlertService.restore` 与 `PersistenceService.loadAlerts`。 / Alert persistence: alert events now flush to disk alongside logs/network/errors, so they survive crashes and restarts and can be reviewed in the Alerts tab; the session archive export also includes an `alerts` section. New `AlertService.restore` and `PersistenceService.loadAlerts`.

### Fixed / 修复
- 拦截器请求体缓冲无上限导致大 body 经 `add` / `write` 上传 OOM(上限此前只实现在 `addStream` 上):现 `add` / `write` 也按 512KB 上限缓冲,超限后直传底层请求,重放不再重复写入或截断大 body。 / Interceptor request-body buffering was unbounded, so uploading a large body through `add` / `write` could OOM (the cap only existed on `addStream`); `add` / `write` now also honor the 512KB cap and switch to pass-through, and replay no longer duplicates or truncates large bodies.
- 二进制响应(gzip / brotli / protobuf / 图片)解码失败会抛异常、整条记录(含状态码)丢失:现降级为「字节数 + 前若干字节 hex 预览」,小体积二进制改用 base64 承载,面板可直接预览图片。 / Binary responses (gzip / brotli / protobuf / images) used to throw and lose the whole record (status code included); they now fall back to a byte count + leading hex preview, and small binary bodies are carried as base64 so the panel can preview them.
- `AlertService` 节流表(`(source, message)`,source 多为完整 URL)长跑无界增长,造成确定性内存泄漏:现设 512 项硬上限 + 软阈值过期清扫,按插入顺序淘汰最旧项。 / `AlertService`'s throttle map (keyed by `(source, message)`, source often a full URL) grew unbounded over long runs — a deterministic leak; it now has a 512-entry hard cap plus an expiry sweep, evicting the oldest entries by insertion order.
- Hive / SharedPreferences 查看器同键混含 `int` 与 `String` 时 `List.sort()` 抛 `TypeError`:抽出共享 `KeyValueQuery` 工具做安全排序与分页,永不抛异常。 / The Hive / SharedPreferences viewers threw `TypeError` from `List.sort()` when keys mixed `int` and `String`; a shared `KeyValueQuery` helper now does safe sorting and paging that never throws.
- `LogLevel` 缩写文本此前在 `LogEntry` 与 `ExportService` 各有一份相同 switch,新增级别易漏改:收敛为单一 `LogLevelText.of`。 / The `LogLevel` abbreviation switch was duplicated in `LogEntry` and `ExportService`; it is now a single `LogLevelText.of` implementation.

## 1.10.1

### Changed / 变更
Expand Down
35 changes: 24 additions & 11 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ An in-app developer console for Flutter: inspect HTTP, WebSocket & gRPC traffic,
[![Dart](https://img.shields.io/badge/Dart-✓-0175C2?logo=dart)](https://dart.dev)
[![Style: effective dart](https://img.shields.io/badge/style-effective_dart-40c4ff.svg)](https://pub.dev/packages/effective_dart)

> **🔔 Upgrade recommended:** This release updates the open-source license — the plugin is now **MPL-2.0** (commercial and closed-source use allowed; modified files must be published in source form). The `LICENSE` file is now the clean upstream MPL-2.0 text so pub.dev detects it, with the copyright notice and additional statements moved to [NOTICE](NOTICE). All users are encouraged to upgrade to the latest version (`^1.10.1`).
> **🔔 Upgrade recommended:** This release adds an editable replay editor (edit only query params — URL/headers/body stay read-only), phased FPS timing (build + raster split) with an adaptive jank threshold, `PlatformDispatcher.onError` capture, and on-disk alert persistence that survives restarts. It also adds `ZeroInspectorKit.dispose()` for a full runtime teardown. All users are encouraged to upgrade to the latest version (`^1.11.0`).

🌐 **[Official Website](https://www.zerolabsco.com/)**  ·  📦 **[View on pub.dev](https://pub.dev/packages/zero_inspector_kit)**  ·  🔗 **[View on GitHub](https://github.com/zero-labsco/zero_inspector_kit)**

Expand Down Expand Up @@ -57,16 +57,16 @@ An in-app developer console for Flutter: inspect HTTP, WebSocket & gRPC traffic,
## Features

- **Zero-Invasion Integration** — One line of code, no changes to existing project code.
- **Network Inspector** — Real-time capture of all HTTP (http & Dio) requests; modify bodies/headers via interceptor rules; batch cURL copy; sensitive-header masking; filterable by method/status/interception.
- **Network Inspector** — Real-time capture of all HTTP (http & Dio) requests; modify bodies/headers via interceptor rules; in-app **replay editor** (edit only query params — URL/headers/body stay read-only — and preview the response); batch cURL copy; sensitive-header masking; filterable by method/status/interception.
- **WebSocket / gRPC Capture** — Opt-in streaming-protocol capture (off by default, runtime toggle like Memory/FPS); WebSocket frames and gRPC calls appear in the Network list.
- **Logging System** — Auto-captures `print()`, `debugPrint()`, and custom logs across multiple levels; integrates with third-party log libraries; auto-scroll (pausable), regex search, tag filtering and one-tap copy of a single log entry.
- **Error Monitor** — Dedicated Errors tab (since v1.9.0): hooks `FlutterError.onError` + `runZonedGuarded`, aggregates & dedups crashes by type + stack signature with count and first/last seen; a red count badge sits on the Errors tab icon.
- **Session Persistence** — Logs / network / errors are asynchronously flushed into the inspector's own `zero_inspector_kit.db` (since v1.9.0; a disk ring buffer that also shows up in the Database tab); on launch logs & errors replay into their tabs; export & share the full session archive from the panel header.
- **Session Persistence** — Logs / network / errors / **alerts** are asynchronously flushed into the inspector's own `zero_inspector_kit.db` (since v1.9.0; a disk ring buffer that also shows up in the Database tab); on launch logs, errors & alerts replay into their tabs; export & share the full session archive (now including alerts) from the panel header.
- **Database Viewer** — Inspect SQLite and other databases via custom providers.
- **Memory Monitor** — Trend chart, Dart Heap, Native memory breakdown, leak detection, image-cache & storage stats (master switch to avoid overhead). Since v1.9.0 the leak detector also bridges Flutter's official `FlutterMemoryAllocations` to cut false positives.
- **FPS Monitor** — Real-time FPS, jank detection, trend chart, frame records (master switch to avoid overhead).
- **Route Tracker** — Navigation history and current route.
- **Alert System** — Rule-based alerts on network/logs/memory/FPS with unread badge and throttling.
- **FPS Monitor** — Real-time FPS, jank detection, trend chart, frame records with **phased build + raster timing** and an **adaptive jank threshold** derived from the display refresh rate (so 120Hz screens stay strict). Master switch to avoid overhead.
- **Route Tracker** — Navigation history and current route (`navigatorObservers: [InspectorRouteObserver()]`).
- **Alert System** — Rule-based alerts on network/logs/memory/FPS with unread badge and throttling; alerts are persisted to disk and survive app restarts.
- **Floating Button** — Breathing-animation overlay button that auto-docks to screen edges, avoiding back-gesture conflicts.
- **One-Click Bug Report** — Tap the bug icon in the panel header to share a ready-to-file snapshot (device model + OS + current memory + recent logs + recent network) via the system share sheet.
- **Modern UI** — Dark theme with gradients and centralized, customizable colors.
Expand Down Expand Up @@ -102,7 +102,7 @@ An in-app developer console for Flutter: inspect HTTP, WebSocket & gRPC traffic,

```yaml
dependencies:
zero_inspector_kit: ^1.10.1
zero_inspector_kit: ^1.11.0
```

### GitHub
Expand All @@ -112,7 +112,7 @@ dependencies:
zero_inspector_kit:
git:
url: https://github.com/zero-labsco/zero_inspector_kit.git
ref: release/v1.10.1 # replace 1.10.1 with the version you need
ref: release/v1.11.0 # replace 1.11.0 with the version you need
```

---
Expand Down Expand Up @@ -243,7 +243,7 @@ InspectorLogInterceptor.instance.onLogCaptured = (entry) {

> Available since v1.9.0

The **Errors** tab answers "is the same crash happening repeatedly?" `ErrorService` hooks `FlutterError.onError` (keeping the default red-screen behavior) plus `runZonedGuarded` inside `runAppWithInspector()`, then aggregates each exception by **type + stack signature**: repeated crashes merge into one record with a **×N** count and first/last-seen time. Tap a row to expand the full stack sample, filter by search, and copy individual stacks. A red count badge on the Errors tab icon shows the number of aggregated records while the panel is open.
The **Errors** tab answers "is the same crash happening repeatedly?" `ErrorService` hooks `FlutterError.onError` and `PlatformDispatcher.onError` (both with save/restore, default red-screen behavior kept) plus `runZonedGuarded` inside `runAppWithInspector()`, then aggregates each exception by **type + stack signature**: repeated crashes merge into one record with a **×N** count and first/last-seen time. Tap a row to expand the full stack sample, filter by search, and copy individual stacks. A red count badge on the Errors tab icon shows the number of aggregated records while the panel is open.

```dart
import 'package:zero_inspector_kit/zero_inspector_kit.dart';
Expand All @@ -264,7 +264,7 @@ Toggle with `enableErrorCapture` in `init()` (default `true`). Full details on t

> Available since v1.9.0

Logs, network requests, and aggregated errors are asynchronously flushed into the inspector's own database file, **`zero_inspector_kit.db`** — a SQLite-backed disk ring buffer that also appears in the **Database** tab. On the next launch, **logs and aggregated errors replay into their tabs**; network requests stay archived on disk for later export. Data therefore survives app restarts even if you never opened the panel. Tap the **storage icon** in the panel header to open the **Persisted data** manager: see row counts per category, export the **full session archive** as JSON (share sheet), or clear the disk.
Logs, network requests, aggregated errors and **alerts** are asynchronously flushed into the inspector's own database file, **`zero_inspector_kit.db`** — a SQLite-backed disk ring buffer that also appears in the **Database** tab. On the next launch, **logs, aggregated errors and alerts replay into their tabs**; network requests stay archived on disk for later export. Data therefore survives app restarts even if you never opened the panel. Tap the **storage icon** in the panel header to open the **Persisted data** manager: see row counts per category, export the **full session archive** (now including an `alerts` section) as JSON (share sheet), or clear the disk.

```dart
// Reading persisted data programmatically (optional)
Expand Down Expand Up @@ -376,8 +376,9 @@ MemoryInspectorService.instance.clearLeakRecords(); // clear all
Real-time frame analysis with a master switch (off by default).

- **Master Switch:** top toggle; off = no timings callback, zero overhead.
- **Metrics:** current FPS, jank rate, total frames, 30-second trend chart (60 points), janky-frame list (>16ms).
- **Metrics:** current FPS, jank rate, total frames, 30-second trend chart (60 points), janky-frame list with **build + raster split** (each janky frame shows its build vs raster duration so you can tell which phase stalled).
- **Accuracy (since v1.2.1):** uses real `buildStart` timestamps (not `DateTime.now()`) and `rasterFinish - buildStart` duration, catching GPU raster jank.
- **Adaptive threshold:** the jank cutoff is derived from the display refresh rate (`1000ms / refreshRate`), so 60Hz≈16.7ms while a 120Hz screen uses a tight ≈8.3ms bar instead of being let through by a fixed 16ms.

```dart
FpsService.instance.start();
Expand Down Expand Up @@ -440,6 +441,18 @@ Sensitive headers are masked the same way as in the Network tab (toggle "Sensiti

## API Reference

### ZeroInspectorKit

The top-level entry class. Call `init()` (or `runAppWithInspector()`) once to start collection; call `dispose()` to fully release the inspector's process-wide resources (persistence flush timer, `FlutterError.onError` / `PlatformDispatcher.onError` hooks, memory / FPS timers, throttle notifiers and on-disk persistence) so collection can be switched off entirely at runtime — e.g. behind a privacy-compliance toggle — and re-enabled later via `init()`.

```dart
// Fully stop collection (releases every process-wide resource).
ZeroInspectorKit.instance.dispose();

// Re-enable later with the same or different options.
ZeroInspectorKit.instance.init();
```

### FloatingInspectorButton

| Parameter | Type | Description |
Expand Down
Loading
Loading