CliSubprocessCore.ProviderProfile defines the contract every first-party
built-in or external provider CLI profile must implement.
Behaviour Surface
@callback id() :: atom()
@callback capabilities() :: [atom()]
@callback build_invocation(keyword()) ::
{:ok, CliSubprocessCore.Command.t()} | {:error, term()}
@callback init_parser_state(keyword()) :: term()
@callback decode_stdout(binary(), term()) ::
{[CliSubprocessCore.Event.t()], term()}
@callback decode_stderr(binary(), term()) ::
{[CliSubprocessCore.Event.t()], term()}
@callback handle_exit(term(), term()) ::
{[CliSubprocessCore.Event.t()], term()}
@callback transport_options(keyword()) :: keyword()Responsibilities
Each profile owns:
- the normalized provider id
- the capability list exposed to downstream consumers
- CLI command construction for that provider across both
CliSubprocessCore.Command.run/1andCliSubprocessCore.Session - stdout parsing into normalized core events
- stderr parsing into normalized core events
- exit handling into normalized terminal events
- transport option overrides needed by the provider CLI
The foundation explicitly keeps those responsibilities out of downstream repos.
Validation Helpers
The behaviour module provides two helper functions:
CliSubprocessCore.ProviderProfile.ensure_module/1CliSubprocessCore.ProviderProfile.validate_invocation/1
ensure_module/1 verifies that a module is loaded, declares the behaviour, and
exports the required callbacks.
validate_invocation/1 verifies that the profile returned a valid
CliSubprocessCore.Command struct.
That same invocation contract is reused by both:
CliSubprocessCore.Command.run/1for one-shot non-PTY executionCliSubprocessCore.Session.start_session/1for long-lived normalized sessions
Registry Integration
CliSubprocessCore.ProviderRegistry stores provider profile modules by id.
External preloads are supported at application boot:
config :cli_subprocess_core,
built_in_profile_modules: [
MyApp.ProviderProfiles.Example
]That preload hook only affects the default registry boot list. It does not make
the external profile a first-party built-in shipped by
cli_subprocess_core.
Ad hoc registrations can also be added at runtime:
:ok =
CliSubprocessCore.ProviderRegistry.register(
MyApp.ProviderProfiles.Example
)Design Constraints
Provider profiles should emit only CliSubprocessCore.Event values containing
CliSubprocessCore.Payload.* structs. They should not invent competing
normalized payload families in downstream repos.
For a step-by-step implementation guide, see
guides/custom-provider-profiles.md.