# `Agentic.Protocol.ACP.Client`

JSON-RPC 2.0 client over stdio for ACP communication.

Manages bidirectional communication with an ACP agent subprocess.
Handles request/response correlation, notification delivery, and
incoming requests from the agent (e.g. permission requests).

## Architecture

A listener process reads from the subprocess stdout and routes:
- Responses (has "id") to waiting callers via `:persistent_term`
- Notifications (no "id") to the registered notification handler
- Incoming requests (has "id" and "method" from agent) to request handler

## Usage

    {:ok, client} = Agentic.Protocol.ACP.Client.start_link(
      command: "kimi",
      args: ["acp"],
      env: %{}
    )

    {:ok, result} = Agentic.Protocol.ACP.Client.request(client, "initialize", params)
    Agentic.Protocol.ACP.Client.notify(client, "session/cancel", %{sessionId: "..."})
    Agentic.Protocol.ACP.Client.stop(client)

# `client`

```elixir
@type client() :: pid()
```

# `request_opts`

```elixir
@type request_opts() :: [{:timeout, non_neg_integer()}]
```

# `child_spec`

Returns a specification to start this module under a supervisor.

See `Supervisor`.

# `command`

```elixir
@spec command(client()) :: String.t()
```

Get the command that was used to start this client.

# `get_prompt_state`

```elixir
@spec get_prompt_state(client()) :: {String.t(), [map()]}
```

Get the current prompt accumulator text and updates list.

# `notify`

```elixir
@spec notify(client(), String.t(), map()) :: :ok
```

Send a JSON-RPC notification (no response expected).

# `request`

```elixir
@spec request(client(), String.t(), map(), request_opts()) ::
  {:ok, map()} | {:error, term()}
```

Send a JSON-RPC request and wait for the response.

# `reset_prompt_state`

```elixir
@spec reset_prompt_state(client()) :: :ok
```

Reset the prompt accumulator and updates list.

# `start_link`

```elixir
@spec start_link(keyword()) :: GenServer.on_start()
```

Start an ACP client that communicates with a subprocess.

## Options

  - `:command` - CLI binary path (required)
  - `:args` - List of arguments
  - `:env` - Extra environment variables (map)
  - `:notification_handler` - Function called with `(method, params)` for notifications
  - `:request_handler` - Function called with `(id, method, params)` for incoming requests, must return response

# `stop`

```elixir
@spec stop(client()) :: :ok
```

Gracefully stop the client and terminate the subprocess.

---

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