Files
XStats/README.md
T
缘生 6a7aeffb83 fix(security): 修复辅助工具鉴权、升级路径与卸载误删 (#1)
* fix(security): 修复辅助工具鉴权降级与五处正确性缺陷

代码审查(安全/质量/性能/架构四维度)发现的问题,逐条修复。

辅助工具鉴权(High)
  ad-hoc 构建下 clientRequirement 退化为只校验 bundle identifier,不含
  anchor 约束,任何进程 codesign -s - 伪造同名即可连上 root 辅助工具,
  驱动 DNS、睡眠、本地快照与风扇。project.yml 默认就是 ad-hoc 签名,
  而 make build 是文档化的安装路径,开发机上属常态。
  改为无团队签名时返回 nil 并拒绝连接,与在线升级在 ad-hoc 下直接禁用
  的策略一致;此时 App 走一次性管理员授权回退,功能不丢。

卸载器批量误删
  validate 只拒绝 com.apple. 前缀,包名为 "com" 的应用可通过;随后
  hasPrefix("com.") 把 leftovers 扫描的十余个目录(Preferences、Caches、
  Containers、Saved Application State 等)下所有 com.* 条目当成残留列出
  并默认勾选,一次点击即整体移入废纸篓。前缀匹配改为要求至少三段反向
  域名,精确匹配不受影响。

退出时静默跳过恢复睡眠
  restoreDefaultsSynchronously 的 guard 在循环体内用 return 而非 continue,
  第一步取代理失败就连带跳过第二步,Mac 保持禁止睡眠。同时把两步各等 1 秒
  改为总预算 1.5 秒,避免主线程退出卡顿。

公网 IP 查询重入保护失效
  isLookingUpPublic 同时承担重入锁与转圈开关两个相反职责,有缓存且非强制
  刷新时恒为 false,guard 形同虚设,两个 Task 可各发三次请求并发写缓存,
  失败结果可能覆盖好结果。拆出独立的 isFetchingPublic,并用 defer 确保
  所有退出路径复位。

诊断导出的崩溃报告未脱敏
  日志与清理记录都走了 redact,但 .ips 崩溃报告原样入包,其中可能夹带
  进程内存中的 WebDAV 目录、用户名、公网 IP 与主机名,与界面“不含 IP、
  序列号与硬件地址”的声明不符。改为同样脱敏后写入。

PowerSampler
  channels(in:) 的 unsafeBitCast 改为 Unmanaged.fromOpaque.takeUnretainedValue。
  未加 deinit 释放 IOReport 订阅:IOReport 是私有框架,无公开释放入口且
  无法验证其是否为 CF 对象,而全进程只有一个 PowerSampler、订阅各只创建
  一次且随进程存在,不是增长型泄漏——已就此写明注释。

补回归测试:clientRequirement 的 ad-hoc 分支与 anchor 约束、
matchesIdentifier 的过宽前缀与派生名匹配。

make test 141 项通过(新增 4 项),Release 完整构建通过。

* fix(security): 完善辅助工具升级与卸载边界校验

* fix(ui): 拆分评分条视图以解决 CI 类型检查超时

* fix(webdav): 规范化目录路径以兼容 macOS 15
2026-09-21 09:34:01 +08:00

21 KiB
Raw Blame History

XStats

XStats

Mac 的状态,抬眼就看见——CPU、GPU、内存、网络与温度常驻菜单栏,还能调风扇、防休眠、一键清理、卸载应用,检测 IP 纯净度。

Release Stars Last commit Commit activity CI macOS License

XStats 是一款 macOS 菜单栏应用,实时显示 Mac 正在做什么:各核心 CPU 负载、GPU、内存压力、 网速、磁盘、电池、温度和风扇,并且可以直接处理:给风扇提速、合盖后继续运行、清理缓存、彻底卸载应用、停用启动项; 网络详情还能检测公网 IP 的纯净度,看出出口是否被标记为 VPN、代理、机房或有滥用记录。 所有数据都在你自己的 Mac 上读取,没有统计上报。不需要 XStats 账号,可通过自己的 WebDAV 服务器手动备份和恢复偏好设置。其他可关闭的联网功能包括:打开网络详情时查询公网 IP 与纯净度、定时 ping 你选择的探测目标,以及每天检查一次新版本。

下载 · 更新日志 · 架构说明

简体中文 · English · 日本語 · 한국어


安装

在 GitHub Releases 查看已发布的 XStats 构建,按 Mac 芯片选择 AppleSilicon 或 Intel。 若尚无构建可下载,请按下文从源码构建。

XStats 暂无官网。自动更新与现有 GeoIP 服务保持不变;账号登录已替换为手动 WebDAV 同步。 更新安装仍严格检查应用身份与签名:旧服务提供的 OpenStats 安装包不能替换 XStats。

需要 macOS 14(Sonoma)或更高版本。主要在 Apple 芯片上开发和测试;Intel 机型上不能用 Apple 智能解释进程, CPU 不分性能核与能效核,部分功耗与频率读数可能不显示。 界面支持简体中文、繁體中文、日本語、한국어、English、Deutsch、Español、Français 和 العربية。 默认自动检测系统首选语言,可在“设置 · 通用 · 语言”中搜索并切换;阿拉伯语使用从右到左布局。

最近更新

最新版本 0.6.1(2026-09-18) · 开发中 3 项改动尚未发布 · 完整更新日志

2026-09-20 · 未发布 · 新增 2 · 调整 1

新增

  • 语言设置支持搜索下拉选择、自动检测和选中标记,增加繁体中文、日语、韩语、德语、西班牙语、法语与阿拉伯语;阿拉伯语使用从右到左布局,语言偏好继续参与 WebDAV 设置备份。
  • 设置同步改用 WebDAV:配置已有 HTTPS 目录、用户名和密码,手动上传本机设置或下载后确认应用。密码只存本机钥匙串,备份不包含监控数据、历史记录和连接凭据;文件大小、格式与版本校验失败时保持本机设置不变。

调整

  • 移除 GitHub、Google、Apple 账号登录及后台自动同步,不再依赖原账号服务和登录回调。自动更新及 GeoIP 服务保持现状。
2026-09-18 · 0.6.1 · 新增 1

新增

  • 菜单栏“合并为一个”时,点击图标弹出状态总览,不再直接打开主窗口:菜单栏里开启的每一项占一行,写着当前数值、一句状态(负载与温度、已用内存、上下行速度、剩余时间等)和最近的走势,数值偏高时变色;点一行或点顶部的标签,就能看到该项的完整详情,与“每项独立”时点单个图标看到的一样。顶部标签可在总览与各项之间来回切换,面板高度随内容变化;标题栏右侧可以打开主窗口的仪表盘或设置。「设置 · 菜单栏」里各项弹窗显示哪些区块的选项,合并模式下同样可用。解决 Issue #2:合并显示时点击只能打开主窗口,看不到各项状态。
2026-09-18 · 0.6.0 · 新增 5 · 样式 1

新增

  • 新增出口与分流窗口:网络页顶栏和菜单栏网络弹窗各有一个入口。一次检测约十秒,看清 VPN 与代理有没有生效、各个网站分别从哪个出口出去。
  • 结论只用一句话说清:未使用代理、代理出口(地区)、代理没有生效、网络不通四种情况。右侧同时给出经代理、直连、连不上的网站数量。
  • 本机网络:物理网卡的出口 IP、归属地、运营商与 IPv6。归属地数据来自 cleanip.io。
  • 网站分流:25 个常用网站分别从哪个出口出去。按 AI、影音、社交、开发、国内分类筛选;接入 Cloudflare 的网站能实测出口与边缘节点,其余按国内 / 国际规则推断,每个网站带延迟信号条。
  • 代理方式一览:VPN / 隧道、系统代理、自动代理配置、DNS 与检测到的代理软件。DNS 被代理接管时会标出来。

样式

  • 菜单栏网络弹窗的 DNS 区块重排:网络服务与线路做成两个徽章(Wi-Fi / 有线、直连或经过哪个代理),走隧道时标题旁有叹号提示 DNS 可能被接管,刷新 DNS 缓存改为图标按钮。

活跃度

近 26 周每天的提交数

星标历史

界面一览

主窗口仪表盘(深色) 主窗口仪表盘(浅色)

数据显示在哪里

菜单栏

  • 八种风格整体选择、统一套用:双行文字、单行文字、图标、圆环、饼图、柱状历史、电量条、状态圆点; 也可以给个别指标单独指定。设置里每种风格都有示例预览,并说明图形代表什么。
  • 网速可选双行圆点、双行箭头或单行:绿色上传、蓝色下载,始终带单位(KB/s、MB/s、GB/s)。
  • 字号小而统一:两行布局 7pt 标签加 10pt 数值,单行 11pt,网速 9pt;数值等宽,刷新时菜单栏不抖动。 鼠标悬停显示完整读数。

菜单栏

详情弹窗——每个指标一个菜单栏图标,点击弹出该项的窄详情,显示哪些区块可在设置里勾选;按 Esc 关闭。

  • CPU:占用与状态、与 30 秒前的变化、CPU 温度与余量、1 / 3 / 5 分钟走势;核心热力图与此刻各核心占用;核心分工与频率;排队程度(每核平均负载与趋势);按应用汇总。
  • 内存:还可用多少与压力走势;内存水位条;压缩省下的内存与交换区读写;按应用汇总。
  • 网络:流量历史;连接探测格子(通了是绿格、不通是红格,最近 60 次);接口、Wi-Fi 信号、VPN / 代理;本地与公网 IPv4 / IPv6, 归属地国旗、ASN;IP 纯净度评分与 F 到 A+ 等级、风险标记(VPN、代理、Tor、机房、滥用记录);DNS 一键刷新,一键切换 Cloudflare、Google、腾讯、阿里云或手动填写;各进程流量。
  • 磁盘:启动磁盘容量分段条(已用、可清除、可用);读写速度与 60 秒走势;SSD 健康;读写最多的应用。
  • GPU、温度与风扇:使用历史、各组温度、风扇转速与快捷模式。
  • 电池:电量与剩余 / 充满时间、适配器功率与电池温度;最近 24 小时电量曲线;功耗;健康度与循环次数;已连接蓝牙设备的电量(AirPods、妙控键盘 / 鼠标 / 触控板)。没有电池的 Mac 只显示蓝牙设备。

CPU 详情弹窗 磁盘详情弹窗 内存详情弹窗(深色)

IP 纯净度检测——网络详情里直接看出口 IP 干不干净:CleanIP.io 纯净度评分与 F 到 A+ 等级色带,风险评分与命中的 风险标记(VPN、代理、Tor、机房、滥用记录等);IP 地址区块用徽章标出原生 / 广播、住宅 / 机房。IPv4 与 IPv6 分别检测, 结果在本机缓存 7 天,换了 IP 或点刷新才重查。

IP 地址与 IP 纯净度(浅色) IP 地址与 IP 纯净度(深色)

主窗口——左侧边栏切换仪表盘、本机信息、历史、CPU、GPU、内存、磁盘、网络、温度与风扇、电池,以及进程、启动项、防休眠、清理、卸载应用几个工具,宽高都可调整。 仪表盘有健康评分、芯片与系统徽章、三列指标卡片、核心负载、电池、高占用进程和快捷开关;清理见清理。

用 Apple 智能解释进程——看不懂的进程右键「用 Apple 智能解释」,由系统自带的本机大模型说明它是什么、占用是否正常、能否退出。 不接入第三方 AI,不联网;需要 macOS 26 并开启 Apple 智能,回答可能不准确,结束进程前请自行确认。

浅色为白底蓝色、深色为黑底蓝色,窗口与弹窗统一外观,可一键切换或跟随系统。

温度与风扇 防休眠

风扇与睡眠

风扇模式 行为
自动 交还 macOS 温控
降温 固定在最低到最高转速之间的 60%
强冷 最高转速
自定义 用滑块在风扇转速范围内自由设定

自定义模式下,CPU 一旦达到安全温度(默认 95°C)就交还系统控制。退出 XStats 或应用崩溃时, 风扇恢复自动。合盖运行在使用电池且电量低于你设定的下限时自动关闭。

这两项需要系统权限,由一个通过 SMAppService 注册的小型辅助工具完成,首次使用时在 “系统设置 › 通用 › 登录项”中批准一次。辅助工具只提供固定的几个操作:设置风扇目标转速、恢复自动、 切换 pmset disablesleep、刷新 DNS 缓存、释放内存,不执行任意命令。它会校验调用方的代码签名, 应用断开连接时恢复风扇与睡眠设置;异常退出后,下次开机也会恢复。

清理

  • 扫描范围:应用缓存、日志与崩溃报告、浏览器缓存(Chrome、Edge、Brave、Arc、Firefox、Safari)、 Xcode 编译缓存、模拟器缓存、npm 缓存、Xcode 归档、未完成的下载、安装包和废纸篓。
  • 先预览:按类别显示大小,每条规则可展开查看具体项目,清理前再确认一次。缓存与日志直接删除, 空间立即释放;下载目录的内容移到废纸篓。也可以一键改为全部先移到废纸篓。
  • 安全:只处理白名单目录。钥匙串、密码管理器、VPN、Cookie、历史记录一律不碰。正在运行的应用的缓存 会跳过,浏览器需要先退出,删除前每一项都会再校验一次。所有操作记录在 ~/Library/Logs/XStats/cleanup.log。
  • 系统维护:刷新 DNS 缓存、释放内存。已安装辅助工具时直接执行,否则请求一次管理员授权。

清理

卸载应用与启动项

  • 卸载应用:列出“应用程序”里的第三方应用及其体积,选中或把应用拖进来,找出它留在资源库里的应用数据、缓存、 偏好设置、沙盒容器、窗口状态、日志、网页数据和登录启动项,可逐项取消勾选;确认后连同应用一起移到废纸篓(可放回), 并从程序坞移除图标。只匹配应用包名与同名目录,系统自带和 Apple 的应用不列出,正在运行的应用会提示先退出。
  • 启动项:列出当前用户、所有用户的 LaunchAgents 和系统 LaunchDaemons,显示所属应用、可执行文件、是否登录时运行 / 保持运行,以及运行中、已加载、已停用状态。当前用户的启动项可以直接停用或重新启用(写入 launchd 停用记录并卸载, 不删除文件),其余只读,并提供系统登录项设置的入口。

启动项

你的数据

指标来自本机的内核接口(host_processor_info、host_statistics64、sysctl)、IOKit 与 SMC。 偏好设置保存在应用自己的 user defaults 中,不含个人信息。没有任何统计与上报。

会联网的功能都可以关闭。前两项在“设置 → 网络”中,检查更新在“设置 · 关于”中:

  • 公网 IP:打开网络详情时向 Cloudflare 1.1.1.1(回退 ipify)请求一次公网地址,10 分钟内不重复请求。归属地、ASN、网络类型与纯净度评分由这台 Mac 直接向 cleanip.io 查询,只发送公网地址、不经过我们的服务器;地址没变、不满 7 天就沿用上次结果,点刷新才重查。
  • 连接探测:打开网络详情时每秒(后台每 10 秒)向你选择的目标(Cloudflare、Google、阿里云、腾讯或路由器)发送一次 ICMP ping,只在菜单栏显示网络项或打开网络详情时运行。
  • 检查更新:启动时与之后每天向 getopenstats.com 读取一次版本清单,只下载清单本身;发现新版本时提示,由你决定是否安装。

WebDAV 只向你配置的服务器传输偏好设置,不上传监控数据、历史记录或 WebDAV 凭据。

WebDAV 设置同步

  1. 在 WebDAV 服务器上创建目录,打开 设置 → 设置同步。
  2. 填写该目录的 HTTPS 地址、用户名和密码(或应用专用密码),保存配置。支持 Basic 认证,需要有效的 HTTPS 证书;不跟随重定向,请填写最终目录地址。
  3. 点击“上传本机设置”,确认后写入 xstats-settings.json,替换远端同名文件,不合并其他 Mac 的改动。
  4. 在另一台 Mac 配置相同目录,点击“下载并应用”;备份校验通过后,再确认覆盖本机对应偏好。

第一版仅手动同步,不在启动、唤醒或设置变更时自动上传。每台 Mac 需要单独配置连接信息,密码仅存本机钥匙串。 XStats 不对远端 JSON 文件额外加密,请使用私有 WebDAV 目录。首次使用需要先上传,才能在其他设备下载。 超过 1 MB、格式无效或版本不受支持的备份会被拒绝,本机设置保持不变。 GitHub、Google、Apple 登录及旧账号后端已移除,设置同步只需要你自己的 WebDAV 服务器。

用 Apple 智能解释进程完全在本机完成,进程信息不会离开这台 Mac。

构建与运行

需要 macOS 14+、Xcode 26 或更高版本(仅有 CommandLineTools 时缺少 SwiftUI 宏插件)以及 XcodeGen。

brew install xcodegen
make run                  # 生成工程,编译 Release、安装并启动
make install              # 编译 Release,安装到 /Applications 并启动
make test                 # 单元测试:指标采集、SMC 编解码、清理安全边界
make open                 # 生成工程并用 Xcode 打开

菜单栏应用没什么可截图的窗口,可以用本机实时数据渲染各个界面:

/Applications/XStats.app/Contents/MacOS/XStats --snapshot ./snapshots

需要测量面板打开时的资源占用,用 --show-panel 启动,面板会自动展开并固定。

修改 CHANGELOG.md 后运行 python3 Scripts/sync_changelog.py,更新上方的“最近更新”和活跃度图。

分发

只走 Developer ID,不上 App Store——沙盒不允许访问 SMC、读取其他应用的缓存、安装特权辅助工具, 而这正是大部分功能。

你拥有的 别人打开时看到的
什么都没有 ad-hoc 签名,只能在你自己的 Mac 上运行。别人会看到 “XStats 已损坏”。
Developer ID 证书 启用 Hardened Runtime。别人会看到 “Apple 无法检查其是否包含恶意软件”。
证书 + 公证 Gatekeeper 放行,只有常规的 “从互联网下载” 提示。

make build 与 make install 会自动使用钥匙串里的第一个 Developer ID Application 证书签名,没有证书时退回 ad-hoc。 辅助工具在运行时读取自己的签名团队,只接受同一团队签名的调用方。

ad-hoc 构建不安装或使用特权辅助工具,风扇控制与合盖运行不可用;DNS、内存维护等已有回退的操作仍可请求一次性管理员授权。启动时会注销已注册的旧 ad-hoc 服务。团队签名构建会注销并升级协议版本低于 5 的辅助工具,验证成功后才允许特权调用。

make release                          # 签名、公证、装订,生成 DMG 与 Homebrew cask
NOTARY_PROFILE=XStats make release # 使用其他 notarytool 钥匙串凭据
SKIP_NOTARIZE=1 make release          # 生成未公证的 DMG,仅供本机测试

Scripts/release.sh 会拒绝生成 Gatekeeper 仍会拒绝的 DMG。

架构

  • Packages/XStatsKit/Sources/SMC——SMC 读写、风扇控制、温度传感器发现。
  • Packages/XStatsKit/Sources/Metrics——CPU、内存、网络、GPU、磁盘、电池、进程、传感器的采集器, 以及只采集屏幕上需要的指标的 MetricsHub。
  • Packages/XStatsKit/Sources/Cleaner——清理规则、安全守卫、扫描与执行。
  • Packages/XStatsKit/Sources/HelperShared——XPC 协议与系统维护命令。
  • Packages/XStatsKit/Sources/WebDAVSync——WebDAV 手动同步与钥匙串密码存储。
  • Packages/XStatsKit/Sources/XStatsUI——设计 token、主窗口各页与设置页、详情弹窗、菜单栏绘制。
  • Helper/——特权辅助工具及其 launchd 配置;App/——应用入口。

更多内容见 ARCHITECTURE.md。应用的每一项改动都按日期记录在 CHANGELOG.md。

致谢

XStats 基于以下开源项目,谢谢。

项目 作者 许可证 XStats 借鉴了什么
OpenStats GiantAccel, LLC MIT XStats 的上游项目,感谢原项目的开源贡献
Stats Serhiy Mytrovtsiy MIT SMC 访问、Apple Silicon 风扇解锁流程、菜单栏迷你样式的字号参数
Mole tw93 GPL-3.0 哪些目录值得清理、哪些绝对不能碰;清理模块为独立的 Swift 实现,不含 Mole 代码
QuotaBar GiantAccel, LLC MIT 本 README 的版式、更新日志同步与活跃度图脚本

详见 ThirdPartyNotices.md。

XStats 是独立的第三方应用,与 Apple 及文中提到的其他公司没有隶属、认可或赞助关系。相关名称与标志归各自所有者所有。

许可证

XStats 新增代码与修改采用 AGPL-3.0-or-later,见 LICENSE 与 许可范围及贡献要求。

OpenStats 上游代码保留原 MIT 许可与版权声明,其他第三方许可见 ThirdPartyNotices.md。