diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml
new file mode 100644
index 0000000..36df2c4
--- /dev/null
+++ b/.github/workflows/ci.yml
@@ -0,0 +1,53 @@
+name: CI
+
+on:
+ push:
+ branches: [main]
+ pull_request:
+
+jobs:
+ build-and-test:
+ runs-on: macos-15
+ steps:
+ - uses: actions/checkout@v7
+
+ # CommandLineTools alone cannot expand SwiftUI's @Observable / @Entry
+ # macros — the plugins ship only with full Xcode. Use the runner's
+ # default Xcode rather than pinning a version that may not be installed
+ # on a future image.
+ - name: Select Xcode
+ run: |
+ ls -d /Applications/Xcode*.app
+ sudo xcode-select -s /Applications/Xcode.app/Contents/Developer
+ swift --version
+
+ - name: Install XcodeGen
+ run: brew install xcodegen
+
+ - name: Test
+ run: make test
+
+ - name: Build app
+ run: make build CONFIG=Release
+
+ - name: Verify bundle
+ run: |
+ APP=build/DerivedData/Build/Products/Release/OpenStats.app
+ test -x "$APP/Contents/MacOS/OpenStats"
+ test -x "$APP/Contents/MacOS/OpenStatsHelper"
+ test -f "$APP/Contents/Library/LaunchDaemons/com.openstats.helper.plist"
+ test -f "$APP/Contents/Resources/AppIcon.icns"
+ codesign --verify --verbose "$APP"
+
+ # Smoke test: the panel is a menu-bar popover with no window to drive in
+ # CI, so render it off-screen instead. A view that traps on layout fails
+ # here rather than the first time a user clicks the menu-bar item.
+ - name: Render UI snapshots
+ run: |
+ build/DerivedData/Build/Products/Release/OpenStats.app/Contents/MacOS/OpenStats --snapshot "$PWD/snapshots"
+ test "$(ls snapshots/*.png | wc -l)" -ge 20
+
+ - uses: actions/upload-artifact@v7
+ with:
+ name: ui-snapshots
+ path: snapshots/
diff --git a/ARCHITECTURE.md b/ARCHITECTURE.md
new file mode 100644
index 0000000..affe277
--- /dev/null
+++ b/ARCHITECTURE.md
@@ -0,0 +1,105 @@
+# OpenStats
+
+macOS 14+ menu-bar system monitor. Swift 6 language mode, AppKit status item and panels
+hosting SwiftUI, no third-party dependencies. The Xcode project is generated from
+`project.yml` by XcodeGen; everything testable lives in the local Swift package.
+
+- `App/` — `main.swift` and the asset catalog.
+- `Helper/` — the privileged helper (`OpenStatsHelper`) and its launchd plist, embedded in
+ the app bundle for `SMAppService.daemon`.
+- `Packages/OpenStatsKit/Sources/SMC` — the AppleSMC user client, fan control, temperature
+ key discovery.
+- `Packages/OpenStatsKit/Sources/Metrics` — one sampler per metric and `MetricsHub`.
+- `Packages/OpenStatsKit/Sources/Cleaner` — cleanup rules, `SafetyGuard`, `CleanEngine`.
+- `Packages/OpenStatsKit/Sources/HelperShared` — the XPC protocol and maintenance commands
+ shared by the app and the helper.
+- `Packages/OpenStatsKit/Sources/OpenStatsUI` — design tokens, panel pages, settings,
+ menu-bar renderer, app controller, snapshot renderer.
+- `Packages/OpenStatsKit/Tests` — metrics, SMC decoding and cleanup safety.
+
+## Build
+
+**A full Xcode is required.** CommandLineTools does not ship the SwiftUI macro plugins.
+
+```bash
+brew install xcodegen
+make build # Debug
+make install # Release into /Applications
+make test # swift test in the package
+```
+
+Builds are ad-hoc signed (`CODE_SIGN_IDENTITY: "-"` in `project.yml`). For a release,
+switch to a Developer ID identity, keep hardened runtime on, notarize, and set
+`HelperConstants.teamIdentifier` so the helper's code-signing requirement includes the team.
+
+## Sampling
+
+`MetricsHub` is an actor that runs one loop. `AppModel.demand` describes what is on screen —
+which menu-bar items are enabled, whether the panel is open and on which tab — and the hub
+samples only that: CPU always; memory and network cheaply; GPU, disk, processes, sensors and
+fans only when a visible surface needs them. Disk is read at most every 30 s, battery every
+10 s. The loop pauses on screen sleep, system sleep and session switch.
+
+Things that are easy to get wrong and are handled on purpose:
+
+- `host_processor_info` returns kernel-allocated memory; it is `vm_deallocate`d every sample.
+- `getifaddrs`' `if_data` counters are 32-bit and wrap at 4 GiB; network uses
+ `NET_RT_IFLIST2` and `if_data64`.
+- Memory follows Activity Monitor: app memory is `internal − purgeable` pages; the page size
+ comes from `host_page_size` (16 KB on Apple Silicon).
+- Process CPU time and wall time are both in mach absolute units, so their ratio needs no
+ timebase conversion.
+- Core types come from `hw.perflevelN`; logical CPUs are numbered from the lowest
+ performance level up.
+
+## SMC
+
+Temperatures are not hard-coded per chip. On first use the sampler enumerates every SMC key
+once (≈3,800 keys in about 10 ms on an M5 Max), groups `Tp*`/`Te*` as CPU, `Tg*` as GPU,
+`Tm*` as memory, `TB*` as battery and `Ts0P`/`Ts1P` as palm rest, keeps keys whose first
+reading is plausible, and samples at most 12 per group.
+
+Fans are read without privileges. Writing needs root and goes through the helper. On M5
+the mode key (`F0md`) accepts a direct write; M1–M4 first need `Ftst=1` and a pause while
+`thermalmonitord` lets go. The firmware records only manual or automatic, not who set it, so
+a fan in manual mode that OpenStats did not set is shown as controlled by another program.
+
+## Helper
+
+Registered with `SMAppService.daemon`; `RunAtLoad` so that an unclean exit is repaired at
+boot. The XPC interface is a fixed list of operations — no arbitrary commands — and each
+connection gets `setCodeSigningRequirement`. State that must be undone (manual fans, disabled
+sleep) is persisted to `/Library/Application Support/OpenStats/helper-state.plist` and
+reverted when the last client disconnects or at the next start. The helper exits after 30 s
+without clients.
+
+## Cleanup
+
+Every rule lists candidate items; every item passes `SafetyGuard` twice — at scan and again
+right before deletion, because apps start in between.
+
+- Deny by default: an item must sit strictly inside an allow-listed root under the home
+ folder, never be the root itself, contain no `..` or control characters, and still pass
+ after symlinks are resolved (resolution can only reject, never allow).
+- Under `Application Support`, only folders named like caches (`Code Cache`, `GPUCache`,
+ `CacheStorage`, …) are allowed.
+- Any path component matching a protected keyword (keychains, password managers, VPNs,
+ cookies, history, …) is rejected.
+- Reverse-DNS cache folders whose app is running are skipped; browser rules are blocked while
+ the browser runs; items modified in the last two minutes count as in use.
+
+Regenerable caches are deleted outright; user files go to the Trash. Each action is appended
+to `~/Library/Logs/OpenStats/cleanup.log` as a JSON line.
+
+## Panel
+
+A borderless, non-activating `NSPanel` under the status item, hosting SwiftUI inside
+`NSGlassEffectView` on macOS 26+ (`NSVisualEffectView` before). The SwiftUI tree is created on
+open and destroyed on close, so a hidden panel costs nothing. Height comes from measuring a
+flat, scroll-free copy of the same view; placeholders keep that height stable until data
+arrives, and the window is resized without animation because animating it makes SwiftUI
+re-lay out every frame. Charts are drawn with `Canvas`, not Swift Charts.
+
+`--snapshot
` renders every panel tab, settings section and the menu bar in light and
+dark, through real `NSHostingView`s in off-screen windows — `ImageRenderer` washes out pages
+that contain bitmaps.
diff --git a/Assets/icon.png b/Assets/icon.png
new file mode 100644
index 0000000..1ae4185
Binary files /dev/null and b/Assets/icon.png differ
diff --git a/Assets/readme/activity.svg b/Assets/readme/activity.svg
new file mode 100644
index 0000000..a92ae24
--- /dev/null
+++ b/Assets/readme/activity.svg
@@ -0,0 +1,199 @@
+
diff --git a/Assets/readme/activity.zh.svg b/Assets/readme/activity.zh.svg
new file mode 100644
index 0000000..3d4ef2d
--- /dev/null
+++ b/Assets/readme/activity.zh.svg
@@ -0,0 +1,199 @@
+
diff --git a/docs/images/cleaner-light.png b/Assets/readme/cleaner-light.png
similarity index 100%
rename from docs/images/cleaner-light.png
rename to Assets/readme/cleaner-light.png
diff --git a/docs/images/keepawake-light.png b/Assets/readme/keepawake-light.png
similarity index 100%
rename from docs/images/keepawake-light.png
rename to Assets/readme/keepawake-light.png
diff --git a/docs/images/menubar-dark.png b/Assets/readme/menubar-dark.png
similarity index 100%
rename from docs/images/menubar-dark.png
rename to Assets/readme/menubar-dark.png
diff --git a/docs/images/overview-dark.png b/Assets/readme/overview-dark.png
similarity index 100%
rename from docs/images/overview-dark.png
rename to Assets/readme/overview-dark.png
diff --git a/docs/images/overview-light.png b/Assets/readme/overview-light.png
similarity index 100%
rename from docs/images/overview-light.png
rename to Assets/readme/overview-light.png
diff --git a/docs/images/settings-menubar-light.png b/Assets/readme/settings-menubar-light.png
similarity index 100%
rename from docs/images/settings-menubar-light.png
rename to Assets/readme/settings-menubar-light.png
diff --git a/docs/images/thermal-dark.png b/Assets/readme/thermal-dark.png
similarity index 100%
rename from docs/images/thermal-dark.png
rename to Assets/readme/thermal-dark.png
diff --git a/CHANGELOG.md b/CHANGELOG.md
new file mode 100644
index 0000000..b834aef
--- /dev/null
+++ b/CHANGELOG.md
@@ -0,0 +1,40 @@
+# 更新日志
+
+记录 OpenStats 应用的功能新增、样式调整和问题修复,按版本与日期倒序排列。
+官网、构建与发布脚本等不影响应用本身的改动不在此记录。
+
+## 未发布
+
+### 2026-09-13
+
+#### 新增
+
+- 菜单栏显示 CPU、GPU、内存、网速、CPU 温度和风扇转速。CPU、GPU、内存可以分别选择数字、柱状图、圆环、饼图、柱状图加数字五种样式;网速两行显示,绿点上传、蓝点下载,带完整单位。
+- 下拉面板分为概览、进程、散热、防休眠、清理五页。概览页顶部是健康评分和芯片、内存、系统版本、运行时长、机型徽章,下面是 CPU 柱状历史、GPU 折线、内存面积图、磁盘、网络双线、风扇三列卡片,以及核心负载、电池环形图、高占用进程和快捷开关。
+- CPU 按超级核、性能核、能效核分组显示各核心负载;内存口径与活动监视器一致,并显示内存压力;网速读取 64 位计数器,大流量下不会回绕。
+- 温度与风扇:启动时枚举一次 SMC 键并按前缀归类,不按芯片型号硬编码,显示 CPU、GPU、内存、电池和掌托温度。
+- 按界面需要分级采样:面板收起时只采集菜单栏用到的指标,锁屏、屏幕休眠和系统睡眠时暂停。
+- 风扇调速:自动、降温、强冷、自定义四种模式。自定义模式下 CPU 达到安全温度会自动交还系统控制,应用退出或断开连接时风扇恢复自动。
+- 防休眠:屏幕保持常亮、仅系统不休眠、合盖后继续运行,可设定持续时间;使用电池且电量低于下限时自动关闭合盖运行。
+- 辅助工具:通过 SMAppService 注册,只提供设置风扇转速、切换合盖不睡眠、刷新 DNS、释放内存几个固定操作,并校验调用方签名;异常退出后下次开机自动恢复风扇与睡眠设置。
+- 清理:扫描应用缓存、日志与崩溃报告、Chrome / Edge / Brave / Arc / Firefox / Safari 缓存、Xcode 编译缓存、模拟器缓存、npm 缓存、Xcode 归档、未完成的下载、安装包和废纸篓。按类别显示大小,可展开查看具体项目;清理前二次确认,操作写入 `~/Library/Logs/OpenStats/cleanup.log`。
+- 清理的安全边界:只清理白名单目录,钥匙串、密码管理器、VPN、Cookie、历史记录一律不碰;正在运行的应用和浏览器自动跳过,执行前逐项重新校验。
+- 系统维护:一键刷新 DNS 缓存、释放内存,已安装辅助工具时直接执行,否则请求一次管理员授权。
+- 进程页按 CPU 或内存排序,辅助进程归并显示为所属应用。
+- 设置窗口:外观、登录时启动、刷新频率、温度单位、菜单栏显示项与样式、风扇安全温度、合盖运行电量下限、辅助工具安装与卸载。
+- 外观可选跟随系统、浅色、深色;macOS 26 起面板使用液态玻璃。
+- 截图命令 `OpenStats --snapshot <目录>`:用本机实时数据渲染面板、设置和菜单栏的浅色与深色截图。
+
+#### 样式
+
+- 菜单栏字号对齐常见菜单栏监控工具:标签 7pt 细体、数值 12pt 常规、网速 9pt 细体,指标之间留出更宽的间距。
+- 面板加宽为三列布局,高度按内容自动计算,常见屏幕上不需要滚动。
+- 更换应用图标,面板左上角和关于页使用同一图标。
+- 首次启动默认在菜单栏显示 CPU、内存与网速。
+
+#### 修复
+
+- 深色菜单栏上 CPU、RAM 小标签颜色过深,几乎看不清。
+- 面板打开后高度会再调整一次、内容轻微回弹,看起来在抖动;面板打开时点击菜单栏图标关闭,会立刻又被打开。
+- 风扇被其他程序设为手动模式时,误显示为由 OpenStats 控制。
+- 风扇转速、PID 等数字出现千分位分隔符,例如 1,350 RPM。
diff --git a/LICENSE b/LICENSE
new file mode 100644
index 0000000..c060f0a
--- /dev/null
+++ b/LICENSE
@@ -0,0 +1,21 @@
+MIT License
+
+Copyright (c) 2026 GiantAccel, LLC
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+SOFTWARE.
diff --git a/README.md b/README.md
index bfe2fe5..33c156e 100644
--- a/README.md
+++ b/README.md
@@ -1,170 +1,260 @@
-
+**Your Mac at a glance — CPU, GPU, memory, network and temperatures in the menu bar, with fan control, keep-awake and one-click cleanup.**
-
-
-
-
+[](https://github.com/gentpan/OpenStats/releases/latest)
+[](https://github.com/gentpan/OpenStats/releases)
+[](https://github.com/gentpan/OpenStats/stargazers)
+[](https://github.com/gentpan/OpenStats/commits/main)
+[](https://github.com/gentpan/OpenStats/graphs/commit-activity)
+[](https://github.com/gentpan/OpenStats/actions/workflows/ci.yml)
+[](https://github.com/gentpan/OpenStats/releases/latest)
+[](LICENSE)
+
+OpenStats is a macOS menu-bar app that shows what your Mac is doing right now — per-core
+CPU load, GPU, memory pressure, network speed, disk, battery, temperatures and fans — and
+lets you act on it: spin the fans up, keep the Mac awake with the lid closed, clear caches.
+Everything is read on your own Mac. No account, no telemetry, no network access at all.
+
+[Download](https://github.com/gentpan/OpenStats/releases/latest) ·
+[Website](https://getopenstats.com) ·
+[Changelog](CHANGELOG.md) ·
+[Architecture](ARCHITECTURE.md)
+
+**English** · [简体中文](README.zh-CN.md)
+
+
---
-## 为什么做 OpenStats
+## Install
-市面上的菜单栏监控要么功能单一,要么常驻耗电。OpenStats 的目标很简单:
+OpenStats has not had a release yet. The first one will be a `.dmg` on
+[Releases](https://github.com/gentpan/OpenStats/releases/latest), signed with a Developer ID
+certificate and notarized by Apple, followed by a Homebrew cask. Until then, build it from
+source — see [Build & run](#build--run).
-- **一眼看全**:点开菜单栏就是一整屏仪表盘,不用翻页、不用下拉。
-- **足够省电**:面板收起时只采集菜单栏用到的指标,M5 Max 实测 **约 0.3% CPU、16 MB 内存**。
-- **原生体验**:Swift 6 + AppKit + SwiftUI,macOS 26 起使用系统液态玻璃,跟随浅色 / 深色外观。
+Requires macOS 14 (Sonoma) or later; the panel uses Liquid Glass on macOS 26 and later.
+Developed and tested on Apple Silicon. The interface is in Simplified Chinese.
-## 功能
+## Recent updates
-### 菜单栏
+
+
-
+
+## Where the numbers show
+
+**Menu bar**
+- CPU, GPU and memory each in one of five styles — number, bars, ring, pie, or bars with a
+ number — plus network speed, CPU temperature and the fastest fan.
+- Network speed takes two rows: a green dot for upload, a blue dot for download, always with
+ its unit (`KB/s`, `MB/s`, `GB/s`).
+- Labels at 7 pt and figures at 12 pt, matching the menu-bar monitors people already use.
+ Figures are fixed-width, so the bar does not jitter as they change.
+
+
+
+**Panel** — click the menu-bar item.
+- **Overview.** A health score with badges for the chip, memory, macOS version, uptime and
+ model; then CPU history as bars, GPU as a line, memory, disk, network and fans in three
+ columns; per-core load grouped by core type (super, performance, efficiency); battery as a
+ ring; the busiest processes and quick switches.
+- **Processes.** Sorted by CPU or memory; helper processes are shown under their app.
+- **Thermal.** CPU, GPU, memory, battery and palm-rest temperatures, and the fans.
+- **Keep awake.** Keep the display on, keep only the system awake, or keep running with the
+ lid closed — for a set time or indefinitely.
+- **Clean.** Scan, review, clean. See [Cleanup](#cleanup).
+
+The panel sizes itself to its content and needs no scrolling on common screens. `Esc`
+closes it. Light, dark or follow the system.
+
+
+
+
+
+
+## Fans and sleep
+
+| Fan mode | What it does |
|---|---|
-| 自动 | 交还 macOS 温控 |
-| 降温 | 固定在最低到最高转速的 60% |
-| 强冷 | 最高转速 |
-| 自定义 | 滑块自由设定 |
+| Auto | Hands the fans back to macOS |
+| Cool | Holds them at 60% between minimum and maximum speed |
+| Max | Full speed |
+| Custom | A slider, anywhere in the fan's range |
-安全机制:自定义模式下 CPU 达到设定温度(默认 95°C)自动交还系统控制;应用退出、崩溃或断开连接时风扇自动恢复。
+In Custom, the fans are handed back to macOS the moment the CPU reaches the safety
+temperature (95 °C by default). Quitting OpenStats, or the app crashing, restores automatic
+control. Running with the lid closed switches itself off on battery below a floor you choose.
-### 清理与系统维护
+Both need system privileges, provided by a small helper registered with `SMAppService` and
+approved once in System Settings → General → Login Items. The helper offers a fixed set of
+operations — set a fan's target speed, return fans to auto, toggle `pmset disablesleep`,
+flush the DNS cache, purge memory — and **never runs arbitrary commands**. It checks the
+caller's code signature, restores fans and sleep when the app disconnects, and after an
+unclean exit restores them at the next boot.
-- **一键扫描**:应用缓存、日志与崩溃报告、浏览器缓存(Chrome / Edge / Brave / Arc / Firefox / Safari)、Xcode 编译缓存、模拟器缓存、npm 缓存、Xcode 归档、未完成的下载、安装包、废纸篓。
-- **先预览再清理**:按类别显示大小,可展开查看具体项目并在访达中定位;清理前二次确认。
-- **安全边界**:只清理白名单目录;钥匙串、密码管理器、VPN、Cookie、历史记录一律不碰;正在运行的应用和浏览器自动跳过;执行前逐项重新校验;所有操作写入 `~/Library/Logs/OpenStats/cleanup.log`。
-- **系统维护**:一键刷新 DNS 缓存、释放内存(已安装辅助工具时直接执行,否则请求一次管理员授权)。
+## Cleanup
-
+- **What it scans.** App caches, logs and crash reports, browser caches (Chrome, Edge,
+ Brave, Arc, Firefox, Safari), Xcode DerivedData, simulator caches, the npm cache, Xcode
+ archives, unfinished downloads, installers and the Trash.
+- **Review first.** Sizes by category, every rule expandable to its items, a second click to
+ confirm. Caches and logs are deleted outright so the space comes back at once; downloads go
+ to the Trash. One switch sends everything to the Trash instead.
+- **Safety.** Only allow-listed folders are ever touched. Keychains, password managers,
+ VPNs, cookies and history are off limits. Caches of running apps are skipped, browsers must
+ be quit first, and every item is checked again right before it goes. Each action is logged
+ to `~/Library/Logs/OpenStats/cleanup.log`.
+- **Maintenance.** Flush the DNS cache and purge memory — through the helper if it is
+ installed, otherwise after a one-time administrator prompt.
-### 设置
+
-
+## Your data
-外观(跟随系统 / 浅色 / 深色)、登录时启动、刷新频率、温度单位、菜单栏显示项与样式、风扇安全温度、合盖模式电量下限。
+OpenStats makes **no network connections**. Metrics come from the kernel (`host_processor_info`,
+`host_statistics64`, `sysctl`), IOKit and the SMC on your own Mac. Preferences live in the
+app's user defaults and contain nothing personal. There is no analytics and no telemetry.
-## 技术实现
+## Build & run
-| 数据 | 来源 |
-|---|---|
-| CPU | `host_processor_info`,按 `hw.perflevelN` 区分核心类型 |
-| 内存 | `host_statistics64`,口径与活动监视器一致;`kern.memorystatus_vm_pressure_level` |
-| 网络 | `sysctl(NET_RT_IFLIST2)` 读取 64 位计数器(避免 `getifaddrs` 32 位回绕) |
-| GPU | `IOAccelerator` 的 `PerformanceStatistics` |
-| 温度 / 风扇 | AppleSMC;启动时枚举全部 SMC 键按前缀归类,**不硬编码芯片型号** |
-| 进程 | `proc_pid_rusage`,CPU 时间与墙钟时间同用 mach 时间单位 |
-| 电池 | `IOPowerSources` + `AppleSmartBattery` |
-
-采集按界面需要分级:面板收起时只采菜单栏用到的指标;锁屏、屏幕休眠、系统睡眠时暂停。图表全部用 Canvas 自绘,面板关闭后立即销毁视图。
-
-## 辅助工具与安全
-
-风扇调速、“合盖后继续运行”、刷新 DNS 与释放内存需要系统权限,由 `SMAppService.daemon` 注册的辅助工具完成,首次使用时在“系统设置 › 通用 › 登录项”中批准一次。
-
-- 只暴露固定的几个操作:设置风扇目标转速、恢复自动、切换 `pmset disablesleep`、刷新 DNS、释放内存,**不提供任意命令执行**。
-- 通过 XPC 通信,并校验调用方代码签名。
-- 客户端断开时自动恢复风扇与睡眠设置;异常退出后下次开机也会恢复。
-
-## 安装
-
-尚未发布正式版本。发布后将提供经过 Developer ID 签名与 Apple 公证的 DMG。
-
-## 从源码构建
-
-需要 Xcode 16 及以上,以及 [XcodeGen](https://github.com/yonaskolb/XcodeGen):
+Requires macOS 14+, a **full Xcode** (the SwiftUI macro plugins do not ship with
+CommandLineTools) and [XcodeGen](https://github.com/yonaskolb/XcodeGen).
```bash
brew install xcodegen
-make run # 生成工程、编译并启动(Debug)
-make run CONFIG=Release # Release 构建
-make install # Release 构建并安装到 /Applications 后启动
-make test # 单元测试
-make snapshot # 用本机实时数据渲染各页面截图到 build/snapshots
-make open # 生成并用 Xcode 打开工程
+make run # generate the project, build Debug and launch
+make install # build Release, install into /Applications and launch
+make test # unit tests: metrics, SMC decoding, cleanup safety
+make open # generate the project and open it in Xcode
```
-开发调试参数:
+The app is a menu-bar agent, so there is little to screenshot. Render the surfaces with
+live data instead:
-- `--snapshot <目录>`:输出面板、设置页、菜单栏的浅色 / 深色截图
-- `--show-panel`:启动后展开并固定面板,用于测量面板打开时的资源占用
-
-## 项目结构
-
-```
-App/ 应用入口与图标
-Helper/ root 辅助工具及其 launchd 配置
-Packages/OpenStatsKit/
- Sources/SMC SMC 读写、风扇控制、温度传感器归类
- Sources/Metrics 指标采集与分级调度(MetricsHub)
- Sources/HelperShared XPC 协议与系统维护命令
- Sources/Cleaner 清理规则、安全守卫、扫描与执行引擎
- Sources/OpenStatsUI 设计 token、面板、设置窗口、菜单栏绘制
- Tests/ 单元测试(采集、SMC 编解码、清理安全边界)
-project.yml XcodeGen 工程描述
-docs/PLAN.md 技术方案与调研记录
+```bash
+build/DerivedData/Build/Products/Debug/OpenStats.app/Contents/MacOS/OpenStats --snapshot ./snapshots
```
-## 路线图
+Glass and vibrancy exist only on screen. To measure the panel while it is open, launch with
+`--show-panel`, which opens the panel and pins it.
-- [x] 菜单栏多指标与多种显示样式
-- [x] 概览仪表盘、进程、散热、防休眠
-- [x] 液态玻璃面板与浅色 / 深色主题
-- [x] 风扇调速与合盖运行(辅助工具)
-- [x] 缓存清理、刷新 DNS、释放内存
-- [ ] 应用卸载(含残留文件与程序坞图标)
-- [ ] 磁盘健康(SSD 寿命、写入量、温度)
-- [ ] 点击菜单栏各指标弹出独立详情
-- [ ] Developer ID 签名、公证与 DMG 发布
-- [ ] Sparkle 自动更新
-- [ ] 功耗、磁盘读写等更多指标
-- [ ] 桌面小组件
+After editing `CHANGELOG.md`, run `python3 Scripts/sync_changelog.py` to refresh the recent
+updates above and the activity chart.
-## 致谢
+## Distribution
-SMC 通信与 Apple Silicon 风扇控制流程移植自 [exelban/stats](https://github.com/exelban/stats)(MIT License),详见 [ThirdPartyNotices.md](ThirdPartyNotices.md)。
+Developer ID only, not the App Store — the sandbox forbids talking to the SMC, reading other
+apps' caches and installing a privileged helper, which is most of the feature set.
-## 许可证
+| What you have | What others get |
+|---|---|
+| Nothing | Ad-hoc signature — runs on your Mac only. Others see *"OpenStats is damaged"*. |
+| Developer ID certificate | Hardened runtime. Others see *"Apple cannot check it for malicious software"*. |
+| Certificate + notarization | Gatekeeper accepts it — the normal *"downloaded from the internet"* prompt. |
-待定。
+Before a release, set the Team ID in `HelperShared/HelperProtocol.swift` so the helper
+requires the caller to be signed by it.
+
+## Architecture
+
+- `Packages/OpenStatsKit/Sources/SMC` — SMC reads and writes, fan control, temperature
+ sensor discovery.
+- `Packages/OpenStatsKit/Sources/Metrics` — samplers for CPU, memory, network, GPU, disk,
+ battery, processes and sensors, and `MetricsHub`, which samples only what is on screen.
+- `Packages/OpenStatsKit/Sources/Cleaner` — cleanup rules, the safety guard, scanning and
+ cleaning.
+- `Packages/OpenStatsKit/Sources/HelperShared` — the XPC protocol and maintenance commands.
+- `Packages/OpenStatsKit/Sources/OpenStatsUI` — design tokens, the panel, settings and the
+ menu-bar renderer.
+- `Helper/` — the privileged helper and its launchd plist. `App/` — the entry point.
+
+More in [ARCHITECTURE.md](ARCHITECTURE.md). Every change to the app is logged, dated, in
+[CHANGELOG.md](CHANGELOG.md).
+
+## Acknowledgements
+
+OpenStats builds on these open-source projects. Thank you.
+
+| Project | Author | License | What OpenStats took |
+|---|---|---|---|
+| [Stats](https://github.com/exelban/stats) | Serhiy Mytrovtsiy | MIT | SMC access, the Apple Silicon fan unlock sequence and the menu-bar mini widget metrics |
+| [Mole](https://github.com/tw93/Mole) | tw93 | GPL-3.0 | Which folders are worth cleaning and which must never be touched; the cleaner is an independent Swift implementation and contains no Mole code |
+| [QuotaBar](https://github.com/gentpan/quotabar) | GiantAccel, LLC | MIT | This README's layout, the changelog sync and the activity chart |
+
+Details in [ThirdPartyNotices.md](ThirdPartyNotices.md).
+
+OpenStats is an independent third-party app. It is not affiliated with, endorsed by, or
+sponsored by Apple or any other company it mentions. Their names and logos belong to their
+respective owners.
+
+## License
+
+MIT — see [LICENSE](LICENSE).
diff --git a/README.zh-CN.md b/README.zh-CN.md
new file mode 100644
index 0000000..738bc65
--- /dev/null
+++ b/README.zh-CN.md
@@ -0,0 +1,233 @@
+