CLI to control Windows applications using UI Automation (UIA) (and optionally browser automation).
- Operate native Windows apps "like a human": focus windows, find UI controls, click, type, wait.
- Provide a scriptable CLI + a small macro language for repeatable flows.
python -m venv .venv
.\.venv\Scripts\activate
pip install -e .Get a full command reference (grouped by category):
hf help
hf help --json # machine-readable JSON (great for agents)
hf help --category drag # filter to a specific grouppython -m venv .venv
.\.venv\Scripts\activate
pip install -e .hf list-windows
hf list-windows --json
hf list-windows --title-regex "Outlook"Launch from Start menu (generic):
hf start --app "Outlook"
hf start --app "Paint"
hf start --app "LinkedIn"Open a folder in File Explorer (most reliable = direct explorer.exe):
hf open-path --path "C:\\Users\\lijin\\.openclaw\\workspace"
# Human-style fallback:
# hf open-path --path "C:\\...\\workspace" --direct falsehf focus --title "LinkedIn"
# or
hf focus --title-regex "Untitled - Paint"Export the UI Automation tree (JSON):
hf tree --title-regex "Untitled - Paint" --depth 10 --max-nodes 30000List controls in a table (quick glance):
hf list-controls --title-regex "Untitled - Paint" --depth 4Inspect element under cursor (prints robust selector JSON):
hf inspect --jsonResolve a selector JSON against the current UI (debugging):
hf resolve --selector-file selector.json
# or override the window matcher:
hf resolve --selector-file selector.json --title-regex "Untitled - Paint"hf click --title "LinkedIn" --name "Sign in with browser" --control-type "Hyperlink"
hf type --title-regex "Notepad" --control "Edit" --text "Hello from handsfree-windows!"Absolute screen drag:
hf drag-screen --start-x 350 --start-y 320 --end-x 950 --end-y 620 --backend sendinputDrag inside the detected canvas/content area (avoids out-of-canvas drags):
hf drag-canvas --title-regex "Untitled - Paint" --backend sendinput
# tweak shape size/position with fractions:
# hf drag-canvas --title-regex "Untitled - Paint" --x1 0.30 --y1 0.30 --x2 0.55 --y2 0.50hf record --out demo.yaml
hf run demo.yamlTest web apps and desktop apps with the same CLI. Browser sessions are persistent — login cookies survive between commands.
python -m playwright install chromium
# optionally: python -m playwright install firefox webkitOpen a URL (visible browser window):
hf browser-open --url "https://github.com"Open headless:
hf browser-open --url "https://github.com" --headlessNavigate within the same session:
hf browser-navigate --url "https://github.com/login"Snapshot the current page (accessibility tree or text):
hf browser-snapshot --fmt aria
hf browser-snapshot --fmt textClick an element:
hf browser-click --text "Sign in"
hf browser-click --selector "button[type=submit]"Type into an input:
hf browser-type --selector "#login_field" --text "myuser"Take a screenshot:
hf browser-screenshot --out result.png --full-pageEvaluate JavaScript:
hf browser-eval --js "document.title"List all links:
hf browser-links# Open an app from Start menu (UIA)
- action: start
args:
app: "My Desktop App"
# Meanwhile open a URL in the browser
- action: browser-open
args:
url: "https://app.example.com/login"
headless: false
# Click login button
- action: browser-click
args:
text: "Sign in"
- action: sleep
args:
seconds: 2
# Screenshot for verification
# (not a macro step yet; run manually: hf browser-screenshot)- UIA backend:
pywinauto. Some apps require elevated privileges. - Browser backend:
Playwright(Chromium/Firefox/WebKit). - Profiles stored at
~/.handsfree-windows/browser-profiles/<engine>/— login sessions persist. - This project is for local automation/testing only; not for stealth/botting.