TapBuddy 🐾
March 21, 2026 · View on GitHub
一只陪你敲代码的桌面宠物。随着你敲键盘、移动鼠标,它会实时做出反应。
功能
- 跟手输入 — 敲左侧按键左爪抬起,敲右侧按键右爪抬起,松手自动回到待机
- 点击反应 — 鼠标点击时嘴巴张开
- 多套皮肤 — 内置橘猫、柴犬、毛驴,支持用户添加自定义皮肤
- 常驻状态栏 — 不占 Dock,右键菜单控制一切
截图
| 狗 | 猫 | 驴 |
|---|---|---|
安装
方式一:直接下载
前往 Releases 下载最新版 .dmg,拖入 Applications 即可。
方式二:自行编译
环境要求:
- macOS 13+
- Xcode 15+
git clone https://github.com/shaozhengmao/TapBuddy.git
cd TapBuddy
open TapBuddy.xcodeproj
Xcode 中选择 TapBuddy target,Command + R 运行。
⚠️ 首次运行需要授予辅助功能权限(系统设置 → 隐私与安全性 → 辅助功能),用于监听键盘输入。
打包 DMG
项目提供了一键打包脚本:
# 默认版本号 1.0.0
./build-dmg.sh
# 指定版本号
./build-dmg.sh 1.0.1
打包完成后,DMG 文件位于 release/ 目录。
使用
启动后宠物浮窗出现在屏幕右下角,可自由拖拽位置。
右键菜单:
| 菜单项 | 功能 |
|---|---|
| 切换皮肤 | 选择内置或自定义皮肤 |
| 刷新皮肤列表 | 添加自定义皮肤后刷新 |
| 打开皮肤文件夹 | 用 Finder 打开用户皮肤目录 |
| 退出 | 关闭应用 |
自定义皮肤
- 右键宠物 → 打开皮肤文件夹,Finder 自动打开皮肤目录
- 在目录中新建文件夹(文件夹名即皮肤 ID),放入以下图片:
my_skin/
├── idle.png # 必须,待机状态
├── left_paw.png # 左键按下
├── right_paw.png # 右键按下
└── skin.json # 可选,皮肤信息
图片规格: 448 × 320 px,PNG 格式,透明背景
skin.json 示例(可选):
{
"name": "我的皮肤",
"author": "你的名字",
"description": "自制可爱皮肤",
"version": "1.0"
}
- 右键宠物 → 刷新皮肤列表,即可看到新皮肤
项目结构
TapBuddy/
├── App/
│ ├── AppDelegate.swift # 应用入口
│ └── TapBuddyApp.swift
├── Models/
│ └── PetState.swift # 状态机(键盘/鼠标 → 动作/点击反应)
├── Services/
│ ├── InputMonitor.swift # 全局键盘鼠标监听
│ └── SkinManager.swift # 皮肤扫描/加载/切换
└── Views/
├── FloatingWindowController.swift # 浮窗 + 右键菜单
├── PetImageView.swift # PNG 皮肤渲染
├── DogView.swift # 代码绘制(柴犬原版)
└── ... # 其他代码绘制皮肤
技术栈
- SwiftUI + AppKit — 浮窗使用 NSPanel,内容用 SwiftUI 渲染
- CGEvent Tap — 全局输入监听,无需第三方库
- Combine — 状态机使用 ObservableObject 驱动 UI
FAQ
为什么需要辅助功能权限?
TapBuddy 需要监听全局键盘和鼠标事件来实现宠物响应输入的功能。这是 macOS 的安全机制要求,应用不会记录或上传任何按键内容。
如何授权辅助功能权限?
- 打开「系统设置」→「隐私与安全性」→「辅助功能」
- 点击左下角的锁图标解锁
- 勾选 TapBuddy
- 如果列表中没有 TapBuddy,点击「+」按钮手动添加应用
下载的 DMG 无法打开怎么办?
从网络下载的 DMG 文件会被 macOS 标记隔离属性。有两种解决方法:
方法 1:终端命令(推荐)
打开终端,执行以下命令:
xattr -d com.apple.quarantine ~/Downloads/TapBuddy-1.0.0.dmg
然后双击 DMG 即可正常打开。
方法 2:右键打开
- 右键点击 DMG 文件 → 选择「打开」
- 在弹出的对话框中点击「打开」
方法 3:系统设置
- 右键点击 DMG → 「打开」会提示风险
- 打开「系统设置」→「隐私与安全性」
- 向下滚动找到 DMG 被阻止的提示
- 点击「仍要打开」