# `ClaudeWrapper.DuplexSession.Adapter.Forcola`
[🔗](https://github.com/genagent/claude_wrapper_ex/blob/main/lib/claude_wrapper/duplex_session/adapter/forcola.ex#L2)

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

# `child_spec`

Returns a specification to start this module under a supervisor.

See `Supervisor`.

---

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