Metadata-Version: 2.4
Name: humanized-autotyper
Version: 1.0.0
Summary: 模拟真人打字节奏的自动输入器：对数正态延迟、突发快打、错字回删、长暂停与恢复仪式
Classifier: Programming Language :: Python :: 3
Classifier: Topic :: Utilities
Requires-Python: >=3.8
Description-Content-Type: text/markdown
Requires-Dist: pynput>=1.7

# Humanized Autotyper

模拟真人打字节奏的自动输入器：对数正态延迟、突发快打、疲劳漂移、内联错字与
自我纠正、回删爆发、回到前文原位重写、整段重打、长暂停与恢复仪式。

## 安装

```bash
py -m pip install -e .        # 可编辑安装（改代码立刻生效，开发用这个）
py -m pip install .           # 普通安装（拷进 site-packages，改源码不再生效）
```

安装后有三条命令：

| 命令 | 作用 |
|---|---|
| `autotyper` | 命令行输入器（默认 dry-run，加 `--live` 才真打字） |
| `autotyper-gui` | Tk 图形界面 |
| `autotyper-report` | 审计 CSV 事件日志（观测频率 vs 配置概率） |

不想让脚本进 PATH，也可以用模块方式（三者等价）：

```bash
py -m humanized_autotyper              # == autotyper
py -m humanized_autotyper.gui          # == autotyper-gui
py -m humanized_autotyper.report out.csv
```

- 运行时依赖只有 `pynput`（`pip install` 会自动装），它只在**真实输入**时才被
  import；dry-run、自检、日志审计都不需要它。
- **用户数据都在「当前工作目录」**：`source.txt`（GUI 内容页读取/保存）、
  `gui_settings.json`（滑块记忆）、`autotyper_log.csv`（默认日志路径）。
  `autotyper` 不带 `--file` 时先找 `./source.txt`，找不到才用内置演示代码。
- 图形界面需要 Python 自带 tkinter（Windows/macOS 官方安装包默认自带；
  部分 Linux 发行版要额外装 `python3-tk`）。

## 图形界面（推荐入门方式）

```bash
autotyper-gui          # 或 py -m humanized_autotyper.gui
```

四个标签页：

| 页 | 功能 |
|---|---|
| 📝 内容 | 直接编辑要输入的文字（保存到 source.txt），或从文件导入 |
| ⌨️ 节奏与错误 | 滑块调整：基础敲键间隔 / 节奏抖动 / 突发快打 / 错字率 / 连错窗口 / 疲劳 |
| ⏸️ 停顿与删改 | 滑块调整：回删爆发 / 短停顿 / 长暂停(可开关) / 跳回重写 / 整段重打 |
| ▶️ 运行 | 预设人设（标准/高效型程序员/手生普通人）、倒计时 |

使用流程：**①** 「内容」页写好文字 → **②** 「运行」页设好倒计时秒数与速度
→ **③** 点「开始真实输入」→ **④** 趁倒计时把光标点进目标窗口。滑块参数会自动
记忆（gui_settings.json）。命令行高级用法见下。

> GUI 只有真实输入（没有演练模式）。想先无副作用地空跑一遍验证文本模型，用
> CLI 的默认 dry-run：`autotyper --file 你的文件`（不传 `--live`）。

## 预设人设（GUI 与 CLI 共用）

三个内置人设定义在 `presets.py`，两端行为完全一致：

| 预设 | 特点 |
|---|---|
| 标准 | config 默认参数 |
| 高效型程序员 | 中位间隔~80ms、错字率0.5%、节奏稳 |
| 手生普通人 | 中位间隔~180ms、错字率2.5%、忽快忽慢易连错 |

- CLI：`autotyper --preset 手生普通人 --live --window Notepad`
  （`--preset list` 查看全部；预设只覆盖行为参数，`--speed`/窗口等不受影响）
- GUI：「运行」页下拉框选择即自动换算到滑块

### 新增自定义预设

在 `presets.py` 的 `PRESETS` 里加一项即可，两个界面自动出现：

