docs: add AGENTS.md architecture overview

This commit is contained in:
2026-07-04 14:23:57 +08:00
parent 71ca67c0ee
commit 5ce3eba455
+67
View File
@@ -0,0 +1,67 @@
# AGENTS.md
## 项目概述
SnapGo 是一个常驻菜单栏的轻量截图工具:全局快捷键唤起选区截图,确认后自动上传到 S3 兼容对象存储(或通过 SSH/SCP 保存到远端),并把可分享链接复制到剪贴板。目前主要打磨 macOS 体验。
技术栈:**Wails v2**Go 后端 + WebView 前端)+ **Vue 3 / TypeScript / Vite** 前端。Go 后端遵循分层架构(domain → application → infrastructure),macOS 上截图选区使用原生 AppKit overlay,其它平台回退到 Wails 透明窗口 overlay。
### 分层架构(`internal/`
- `domain/`:核心业务类型与接口,**不依赖任何第三方 SDK 或 OS API**(仅标准库)。如 `OSSProvider` 接口、`AppConfig`/`S3Config`/`SSHConfig``Screenshot`/`UploadResult`
- `application/`:用例编排(capture → upload/save → clipboard → notify)。**只依赖 domain 接口**,具体适配器从 `main.go`/`app.go` 注入,便于单测。如 `CaptureAndUploadService``CaptureActionsService``CaptureAndSSHService``ApplyAnnotations`
- `infrastructure/`:对接外部世界的适配器实现 —— `oss/`(S3)、`ssh/`(内置 Go client + Kerberos 委托系统 ssh)、`clipboard/``config/`(JSON 文件存储)、`screencapture/``display/``cursor/``hotkey/``tray/`(菜单栏)、`logging/`
### 顶层文件(`main` 包,根目录)
- `main.go`Wails 启动入口,embed `frontend/dist`,装配 tray 与 `App`
- `app.go``App` 结构体,通过 Wails `Bind` 暴露给前端的方法(RPC),编排截图/上传/保存流程与 overlay 窗口生命周期。
- `*_darwin.go` / `*_other.go`:平台分离的 overlay、dock 图标、激活策略、帧刷新等实现。`native_overlay_darwin.go` 使用 cgo + AppKit。
### 关键约定
- 前端通过 Wails 自动生成的 `frontend/wailsjs/go/main/App.js` 调用后端 `App` 的导出方法;后端通过 `wruntime.EventsEmit` 向前端推事件(如 `upload:success``upload:failure``hotkey:ready``capture:overlay`)。
- 新增 OSS provider 只需在 `infrastructure/oss/` 加适配器并实现 `domain.OSSProvider`,无需改 application 层。
- S3 与 SSH 走独立 pipeline`runUploadPipeline` vs `runSaveRemotePipeline`),避免 provider 分支泄漏进彼此。
## 构建与命令
依赖前置:Go 1.23+、Node/npm、`wails` CLI`go install github.com/wailsapp/wails/v2/cmd/wails@latest`)。
- `go mod tidy`:同步 Go 依赖。
- `wails dev`:开发模式(热重载前端 + 后端),日志可直接在终端看到。
- `wails build -platform darwin/arm64 -clean`:构建 `.app`(产物在 `build/bin/`)。
- `./scripts/create-dev-cert.sh`:首次创建本地自签开发证书(保证 macOS TCC 权限不被反复重置)。
- `./scripts/dev-build.sh`:本地迭代用 —— 构建 + 稳定证书重签名 + 同步到 `/Applications` + 打开。优先用它而非裸 `wails build`
- `./scripts/release.sh`:一键 build → sign → DMG → notarizenotarize 需 `NOTARIZE=1` 与凭证,默认跳过)。`ARCH=universal` 可出 fat binary。
- 前端单独命令(`frontend/`):`npm run dev` / `npm run build``vue-tsc --noEmit && vite build`/ `npm run preview`
## 代码风格
- **Go**:标准 `gofmt`(tab 缩进)。包级 doc 注释说明“设计动机/rationale”是本仓库的强约定,注释解释“为什么”而非“是什么”。导出标识符必须有注释。错误用 `fmt.Errorf("...: %w", err)` 包装。日志统一用 `log/slog`(结构化 kv,如 `slog.Info("...", "host", h)`)。
- **平台分离**:用 `_darwin.go` / `_other.go` 文件名后缀或 `//go:build` 标签隔离平台代码,保持跨平台编译通过。
- **TypeScript/Vue**Vue 3 `<script setup>` + Composition API2 空格缩进。视图在 `frontend/src/views/`,组件在 `components/`
- 注释中可使用中文(部分 infra 包如 logging 已用中文 rationale),与现有文件保持一致即可。
- 不要手改 `frontend/wailsjs/` 下文件,它们由 Wails 生成。
## 测试
- 框架:Go 标准 `testing` 包(无第三方断言库)。运行:`go test ./...`
- 现有测试集中在 `internal/application/`(如 `capture_actions_test.go``annotation_test.go`)。
- 约定:application 层依赖 domain 接口,测试用手写 fake 实现(如 `fakeClipboard``fakeNotifier`)注入,不触碰真实 OS/网络。文件 IO 测试使用 `t.TempDir()`
- infrastructure 适配器(S3/SSH/screencapture 等)依赖真实环境,通常不写单测;SSH 连通性可借助 `cmd/sshdiag/` 诊断工具与设置页的 “Test connection” 按钮验证。
## 安全
- **凭证落盘**:配置(含 S3 access key、SSH 密码)以 JSON 存于 `os.UserConfigDir()/SnapGo/config.json`,文件权限 `0600`、目录 `0700`。尚未接入 OS keychain(后续计划),改动配置存储时务必保持严格权限并避免把密钥写入日志。
- **日志**:写入 `~/Library/Logs/SnapGo/snapgo.log`(大小滚动,5MiB×2 备份)。记录连接信息时只记 host/user/port 等非敏感字段,**切勿记录密码/密钥**(参考 `app.go` 中的 `slog` 用法)。
- **SSH**`StrictHostKey=false` 时使用 `InsecureIgnoreHostKey()`(牺牲安全换首启可用性,仅限个人 LAN);Kerberos 模式委托系统 `/usr/bin/ssh` 复用 `kinit` 凭证缓存。`PathPrefix` 相对远端 `$HOME`,会剥离前导 `/``~` 防止逃逸。
- **上传兜底**:上传失败时把 PNG 落地到 `~/Pictures/SnapGo` 并复制本地路径,保证不丢截图。
- macOS 需 Screen Recording / AccessibilityTCC)权限;稳定的代码签名身份与安装路径是权限保持的关键(见 `dev-build.sh` 注释)。
## 配置
- Wails 项目配置:`wails.json`(产物名、frontend install/build/dev 命令、应用元信息)。
- 运行时配置:首启写入默认值(`domain.DefaultAppConfig()`:快捷键 `cmd+shift+a`、S3 `pathPrefix=snapgo/`、SSH port 22 / timeout 10s)。原子写入(temp + rename)。
- 环境变量:`SNAPGO_LOG_LEVEL=debug|info|warn|error`(默认 debug)。Release 相关:`ARCH``NOTARIZE``SIGN_MODE``DEVELOPER_ID_APPLICATION``KEYCHAIN_PROFILE``APPLE_ID`/`APPLE_TEAM_ID`/`APPLE_APP_SPECIFIC_PASSWORD`
- S3 兼容性:`UsePathStyle` 默认 true(适配 MinIO/R2);`PublicURLBase` 可选用于 CDN/自定义域名,否则回退 `{Endpoint}/{Bucket}/{Key}`