Appearance
Human Behavior
FreshSource: BIBLE.md (humanization section), bible/understand-everything.md
Four core modules simulate real human interaction: mouse, keyboard, scroll, timing. All inherited from V1 and upgraded to accept outputMode: 'os' for ghost mode.
human-mouse.mjs
Bezier mouse curves.
How it works
Mouse movements follow cubic Bezier paths with randomized control points, not straight lines. Real humans do not move the mouse in straight lines.
flowchart LR S[Start point] --> CP1[Control point 1, random] CP1 --> CP2[Control point 2, random] CP2 --> E[End point] E --> CL[humanized click]
Output modes
| Mode | Backend |
|---|---|
cdp (default) | Puppeteer Input.dispatchMouseEvent |
os | Windows SendInput via os-input.mjs |
adb | Android Debug Bridge via adb-input.mjs |
Same Bezier math in all three, only the delivery path changes.
Key functions
humanMove(page, fromX, fromY, toX, toY, opts)humanClick(page, x, y, opts)(button, hover delay, dwell after click)humanDrag(page, fromX, fromY, toX, toY, opts)
human-keyboard.mjs
Adjacent-key typo simulation.
How it works
Occasionally hits the key next to the target, then backspaces to correct. Typing has natural variance, not a constant interval per character.
Speed profiles
| Profile | Avg ms/char | Description |
|---|---|---|
fast | 60-100 | Power typist |
normal | 100-180 | Average user |
slow | 200-350 | Hunt and peck |
Output modes
Same as mouse: cdp, os, adb.
Key functions
humanType(page, text, opts)(speed, typos enabled, typo rate)humanPressKey(page, key)(single key)
human-scroll.mjs
Ease-in-out scroll with re-reading.
How it works
Scroll speed ramps up at start, peaks in the middle, ramps down at the end. Random re-reading pauses in the middle (scrolls up a small amount, then resumes).
Output modes
cdp, os, adb. ADB version uses Bezier swipe paths.
Key functions
humanScroll(page, direction, distance, opts)humanScrollFeed(page, count, opts)(multi-scroll feed browsing with dwell)
human-timing.mjs
Utility helpers.
Functions
| Function | What |
|---|---|
sleep(ms) | Promise-based sleep |
randomInt(min, max) | Inclusive integer |
randomFloat(min, max) | Float in range |
weightedChoice(items, weights) | Probabilistic pick |
readingPause(textLength) | Realistic reading delay based on word count |
Same math, different backends
The big architectural win: same humanization math across all three backends.
flowchart TD HM[human-mouse.mjs Bezier path] --> CDP[CDP path: Input.dispatchMouseEvent] HM --> OS[OS path: SendInput sequence] HM --> ADB[ADB path: chained short swipes]
Desktop Bezier curves, ADB Bezier swipes, and CDP Bezier paths all use the same cubic interpolation. Consistency across modes is an invariant: if a session switches modes mid-run, the input pattern stays the same.
Related
- OS Input: Windows SendInput delivery
- ADB Input: Android delivery
- behavioral-identity plugin: per-account behavioral fingerprint