Assay.Daemon (assay v0.3.0)

View Source

JSON-RPC daemon that exposes incremental Dialyzer runs to tooling (e.g. MCP).

The daemon speaks line-delimited JSON-RPC over stdio. Each request must be a single JSON object terminated by a newline. Responses are emitted in the same format. Only a handful of methods are implemented:

  • assay/analyze — triggers an incremental run and returns diagnostics
  • assay/getStatus — reports the daemon status and last run result
  • assay/getConfig — returns the current config (including overrides)
  • assay/setConfig — applies config overrides (apps, warning apps, etc)
  • assay/shutdown — cleanly stops the daemon

Summary

Functions

Handles a decoded JSON-RPC request map and returns {reply | nil, state, action}.

Initializes daemon state. Accepts :config and :runner overrides for tests.

Starts the daemon and blocks, reading JSON-RPC requests from stdio.

Types

t()

@type t() :: %Assay.Daemon{
  base_config: Assay.Config.t(),
  config: Assay.Config.t(),
  last_result: map() | nil,
  overrides: map(),
  runner: module(),
  status: :idle | :running
}

Functions

handle_rpc(request, state)

@spec handle_rpc(map(), t()) :: {map() | nil, t(), :continue | :stop}

Handles a decoded JSON-RPC request map and returns {reply | nil, state, action}.

Useful for tests; action is either :continue or :stop.

Examples

# Analyze request
request = %{
  "jsonrpc" => "2.0",
  "id" => 1,
  "method" => "assay/analyze",
  "params" => %{"formats" => ["json"]}
}
state = Assay.Daemon.new()
{reply, new_state, action} = Assay.Daemon.handle_rpc(request, state)
# reply contains JSON-RPC response with diagnostics
# action is :continue

# Get status request
request = %{
  "jsonrpc" => "2.0",
  "id" => 2,
  "method" => "assay/getStatus"
}
{reply, new_state, action} = Assay.Daemon.handle_rpc(request, state)
# reply contains status information
# action is :continue

# Shutdown request
request = %{
  "jsonrpc" => "2.0",
  "id" => 3,
  "method" => "assay/shutdown"
}
{reply, new_state, action} = Assay.Daemon.handle_rpc(request, state)
# action is :stop

new(opts \\ [])

@spec new(keyword()) :: t()

Initializes daemon state. Accepts :config and :runner overrides for tests.

serve(opts \\ [])

@spec serve(keyword()) :: no_return()

Starts the daemon and blocks, reading JSON-RPC requests from stdio.