跳到主要内容

Remote Control Daemon

The Aethrix daemon is a background service that exposes a local HTTP control API. It executes automation projects, manages service simulation servers, and installs extension packages — so CI agents, scripts, and other tools can drive Aethrix without opening Aethrix Studio.

The daemon runs locally on your machine. Each automation run executes in its own child aeth run process, isolated from Aethrix Studio: the daemon has its own state root, settings, and workspace, and never touches Studio's data.

Quickest Scenario​

Start the daemon in the background (it returns control immediately):

aeth daemon

The daemon publishes a discovery file with its address and access token:

%APPDATA%\AethrixTech\Aethrix\daemon.json
{
"version": 1,
"pid": 21440,
"port": 52341,
"token": "bTRhbDk…",
"workspace": "C:\\Users\\you\\AppData\\Roaming\\AethrixTech\\Aethrix\\daemon\\workspace",
"startedAt": "2026-09-06T09:00:00Z"
}

Every call (except GET /v1/healthz) requires the token as a bearer header:

TOKEN=$(python -c "import json;print(json.load(open(r'%APPDATA%\AethrixTech\Aethrix\daemon.json'))['token'])")
curl -s http://127.0.0.1:52341/v1/healthz
curl -s -H "Authorization: Bearer $TOKEN" http://127.0.0.1:52341/v1/system/info

Run an automation project and fetch its report:

curl -s -X POST -H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{"projectId":"MyProject/MyProject.aprj","reportFormats":["junit"]}' \
http://127.0.0.1:52341/v1/runs

Build a project's shape without opening Studio — one command per step of it, so a script says what it creates:

curl -s -H "Authorization: Bearer $TOKEN" http://127.0.0.1:52341/v1/commands # what this door runs
curl -s -X POST -H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{"project":"projects/MyProject/MyProject.aprj","parameters":{"suite_name":"Smoke"}}' \
http://127.0.0.1:52341/v1/commands/structure.suite.add
curl -s -X POST -H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{"project":"projects/MyProject/MyProject.aprj","parameters":{"suite_name":"Smoke","test_case_name":"Login"}}' \
http://127.0.0.1:52341/v1/commands/structure.case.add
curl -s -X POST -H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{"project":"projects/MyProject/MyProject.aprj","parameters":{"suite_name":"Smoke","test_case_name":"Login","operation_id":"Swagger.PetStore.POST /pet/{petId}"}}' \
http://127.0.0.1:52341/v1/commands/structure.step.send.add

Stop the daemon when done:

aeth daemon --stop

Start and Stop Options​

OptionDescription
(default)Start the daemon in the background and return control once it is ready
--startSame as the default action (accepted for readability)
--foregroundRun attached to the terminal; press Ctrl+C to stop
--stopAsk a running daemon to shut down gracefully, then stop it
--workspace <path>Use a custom workspace root instead of the default daemon state root
--port <port>Listen on a fixed TCP port instead of a free ephemeral port

Rules that apply on a machine:

  • One daemon at a time. A machine-wide lock file (daemon.lock) prevents a second instance. Starting while one runs just reports the existing daemon.
  • Stale entries are cleaned up. If a previous daemon died without cleaning up, the discovery file is detected as stale and removed.
  • sim start and the daemon are mutually exclusive. If a background aeth sim start process owns the simulation servers, aeth daemon refuses to start (and vice versa) — one owner per machine.

Isolation from Aethrix Studio​

The daemon keeps its own state in %APPDATA%\AethrixTech\Aethrix\daemon (or the --workspace path you give it): settings, workspace, projects, run outputs. Each run spawns a fresh aeth run child process with this state root injected, so:

  • Runs use the daemon's environment variables and settings, not Studio's.
  • A crashed or cancelled run cannot corrupt the daemon process; it is detected and reported.
  • A run can be cancelled cooperatively (stop sentinel) or killed after a grace period.

Authentication​

