Skip to content

hammadxcm/go-phantom

Folders and files

NameName
Last commit message
Last commit date

Latest commit

Β 

History

18 Commits
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 

version python license tests coverage platform

Phantom

Cross-platform activity simulator that keeps your computer looking busy.

Realistic mouse movements β€’ Keyboard activity β€’ Scrolling β€’ App switching β€’ Browser tabs
Stealth mode β€’ System tray β€’ TUI dashboard β€’ Global hotkeys β€’ Fully configurable


Table of Contents


How it Works

graph LR
    A[Phantom App] --> B[Scheduler]
    B --> C{Weighted Random<br/>Selection}
    C --> D[πŸ–±οΈ Mouse]
    C --> E[⌨️ Keyboard]
    C --> F[πŸ“œ Scroll]
    C --> G[πŸ”€ App Switcher]
    C --> H[🌐 Browser Tabs]
    D --> I[Bezier Curve<br/>Movement]
    E --> J[Modifier Keys<br/>Only]
    B --> K[Anti-Detection]
    K -->|blocks repeats| C
    B --> L[Gaussian Timing<br/>+ Random Idle]
Loading

Phantom's scheduler runs in a daemon thread, picking a random simulator on each cycle. The selection is weighted β€” higher weight means chosen more often. Timing follows a normal distribution with configurable mean/stddev, plus random idle periods that mimic natural breaks. An anti-detection system prevents repetitive patterns (e.g., same action 4+ times in a row, or alternating A-B-A-B sequences).


Features

mindmap
  root((Phantom))
    Simulators
      Mouse β€” Bezier curves + micro-corrections
      Keyboard β€” modifier keys only, no visible output
      Scroll β€” vertical + horizontal
      App Switcher β€” Cmd+Tab / Alt+Tab
      Browser Tabs β€” context-aware shortcuts
    Stealth
      Process name masking
      Tray icon hiding
      Anti-detection timing
      Pattern variation
    Cross-Platform
      macOS
      Windows
      Linux X11
    Interface
      System tray icon
      TUI dashboard
      Rich colored logging
      Global hotkeys
      CLI flags
      JSON config
Loading
Simulator What it does Default Weight
Mouse Moves cursor along randomized cubic Bezier curves with 30% chance of micro-correction jitter at the end 40
Keyboard Presses modifier keys (Shift, Ctrl, Alt) + CapsLock double-tap β€” produces no visible output 30
Scroll Vertical scrolling (90%) or horizontal scrolling (10%), random direction and amount 15
App Switcher Simulates Cmd+Tab (macOS) or Alt+Tab (Windows/Linux) to switch 1-3 apps 10
Browser Tabs Context-aware tab switching β€” detects the active app and sends the correct shortcut (e.g. Cmd+Shift+] for browsers on macOS, Ctrl+Tab for VS Code). Falls back to Ctrl+Tab when detection is unavailable 5

Installation

Quick Install

# PyPI (all platforms)
pipx install go-phantom

# Homebrew (macOS)
brew install hammadxcm/go-phantom/phantom

# Snap (Linux)
sudo snap install go-phantom

# Chocolatey (Windows)
choco install go-phantom

# WinGet (Windows)
winget install hammadxcm.go-phantom

# Scoop (Windows)
scoop bucket add phantom https://github.com/hammadxcm/scoop-phantom
scoop install go-phantom

# Download binary from GitHub Releases
# macOS: phantom-macos-arm64
# Linux: phantom-linux-x86_64 or phantom_0.0.2_amd64.deb
# Windows: phantom-windows.exe
Platform Method Install Run
All PyPI pipx install go-phantom phantom
macOS Homebrew brew install hammadxcm/go-phantom/phantom phantom
Linux Snap sudo snap install go-phantom phantom
Linux .deb sudo dpkg -i phantom_*.deb phantom
Windows Chocolatey choco install go-phantom phantom
Windows WinGet winget install hammadxcm.go-phantom phantom
Windows Scoop scoop install go-phantom phantom
Any Binary Download from Releases ./phantom

One-command install (from source)

Both installers are fully cross-platform β€” use whichever you prefer on any OS:

Method Command Works on
Bash
git clone https://github.com/hammadxcm/go-phantom.git && cd phantom && ./install.sh
macOS, Linux, Windows (Git Bash / WSL / MSYS2)
PowerShell
git clone https://github.com/hammadxcm/go-phantom.git; cd phantom; .\install.ps1
Windows, macOS (pwsh), Linux (pwsh)
CMD
git clone https://github.com/hammadxcm/go-phantom.git && cd phantom && install.bat
Windows (Command Prompt)
Make
git clone https://github.com/hammadxcm/go-phantom.git && cd phantom && make setup
macOS, Linux, Windows (Git Bash / MSYS2)
graph TD
    A[Run installer] --> B{Detect OS}
    B -->|macOS| C[Check Python 3.8+]
    B -->|Linux| D[Check Python 3.8+ & X11]
    B -->|Windows| E[Check Python 3.8+]
    B -->|WSL| F[Check Python 3.8+ & DISPLAY]
    C --> G[Create venv at ~/.phantom]
    D --> G
    E --> G
    F --> G
    G --> H[pip install dependencies]
    H --> I[Create phantom command in ~/.local/bin]
    I --> J{OS-specific notes}
    J -->|macOS| K[Grant Accessibility permission]
    J -->|Windows| L[Add AV exclusion]
    J -->|Linux| M[Ensure X11 + tray support]
    J -->|WSL| N[Configure X11 display server]

    style A fill:#4CAF50,color:#fff
    style J fill:#FF9800,color:#fff
