ruvnet / ruos-host-run
Run a ruflo swarm agent on the user's own ruOS cloud desktop through the tenant-authenticated fleet MCP, stream its output, and record it in ruflo's swarm state. Use when the user wants an agent to run on a ruOS desktop, asks to "run this on my ruOS desktop", or places a swarm agent on a remote ruOS host.
Run a ruflo agent on a ruOS desktop (session path, ADR-405)
Transport rules — non-negotiable:
Use ONLY the fleet MCP tools (
mcp__ruos__*, or the claude.ai ruOS connector's
equivalents) or the plugin CLI. Never call a desktop on port 17870 and never set aHostheader yourself (ruOS ADR-070: that executor has no per-tenant auth).Send ONLY the command strings printed by
cli.mjs build. Never compose adesktop_execcommand from task text.
CLI below is node "${CLAUDE_PLUGIN_ROOT}/scripts/cli.mjs".
desktop_exec output is framed: the first line echoes your command (▶ run: …), and the
last lines are ✓ SUCCESS… and 📝 transcript:. Every marker the desktop prints isRUOS<nonce>_NAME, on its own line, where <nonce> is the nonce from CLI build. That
token never appears in the echoed command, so match only complete lines that start with it.
Output is capped at about 4 KiB, so poll returns 2 KiB slices.
Never call desktop_delete or secret_delete; deleting is the user's job.
Pick the host. Call
desktop_status. Resolve the user's desktop bymachine_id,fly_machine_idor exactdisplay_name; if it is not in that list, stop. Save the raw
JSON to a temp file (status.json) for step 4.Liveness. A desktop is up only if
heartbeat_statusis notasleep/missing/stale
andlast_heartbeat_atis recent. If it is down, ask beforedesktop_start(billable),
then re-polldesktop_statusuntil the heartbeat advances.Auto-stop.
CLI statusprintsnextAutoStop(weekday 23:00 America/Toronto). If the
run could cross it, tell the user and stop unless they accept.desktop_keepawakeblocks
idle autosleep only; it does not override the 23:00 stop.Build + record. Write the task to a file, then:
CLI build --prompt-file task.txt [--model sonnet]→ JSON withrunId,steps[],poll,stop,promptSha256.CLI record start --run <runId> --desktop "<ref>" --desktop-status-file status.json --task "<one-line summary>"
— registers the agent through ruflo'sagent_spawn(withconfig.host) and claimsruos-run-<runId>viaclaims_claim.
Before launching, call
llm_route_get. Stop if the desktop has no route. If the gateway is
"unconfigured" but the route is "shared", warn and continue.Launch. Call
desktop_execwith eachsteps[i]in order (machine= the desktop'sfly_machine_id). The last step printsRUOS<nonce>_SHA:<hash>— it must equalpromptSha256, elsedesktop_execthestopstring and abort.RUOS<nonce>_NO_RUNNERmeansclaudeis not installed there.Stream. Call
desktop_execwithpoll(rebuild withCLI build --run <runId> --nonce <nonce> --offset <n> ...
as the offset grows, or useCLI runfor automatic polling). Output isRUOS<nonce>_POLL:<exit|->:<size>:<alive 0|1>:<base64>; pass the base64 toCLI record output --run <runId> --b64 <b64>and show the decoded text. Back off 1s→5s
between empty polls — each poll is audited on ruOS and serialises behind the desktop's
run lock.Finish. When exit is not
-and all bytes are read:CLI record end --run <runId> --exit <code>(agent → idle, claim released).
On failure, checkdesktop_status: a stopped desktop means it was auto-stopped mid-run.- Stop early only on the user's request:
desktop_execthestopstring.
For unattended runs from a terminal, CLI run --desktop "<ref>" --prompt-file task.txt
does steps 1–7 itself (needs RUOS_MCP_URL + RUOS_MCP_TOKEN, or --transport ssh withRUOS_SSH_KEY when ruflo runs on a same-tenant ruOS desktop).