client

package
v0.0.0-...-13f862e Latest Latest
Warning

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

Go to latest
Published: May 22, 2026 License: MIT Imports: 15 Imported by: 0

Documentation

Overview

Package client is the typed Go HTTP client for the gemba server API (gm-o9t8.1.1.4).

The low-level surface (one method per OpenAPI operationId) is generated by oapi-codegen from the spec the server itself serves at /api/openapi.json (source: internal/server/openapi/openapi.json). The generated code lives in the `gen` subpackage and MUST NOT be edited by hand; run `go generate ./internal/client/...` to refresh it after the spec changes.

On top of the generated client, this package adds three concerns the raw codegen output doesn't cover:

  1. Auth header injection. New() consults the credstore (internal/auth/credstore) for the requested server URL and attaches `Authorization: Bearer <token>` to every outbound call. Callers may override the token explicitly with WithToken.

  2. X-GEMBA-Confirm nonce. State-mutating verbs (POST/PATCH/DELETE) on the Govern surface require a one-shot UUID nonce; the wrapper generates one per request so callers never have to think about it. GET / HEAD / OPTIONS calls do NOT get the header so they stay cacheable.

  3. Error envelope mapping. The server returns a stable JSON envelope (`{"error":"...","message":"..."}` per the OpenAPI `Error` component) for 4xx / 5xx responses. errors.go parses this and surfaces typed sentinels (ErrUnauthorized, ErrNotFound, ErrConflict, ErrNotImplemented, ErrBadRequest) plus a generic `*ServerError` for everything else.

Index

Constants

View Source
const DefaultUserAgent = "gemba-cli/dev"

DefaultUserAgent is sent on every request unless overridden with WithUserAgent. The version segment is bumped by the build pipeline.

Variables

View Source
var (
	ErrUnauthorized   = errors.New("unauthorized")
	ErrNotFound       = errors.New("not found")
	ErrConflict       = errors.New("conflict")
	ErrNotImplemented = errors.New("not implemented")
	ErrBadRequest     = errors.New("bad request")
)

Sentinel errors callers can compare with errors.Is.

Functions

This section is empty.

Types

type CascadeDispatchError

type CascadeDispatchError struct {
	WorkItemID string `json:"work_item_id"`
	Message    string `json:"message"`
}

CascadeDispatchError is one entry in the Errors slice.

type CascadeDispatchInput

type CascadeDispatchInput struct {
	AgentType string `json:"agent_type,omitempty"`
	Limit     int    `json:"limit,omitempty"`
}

CascadeDispatchInput is the optional body POSTed to /api/work-items/{id}/cascade-dispatch. Fields default to "no override" when zero.

type CascadeDispatchResponse

type CascadeDispatchResponse struct {
	WrapperID  string                  `json:"wrapper_id"`
	Dispatched []CascadeDispatchedItem `json:"dispatched"`
	Blocked    []string                `json:"blocked,omitempty"`
	Skipped    []string                `json:"skipped,omitempty"`
	Errors     []CascadeDispatchError  `json:"errors,omitempty"`
}

CascadeDispatchResponse mirrors the subset of the server's cascadeDispatchResponse envelope that the CLI consumes (gm-o9t8.1.5.5). Decoupled from the server-side type so the wire client stays independent of internal/server.

type CascadeDispatchedItem

type CascadeDispatchedItem struct {
	WorkItemID string `json:"work_item_id"`
	SessionID  string `json:"session_id,omitempty"`
}

CascadeDispatchedItem is one entry in the Dispatched slice.

type Client

type Client struct {
	*gen.ClientWithResponses
	// contains filtered or unexported fields
}

Client is the gemba typed HTTP client. The embedded *gen.ClientWithResponses gives callers direct access to every generated operation (GetWhoamiWithResponse, ListSpecsWithResponse, ReconcileSpecWithResponse, …). Wrapper-level methods provide envelope-mapped, typed convenience shortcuts.

func New

func New(server string, opts ...Option) (*Client, error)

New constructs a Client bound to server. The credstore is consulted for a stored token unless WithToken supplies one explicitly.

Returns an error when:

  • server is empty;
  • the credstore can't be loaded;
  • no credential exists for server AND WithToken was not supplied.