Loading

The installer automatically:

  1. Detects your OS and checks prerequisites (Python 3.8+, X11 on Linux, DISPLAY on WSL)
  2. Creates an isolated virtual environment at ~/.phantom/
  3. Installs all dependencies
  4. Creates OS-appropriate launcher scripts:
    • macOS / Linux: ~/.local/bin/phantom (bash)
    • Windows: phantom.cmd (CMD) + phantom.ps1 (PowerShell)
    • Git Bash on Windows: all three launchers
  5. Checks PATH and shows how to add it if needed

After install, just run:

phantom          # start with defaults
phantom -v       # start with debug logging

Manual install (advanced)

git clone https://github.com/hammadxcm/go-phantom.git
cd phantom

python3 -m venv .venv
source .venv/bin/activate   # macOS/Linux
# .venv\Scripts\activate    # Windows

pip install -e .
python -m phantom

Pre-built binary

pip install -e ".[dev]"     # Install PyInstaller
make build                  # Outputs: dist/phantom
./dist/phantom              # Run standalone (no Python needed)

Uninstall

make uninstall              # Removes ~/.phantom and phantom command

Dependencies

All installed automatically β€” no manual setup needed:

Package Purpose
pynput Global hotkeys and keyboard control
pyautogui Mouse movement and scrolling
pystray System tray icon
Pillow Tray icon image generation
setproctitle Process name masking
rich TUI dashboard and colored logging

Usage

Quick Start

phantom                    # run with defaults (mouse + keyboard + scroll)
phantom --tui              # TUI dashboard mode
phantom -v                 # debug logging
phantom -c ~/config.json   # custom config file

Run Individual Simulators

# Single simulator
phantom --mouse-only           # mouse movement only
phantom --keyboard-only        # keyboard modifier keys only
phantom --scroll-only          # scroll wheel only

# Pick exactly which simulators to run
phantom --only mouse,scroll              # mouse + scroll, nothing else
phantom --only keyboard,browser_tabs     # keyboard + tab switching
phantom --only app_switcher              # app switching only (Cmd/Alt+Tab)

# Add to defaults (mouse + keyboard + scroll are on by default)
phantom --enable app_switcher            # add app switching
phantom --enable app_switcher,browser_tabs  # add both

# Remove from defaults
phantom --disable scroll                 # no scrolling
phantom --disable mouse,keyboard         # scroll only

# Enable everything
phantom --all                            # all 5 simulators active

Timing Control

# Fast mode β€” action every ~3 seconds
phantom --interval 3.0

# Slow mode β€” action every ~20 seconds with high variance
phantom --interval 20.0 --interval-stddev 10.0

# No idle pauses (continuous activity)
phantom --idle-chance 0

# Lots of idle pauses (25% chance each cycle)
phantom --idle-chance 0.25

Simulator Tuning

# Mouse: small, smooth movements
phantom --mouse-only --mouse-distance 20 100 --mouse-speed 150

# Mouse: large, fast movements
phantom --mouse-only --mouse-distance 200 800 --mouse-speed 30

# Keyboard: single key press per action
phantom --keyboard-only --key-presses 1

# Scroll: gentle scrolling (1-2 clicks)
phantom --scroll-only --scroll-clicks 1 2

# Scroll: aggressive scrolling (5-10 clicks)
phantom --scroll-only --scroll-clicks 5 10

Weight Control

Weights control how often each simulator is picked. Higher = more frequent.

# Mouse-heavy (80% mouse, 20% keyboard)
phantom --only mouse,keyboard --mouse-weight 80 --keyboard-weight 20

# Equal distribution across all simulators
phantom --all --mouse-weight 20 --keyboard-weight 20 --scroll-weight 20 \
  --app-switcher-weight 20 --browser-tabs-weight 20

# Mostly scrolling with some mouse
phantom --only mouse,scroll --scroll-weight 70 --mouse-weight 30

Stealth Options

# Maximum stealth (rename process + hide tray icon)
phantom --stealth

# Custom process name
phantom --process-name "WindowServer"

# No stealth at all
phantom --no-stealth

Custom Hotkeys

