Running a Single Handler (--handle)¶
The Universal client can run one handler action and exit, instead of loading a full timeline and running as a long-lived agent. This turns each GHOSTS handler into an atomic, invokable primitive — useful when an external system (for example, an agent/LLM harness) decides what an NPC should do, and GHOSTS simply executes how.
This does not start the agent
--handle is a standalone entry point. It never starts the scheduler, sockets, listeners, or the normal timeline loop. Running the client with no flags behaves exactly as before.
Usage¶
dotnet ghosts.client.universal.dll --handle <handler> --command <verb> [--arg <value> ...] [--handler-arg key=value ...] [--json]
| Flag | Description |
|---|---|
--handle |
The handler to run (e.g. bash, browserfirefox, curl). Case-insensitive. |
--command |
The handler command/verb to execute (e.g. browse, random). |
--arg |
A command argument. Repeat the flag for multiple arguments. |
--handler-arg |
A handler option as key=value. Repeat for multiple. |
--json |
Emit the result as JSON to stdout (see Output). |
The values map directly onto a single timeline event: --command becomes the event's Command, each --arg is appended to CommandArgs, and each --handler-arg is added to the handler's HandlerArgs. The action is run once (Loop is false), and working-hours gating is disabled so it runs immediately.
Examples¶
Run a shell command:
dotnet ghosts.client.universal.dll --handle bash --command "whoami"
Browse a URL with Firefox (headless — see below):
dotnet ghosts.client.universal.dll --handle browserfirefox --command browse --arg "https://example.com"
Pass multiple arguments and a handler option:
dotnet ghosts.client.universal.dll --handle bash --command "echo one" --arg "echo two" --handler-arg execution-probability=100
Output¶
By default, each result is printed to stdout in human-readable form, with the banner and logs alongside it.
With --json, stdout carries only the JSON result — the banner and all console logging are redirected to stderr — so the output can be consumed by another program:
dotnet ghosts.client.universal.dll --handle bash --command "echo hello" --json 2>/dev/null
{
"handler": "Bash",
"command": "echo hello",
"success": true,
"error": null,
"results": [
{
"Handler": "Command",
"Command": "echo hello",
"Result": "hello\n"
}
]
}
successreflects whether the handler completed without throwing. It does not reflect the exit status of a command the handler ran (for example,bashrunning a nonexistent binary still reportssuccess: true, because the handler itself ran).resultscontains the records the handler reported for this action (the same records normally written tologs/clientupdates.log).- The process exit code is
0on success and1on failure (unknown handler, or the handler threw).
Platform notes¶
Office handlers¶
The Word, Excel, and PowerPoint handlers rely on Office COM automation and only run on Windows. On non-Windows platforms, --handle word|excel|powerpoint transparently runs the cross-platform LightWord/LightExcel/LightPowerPoint variants instead, which write the corresponding document file without a live Office application. The handler field in the JSON output reflects the handler that actually ran.
Outlook and Outlookv2 are already cross-platform (MailKit-based) and run as-is.
Browsers¶
Browser handlers (browserfirefox, browserchrome, browseredge) default to headless mode so they can run without a display. Pass --handler-arg isheadless=false to override. As with timeline-driven browsing, the appropriate browser and its automation driver must be installed (see the client overview).