jianzhichun/emerge/remote-runner-dev
Claude Code and agent skill by jianzhichun/emerge
- community
Checking that the SKILL.md file is still in the repository.
Use when developing emerge plugin code that targets a remote runner — deploying script changes, managing runner/watchdog lifecycle, debugging execution environment issues (session isolation, tool availability, GUI access), or setting up a new runner on any platform.
Install
npx vskill@latest install jianzhichun/emerge/remote-runner-devSKILL.md
Remote Runner Dev
Overview
Emerge's remote_runner.py is a lightweight HTTP execution server that runs on any machine where the actual tools live — a Windows VM with CAD software, a Linux HPC node with simulation tools, a GPU workstation, a mobile device emulator host. The dev machine stays clean; all environment-specific execution happens on the runner.
Core principle: deploy via `icc_exec` HTTP — not SSH exec, not SCP. The runner is its own deployment channel.
Architecture
The runner executes code in its own process environment — not in the SSH session that deployed it. This distinction matters when the tool requires:
- A specific user session (Windows COM, GUI automation)
- Local hardware (GPU, USB device, simulator)
- Environment variables set at desktop login (conda env, license server, display)
Key Source Files
| File | Role | |
|---|---|---|
scripts/remote_runner.py | HTTP server; executes icc_exec only. Also contains RunnerSSEClient (connects to daemon SSE, dispatches popup commands) | |
scripts/operator_popup.py | Popup renderer. Persistent tk-main thread + _tk_dispatch queue; all popup types use tkinter Toplevel dialogs | |
scripts/runner_watchdog.py | Keeps runner alive; restarts on crash or .watchdog-restart signal | |
scripts/repl_admin.py | CLI: runner-install-url, runner-deploy, runner-status | |
scripts/runner_client.py | Routes requests to runner by target_profile |
Runner setup (first time)
Operators install from the daemon using one copy-paste command (no SSH from the dev machine).
Or open Cockpit → Monitors → Add Runner and copy the curl … | bash / irm … | iex lines. The script downloads the runner bundle from the daemon, writes ~/.emerge/runner-config.json, installs optional pip deps, and registers autostart (systemd / launchd / Windows Run).
After the operator has run the installer, persist the route on the dev machine if needed:
Use runner-deploy for subsequent code updates (HTTP push, hot-reload).
Development Workflow
How runner-deploy works
- Reads
scripts/*.pyfrom local project - Base64-encodes each file, POSTs to
<runner_url>/runasicc_execcalls - Runner writes files to
<plugin_root>/scripts/in-place - Touches
.watchdog-restart→ watchdog restarts runner with new code (~5s)
Why icc_exec, not SSH/SCP
| Method | Problem | |
|---|---|---|
| SSH exec | Runs in SSH session context, not the runner's execution environment | |
| SSH stdin pipe → tar (Windows) | PowerShell $input corrupts binary → Unrecognized archive format | |
| SCP | Hangs on NAT'd / high-latency connections; file locking on Windows | |
icc_exec HTTP | Text-safe (base64), runs in correct environment, no SSH dependency |
Watchdog
runner_watchdog.py wraps the runner process:
- Crash recovery: if runner exits unexpectedly, restarts after
RESTART_DELAY_S(default 3s) - Signal restart: polls for
.watchdog-restartfile everyPOLL_INTERVAL_S(default 2s) - Log: writes start/restart events with PID to
.watchdog.log
Trigger hot-reload manually (without full deploy):
Platform-Specific Setup Notes
Windows — interactive session required for GUI/COM
COM objects (DesktopDraftingApp, DesktopDraftingApp, SpreadsheetApp, etc.) and GUI automation are session-scoped. A process can only access COM objects created in its own Windows session.
The session trap: several approaches silently land the runner in Session 0 (background service context) where COM/GUI calls fail:
| Launch method | Session | GUI/COM | |
|---|---|---|---|
SSH exec / start /B | Session 0 | ✗ fails | |
schtasks /run from SSH | Session 0 | ✗ fails | |
schtasks /create /sc onlogon triggered at actual logon | Session 1+ | ✓ works | |
Registry HKCU\...\Run at logon | Session 1+ | ✓ works | |
| Double-click VBS from desktop | Session 1+ | ✓ works |
Verify the session before debugging COM errors:
Fix: register the watchdog in the user's logon autostart via registry (correct session guaranteed):
If runner is already running in Session 0, you must reboot (or log off/on) to get a clean Session 1 start — killing and restarting via SSH will land back in Session 0. After reboot the registry entry auto-starts the runner in the correct session.
The self-install script can create start_emerge_runner.vbs (Windows autostart). Manual equivalent:
Linux/Mac — standard nohup launch
No session isolation issues for headless Linux; use the install script or systemd user service from runner-install-url output.
ExecSession — Persistent Globals and COM Limitations
icc_exec calls to the same target_profile share one ExecSession (a persistent Python process). Globals survive across calls — like a Jupyter notebook cell:
Exception: Windows COM objects — COM apartments are thread-local; COM objects do not survive across calls. See ~/.emerge/connectors/<vertical>/NOTES.md for vertical-specific patterns.
Non-COM globals (dicts, numpy arrays, plain objects) are safe to reuse across calls — skip redundant imports after the first call.
self-contained Import
remote_runner.py inserts its own root into sys.path — no PYTHONPATH needed regardless of working directory:
Popup Push Flow
runner_notify delivers interactive popups daemon → runner without requiring the runner to be TCP-reachable (NAT-safe):
toast (type=toast) is fire-and-forget: popup_id="", no result POST, daemon returns immediately.
Timeout layering (three levels, outer ≥ inner):
| Layer | Where | Value | |
|---|---|---|---|
| UI countdown | ui_spec.timeout_s | auto-selects first option for choice type | |
| daemon wait | request_popup ev.wait | ui_spec.timeout_s + 30 s | |
| dispatch wait | _tk_dispatch ev.wait | 120 s hard cap on runner side |
Windows Session requirement: operator_popup.py uses tkinter, which requires an interactive desktop session (Session 1). SSH-started processes run in Session 0 (no visible desktop) — popups will silently fail. Runner must be started via Registry Run key (installer sets this up) or by the user double-clicking the VBS shortcut.
Ops Endpoints
Daemon endpoints consumed by runner (runner initiates, daemon receives):
The runner accepts only `icc_exec` requests on /run. Pipeline bridge execution is handled by the daemon (icc_span_open when stable): it loads pipeline .py + .yaml locally, builds self-contained inline code, and sends it as icc_exec. Connector files never need to exist on the runner machine.
Request / response shape for /run:
EventBus endpoints
POST /operator-event — append a single operator event to the local EventBus file.
Request body (JSON):
machine_id must be a plain identifier — no path separators or .. components. Response: {"ok": true} or HTTP 400 with {"ok": false, "error": "..."}.
GET /operator-events?machine_id=<id>&since_ms=<ts>&limit=<n> — read events newer than since_ms (default 0), up to limit (default 200, max 1000).
Response: {"ok": true, "events": [...]}.
These two endpoints are consumed by OperatorMonitor in the daemon when EMERGE_OPERATOR_MONITOR=1.
Common Mistakes
This is the start of the file. Read the full SKILL.md on GitHub.
Security
- Security scanPassed, 95 of 100Pattern checks on the skill's files.
- Model reviewPassed
Quality evaluation
- Task evaluationNot runNo evaluation yet. Run one in Skill Studio.
Source
- SKILL.md in the repositoryCheckingskills/remote-runner-dev/SKILL.md
Popularity
- Repository stars
- 106
- Repository forks
- 13
- 7-day trend score
- 23
Stars and forks are for the whole GitHub repository, not this skill alone. Not refreshed yet.
Works with
Any agent vskill installs to: 56 targets in all. These 39 have a page on this site.
- Claude Code
- Cursor
- GitHub Copilot
- Windsurf
- Codex
- Gemini CLI
- Cline
- Amp
- Roo Code
- Goose
- Continue
- Kilo Code
- Junie
- Trae
- OpenHands
- Qwen Code
- AI Agent
- Tabnine Chat
- Sourcegraph Cody
- Amazon Q
- Firebase Genkit
- Sweep
- Devin
- Phind
- Mentat
- Claude Desktop
- Aider
- GPT Pilot
- Plandex
- bolt.new
- v0
- Replit Agent
- Anse
- TypingMind
- BetterChatGPT
- LibreChat
- Warp AI
- Pieces
- Fig AI
Embed badge
[](https://verified-skill.com/skills/jianzhichun/emerge/remote-runner-dev)