Headless Desktop Lua Automation
The headless Desktop Lua runner lets RTFMv2.Console execute Desktop-compatible Lua scripts without opening the CoordOps Desktop UI. It is designed for automation, smoke tests, CI checks, and repeatable validation of Desktop script behavior.
Unlike interactive console Lua scripts, this feature runs scripts against a virtual Desktop window runtime. Scripts can inspect the Desktop script metadata catalog, open virtual window runtimes by window_id, set control values, click run buttons, and receive command callbacks.
Command Syntax
RTFMv2.Console.exe desktop-lua run --file <script.lua> [options]
Options
| Option | Required | Description |
|---|---|---|
--file <path> |
Yes | Path to the Desktop Lua script to execute. |
--new-session <name> |
No | Create a new local session before the script runs. |
--target <host-or-range> |
With --new-session |
Target host, range, or domain for the new session. |
--load-session <path> |
No | Load an existing session file or session directory before the script runs. |
--password <value> |
No | Session database password for creating or loading a session. |
--dry-run |
No | Generate commands and callbacks without launching external tools. |
--fail-fast |
No | Return a non-zero exit code when a generated command fails. |
--timeout <seconds> |
No | Maximum script runtime. Defaults to 300. |
--output text|json |
No | Output format. Defaults to text. |
Common Examples
Run a metadata smoke test in dry-run mode:
RTFMv2.Console.exe desktop-lua run ^
--file "Assets\Scripts\LUA\11_window_metadata_showcase.lua" ^
--new-session Headless_Metadata_Test ^
--target 127.0.0.1 ^
--password test ^
--dry-run ^
--timeout 30
Run a Desktop Nmap automation script without launching Nmap:
RTFMv2.Console.exe desktop-lua run ^
--file "Assets\Scripts\LUA\automation_test_1.lua" ^
--new-session Headless_Nmap_Test ^
--target 192.168.0.100 ^
--password test ^
--dry-run ^
--timeout 30
Load an existing session and emit JSON for CI tooling:
RTFMv2.Console.exe desktop-lua run ^
--file "Assets\Scripts\LUA\11_window_metadata_showcase.lua" ^
--load-session "C:\CoordOps\Sessions\Assessment1" ^
--password "session-password" ^
--output json
On Linux, use the same command with dotnet RTFMv2.Console.dll and Unix-style paths:
dotnet RTFMv2.Console.dll desktop-lua run \
--file ./Assets/Scripts/LUA/11_window_metadata_showcase.lua \
--new-session Headless_Metadata_Test \
--target 127.0.0.1 \
--password test \
--dry-run \
--timeout 30
Runtime Model
The runner starts in a virtual Main Window runtime:
rtfm.window_meta.window_idismain.window.rtfm.sessionis available when a session was created or loaded.rtfm.commandsexposes the current framework command catalog.rtfm.windowsis available from the Main Window runtime for catalog and cross-window automation.
Use rtfm.windows.open_by_window_id() to create a virtual runtime for a Desktop window:
rtfm.windows.open_by_window_id("scanner.nmap")
for _, runtime in ipairs(rtfm.windows.runtime_list()) do
if runtime.window_id == "scanner.nmap" then
rtfm.windows.execute(runtime.runtime_key, [[
rtfm.set_text("txtHost", "192.168.0.100")
rtfm.set_is_checked("sS", true)
rtfm.set_is_checked("sV", true)
rtfm.set_is_checked("T4", true)
rtfm.click("btnRun")
]])
end
end
Headless Lua API
The virtual runtime supports the Desktop rtfm table used by bundled Desktop Lua scripts.
| API | Description |
|---|---|
rtfm.print(message) |
Writes output with the current virtual window title. |
rtfm.has_session() |
Returns whether a session is active. |
rtfm.create_session(name, target, password) |
Creates a local session. |
rtfm.load_session(path, password) |
Loads a session file and returns success/error values. |
rtfm.close_session() |
Clears the current session. |
rtfm.session |
Current session object, or nil if no session is active. |
rtfm.commands |
Current framework command catalog. |
rtfm.cancel_requested() |
Always returns false in the current headless runner. |
rtfm.window |
Virtual controls for the current runtime. |
rtfm.window_meta |
Runtime metadata, including runtime_key, window_id, and window_title. |
rtfm.get_text(control) / rtfm.set_text(control, value) |
Read or write text controls. |
rtfm.get_is_checked(control) / rtfm.set_is_checked(control, value) |
Read or write checkbox controls. |
rtfm.get_selected_index(control) / rtfm.set_selected_index(control, index) |
Read or write selected indexes. |
rtfm.control_type(control) |
Returns the virtual control kind. |
rtfm.control_description(control) |
Returns control description metadata. |
rtfm.control_meta(control) |
Returns available metadata for a control. |
rtfm.click(control) |
Simulates a supported button click. |
The Main Window runtime also supports:
| API | Description |
|---|---|
rtfm.windows.catalog() |
Returns catalog metadata for known Desktop windows. |
rtfm.windows.list() |
Alias for catalog(). |
rtfm.windows.get_meta(window_id) |
Returns metadata for a specific window id. |
rtfm.windows.runtime_list() |
Returns currently registered virtual runtimes. |
rtfm.windows.open_by_window_id(window_id) |
Creates a virtual runtime for a Desktop window. |
rtfm.windows.open(runtime_key) |
Returns whether a runtime exists. |
rtfm.windows.close(runtime_key) |
Removes a virtual runtime. |
rtfm.windows.execute(runtime_key, script_text) |
Executes Lua inside another virtual runtime. |
Command Generation
When a script clicks a supported run button, the headless runtime generates a command from the virtual controls:
- If
txtMainhas text, that text is used as the command. - For
scanner.nmap, the runtime can compose annmapcommand fromtxtHostand flags such assS,sV,sC,Pn,T4, andT3. - If
txtTargethas text, the runtime falls back to<window_id> <target>.
With --dry-run, generated commands are printed and callbacks are invoked, but external processes are not launched.
Callbacks
Desktop Lua scripts can define command callbacks:
function on_command_generated(ctx)
rtfm.print("Generated: " .. tostring(ctx.command_string))
end
function on_command_output(ctx)
rtfm.print(tostring(ctx.stream) .. ": " .. tostring(ctx.line))
end
function on_command_done(ctx)
rtfm.print("Exit code: " .. tostring(ctx.exit_code))
end
The callback context includes fields such as command_id, command_string, stream, line, exit_code, success, source_window_id, and source_window_title, depending on the callback.
Exit Codes
| Code | Meaning |
|---|---|
0 |
Script completed successfully. |
1 |
Script file, syntax, or Lua runtime error. |
2 |
Session setup error. |
3 |
Timeout. |
4 |
Generated command failure when --fail-fast is enabled. |
Limitations
- This is a true headless runtime. It does not launch Avalonia windows.
rtfm.ui.prompt()andrtfm.ui.prompt_credentials()return an unavailable result in headless mode.- Virtual controls are based on script metadata and common control names. They are not full visual UI controls.
- Use
--dry-runfor CI and smoke tests when external scanners should not be executed. - Scripts that require interactive prompts should provide defaults or branch when prompts are unavailable.
Recommended Test Pattern
For CI or release validation, run fast Desktop Lua smoke tests in dry-run mode:
RTFMv2.Console.exe desktop-lua run ^
--file "Assets\Scripts\LUA\11_window_metadata_showcase.lua" ^
--new-session Headless_CI ^
--target 127.0.0.1 ^
--password test ^
--dry-run ^
--timeout 30 ^
--output json
This validates session setup, the Desktop script catalog, Lua execution, and virtual window metadata without depending on the desktop UI or third-party tools.