# Session API
`CliSubprocessCore.Session` is the normalized long-lived provider session
runtime.
It adds provider command construction, stdout/stderr decoding, normalized event
sequencing, and subscriber fanout above the shared transport substrate.
## Start A Session
```elixir
ref = make_ref()
{:ok, session, info} =
CliSubprocessCore.Session.start_session(
provider: :claude,
prompt: "Explain the latest failing test",
subscriber: {self(), ref}
)
```
## Session Delivery
Tagged subscribers receive:
- `{session_event_tag, ref, {:event, %CliSubprocessCore.Event{}}}`
Use `CliSubprocessCore.Session.extract_event/2` instead of hard-coding the
outer mailbox shape.
## Transport Snapshot
`Session.info/1` exposes transport data through a sanitized public snapshot:
- `info.transport.info` is recognized by `TransportInfo`
- `info.transport.info` omits lower runtime handles such as BEAM pids, OS
pids, ports, and transport modules
- `info.transport.status` reflects the normalized transport status
That keeps the core session API stable while the local session-bearing lane now
runs on the Execution Plane-owned process transport seam.
## Placement
Pass `execution_surface` when the provider session should run somewhere other
than the default local subprocess:
```elixir
{:ok, session, info} =
CliSubprocessCore.Session.start_session(
provider: :antigravity,
prompt: "Hello from SSH",
execution_surface: [
surface_kind: :ssh_exec,
transport_options: [destination: "buildbox.example"]
]
)
```
## Lifecycle Calls
The core session API exposes:
- `send/2`
- `send_input/3`
- `end_input/1`
- `interrupt/1`
- `close/1`
- `subscribe/2`
- `subscribe/3`
- `unsubscribe/2`
- `info/1`
These calls delegate to the transport substrate but keep provider-facing
semantics and event normalization in the core.