Back to Pi Mono

Experimental client/server service slices

packages/coding-agent/src/experimental/services/README.md

0.85.17.2 KB
Original Source

Experimental client/server service slices

Facet setup generates each host's RPC service catalogue from its provided non-local tokens. Remote service sources obtain those catalogues and bind only services required by consuming facets; there is no handwritten built-in service inventory. With no selected Session, its deferred source admits unresolved requirements as unavailable and keeps their handles disconnected. Attachment validates them against the worker's generated catalogue, which is cached for later detached generations. Keyed services hydrate as an empty directory until their owning feature spawns an instance.

ScopeServiceCurrent sliceContinuation point
serverSessionDirectoryreplicated state implementedadd authenticated per-client projection when identity lands
serverSessionManagementcreate, remove, attach, detach implementedadd authenticated workspace authorization
serverPresentationPluginsprepares the selected Session branch's matching TUI artifacts and reloads that branchadd authenticated plugin policy
sessionSessionPluginsreloads the configured Session facet generationadd coordinated multi-worker reload reporting
sessionModelsstate, default-persisting selection, thinking, refresh implementedmove provider/auth composition behind plugin facets
sessionAgentControllerpresentation-safe AgentLane facade for prompting, queueing, abort, resume, compaction, and navigationadd new lane operations only when a presentation requires them
sessionTranscriptreplicated lane state with source-event metadataadd projections only when another presentation needs them
presentationSlashCommandsprocess-local contribution registry with model, thinking, compact, reload, and example hello commandsadd more presentation hookpoints only as concrete plugin slices require them
presentationPresentationUIprocess-local selection and status capabilitiesadd narrowly scoped UI capabilities only when commands require them

ServerServiceSource.connection and SessionServiceSource.attachment are implemented local control states. Session directory, creation, and address DTOs are owned by these coding-agent service contracts rather than pi-protocol; the transport treats their payloads as opaque service data.

With PI_EXPERIMENTAL=1, an interactive pi client creates and attaches a Session before opening the service-only chat TUI. pi client -c and pi client -r attach the newest existing Session instead, preserving its durable model and thinking configuration. Model selection is available on demand through /model; it is never a startup screen. The presentation always uses the stable coding agent's alternate-screen renderer and shared transcript/dock viewport. It loads configured theme resources and uses the stable terminal light/dark detection and appearance-change notifications. Its replicated state feeds the stable editor, message, tool, status, theme, and tool-renderer components. The presentation drives the worker-owned main lane through AgentController and renders the Transcript service's complete replicated value while controller calls are pending. The provider remains the sole Harness reducer and mutates Transcript's tracked snapshot before publishing each event. Chord flushes compact operations once per publication, while each client/state pairing encodes them with an independent path dictionary. Chord reconstructs presentation replicas and owns hydration, sequencing, and gap detection.

A foreground server uses repeatable -e options to establish its default Session and TUI facets. A local client may instead select packages for the Session it creates or resumes; that branch selection is persisted with the Session and does not alter other workers or the server default. Before attaching, the server asks Chord to build conventional src/session.ts and src/tui.ts entries into separate plugin-builds/ directories, passes the generated manifest paths to that Session worker, and returns the matching TUI artifacts. The Session worker loads built-in facets and separately owned plugin generations, then creates one active FacetHost. /reload atomically rebuilds the packages, loads fresh plugin candidates, cuts them over through FacetHost.reload(), and disposes the retired generations. Host-created implementation dependencies such as AgentLane, ModelRuntime, and SettingsManager are passed directly to built-in facet factories; they are not exposed as services. The TUI loads configured presentation facets and adds one private bridge facet that consumes the connected server and selected-Session services for ExperimentalClientTui. Its local presentation services are SlashCommands, which owns command contributions, and PresentationUI, which exposes selection and status rendering without exposing the raw TUI. Command callbacks receive Chord Context directly. Facets consume AgentController explicitly for prompting, steering, or queueing and return structured controller results to the command dispatcher.

A host may reload selected facets when their declared service shape is unchanged; retained consumers keep the same service facades while replacement implementations and singleton snapshots are installed behind them. Synchronous setup-time env.provide(), env.provideMany(), env.use(), and env.observe() calls produce the internal dependency graph; setup does not repeat a declarative dependency list, and service handles remain disconnected until the complete graph validates. Providers activate before consumers, observations connect with their consuming facet, and facet replacement or host shutdown disposes affected lifecycles in reverse dependency order. Server and Session service tokens are non-local and automatically published by their providing host. Presentation-only hookpoints such as SlashCommands are explicitly local and never enter an RPC catalogue.

A facet always calls unqualified env.use() or env.observe(). The host resolves each token across facet-provided and connected services. The example plugin package contributes /hello through its TUI facet. examples/plugins/pi-example-plugin/ is an actual @earendil-works/pi-example-plugin package: repeatable -e options select plugin packages as server defaults or for one Session branch, Chord discovers and builds their conventional facets, and the attached presentation receives matching TUI artifacts through PresentationPlugins. Other host facets from the same plugin remain separate bundle entries rather than one aggregate plugin object. Transport bindings remain internal machinery rather than part of the facet environment. ExperimentalClientTui currently owns terminal rendering, state subscriptions, navigation, and action dispatch directly. The server provider remains directly assembled until its complete host environment exists. The question dialog, diff review, Git, indexing-job, canvas, and rich local TUI service examples in packages/agent/docs/plugins.md are extension patterns, not built-in coding-agent services. Private references, trace carriers, and flow control remain protocol/host infrastructure slices rather than presentation service tokens.