Codeonix is a free, open-source desktop automation platform for Windows. You write real code and attach it to triggers — a schedule, a file change, a webhook call, a keyboard shortcut, a USB device, a clipboard copy, a network change, and many more — and Codeonix runs your scripts automatically in the background, without any extra tooling or config files.
Unlike visual automation builders, Codeonix gives you full programmatic control with 3 supported runtimes: Python, Node.js, PowerShell. An integrated AI assistant can write or fix your scripts from a plain-text description. A built-in webhook server lets you trigger any task remotely or integrate Codeonix with external apps and services.
Everything runs 100% locally on your machine. No cloud, no subscriptions, no usage limits.
- 31 built-in triggers — manual, schedule, webhook, filesystem events, downloads, network, battery, system lifecycle, processes, clipboard, USB, hotkeys, and more
- 3 runtimes — Python, Node.js, PowerShell — choose per task
- 100% local-first — no cloud, no telemetry required, no internet dependency for core functionality
- 100% open source — free and unlimited usage, MIT licensed
- AI integrated — describe what you want; Claude, ChatGPT, Gemini, or OpenRouter writes or fixes the code for you
- Webhook built-in server — every task is reachable over HTTP on
localhost:1995; use it to run tasks remotely or integrate with Zapier, n8n, GitHub Actions, or any HTTP-capable service - Command Palette — global shortcut
Ctrl+Downto search and launch any task instantly from anywhere on your desktop - Monaco editor — the same editor that powers VS Code, with syntax highlighting and auto-formatting
- Offline asset bundle — all third-party libraries ship locally; no CDN requests at runtime
- Import / Export — back up and share task bundles as JSON files
- Auto-update — silent background updates; installs on next restart
- Dark & light theme
- Start on boot, run minimised to tray
Head to codeonix.app and download the installer for Windows:
- Windows —
.exeinstaller, run it with no configuration needed
Note: Codeonix currently supports Windows only. macOS and Linux builds are planned for a future release.
Before creating tasks you need to install the runtimes you plan to use:
- Python — python.org (set the path in Settings → Runtimes → Python)
- Node.js — nodejs.org (set the path in Settings → Runtimes → Node.js)
- PowerShell — built into Windows
Prerequisites: Node.js ≥ 18, npm
git clone https://github.com/hassananayi/codeonix.git
npm install
npm start # development
npm run build # package for production- Launch Codeonix. The app starts silently in your system tray.
- Create a task — click the + button in the sidebar or press the New Task shortcut.
- Choose a trigger — pick what starts the task (schedule, webhook, file change, network event, etc.).
- Choose a runtime — Python, Node.js, PowerShell, Bash, or Shell (sh).
- Write your script — use the Monaco editor or click AI ✦ and describe what you want in plain text.
- Save and run — click Run Now to test, then enable the task to let the trigger fire it automatically.
- Use the Command Palette — press
Ctrl+Down(global shortcut) to search and run any saved task without opening the app window.
Codeonix includes 31 built-in triggers across 7 categories. Every trigger injects context into your script as environment variables so you always know why and how the script was started.
Two variables are always present in every run regardless of trigger type:
CODEONIX_TASK_ID — unique ID of the task
CODEONIX_TRIGGER — trigger type that started this run
| Trigger | Fires when… | Environment variables injected |
|---|---|---|
| Manual | You click Run Now or use the Command Palette | — |
| Schedule | A time-based schedule fires (interval, daily, weekly, or cron) | — |
| Webhook | A GET /run?id=TASK_ID request hits the local webhook server |
CODEONIX_WEBHOOK_BODY — raw request body |
| Keyboard Shortcut | The configured global keyboard shortcut is pressed | — |
| Command-Line (CLI) | The task is triggered via curl or CLI at /cli/:taskId |
— |
| System Idle | The user has been inactive for a configured number of minutes | — |
| Trigger | Fires when… | Environment variables injected |
|---|---|---|
| File Added | A new file is created inside the watched folder | CODEONIX_FILE_PATH, CODEONIX_EVENT_TYPE (added), CODEONIX_FILE_NAME, CODEONIX_FILE_EXT |
| File Removed | A file is deleted from the watched folder | CODEONIX_FILE_PATH, CODEONIX_EVENT_TYPE (removed), CODEONIX_FILE_NAME, CODEONIX_FILE_EXT |
| File Updated | An existing file inside the watched folder is modified | CODEONIX_FILE_PATH, CODEONIX_EVENT_TYPE (modified), CODEONIX_FILE_NAME, CODEONIX_FILE_EXT |
| New Download | A new file appears in the system Downloads folder | CODEONIX_FILE_PATH, CODEONIX_EVENT_TYPE (added), CODEONIX_FILE_NAME, CODEONIX_FILE_EXT |
| Specific File Change | A specific file is created, modified, or deleted | CODEONIX_FILE_PATH, CODEONIX_EVENT_TYPE, CODEONIX_FILE_NAME, CODEONIX_FILE_EXT |
| Folder Change | Any file or sub-folder inside a watched directory changes | CODEONIX_FILE_PATH, CODEONIX_EVENT_TYPE, CODEONIX_FILE_NAME, CODEONIX_FILE_EXT |
| Trigger | Fires when… | Environment variables injected |
|---|---|---|
| Wi-Fi Connected | Device connects to a Wi-Fi network | — |
| Wi-Fi Disconnected | Device disconnects from Wi-Fi | — |
| Internet Connected | Internet connectivity is restored | — |
| Internet Lost | Internet connectivity is lost | — |
| LAN Connected | A wired Ethernet connection is established | — |
| LAN Disconnected | The wired Ethernet connection is lost | — |
| Network Change | Network state or interfaces change | CODEONIX_NETWORK — serialised interface list |
| Trigger | Fires when… | Environment variables injected |
|---|---|---|
| Battery Low | Battery drops below the configured threshold (default 20%) | CODEONIX_BATTERY_PERCENT, CODEONIX_BATTERY_CHARGING, CODEONIX_BATTERY_THRESHOLD |
| Laptop Unplugged | Power adapter is disconnected | CODEONIX_BATTERY_PCT |
| Laptop Plugged In | Power cable is connected | CODEONIX_BATTERY_PERCENT, CODEONIX_BATTERY_CHARGING |
| Trigger | Fires when… | Environment variables injected |
|---|---|---|
| Process Started | A specific application or process launches | CODEONIX_PROCESS |
| Process Closed | A specific application or process exits | CODEONIX_PROCESS |
| High CPU Usage | CPU usage exceeds the configured threshold | CODEONIX_PROCESS_NAME, CODEONIX_CPU_PCT, CODEONIX_THRESHOLD |
| High RAM Usage | RAM usage exceeds the configured threshold | CODEONIX_PROCESS_NAME, CODEONIX_RAM_PCT, CODEONIX_THRESHOLD |
| Trigger | Fires when… | Environment variables injected |
|---|---|---|
| Clipboard Changed | Clipboard text content changes | CODEONIX_CLIPBOARD |
| Image Copied | An image is copied to the clipboard | CODEONIX_CLIPBOARD_IMAGE — path to the saved image file |
| URL Copied | A URL (http:// or https://) is copied to the clipboard |
CODEONIX_CLIPBOARD |
| Trigger | Fires when… | Environment variables injected |
|---|---|---|
| Device Connected | A USB device is plugged in | CODEONIX_DEVICE_VENDOR_ID, CODEONIX_DEVICE_PRODUCT_ID |
| Device Disconnected | A USB device is removed | CODEONIX_DEVICE_VENDOR_ID, CODEONIX_DEVICE_PRODUCT_ID |
Every trigger passes context to your script as environment variables. Two are always present in every run:
CODEONIX_TASK_ID — unique ID of the task
CODEONIX_TRIGGER — trigger type that started this run
import os
import json
# Always available — every trigger
task_id = os.environ.get('CODEONIX_TASK_ID')
trigger = os.environ.get('CODEONIX_TRIGGER')
print(f"Task: {task_id} | Started by: {trigger}")
# ── Filesystem triggers ──────────────────────────────────────────────────────
# File Added, File Removed, File Updated, New Download, Specific File Change, Folder Change
file_path = os.environ.get('CODEONIX_FILE_PATH', '')
file_name = os.environ.get('CODEONIX_FILE_NAME', '')
extension = os.environ.get('CODEONIX_FILE_EXT', '') # e.g. ".pdf"
event_type = os.environ.get('CODEONIX_EVENT_TYPE', '') # "added" | "modified" | "removed"
if file_path:
print(f"File event '{event_type}': {file_name} ({extension}) → {file_path}")
# ── Webhook trigger ──────────────────────────────────────────────────────────
raw_body = os.environ.get('CODEONIX_WEBHOOK_BODY', '{}')
payload = json.loads(raw_body)
print(f"Webhook payload: {payload}")
# ── Keyboard Shortcut trigger ────────────────────────────────────────────────
shortcut = os.environ.get('CODEONIX_SHORTCUT', '')
if shortcut:
print(f"Hotkey pressed: {shortcut}")
# ── System Idle trigger ──────────────────────────────────────────────────────
idle_seconds = os.environ.get('CODEONIX_IDLE_SECONDS', '0')
if idle_seconds:
print(f"System idle for {idle_seconds} seconds")
# ── Clipboard triggers ───────────────────────────────────────────────────────
clipboard_text = os.environ.get('CODEONIX_CLIPBOARD', '') # Clipboard Changed / URL Copied
clipboard_url = os.environ.get('CODEONIX_CLIPBOARD_URL', '') # URL Copied
clipboard_image = os.environ.get('CODEONIX_CLIPBOARD_IMAGE', '') # Image Copied — path to saved file
if clipboard_text:
print(f"Copied text: {clipboard_text}")
if clipboard_url:
print(f"Copied URL: {clipboard_url}")
if clipboard_image:
print(f"Copied image saved at: {clipboard_image}")
# ── Power / Battery triggers ─────────────────────────────────────────────────
# Battery Low, Laptop Plugged In
battery_pct = os.environ.get('CODEONIX_BATTERY_PERCENT', '') # e.g. "18"
battery_charging = os.environ.get('CODEONIX_BATTERY_CHARGING', '') # "true" | "false"
battery_threshold = os.environ.get('CODEONIX_BATTERY_THRESHOLD', '') # Battery Low only
# Laptop Unplugged
battery_pct_alt = os.environ.get('CODEONIX_BATTERY_PCT', '')
if battery_pct:
print(f"Battery: {battery_pct}% | Charging: {battery_charging}")
# ── Process Monitoring triggers ──────────────────────────────────────────────
# Process Started / Process Closed
process = os.environ.get('CODEONIX_PROCESS', '')
if process:
print(f"Process event: {process}")
# High CPU Usage / High RAM Usage
process_name = os.environ.get('CODEONIX_PROCESS_NAME', '')
cpu_pct = os.environ.get('CODEONIX_CPU_PCT', '')
ram_pct = os.environ.get('CODEONIX_RAM_PCT', '')
threshold = os.environ.get('CODEONIX_THRESHOLD', '')
if cpu_pct:
print(f"{process_name} is using {cpu_pct}% CPU (threshold: {threshold}%)")
if ram_pct:
print(f"{process_name} is using {ram_pct}% RAM (threshold: {threshold}%)")
# ── Network Change trigger ───────────────────────────────────────────────────
network_raw = os.environ.get('CODEONIX_NETWORK', '[]')
interfaces = json.loads(network_raw)
print(f"Network interfaces: {interfaces}")
# ── Devices triggers ─────────────────────────────────────────────────────────
# Device Connected / Device Disconnected
vendor_id = os.environ.get('CODEONIX_DEVICE_VENDOR_ID', '')
product_id = os.environ.get('CODEONIX_DEVICE_PRODUCT_ID', '')
if vendor_id:
print(f"Device — VID: {vendor_id} | PID: {product_id}")const env = process.env;
// Always available — every trigger
console.log(`Task: ${env.CODEONIX_TASK_ID} | Started by: ${env.CODEONIX_TRIGGER}`);
// ── Filesystem triggers ──────────────────────────────────────────────────────
// File Added, File Removed, File Updated, New Download, Specific File Change, Folder Change
const filePath = env.CODEONIX_FILE_PATH ?? '';
const fileName = env.CODEONIX_FILE_NAME ?? '';
const extension = env.CODEONIX_FILE_EXT ?? ''; // e.g. ".pdf"
const eventType = env.CODEONIX_EVENT_TYPE ?? ''; // "added" | "modified" | "removed"
if (filePath) {
console.log(`File event '${eventType}': ${fileName} (${extension}) → ${filePath}`);
}
// ── Webhook trigger ──────────────────────────────────────────────────────────
const payload = JSON.parse(env.CODEONIX_WEBHOOK_BODY ?? '{}');
console.log('Webhook payload:', payload);
// ── Keyboard Shortcut trigger ────────────────────────────────────────────────
const shortcut = env.CODEONIX_SHORTCUT ?? '';
if (shortcut) console.log(`Hotkey pressed: ${shortcut}`);
// ── System Idle trigger ──────────────────────────────────────────────────────
const idleSeconds = env.CODEONIX_IDLE_SECONDS ?? '0';
if (idleSeconds !== '0') console.log(`System idle for ${idleSeconds} seconds`);
// ── Clipboard triggers ───────────────────────────────────────────────────────
const clipboardText = env.CODEONIX_CLIPBOARD ?? ''; // Clipboard Changed / URL Copied
const clipboardUrl = env.CODEONIX_CLIPBOARD_URL ?? ''; // URL Copied
const clipboardImage = env.CODEONIX_CLIPBOARD_IMAGE ?? ''; // Image Copied — path to saved file
if (clipboardText) console.log(`Copied text: ${clipboardText}`);
if (clipboardUrl) console.log(`Copied URL: ${clipboardUrl}`);
if (clipboardImage) console.log(`Copied image saved at: ${clipboardImage}`);
// ── Power / Battery triggers ─────────────────────────────────────────────────
// Battery Low, Laptop Plugged In
const batteryPct = env.CODEONIX_BATTERY_PERCENT ?? ''; // e.g. "18"
const batteryCharging = env.CODEONIX_BATTERY_CHARGING ?? ''; // "true" | "false"
const batteryThreshold = env.CODEONIX_BATTERY_THRESHOLD ?? ''; // Battery Low only
// Laptop Unplugged
const batteryPctAlt = env.CODEONIX_BATTERY_PCT ?? '';
if (batteryPct) console.log(`Battery: ${batteryPct}% | Charging: ${batteryCharging}`);
// ── Process Monitoring triggers ──────────────────────────────────────────────
// Process Started / Process Closed
const process_ = env.CODEONIX_PROCESS ?? '';
if (process_) console.log(`Process event: ${process_}`);
// High CPU Usage / High RAM Usage
const processName = env.CODEONIX_PROCESS_NAME ?? '';
const cpuPct = env.CODEONIX_CPU_PCT ?? '';
const ramPct = env.CODEONIX_RAM_PCT ?? '';
const threshold = env.CODEONIX_THRESHOLD ?? '';
if (cpuPct) console.log(`${processName} is using ${cpuPct}% CPU (threshold: ${threshold}%)`);
if (ramPct) console.log(`${processName} is using ${ramPct}% RAM (threshold: ${threshold}%)`);
// ── Network Change trigger ───────────────────────────────────────────────────
const interfaces = JSON.parse(env.CODEONIX_NETWORK ?? '[]');
console.log('Network interfaces:', interfaces);
// ── Devices triggers ─────────────────────────────────────────────────────────
// Device Connected / Device Disconnected
const vendorId = env.CODEONIX_DEVICE_VENDOR_ID ?? '';
const productId = env.CODEONIX_DEVICE_PRODUCT_ID ?? '';
if (vendorId) console.log(`Device — VID: ${vendorId} | PID: ${productId}`);The built-in HTTP server starts automatically on localhost:1995 (configurable). Every task can be triggered via HTTP regardless of its configured trigger type — use this to integrate Codeonix with other apps, run tasks from CI pipelines, or call them from n8n, Zapier, or any HTTP client.
| Method | Endpoint | Description |
|---|---|---|
GET |
/status |
App status, version, task count |
GET |
/tasks |
List all tasks |
GET |
/run?id=<task_id> |
Run a task; request body available as CODEONIX_WEBHOOK_BODY |
GET |
/cli/<task_id> |
Run a task from the terminal |
# Check status
curl http://localhost:1995/status
# Run a task with a JSON payload
curl -X GET http://localhost:1995/run?id=abc123 \
-H "Content-Type: application/json" \
-d '{"source":"github","event":"push"}'
# CLI trigger (simple GET)
curl -s "http://localhost:1995/cli/abc123"You can copy the exact curl command for any task by right-clicking it in the sidebar and selecting Copy CLI Command.
Codeonix integrates with four AI providers. Set your API key once in Settings → General → AI.
| Provider | Models |
|---|---|
| Claude (Anthropic) | claude-opus-4-6, claude-sonnet-4-6, claude-haiku-4-5 |
| ChatGPT (OpenAI) | gpt-4.1, gpt-4o, gpt-4o-mini, o3-mini |
| Gemini (Google) | gemini-2.5-pro, gemini-2.0-flash, gemini-1.5-pro |
| OpenRouter | Claude, GPT-4o, Llama 3.3, DeepSeek R1, and more |
Click the AI ✦ button in the task editor and describe what you want the script to do. The AI sees the trigger type and generates code that uses the correct environment variables automatically. If an existing script has an error, click AI ✦ again and describe the problem — it will attempt to fix it.
| Setting | Default | Description |
|---|---|---|
| Python Path | — | Path to your Python executable (must be installed separately) |
| Node.js Path | — | Path to your Node.js executable (must be installed separately) |
| Webhook Port | 1995 |
Port the built-in HTTP server listens on |
| Task Timeout | 120000 ms |
Max run time per task; 0 = unlimited |
| AI Provider | Claude | Which AI service to use for code generation |
| AI Model | claude-sonnet-4-6 | Model within the selected provider |
| API Key | — | Your API key for the selected provider |
| Command Palette Shortcut | Ctrl+Down |
Global shortcut to open the Command Palette from anywhere |
| Theme | Dark | Dark or light UI theme |
| Start Minimised | Off | Launch directly to system tray |
| Run on Startup | Off | Start Codeonix when the OS boots |
| Auto-Update | On | Silently download and install updates |
| Analytics | On | Send anonymous usage events; disable from Settings → Privacy |
Contributions are welcome — bug fixes, new trigger types, UI improvements, or documentation.
- Fork the repository
- Create a branch:
git checkout -b feature/my-feature - Make your changes and test them
- Open a pull request with a clear description of what you changed and why
Please open an issue and include:
- Your Windows version (Windows 10 or 11)
- Codeonix version (visible in Settings → About)
- Steps to reproduce
- What you expected vs. what happened
MIT © Codeonix Contributors — see LICENSE for full text.




