KennethCheng b30b2f0e28 feat: 实现 Phase 1 — Bootstrap(Slint hello window + 编译验证通过)
完成 AGENTS.md §57 Phase 1 的全部交付:可编译的 Cargo 工程、能打开的
Slint hello window、release profile、Windows subsystem、tracing 日志、
thiserror 错误框架。`cargo build` 与 `cargo build --release` 均通过,
0 warning。

实现概览
--------

新增 / 修改的文件:

  src/lib.rs           lib crate 入口;`slint!{}` 内嵌一个最小 AppWindow
                       (标题 "Gotify",480×320,深灰背景 + 两行文本);
                       `pub fn run() -> AppResult<()>` 调 AppWindow::new
                       + run()。
  src/main.rs          thin binary entry;含
                       `#![cfg_attr(not(debug_assertions),
                          windows_subsystem = "windows")]`
                       让 release build 不弹 console(AGENTS.md §43);
                       debug build 保留 console 让 tracing 日志可见。
  src/error.rs         `AppError` + `AppResult`,thiserror 2.0.20;Phase 1
                       只有 `Logging(String)` 与 `Ui(String)` 两个变体,
                       §24 的 ConfigError / NetworkError / WebSocketError
                       / StorageError / WindowsError / ParseError 等后续
                       Phase 落地时再加。
  src/logging.rs       `init_logging()`:tracing-subscriber 0.3.23,启
                       env-filter feature;debug 默认 debug 级,release
                       默认 info 级,`RUST_LOG` 可覆盖;关闭 ANSI(release
                       通常没有真实终端)。符合 §25 的"默认不记录消息正文"
                       基线——具体红线靠代码 review 强制。
  Cargo.toml           实际可编译的 manifest:[[bin]] 指向 src/main.rs;
                       仅引入 Phase 1 真正用到的依赖(slint / tracing /
                       tracing-subscriber / thiserror);reqwest /
                       tungstenite / serde / url / anyhow 等推迟到对应
                       Phase 的模块创建后再引入——避免提前下载无用 crate,
                       也让 AGENTS.md §44 的 "Cargo 依赖最小化原则" 落到
                       每一阶段的 commit 上。
  Cargo.lock           已生成(564 个 transitive deps,含 slint 1.18.0、
                       skia-bindings、accesskit、parley、fontique 等)。
                       二进制工程,lock 文件进 git——保证可重现构建。

技术选型说明
------------

