control

package
v0.1.0-rc.1 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Jun 21, 2026 License: MIT Imports: 12 Imported by: 0

Documentation

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

This section is empty.

Types

type Client

type Client struct {
	// contains filtered or unexported fields
}

func NewClient

func NewClient(socketPath string) *Client

func (*Client) Attach

func (c *Client) Attach(ctx context.Context, id string, req model.SessionAttachRequest) error

func (*Client) CloseSession

func (c *Client) CloseSession(ctx context.Context, id string, req model.SessionCloseRequest) error

func (*Client) CreateSession

func (c *Client) CreateSession(ctx context.Context, req model.SessionCreateRequest) (*model.Session, error)

func (*Client) Errors

func (c *Client) Errors(ctx context.Context, sessionID string) ([]model.ErrorRecord, error)

func (*Client) GetSession

func (c *Client) GetSession(ctx context.Context, id string) (*model.Session, error)

func (*Client) ListSessions

func (c *Client) ListSessions(ctx context.Context) ([]model.Session, error)

func (*Client) Requests

func (c *Client) Requests(ctx context.Context, sessionID string) ([]model.RequestRecord, error)

func (*Client) SetRoute

func (c *Client) SetRoute(ctx context.Context, id string, req model.SessionRouteRequest) error

SetRoute is retained as a test fixture for configuring a session route directly (the production launch + SwitchProfile paths publish a routing posture in-process from a *preflight.Result via supervisor.newResolved, with no SessionRouteRequest round-trip). Kept alongside the supervisor-side setRoute handler and model.SessionRouteRequest so the test suite can drive a session's posture from a literal request.

func (*Client) Shutdown

func (c *Client) Shutdown(ctx context.Context) error

func (*Client) SocketPath

func (c *Client) SocketPath() string

func (*Client) Status

func (c *Client) Status(ctx context.Context) (*model.StatusResponse, error)

func (*Client) StreamEvents

func (c *Client) StreamEvents(ctx context.Context, handler func(model.Event)) error

func (*Client) SwitchProfile

func (c *Client) SwitchProfile(ctx context.Context, sessionID, name string) (*SwitchOutcomeView, error)

SwitchProfile calls the supervisor's profile-switch control op and decodes the structured outcome into a *SwitchOutcomeView.

The endpoint is POST /v1/sessions/{id}/profile with JSON body {"name": "<requested>"}. The outcome is always structured (errors live INSIDE the outcome — never returned/logged raw across the boundary), so a non-2xx HTTP status does NOT mean SwitchProfile returned err; a transport-level failure (socket unreachable, JSON malformed) does. Callers inspect out.Result to decide what to render.

func (*Client) Trace

func (c *Client) Trace(ctx context.Context, sessionID string) ([]model.TraceRecord, error)

type ProfileCatalogResponse

type ProfileCatalogResponse struct {
	HasProfilesFile bool              `json:"has_profiles_file"`
	Default         string            `json:"default,omitempty"`
	ActiveProfile   string            `json:"active_profile,omitempty"`
	Items           []SafeCatalogItem `json:"items"`
	Source          string            `json:"source,omitempty"`
	LoadError       string            `json:"load_error,omitempty"`
	// EnvBaseURLHost is the host[:port] of ANTHROPIC_BASE_URL as
	// captured in the supervisor's snapshotted parent env at launch
	// (lookupEnv over LaunchContext.Options.ParentEnv). Empty when the
	// env var is unset or its value is malformed. The popover renders
	// it next to the inherit-env row so the user can see what inherit-
	// env mode would actually route to — and detect drift between the
	// frozen active profile's BaseURL and the live env.
	EnvBaseURLHost string `json:"env_base_url_host,omitempty"`
	// EnvHasCredentials reports whether the launch-time parent env has
	// either ANTHROPIC_API_KEY or ANTHROPIC_AUTH_TOKEN set (non-empty
	// after trim). The popover uses this to decide whether the
	// inherit-env row's [test] button is meaningful: in OAuth-mode
	// claude-code sessions, both env vars are empty (OAuth tokens
	// live in the keychain, not env), so a probe would always fail
	// with "credentials missing" and the button is misleading.
	EnvHasCredentials bool `json:"env_has_credentials"`
}