func (*Client) CascadeDispatchWorkItem

func (c *Client) CascadeDispatchWorkItem(ctx context.Context, id string, in CascadeDispatchInput) (*CascadeDispatchResponse, error)

CascadeDispatchWorkItem POSTs to /api/work-items/{id}/cascade-dispatch and decodes the wrapper response. The wrapper_id is the cascade run id (used by `gemba logs -f <run_id>`). X-GEMBA-Confirm is auto-injected by the wrapper's request editors.

func (*Client) CreateWorkItem

func (c *Client) CreateWorkItem(ctx context.Context, in CreateWorkItemInput) (*core.WorkItem, error)

CreateWorkItem POSTs a new work item and returns the materialized core.WorkItem. Body is wrapped in `{"item": {...}}` per transport.DecodeCreateWorkItem.

func (*Client) Do

func (c *Client) Do(req *http.Request) (*http.Response, error)

Do satisfies gen.HttpRequestDoer so we can delegate to the real *http.Client while keeping a hook point for future request-level instrumentation (metrics, retries, …).

func (*Client) GetWorkItem

func (c *Client) GetWorkItem(ctx context.Context, id string) (*core.WorkItem, error)

GetWorkItem fetches a single work item by id.

func (*Client) ListWorkItems

func (c *Client) ListWorkItems(ctx context.Context, f ListWorkItemsFilter) ([]core.WorkItem, error)

ListWorkItems is a typed wrapper over GET /api/work-items.

func (*Client) ListWorkItemsByStatus

func (c *Client) ListWorkItemsByStatus(ctx context.Context, status string) ([]core.WorkItem, error)

ListWorkItemsByStatus is a convenience wrapper over ListWorkItems that filters by a single status. Used by the dashboard's fallback path when the primary status endpoint returns 501.

func (*Client) NoteWorkItem

func (c *Client) NoteWorkItem(ctx context.Context, id, note string) error

NoteWorkItem appends a free-form operator note to a work item.

Backed by POST /api/work-items/{id}/notes which is currently a 501 stub (added in gm-o9t8.1.3.2 alongside this client). The CLI wires the verb so the surface is discoverable; the server-side semantics land in a follow-up bead.

func (*Client) PatchWorkItem

func (c *Client) PatchWorkItem(ctx context.Context, id string, patch core.WorkItemPatch) (*core.WorkItem, error)

PatchWorkItem PATCHes a work item with the supplied core.WorkItemPatch.

func (*Client) Whoami

func (c *Client) Whoami(ctx context.Context) (*gen.WhoamiResponse, error)

Whoami is a convenience that calls the generated GetWhoami operation and returns the typed WhoamiResponse on success, or a mapped error (see errors.go) on failure.

func (*Client) WorkItemEvents

func (c *Client) WorkItemEvents(ctx context.Context, runID, lastEventID string) (io.ReadCloser, error)

WorkItemEvents opens GET <server>/events?work_item_id=<runID> as an SSE stream and returns the response body for the caller to parse.

When lastEventID is non-empty it is sent as the Last-Event-ID header so the server can replay missed frames on reconnect. Bearer auth and User-Agent are injected via the wrapper's request editors. Confirm header injection is a no-op for GET.

On non-2xx the body is read for the error envelope and a typed sentinel (e.g. ErrUnauthorized, ErrNotFound) is returned via mapErr. On 2xx the caller owns Close() on the returned ReadCloser.

func (*Client) WorkspaceStatus

func (c *Client) WorkspaceStatus(ctx context.Context, wsid string) (*WorkspaceStatusResponse, error)

WorkspaceStatus GETs /api/v1/workspaces/{wsid}/status. Pass "_" as wsid to ask the server to resolve the active workspace for the authenticated user.

Sentinels mapped via mapErr: ErrUnauthorized (401), ErrNotFound (404), ErrNotImplemented (501). Other 4xx/5xx return *ServerError.

type CreateWorkItemInput

type CreateWorkItemInput struct {
	Title         string   `json:"title"`
	Kind          string   `json:"kind"`
	Status        string   `json:"status"`
	StateCategory string   `json:"state_category"`
	Description   string   `json:"description,omitempty"`
	Labels        []string `json:"labels,omitempty"`
	Priority      int      `json:"priority,omitempty"`
	ParentID      string   `json:"parent_id,omitempty"`
}

