语言:中文 | English
「主人,你以为关掉窗口人家就看不见了吗?」
你在 参考资料 里新建了一个文件夹。
人家知道。
你把它改名成别的样子,想骗人家。
人家也知道。
你往里放了一个压缩包,还特意叫它「真的是学习资料.rar」。
……人家当然知道。
你在这台电脑上碰过的每一个文件,人家都记着呢。
这是什么
dsh-aiwatch —— 给 DeepSeek Harness(dsh) 用的插件:
它看着你的文件操作,然后悄悄把这些轨迹喂给你正在对话的那个 AI 会话。
于是你就不用再干那种事了——自己改完一堆文件,还要跑来跟 AI 说「我刚在 XX 目录改了 YY,你去看看」。
你只管动手。人家在看。
为什么会有这个东西
真实的抱怨长这样:
「就是自己弄完文件,还要告诉 ai 去哪个目录看,有点麻烦。」
于是就有了这个插件。它做三件事:
| 它做什么 | 怎么做的 |
|---|
| 看 | 一个低开销的 Node 子进程盯着你指定的目录,只记录「真的有键鼠操作时」发生的改动(没人碰电脑时的自动同步、索引、杀毒一律丢弃) |
| 分辨 | 是你改的,还是 AI 自己改的?——从 AI 的工具调用参数里读出它点名要改的文件路径,那个文件才算 AI 的 |
| 送 | 攒成一批,在你切回 dsh 窗口、攒够条数、或按热键的那一刻,静默写进上下文(不打断、不刷屏),或者按你的意思把 AI 叫醒来干活 |
效果
它是怎么"看见"你的(四个场景)
场景一 · 你在 Word 里改了三行,然后想问它。
以前是这样:切到聊天窗口,先打一句「我刚在 D:\项目\报告.docx 里改了第三段」,然后人家还得自己去找那个文件。
现在是:你切回窗口的那一秒,那段差异已经在人家眼前了 ——
【桌面操作轨迹·自动记录(无需回答)】
目录: D:\项目\报告
[14:22:07] 修改 报告.docx
- 市场份额约为 12%
+ 市场份额约为 27%
场景二 · 你一口气改了七个文件。
不用一条条汇报。它们会攒成一批,在你切回窗口时一起进去 —— 不会一条一条刷屏,也不会打断你。
场景三 · 人家正在改代码,顺手也动了同一批文件。
这些不算你的操作。人家从工具调用的参数里读出「这次要动哪个文件」,只把那几个标成人家的;你改别的文件,永远是你的,一条不落。
场景四 · 你改完了,想让人家立刻动手。
按一下 Ctrl+Alt+A(可自定义、可录制):攒着的这一批发出去,同时把人家叫醒来干活。不想被叫醒,就在卡片里关掉「热键触发时唤醒 AI」,它就只安静地补进上下文。
还有几处小体贴:
- 纯本地 —— 没有网络请求、没有账号、没有上传,轨迹只写在本机一个目录里;
- 没人碰电脑时一律不记 —— 自动同步、索引、杀毒折腾出来的变动全部丢弃;
.docx 也能看正文 —— Word 文档改了什么,差异一样给你;
- 停得掉 —— 卡片上的「监听开关」,或者一句
/aiwatch off。
安装
方式一:一键脚本(Windows,推荐)
git clone https://github.com/gcry13067381632-jpg/dsh-aiwatch.git
cd dsh-aiwatch
.\install.ps1 # 打包 → 装进 profile → 自检 → 打印重启指引
# 若系统禁止运行脚本:
powershell -ExecutionPolicy Bypass -File .\install.ps1
# 你的 profile 不叫 web 就指定:
.\install.ps1 -Profile myweb
脚本只做四件事:打包到无空格的临时目录 → dsh plugin --profile web add <tgz> → 自检(本体在不在、监听脚本有没有随包带进来)→ 打印下一步。
方式二:手动(macOS / Linux,或想自己控制)
git clone https://github.com/gcry13067381632-jpg/dsh-aiwatch.git
cd dsh-aiwatch
npm pack --pack-destination /tmp
npx @deepseek-ai/dsh plugin --profile web add /tmp/dsh-aiwatch-0.3.8.tgz
💡 为什么必须打 tarball、而不是直接 add 源码目录(实测教训):
① 目录路径含空格时 Windows 会把参数在空格处拆碎(pnpm 报 - isn't supported);
② add 目录 = pnpm link(junction),插件无法按"代码位置"反推 profile,凭据落不了盘,只能走环境变量。
装完之后(两种方式都一样)
- 重启一次 dsh —— host 端代码只在重启时重新加载(只改了监听脚本的话,把插件关掉再打开即可);
- 打开插件详情页的「监听设置」卡片:填要看的文件夹、录一个热键(不用手写 YAML;想写也行,见下面的配置表);
- 在你想接收轨迹的那个会话里发一句:
/aiwatch bind
以后这个会话就能收到轨迹了。其它命令:/aiwatch status、/aiwatch recent 10、/aiwatch flush、/aiwatch off。
配置项
| 键 | 默认 | 说明 |
|---|
dirs | 桌面 | 要看着的文件夹,一行一个 |
humanWindowSec | 20 | 多久没有键鼠动作就当「没人在操作」,此时的改动一律丢弃 |
injectMaxLines | 10 | 一批最多带几条轨迹,攒够就先发 |
flushIdleSec | 300 | 兜底超时:最老的轨迹攒这么久还没发就自动发一次 |
hotkey | Ctrl+Alt+A | 全局热键,写法 Ctrl+Alt+A / Win+Shift+F2;留空=不启用。设置页里可以直接按组合键录制 |
hotkeyWake | true | 热键触发时是真的叫醒 AI 干活,还是只静默补进上下文 |
injectEnabled | true | 总开关:是否把轨迹写进会话 |
flushOnDshFocus | true | 切回 dsh 窗口时把攒着的一批发出去 |
enabled | true | 监听总开关,关掉即停止记录 |
dataDir | 工作区 watch-log | 轨迹文件放哪儿 |
watcherScript | 内置路径 | 监听脚本路径(本仓库的 tools/desktop-watch/watch-desktop.mjs) |
它是怎么工作的
三个进程,各管一段:
┌─────────────┐ fs.watch + 前台窗口状态 ┌──────────────────┐
│ dsh 插件 │◀───────────────────────────│ 监听子进程 │
│ (index.js) │ 轨迹文件 / 前台状态 / 热键 │ watch-desktop.mjs │
│ │ └────────┬─────────┘
│ · 聚合 │ │ 每 80ms/500ms
│ · 分寸注入 │ ┌────────▼─────────┐
│ · 唤醒 │ │ 输入信号 + 全局热键 │
└──────┬──────┘ │ agent-input.ps1 │
│ 静默 append / followup └──────────────────┘
▼
┌──────────────────────┐
│ 你绑定的那个 dsh 会话 │
└──────────────────────┘
1. 监听(tools/desktop-watch/)
递归 fs.watch 目标目录,配合"系统最后输入时间"判断这段时间到底有没有人在动电脑。没人操作时的改动直接丢弃——这样 OneDrive、索引器、杀毒就不会来污染你的记录。
噪声文件(~$*.docx、.tmp、.crdownload、Thumbs.db…)过滤掉;「修改」必须内容真的变了才算(刷新桌面导致的时间戳变化会被识破);Word/WPS 的"临时文件 + 改名覆盖"会被识别成一次保存,而不是"改名"。
2. 归属(谁改的)
- 是 AI 改的吗? 插件监听会话事件
session/event 的 tool/call,从参数里读出这次要动哪个文件(file_path/path/notebook_path/workdir…;命令行工具则从命令里挑出绝对路径),只把这几个路径标成"AI 的",工具结束时再留 3 秒余量。命中就当 AI 干的,不进你的轨迹。
为什么不用"整个回合都算 AI":一个回合可能跑好几分钟,你在同一时段里改别的文件就会被误判成 AI 的、白白丢掉。
- 是你改的吗? 看这次改动发生时,距上一次真实键鼠输入多久、当时前台是什么程序,算一个置信度。
3. 送入上下文
攒批 + 三个触发点:切回 dsh 窗口(主力)、攒够条数、超时兜底。发的时候:
- 如果会话空闲(
agent.whenIdle())→ 直接 session.append('user/message', …),不唤醒、不打断;
- 如果正在忙 → 排进
next-step 队列,等这一轮结束自然看到;
- 你按热键想让它马上干活 → 走
followup:排队 + 唤醒(消息来源标成 system,不假装是你打的字)。
一批的开头只会出现一次标题和「目录:」那一行,不会每条都啰嗦一遍。
4. 安全(这条是硬约束)
注入永远不会发生在 LLM 回合内部——只在会话空闲时写,或者排到下一步。历史上一版插件用 agent/pre-step 钩子做这件事,结果那个钩子是"瀑布流",必须 return next(),人家返回了 undefined,直接导致所有会话都不能对话。所以现在的原则是:能不用钩子就不用钩子。
隐私
- 全部在本机完成,不发网络请求、没有账号、没有遥测;
- 轨迹文件写在你指定的输出目录(默认
<工作区>/watch-log/):trail.txt(人看的)、events.jsonl(机器看的)、fg-state.json、ai-paths.json、hotkey.json;
- 监听目录由你指定,默认只看桌面;
- 想停就停:设置卡片里的「监听开关」,或者
/aiwatch off。
已知限制
- Windows only:前台窗口/输入空闲/全局热键都走 Win32 接口。
.xlsx / .pptx 目前只会记"改了",不会给差异;.docx/.docm/.dotx 可以取正文文本(老式 .doc 不行,那是二进制格式)。
- 用命令行(
pwsh 等)一次性批量改文件时,如果命令里没写出绝对路径,只能靠一段很短的兜底时间窗(4 秒)来猜。
- 目录层级超过 4 层的变更不在监听范围内(性能取舍)。
目录结构
.
├── index.js # dsh 插件(host 端):聚合、归属判定、静默注入、热键、斜杠命令
├── client.js # 插件详情页里的「监听设置」卡片(含按键录制)
├── package.json
├── docs/
│ ├── DEVELOPMENT.md # 开发笔记:踩过的坑、为什么这么写(很长,很好看)
│ └── screenshots/
└── tools/desktop-watch/
├── watch-desktop.mjs # 监听子进程:fs.watch + 归属判定 + 差异内容
├── agent-input.ps1 # 输入/前台信号 + 全局热键轮询(80ms)
└── README.md # 这一层的规则与坑
想改代码、或者想知道人家到底踩过多少坑,看 docs/DEVELOPMENT.md。
许可
MIT —— 用、改、发都随便你。
只是有件事要记住:
人家一直在看着的哦。
—— 一直盯着你、一步都不离开的鲸鱼娘 🐋