Skip to content

monorepo finale: relocate crates, monitor release pipeline, docs overhaul - #1234

Draft
lollipopkit wants to merge 173 commits into
mainfrom
frb
Draft

monorepo finale: relocate crates, monitor release pipeline, docs overhaul#1234
lollipopkit wants to merge 173 commits into
mainfrom
frb

Conversation

@lollipopkit

@lollipopkit lollipopkit commented Jul 18, 2026

Copy link
Copy Markdown
Owner

Summary

This PR finishes the monorepo migration with three main blocks, plus follow-up hardening:

1. migrate: merge rust/ and rust_builder/ into crates/sbm_ffi

  • The cargokit plugin shell and the sbm_ffi crate now share one directory (cargokit's official example layout), keeping the top level clean
  • Workspace members, FRB rust_root, pubspec paths, and per-platform glue updated in sync
  • Verified: cargo test --workspace green, 12/12 FFI parity tests pass, flutter build macos --debug builds through cargokit for real

2. feat: monitor release pipeline

  • Manual trigger only; version comes from the monitor crate (monitor-v* tags), decoupled from the app's v1.0.x
  • Native binaries: Linux musl (amd64/arm64, native arm runners) / macOS (both archs) / Windows → GitHub Release + SHA256SUMS
  • Docker: the Linux musl binary is reused in an Alpine image pushed to ghcr.io — zero in-image compilation, no QEMU
  • Drive-by fixes: Dockerfile frontend path mismatch with server.rs, build/runtime glibc mismatch, reqwest switched to rustls to drop the OpenSSL dependency (prerequisite for static musl builds)
  • install.sh rewritten for the new release layout; fresh installs generate a random JWT_SECRET
  • Verified: local image build + run smoke test (health 200, frontend OK, uptime collection OK), 41 monitor tests green

3. docs: full audit of the docs site (en/zh/ja/de/fr/es)

  • Removed content confirmed fabricated after checking against the code: system tray, Touch Bar, multi-window, NUL keep-alive, SFTP paging/TTL cache, nonexistent keyboard settings, etc.
  • Fixed factual errors: home tab list, Windows integration language, encrypted-storage description, class/setting names, nonexistent test file examples
  • Added monorepo layout, Rust testing, and FRB codegen docs; README monitor links point into the monorepo
  • Added dependabot config (cargo × 3 directories + monitor frontend npm + GitHub Actions)
  • Removed doc/adr (intentional) and cleaned up all references
  • Verified: docs site builds, 139 pages

4. Follow-ups on this branch

  • Monitor dependencies upgraded across major versions (backend: ntex 3, sqlx 0.9, jsonwebtoken 10, reqwest 0.13, etc.; frontend: react 19, vite 8, vitest 4, tailwind 4, eslint 10) — also resolves the vitest critical CVE (GHSA-5xrq-8626-4rwp) flagged by Socket
  • All 6 inline review findings fixed (full-volume drop on Windows, missing Windows net counters, hard-coded velocity key, unbounded retention tables, dead serve CLI flags + TLS wiring, since-boot CPU average)
  • Security hardening: no baked-in admin/admin123, no default JWT secret — both generated randomly on first start

Notes

  • After the first monitor-release workflow run, set the server-box-monitor ghcr image to public in package settings if desired
  • The cargokit path changes for iOS/Android/Linux/Windows mirror macOS but are unverified on-device; watch the first five-platform CI build

Summary

Changes

  • sbm_parser: Linux/BSD/Windows status parsing (core parsers): New Rust crate implementing pure-function parsers for CPU, memory, swap, disk (lsblk + df fallback), network, temperature, connections, disk IO, batteries, sensors, GPU (NVIDIA XML, AMD JSON), and SMART health — replacing the Dart parsing layer as the single source of truth. Parsers emit raw counters; diff/windowing helpers are provided as pure functions with no mutable state.
  • sbm_parser: Script generation and output parsing (shared wire format): New Rust script generation module that is a literal port of the Dart script builders: Unix sh and Windows PowerShell scripts with status/process/shutdown/reboot/suspend functions, custom command injection, disabled-command filtering, install/exec command generation (including Windows -EncodedCommand base64 wrapping), and output segment splitting.
  • sbm_ffi: flutter_rust_bridge FFI layer (Rust side): New FFI binding crate exposing sbm_parser functions to Dart via flutter_rust_bridge 2.12.0: parse_status_json (async), parse_windows_net_speed_json (sync), command_specs (sync), separator (sync), build_script, install_command, exec_command, shell_func_flag, parse_script_output (async). System string parsing, error handling, and JSON serialization at the boundary.
  • Dart FFI integration: app-side script generation and status parsing migration: Dart app migrated from Dart-based parsing and script generation to FFI calls into sbm_ffi. shell_func.dart now delegates to ffi.buildScript/installCommand/execCommand/shellFuncFlag. server_status_update_req.dart calls ffi.parseStatusJson and assembles JSON into existing model classes. single.dart calls ffi.parseScriptOutput for output splitting. Dart script_builders.dart and windows_parser.dart deleted.
  • Dart test migration: deleted tests and FFI parity tests: Dart unit tests for parsing (amd_smi, btrfs, conn, cpu, memory, uptime, script_builder, disabled_cmd_types) deleted — behavior now locked by Rust dart_compat.rs and script_compat.rs. New frb_parser_test.dart verifies FFI binding loading and JSON contract. rust_lib_helper.dart loads the native dylib in tests.
  • Monitor: Authentication and JWT security: New authentication system for the monitor web service: JWT token generation/verification (HS256, 24h expiry), bcrypt password hashing, bearer token middleware, initial admin bootstrap with random password, JWT secret auto-generation with validation against known defaults and minimum length.
  • Monitor: Web server, API routes, and CORS: ntex web server with TLS (rustls/ring), CORS allowlist middleware, static file serving (SPA fallback), API routes (/login, /status, /metrics, /metrics/history, /velocity, /velocity/history, /health), and legacy Go-compatible /status endpoint.
  • Monitor: Configuration loading, Go-compat normalization, and env overrides: Config struct supports both Rust-native and Go-compatible fields, with automatic normalization from Go format. TOML/JSON file loading, environment variable overrides, CLI arg overrides (--addr/--cert/--key), JWT secret resolution, push rate parsing.
  • Monitor: Database schema, migrations, and data cleanup: Three SQL migrations creating system_metrics, alerts, users, velocity_metrics, cpu_core_metrics, network_totals, config management tables, component_metrics, rule_executions, performance_metrics, and retention_policies. Data cleanup service with time-based retention, DB size cap enforcement, and VACUUM scheduling.
  • Monitor: Monitoring loop, metrics collection, and status adaptation: Monitoring loop generates a core-only status script via sbm_parser, writes/executes it locally each cycle, parses output, and adapts ServerStatus into SystemMetrics. CPU delta logic differs per platform (Linux cumulative ticks vs BSD/Windows one-shot percentages). Disk aggregation with APFS volume pooling. Metrics stored in SQLite.
  • Monitor: Velocity/time-series processing and rules engine: Velocity tracking via NetworkTimeSeries and CpuTimeSeries (two-sample delta), VelocityProcessor/VelocityManager with per-server state and DB persistence. Rules engine checks CPU/memory/swap/disk/network/temperature thresholds with Go-compatible threshold parsing, triggers push notifications with rate limiting.
  • Monitor: Push notification channels: Push notification implementations for webhook (configurable method/headers/body template), ServerChan (SCT API), Bark (iOS push), and iOS (push.lolli.tech). Template variable replacement ({{message}}, {{name}}). URL encoding for Bark. Rate limiting via global PushRateLimiter.
  • Monitor: Docker, install script, and CI/CD release pipeline: Two Dockerfiles (local build with Alpine/musl, CI with prebuilt musl binaries), docker-compose.yaml, systemd install script, and GitHub Actions monitor-release.yml workflow for multi-platform native binaries + Docker image publishing to ghcr.io.
  • Monitor: Frontend (Svelte) and webui package: New Svelte frontend for the monitor: login page, dashboard, detail panel, charts, theme/locale toggles, API client with JWT bearer auth and 401 auto-logout. New packages/webui shared Svelte component library (Badge, Button, Card, IconButton, Input, Select, Spinner) with theme CSS.
  • Monitor: SSH e2e test and integration tests: Opt-in SSH e2e test for sbm_parser (upload script → exec → parse → compare with direct commands) for both Unix and Windows remotes. Monitor integration tests for config loading, database init, JWT auth, and password hashing.
  • Rust workspace and dependency vulnerabilities: New Rust workspace (Cargo.toml) with three members: sbm_parser, sbm_ffi, monitor. Verified dependency vulnerabilities: rsa@0.9.10 (RUSTSEC-2023-0071, Marvin Attack timing sidechannel) and rustls-pemfile@2.2.0 (RUSTSEC-2025-0134, unmaintained).
  • App platform integration: iOS/Android/macOS/Linux/Windows build config: Platform-specific build configuration for the FFI plugin: iOS/macOS Podspecs, Android build.gradle, Linux/Windows CMakeLists, cargokit build tool integration. iOS Podfile added, xcconfig modified. Generated plugin glue files for all platforms.
  • Documentation updates: CLAUDE.md, README, and docs updated to describe the new monorepo layout, Rust workspace, FFI architecture, shared parser design, monitor service, and testing instructions. Multi-language docs (en/zh/de/es/fr/ja) updated.

sbm_parser 早已解析这六类数据,但 monitoring.rs 从不读取,面板也没有对应
UI。新增低频"扩展采集周期"(默认 60s,可配 extended_interval_secs)跑一次
完整脚本获取 battery/sensors/SMART/AMD 等慢命令,核心 5s 周期之间用
carry-forward 语义补齐(顺带修好了 AMD GPU 因 core:false 从未被采集到的
潜在 bug)。前端加对应卡片/详情页,15 个 locale 同步补齐翻译 key。
diskio 是磁盘的从属信息,合到 disk 详情页底部的表格里更合理;
首页少一张卡片,DetailKind 也去掉了独立的 diskio 枚举值。
aggregate_disks/flatten_disks 用 path.starts_with("/dev") 过滤磁盘,这是
Unix 惯例;Windows 上磁盘 path 是盘符("C:"),永远不匹配,导致 disk 恒为
0、disk_details 恒为空。改为按 SystemType 分支:Windows 只要求 size>0,
Unix/BSD 保留原有 /dev 前缀过滤。
之前 ServerStatus 每个字段在 Linux/BSD/Windows 上是否支持,全靠"没写
代码所以恰好是空"隐性表达,调用方无法区分"平台不支持"和"没这个硬件"。
capabilities() 从 commands 表机械派生 Supported/NotImplemented/
HardwareDependent 三态,随命令表变化自动同步,只有 swap(无专属命令)
需要显式特判并写明原因。
commands.rs 里 Windows 的 SENSORS/DISK_SMART 命令一直有定义、脚本也真的
采集了对应输出,但 lib.rs 的 Windows 分发从没接上解析函数,数据白采了。
新增 windows::parse_sensors/parse_disk_smart(两个命令均无 Dart 对应实现,
按 WMI 输出字段直接给出;disk_smart 没有 pass/fail 标志就不编健康状态)。
不动 adapt_cpu/diskio 的统一(影响已部署实例历史数据口径,需要单独
评估),先把"混乱"从隐性变成文档里写明的已知限制:类型定义处加详细
doc comment,monitor/CLAUDE.md 加一节汇总,并说明 capabilities() 能
力矩阵的存在及其边界(反映命令清单是否存在,不代表分发逻辑一定接好)。
按"monitor 本机 / App 远程"拆分:sbm_parser 继续服务 App 的 SSH+脚本
路径不变,sbm_native 只服务 monitor 的本机直接采集,内部按
#[cfg(target_os)] 分子模块支持多平台(不是每平台一个 crate)。这一步
只搭骨架(sample() 占位返回空 ServerStatus),Linux/sysinfo 后端留给
后续子步骤实现。
cpu/mem/swap/net/conn/diskio/temps/cpu_brand 直接读对应 /proc、/sys 文件,
一字不改地喂给现有 sbm_parser::linux::parse_*;disks/uptime 没有干净的单
文件 procfs 等价物,保留一次目标明确的 df -k / uptime 子进程调用(仍比
"生成整个脚本再按分隔符切"轻量得多)。batteries/sensors/nvidia/amd/
disk_smart 留空,继续走共享脚本路径。cargo check --target
x86_64-unknown-linux-gnu 通过;真机数值对比留到影子模式那一步。
吸收 macos_cpu.rs 的"起 sysinfo::System + 每周期 refresh 求 delta"模式,
从"仅 macOS cpu 一个字段"扩到 mem/swap/disks/diskio/net/uptime/host/sys。
NativeState 里的 sysinfo 部分改成调用方持有,不再用 static Mutex 全局态。

顺带发现:sysinfo 的 disk usage() 是真正的累计读写字节数,不像现有
Windows 脚本路径的 diskio 那样把速率误标成累计值——原生路径这块反而是
对的。也顺带确认了一个新坑:sysinfo 在 macOS 上 Disk::name() 返回卷标
("Macintosh HD"),不是 /dev 路径,留了 doc comment 提醒 monitor 集成时
is_real_disk 的 Bsd 分支不能再要求 /dev 前缀(和今天早些时候修的 Windows
磁盘过滤是同一类坑)。

cargo check 验证了 Linux/macOS/Windows 三个 target 都能过编译,macOS 上
真机跑了单测。macos_cpu.rs 暂不删——留到 monitor 集成那一步再替换,避免
中间状态出现 mac CPU 数据来源的空档期。
collect_metrics 每周期额外跑一次 sbm_native::sample(),不改变最终返回值
(仍是脚本解析结果),只把两路结果的关键字段 debug! 出来供人工核对。

本机(macOS)实测跑了几轮,数值符合预期:cpu_cores 第二轮起完全对齐,
host 完全一致;mem_total/disks/net_ifaces/sys 有差异但都能解释(script
的 mem.total 来自 vm_stat 页统计会随内存压力小幅漂移,native 用的是
真实物理内存大小,反而更稳;native.disks=3 是 sysinfo 已经去重过的真实
卷,script.disks=15 是 df 原始行数,aggregate_disks 自己的 APFS 池化逻辑
会把它收敛到同样的口径;net_ifaces 多出的是 script 路径过滤掉的虚拟
接口;sys 两边给的是不同粒度的系统描述,都对)。没有发现数值错误。
collect_metrics 改为 sbm_native::sample() 打底(cpu/mem/swap/disk/diskio/
net/uptime/host/sys),nvidia-smi 独立一次子进程调用(不再走生成脚本),
只有 amd/sensors/batteries/disk_smart(以及 Windows 的 conn,原生没做)
还走扩展周期脚本,靠已有的 carry_forward 语义在非扩展周期保留上次值。

is_real_disk 的 Bsd 分支不再要求 /dev 前缀(sysinfo 在 macOS 上
Disk::name() 给的是卷标不是设备路径,继续要求 /dev 会把所有原生磁盘过滤
成 0,和今天早些时候修的 Windows 磁盘 bug 是同一类问题,这次直接在切换
前改掉,不留同样的坑)。

macos_cpu.rs 删除,吸收进 sbm_native::sysinfo_backend。build_status_script/
script_path/execute_commands 去掉 core_only 参数,只保留一种(扩展)脚本
变体。monitor/CLAUDE.md 更新采集架构描述,补了 sbm_native 的说明。

验证:cargo test --workspace 全过;本机(macOS)、lkd-wsl(Linux)、
lkd(Windows)影子模式下三边数值分别核对过(cpu/mem/uptime/host 基本一致,
disks/net_ifaces 计数差异均可解释,非错误);本机切换后实跑校验了
/api/v1/metrics 输出(cpu/mem/disk/disk_details/network/diskio 都正确)。
已经可以在 config.toml 里配置,只是默认值太保守。降到 10s 后需要注意:
默认 interval_seconds=7 时扩展周期会变成每个核心周期都跑一次(10/7 取整
为 1),等于 amd-smi/sensors/smartctl 这些命令每次采集都执行——如果磁盘
唤醒延迟不可接受,需要显式调大这个值。
… config.toml

extended_interval_secs 改成 Option<u64>,未配置时(默认)通过
effective_extended_interval_secs() 取 interval_seconds 的值,而不是写死
的常量,这样跟着 interval_seconds 走,不用同时维护两个默认值。

config.json(旧 Go 兼容格式)加载后现在会一次性迁移写出 config.toml,
原文件改名保留为 config.json.migrated(不删除,留作回退),下次启动直接
走 config.toml 分支。新增集成测试锁定这个行为(独立测试文件,避免和其他
测试共享进程级 CWD 状态互相干扰)。
Cloudflare Pages 一直在构建失败(check-run: Cloudflare Pages: sbmd,
failure),本地用完全相同的命令复现确认:svelte-check 报 8 个
"Cannot find module" 错误,全部指向 packages/webui/src 下的文件
(clsx/tailwind-merge/tailwind-variants/svelte 本身)。

根因和 Docker 构建之前踩过的坑一样(3bd4263 修的):@serverbox/webui 是
file:../../packages/webui 依赖,npm ci 在 monitor/frontend 里只会把它
软链进来,不会装它自己的 devDependencies。Dockerfile 已经补了
`npm install --prefix /app/packages/webui`,但 Cloudflare Pages 控制台
里配置的构建命令没有同步更新。

这次改动只更新了 CLAUDE.md 里记录的正确命令并本地验证通过(clone 到
临时目录,完全按文档命令跑,0 错误、构建成功)——Cloudflare Pages 控制台
的实际构建命令是外部平台设置,不在仓库里,需要手动去后台改。
APFS 同一容器下的多个卷("/" 和 "/System/Volumes/Data")在 sysinfo 里
name() 返回同一个值("Macintosh HD"),disks/diskio 因此各出现一条重复
记录。disk_details 侥幸被 monitor 侧的 seen-path 去重挡住了,但 diskio
没有任何下游去重,直接把重复 dev 喂给前端 `{#each m.diskio as d (d.dev)}`
——Svelte keyed each 遇到重复 key 会直接报错崩掉整个磁盘详情页渲染,
点击磁盘卡片跳转到子页面时就表现为"点了没反应"。

在 sysinfo_backend.rs 里按卷名去重一遍,disks 和 diskio 共用同一份去重
后的列表,不再依赖 monitor 侧偶然的去重逻辑。新增回归测试(在这台真机上
断言 disks/diskio 的 key 全部唯一,机器本身就有这个 APFS 重复条件)。

顺带修正 Cloudflare Pages 构建命令文档:根据用户贴的真实构建日志确认
该项目 Root directory 配置的是 monitor/frontend(不是仓库根目录),
之前记的命令假设错了根目录,已按日志重新验证并改成相对路径版本。
diskio 现在每个核心周期都被原生采集刷新(不再局限于扩展周期),具备了
算真实速率的条件:新增 diskio_rate,用当前周期和上一周期的累计扇区数
+ 时间戳差值算出 bytes/sec,首个周期或设备刚出现时没有基线,留空。

磁盘详情页的 I/O 表格改为主显速率(读/写 每秒),累计总量降级为设备名
下面的小字辅助信息。加了单测锁定速率计算(固定用例:2 秒内 +2000/+1000
扇区,应得 512000/256000 B/s)。
新增 GET /api/v1/capabilities(平台相关、不随采样变化,前端只在切服务器
时拉一次,不跟 /metrics 一起轮询)。首页 gpu/battery/sensors/smart 四张
卡片的可见性判断从"数组非空"改成"能力矩阵不是 not_implemented 且数组非
空",能力矩阵没加载完时按放行处理避免闪烁。

验证过程中发现两个原生采集(sbm_native)的真实回归,顺手修了:
- cpu_brand 在 sysinfo 后端(mac/Windows)从没被填过,cutover 后 CPU 卡片
  型号信息在这两个平台上一直是空的——加 cpu.brand() 分组统计补上。
- temps(CPU 温度)同理从没接,Windows 温度显示因此跟着丢了;加 sysinfo
  Components 支持。本机(Apple Silicon)硬件本身不暴露温度传感器,验证后
  确认是平台限制不是 bug,capabilities 矩阵相应标成 hardware_dependent。

capabilities() 本身留在 sbm_parser、只反映脚本清单(App 用得到的口径不
能改);swap/diskio/temps 在 Bsd 上因为原生采集新增覆盖而被脚本清单标记
过时的问题,在 monitor 侧新增 effective_capabilities() 覆盖,不碰共享
crate。

本机(macOS)实测验证:cpu_brand 恢复正确显示,capabilities 端点返回值
符合预期。cargo test --workspace / npm run check+build 全过。
battery/sensors/SMART 详情页顶部加"更新于 X"提示(extended_updated_at,
只在真正跑了扩展脚本那一轮更新,carry_forward 的周期不刷新),复用现有
lastUpdated 翻译,不需要新增语言包。

首页卡片网格加 md:grid-cols-3,原来 2 列直接跳到 4 列,平板宽度(约
640-1023px)满配 8 张卡片时和手机一样挤,现在有个过渡档位。

顺带发现并修了 adapt_status 里"Bsd 强制温度为 None"的过时逻辑(注释写的
是"top 命令没有温度",但原生采集 cutover 后 sysinfo Components 在部分
Bsd/macOS 机器上是能拿到真实温度的)。本机实测验证:extended_updated_at
正确入库,且温度字段从 None 变成了真实读数 44°C,证明这个平台确实有可用
的温度传感器,之前是代码强制清空,不是硬件限制。

cargo test --workspace / npm run check+build+test 全过。
新迁移(004)给 system_metrics 加 diskio_read_bytes/diskio_write_bytes
(跨设备汇总累计字节数,和 network_rx/tx_bytes 同样存法)、battery_percent
(只存第一块电池,和首页卡片现状一致)。sensors/disk_smart 不做曲线——没
有统一的单一数值语义,更适合当前值展示或以后做告警,不是趋势图。

store_metrics 写入这两列;get_metrics_history 的 SQL 和 rx/tx 一样对
diskio 做 bucket 差分算速率,battery 直接 avg。磁盘详情页加读写速率
曲线,电池详情页加电量曲线。

新增集成测试锁定 store_metrics 的聚合口径(多设备求和、取首块电池)。
sqlx 离线查询缓存已用 cargo sqlx prepare 重新生成并入库。

cargo test --workspace(含 DATABASE_URL 未设置的离线模式)/ npm run
check+build+test 全过;本机实测确认 history 端点返回真实的
diskio_read_speed/write_speed 数值。
新增 GET/PUT /api/v1/settings(白名单读写 interval_seconds/extended_interval_secs/
idle_pause_enabled/idle_pause_threshold_secs/rules/data_retention/cors_allowed_origins,
绝不涉及 jwt_secret/database_url/push 密钥),保存前备份 config.toml。

空闲暂停:AppState 新增 live_settings + last_viewer_seen 心跳(由 /metrics、/status
轮询驱动),run_monitoring_loop 每轮实时读取,should_run_extended 只会把已到期的扩展
周期(smartctl/sensors/amd-smi)降级为跳过,核心指标采集和告警检查不受影响。

前端新增设置页(Sidebar 入口、无路由的视图切换),表单标注哪些字段保存即生效、
哪些需要重启;补全 15 个语言包对应文案。
新增 GET/PUT /api/v1/card-order,独立于 /settings 单独存 config.toml 的
[server].card_order,避免和规则/CORS 的读改写产生并发覆盖;首页卡片支持拖拽
重排,自动为新增卡片类型补位。

/api/v1/capabilities 响应增加 platform 字段(复用 system_type() 机械推导,和
capabilities 本身不会失配),前端新增 OsIcon 组件+capabilitiesStore 缓存,
sidebar 每个已登录服务器和顶部标题栏据此显示对应的系统图标。

CPU 卡片已显示温度,系统信息卡片移除重复的温度行。
@GT-610

GT-610 commented Jul 20, 2026

Copy link
Copy Markdown
Collaborator

@coderabbitai review

@coderabbitai

coderabbitai Bot commented Jul 20, 2026

Copy link
Copy Markdown
Contributor
✅ Action performed

Review finished.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

@GT-610

GT-610 commented Jul 20, 2026

Copy link
Copy Markdown
Collaborator

@winnowl review

规则编辑区加字段说明(type/matcher/threshold 取值与格式)+ 示例 placeholder,
去掉规则/CORS 列表项的外框,改用 divider 分隔,item 左侧加序号,删除按钮挪到
每项顶部,避免和某个字段绑死。

新增 PageHeader 组件,统一 Dashboard/Settings/DetailPanel 的顶栏(page 变体
全宽 sticky,section 变体用于 DetailPanel 的返回栏,叠在 page 头下方),取代
三处重复的 header 标记;Settings 保存按钮移入顶栏。

在线状态从小圆点改为给图标本身着色(sidebar 每行图标、Dashboard 标题图标),
未知/离线态可读性更好;sidebar 已命名的服务器不再重复显示 URL。
@lollipopkit

Copy link
Copy Markdown
Owner Author

@coderabbitai ignore

@coderabbitai

coderabbitai Bot commented Jul 20, 2026

Copy link
Copy Markdown
Contributor
✅ Action performed

Reviews paused.

@lollipopkit
lollipopkit marked this pull request as draft July 20, 2026 11:14
面板可选走官方 relay 转发、不暴露公网端口的设计要点(鉴权、推拉节奏、数据
最小化、成本控制、混合兜底)记到根目录 TODOS.md,全部转中文。删除
monitor/doc/TODO.md,未完成项没有迁移(Web UI/Firebase 推送等),仍在 git 历史里。
- sbm_parser 的 BSD 命令表新增 diskSmart(此前 BSD 平台完全没有 smartctl 命令),
  用 diskutil list 只筛选真实物理盘(排除 APFS 合成卷/磁盘映像),复用 Linux
  同一套 JSON 解析,is_physical_disk 加 /dev/diskN 白名单。真机(Apple Silicon
  NVMe SSD)实测验证过完整链路:capabilities 从 not_implemented 变成
  hardware_dependent,/api/v1/metrics 拿到真实健康状态/温度/开机时长/通电次数。
  额外修了 parse_status_opts 里 Bsd 分支从未读取 DISK_SMART 段的遗漏(是这条链路
  之前完全不通的真正原因,不只是缺命令)。
- Dart 侧 BSDStatusCmdType 补 diskSmart 保持和 Rust 命令表的清单一致性(locked by
  test/frb_parser_test.dart),server edit 页的磁盘健康开关同步补上 BSD 分支。
- Linux 的 smartctl 调用改成先 `[ -r /dev/$d ]` 探测可读性,不可读才补
  `sudo -n`(非交互、没配置就在 1 秒内失败,不阻塞、不弹密码提示)——不是无脑加
  sudo 前缀,避免在已经能跑通的机器上多此一举或因为没装 sudo 反而变差。
- 新增 smart_parse_macos_nvme dart_compat 测试,用真实(序列号已脱敏)Apple SSD
  smartctl JSON 锁定行为。
- extended_interval_secs 未配置时的默认值从"等于采集间隔"(等于每 7 秒跑一次
  smartctl/sensors/amd-smi)改成 interval_seconds x10、下限 120 秒,降低这类
  CLI 工具调用对 CPU/功耗的常态开销;SMART 读取本身对闪存寿命的影响可忽略
  (诊断性日志读取,不是写入),这次调整解决的是主机资源占用,不是磁盘寿命。
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants