# typing-insight — DSH 输入记录与分析插件

本地记录你的键盘与输入文字，提供统计、内容分析与日报导出。**隐私优先：密码框零记录、敏感信息脱敏、数据仅存本机。**

## 隐私声明（重要）

- 本插件为**个人电脑自用**设计；请勿在公司电脑、共享设备或他人设备上使用。
- 密码输入框通过 UIA 的 IsPassword 强制排除，**不记录任何按键与文本**；无法确认安全的控件一律按密码框处理（fail-closed）。
- 手机号、身份证号、银行卡号、邮箱自动脱敏后才落盘；日志与导出永不包含明文。
- 所有数据仅保存在本机 `$DSH_HOME/data/typing-insight/`（catalog + 每日 SQLite 分片）；插件运行期无任何网络出口。
- **数据为明文存储**（SQLite 未加密；FR-022 加密功能尚未实现）：能物理访问本机的人可读取库文件；插件提供的是内容级脱敏与密码框排除，**不是磁盘加密**。请勿在共享设备上启用本插件。
- 卸载不会自动删除数据；如需彻底清除：卸载前在对话中执行 `/typing clear all`，或手动删除上述数据目录。

## 安装与启用

1. 安装：`dsh plugin add <本插件路径或 npm 包名>`。
2. 重启 DSH Desktop 生效。
3. 打开 设置 → 「输入记录与统计」，在白名单勾选要记录的应用（默认白名单为空 = 不记录任何应用）。

## 对话命令（工具）

| 命令 | 功能 |
| --- | --- |
| /typing status | 采集状态：钩子/UIA/密码门/今日计数/库大小 |
| /typing today [日期] | 当日统计：字数/按键/活跃时长/速度/应用分布/小时分布 |
| /typing report [周偏移] | 周报：7 日趋势 + Top 应用 + 关键词 + 摘要 |
| /typing analyze [日期|all] | 内容分析：关键词、主题聚类（≤5）、本地摘要 |
| /typing export 日期 [md|json|csv] | 导出日报（Markdown 默认），返回路径与 SHA-256 |
| /typing pause / resume | 暂停 / 恢复采集 |
| /typing clear [日期] | 清除指定日期（缺省全部）的记录，不可恢复，需确认 |
| /typing usage [日期] | 软件使用时长：按应用的前台 / 前台活跃 / 强交互分钟数与未知缺口 |
| /typing config | 查看/修改配置（记录范围、保留期等） |

## 采集原理与限制

- 键盘：全局低级钩子（uiohook-napi）；中文输入法的上屏文字由 UIA 辅助进程（typing-insight-uia.exe）捕获，拼音过程不计入。
- 只记录"上屏后"的文本增量；粘贴、程序化写入、组合中的候选文本不记录。
- 按键数与文本数始终分列统计，按键不折算为文字数。
- 全局快捷键（FR-014）：可绑定 Ctrl+Alt+Shift+P 或 Ctrl+Alt+Shift+L 一键暂停/恢复（默认未绑定，设置面板或 /typing config 配置 hotkey 字段）；热键暂停为"软暂停"——钩子保留以监听恢复热键，文本与前台采集关闭；对话命令暂停会停止钩子，需命令恢复。
- 状态可见性（FR-042）：设置页与 /typing status 显示运行状态、今日字数、数据库大小与最近一次采集时间。
- 实时态势（DD-042/AD-027 首增量）：设置面板「实时态势」卡展示最近 30 分钟输入/按键双轨（5 秒桶）、60 分钟采集状态轨与前台应用段、健康矩阵（Hook/UIA/密码门/DB/队列/重启/缺口），5 秒自动刷新；数据仅含计数与状态，无任何文本内容。
- 采集降级（FR-012）：对 UIA 不可用/失败的控件与全屏独占应用（游戏等）自动降级为"仅按键"统计，按键事件标记 capture_mode=keys-only（capture_mode=2），数据不丢弃；设置面板应用行显示「仅按键 N」计数，全屏独占检测 = 无边框窗口覆盖所在显示器。
- 保留策略：默认保留 90 天，可配置 7/30/90/365 天或永久（设置面板或 /typing config）；过期分片每日自动清理（服务启动时与每 6 小时一次）。
- 软件使用时长（FR-034）：前台窗口事件 + 会话最后输入时间（GetLastInputInfo）+ 锁屏/解锁通知 + 5 秒心跳共同判定；仅保存应用、起止时间、状态、聚合时长与交互计数，不采集鼠标坐标/点击目标/滚轮轨迹/窗口标题。三类口径并列：前台 / 前台活跃（前台且非 AFK，默认核心指标，是估算而非实际工时）/ 强交互（30 秒内有输入信号）；锁屏、休眠、故障与心跳缺口不计入活跃，缺失区间记为 unknown/gap 且不归属任何应用。AFK 阈值可配置 60/180/300 秒（默认 180）。
- 采集依赖 DSH Desktop 运行。

### 兼容矩阵（v1 验收范围）

| 应用类型 | 按键统计 | 文本采集 | 说明 |
| --- | --- | --- | --- |
| Chromium / UIA 应用（Chrome、Edge、ChatGPT、Codex、钉钉、DSH Desktop 等） | ✓ | ✓ | TextPattern/ValuePattern 通道，已实测 |
| 标准 Win32 输入框（Edit/RichEdit 类，记事本等） | ✓ | ✓ | WM_GETTEXT 通道 |
| IMM32 型输入法应用（无 UIA 支持时） | ✓ | 部分 | IME 提交串兜底通道（GCS_RESULTSTR 轮询） |
| **微信 4.1.x（MMUI 自研渲染）** | **✓** | **✗** | 聊天输入区为 Qt 外壳 + MMUIRenderSubWindowHW 封闭渲染，UIA/MSAA/Win32 子窗口/IME(IMM32) 四条路径均已实证不可达；面板显示原因码 unsupported_mmui_text，仅按键统计，不采集文本 |
| 密码框 | ✗ | ✗ | 四道隐私门 fail-closed，始终排除 |
| 其他自绘界面（部分游戏等） | ✓ | ✗ | 无 UIA 文本支持时降级为仅按键统计 |

- **v1 验收范围**：Chromium/UIA 应用、标准 Win32 输入框、IMM32 型兜底通道；**微信 4.1 MMUI 明确排除在文本采集范围外**（仅按键统计）。
- **微信 3.9.x**：聊天界面为 Chromium，文本采集可用，列为**可选兼容方案**（如自行降级可用完整功能）；注意 3.9 与 4.1 本地聊天记录存储不互通、版本维护与兼容风险自担，**不作为推荐安装路径**。
- 微信按键/文本在设置面板与统计报表中始终分列展示，不会把按键数折算成文字数。

## 故障恢复

- 插件导致 DSH 启动失败时：检查 DSH 日志中的 `unsupported JSON schema` / `additionalProperties` 错误；可临时从 profile 的 package.json 中移除本插件（保留依赖与数据），修复后加回。
- 采集异常时先看 /typing status 的 gate/hook/uia 状态；重启 DSH Desktop 可完整复位采集管线。

## 开发

- 冒烟测试：`node smoke-test-m2.mjs`（文本管线）、`node smoke-test-m3.mjs`（统计/分析/导出）、`node smoke-test-cold.mjs`（全组件冷启动）、`node smoke-test-uia.mjs`（UIA helper）。
- 测试注入依赖环境变量 `TYPING_INSIGHT_DEBUG=1`；所有测试使用唯一临时数据目录，不触碰正式数据。
