cli_subprocess_core is the provider-facing runtime layer above the lower
execution substrate.
Use it when you want normalized provider commands, sessions, payloads, and events instead of working directly with the raw transport substrate.
For the covered runtime slice, provider-aware local one-shot commands route
through ExecutionPlane.Process.run/2, while raw sessions and non-local
surfaces route through ExecutionPlane.Process.Transport.
Install
def deps do
[
{:cli_subprocess_core, "~> 0.2.0"}
]
endChoose The Right API
Use:
CliSubprocessCore.Commandfor provider-aware one-shot executionCliSubprocessCore.RawSessionfor long-lived raw subprocess ownershipCliSubprocessCore.Sessionfor normalized provider eventsCliSubprocessCore.ChannelorCliSubprocessCore.ProtocolSessionfor framed or protocol-driven sessions
One-Shot Commands
{:ok, result} =
CliSubprocessCore.Command.run(
provider: :claude,
prompt: "Summarize the latest changes"
)The result type is CliSubprocessCore.Command.RunResult. For
surface_kind: :local_subprocess, the core emits ProcessExecutionIntent.v1
and delegates the lower one-shot hop to execution_plane before projecting the
outcome back into the core-owned command shape.
Raw Sessions
{:ok, session} =
CliSubprocessCore.RawSession.start("sh", ["-c", "cat"], stdin?: true)
:ok = CliSubprocessCore.RawSession.send_input(session, "alpha")
:ok = CliSubprocessCore.RawSession.close_input(session)
{:ok, result} = CliSubprocessCore.RawSession.collect(session, 5_000)RawSession is the lowest public CLI-owned layer. For the covered local
session-bearing lane it uses ExecutionPlane.Process.Transport underneath
while keeping the public placement seam generic. The same transport seam also
handles non-local placement through execution_surface.
Normalized Sessions
ref = make_ref()
{:ok, session, info} =
CliSubprocessCore.Session.start_session(
provider: :codex,
prompt: "Review this change",
subscriber: {self(), ref}
)
IO.inspect(info.transport.info.surface_kind)Execution Surface
Placement stays on one execution_surface contract:
execution_surface = [
surface_kind: :ssh_exec,
transport_options: [
destination: "buildbox.example",
ssh_user: "deploy"
],
target_id: "buildbox-1",
boundary_class: :remote
]Pass that value through Command.run/1, Command.run/2,
RawSession.start/2, or Session.start_session/1.
When Command.run/1,2 receives surface_kind: :local_subprocess, the covered
minimal one-shot lane runs through execution_plane. RawSession,
Channel, and Session now use the Execution Plane-backed local session lane
for :local_subprocess as well. Non-local surfaces also resolve through the
same Execution Plane-backed transport seam.
Supported landed surface kinds are:
:local_subprocess:ssh_exec:guest_bridge