The daemon generates a random token at startup and stores it in daemon.json. Requests must carry Authorization: Bearer <token>; anything else is answered with 401 Unauthorized. GET /v1/healthz is anonymous for liveness probes.

HTTP API Reference​

Base URL: http://127.0.0.1:<port>. All bodies are JSON unless noted. A machine-readable OpenAPI document is served at GET /v1/openapi.json.

MethodPathDescription
GET/v1/healthzLiveness probe (no auth)
GET/v1/system/infoVersion, uptime, workspace, run capacity
POST/v1/system/shutdown?force=Graceful (or forced) shutdown
GET/v1/projectsDiscover .aprj files under the workspace
POST/v1/projects?mode=replace&#124;mergePush a zipped project (binary body)
GET/v1/environments?project=<id>List project environments (values are never returned)
PUT/v1/environments/variablesCreate or update a variable in a project environment
GET/v1/commandsThe workspace operations this door runs, read from the command catalog (id, summary, risk, arguments)
POST/v1/commands/<id>Run one of them against a project: {"project": "…", "parameters": {"suite_name": "…"}}. An argument the command does not declare is refused, and a command not offered to a remote caller is answered 404
POST/v1/runsStart a run ({"projectId": "…", "reportFormats": ["junit"]})
GET/v1/runsList runs
GET/v1/runs/{id}Run status, counters, diagnostics
POST/v1/runs/{id}/cancelCancel a running job
GET/v1/runs/{id}/report?format=json&#124;junit&#124;sarif&#124;htmlFetch a generated report
GET/v1/eventsServer-sent events for all topics
GET/v1/runs/{id}/eventsServer-sent events for one run
POST/v1/extensions?force=&fileName=Install a .pkg extension (binary body)
GET/v1/extensionsList installed extensions
GET/v1/simulationsSimulation servers, routes, responses, base URLs
POST/v1/simulations/startStart simulation servers ({"server": "HttpServer"} or omit for all)
POST/v1/simulations/stopStop simulation servers
POST/v1/simulations/config/import?strategy=…Import a .mockconfig.json configuration
GET/v1/simulations/responsesList imported responses
POST/v1/simulations/responsesAdd one saved response

Project ids are slash-separated paths relative to the workspace (e.g. MyProject/MyProject.aprj) because the same .aprj file name can exist in several folders.

Pushing a project​

Zip a project folder (the .aprj file plus its sibling suites, code, and embedded extension folders) and POST the archive:

cd /path/to/projects
zip -r MyProject.zip MyProject
curl -s -X POST -H "Authorization: Bearer $TOKEN" \
--data-binary @MyProject.zip \
"http://127.0.0.1:52341/v1/projects?mode=replace"

The archive must contain exactly one .aprj file. With mode=replace (default) an existing project with the same name is removed first; merge extracts over it.

Updating a project environment​

Variable values are write-only: GET returns names and whether a value is set, never the value itself. Create or update a variable:

curl -s -X PUT -H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{"project":"MyProject/MyProject.aprj","environment":"staging","name":"baseUrl","value":"https://staging.example.com"}' \
http://127.0.0.1:52341/v1/environments/variables

Omit environment to target the default environment. Password-protected (encrypted) projects cannot be edited through the daemon.

Following a run live​

curl -N -H "Authorization: Bearer $TOKEN" http://127.0.0.1:52341/v1/runs/<id>/events

Events are JSON lines over SSE: run started, suite/case completion counters, step progress, and the final result. The same feed powers GET /v1/runs/{id} snapshots.

Simulation Servers Started by Runs​

When a run executes Service Simulation - Control test steps (start/stop) or Service Simulation - Update Data steps, and the run was started by the daemon, those steps are routed to the daemon's own simulation endpoints instead of starting a competing server inside the run process. The started servers stay up after the run finishes (until you POST /v1/simulations/stop), so a pipeline can run tests against them.

aeth sim start --background is the standalone (daemon-less) equivalent for CI machines; see Simulation CLI.

See Also​