Documentation
¶
Overview ¶
Package client provides an HTTP client for the BuildMax server API.
Index ¶
- Constants
- Variables
- func NewArtifactPublisher(serverURL, spaceID string, token TokenFunc) tool.ArtifactPublisher
- func NewIssueClient(serverURL, spaceID, issueID string, token TokenFunc) tool.IssueClient
- type AdminAccount
- type AssignedIssue
- type Client
- func (c *Client) DownloadRelease(ctx context.Context, token, name, version string, allowYanked bool, ...) (string, error)
- func (c *Client) FindAccountByEmail(ctx context.Context, token, email string) (*AdminAccount, error)
- func (c *Client) FindIssue(ctx context.Context, token, issueID string) (corespace.Space, coreissue.Issue, error)
- func (c *Client) GetPlugin(ctx context.Context, token, name string) (*pluginwire.PluginResponse, error)
- func (c *Client) GrantSystemRole(ctx context.Context, token, userID, role string) (*SystemGrant, error)
- func (c *Client) IssueThread(ctx context.Context, token, spaceID, issueID string) ([]coreissue.Issue, []coreissue.Comment, int, error)
- func (c *Client) ListAssignedIssues(ctx context.Context, token, status string, limit int) ([]AssignedIssue, []error)
- func (c *Client) ListPlugins(ctx context.Context, token string) ([]coreplugin.Plugin, error)
- func (c *Client) ListServerModels(ctx context.Context, token string) ([]llmwire.Model, error)
- func (c *Client) ListSpaceActivations(ctx context.Context, token, spaceID string) (*pluginwire.ActivationsResponse, error)
- func (c *Client) ListSpaces(ctx context.Context, token string) ([]corespace.Space, error)
- func (c *Client) ListSystemGrants(ctx context.Context, token string, includeRevoked bool) ([]SystemGrant, error)
- func (c *Client) Login(ctx context.Context, email, otp, platform string) (*LoginResponse, error)
- func (c *Client) LoginWithPassword(ctx context.Context, email, password, platform string) (*LoginResponse, error)
- func (c *Client) Logout(ctx context.Context, refreshToken, accessToken string) error
- func (c *Client) PublishRelease(ctx context.Context, token, name string, body io.Reader, ...) (*coreplugin.Release, error)
- func (c *Client) Refresh(ctx context.Context, refreshToken string) (*RefreshResponse, error)
- func (c *Client) RequestOTP(ctx context.Context, email, intent string) error
- func (c *Client) RevokeSystemRole(ctx context.Context, token, userID, role string) error
- func (c *Client) SetIssueStatus(ctx context.Context, token, spaceID, issueID, status string, version uint64) (coreissue.Issue, error)
- func (c *Client) SetPluginArchived(ctx context.Context, token, name string, archived bool) error
- func (c *Client) YankRelease(ctx context.Context, token, name, version, reason string) error
- type LoginResponse
- type LoginUser
- type RefreshResponse
- type SystemGrant
- type TokenFunc
Constants ¶
const DefaultServerURL = "http://localhost:5678"
DefaultServerURL is where a client looks when nobody has named a server: the address buildmax-server listens on when it runs on this machine. It is the last fallback, not an assumption — settings.yaml's server_url wins, and a deployment behind an ingress publishes one origin for Portal and API that is not this one.
Variables ¶
var ErrRefreshRejected = errors.New("refresh token rejected")
ErrRefreshRejected means the server refused the refresh token: it is spent, revoked, expired, or was replayed. The session is over and only a new login will produce another.
Functions ¶
func NewArtifactPublisher ¶
func NewArtifactPublisher(serverURL, spaceID string, token TokenFunc) tool.ArtifactPublisher
NewArtifactPublisher returns a publisher, or nil when this surface has no server to reach. Returning nil is what leaves the tool unregistered.
func NewIssueClient ¶
func NewIssueClient(serverURL, spaceID, issueID string, token TokenFunc) tool.IssueClient
NewIssueClient scopes a local session to one Issue on one server.
The Issue and the space are fixed here, not passed per call, for the reason the worker client has no issue parameter either: a model that can name an Issue turns every instruction hidden in a comment thread into a working verb. See docs/design/issue-agent-access.md section 5.3.
Returns nil when anything needed is missing, so the caller registers no tools rather than tools that fail on every call.
Types ¶
type AdminAccount ¶
type AdminAccount struct {
ID string `json:"id"`
Email string `json:"email"`
DisabledAt *time.Time `json:"disabled_at,omitempty"`
}
AdminAccount is one account as the admin user list returns it. Only the fields the CLI needs — to resolve an email to an id and show whether the account is disabled — are kept.
type AssignedIssue ¶
AssignedIssue is one item of the caller's inbox, with the space it belongs to kept alongside it.
The space travels with the issue because a local surface has no current space: a login names a server and a person, and that person's work is spread across every space they are in. Anything the caller does next with this issue needs the space back.
type Client ¶
Client is a stateless HTTP client for the BuildMax server API.
func (*Client) DownloadRelease ¶
func (c *Client) DownloadRelease(ctx context.Context, token, name, version string, allowYanked bool, w io.Writer) (string, error)
DownloadRelease streams one release's bytes into w and returns the digest the server sent with them.
The bytes are copied straight through rather than collected: a package is bounded, but bounded at tens of megabytes, and the caller is writing to a staging file anyway.
func (*Client) FindAccountByEmail ¶
func (c *Client) FindAccountByEmail(ctx context.Context, token, email string) (*AdminAccount, error)
FindAccountByEmail resolves an email to exactly one account through the admin user search. It refuses when the search matches no account or more than one, so a caller never hands authority to a guess. The search is a substring match server-side, so this narrows it to an exact, case-insensitive address.
func (*Client) FindIssue ¶
func (c *Client) FindIssue(ctx context.Context, token, issueID string) (corespace.Space, coreissue.Issue, error)
FindIssue reports which of the caller's spaces holds an issue, and the issue.
One request per space until one answers, because the server addresses an issue through its space and there is no route that resolves a bare issue id. Adding one would let anyone probe whether an id exists in a space they cannot see, which is a worse trade than a handful of requests a person makes once when starting work.
The issue comes back with the space because every caller needs it next: to print it, to say what a session is working on, or to read the version an update has to carry.
func (*Client) GetPlugin ¶
func (c *Client) GetPlugin(ctx context.Context, token, name string) (*pluginwire.PluginResponse, error)
GetPlugin returns one entry and every release published under it, withdrawn ones included and marked.
func (*Client) GrantSystemRole ¶
func (c *Client) GrantSystemRole(ctx context.Context, token, userID, role string) (*SystemGrant, error)
GrantSystemRole grants role to the account with userID and returns the grant. An empty role lets the server apply its default (system_admin).
func (*Client) IssueThread ¶
func (c *Client) IssueThread(ctx context.Context, token, spaceID, issueID string) ([]coreissue.Issue, []coreissue.Comment, int, error)
IssueThread reads an issue's children and recent comments for a person to look at. Same window as the agent gets, for the same reason.
func (*Client) ListAssignedIssues ¶
func (c *Client) ListAssignedIssues(ctx context.Context, token, status string, limit int) ([]AssignedIssue, []error)
ListAssignedIssues returns what the caller has been assigned, across every space they belong to.
One request per space, because the server has no cross-space listing and inventing one would put a route that reads every space a person is in behind a question only this inbox asks. A person's spaces are few; if that stops being true, the fix is a route, not a wider fan-out here.
A space that fails is skipped rather than failing the inbox: an inbox missing one space's work is more useful than no inbox, and the caller is told which space could not be read.
func (*Client) ListPlugins ¶
ListPlugins returns the deployment's browsable catalog.
func (*Client) ListServerModels ¶
ListServerModels calls GET /api/llm/models and returns the models this deployment offers through the managed gateway. Being signed in is the whole authorization: every catalog model is available to every user.
The reply names models only. Which provider serves one, and with whose credential, stays on the server.
func (*Client) ListSpaceActivations ¶
func (c *Client) ListSpaceActivations(ctx context.Context, token, spaceID string) (*pluginwire.ActivationsResponse, error)
ListSpaceActivations returns what a space has activated for its background runs, and who fills that list.
It is a read only. Changing an activation stays in Portal, where the audit trail and the space's other shared automation already are; what this serves is somebody debugging a run who wants the answer without a browser.
func (*Client) ListSpaces ¶
ListSpaces returns the spaces the caller belongs to.
func (*Client) ListSystemGrants ¶
func (c *Client) ListSystemGrants(ctx context.Context, token string, includeRevoked bool) ([]SystemGrant, error)
ListSystemGrants returns the deployment's system grants, newest first. includeRevoked adds the retired ones, which is how the trail of who held authority is read.
func (*Client) Login ¶
Login calls POST /api/login with a single-use login code — the recovery path, used to claim a new account or replace a forgotten password. platform identifies the calling client ("cli", "desktop", "portal").
func (*Client) LoginWithPassword ¶
func (c *Client) LoginWithPassword(ctx context.Context, email, password, platform string) (*LoginResponse, error)
LoginWithPassword calls POST /api/login with a password, the everyday way in.
func (*Client) PublishRelease ¶
func (c *Client) PublishRelease( ctx context.Context, token, name string, body io.Reader, source coreplugin.ReleaseSource, ) (*coreplugin.Release, error)
PublishRelease uploads one package.
The body is the archive itself, streamed from the reader, and the claim about where it came from travels beside it. The server hashes and inspects what it receives, so nothing here is trusted on the far side.
func (*Client) Refresh ¶
Refresh calls POST /api/token/refresh, exchanging a refresh token for a new pair.
A rejected token returns ErrRefreshRejected, which the caller must be able to tell apart from the server being unreachable: one means sign in again, the other means try later.
func (*Client) RequestOTP ¶
RequestOTP calls POST /api/otp/request. intent is "login" or "signup".
func (*Client) RevokeSystemRole ¶
RevokeSystemRole revokes role from the account with userID. An empty role lets the server apply its default (system_admin). Revoking the last holder is refused by the server; the error carries the recovery command.
func (*Client) SetIssueStatus ¶
func (c *Client) SetIssueStatus(ctx context.Context, token, spaceID, issueID, status string, version uint64) (coreissue.Issue, error)
SetIssueStatus moves an issue, carrying the version it was read at.
A person's action, never a tool's: status is what the space reads to plan around, and `done` means a person accepted the work. See docs/design/issue-agent-access.md section 6.
The version is a parameter rather than something this re-reads, so the status a caller confirmed is the status of the issue they looked at. Re-reading here would turn a refused stale write into a silent one.
func (*Client) SetPluginArchived ¶
SetPluginArchived retires or restores a catalog entry.
type LoginResponse ¶
type LoginResponse struct {
// Token is AccessToken under the name it had before a login returned two
// credentials. A server older than that split sends only this one.
Token string `json:"token"`
AccessToken string `json:"access_token"`
// RefreshToken is empty when the server keeps no store for it, which means
// the login ends when the access token does.
RefreshToken string `json:"refresh_token"`
ExpiresIn int64 `json:"expires_in"`
User LoginUser `json:"user"`
}
LoginResponse is the successful result of POST /api/login.
func (*LoginResponse) Access ¶
func (r *LoginResponse) Access() string
Access returns the access token under whichever name the server used.
type LoginUser ¶
type LoginUser struct {
ID string `json:"id"`
Email string `json:"email"`
Name string `json:"name"`
}
LoginUser is the user subset returned in a login response.
type RefreshResponse ¶
type RefreshResponse struct {
AccessToken string `json:"access_token"`
RefreshToken string `json:"refresh_token"`
ExpiresIn int64 `json:"expires_in"`
}
RefreshResponse is the successful result of POST /api/token/refresh.
type SystemGrant ¶
type SystemGrant struct {
ID string `json:"id"`
UserID string `json:"user_id"`
Role string `json:"role"`
GrantedBy string `json:"granted_by"`
GrantedAt time.Time `json:"granted_at"`
RevokedAt *time.Time `json:"revoked_at,omitempty"`
Email string `json:"email,omitempty"`
}
SystemGrant is one deployment-scoped authority as the admin API returns it, with the account it names already resolved to an email.
func (SystemGrant) Active ¶
func (g SystemGrant) Active() bool
Active reports whether the grant is still in force.