Repio Documentation
Macro Recorder, Editor & Player — v5.3.0 (Enterprise Edition)
Single-file Python/tkinter application
#Community Edition FREE
Community Edition (v3.3) is a free, open-source single-file Python application available on GitHub. It provides core macro recording and playback functionality.
- Mouse & keyboard recording — clicks, movement, scroll, keydown/keyup
- Precise playback engine — lazy generator with virtual clock
- CSV editor with loops — TreeView table, loop_start/loop_end pairs
- Include files — local CSV includes with LRU cache (32 entries)
- Undo / Redo — 50-state history with deep copy
- Breakpoints (F9) — toggle, red highlight, auto-stop during playback
- Bookmarks (Ctrl+B) — toggle, cyan highlight, navigate with wrap-around
- Search in comments (Ctrl+F / F3) — case-insensitive, cyclic
- Open source (Python) — single
repio-dev-comm.pyfile, MIT-friendly
Features available in PRO only: Web Hooks (HTTP URL includes), Save As, Unsaved changes tracking, Settings dialog, Column management, Cumulative timeline, Post-script actions, Configurable hotkeys, Build versioning, Run external program, Window persistence, Launch on login.
⬇ Download Community Edition from GitHub • Compare editions
#1.1 Recording
Records all user actions in real-time:
- Mouse movement — coordinates (x, y) with high-precision timestamps (
time.perf_counter()) - Mouse clicks — separate mousedown/mouseup, buttons: left, right, middle
- Scroll wheel — scroll with delta (dx, dy) and coordinates
- Keyboard — separate keydown/keyup for each key (including Shift, Ctrl, Alt, function keys, etc.)
- Auto pause insertion —
pausewith precisedelay_msbetween events - Move collapse — consecutive move events merged into one (noise reduction)
- Start/End markers — auto-inserted comments
--- Start Rec [N] --- - Record from position — insert recording after selected row
- Filter hotkeys — F6 (stop) filtered from recording
Hotkey: F5 (toggle — start/stop recording)
#1.2 Playback
Lazy playback engine with memory optimization:
- Generator engine —
lazy_action_iterator()uses Python generators andyield fromfor recursive loop/include expansion. Memory: O(depth) instead of O(total_actions) - Virtual clock — precise timing via
time.perf_counter()with virtual accumulator. Sleep granularity: 10ms - Position context — generator returns
(action, context)with file, line, loop stack info - Status bar — updates every 5 actions with current action number, file, loop iterations
- Cleanup on stop — all held keys and mouse buttons automatically released
- Duration display — shows expected duration before start
Hotkeys: F8 Play • F6 Stop • Esc Stop
#1.3 Pause / Resume
- F7 — toggle pause/resume
- Pause button in toolbar changes appearance (sunken + orange background)
- Generator state preserved in memory — resumes from exact position
- Play button always shows ▶ (never changes to "Continue")
#1.4 Breakpoints Community
- F9 or context menu to toggle
- Red highlight (IndianRed
#CD5C5C) with white text - Player auto-stops at breakpoint lines
- Continue with F7 or F8
- Stored in CSV as
is_breakpointfield
#1.5 Bookmarks Community
- Ctrl+B or context menu to toggle
- Cyan highlight (
#E0FFFF) - Navigate with toolbar buttons with wrap-around
- Stored in CSV as
is_bookmarkfield
#1.6 Loops
- Select rows → Insert > Loop → enter repeat count
- Structure:
loop_start(withloop_count) andloop_endpair - Nested loops supported with correct level matching
- Lazy expansion during playback (no memory copies)
- Status display: "Loop 3/10 > 2/5" for nested loops
#1.7 Include Files
- Insert > Include File → choose local CSV or HTTP URL (HTTP/URL includes — PRO only)
- Recursive inline playback via generator
- Duration annotation auto-calculated in comment (PRO only)
- Loaded dynamically at execution time — the file/URL is fetched when playback reaches that row, not on scenario open
- Local files: LRU cache (32 entries), invalidated by
mtime— editing a file mid-run takes effect on next include hit - URL includes: TTL cache 60 s — re-fetched after 60 seconds, enabling live server-side updates
- Max depth: 20 levels (circular include protection)
- Status shows:
[filename.csv:15]— current file and line
#1.8 Editing
TreeView table with 10 columns: #, Type, X, Y, Btn, Key, Delay, Loops, File, Comment
- Double-click or Enter opens EditDialog
- EditDialog: modal window with fields for all action properties, "Record Key" button for live key capture
- Move rows with ⬆/⬇ toolbar buttons
- Multi-select: Shift+Click, Ctrl+Click
- Page Up/Page Down — move selection by 15 rows
- Ctrl+Up/Ctrl+Down — move selected rows up/down
- Shift+Up/Shift+Down — extend selection (standard behavior)
#1.8b Column Management PRO
- View > Column Settings — reorder columns, toggle visibility
- Timeline column — cumulative duration (running total) left of row number
- Delay column displays in short format:
5.4s,1m 5.0s - Column order and visibility persisted in
settings.json
#1.8c Settings PRO
- Tools > Settings — opens 4-tab dialog
- Recording: min mouse movement filter (pixels), ignore multiple modifier keys
- Playback: pause on real mouse movement, pause on keyboard, post-script action, random delay jitter (±1–50%)
- Hotkeys: reconfigure Start/Stop/Play/Pause keys
- General: launch on login, start minimized, auto-open last file, auto-play on startup, screenshot output folder
#1.8d Run External Program PRO
- Insert > Run Program — select executable and arguments
- Creates
run_programaction type - During playback: launches the program via
subprocess.Popen(non-blocking) - Variable interpolation in path —
$varnameexpands in the executable path field - Stdout capture — append
|$varnameto the arguments field to capture program output into a variable; switches to blockingsubprocess.runfile_path: C:\tools\myapp.exe arguments: --input $file|$result
#1.8e Shell Script PRO
- Insert > Shell Script… — type any shell command inline (no external file needed)
- Creates
scriptaction; command stored in Comment field; supports$varnameinterpolation - Without output variable:
subprocess.Popen(cmd, shell=True)— non-blocking (fire and forget) - Stdout capture — set the “Output variable” field (e.g.
$result) to run blocking and store stdout in a variablescript: powershell -command "Get-Date -Format HH:mm" output: $time → $time contains "14:32" - Also available:
runaction type — alias forrun_program
#1.8f Post-Script Actions PRO
- After script completes: None, Lock, Logout, Restart, Shutdown
- Configurable in Settings > Playback tab
- Windows-only: uses
ctypesandshutdowncommands
#1.8g Conditional Actions Enterprise
Pixel-color condition: checks screen pixel at (x, y) and branches on match.
- Insert > If Block — inserts
if_color / else / end_iftriple; wraps selection if rows are selected - Pick Color button in EditDialog reads pixel at (x, y) and fills Color field automatically
- Tolerance field (
dx) — per-channel delta 0–255; 0 = exact match - Nesting supported; level tracking is automatic
if_color x=540 y=320 color=#FF0000 tolerance=10
pause 200
else
pause 50
end_if
#1.8h Variables Enterprise
Runtime variable store shared across all nested loops and includes. Reference syntax: $varname. The legacy $_varname_ syntax is still accepted for backward compatibility.
- Loop variable — set Comment of
loop_startto a name; that variable receives the 1-based iteration index before each loop body executes set_varaction — Comment =name=expression; supports arithmetic (+ - * / ** %) and$varreferences on the right-hand side; not executed as a macro step, pure side-effectif_varaction — Comment = condition expression (e.g.$i > 3,$counter == 5); useselse / end_ifsame asif_color- Interpolation applied in:
typetext,delay_ms,scriptcommand,run_programpath and arguments set_varsupports strings —dir=C:\Scriptsstores a string; arithmetic expressions still evaluate numerically- Unknown variables left as-is; eval failure returns safe default (0.0 / false)
loop_start 100 i ← variable "i" = 1, 2, …, 100
set_var result=$i*2
if_var $i > 50
exit
end_if
type Step $i: result=$result
pause $result ← delay_ms supports expressions
loop_end
#1.8i Goto & Labels Enterprise
Named jump points for non-linear flow. Typical use: error recovery — detect failure via pixel color, restart from beginning.
label— position marker; Comment = label name; never executed; gray italic in editorgoto— Comment = label name; jumps to matching label, propagating through any nesting- Insert > Label… / Goto… — Goto dialog shows a Combobox of existing labels in the current file
- Variable store preserved across
gotorestarts - Label not found → playback stops cleanly (same as
exit)
label start
…actions…
if_color x=200 y=100 color=#0000FF dx=5
goto start ← restart on failure
end_if
#1.8j Comment / Uncomment Rows Enterprise
Temporarily disable actions without deleting them. Commented rows are skipped during playback and shown as gray overstrike text.
- Ctrl+/ — toggle comment on selected rows
- Right-click → Comment / Uncomment
- Edit dialog — “Commented out” checkbox
- CSV field:
is_commented(14th field, backward-compatible)
#1.8k Screenshot OCR Enterprise
Capture the screen and recognize text using the native OS OCR engine. No external software required.
screenshotaction Comment format:label|$varname- If
$varnameis present, OCR runs after capture and stores recognized text in the variable - Windows: uses
Windows.Media.OcrAPI; macOS: Vision framework (planned) - Combine with
if_var+like()for text-based conditions
screenshot check|$screen_text
if_var like("Login", $screen_text)
type [email protected]
end_if
#1.8l like() Function Enterprise
Case-insensitive substring count for use in if_var conditions.
- Syntax:
like("needle", $text)— returns the number of non-overlapping occurrences of needle in text - Both arguments can be string literals (
"...") or variables ($name) - Comparison is case-insensitive
- Returns
0(falsy) if not found,1,2,3… if found — backward-compatible with existing boolean conditions - Supports numeric comparisons:
like("err", $log) > 1
#1.9 Clipboard & History
- Ctrl+C/Ctrl+X/Ctrl+V — Copy/Cut/Paste with deep copy
- Ctrl+Z/Ctrl+Y — Undo/Redo (50 states max)
- Ctrl+A — Select All
#1.10 Search Community
- F3 / Ctrl+F — search in comment fields
- Case-insensitive, cyclic (wraps around)
- Remembers last query
#1.11 File Operations
CSV format with 13 header fields, UTF-8 encoding.
- Ctrl+N New • Ctrl+O Open • Ctrl+S Save • Ctrl+Shift+S Save As
- Recent Files submenu (up to 10 files)
- Auto-open last file on startup
- Unsaved changes tracking: asterisk (*) in title, confirmation dialog on close
#1.11b Multi-Tab Support PRO
- Open multiple
.repiofiles simultaneously in one window - Tab bar between toolbar and table; shows filename with
*if modified - Ctrl+T new tab • Ctrl+W close tab • Ctrl+Tab next • Ctrl+Shift+Tab prev • Ctrl+1–9 direct switch
- Close tab with unsaved changes → prompted to save; closing the last tab resets to empty (window stays open)
- Only one macro plays at a time (the active tab); all existing hotkeys unchanged
#1.11c Quick List Enterprise
A collapsible macro library sidebar on the left side of the main window. Stores a global list of .repio files with optional hotkeys.
- Toggle via the ☰ Library toolbar button; width is saved across sessions
- + adds a file • − / Del removes with confirmation • Double-click / Enter opens in tab
- Open — opens file in a new tab, or switches to it if already open
- Play — runs the macro headlessly in a background thread (skipped if already running)
- Set Key — assigns a global hotkey to the selected entry; fires even when Repio is minimized
- Hotkeys from Quick list are merged with Tab Hotkeys and Macro Hotkeys into the global listener
macro_library — list of {file, hotkey, name} objects stored in settings.json#1.11d Per-Macro Hotkeys Enterprise
Settings → Macro Hotkeys (7th tab) — 10 configurable slots, each mapping a key combo to a .repio file path.
- Hotkey fires globally, even when Repio is minimized or in background
- If the file is open in a tab — plays via GUI player; otherwise loads and runs headless
- Conflict detection checks against F5–F8 internal keys and all Tab Hotkeys
- Second trigger while playback is still running is silently ignored
#1.11e CLI & Headless Mode Enterprise
Enterprise edition supports running scenarios directly from the command line without opening the GUI window.
Basic usage
Repio-Enterprise.exe --run scenario.repio
Repio-Enterprise.exe --run scenario.repio --output-dir C:\screenshots
Repio-Enterprise.exe --run scenario.repio --silent
Repio-Enterprise.exe --help
Options
| Option | Description |
|---|---|
--run FILE | Play a .repio or .csv file headlessly (no GUI) |
--output-dir DIR | Directory for screenshot-action output (default: current directory) |
--silent | Suppress startup hints and pause/stop notification windows — for use in scripts and scheduled tasks |
--help | Print help and exit |
Headless controls
Global hotkeys remain active during --run. Keys are read from Settings (same as GUI mode):
- Pause / Resume — default F7 (configurable in Settings)
- Stop — default F6 (configurable in Settings)
- Abort — Ctrl+C (immediate, no cleanup)
On startup (without --silent) Repio prints the active key bindings, for example:
Playing: daily.repio (142 actions)
Controls: [F7] Pause/Resume [F6] Stop [Ctrl+C] Abort
When playback is paused (hotkey or breakpoint) a small popup appears — click OK to resume. Use --silent to skip the popup (playback resumes immediately after the pause callback returns — i.e. pausing is still possible but the window is suppressed).
Exit codes
0— completed normally or stopped by hotkey1— file could not be loaded
Automation example (Task Scheduler / bat)
Repio-Enterprise.exe --run C:\tasks\daily.repio --silent
if %errorlevel% neq 0 echo Playback failed
#1.12 Versioning PRO
- Base version:
APP_VERSION_BASE = "4.0" - Build index: auto-increment on each run, stored in
build_index.json - Full version:
4.0.Ndisplayed in window title and About dialog
#1.14 Web Hooks PRO
Include macro actions from a remote server via HTTP/HTTPS.
- URL in
file_pathfield ofincludeaction - GET request with query params:
?filename=...&ip=...&line=... - Timeout: 3 seconds • User-Agent:
Repio/{version} - Response: CSV with compatible headers (13 fields)
- Cache: TTL 60 seconds for URL responses
- Preview Hook: context menu to preview URL content in separate window
https://server.com/hook?filename=main&ip=192.168.1.5&line=42#Hotkeys Reference
| Key | Action | Context |
|---|---|---|
| F5 | Start/Stop Recording | Global |
| F6 | Stop All | Global |
| F7 | Pause / Resume | Global |
| F8 | Play | Global |
| Esc | Stop All | Global |
| F9 | Toggle Breakpoint | Global |
| Ctrl+N | New File | Global |
| Ctrl+O | Open File | Global |
| Ctrl+S | Save | Global |
| Ctrl+Shift+S | Save As | Global |
| Ctrl+Z | Undo | Global |
| Ctrl+Y | Redo | Global |
| Ctrl+C/X/V | Copy / Cut / Paste | Global |
| Ctrl+A | Select All | Global |
| Ctrl+B | Toggle Bookmark | Global |
| Ctrl+F | Search | Global |
| F3 | Find Next | Global |
| Del | Delete Selected | Global |
| Ins | Add Action | Global |
| PgUp/PgDn | Move Selection (±15 rows) | TreeView |
| Double-click / Enter | Edit Action | TreeView |
| Right-click | Context Menu | TreeView |
| Ctrl+T | New Tab | Global |
| Ctrl+W | Close Tab | Global |
| Ctrl+Tab | Next Tab | Global |
| Ctrl+Shift+Tab | Previous Tab | Global |
| Ctrl+1–9 | Switch to Tab N | Global |
| Middle-click on tab | Close Tab | Tab Bar |
| Del in Quick List | Remove entry (with confirm) | Quick List |
| Double-click / Enter in Quick List | Open macro in tab | Quick List |
#CSV Format
UTF-8 encoding, comma delimiter, first row is headers. 13 fields:
| Field | Type | Description |
|---|---|---|
type | string | Action type |
x | int/float | Mouse X coordinate |
y | int/float | Mouse Y coordinate |
button | string | Mouse button: left, right, middle |
key_code | string | Key code: Key.shift, a, B, 1, etc. |
delay_ms | float | Delay before action (ms), format "%.4f" |
loop_count | int | Repeat count for loop_start |
file_path | string | Path or URL for include |
dx | int | Horizontal scroll delta |
dy | int | Vertical scroll delta |
comment | string | Comment text |
is_bookmark | string | True / False |
is_breakpoint | string | True / False |
is_commented | string | True / False — skipped during playback |
#Action Types
| Type | Description | Fields Used |
|---|---|---|
move | Move cursor | x, y, delay_ms |
mousedown | Press mouse button | x, y, button, delay_ms |
mouseup | Release mouse button | x, y, button, delay_ms |
click | Click (press+release) | x, y, button, delay_ms |
scroll | Scroll wheel | x, y, dx, dy, delay_ms |
keydown | Press key | key_code, delay_ms |
keyup | Release key | key_code, delay_ms |
pause | Delay | delay_ms |
wait | Alias for pause | delay_ms |
loop_start | Loop begin | loop_count, comment |
loop_end | Loop end | comment |
include | Include file/URL | file_path, comment |
run_program | Run external executable; append |$var to args to capture stdout | file_path (exe, supports $var), comment (args) |
run | Alias for run_program | file_path, comment |
script | Inline shell command; blocking + stdout capture if output variable set | comment (command), file_path (output variable, optional) |
type | Type string (unicode-safe) | comment (text), delay_ms |
screenshot | Capture full screen; OCR if variable specified | comment (label|$varname) |
if_color | Branch on pixel color at (x,y) | x, y, comment (#RRGGBB), dx (tolerance) |
if_var | Branch on variable condition | comment (expression, e.g. $i > 3) |
else | Else branch for if_color / if_var | — |
end_if | Close if block | — |
set_var | Assign variable (side-effect only) | comment (name=expression) |
break | Exit innermost loop | — |
exit | Stop all playback | — |
label | Named position marker (not executed) | comment (name) |
goto | Jump to label | comment (label name) |
comment | Comment (not executed) | comment |
#Architecture
Threading Model
Main Thread (UI) ← tkinter mainloop
_process_queue() root.after(10ms) polling
refresh_table()
all UI callbacks
pynput listeners ← Background daemon threads
mouse.Listener Write events to queue.Queue
keyboard.Listener
Playback Thread ← threading.Thread (daemon)
player.play() Reads from generator
virtual clock
Key Classes
| Class | Purpose |
|---|---|
UnifiedRecorder | Records mouse & keyboard events via pynput into Queue |
IncludeCache | LRU cache (32 entries) for included files & URLs |
lazy_action_iterator | Generator: recursively expands loops, includes, conditionals & variables |
VariableStore | Runtime key-value store; $name interpolation, numeric & bool expression eval |
MacroPlayer | Playback engine with virtual clock & state tracking |
HistoryManager | Undo/Redo stack (50 states, deep copy) |
CSVHandler | Save/Load CSV with 13-field format |
EditDialog | Modal dialog for editing individual actions |
MacroApp | Main application class, coordinates all components |
#Constants
| Constant | Value | Description |
|---|---|---|
WINDOW_SIZE | 1200x800 | Default window size |
HISTORY_LIMIT | 50 | Max undo/redo states |
MAX_INCLUDE_DEPTH | 20 | Max include nesting |
IncludeCache.max_size | 32 | Max cached files |
URL_CACHE_TTL | 60s | URL response cache lifetime |
WEB_HOOK_TIMEOUT | 3s | HTTP request timeout |
| Queue poll interval | 10ms | Event queue polling rate |
| Sleep granularity | 10ms | Min sleep step in playback loop |
| Page step | 15 rows | PgUp/PgDn step size |
#Dependencies
python >= 3.7
tkinter, csv, time, threading, queue, copy,
os, json, io, webbrowser, urllib.request,
urllib.parse, urllib.error, socket # all stdlib
pynput # pip install pynput (only external dep)