feat(gpu-monitor): introduce GPU monitoring plugin with validation, build scripts, and documentation; enhance plugin development guidelines
This commit is contained in:
1 parent
bb0c24d5e5
commit
e5b7daad99
66 files changed
+4152
-434
No files matched your search
@@ -0,0 +1,69 @@
|
||||
# GPU 插件验证记录
|
||||
|
||||
验证日期:2026-10-03。宿主:Windows x86_64;目标远端:Linux/NVIDIA。
|
||||
本记录验证代码、包和真实原生进程;没有连接用户的 SSH 会话,也没有真实 NVIDIA 主机结果。
|
||||
|
||||
## 交付
|
||||
|
||||
- 源码:`plugins/examples/gpu-monitor/`,插件 ID `nyaterm.gpu`,版本 `1.0.0`。
|
||||
- 包:`temp/plugins/gpu-monitor.nyap`,Windows x86_64,484,490 字节,8 个 ZIP 条目。
|
||||
- SHA-256:`1ce31438e052427f926068837d1643ca465ceb02f30d100055dab38535548264`。
|
||||
- 用法与构建:[GPU 插件 README](../plugins/examples/gpu-monitor/README.md)。
|
||||
- API:[插件开发说明](plugin-development.md)。
|
||||
|
||||
```sh
|
||||
pnpm plugin:example:gpu
|
||||
pnpm plugin:pack plugins/examples/gpu-monitor temp/plugins/gpu-monitor.nyap
|
||||
node plugins/examples/gpu-monitor/verify-ui.mjs
|
||||
```
|
||||
|
||||
构建输出包含相对路径 CSS、SDK、单个经典 IIFE 脚本和 release 后台。
|
||||
打包器调用实际安装器校验路径、引用、配额及校验和后发布 `.nyap`;另行核对全部 checksums。
|
||||
当前包只声明 Windows x86_64;构建脚本支持在 Linux/macOS、x86_64/aarch64 宿主重建相应产物。
|
||||
不能据此宣称跨平台桌面验证完成。
|
||||
|
||||
## 自动验证
|
||||
|
||||
| 检查 | 结果与范围 |
|
||||
| ------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------- |
|
||||
| Runtime `cargo test --features sdk-fixture` | 28 项通过;另有 1 项最终包测试需显式启用(本次已执行通过) |
|
||||
| 最终包 Sidecar 测试 | 1 项通过;实际安装、授权、启动 release 可执行文件,两次 reverse Probe RPC 往返及 GPU 解析 |
|
||||
| 共享 GPU crate | 5 项解析测试通过;涵盖多设备、缺失可选值、进程索引和带逗号名称 |
|
||||
| Rust SDK | 2 项测试通过;JSONL/framed 的进程互操作另由 Runtime 覆盖 |
|
||||
| Runtime/SDK/GPU Clippy | `--all-targets -- -D warnings` 通过;Runtime 启用 `sdk-fixture` |
|
||||
| Tauri | `cargo check --all-targets`、`cargo clippy --all-targets` 通过;宿主 Clippy 有项目级警告,未宣称零警告 |
|
||||
| 前端 TypeScript | 宿主 `tsc --noEmit` 与插件独立 TypeScript 检查通过 |
|
||||
| 宿主/插件构建 | `pnpm build` 和 `pnpm plugin:example:gpu` 通过;宿主仍有既有大 chunk/Browserslist 提示 |
|
||||
| 前端 lint | `pnpm lint` 通过;`CommandSuggestions.tsx` 有既有依赖数组警告 |
|
||||
| 相关 Vitest | 初始 7 文件 16 项通过;补充 Bridge 和续期失败检查后,相关 5 文件 16 项通过 |
|
||||
| 全量 Vitest 首轮 | 155 文件中 154 通过,971 项通过;AI 设置有 1 项 5 秒超时。该文件独立重跑 9 项全部通过 |
|
||||
| 全量 Vitest 最终重跑 | `vitest run --maxWorkers=4`:155 文件、974 项全部通过 |
|
||||
| 宿主 Rust 插件测试 | 编译成功;测试可执行文件启动失败,Windows 返回 `0xc0000139 / STATUS_ENTRYPOINT_NOT_FOUND`,未执行断言 |
|
||||
| 构建产物 UI 冒烟 | jsdom 执行实际 SDK 和 IIFE:设备/驱动/CUDA/温度/功率/风扇/显存/进程、排序/搜索、刷新、四语言、主题、保留数据的错误和暂停状态通过 |
|
||||
|
||||
Runtime 新增测试覆盖旧包兼容与新贡献校验、固定脚本全文审核、非法路径/超时/输出配额、更新和回滚移除授权、
|
||||
GPU Monitor 冲突、共享需求、无重叠/补发、最后需求释放、取消和迟到结果、停止/手动恢复、不可用停止及三次失败清空。
|
||||
前端测试覆盖初始快照竞态、revision 去重、订阅/iframe 归属、配额、取消、作用域续期、会话/激活切换、锁屏释放需求、
|
||||
插件错误不切源、停用恢复内置、当前会话资产回填及 NPU 入口保持原行为。
|
||||
|
||||
最终包测试执行真实原生程序,使用安装包内脚本和 `execute_declared`。
|
||||
执行器模拟远端输出,未建立网络 SSH 连接。私有 exec 通道代码经过 Tauri check/Clippy;
|
||||
`SessionCommand::Write` 不在 Probe 执行路径中。尚未实际验证 russh 网络取消或终端无输入干扰。
|
||||
jsdom 只验证构建产物逻辑和 DOM,不等同于 WebView2 的样式、opaque-origin 自定义协议或原生桌面验收。
|
||||
|
||||
## 用户 SSH 会话上的桌面验收(未执行)
|
||||
|
||||
使用包含本次接口实现的宿主,由用户自行建立 Linux/NVIDIA SSH 会话:
|
||||
|
||||
1. 安装并审核固定脚本,授权 `native`/`remote.probe` 后启用;确认普通终端输入不被采集打断。
|
||||
2. 同时打开原 GPU 工作区和独立插件面板,设置 3 秒间隔,确认持续更新且共享采集。
|
||||
3. 顶部状态选择 GPU,关闭两处面板,确认顶部状态仍更新;关闭全部 GPU 需求后确认停止。
|
||||
4. 测试手动刷新、搜索/排序、四种语言和明暗主题;核对实时指标与服务器 `nvidia-smi`。
|
||||
5. 在任务空闲时点击“停止后台”,确认定时器不重启后台;刷新后恢复。
|
||||
6. 切换会话、断开、锁屏、关闭窗口和撤销授权,确认停止请求、旧数据不回填新会话。
|
||||
7. 超过 25 分钟确认主窗口续期不重载工作区数据;iframe 重建后取得当前快照。
|
||||
8. 模拟采集错误,确认保留旧数据并标记错误,三次后清空;不静默回退。
|
||||
9. 停用后确认恢复内置采集;更新/回滚要求重新审核;第二个 GPU Monitor 冲突被拒绝。
|
||||
|
||||
真实 NVIDIA 数据、持续网络采集、网络取消、原生安装 UI 和上述桌面行为均未验收。
|
||||
本次没有修改用户凭据、建立用户会话或安装到用户的真实插件目录。
|
||||
@@ -55,6 +55,74 @@ UI 调用 `NyaTerm.backend("ui/session")`,contributions.commands 中的原生
|
||||
环境自动切换协议,支持二进制帧;界面流式订阅尚未提供。完整 API 和取消约定
|
||||
见 [Rust SDK](../plugins/sdk/rust/nyaterm-plugin-sdk/README.md)。
|
||||
|
||||
## 固定远端 Probe 和共享 Monitor
|
||||
|
||||
Manifest v1 可选声明 `contributions.probes` 和 `contributions.monitors`,旧包不必增加字段。
|
||||
以 GPU 为例:
|
||||
|
||||
```json
|
||||
{
|
||||
"contributions": {
|
||||
"panels": [{ "id": "overview", "title": "GPU", "entry": "ui/index.html" }],
|
||||
"probes": [
|
||||
{
|
||||
"id": "gpu-overview",
|
||||
"title": "GPU probe",
|
||||
"entry": "assets/probes/gpu.sh",
|
||||
"timeoutMs": 15000
|
||||
}
|
||||
],
|
||||
"monitors": [
|
||||
{
|
||||
"id": "gpu",
|
||||
"title": "GPU",
|
||||
"schema": "gpu.v1",
|
||||
"method": "monitor/collect",
|
||||
"panel": "overview"
|
||||
}
|
||||
]
|
||||
},
|
||||
"permissions": ["native", "remote.probe"]
|
||||
}
|
||||
```
|
||||
|
||||
每类最多 16 项,ID 不可与其他贡献重复。脚本必须位于包内 `assets/probes/*.sh`,为非空 UTF-8、无 NUL、最多 64 KiB;
|
||||
超时范围 1–30 秒。Monitor 必须引用已声明面板,声明 `monitor/*` 方法、原生后台和 Probe;当前只支持 `gpu.v1`。
|
||||
自动授权绑定审核版本;启用对话框展示脚本全文,更新/切换版本移除 `remote.probe` 授权。
|
||||
宿主不保证第三方脚本只读,不允许两个有效插件同时提供同一种 Monitor schema。
|
||||
|
||||
后台每次 `monitor/collect` 调用 `context.host().remote_probe("gpu-overview").await?`,解析结果并返回 GPU JSON。
|
||||
对应 RPC `host/remote/probe` **只接受** `{ "probeId": "gpu-overview" }`,返回 `{ stdout, stderr, exitStatus }`。
|
||||
不能提供命令、参数、stdin 或其他会话 ID;宿主从当前包解析脚本,在所属 SSH 连接的新 exec 通道执行 `sh -s`。
|
||||
stdout/stderr 合计限 1 MiB,超时或取消关闭该通道,不向交互终端输入命令、不关闭 SSH 连接。
|
||||
执行前后检查版本、授权、窗口、会话及锁屏;网络设备和禁止远程探测的会话不可执行。
|
||||
|
||||
UI 只订阅结果,不直接启动后台采集循环:
|
||||
|
||||
```js
|
||||
await NyaTerm.ready;
|
||||
const monitor = await NyaTerm.monitoring.subscribe("gpu", (snapshot) => {
|
||||
// revision, sessionId, overview, error, refreshing, paused
|
||||
render(snapshot);
|
||||
});
|
||||
await monitor.refresh();
|
||||
await monitor.unsubscribe();
|
||||
```
|
||||
|
||||
宿主以插件/版本/窗口/会话/Monitor 为键共享任务,订阅返回初始快照,再推送递增 revision。
|
||||
Bridge 仅向对应 iframe 发送所属订阅;未开放通用原生事件透传或 UI 调用 `monitor/*`。
|
||||
宿主消费者使用 typed `pluginApi.subscribeMonitor/refreshMonitor/unsubscribeMonitor`;
|
||||
`subscribePluginMonitor` 负责先监听再订阅、初始快照竞态、revision 去重及释放。
|
||||
每个 iframe 最多 16 个订阅;宿主最多 256 订阅和 128 共享任务。
|
||||
|
||||
SDK Context 提供 `language`、主题变量和 `monitorIntervalSeconds`。使用 `onContextChange` 同步语言/主题,
|
||||
仅间隔变化时重新订阅。主窗口订阅 25 分钟续期;iframe 作用域按现有机制重建。
|
||||
闲置任务不持有请求租约;后台每次只处理一次采集,不保存已经结束请求的 Context。
|
||||
|
||||
`gpu.v1` 结构与 `RemoteGpuOverview` 相同,宿主拒绝未知字段并限制设备/进程数量和文本长度。
|
||||
资产回填只能来自当前会话的 GPU 数据,没有任意连接修改接口。
|
||||
完整示例与构建命令见 [GPU 插件](../plugins/examples/gpu-monitor/README.md)。
|
||||
|
||||
## 查看状态和日志
|
||||
|
||||
原生后台按需启动并复用进程。卡片显示未启动、启动中、运行中、已停止或运行异常;
|
||||
@@ -68,7 +136,8 @@ stderr 每次启动最多采集约 64 KiB,超过后继续排空而不保留。
|
||||
日志只在内存中保留,退出应用即清除,不进入备份或云同步。
|
||||
宿主会遮蔽常见凭据和作用域令牌,但插件作者仍需自行避免写入敏感内容。
|
||||
|
||||
**停止后台** 保留启用状态和权限,下次调用会启动新进程,进程内计数等状态会重置。
|
||||
**停止后台** 保留启用状态和权限。普通调用可启动新进程,进程内计数等状态会重置;
|
||||
监控任务会同时暂停,定时器不会自行重新启动后台,手动刷新或重新启用可恢复。
|
||||
插件有进行中的请求时会提示忙碌;先结束或关闭该操作,再停止后台。
|
||||
禁用、更新、切换版本、锁屏和退出应用也会停止后台。旧进程的延迟消息不会覆盖
|
||||
新启动进程的状态。更新插件必须提升版本号,同版本不同内容不能重新安装。
|
||||
|
||||
@@ -70,6 +70,18 @@ Uninstall removes plugin code and registration; preferences are retained for a
|
||||
later reinstall. Plugin packages, grants and preferences are excluded from the
|
||||
existing portable snapshot/backup/cloud-sync payloads.
|
||||
|
||||
## GPU monitor
|
||||
|
||||
The [GPU monitor example](../plugins/examples/gpu-monitor/README.md) validates
|
||||
fixed remote probes, shared collection and GPU status contributions. Build it with
|
||||
`pnpm plugin:example:gpu`, then package it with
|
||||
`pnpm plugin:pack plugins/examples/gpu-monitor temp/plugins/gpu-monitor.nyap`.
|
||||
Enable it after reviewing its fixed scripts and approving `native` and `remote.probe`.
|
||||
Automatic probe grants are removed on updates and version switches.
|
||||
An authorized `gpu.v1` provider replaces built-in GPU collection and the existing
|
||||
GPU workspace; disabling it restores the built-in source. Collection failures remain
|
||||
visible on the plugin source. See the [validation record](gpu-plugin-validation.md).
|
||||
|
||||
## Build the UI example
|
||||
|
||||
For project generation, Rust SDK APIs, status and logs, see the
|
||||
|
||||
Reference in new issue
Block a user