```python
PRESETS["夜班摸鱼"] = {
    "delay_mu": 0.25,        # Config 真实单位：秒 / 概率小数
    "p_typo": 0.02,
    ...
}
```

## 文件结构

```
pyproject.toml     # 打包配置：元数据、依赖、console scripts
README.md
source.txt         # 默认输入内容（也可用 --file 指定其他文件）
humanized_autotyper/       # 包本体
├── __init__.py    # 版本号（pyproject 从这里动态取）
├── __main__.py    # python -m humanized_autotyper
├── config.py      # 全部可调参数（概率、分布参数）
├── presets.py     # 预设人设（GUI 与 CLI 共用）
├── keymap.py      # Shift 符号表 + 邻键表 + 控制字符预检
├── buffer.py      # 虚拟文本缓冲区（唯一真相源，禁止读屏）
├── delays.py      # 延迟采样器（lognormal + 修正因子 + burst/疲劳/预热）
├── typos.py       # 错误生成器（adjacent/double/transposition/random）
├── executor.py    # pynput 键盘层 + dry-run + F10 终止 + CSV 日志
├── machine.py     # 状态机（TYPING/BACKSPACE_BURST/PAUSE_SHORT/
│                  #          PAUSE_LONG/EDIT_PREVIOUS/REWRITE_CHUNK）
├── main.py        # CLI 入口（autotyper）：倒计时、窗口校验、调度循环
├── gui.py         # 图形界面（autotyper-gui）
├── report.py      # 事件日志频率审计（autotyper-report）
├── sanity_check.py # 全链路 dry-run 自检 + 单元验证
└── validate.py    # 多种子批量验证 + kill 开关路径测试
```

包内模块之间用相对导入（`from .config import Config`），因此要整体安装后使用；
单独 `py humanized_autotyper/main.py` 这样直接跑文件是不行的，用命令或 `-m`。

## 快速开始

```bash
autotyper --preset list                    # 看预设

# dry-run 冒烟（无副作用，导出事件日志）
autotyper --file mysource.py --seed 1 --log out.csv

# 审计实际频率是否命中配置概率
autotyper-report out.csv

# 实机输入（见下方安全清单！）
autotyper --live --window Notepad --file mysource.py

# 三条自检入口
py -m humanized_autotyper.sanity_check     # 应输出 ALL SANITY CHECKS PASSED
py -m humanized_autotyper.validate         # 批量种子验证 + kill 开关测试
autotyper-gui --selftest                   # 无界面 GUI 自检
```

`autotyper` 参数：

| 参数 | 说明 |
|---|---|
| `--file` | 要输入的源文本（UTF-8）。缺省时读当前目录 `source.txt`，都没有才用内置演示代码 |
| `--live` | 发送真实击键（默认 dry-run） |
| `--speed X` | 整体速度倍率：>1 加速 / <1 减速（只缩放墙钟时间，不改变人类节奏形状） |
| `--seed` | 固定随机种子（复现行为） |
| `--window "标题子串"` | 前台窗口校验，不匹配则拒绝启动（强烈建议加） |
| `--log FILE` | CSV 事件日志路径 |
| `--verbose` | 逐事件打印到控制台 |

## LIVE 模式安全清单

1. **目标窗口就位**：先打开并聚焦目标窗口（如记事本），再运行命令。
   必须传 `--window`——启动时与每个行尾都会校验前台窗口标题，不匹配直接中止。
   注意 **GUI 没有这道校验**，只能靠倒计时切焦点 + F10 兜底。
2. **倒计时 5 秒**：启动后立即把焦点切到目标窗口。
3. **F10 = 紧急停止**：pynput 监听线程独立置位 kill_flag，分片 sleep 保证
   最长约一个 sleep 片（短停顿 0.25s / 长停顿 2s）内响应。若停止请求正好落在
   "已删除、还没重打"之间，会先把这一小段补完再停，以免文档缺字。
4. **只在无副作用的编辑器里测**：不要对着聊天框/终端/IDE 测试，
   Edit/Rewrite 状态会移动光标、删除重写前文。
