Directive & Remote Computing
DIRECTIVE sends commands to a registered remote machine. The oql-client agent is installed on any machine — it connects outbound to ql.ocalt.com, receives commands, and executes them natively. No inbound ports. No firewall rules required. The agent does not run an OcaltQL runtime — it executes shell commands, file transfers, and system operations directly. All OcaltQL logic stays on the server side.
Inline Operations
Every DIRECTIVE operation is a single inline statement — there is no OPEN ... CLOSE block form. The agent executes shell commands, file transfers, and system operations directly; all OcaltQL logic (conditionals, loops, variable handling) stays on the server. EXEC can run any shell command on the target machine, which means any operation the machine supports is reachable through it.
Machine Slots
Every machine must claim a slot before it can be addressed. DIRECTIVE REGISTER claims one for a machine id of your choosing — that id is what you use in every later DIRECTIVE call. Calling DIRECTIVE against an id that was never registered is a fatal error.
Every account holds 4,096 machine slots — the same on every plan. A slot is taken when a machine registers and released when it is removed.
A claimed slot is held for 24 hours. Within that window it cannot be released or reassigned — this keeps a machine id stable for anything already addressing it. After 24 hours, DIRECTIVE UNREGISTER frees the slot for another machine.
DIRECTIVE REGISTER fails with a fatal error telling you either to release a slot, or how many hours remain until the oldest one can be released. Re-registering an id you already hold is harmless and does not consume a second slot.DIRECTIVE REGISTER "home-nas" SET ?reg
AFTER EMIT ?reg("slots")
AFTER EMIT ?reg("used")
AFTER DIRECTIVE "home-nas" EXEC "uptime" SET ?r
AFTER EMIT ?r("stdout")
DIRECTIVE UNREGISTER "old-laptop" SET ?rel
AFTER EMIT ?rel
AFTER DIRECTIVE REGISTER "new-laptop" SET ?reg
AFTER EMIT ?reg
DIRECTIVE "never-registered" EXEC "echo hi"
(* Fatal: unregistered machine id 'never-registered' — claim a slot with DIRECTIVE REGISTER first *)
DIRECTIVE REGISTER "one-too-many"
(* Fatal: 'one-too-many' was registered less than 24 hours ago and
cannot be re-registered yet — it unlocks in 19 hour(s) *)
Agent Management
DIRECTIVE LIST SET ?agents
AFTER EMIT ?agents("agents")
AFTER EMIT ?agents("used")
AFTER EMIT ?agents("slots")
AFTER DIRECTIVE STATUS "my-home-server" SET ?status
AFTER EMIT ?status("online")
POLL — How Often an Agent Checks In
An agent polls for work on an interval. POLL sets it, per machine, and takes effect on that machine’s next check-in.
DIRECTIVE "my-server" POLL 1 SECONDS
AFTER DIRECTIVE "home-nas" POLL 5 MINUTES
AFTER DIRECTIVE "backup-box" POLL 60 MINUTES
EXEC and KILL — Remote Shell
Shell commands run directly on the target machine. BACKGROUND makes the call non-blocking, returning a process handle immediately instead of waiting for completion.
DIRECTIVE "my-server" EXEC "apt-get update && apt-get install -y ffmpeg" SET ?r
AFTER EMIT ?r("stdout")
DIRECTIVE "my-server" EXEC "python3 /home/worker.py" BACKGROUND SET ?pid
AFTER SLEEP 5 SECONDS
AFTER DIRECTIVE "my-server" KILL ?pid
DOWNLOAD and UPLOAD
Transfers stream directly between the machine and your namespace, so file size is bounded by your storage quota rather than by memory. DOWNLOAD pulls a file from the machine into the namespace; UPLOAD pushes one the other way. Namespace paths are absolute — /root/... or /mounted/....
Transfers run synchronously by default — the next statement waits until the file has finished moving. To keep working while a transfer runs, make it a promise with SET PROMISE: the transfer starts in the background, the variable reads WAITING until it is done, and WAIT FOR collects the result.
DIRECTIVE "home-nas" DOWNLOAD "/srv/reports/latest.csv" TO "/root/latest.csv" SET ?downl
AFTER EMIT ?downl("state")
(* First path is on the machine, second is in your namespace.
Synchronous: this line does not run until the transfer completes. *)
DIRECTIVE "my-server" UPLOAD "/root/config.json" TO "/etc/app/config.json" SET ?upl
DIRECTIVE "my-server" DOWNLOAD "/var/big.bin" TO "/root/big.bin" SET PROMISE ?job
AFTER EMIT "transfer started, script keeps running"
AFTER IF ?job IS WAITING OPEN EMIT "still transferring" CLOSE
AFTER WAIT FOR ?job SET ?done
AFTER EMIT ?done("state")
(* Fires without blocking; ?job is WAITING until it lands, then WAIT FOR collects it *)
PEERS and NETWORK — Machine-to-Machine Transfer
DOWNLOAD from one, UPLOAD to the other. Slower for a large file on the same LAN, and correct everywhere.DIRECTIVE PEERS groups several registered machines into one network value. DIRECTIVE NETWORK ... TRANSFER then moves a file directly between two of them — the bytes travel machine to machine, not up through the server and back down. Each endpoint is written as a machine id, then ://, then a path on that machine.
DIRECTIVE PEERS "deviceid1" AND "deviceid2" AND "deviceid3" SET ?network
AFTER EMIT ?network(0)("id")
AFTER COUNT ?network SET ?n
AFTER EMIT ?n & " peers"
DIRECTIVE PEERS "deviceid1" AND "deviceid2" AND "deviceid3" SET ?network
AFTER DIRECTIVE NETWORK ?network TRANSFER FROM ?network(0)('id') & "://c:/downloads/file.zip" TO ?network(1)('id') & "://var/www/folder/destfile.zip" SET ?statusanchor
AFTER DIRECTIVE STATUS ?statusanchor SET ?progress
AFTER IF ?progress IS IDENTICAL TO "buffering"
OPEN
SLEEP 5 SECONDS
CLOSE
OR IF ?progress IS IDENTICAL TO "done"
OPEN
EMIT "peer transfer done"
CLOSE
OR
OPEN
EMIT "still in progress check back later"
CLOSE
DIRECTIVE PEERS "deviceid1" AND "deviceid2" AND "deviceid3" SET ?network
AFTER DIRECTIVE NETWORK ?network SHARE ?network(0)('id') PORT 80 AS 8080 SET ?status
(* Any machine in the network can now reach node 0's port 80
at its own localhost:8080 *)
SHARE is peer-to-peer, not a public tunnel. PORT names the port on the machine being shared; AS is the local port every other peer binds. Nothing is exposed to the internet — only members of the network reach it, and only on their own loopback. TUNNEL is the verb for a public URL.TRANSFER returns a status anchor immediately rather than waiting for the file to land. DIRECTIVE STATUS ?statusanchor reads the current state of that transfer — distinct from DIRECTIVE STATUS "id", which reports whether a machine is online. The verb tells them apart by what it is given: a status anchor, or a machine id.SCREENSHOT and WAKE
DIRECTIVE "my-server" SCREENSHOT SET ?shot
AFTER EMIT ?shot
(* ?shot is the path to a real PNG in your namespace *)
The capture is written into your namespace as an ordinary PNG and the verb hands back its path. Nothing is base64, and nothing needs decoding: it is a file, so IMAGE LOAD, GRAPHIC, FILE SHARE and everything else that takes a file work on it directly.
DIRECTIVE "laptop" SCREENSHOT SET ?shot
AFTER FILE SHARE ?shot SET ?link
AFTER EMIT ?link("url")
AFTER EMIT `<img src="` & ?link("url") & `">`
(* The URL points at the PNG itself — no wrapper page needed *)
DIRECTIVE "office-pc" WAKE "AA:BB:CC:DD:EE:FF"
(* An online agent sends the magic packet on its LAN to wake another machine *)
WAKE only succeeds if another already-online oql-client agent shares that machine's local network and can relay the magic packet locally.TUNNEL — Hosting Without a Static IP
Tunnel traffic travels over the connection the agent already holds open to Ocalt — there is no second program to install and no port to open on the machine or the router. Requests arrive at the tunnel URL, are passed down that connection, answered by whatever is listening on the machine's local port, and streamed back.
A tunnel exposes a port on the target machine to the public internet through the agent's own outbound connection — no port forwarding, no static IP, works behind NAT and on mobile connections. Opening one returns a generated URL of the form https://<token>.tunnel.ocalt.com. The tunnel runs independently of the script that created it; closing it deletes the token, and the URL stops working immediately even if the machine is still online.
Exposes a port on the remote machine to the public internet through the agent's already-open outbound connection — no port forwarding, no static IP, works over mobile/cellular connections. The tunnel runs indefinitely once created, independent of the script that started it, and is closed by a separate, later call.
DIRECTIVE "home-nas" TUNNEL PORT 3000 SET ?tunnel
AFTER EMIT ?tunnel("url")
(* Returns https://<token>.tunnel.ocalt.com — public traffic reaches localhost:3000 on the agent machine *)
DIRECTIVE TUNNEL END ?tunnel
/style.css and /img/logo.png resolve inside that tunnel rather than colliding at the top of a shared domain. Nothing is stored in the browser to make this work.Tunnel URLs are generated per tunnel and are not tied to your subdomains. Site Mode hosting is unaffected by tunnels: a subdomain always serves its own files, whether or not any tunnel is open.
REDIRECT on the Remote Agent
DIRECTIVE "id" REDIRECT "url" opens a URL on the remote agent machine's own local client — useful when the remote machine itself needs to open something locally, such as joining a video call from its own side. This is distinct from the normal REDIRECT verb, which redirects the visitor who triggered the script.
NEW VIDEO BRIDGE 2 PEERS SET ?room
AFTER DIRECTIVE "home-server" REDIRECT ?room("peers")(0)("connect_url")
(* Opens the URL on the remote agent's own local client *)
AFTER REDIRECT ?room("peers")(1)("connect_url")
(* Redirects the actual visitor who ran this script *)
File Access — Read & Write
Read and write files directly on the target machine, resolved under the client's configured root folder. Paths are confined to that root.
DIRECTIVE "my-server" WRITE "config/app.json" CONTENT "{"mode":"live"}" SET ?w
AFTER DIRECTIVE "my-server" READ "config/app.json" SET ?cfg
AFTER EMIT ?cfg("data")
(* WRITE creates parent folders as needed; READ returns file contents in data *)
DIRECTIVE "my-server" READ "C:/app/config.json" SET ?cfg
AFTER EMIT ?cfg
DIRECTIVE "my-server" READ "/var/log/app.log" SET ?log
AFTER FILE WRITE "/mounted/logs/app.log" CONTENT ?log
Browsing the Machine's Filesystem
LIST FROM returns the contents of a folder on the target machine; LIST DRIVES returns the machine's drives, which is how you find out what paths exist before listing one. Both are read-only and need no desktop session.
DIRECTIVE "my-server" LIST DRIVES SET ?arrayofdrives
AFTER EMIT ?arrayofdrives(0)
AFTER DIRECTIVE "my-server" LIST FROM "C:/" SET ?cdrivefolderitemarray
AFTER FOREACH ?cdrivefolderitemarray SET ?item
OPEN
EMIT ?item("name")
CLOSE
LIST FROM carries name, is_dir, size and modified — the same shape FILE LIST returns for your own namespace, so the two can be walked by identical code.SERVE — Expose a File Over the Tunnel
SERVE exposes a single file on the machine, without copying it anywhere. It returns a public url ready to use, and also the local port it bound, so the file can be paired with TUNNEL by hand when a script needs the port for something else. Nothing is installed and nothing is uploaded; the file is read from disk as it is requested.
DIRECTIVE "laptop" SERVE "C:/media/clip.mp4" SET ?src
AFTER EMIT ?src("url")
(* Returns https://serve.ocalt.com/<token>.mp4 — the served file’s extension is part of the URL, so a browser or player picks the right handler. The file streams from the machine on demand *)
SERVE uses serve.ocalt.com/<token>.<ext> — the token carries the served file’s extension so the URL ends in .mp4, .pdf and the like — while a TUNNEL, which fronts a whole site, gets its own subdomain instead.DIRECTIVE "laptop" SERVE "C:/media/clip.mp4" SET ?src
AFTER DIRECTIVE "laptop" TUNNEL PORT ?src("port") SET ?tunnel
AFTER EMIT ?tunnel("url")
(* The file is now readable at that URL, streamed from the machine on demand *)
SCREEN — Display Geometry
SCREEN returns one entry per display, so a script can work out where it is pointing before it moves anything. Each entry carries width, height, x, y and primary.
DIRECTIVE "laptop" SCREEN SET ?screen
AFTER EMIT ?screen(0)("width")
AFTER EMIT ?screen(0)("height")
AFTER CALCULATE ?screen(0)("width") / 2 SET ?cx
AFTER CALCULATE ?screen(0)("height") / 2 SET ?cy
AFTER DIRECTIVE "laptop" POINTER X ?cx Y ?cy
AFTER DIRECTIVE "laptop" MOUSE "[Click]"
(* ?screen(1) is null when there is only one display *)
VIEW — The Screen, Live
SCREENSHOT is a moment; VIEW is a stream. It opens a live feed of the machine’s screen and returns a URL that plays it — no polling, no refresh loop, no series of stills pretending to be video.
VIEW previously wrote a single frame to a fixed path, overwriting it each call — which is what SCREENSHOT now does properly, with a file per capture. The live feed rides on the same tunnel and transcode machinery used elsewhere; until it lands, VIEW returns an error pointing you at SCREENSHOT.DIRECTIVE "laptop" VIEW SET ?feed
AFTER EMIT ?feed("url")
(* A tokened URL. Open it in a player or an iframe. *)
AFTER EMIT `<iframe src="` & ?feed("url") & `" allow="autoplay"></iframe>`
Choosing a display
A machine with two monitors has two screens worth seeing, and capturing only the first would quietly hide half of it. ON DISPLAY says which — on SCREENSHOT and on VIEW alike.
DIRECTIVE "laptop" SCREENSHOT SET ?shot
(* the primary display *)
AFTER DIRECTIVE "laptop" SCREENSHOT ON DISPLAY 2 SET ?second
(* the second monitor *)
AFTER DIRECTIVE "laptop" SCREENSHOT ON DISPLAY "all" SET ?shots
AFTER COUNT ?shots SET ?n
AFTER EMIT ?n & " displays captured"
(* ?shots(0) ?shots(1) ... one path per display *)
Displays are numbered from 1, in the order SCREEN reports them, so a script can ask what is there before deciding what to capture.
DIRECTIVE "workstation" VIEW ON DISPLAY "all" SET ?feeds
AFTER FOREACH ?feeds SET ?f
OPEN
EMIT `<iframe src="` & ?f("url") & `"></iframe>`
CLOSE
(* Three monitors become three players, side by side *)
How long a feed lasts
A feed lives while it is being watched. Five minutes after the last time anything pulls from it, it closes and its URL stops working.
Idle is the right thing to measure, not age. A fixed expiry would cut off someone in the middle of watching, and would keep an abandoned tab transcoding long after everyone walked away. This way a feed you are using never dies under you, and a feed nobody is looking at stops costing anything.
DIRECTIVE "laptop" VIEW SET ?feed
AFTER EMIT ?feed("url")
AFTER EMIT ?feed("expires_after")
(* 300 — seconds of inactivity before it closes *)
(* Later, in another script *)
AFTER DIRECTIVE VIEW END ?feed
(* Or just stop watching: it closes on its own. *)
DIRECTIVE VIEW END closes it immediately.Look, decide, act
(* Look. *)
DIRECTIVE "my-server" SCREENSHOT SET ?before
AFTER FILE SHARE ?before SET ?link
AFTER EMIT ?link("url")
(* Act, then look again. *)
AFTER DIRECTIVE "my-server" POINTER X 400 Y 300
AFTER DIRECTIVE "my-server" MOUSE "[Click]"
AFTER DIRECTIVE "my-server" SCREENSHOT SET ?after
AFTER FILE SHARE ?after SET ?link2
AFTER EMIT ?link2("url")
(* Two files, two moments — you can see exactly what the click did. *)
MOUSE, KEYBOARD, POINTER, SCREENSHOT, VIEW and SCREEN all act on a real display — injecting input into it or reading pixels from it. On a machine with no graphical session, such as a headless server, they return an error about not reaching a display. That is not something a script can work around: the machine needs a logged-in desktop for them to have anything to act on.Input Control — Mouse, Keyboard & Pointer
Beyond shell access, DIRECTIVE can drive the target machine's actual mouse and keyboard through the OcaltQL Client's input service. The client must be running on the target with input access — combined with SCREENSHOT, this makes a machine fully navigable from a script. Keys and buttons are written as [Name] tokens joined by +: "[Control]+[c]", "[MouseDown]+[Down]". The full grammar is below.
Key and Button Syntax
Keys and buttons are written as [Name] tokens. Combine them with + between brackets — [Control]+[c], [Control]+[Shift]+[Escape]. A quoted string inside the brackets is a literal character, which is how you send the bracket keys themselves: ["]"] is the ] key, ["["] is [. Single characters need no quotes: [a], [5], [/].
Named keys follow the platform key set: [Enter], [Escape], [Tab], [Space], [Backspace], [Delete], [Insert], [Home], [End], [PageUp], [PageDown], [Up] [Down] [Left] [Right] (or [ArrowUp] etc.), [F1]–[F20], [CapsLock], [NumLock], [ScrollLock], [PrintScreen], [Pause], [ContextMenu], media keys such as [VolumeUp], [VolumeDown], [VolumeMute], [MediaPlayPause], [MediaNextTrack], and numpad keys [Numpad0]–[Numpad9].
Modifiers: [Control] (or [Ctrl]), [Shift], [Alt], [Meta] (or [Win], [Cmd]). In a combination the last token is the key pressed; everything before it is held down and released after.
Mouse tokens: [Click], [RightClick], [MouseDown], [MouseUp], [Up] [Down] [Left] [Right] (relative movement), [ScrollUp], [ScrollDown]. Combine them the same way: [MouseDown]+[Down] drags downward.
0,0; a monitor to its right occupies x values beyond the primary's width, and one to its left uses negative x. POINTER COORDINATES reads back in the same space, so you can read a position, work out which display it falls on, and move relative to it.DIRECTIVE "my-server" POINTER X 400 Y 300
AFTER DIRECTIVE "my-server" POINTER COORDINATES SET ?coord
AFTER EMIT ?coord("x")
AFTER EMIT ?coord("y")
(* POINTER COORDINATES blocks for the agent's reply — ?coord("x"), ?coord("y") *)
DIRECTIVE "my-server" MOUSE "[MouseDown]+[Down]"
AFTER DIRECTIVE "my-server" MOUSE "[ScrollDown]"
(* Tokens: [Click] [RightClick] [MouseDown] [MouseUp] [Up] [Down] [Left] [Right] [ScrollUp] [ScrollDown] *)
DIRECTIVE "my-server" KEYBOARD "[Control]+[c]"
AFTER DIRECTIVE "my-server" KEYBOARD "[Enter]" SET ?ok
AFTER EMIT ?ok
(* Single keys or + combinations. Optional SET returns true/false for success *)
DIRECTIVE "my-server" SCREENSHOT SET ?img
AFTER DIRECTIVE "my-server" POINTER X 250 Y 480
AFTER DIRECTIVE "my-server" MOUSE "[Click]"
AFTER DIRECTIVE "my-server" KEYBOARD "[Enter]"
(* Capture, locate a target, move, click, type — the remote navigation loop *)
When Things Fail
Two conditions stop a script outright, because the script named something that cannot work: addressing a machine id that holds no slot, and calling DIRECTIVE REGISTER when every slot is in use. Both raise a fatal error naming the id and, for slot saturation, how long until a slot can be released.
Everything else is reported rather than fatal. A blocking command against an agent that is offline or stops responding waits until the command's ceiling of 300 seconds and then returns a timeout — the row stays on the hub, so if that agent reconnects later it still receives the work. A command the agent could not carry out comes back with ok false and an error describing why, which you can branch on. Use DIRECTIVE STATUS "id" before a long run if you would rather check that a machine is online first.
A tunnel is torn down if its agent stops reconnecting, and closing one revokes it centrally: the URL stops working immediately, whatever state the machine is in.
Rules
| Rule | Detail |
|---|---|
| No nesting | Cannot call DIRECTIVE inside another DIRECTIVE statement |
| Machine ID | Must be a registered slot; the agent must be online except for WAKE, which targets an offline machine through an online relay |
| Filesystem | DIRECTIVE READ/WRITE resolve paths on the remote machine's filesystem |
| Credentials | The agent uses the same Ocalt credentials as the namespace that registered it |
| Machine slots | 4,096 on every plan — a released slot unlocks after 24 hours |
The Machine's Location
Every registered machine reports approximate coordinates, resolved from its public address when the agent starts. No permission prompt, no GPS — it is the same city-level accuracy a web server infers from an IP.
DIRECTIVE STATUS "home-nas" SET ?s
AFTER EMIT ?s("lat") & ", " & ?s("lon")
AFTER DIRECTIVE LIST SET ?machines
AFTER FOREACH ?machines SET ?m
OPEN
EMIT ?m("id") & " — " & ?m("lat") & "," & ?m("lon")
CLOSE
A Local Server on the Machine
The agent can serve the machine’s root folder as a website on a port of its own. Static files come straight off local disk; an .oql file executes on Ocalt with the visitor’s request forwarded, exactly as Site Mode does. The same script behaves identically on a subdomain and on the machine.
localhost:12345/config, alongside the root folder. Any free port works — including 80 — except 12345, which the agent’s own interface uses. Blank or 0 turns it off.DIRECTIVE "home-nas" TUNNEL PORT 80 SET ?t.Using it as a development server
This is how you build a site without deploying anything. Point the agent’s root at the folder you are working in, give it a port, and open it in a browser — you are editing files on your own machine while real OcaltQL runs against your real namespace.
(* 1. Open the agent's own manager on the machine *)
http://localhost:12345/config
(* 2. Set two fields:
Root /home/you/projects/myshop
Local port 8080 *)
(* 3. Write a script in that folder *)
/home/you/projects/myshop/index.oql
(* 4. Open it *)
http://localhost:8080/
No build step, no upload, no restart. The agent reads the file off disk on every request, so a refresh always shows what you last saved.
How a URL becomes a file
| You open | It serves |
|---|---|
/ | index.oql in the root folder |
/orders | orders.oql — an extensionless path falls back to .oql |
/shop/ | shop/index.oql — a folder serves its index |
/style.css | The file itself, straight off local disk |
/video.mp4 | The file, with byte ranges — so seeking in a player works |
That is the same routing Site Mode uses on a subdomain, which is the point: a script that works here works there unchanged, because it is the same script running in the same place. Only the thing that fetched it differs.
What reaches your script
The agent forwards the visitor’s method, query string, body and cookies along with the script, so !GET, !POST, !REQUEST, !COOKIE and START SESSION behave exactly as they will in production. A form you test on localhost posts to the same code that will receive it live.
(* index.oql *)
IF !REQUEST("method") IS IDENTICAL TO "POST"
OPEN
EMIT "You sent: " & !POST("message")
CLOSE
OR
OPEN
EMIT `<form method="post">
<input name="message">
<button>Send</button>
</form>`
CLOSE
.. is rejected before it is looked at. Port 12345 cannot be used — that is the agent’s own manager.Agent Setup
Install the oql-client application on the machine you want to reach. On first run it opens its own local manager at http://localhost:12345, where you enter your Ocalt credentials, a machine alias (the id you target in DIRECTIVE), and a local root folder. The agent stores that config and connects outbound on its own — no inbound port forwarding, and nothing to open on your router.
The manager also shows a live activity log of every command the machine has run, and the agent can be set to start automatically at logon. Once configured, the machine is addressable from any OcaltQL script using its alias.
Full Verb Reference
| Verb | Description |
|---|---|
DIRECTIVE "id" EXEC "cmd" SET ?r | Run a shell command, blocking |
DIRECTIVE "id" EXEC "cmd" BACKGROUND SET ?pid | Run a shell command, non-blocking |
DIRECTIVE "id" KILL ?pid | Terminate a background process by its operating-system pid — the whole process group is signalled, so child processes die with it |
DIRECTIVE "id" DOWNLOAD "remote" TO "local" SET ?h | Transfer a file from the remote machine |
DIRECTIVE "id" UPLOAD "local" TO "remote" SET ?h | Transfer a file to the remote machine |
<transfer> SET PROMISE ?job | Run a transfer in the background — ?job is WAITING, collect with WAIT FOR |
DIRECTIVE "id" SCREENSHOT SET ?img | Capture the remote machine's screen |
DIRECTIVE "id" WAKE "MAC" | An online agent broadcasts a Wake-on-LAN packet on its LAN for the given MAC |
DIRECTIVE "id" TUNNEL PORT n SET ?tunnel | Expose a local port publicly, no port forwarding needed |
DIRECTIVE TUNNEL END ?tunnel | Close an active tunnel |
DIRECTIVE REGISTER "id" SET ?reg | Claim a machine slot — fatal if every slot is in use |
DIRECTIVE UNREGISTER "id" SET ?rel | Release a slot, permitted once it is 24 hours old |
DIRECTIVE "id" SERVE "path" SET ?src | Serve one file straight off the machine — returns a public url plus the local port |
DIRECTIVE "id" SCREEN SET ?s | Display geometry per monitor — ?s(0)("width"), ("height"), ("x"), ("y"), ("primary") |
DIRECTIVE "id" SCREENSHOT [ON DISPLAY n|"all"] SET ?path | Capture a display to a timestamped PNG in your namespace |
DIRECTIVE "id" VIEW [ON DISPLAY n|"all"] SET ?feed | Open a live feed of a display, returning its URL |
DIRECTIVE "id" REDIRECT "url" | Open a URL in that machine's own default browser |
DIRECTIVE "id" POLL n SECONDS|MINUTES | Check-in interval for one machine — 1 SECOND to 60 MINUTES, default 1 SECOND |
DIRECTIVE PEERS "id" AND "id" SET ?network | Group registered machines into one peer network value |
DIRECTIVE NETWORK ?network TRANSFER FROM "id://path" TO "id://path" SET ?anchor | Move a file directly between two peers — non-blocking, returns a status anchor |
DIRECTIVE NETWORK ?network SHARE "id" PORT n AS n SET ?status | Expose one peer’s port on every other peer’s localhost |
DIRECTIVE STATUS ?anchor SET ?progress | Read a peer transfer's progress — buffering, done, or in progress |
DIRECTIVE "id" LIST FROM "C:/" SET ?items | List a folder on the machine — name, is_dir, size, modified |
DIRECTIVE "id" LIST DRIVES SET ?drives | List the machine's drives |
DIRECTIVE LIST SET ?a | Registered machines plus slot accounting — ?a("agents"), ?a("used"), ?a("slots") |
DIRECTIVE STATUS "id" SET ?status | Check a specific agent's online status |
DIRECTIVE "id" READ "path" | Read a file under the client root — returns data |
DIRECTIVE "id" WRITE "path" CONTENT "..." | Write a file under the client root |
DIRECTIVE "id" MOUSE "[Token]" | Button, scroll or relative move, e.g. "[MouseDown]+[Down]" |
DIRECTIVE "id" KEYBOARD "[Key]+[Key]" | Send a key or chord, e.g. "[Control]+[c]" |
DIRECTIVE "id" POINTER X n Y n | Move the pointer to absolute coordinates |
DIRECTIVE "id" POINTER COORDINATES SET ?c | Read current pointer position — ?c("x"), ?c("y") |