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
7 changes: 7 additions & 0 deletions AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -108,6 +108,13 @@ Notes / 说明:
- [ ] `README_zh.md`: same spots as `README.md` (`^X.Y.Z`, `` `X.Y.Z` `` placeholder, `ref: release/vX.Y.Z`, and the "🔔 推荐升级:" callout). The callout should briefly summarize what the current release changed and recommend the latest version; it must not reference previous versions.
- [ ] `website/pages/*.md`: the install snippet uses the `__ZIK_VERSION__` placeholder; it is auto-filled from `pubspec.yaml` by `website/scripts/sync-docs.mjs`, so bumping `pubspec.yaml` alone is enough (do NOT hardcode a version there).
- [ ] `CHANGELOG.md`: add a new `## X.Y.Z` section at the top describing the changes.
- **CHANGELOG bilingual format / 变更日志双语格式:** Every entry MUST be bilingual English-primary, Chinese-secondary (EN-primary, ZH-secondary). Do NOT use a ` / ` slash to separate the two languages — it is too easy to miss. Use a nested sub-bullet instead: the English description is the top-level bullet, and the Chinese translation is an indented nested bullet directly beneath it, with **no** explicit "中文:" / "EN:" label. Section headers stay bilingual as `### Fixed / 修复`, `### Changed / 优化`, `### Added / 新增`. Example:
```markdown
### Fixed / 修复
- Fixed several memory-leak tracking issues: `_trackedRecords` now evicts oldest entries by priority `leaked > verifying > tracking > released` ...
- 修复内存泄漏追踪的若干隐患:`_trackedRecords` 改为按优先级 `leaked > verifying > tracking > released` ...
```
/ 每条变更必须英中双语(英文为主、中文为辅,EN-primary, ZH-secondary)。不要用 ` / ` 斜杠分隔中英文(太不显眼)。改用嵌套子条目:英文描述作为一级条目,中文翻译缩进为其下方子条目,且**不要**加"中文:" / "EN:" 这类显式标签。小节标题保持 `### Fixed / 修复`、`### Changed / 优化`、`### Added / 新增` 形式。
- **Changelog scope rule / 变更日志范围规则:** Only changes to `lib/` (i.e. published-package runtime behavior) earn a CHANGELOG entry. Pure documentation updates (`README*.md`, `website/`, `docs/`) and `example/` changes must NOT get a CHANGELOG entry — they do not change the released package's runtime behavior. The single exception is a **pure version-bump commit**: bumping the version legitimately updates the CHANGELOG (and the doc version strings) as part of cutting the release, which is allowed. / 只有 `lib/` 的改动(即已发布包的运行行为)才进 CHANGELOG;纯文档(`README*.md`、`website/`、`docs/`)与 `example/` 的改动不应写进 CHANGELOG——它们不改变发布包的运行行为。唯一的例外是「单纯 bump 版本」的提交:为发版而更新 CHANGELOG(及文档版本号)是允许的。
- Grep sanity check before committing: `grep -rn "old_version" README.md README_zh.md website/pages` must return NOTHING (only legitimate historical prose may remain; the `__ZIK_VERSION__` placeholder is expected and is not a real version).
**Website (Nextra docs site):** `website/` is built and synced to `docs/` automatically by the `pre-commit` hook (`website/scripts/sync-docs.mjs`). Version references in `website/pages/*.md` use the `__ZIK_VERSION__` placeholder, which is filled from `pubspec.yaml` at build time — bumping `pubspec.yaml` propagates to the site automatically. Never edit `docs/` by hand; it is regenerated on every commit that touches `website/`.
Expand Down
34 changes: 34 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,39 @@
# Changelog

## 1.14.0