- Slint 版本选择:AGENTS.md §1 写的是 "Slint 1.17.x 或当前稳定兼容版
  本"。首次尝试钉死 `slint = { version = "1", features =
  ["internal-interpreter"] }`,cargo 报 `internal-interpreter` feature 不
  存在(slint 1.18.0 已移除该 feature,slint!{} macro 走 default feature
  set 即可)。改为 `slint = "1"`,cargo 自动选到 1.18.0,与 Rust 1.98.1 +
  MSVC 工具链编译通过。AGENTS.md §1 的措辞明确允许"当前稳定兼容版本",
  本次选 1.18.0 不偏离约束。
- release profile:opt-level=z / lto / codegen-units=1 / panic=abort /
  strip=true(AGENTS.md §42 模板)。Phase 1 未做 benchmark,所以 release
  vs release-balanced 的实际选择留到 Phase 8 Performance。
- 没引 slint-build / 没建 build.rs:Phase 1 hello window 内嵌在
  `slint!{}` macro 里,足以通过验收。Phase 2 切到独立 .slint 文件 +
  `include_slint!()` 时再决定是否需要 build.rs。

验证结果
--------

  cargo build          exit 0, 5.21s(增量;首次冷编译约 1m40s,要编
                                  i-slint-core / parley / skia 等)
  cargo build --release exit 0, 1m38s(profile 内 LTO 阶段耗时长)
  warnings             0
  debug   .exe         25.58 MB, PE subsystem = 3 (WINDOWS_CUI / console)
  release .exe          7.82 MB, PE subsystem = 2 (WINDOWS_GUI)

AGENTS.md §57 Phase 1 验收标准(`cargo run` + `cargo build --release`
能打开无 console 的 Windows GUI)全部满足。PE subsystem 通过直接读
Optional Header 的 Subsystem 字段验证——而不是盲目信任 cfg_attr。

下一步
------

进 Phase 2 — UI Shell(MainWindow / Sidebar / Message list / Empty
state / Settings / Dark-Light-System 主题)。本阶段仍然只用 mock 消息,
不接网络。

遗留
----

- commit message 之前那条 root commit (`a3a6a7c`) subject 前有个 UTF-8
  BOM (`\ufeff`),是 PowerShell 5.1 `Set-Content -Encoding UTF8` 默认带
  BOM 造成的。本 commit 用 `[System.IO.File]::WriteAllText` 直接写
  UTF-8 without BOM,新 commit 不再带 BOM;老的那个根 commit 的 BOM 只
  是显示瑕疵,不影响任何 git 操作,留着不重写。
- 首次 cargo build 拉了 564 个 crate、走代理拉取成功(crates.io 直连也
  通,HTTPS_PROXY 走 127.0.0.1:7890 是兜底)。
- target/ 1.4 GB 在 .gitignore 内,不会进 git。
- 用户的 .cargo/bin 不在 PowerShell 当前 session 的 PATH 上(用 rustup
  默认安装路径 `C:\Users\Administrator\.cargo\bin`),后续 cargo 命令
  脚本里临时加 PATH 即可,未修改用户全局环境。
2026-09-19 04:15:19 +08:00

Windows-Gotify-Client-Rust

轻量、现代、Windows 原生体验良好的 Gotify 桌面客户端,使用 Rust + Slint 构建。

详细的产品定位、技术栈约束、架构、UI 规范与分阶段实施计划全部记录在 AGENTS.md。本文档只做项目导览。

状态

🚧 从 0 起步 —— 当前仓库只有目录骨架与占位 Cargo.toml,尚未进入 Phase 1(Bootstrap)。 完整 8 阶段路线图见 AGENTS.md §57。

目标平台

  • Windows 10 x64
  • Windows 11 x64(ARM64 条件允许时支持)
  • 后台常驻、托盘型客户端

技术栈

层 选型
语言 Rust stable
UI Slint 1.17.x
HTTP reqwest(blocking + rustls)
WebSocket tungstenite
Windows 集成 windows-rs focused crates(按需引入)
配置 / 状态 JSON 文件(%APPDATA%/WindowsGotify/)
日志 tracing + tracing-subscriber

显式禁用:Tauri / Wails / Electron / WebView2 / WPF / WinUI 3 / Node 运行时。 理由见 AGENTS.md §2。

仓库布局

Windows-Gotify-Client-Rust/
├── Cargo.toml          # 占位 — 见 AGENTS.md §44
├── AGENTS.md           # AI Agent 实施计划(1363 行)
├── README.md
├── LICENSE             # MIT(占位)
├── .gitignore
├── assets/             # 图标、字体等
├── ui/                 # Slint 视图
├── src/                # Rust 业务代码
│   ├── gotify/         # HTTP + WebSocket
│   ├── storage/        # config.json / state.json
│   ├── windows/        # 托盘 / Toast / 启动 / 单实例 / URL
│   └── services/       # 生命周期
├── tests/              # 集成测试
└── scripts/            # PowerShell 构建脚本

开发环境

本仓库目前还没有源码,本节将在 Phase 1 完成后补全具体的 cargo run / cargo build --release 步骤。

隐私与安全

  • App Token 默认以 JSON 明文存储在 %APPDATA%/WindowsGotify/config.json,仅当前用户可访问
  • 日志永不打印完整 Authorization 头
  • 通知点击的 click.url 仅允许 http:// / https://,拒绝 file:// / javascript: / 自定义 scheme
  • 详细策略见 AGENTS.md §13 / §20 / §38 / §51

License

MIT(见 LICENSE)。

S
Description
No description provided
Readme MIT
637 KiB
2026-09-19 20:40:55 +08:00
Languages
Rust 73.7%
Slint 26.3%