ProfileCatalogResponse is the wire shape for GET /profile/catalog. Items is empty array (not null) when no profiles file or when profiles map is empty; HasProfilesFile distinguishes the two. LoadError carries a sanitized message when profiles.json could not be loaded (malformed / IO error); the endpoint still returns HTTP 200 so the UI can distinguish "load failed (here's why)" from "network down".

type RouteError

type RouteError struct {
	Code    string `json:"reason_code"`
	Message string `json:"message"`
}

RouteError is the typed 409 response from /route control operations. A post-attach SetRoute is refused with this typed body so callers can programmatically detect the refusal (via errors.As) without parsing free-form error messages.

Wire format on the control socket (HTTP 409 Conflict):

{"reason_code": "RouteSetupAfterAttach", "message": "<sanitized>"}

func (*RouteError) Error

func (e *RouteError) Error() string

Error implements the error interface. The format keeps Code first (the programmatic key) and folds Message in when present. Stable enough for log lines; callers MUST use errors.As when they need the typed Code.

type SafeAuthSpec

type SafeAuthSpec struct {
	Mode         string `json:"mode"`
	HasInlineKey bool   `json:"has_inline_key,omitempty"`
	HasKeyEnv    bool   `json:"has_key_env,omitempty"`
}

SafeAuthSpec mirrors profiles.SafeAuthSpec. nil means "ccwrap does not own auth"; non-nil carries Mode + boolean presence flags only (no key bytes, no env NAME).

type SafeCatalogItem

type SafeCatalogItem struct {
	Name                string            `json:"name"`
	Provider            string            `json:"provider"`
	BaseURLHost         string            `json:"base_url_host"`
	BaseURL             string            `json:"base_url,omitempty"`
	Auth                *SafeAuthSpec     `json:"auth,omitempty"`
	ModelAliasCount     int               `json:"model_alias_count,omitempty"`
	ModelAliases        map[string]string `json:"model_aliases,omitempty"`
	UpstreamHeaderCount int               `json:"upstream_header_count,omitempty"`
	EgressMode          string            `json:"egress_mode"`
	EgressHost          string            `json:"egress_host,omitempty"`
	EgressURL           string            `json:"egress_url,omitempty"`
}

SafeCatalogItem is the wire mirror of profiles.SafeCatalogItem. Same JSON tag set; the supervisor converts via a direct struct conversion. Keeping the type here preserves the layering (control depends on no internal package).

type SwitchOutcomeView

type SwitchOutcomeView struct {
	Result     string          `json:"result"`
	Class      string          `json:"class,omitempty"`
	View       json.RawMessage `json:"view,omitempty"`
	ReasonCode string          `json:"reason_code,omitempty"`
	Message    string          `json:"message,omitempty"`
}

SwitchOutcomeView is the wire-mirror of supervisor.SwitchOutcome. It lives in internal/control because the SwitchProfile client method returns it; internal/supervisor cannot be imported here (the dependency goes the OTHER way — supervisor is a server, control is a wire/client library that callers compose against). The supervisor serializes its own SwitchOutcome as JSON; this struct decodes that JSON.

View is intentionally an opaque json.RawMessage so the CLI / UI can decode it further on demand without internal/control needing to import internal/preflight (which would create a cyclic dep via Result types). The JSON shape for View matches preflight.ProfileView's tagged fields verbatim.

The string fields (Result, Class, ReasonCode) carry typed enum values from the supervisor (SwitchResult, model.RelaunchClass); they're kept as plain strings here so the CLI can compare with string literals or with the constants below without further marshalling.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL