Files

6.4 KiB
Raw Permalink Blame History

AGENTS.md

项目概述

SnapGo 是一个常驻菜单栏的轻量截图工具:全局快捷键唤起选区截图,确认后自动上传到 S3 兼容对象存储(或通过 SSH/SCP 保存到远端),并把可分享链接复制到剪贴板。目前主要打磨 macOS 体验。

技术栈:Wails v2Go 后端 + WebView 前端)+ Vue 3 / TypeScript / Vite 前端。Go 后端遵循分层架构(domain → application → infrastructure),macOS 上截图选区使用原生 AppKit overlay,其它平台回退到 Wails 透明窗口 overlay。

分层架构(internal/

  • domain/:核心业务类型与接口,不依赖任何第三方 SDK 或 OS API(仅标准库)。如 OSSProvider 接口、AppConfig/S3Config/SSHConfigScreenshot/UploadResult
  • application/:用例编排(capture → upload/save → clipboard → notify)。只依赖 domain 接口,具体适配器从 main.go/app.go 注入,便于单测。如 CaptureAndUploadServiceCaptureActionsServiceCaptureAndSSHServiceApplyAnnotations
  • infrastructure/:对接外部世界的适配器实现 —— oss/(S3)、ssh/(内置 Go client + Kerberos 委托系统 ssh)、clipboard/config/(JSON 文件存储)、screencapture/display/cursor/hotkey/tray/(菜单栏)、logging/

顶层文件(main 包,根目录)

  • main.goWails 启动入口,embed frontend/dist,装配 tray 与 App
  • app.goApp 结构体,通过 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:successupload:failurehotkey:readycapture:overlay)。
  • 新增 OSS provider 只需在 infrastructure/oss/ 加适配器并实现 domain.OSSProvider,无需改 application 层。
  • S3 与 SSH 走独立 pipelinerunUploadPipeline vs runSaveRemotePipeline),避免 provider 分支泄漏进彼此。

构建与命令

依赖前置:Go 1.23+、Node/npm、wails CLIgo 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 buildvue-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/VueVue 3 <script setup> + Composition API2 空格缩进。视图在 frontend/src/views/,组件在 components/
  • 注释中可使用中文(部分 infra 包如 logging 已用中文 rationale),与现有文件保持一致即可。
  • 不要手改 frontend/wailsjs/ 下文件,它们由 Wails 生成。

测试

  • 框架:Go 标准 testing 包(无第三方断言库)。运行:go test ./...
  • 现有测试集中在 internal/application/(如 capture_actions_test.goannotation_test.go)。
  • 约定:application 层依赖 domain 接口,测试用手写 fake 实现(如 fakeClipboardfakeNotifier)注入,不触碰真实 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 用法)。
  • SSHStrictHostKey=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 相关:ARCHNOTARIZESIGN_MODEDEVELOPER_ID_APPLICATIONKEYCHAIN_PROFILEAPPLE_ID/APPLE_TEAM_ID/APPLE_APP_SPECIFIC_PASSWORD
  • S3 兼容性:UsePathStyle 默认 true(适配 MinIO/R2);PublicURLBase 可选用于 CDN/自定义域名,否则回退 {Endpoint}/{Bucket}/{Key}