### Fixed / 修复
- Fixed several memory-leak tracking issues: `_trackedRecords` now evicts oldest entries by priority `leaked > verifying > tracking > released`, closing the previous unbounded-growth hole where only `released` was trimmed (verifying records piled up especially on release / real-device without VM Service); guarded the VM Service WebSocket against concurrent reconnect leaks; added a reentrancy guard to the memory refresh. The tracking id stays `identityHashCode` to keep the public API and existing tests stable.
- 修复内存泄漏追踪的若干隐患:`_trackedRecords` 改为按优先级 `leaked > verifying > tracking > released` 级联淘汰最旧者,封住此前仅删 `released`、其余状态无界增长的内存风险(release / 真机无 VM Service 时 `verifying` 记录尤其会堆积);VM Service WebSocket 增加"连接中"并发保护避免重复建连泄漏;内存刷新增加重入守卫。追踪 ID 仍沿用 `identityHashCode` 以兼容公开 API 与既有测试。
- Fixed resource leaks: made the throttle fallback `Timer` cancelable (avoids transient piles of timers); de-duplicated `WsInspectorService` double-close; restored `FlutterError.onError` to null when it was originally null.
- 修复资源泄漏:`InspectorService.notifyThrottled` 的兜底 Timer 改为可取消(避免瞬时堆积大量 Timer);`WsInspectorService` 重复 `close` 去重;`LogInterceptor` 在 `FlutterError.onError` 原本为 null 时正确恢复。
- Fixed `AlertService` throttle key containing volatile numbers that defeated the 1s cooldown (key is now `source + rule.id`).
- 修复 `AlertService` 节流 key 含易变数值导致 1s 冷却失效的问题(key 改为 `source + rule.id`)。
- Fixed `PersistenceService.init` concurrent re-entry opening two databases (leaking the old handle) by serializing via `_initFuture`.
- 修复 `PersistenceService.init` 并发穿透导致重复 `openDatabase`(旧句柄泄漏),改用 `_initFuture` 串行化。
- Fixed Dio capture: a timeout/no-response now gets a `statusCode: -1` placeholder instead of hanging forever; `responseType: stream` no longer holds an unclosed `ResponseBody` (socket leak), and `bytes` is truncated to the preview cap.
- 修复 Dio 抓包:无响应(超时/网络错)时以 `statusCode: -1` 占位避免请求永挂"进行中";`responseType: stream` 不再持有未关闭的 `ResponseBody`(socket 泄漏),`bytes` 时按预览上限截断。
- Fixed route id collisions from millisecond timestamps by switching to a global auto-increment counter.
- 修复路由 id 用毫秒时间戳会碰撞(`didPush`+`didReplace` 同毫秒),改用全局自增计数器。
- Fixed interceptor rules' response-header rewrite being silently ignored; the HTTP client now infers scheme beyond just `443/8443` and forwards the real `connectionInfo`.
- 修复拦截规则"修改响应头"静默不生效(`responseHeaders` 仅定义未应用);HTTP client 仅按 `443/8443` 猜 scheme 会误判其它 TLS 端口为 http,并转发真实的 `connectionInfo`。
- Fixed `contentLength` after gzip decompression still reporting the pre-compression length.
- 修复 `inspector_response_proxy` gzip 解压后 `contentLength` 仍以压缩前长度下发导致面板字节数偏差。
- Fixed `environment.isInspectorEnabled` ignoring `--dart-define=INSPECTOR_ENABLED=false` in debug by using `String.fromEnvironment`.
- 修复 `environment.isInspectorEnabled` 在 debug 下 `--dart-define=INSPECTOR_ENABLED=false` 失效(改用 `String.fromEnvironment` 区分"未设置 vs false")。
- Fixed WebSocket frame body text in the network detail view rendering in default black on the dark card background (illegible); it now uses `InspectorColors.textPrimary`.
- 修复网络详情页 WebSocket 帧正文在深色卡片背景上以默认黑色渲染、看不清的问题,现改用 `InspectorColors.textPrimary`。
- Fixed `Switch` controls (WebSocket auto-scroll toggle and interceptor rule "Request Matching") using the default purple Material theme instead of the project's mint-green accent; they now use `InspectorColors.accent` for both thumb and track.
- 修复开关控件(WebSocket 自动滚动开关、拦截规则"Request Matching"开关)使用默认紫色 Material 主题而非项目薄荷绿的问题,现 thumbs/track 均使用 `InspectorColors.accent`。

### Changed / 优化
- Hardened sensitive-data masking: no longer falls back to the original body on error; supports Unicode-unescaped JSON keys; recurses into object/array values; widens the Bearer regex; adds phone/ID PII patterns.
- 敏感数据脱敏加固:失败不再原样回退(fail-open)而是保守脱敏;支持 JSON key 的 Unicode 转义(`\u0077` 等)反转义后匹配;敏感键值为对象/数组时也递归脱敏;Bearer 正则覆盖 `:` 等字符;新增手机号/身份证号 PII 正则。
- Perf: FPS frame list uses `ListQueue` to remove per-frame O(n) shifts; WS session body aggregation is throttled to 10Hz; storage stats gained re-entrancy protection.
- 性能:FPS 帧列表改用 `ListQueue` 消除每帧 O(n) 搬移;WS 会话 body 汇总降频到 10Hz;存储统计增加防重入。
- `InspectorService.maxBodyPreviewBytes` now counts real bytes instead of UTF-16 chars, avoiding ~2-3x under-budgeting for CJK / gzip base64.
- `InspectorService.maxBodyPreviewBytes` 单位由"UTF-16 字符"改为真实字节,避免中文 / gzip base64 场景低估约 2-3 倍预算。