# Change toggle and quit hotkeys
phantom --hotkey-toggle "<ctrl>+<shift>+f9" --hotkey-quit "<ctrl>+<shift>+f10"

# Change all hotkeys
phantom --hotkey-toggle "<ctrl>+<alt>+p" \
        --hotkey-quit "<ctrl>+<alt>+x" \
        --hotkey-hide "<ctrl>+<alt>+i"

Combined Examples

# Presentation mode: subtle mouse + no idle + stealth + TUI
phantom --mouse-only --mouse-distance 20 200 --interval 5.0 \
        --idle-chance 0 --stealth --tui

# Work simulation: all simulators, relaxed timing, custom hotkeys
phantom --all --interval 15.0 --idle-chance 0.20 \
        --hotkey-toggle "<ctrl>+<shift>+s"

# Quick test: fast keyboard + scroll, verbose logging
phantom --only keyboard,scroll --interval 2.0 -v

# Screen-lock prevention: minimal mouse movement every 30 seconds
phantom --mouse-only --interval 30.0 --interval-stddev 5.0 \
        --mouse-distance 10 50 --idle-chance 0 --no-stealth

Using Make Targets

make run           # tray mode (defaults)
make tui           # TUI dashboard
make run-verbose   # debug logging

TUI Dashboard

The --tui flag launches a rich terminal dashboard instead of the system tray:

