6.4 KiB
6.4 KiB
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 启动入口,embedfrontend/dist,装配 tray 与App。app.go:App结构体,通过 WailsBind暴露给前端的方法(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(
runUploadPipelinevsrunSaveRemotePipeline),避免 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 → notarize(notarize 需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 API;2 空格缩进。视图在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 / Accessibility(TCC)权限;稳定的代码签名身份与安装路径是权限保持的关键(见
dev-build.sh注释)。
配置
- Wails 项目配置:
wails.json(产物名、frontend install/build/dev 命令、应用元信息)。 - 运行时配置:首启写入默认值(
domain.DefaultAppConfig():快捷键cmd+shift+a、S3pathPrefix=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}。