5. 首次实测先用小文本、把速度倍率调大（GUI 的「整体速度倍率」/ CLI `--speed 3`）
   跑一遍，确认字符映射（尤其符号）无误后再恢复 1.0 倍速。
6. 结果校验：结束后 `final_matches_source: True` 表示 buffer 与源文本一致；
   若为 False 说明目标应用吞了某个键（如 IME 截走了 shift 组合），查 CSV 里
   出错位置附近的 `detail` 列。

## 输出效果（默认参数下的大致画像）

- 中位敲键间隔 ~110ms（约 9 字/秒），句末/换行后有顿挫，空格带词边界微停顿
- ~5% 的字符处于 0.55× 速度的突发段（每分钟几次，6–20 字符一簇）
- 打字错误率 1.2%/字符（错后 10 字符内翻倍——手滑连错），
  65% 在下一个字符就被发现退格纠正
- 每 ~4 分钟左右一次 4–35 分钟的长暂停（Pareto 分布，只在词边界打断），
  醒来后有 Left×N → Right×N 的"找回位置"仪式 + 10 字符预热减速
- 行尾小概率跳回前 5–40 行原位重写单词/短句，或选中 1–3 行整段重打

## 光标移动策略（纯方向键）

所有导航/选区**只使用 ↑ ↓ ← → 四个方向键**（加 Shift 做选区），不使用
Home / End / Ctrl 组合，也不用鼠标和剪贴板：

- 跨行移动：先 `Up/Down × 行数差`（列粘滞由 buffer 镜像推算），再
  `Right/Left` 校正列差
- 同行移动：直接 `Right/Left × delta`
- 选区：`Shift+Down`（整行）/ `Shift+Right`（行内），纯方向键组合

## 调参指南（config.py）

### 改"打得有多像人"

| 旋钮 | 默认 | 效果 |
|---|---|---|
| `delay_mu` | 0.11s | 基础节奏中位数（lognormal μ），调慢打字整体放慢 |
| `delay_ln_sigma` | 0.42 | 节奏抖动；加大更像新手，减小更机械 |
| `burst_len_range` / `p_burst_enter` | (5,20) / 0.05 | 突发段长度 / 进入概率 |
| `fatigue_rate` / `fatigue_cap` | 0.005 / 1.25 | 每活跃分钟变慢 0.5%，上限 1.25× |
| `warmup_factor` / `warmup_chars` | 1.6 / 10 | ≥5s 停顿后的预热减速曲线 |

### 改"犯错多少"

| 旋钮 | 默认 | 效果 |
|---|---|---|
| `p_typo` | 0.012 | 每字符错误率 |
| `typo_weights` | adjacent 60%… | 错误类型构成（邻键/双打/换序/随机） |
| `typo_detect_probs` | (.65,.25,.10) | 错后第 0/1/2 个字符发现的比例 |
| `typo_autocorr_window` | 10 | 手滑连错的窗口长度 |

### 改"中间行为"

| 旋钮 | 默认 | 效果 |
|---|---|---|
| `p_backspace_burst` | 0.008 | 回删爆发频率（每次连删 2–12 字符） |
| `p_pause_short` / `p_pause_short_sentence` | .008 / .06 | 短停顿频率（后者用于句末字符之后） |
| `p_edit_previous` / `edit_min_gap_s` | .004 / 90s | 跳回前文重写频率 / 两次最少间隔 |
| `p_rewrite_chunk` | .006 | 整段重打频率（行尾评估） |
| `long_pause_xmin` / `alpha` / `cap` | 240s / 1.4 / 2100s | 长停顿时长分布 |

## 工作流（蓝图的调参循环）

```bash
autotyper --file big_source.py --log out.csv      # dry-run 导出
autotyper-report out.csv                          # obs vs cfg 对照
# → 调 config.py → 重跑 → 直到各状态观测频率贴近配置值 → 再实机
```

CSV 格式：`ts,state,event,detail,delay_ms`（csv.writer 正确转义逗号）。
`autotyper-report` 给出 typo/burst/pause 观测率 vs 配置率、逐字符延迟分布。