## 1.13.0

### Changed / 优化
Expand Down
6 changes: 3 additions & 3 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 trims large request/response bodies before UTF-8 decoding, so the inspector no longer decodes a 512 KB body just to keep the first 32K characters of the preview — up to ~16x less decoding work for ASCII payloads, with preview content unchanged. All users are encouraged to upgrade to the latest version (`^1.13.0`).
> **🔔 Upgrade recommended:** This release fixes a batch of resource-leak and correctness issues across the inspector: unreleased UI controllers/scroll positions, a duplicated WebSocket connection, double-closed WS sessions, a broken alert throttle, persistence double-init, memory-leak tracking mis-keying, plus Dio failure/stream edge cases and sensitive-data masking gaps. All users are encouraged to upgrade to the latest version (`^1.14.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 @@ -102,7 +102,7 @@ An in-app developer console for Flutter: inspect HTTP, WebSocket & gRPC traffic,

```yaml
dependencies:
zero_inspector_kit: ^1.13.0
zero_inspector_kit: ^1.14.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.13.0 # replace 1.13.0 with the version you need
ref: release/v1.14.0 # replace 1.14.0 with the version you need
```

---
Expand Down
6 changes: 3 additions & 3 deletions README_zh.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@
[![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)

> **🔔 推荐升级:** 本版本在大体积请求 / 响应体解码前先做剪枝,不再为了保留面板预览的前 32K 字符而完整解码 512 KB 的 body —— 纯 ASCII 载荷的解码量最多降到约 1/16,预览内容完全不变。建议所有用户升级到最新版本(`^1.13.0`)。
> **🔔 推荐升级:** 本版本修复了一批检查器内的资源泄漏与正确性问题:未释放的 UI 控制器 / 滚动位置、重复的 WebSocket 连接、重复关闭的 WS 会话、失效的告警节流、持久化重复初始化、泄漏追踪的 key 冲突,以及 Dio 失败 / stream 边界、敏感数据脱敏缺口等。建议所有用户升级到最新版本(`^1.14.0`)。

🌐 **[官方网站](https://www.zerolabsco.com/)**  ·  📦 **[在 pub.dev 查看](https://pub.dev/packages/zero_inspector_kit)**  ·  🔗 **[查看 GitHub 仓库](https://github.com/zero-labsco/zero_inspector_kit)**

Expand Down Expand Up @@ -101,7 +101,7 @@

```yaml
dependencies:
zero_inspector_kit: ^1.13.0
zero_inspector_kit: ^1.14.0
```

### GitHub
Expand All @@ -111,7 +111,7 @@ dependencies:
zero_inspector_kit:
git:
url: https://github.com/zero-labsco/zero_inspector_kit.git
ref: release/v1.13.0 # 将 1.13.0 替换为你需要的版本号
ref: release/v1.14.0 # 将 1.14.0 替换为你需要的版本号
```

---
Expand Down
2 changes: 1 addition & 1 deletion docs/404.html
Original file line number Diff line number Diff line change
@@ -1 +1 @@
<!DOCTYPE html><html><head><meta charSet="utf-8"/><meta name="viewport" content="width=device-width"/><title>404: This page could not be found</title><meta name="next-head-count" content="3"/><link rel="preload" href="/zero_inspector_kit/_next/static/css/df9fc72061aac7da.css" as="style"/><link rel="stylesheet" href="/zero_inspector_kit/_next/static/css/df9fc72061aac7da.css" data-n-g=""/><noscript data-n-css=""></noscript><script defer="" nomodule="" src="/zero_inspector_kit/_next/static/chunks/polyfills-42372ed130431b0a.js"></script><script src="/zero_inspector_kit/_next/static/chunks/webpack-ad90bb3f37d3ab33.js" defer=""></script><script src="/zero_inspector_kit/_next/static/chunks/framework-64ad27b21261a9ce.js" defer=""></script><script src="/zero_inspector_kit/_next/static/chunks/main-f5dfbda958d94c6d.js" defer=""></script><script src="/zero_inspector_kit/_next/static/chunks/pages/_app-dfead9b5b0a86c83.js" defer=""></script><script src="/zero_inspector_kit/_next/static/chunks/pages/_error-7a92967bea80186d.js" defer=""></script><script src="/zero_inspector_kit/_next/static/rhZ5TDhK5xNMS7pIlRbZf/_buildManifest.js" defer=""></script><script src="/zero_inspector_kit/_next/static/rhZ5TDhK5xNMS7pIlRbZf/_ssgManifest.js" defer=""></script></head><body><div id="__next"><div style="font-family:system-ui,&quot;Segoe UI&quot;,Roboto,Helvetica,Arial,sans-serif,&quot;Apple Color Emoji&quot;,&quot;Segoe UI Emoji&quot;;height:100vh;text-align:center;display:flex;flex-direction:column;align-items:center;justify-content:center"><div style="line-height:48px"><style>body{color:#000;background:#fff;margin:0}.next-error-h1{border-right:1px solid rgba(0,0,0,.3)}@media (prefers-color-scheme:dark){body{color:#fff;background:#000}.next-error-h1{border-right:1px solid rgba(255,255,255,.3)}}</style><h1 class="next-error-h1" style="display:inline-block;margin:0 20px 0 0;padding-right:23px;font-size:24px;font-weight:500;vertical-align:top">404</h1><div style="display:inline-block"><h2 style="font-size:14px;font-weight:400;line-height:28px">This page could not be found<!-- -->.</h2></div></div></div></div><script id="__NEXT_DATA__" type="application/json">{"props":{"pageProps":{"statusCode":404}},"page":"/_error","query":{},"buildId":"rhZ5TDhK5xNMS7pIlRbZf","assetPrefix":"/zero_inspector_kit","nextExport":true,"isFallback":false,"gip":true,"scriptLoader":[]}</script></body></html>
<!DOCTYPE html><html><head><meta charSet="utf-8"/><meta name="viewport" content="width=device-width"/><title>404: This page could not be found</title><meta name="next-head-count" content="3"/><link rel="preload" href="/zero_inspector_kit/_next/static/css/df9fc72061aac7da.css" as="style"/><link rel="stylesheet" href="/zero_inspector_kit/_next/static/css/df9fc72061aac7da.css" data-n-g=""/><noscript data-n-css=""></noscript><script defer="" nomodule="" src="/zero_inspector_kit/_next/static/chunks/polyfills-42372ed130431b0a.js"></script><script src="/zero_inspector_kit/_next/static/chunks/webpack-ad90bb3f37d3ab33.js" defer=""></script><script src="/zero_inspector_kit/_next/static/chunks/framework-64ad27b21261a9ce.js" defer=""></script><script src="/zero_inspector_kit/_next/static/chunks/main-f5dfbda958d94c6d.js" defer=""></script><script src="/zero_inspector_kit/_next/static/chunks/pages/_app-dfead9b5b0a86c83.js" defer=""></script><script src="/zero_inspector_kit/_next/static/chunks/pages/_error-7a92967bea80186d.js" defer=""></script><script src="/zero_inspector_kit/_next/static/4hyj41opBQbKAj5dw70NM/_buildManifest.js" defer=""></script><script src="/zero_inspector_kit/_next/static/4hyj41opBQbKAj5dw70NM/_ssgManifest.js" defer=""></script></head><body><div id="__next"><div style="font-family:system-ui,&quot;Segoe UI&quot;,Roboto,Helvetica,Arial,sans-serif,&quot;Apple Color Emoji&quot;,&quot;Segoe UI Emoji&quot;;height:100vh;text-align:center;display:flex;flex-direction:column;align-items:center;justify-content:center"><div style="line-height:48px"><style>body{color:#000;background:#fff;margin:0}.next-error-h1{border-right:1px solid rgba(0,0,0,.3)}@media (prefers-color-scheme:dark){body{color:#fff;background:#000}.next-error-h1{border-right:1px solid rgba(255,255,255,.3)}}</style><h1 class="next-error-h1" style="display:inline-block;margin:0 20px 0 0;padding-right:23px;font-size:24px;font-weight:500;vertical-align:top">404</h1><div style="display:inline-block"><h2 style="font-size:14px;font-weight:400;line-height:28px">This page could not be found<!-- -->.</h2></div></div></div></div><script id="__NEXT_DATA__" type="application/json">{"props":{"pageProps":{"statusCode":404}},"page":"/_error","query":{},"buildId":"4hyj41opBQbKAj5dw70NM","assetPrefix":"/zero_inspector_kit","nextExport":true,"isFallback":false,"gip":true,"scriptLoader":[]}</script></body></html>
Loading
Loading