# `Hyper.Node.FireVMM.Agent`
[🔗](https://github.com/harmont-dev/hyper/blob/main/lib/hyper/node/fire_vmm/agent.ex#L1)

gRPC client to the in-guest agent, dialed through the per-VM relay UDS.

`relay_socket_path/1` is the single source of truth for the host-side
Unix-domain socket the relay listens on. The relay GenServer (Task 7) will
call this function to derive its own listen path, so both sides agree
without a process-registry lookup.

# `exec`

```elixir
@spec exec(Hyper.Vm.Id.t(), [String.t()], keyword()) ::
  {:ok, %{stdout: binary(), stderr: binary(), exit_code: integer()}}
  | {:error, term()}
```

Run `argv` in the guest VM identified by `vm_id` via gRPC through the relay.

Returns `{:ok, %{stdout: binary(), stderr: binary(), exit_code: integer()}}`,
or `{:error, term()}`. Error values: `:agent_unavailable` (relay unreachable —
gRPC UNAVAILABLE), `:timeout` (gRPC DEADLINE_EXCEEDED), or raw transport
errors for unexpected failures.

## Options

  - `:env` — environment map `%{String.t() => String.t()}` for the guest process
  - `:cwd` — working directory inside the guest (`nil` → not set)
  - `:timeout` — gRPC deadline in milliseconds (default: 30000)

# `relay_socket_path`

```elixir
@spec relay_socket_path(Hyper.Vm.Id.t()) :: Path.t()
```

Deterministic host-side path for the per-VM relay Unix socket.

Derived from `Hyper.Cfg.Dirs.socket_dir/0` so both this client and the
relay GenServer agree without a registry lookup.

Task 7: the relay GenServer listens here.

---

*Consult [api-reference.md](api-reference.md) for complete listing*
