guilhermeprokisch/MyWords
GitHub: guilhermeprokisch/MyWords
一款 macOS 本地加密按键记录器,将个人输入文本安全存储于 SQLCipher 数据库中,可用于构建私有 AI 训练语料、文本恢复和自我量化分析。
Stars: 0 | Forks: 0
# MyWords
一款适用于 macOS 的个人、本地设备端按键记录器。它记录**你**输入的文本以及你输入时所使用的应用程序,将所有内容存储在**完全加密**的本地数据库中,并允许你导出数据以训练自己的 AI 模型。
## 功能
- 通过只读的 `CGEventTap` **捕获输入的文本** —— 它只观察按键,但绝不修改或延迟它们。
- **使用前台应用程序标记每个片段**(名称 + bundle id)。
- **跳过密码。**当安全文本框获得焦点时,macOS 会开启“安全输入”,应用程序会丢弃在该窗口期间输入的所有内容。键盘快捷键(⌘/⌃ 组合键)也会被忽略 —— 它们不属于“输入的文本”。对于*没有*触发安全输入的输入框(浏览器、Electron 应用),在存储之前,用户可编辑的**遮蔽列表**会清除匹配的内容 —— 请参阅[遮蔽机密信息](#redacting-secrets)。
- **忽略自身。**在 MyWords 处于最前端(其自身的密码/遮蔽对话框)时输入的按键永远不会被记录。
- 使用 **SQLCipher** (AES-256) **加密整个数据库**。*整个*文件在静止时都会被加密 —— 包括文本*和*元数据(时间戳、应用名称)—— 因此磁盘上绝对不会留下任何可读内容。它使用存储在你 **Keychain** 中的密码解锁,绝不会存储在文件中。
- **按空闲时间分段** —— 在一个应用中连续输入的一串内容会保持在同一行,并在静默约 3 秒(或切换应用)后结束。
- **作为菜单栏应用运行**(无 Dock 图标),开机自启,可随时暂停/恢复。
## 用途
MyWords 是**捕获层** —— 一个私人、可搜索的记录,记下*你*写下的一切。在此基础上构建什么由你决定。人们需要它的一些原因:
- **个人 LLM 上下文 / “第二大脑”。** 将你自己的文字提供给模型,让它了解你的项目、风格和词汇 —— 而无需将你的生活数据上传到云服务。
- **绝不丢失你输入的内容。**崩溃的表单、未发送的聊天消息、重写的提交信息 —— 都可以从跨越每个应用的加密本地历史记录中恢复。
- **写作和语言自我提升。** 随着时间的推移跟踪词汇、语气和反复出现的错误。[`examples/`](examples/) 中的教练会将其转化为日常反馈(作者使用它来练习英语、葡萄牙语和德语)。
- **量化自我。** 每天的单词量、你实际用于写作的应用程序、你什么时候效率最高 —— 这一切都是由你在本地计算的专属分析。
- **私人训练数据。** 建立*你的写作方式*的语料库,以微调或个性化你自己的模型 —— 保存在你的机器上并加密存储。
- **可搜索的思维日志。** 用你自己的话重建你在某一天做了什么或解决了什么问题。
共同主线是:**你的数据,在你的设备上,被加密,受你控制** —— 绝不是云账户。明确的界限是:它用于在*你自己的* Mac 上记录*你自己的*输入,绝不用于监视他人。
## 安装(从源码构建)
**没有下载 —— 这正是重点。**MyWords 是一个按键记录器,因此信任模型是*准确查看你正在运行的内容*:阅读源码,或者让值得信赖的工具或 LLM 为你检查,然后你自己编译它。没有预编译或经过公证的二进制文件需要盲目信任(或被杀毒软件标记)—— 你构建的正是你(或你的审查者)审计过的确切代码。这是一个很小的代码库,构建时间很短。
### 1. 前置条件
- **macOS 13 或更高版本。**
- **Xcode 命令行工具**(`xcode-select --install`)—— 提供 Swift 6。
- **通过 [Homebrew](https://brew.sh) 安装 SQLCipher:**
brew install sqlcipher
这仅是**构建时**的依赖项。`build.sh` 链接到 `/opt/homebrew/opt/sqlcipher`(Apple Silicon 架构;在 Intel 芯片上,请将 `Package.swift` 中的 `sqlcipherPrefix` 修改为你的 `/usr/local` 前缀),并**将库的副本打包到应用内部**,因此完成的 `MyWords.app` 是自包含的,即使你以后卸载了 sqlcipher 也能继续工作。
### 2. 构建和安装
```
git clone MyWords && cd MyWords
./build.sh install # compiles, assembles a signed self-contained app,
# and copies it to ~/Applications
open ~/Applications/MyWords.app
```
单独运行 `./build.sh` 只会生成 `build/MyWords.app`(以及 `mywords-export` CLI),但不会进行安装。
### 3. 授予辅助功能权限并启动
首次启动时,macOS 会提示授予**辅助功能**权限(系统设置 ▸ 隐私与安全性 ▸ 辅助功能)。请授予该权限 —— 否则在你执行此操作之前不会捕获任何内容。随后,菜单栏中的键盘图标会显示状态(实心表示正在记录)。你的加密数据库将创建在:
```
~/Library/Application Support/MyWords/keystrokes.db
```
### 签名说明
`build.sh` 会自动检测代码签名身份:
- **拥有开发者 ID / Apple Development 证书时**,它会进行稳定签名,因此辅助功能授权(和 Keychain 访问权限)在**重建后依然有效**。可以通过 `MYWORDS_SIGN_ID="…" ./build.sh` 覆盖选定的身份。
- **没有任何证书时**,它会回退到**临时签名**。应用仍然可以运行,但每次构建时其签名都会更改,因此 macOS 会在每次重新构建后要求你重新授予辅助功能权限。如果偶尔构建一次这没问题;如果这让你觉得困扰,请获取一个免费的 Apple Development 证书(通过 Xcode ▸ 设置 ▸ 账户)。
## 查看你的数据
由于整个数据库都经过 SQLCipher 加密,你可以通过以下两种方式之一进行查看 —— **除非你明确导出,否则两者都不会将明文写入磁盘**。
**1. 直接在支持 SQLCipher 的 GUI 中打开它**(推荐)。使用 **DB Browser for SQLCipher**:打开 `keystrokes.db`,选择“SQLCipher 4 defaults”,然后粘贴密码。在 **Keychain Access** 中找到密码,服务名为 `com.mywords.logger`,账户名为 `db-passphrase`。它仅将页面解密到内存中 —— 不会创建任何明文文件。(普通的 `sqlite3` CLI 无法打开它;请使用 `sqlcipher` CLI 或 GUI。)
**2. 使用 `mywords-sql` 助手从终端查询它。**它会从 Keychain 读取密码,设置 SQLCipher 密钥,并让你进入查询界面(结果仅打印到终端 —— 没有明文文件):
```
./mywords-sql "SELECT app_name, count(*) FROM keystrokes GROUP BY app_name ORDER BY 2 DESC"
./mywords-sql "SELECT datetime(ts,'unixepoch','localtime'), text FROM keystrokes WHERE app_name='Claude'"
./mywords-sql # interactive SQLCipher shell
```
在底层它使用的是 `sqlcipher` CLI(普通的 `sqlite3` CLI 无法打开加密数据库)。列名:`id, ts, app_name, app_bundle, text`。
**3. 导出明文副本用于训练。**`mywords-export` 会使用 Keychain 密码解锁数据库并将其写出:
```
build/mywords-export --out corpus.jsonl # JSON Lines (default)
build/mywords-export --format text --readable # to stdout, tokens shown
build/mywords-export --format csv --out corpus.csv
```
`--readable` 将控制键渲染为 ``/``/``/``。导出内容为**明文** —— 请将其视为敏感信息并在完成后删除(`corpus.*` 和 `*.jsonl` 已在 git 中被忽略)。
## 遮蔽机密信息
macOS 的安全输入检测能捕捉到许多密码输入框,但并非全部 —— 浏览器、Electron 应用和终端提示通常不会触发它。对于这些情况,请保留一个**遮蔽列表**,以便在机密信息被写入数据库*之前*将其清除。
这些模式存储在**加密数据库内部**(而不是明文文件中),因此它们会受到与其他所有内容同等的保护。从菜单中管理它们:
- **添加遮蔽模式…** —— 不区分大小写;普通单词按字面意思匹配,或者使用正则表达式。匹配的内容在存储前会变为 `[REDACTED]`。
- **清除遮蔽模式** —— 删除所有模式。
- **将遮蔽应用于现有日志** —— 清除在添加该模式*之前*捕获的数据中的匹配项。
模式示例:`myS3cretPassw0rd`、`\b\d{6}\b`(6位 OTP)、`sk-[A-Za-z0-9]{20,}`(API 密钥)。你也可以通过 `mywords-sql`(表 `redaction_patterns`)使用 SQL 管理它们。
## 选择要记录的应用程序
菜单中的**应用**子菜单控制每个应用程序的捕获行为:
- **记录所有应用(被阻止的除外)** —— 默认设置。捕获所有内容;点击一个应用以取消其复选标记,它就会被阻止。适用于构建广泛的个人语料库,同时排除少数敏感应用。
- **仅记录允许的应用** —— 开启此项以切换到严格的允许列表;这样将仅记录你勾选的应用。
- **在记录新应用之前询问** —— 开启后,当你第一次切换到一个从未见过的应用时,它会被阻止,并且你会收到是记录还是忽略的通知。关闭时,新应用将被自动记录。
该列表显示你切换过的每一个应用(MyWords 会监视应用激活,而不仅仅是输入),以及你已经设定过规则的任何应用。规则保存在加密数据库中(bundle id + 允许/拒绝)并实时生效。MyWords 绝不会记录自身。
## 项目
- **许可证:**[GNU AGPL v3](LICENSE) —— © 2026 Guilherme Prokisch。强 Copyleft:任何分发*或网络托管*的衍生作品都必须公开其源代码。这对于隐私工具来说是合理的 —— 修改过的键盘记录器无法在不公开源码的情况下作为服务提供。
- **安全与威胁模型:**[SECURITY.md](SECURITY.md) —— 它可以防范什么,同样重要的是,它不能防范什么。
- **贡献:**[CONTRIBUTING.md](CONTRIBUTING.md)。
- **示例:**可选的粘合代码(语言辅导、自动化、学习应用集成)位于 [`examples/`](examples/) 中 —— 这些都不是核心部分,并且只有当*你*手动设置时,它才会将数据发送到设备外部。
### 法律与道德
MyWords 是一个按键记录器。**仅在你拥有的机器上运行它,以记录你自己的输入。**在大多数司法管辖区,在他人不知情的情况下捕获他人的按键是非法的 —— 你对合法使用负责。本软件**按“原样”提供,不提供任何保证**(参见 [LICENSE](LICENSE))。
## 项目结构
| 路径 | 用途 |
|------|---------|
| `Sources/CSQLCipher/` | 绑定 Homebrew SQLCipher 的模块映射 |
| `Sources/MyWordsCore/` | 数据层:`Database` (SQLCipher)、`KeyManager`、`Migration`、`Crypto`(旧版) |
| `Sources/MyWords/` | 菜单栏应用:`Recorder`(事件监听)、`AppDelegate`、UI |
| `Sources/mywords-export/` | 用于解密和导出语料库的 CLI |
| `Tests/MyWordsCoreTests/` | 存储、密码错误及静态数据加密测试 |
## 注意事项与限制
- **丢失密码 = 丢失数据。**它存在于登录 Keychain(`com.mywords.logger` / `db-passphrase`)中。不要删除它。除非你导出数据或复制密码,否则数据无法移植到另一台 Mac。
- **迁移。**首次运行 SQLCipher 版本时,任何旧的 `keystrokes.sqlite`(以前按字段加密的格式)都会被导入并重命名为 `keystrokes.sqlite.pre-sqlcipher-bak`。一旦你确认数据存在,请删除该备份 —— 它仍然包含明文元数据。
- **签名。**`build.sh` 会自动选择稳定的开发者 ID / Apple Development 身份,以便辅助功能授权在重新构建后依然有效。使用 `MYWORDS_SIGN_ID` 进行覆盖。
- **控制字符**以原始形式被捕获(回车/制表符/退格键);如果你的模型不需要它们,请在预处理中进行规范化处理。
标签:AI训练数据, SQLCipher, 个人知识库, 本地数据采集, 键盘记录