ClaudeWrapper.DuplexSession.Adapter.Forcola (ClaudeWrapper v0.13.0)

Copy Markdown View Source

Leak-free ClaudeWrapper.DuplexSession transport backed by Forcola.Duplex.

Holds the long-lived claude subprocess in its own process group; on session close, owner death, or BEAM death the whole group is killed (SIGTERM then SIGKILL), reaping claude and every stdio MCP server it spawned. The default ClaudeWrapper.DuplexSession.Adapter.Port closes the port instead, which sends no signal (see #185).

This module compiles only when forcola is a dependency. Select it per session with adapter: ClaudeWrapper.DuplexSession.Adapter.Forcola, or globally with config :claude_wrapper, duplex_adapter: ClaudeWrapper.DuplexSession.Adapter.Forcola. forcola is POSIX-only.

How it fits the adapter seam

A small translator GenServer owns the Forcola.Duplex session and forwards its owner messages into the three shapes ClaudeWrapper.DuplexSession.Adapter delivers. The translator's pid is the transport handle, so the session's %{port: handle} match works unchanged:

  • {:forcola_line, _, line} -> {handle, {:data, line <> "\n"}} (forcola strips the trailing newline; the session's buffer splits on it, so it is re-added)
  • {:forcola_exit, _, status} -> {handle, {:exit_status, code}}, then the translator stops and its linked {:EXIT, handle, reason} reaches the session
  • {:forcola_stderr, _, _} is dropped, matching the Port adapter which does not fold stderr into the NDJSON stream

Summary

Functions

Returns a specification to start this module under a supervisor.

Functions

child_spec(init_arg)

Returns a specification to start this module under a supervisor.

See Supervisor.