β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚  PHANTOM   RUNNING         Uptime: 00:14:32      β”‚
β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
β”‚  Stats              β”‚  Live Logs                 β”‚
β”‚  ─────────────      β”‚  17:04:50 Mouse β†’ (694…    β”‚
β”‚  Mouse        12    β”‚  17:04:55 Keyboard 2 …     β”‚
β”‚  Keyboard      8    β”‚  17:04:58 Scroll 3 cl…     β”‚
β”‚  Scroll        5    β”‚  17:05:03 Mouse β†’ (12…     β”‚
β”‚  App Switch    3    β”‚  17:05:10 Idle 23.4s       β”‚
β”‚  Browser       1    β”‚  17:05:33 Mouse β†’ (45…     β”‚
β”‚  ─────────────      β”‚                            β”‚
β”‚  Total        29    β”‚                            β”‚
β”‚  Last: Mouse        β”‚                            β”‚
β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
β”‚  [S] Toggle  [Q] Quit                            β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

Note: TUI mode and system tray are mutually exclusive. The --tui flag runs the dashboard on the main thread; without it, the system tray runs instead.

CLI Reference

Run phantom --help to see all options. Key flags:

Flag Description
-c, --config Path to config.json
-v, --verbose Debug logging
--tui TUI dashboard mode
--mouse-only Mouse simulator only
--keyboard-only Keyboard simulator only
--scroll-only Scroll simulator only
--only SIMS Comma-separated simulators
--enable SIMS Add simulators to defaults
--disable SIMS Remove simulators
--all Enable all 5 simulators
--interval SEC Mean action interval
--idle-chance P Idle probability (0-1)
--mouse-distance MIN MAX Movement range (px)
--mouse-speed STEPS Bezier smoothness
--key-presses MAX Max keys per action
--scroll-clicks MIN MAX Scroll range
--mouse-weight W Mouse frequency weight
--stealth Max stealth mode
--no-stealth Disable stealth
--process-name NAME Custom process name
--hotkey-toggle KEYS Toggle hotkey
--hotkey-quit KEYS Quit hotkey

Global Hotkeys

Hotkey Action Description
Ctrl+Alt+S Toggle Start or pause simulation
Ctrl+Alt+Q Quit Gracefully exit Phantom
Ctrl+Alt+H Hide Toggle tray icon visibility

System Tray

When running, Phantom shows a system tray icon with a right-click menu:

β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚ β–Ά Start/Pause   β”‚
β”‚ ─────────────── β”‚
β”‚ βœ• Quit          β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

Example Session

$ python -m phantom -v

14:13:44 [INFO] phantom.config.manager: No config file found, using defaults
14:13:44 [WARNING] phantom.core.platform: macOS requires Accessibility permission...
14:13:45 [INFO] phantom.stealth.process: Process renamed to 'system_service'
14:13:45 [INFO] phantom.hotkeys.manager: Hotkeys registered: toggle=<ctrl>+<alt>+s, quit=<ctrl>+<alt>+q
14:13:45 [INFO] phantom.core.scheduler: Simulation loop started
14:13:45 [INFO] phantom.app: Phantom started. Press <ctrl>+<alt>+s to toggle.
14:13:47 [DEBUG] MouseSimulator: Mouse moved to (1474, 829)
14:13:52 [DEBUG] KeyboardSimulator: Keyboard: 2 modifier presses
14:13:58 [DEBUG] ScrollSimulator: Scroll: 3 clicks, direction=1
14:14:05 [DEBUG] MouseSimulator: Mouse moved to (892, 341)
14:14:13 [DEBUG] Idle period: 23.4s

Platform Setup

🍎 macOS

Click to expand macOS setup instructions

Prerequisites

  • macOS 10.15+ (Catalina or later)
  • Python 3.8+

Accessibility Permission (Required)

Phantom needs Accessibility access to control mouse and keyboard input. Without it, simulators will fail silently.

System Settings β†’ Privacy & Security β†’ Accessibility

Step by step:

  1. Open System Settings (or System Preferences on older macOS)
  2. Navigate to Privacy & Security β†’ Accessibility
  3. Click the πŸ”’ lock icon and authenticate
  4. Click + and add your terminal app:
    • Terminal.app β€” if using default terminal
    • iTerm.app β€” if using iTerm2
    • Visual Studio Code.app β€” if running from VS Code terminal
  5. If running the built binary, add phantom directly

Verify it works

# Create venv and install
python3 -m venv .venv && source .venv/bin/activate
pip install -e .

# Run with verbose logging β€” watch for mouse movement logs
python -m phantom -v

# Expected output:
# [INFO] phantom.stealth.process: Process renamed to 'system_service'
# [INFO] phantom.core.scheduler: Simulation loop started
# [DEBUG] MouseSimulator: Mouse moved to (x, y)    ← confirms Accessibility works

macOS-specific behavior

Behavior Details
Main thread pystray requires the main thread on macOS β€” Phantom handles this automatically (tray runs on main, scheduler on daemon thread)
App Switcher Uses Cmd+Tab (not Alt+Tab)
Process masking Uses setproctitle with libc.dylib fallback
Gatekeeper Built binary may need: right-click β†’ Open β†’ confirm

Troubleshooting

# Check if Accessibility is working
python3 -c "import pyautogui; print(pyautogui.position())"
# Should print current mouse coordinates, not throw an error

# If pystray crashes on startup
# Ensure you're NOT running in a headless/SSH session
echo $DISPLAY  # Should not be empty if using XQuartz

πŸͺŸ Windows

Click to expand Windows setup instructions

Prerequisites

  • Windows 10/11
  • Python 3.8+ (python.org β€” check "Add to PATH" during install)

Installation

# Clone and install
git clone https://github.com/hammadxcm/go-phantom.git
cd phantom
python -m venv .venv
.venv\Scripts\activate

pip install -e .

Antivirus Exclusion

Some AV software flags Phantom because it simulates input. To add an exclusion in Windows Defender:

Windows Security β†’ Virus & threat protection β†’ Manage settings
β†’ Exclusions β†’ Add or remove exclusions β†’ Add an exclusion

Add either:

  • The phantom directory (folder exclusion)
  • The built phantom.exe (file exclusion)

Verify it works

# Run with verbose logging
python -m phantom -v

# Expected output:
# [INFO] phantom.stealth.process: Console title set to 'system_service'
# [INFO] phantom.core.scheduler: Simulation loop started
# [DEBUG] MouseSimulator: Mouse moved to (x, y)

Windows-specific behavior

Behavior Details
Process masking Uses SetConsoleTitleW via ctypes β€” changes console window title, limited effect on modern Windows Terminal
App Switcher Uses Alt+Tab
UAC No elevation required β€” runs as standard user
Startup To run at login, add a shortcut to shell:startup

Running as a background task

# Option 1: pythonw (no console window)
pythonw -m phantom

# Option 2: Start minimized
start /min python -m phantom

# Option 3: Built executable
dist\phantom.exe

Troubleshooting

# Verify Python is on PATH
python --version

# Verify pyautogui works
python -c "import pyautogui; print(pyautogui.position())"

# If hotkeys don't register, check for conflicts with other apps
# Try changing hotkeys in config.json:
# "hotkeys": { "toggle": "<ctrl>+<alt>+p", ... }

🐧 Linux

Click to expand Linux setup instructions

Prerequisites

  • Linux with X11 (Ubuntu, Fedora, Arch, etc.)
  • Python 3.8+
  • Wayland is NOT supported β€” pyautogui and pynput require X11 APIs

Check your session type

echo $XDG_SESSION_TYPE
# βœ… x11     β†’ supported
# ❌ wayland β†’ NOT supported β€” switch to X11 session at login screen

Switch from Wayland to X11

GNOME (Ubuntu 22.04+):

  1. Log out
  2. Click your username on the login screen
  3. Click the βš™οΈ gear icon (bottom-right)
  4. Select "GNOME on Xorg" or "Ubuntu on Xorg"
  5. Log in

KDE Plasma:

  1. Log out β†’ select "Plasma (X11)" at login

Installation

# Install system dependencies (Debian/Ubuntu)
sudo apt install python3-venv python3-dev python3-tk

# Install system dependencies (Fedora)
sudo dnf install python3-devel python3-tkinter

# Install system dependencies (Arch)
sudo pacman -S python tk

# Clone and install
git clone https://github.com/hammadxcm/go-phantom.git
cd phantom
python3 -m venv .venv
source .venv/bin/activate
pip install -e .

Verify it works

# Confirm X11 session
echo $XDG_SESSION_TYPE  # must output: x11

# Run with verbose logging
python -m phantom -v

# Expected output:
# [INFO] phantom.stealth.process: Process renamed to 'system_service' (setproctitle)
# [INFO] phantom.core.scheduler: Simulation loop started
# [DEBUG] MouseSimulator: Mouse moved to (x, y)

Linux-specific behavior

Behavior Details
Display server X11 only β€” Wayland will fail at runtime
Process masking Uses setproctitle β€” fully renames the process (visible in ps, top, htop)
App Switcher Uses Alt+Tab
Tray icon Requires a system tray (GNOME needs the AppIndicator extension)
Permissions No special permissions needed (X11 apps can send input to other X11 apps)

Running as a background service

# Option 1: nohup
nohup python -m phantom &

# Option 2: systemd user service
mkdir -p ~/.config/systemd/user

cat > ~/.config/systemd/user/phantom.service << 'EOF'
[Unit]
Description=Phantom Activity Simulator
After=graphical-session.target

[Service]
Type=simple
ExecStart=/path/to/phantom/.venv/bin/python -m phantom
Restart=on-failure
Environment=DISPLAY=:0

[Install]
WantedBy=default.target
EOF

systemctl --user daemon-reload
systemctl --user enable --now phantom.service
systemctl --user status phantom.service

Verify process masking

# In another terminal, after starting Phantom:
ps aux | grep system_service
# Should show the phantom process with name 'system_service'

# Or use htop β€” search for 'system_service'

Troubleshooting

# If mouse simulation fails
python3 -c "import pyautogui; print(pyautogui.position())"
# Error? β†’ You're probably on Wayland

# If tray icon doesn't appear (GNOME)
# Install AppIndicator support:
sudo apt install gnome-shell-extension-appindicator
# Then enable it in GNOME Extensions app

# If hotkeys don't work
# Check for conflicts: some DEs grab Ctrl+Alt combos globally
# Change hotkeys in config.json to avoid conflicts

Configuration

Phantom looks for config.json in this order:

graph LR
    A[1. CLI flag<br/><code>-c path</code>] -->|not provided| B[2. Beside executable<br/><i>PyInstaller only</i>]
    B -->|not found| C[3. Current directory<br/><code>./config.json</code>]
    C -->|not found| D[4. Home directory<br/><code>~/.phantom/config.json</code>]
    D -->|not found| E[5. Built-in defaults]

    style A fill:#4CAF50,color:#fff
    style E fill:#2196F3,color:#fff
Loading

Create a custom config

# Create config directory
mkdir -p ~/.phantom

# Generate a starter config (copy and modify)
cat > ~/.phantom/config.json << 'EOF'
{
  "timing": {
    "interval_mean": 8.0,
    "interval_stddev": 4.0,
    "interval_min": 0.5,
    "idle_chance": 0.10,
    "idle_min": 15.0,
    "idle_max": 120.0
  },
  "mouse": {
    "enabled": true,
    "weight": 40.0,
    "min_distance": 50,
    "max_distance": 500,
    "bezier_steps": 50
  },
  "keyboard": {
    "enabled": true,
    "weight": 30.0,
    "max_presses": 3
  },
  "scroll": {
    "enabled": true,
    "weight": 15.0,
    "min_clicks": 1,
    "max_clicks": 5
  },
  "app_switcher": {
    "enabled": false,
    "weight": 10.0
  },
  "browser_tabs": {
    "enabled": false,
    "weight": 5.0,
    "context_aware": true,
    "backward_chance": 0.3
  },
  "hotkeys": {
    "toggle": "<ctrl>+<alt>+s",
    "quit": "<ctrl>+<alt>+q",
    "hide_tray": "<ctrl>+<alt>+h"
  },
  "stealth": {
    "rename_process": true,
    "process_name": "system_service",
    "hide_tray": false
  }
}
EOF

Config Reference

timing β€” Action interval and idle behavior
Key Type Default Description
interval_mean float 8.0 Average seconds between actions (normal distribution center)
interval_stddev float 4.0 Standard deviation β€” higher = more variation
interval_min float 0.5 Floor β€” actions never fire faster than this
idle_chance float 0.10 Probability (0-1) of entering an idle period per cycle
idle_min float 15.0 Minimum idle pause in seconds
idle_max float 120.0 Maximum idle pause in seconds

Tuning tips:

// Fast mode β€” frequent small actions
{ "interval_mean": 3.0, "interval_stddev": 1.5, "idle_chance": 0.05 }

// Relaxed mode β€” slow, natural pace
{ "interval_mean": 15.0, "interval_stddev": 8.0, "idle_chance": 0.20 }
mouse β€” Bezier curve mouse movement
Key Type Default Description
enabled bool true Enable/disable mouse simulator
weight float 40.0 Selection probability (relative to other simulators)
min_distance int 50 Minimum pixels to move per action
max_distance int 500 Maximum pixels to move per action
bezier_steps int 50 Number of points on the curve β€” higher = smoother
graph LR
    A((Start)) -->|"Bezier curve<br/>50 steps"| B((End))
    A -.->|"Control Point 1<br/>(random offset)"| CP1(( ))
    CP1 -.-> B
    A -.->|"Control Point 2<br/>(random offset)"| CP2(( ))
    CP2 -.-> B
    B -->|"30% chance"| C((Micro-correction<br/>Β±3px jitter))
Loading
keyboard β€” Modifier key simulation
Key Type Default Description
enabled bool true Enable/disable keyboard simulator
weight float 30.0 Selection probability weight
max_presses int 3 Maximum key presses per action (1 to N)

Safe keys used: Shift, Ctrl, Alt + CapsLock double-tap (15% chance, toggles on then off immediately).

These keys produce no visible output β€” they won't type into your active application.

scroll β€” Scroll wheel simulation
Key Type Default Description
enabled bool true Enable/disable scroll simulator
weight float 15.0 Selection probability weight
min_clicks int 1 Minimum scroll clicks per action
max_clicks int 5 Maximum scroll clicks per action

90% vertical scroll, 10% horizontal scroll. Direction is random (up/down or left/right).

app_switcher β€” Application switching
Key Type Default Description
enabled bool false Disabled by default β€” will switch your active window
weight float 10.0 Selection probability weight

Uses Cmd+Tab on macOS, Alt+Tab on Windows/Linux. Switches 1-3 applications per action.

⚠️ Warning: This will change your focused application. Only enable if you want realistic app-switching behavior.

browser_tabs β€” Context-aware tab switching
Key Type Default Description
enabled bool false Disabled by default β€” will switch browser tabs
weight float 5.0 Selection probability weight
context_aware bool true Detect active window and send the correct shortcut for that app/OS
backward_chance float 0.3 Probability of switching to the previous tab (vs. next tab)

When context_aware is enabled, Phantom detects the foreground application and sends the correct tab-switching shortcut:

App macOS Windows / Linux
Browsers (Chrome, Firefox, Safari, Edge, Brave, Arc) Cmd+Shift+] / Cmd+Shift+[ Ctrl+Tab / Ctrl+Shift+Tab
VS Code / Cursor Ctrl+Tab / Ctrl+Shift+Tab Ctrl+Tab / Ctrl+Shift+Tab
iTerm2, Terminal.app Cmd+Shift+] / Cmd+Shift+[ β€”
kitty Ctrl+Shift+Right / Ctrl+Shift+Left Ctrl+Shift+Right / Ctrl+Shift+Left
GNOME Terminal, Konsole β€” Ctrl+PageDown / Ctrl+PageUp
Unknown app (fallback) Ctrl+Tab / Ctrl+Shift+Tab Ctrl+Tab / Ctrl+Shift+Tab

Set context_aware: false to restore the original blind Ctrl+Tab behavior.

⚠️ Warning: Only effective when a tabbed application is the active window. Enable alongside app_switcher for realistic browsing simulation.

Note: Active window detection is not supported on Wayland β€” falls back to Ctrl+Tab.

hotkeys β€” Global hotkey bindings
Key Type Default Description
toggle str <ctrl>+<alt>+s Start / pause simulation
quit str <ctrl>+<alt>+q Exit Phantom
hide_tray str <ctrl>+<alt>+h Toggle tray icon visibility

Uses pynput key format. Examples:

// Custom hotkeys
{
  "toggle": "<ctrl>+<shift>+f9",
  "quit": "<ctrl>+<shift>+f10",
  "hide_tray": "<ctrl>+<shift>+f11"
}
stealth β€” Anti-detection features
Key Type Default Description
rename_process bool true Mask the process name in task manager / ps
process_name str system_service What to rename the process to
hide_tray bool false Start with tray icon hidden (toggle with hotkey)
// Maximum stealth
{
  "rename_process": true,
  "process_name": "windowserver",
  "hide_tray": true
}

Config Examples

Mouse-only mode
{
  "mouse": { "enabled": true, "weight": 100.0 },
  "keyboard": { "enabled": false },
  "scroll": { "enabled": false }
}
Aggressive mode β€” fast actions, all simulators
{
  "timing": {
    "interval_mean": 3.0,
    "interval_stddev": 1.0,
    "idle_chance": 0.02
  },
  "mouse": { "enabled": true, "weight": 30.0 },
  "keyboard": { "enabled": true, "weight": 25.0 },
  "scroll": { "enabled": true, "weight": 20.0 },
  "app_switcher": { "enabled": true, "weight": 15.0 },
  "browser_tabs": { "enabled": true, "weight": 10.0 }
}
Minimal footprint β€” slow and subtle
{
  "timing": {
    "interval_mean": 20.0,
    "interval_stddev": 10.0,
    "idle_chance": 0.25,
    "idle_max": 300.0
  },
  "mouse": {
    "enabled": true,
    "weight": 80.0,
    "min_distance": 20,
    "max_distance": 200,
    "bezier_steps": 80
  },
  "keyboard": { "enabled": true, "weight": 20.0, "max_presses": 1 },
  "scroll": { "enabled": false },
  "stealth": { "rename_process": true, "hide_tray": true }
}

Architecture

graph TB
    subgraph "Main Thread"
        TRAY[πŸ–₯️ System Tray<br/><code>ui/tray.py</code>]
        DASH[πŸ“Š TUI Dashboard<br/><code>ui/dashboard.py</code>]
    end

    subgraph "Daemon Threads"
        HK[🎹 Hotkey Listener<br/><code>hotkeys/manager.py</code>]
        SCHED[⏱️ Scheduler<br/><code>core/scheduler.py</code>]
    end

    subgraph "Simulators"
        MOUSE[πŸ–±οΈ Mouse<br/><code>simulators/mouse.py</code>]
        KB[⌨️ Keyboard<br/><code>simulators/keyboard.py</code>]
        SCROLL[πŸ“œ Scroll<br/><code>simulators/scroll.py</code>]
        APP[πŸ”€ App Switcher<br/><code>simulators/app_switcher.py</code>]
        TABS[🌐 Browser Tabs<br/><code>simulators/browser_tabs.py</code>]
    end

    subgraph "Support"
        CFG[βš™οΈ Config Manager<br/><code>config/manager.py</code>]
        RAND[🎲 Randomizer<br/><code>core/randomization.py</code>]
        AD[πŸ›‘οΈ Anti-Detection<br/><code>stealth/anti_detection.py</code>]
        PROC[πŸ‘» Process Mask<br/><code>stealth/process.py</code>]
        PLAT[πŸ’» Platform<br/><code>core/platform.py</code>]
        STATS[πŸ“ˆ Stats<br/><code>core/stats.py</code>]
    end

    APP_PY[πŸš€ PhantomApp<br/><code>app.py</code>] --> TRAY
    APP_PY -->|"--tui"| DASH
    APP_PY --> HK
    APP_PY --> SCHED
    APP_PY --> CFG
    APP_PY --> PROC

    SCHED --> STATS
    DASH --> STATS

    SCHED --> RAND
    SCHED --> AD
    SCHED --> MOUSE
    SCHED --> KB
    SCHED --> SCROLL
    SCHED --> APP
    SCHED --> TABS

    HK -->|toggle/quit/hide| APP_PY
    TRAY -->|menu actions| APP_PY

    MOUSE --> RAND
    APP --> PLAT
    TABS --> PLAT
Loading

Module Map

phantom/
β”œβ”€β”€ __init__.py              # Package version (__version__ = "0.0.1")
β”œβ”€β”€ __main__.py              # CLI entry point β€” argparse, logging setup
β”œβ”€β”€ app.py                   # Orchestrator β€” wires all components
β”‚
β”œβ”€β”€ config/
β”‚   β”œβ”€β”€ defaults.json        # Default values for all settings
β”‚   β”œβ”€β”€ manager.py           # Load/save config, resolution order
β”‚   └── schema.py            # Dataclass definitions (PhantomConfig, etc.)
β”‚
β”œβ”€β”€ core/
β”‚   β”œβ”€β”€ active_window.py     # Cross-platform active window detection (macOS/Win/Linux)
β”‚   β”œβ”€β”€ platform.py          # OS detection, Wayland check, permission warnings
β”‚   β”œβ”€β”€ randomization.py     # Bezier curves, gaussian timing, weighted choice
β”‚   β”œβ”€β”€ scheduler.py         # Main loop β€” weighted selection, idle, anti-detection
β”‚   β”œβ”€β”€ stats.py             # Thread-safe metrics collector for TUI dashboard
β”‚   └── tab_shortcuts.py     # App-to-shortcut mapping registry for tab switching
β”‚
β”œβ”€β”€ hotkeys/
β”‚   └── manager.py           # Global hotkey registration via pynput
β”‚
β”œβ”€β”€ simulators/
β”‚   β”œβ”€β”€ base.py              # Abstract BaseSimulator β€” all simulators extend this
β”‚   β”œβ”€β”€ mouse.py             # Bezier curve movement + micro-corrections
β”‚   β”œβ”€β”€ keyboard.py          # Modifier-key-only presses (Shift, Ctrl, Alt, CapsLock)
β”‚   β”œβ”€β”€ scroll.py            # Vertical/horizontal scroll wheel
β”‚   β”œβ”€β”€ app_switcher.py      # Cmd+Tab (macOS) / Alt+Tab (Windows/Linux)
β”‚   └── browser_tabs.py      # Context-aware tab switching (detects active app)
β”‚
β”œβ”€β”€ stealth/
β”‚   β”œβ”€β”€ anti_detection.py    # History tracking, pattern blocking
β”‚   └── process.py           # Process name masking (per-OS implementation)
β”‚
└── ui/
    β”œβ”€β”€ dashboard.py         # Rich TUI dashboard (--tui mode)
    β”œβ”€β”€ icons.py             # Tray icon image generation (Pillow)
    β”œβ”€β”€ log_handler.py       # Bounded deque log handler for TUI
    └── tray.py              # System tray integration (pystray)

Threading Model

sequenceDiagram
    participant Main as Main Thread
    participant Tray as Tray (Main)
    participant HK as Hotkey (Daemon)
    participant Sched as Scheduler (Daemon)

    Main->>Main: Parse args, load config
    Main->>Main: Check platform, mask process
    Main->>HK: Start hotkey listener
    Main->>Sched: Start scheduler
    Main->>Tray: Run tray event loop (blocks)

    loop Every ~8s (gaussian)
        Sched->>Sched: Pick weighted random simulator
        Sched->>Sched: Anti-detection check
        Sched->>Sched: Execute simulator
        Sched->>Sched: Wait (gaussian interval)
    end

    HK-->>Main: Ctrl+Alt+S (toggle)
    Main->>Sched: toggle()
    Main->>Tray: update_status()

    HK-->>Main: Ctrl+Alt+Q (quit)
    Main->>Sched: shutdown()
    Main->>HK: stop()
    Main->>Tray: stop()
Loading

Building

Build standalone executable

# Install dev dependencies
pip install -e ".[dev]"

# Build (uses PyInstaller spec in build/phantom.spec)
make build

# Output
ls -la dist/phantom
# -rwxr-xr-x  1 user  staff  12345678  phantom

Makefile targets

Target Command Description
make install pip install -e . Install in editable mode
make dev pip install -e ".[dev]" Install with dev tools (ruff, pyinstaller)
make lint ruff check phantom/ Check code style
make format ruff format phantom/ Auto-format code
make run python -m phantom Run normally
make run-verbose python -m phantom -v Run with debug logging
make tui python -m phantom --tui Run with TUI dashboard
make release git tag v* && git push --tags Create release tag
make build pyinstaller build/phantom.spec ... Build single executable
make clean rm -rf dist/ build/tmp/ ... Remove build artifacts

Testing

# Install test dependencies
pip install -e ".[dev]"
pip install pytest pytest-cov

# Run all tests
pytest

# Run with short traceback
pytest --tb=short

# Run with coverage report
pytest --cov=phantom

# Run a specific test file
pytest tests/test_simulators.py

# Run a specific test
pytest tests/test_simulators.py::test_mouse_clamp -v

Test suite overview

tests/
β”œβ”€β”€ test_active_window.py      9 tests β€” cross-platform window detection, cache
β”œβ”€β”€ test_anti_detection.py    10 tests β€” pattern blocking, history tracking
β”œβ”€β”€ test_app.py               10 tests β€” orchestrator wiring, lifecycle
β”œβ”€β”€ test_config_manager.py    14 tests β€” loading, saving, resolution
β”œβ”€β”€ test_config_schema.py     14 tests β€” dataclass defaults, weights
β”œβ”€β”€ test_dashboard.py         17 tests β€” TUI layout, panels, key handling
β”œβ”€β”€ test_hotkeys.py            7 tests β€” hotkey registration, callbacks
β”œβ”€β”€ test_icons.py              5 tests β€” tray icon generation
β”œβ”€β”€ test_log_handler.py        9 tests β€” DequeHandler capture, maxlen
β”œβ”€β”€ test_main.py               6 tests β€” CLI entry point, --tui, RichHandler
β”œβ”€β”€ test_platform.py          15 tests β€” OS detection, Wayland check
β”œβ”€β”€ test_process.py           11 tests β€” process masking per OS
β”œβ”€β”€ test_randomization.py     25 tests β€” Bezier, timing, distributions
β”œβ”€β”€ test_scheduler.py         12 tests β€” loop, weighted selection, idle
β”œβ”€β”€ test_simulators.py        22 tests β€” all 5 simulators + context-aware tabs
β”œβ”€β”€ test_stats.py             14 tests β€” metrics, thread safety, snapshots
β”œβ”€β”€ test_tab_shortcuts.py     13 tests β€” app-to-shortcut registry lookups
└── test_tray.py              15 tests β€” tray menu, status updates
                             ───
                             298 tests β€” 99% coverage

Contributing

See CONTRIBUTING.md for development workflow, code style, and pull request guidelines.

License

MIT β€” see the LICENSE file for details.

About

Cross-platform activity simulator

Resources

License

Code of conduct

Contributing

Security policy

Stars

Watchers

Forks

Packages

 
 
 

Contributors