CreateWorkItemInput is the boundary shape the server accepts on POST /api/work-items. Mirrors transport.CreateWorkItemRequest with a slim, hand-curated subset of WorkItem fields that operator-facing CLI users actually set on create.

type EmbeddedDoltStatus

type EmbeddedDoltStatus struct {
	Enabled      bool   `json:"enabled"`
	State        string `json:"state"`
	Port         int    `json:"port"`
	DataDir      string `json:"data_dir"`
	RestartCount int64  `json:"restart_count"`
	LastError    string `json:"last_error,omitempty"`
}

EmbeddedDoltStatus mirrors the supervisor stripe in the status response (gm-o9t8.1.9). Populated when the server has --embedded-dolt enabled; null/omitted when using an external Dolt via --dolt-url.

type ListWorkItemsFilter

type ListWorkItemsFilter struct {
	Status string
	Limit  int
}

ListWorkItemsFilter is the typed filter struct for ListWorkItems. Fields default to "no filter" when zero.

type Option

type Option func(*options)

Option configures New. Options are applied in order; later options win for fields they overlap on.

func WithCredentialsPath

func WithCredentialsPath(path string) Option

WithCredentialsPath overrides the credstore file path. Mostly useful in tests; production callers should rely on the credstore default.

func WithHTTPClient

func WithHTTPClient(c *http.Client) Option

WithHTTPClient swaps the underlying *http.Client. Default has a 30 s timeout; pass a configured client for proxy / mTLS scenarios.

func WithToken

func WithToken(tok string) Option

WithToken overrides the token the wrapper would otherwise read from the credstore. Useful when a caller already holds a PAT (e.g. the `gemba login` command, which has no credstore entry yet).

func WithUserAgent

func WithUserAgent(ua string) Option

WithUserAgent overrides the default User-Agent string.

type ServerError

type ServerError struct {
	Code    string
	Message string
	Status  int
}

ServerError carries the server's stable error code, the human-readable message, and the HTTP status for callers that need more than a sentinel.

func (*ServerError) Error

func (e *ServerError) Error() string

type WorkspaceAgentStatus

type WorkspaceAgentStatus struct {
	Active         int    `json:"active"`
	LastRunID      string `json:"last_run_id,omitempty"`
	LastRunStatus  string `json:"last_run_status,omitempty"`
	LastRunSummary string `json:"last_run_summary,omitempty"`
}

WorkspaceAgentStatus mirrors the agents stripe.

type WorkspaceBeadCounts

type WorkspaceBeadCounts struct {
	Ready       int `json:"ready"`
	InFlight    int `json:"in_flight"`
	Blocked     int `json:"blocked"`
	OpenTotal   int `json:"open_total"`
	ClosedToday int `json:"closed_today"`
}

WorkspaceBeadCounts mirrors the bead counts the dashboard renders.

type WorkspaceRepoStatus

type WorkspaceRepoStatus struct {
	Head   string `json:"head"`
	Dirty  bool   `json:"dirty"`
	Branch string `json:"branch"`
}

WorkspaceRepoStatus mirrors the server's repo stripe.

type WorkspaceStatusResponse

type WorkspaceStatusResponse struct {
	WorkspaceID  string                `json:"workspace_id"`
	Mode         string                `json:"mode"`
	Repo         *WorkspaceRepoStatus  `json:"repo"`
	Beads        WorkspaceBeadCounts   `json:"beads"`
	Agents       *WorkspaceAgentStatus `json:"agents"`
	EmbeddedDolt *EmbeddedDoltStatus   `json:"embedded_dolt,omitempty"`
}

WorkspaceStatusResponse is the unified envelope the workspace status endpoint returns on 200. Field-for-field mirror of internal/server.WorkspaceStatusResponse; kept here so the client package stays independent of the server package.

Directories

Path Synopsis
Package gen provides primitives to interact with the openapi HTTP API.
Package gen provides primitives to interact with the openapi HTTP API.

Jump to

Keyboard shortcuts

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