Documentation
¶
Index ¶
- Constants
- func ExitCode(err error) int
- type APIError
- type Client
- func (c *Client) CreateContent(ctx context.Context, req CreateContentRequest) (json.RawMessage, json.RawMessage, error)
- func (c *Client) DeleteContent(ctx context.Context, id int) (json.RawMessage, json.RawMessage, error)
- func (c *Client) GetContent(ctx context.Context, id int) (json.RawMessage, json.RawMessage, error)
- func (c *Client) GetMedia(ctx context.Context, id int) (json.RawMessage, json.RawMessage, error)
- func (c *Client) ListContent(ctx context.Context, limit int, cursor string, filters ListContentFilters) (json.RawMessage, json.RawMessage, error)
- func (c *Client) ListMedia(ctx context.Context, limit int, cursor string) (json.RawMessage, json.RawMessage, error)
- func (c *Client) PublishContent(ctx context.Context, id int) (json.RawMessage, json.RawMessage, error)
- func (c *Client) UnpublishContent(ctx context.Context, id int) (json.RawMessage, json.RawMessage, error)
- func (c *Client) UpdateContent(ctx context.Context, id int, req UpdateContentRequest) (json.RawMessage, json.RawMessage, error)
- func (c *Client) UploadMedia(ctx context.Context, req UploadMediaRequest) (json.RawMessage, json.RawMessage, error)
- type CreateContentRequest
- type ListContentFilters
- type UpdateContentRequest
- type UploadMediaRequest
Constants ¶
const ( ExitOK = 0 ExitGeneric = 1 ExitUsage = 2 ExitAuth = 3 ExitNotFound = 4 ExitValidation = 5 ExitRateLimited = 6 ExitServer = 7 )
Documented CLI exit-code scheme (see docs/api-reference.md and the architecture). The cmd layer maps outcomes to these and os.Exit()s with them.
Variables ¶
This section is empty.
Functions ¶
func ExitCode ¶
ExitCode maps a Client error to the documented exit-code scheme. A nil error is success (0); an *APIError maps by HTTP status (401→auth, 404→not-found, 429→rate-limited, other 4xx→validation, 5xx→server, 0→generic); any other error is generic (1). Wrapped *APIErrors are unwrapped via errors.As.
Types ¶
type APIError ¶
APIError is returned by Client methods when the request fails or the server returns an error envelope. StatusCode carries the HTTP status (0 for a transport-level failure); Code/Message come from the server's error object.
type Client ¶
type Client struct {
// contains filtered or unexported fields
}
Client is a typed HTTP client over the /api/v1 surface. It depends only on the JSON contract (stdlib) — it imports no server internals — which is what lets a future MCP server reuse it. Construct it with New.
func New ¶
New builds a Client targeting baseURL authenticated with apiKey. The base URL is normalized (trailing slash trimmed) and must be an http(s) scheme + host with no userinfo and no path (the client appends /api/v1/...); rejecting a path avoids a silent double-prefix when callers proxy under a path. The returned Client follows redirects but strips the API key on cross-host hops. A default 30s per-request timeout is applied so a hung server cannot block the CLI indefinitely.
func (*Client) CreateContent ¶
func (c *Client) CreateContent( ctx context.Context, req CreateContentRequest, ) (json.RawMessage, json.RawMessage, error)
CreateContent POSTs a content-create request to /api/v1/content and returns the decoded data and meta payloads, or an *APIError on failure.
func (*Client) DeleteContent ¶
func (c *Client) DeleteContent( ctx context.Context, id int, ) (json.RawMessage, json.RawMessage, error)
DeleteContent sends DELETE /api/v1/content/{id}. A 204 No Content success returns (nil, nil, nil); a 404 or other 4xx/5xx returns an *APIError.
func (*Client) GetContent ¶
func (c *Client) GetContent( ctx context.Context, id int, ) (json.RawMessage, json.RawMessage, error)
GetContent sends GET /api/v1/content/{id} and returns the decoded data and meta payloads, or an *APIError on failure.
func (*Client) GetMedia ¶
func (c *Client) GetMedia( ctx context.Context, id int, ) (json.RawMessage, json.RawMessage, error)
GetMedia sends GET /api/v1/media/{id} and returns the decoded data and meta payloads, or an *APIError on failure.
func (*Client) ListContent ¶
func (c *Client) ListContent( ctx context.Context, limit int, cursor string, filters ListContentFilters, ) (json.RawMessage, json.RawMessage, error)
ListContent sends GET /api/v1/content?limit=&cursor=&tag=&language=&status=&post_type=&author=&search= and returns the decoded data (a bare array of content projections) and meta (with pagination), or an *APIError on failure. A limit of 0 (or negative) is passed as "no limit" (the server uses its default); an empty cursor is passed as "no cursor" (the first page). Each non-empty filter field emits its query key; an empty field is omitted entirely so the wire stays minimal. Tags is expanded into repeated ?tag= keys (one per tag) so the server can AND-of-tags.
func (*Client) ListMedia ¶
func (c *Client) ListMedia( ctx context.Context, limit int, cursor string, ) (json.RawMessage, json.RawMessage, error)
ListMedia sends GET /api/v1/media?limit=&cursor= and returns the decoded data (a bare array of media projections) and meta (with pagination), or an *APIError on failure. A limit of 0 (or negative) is passed as "no limit" (the server uses its default); an empty cursor is passed as "no cursor" (the first page).
func (*Client) PublishContent ¶
func (c *Client) PublishContent( ctx context.Context, id int, ) (json.RawMessage, json.RawMessage, error)
PublishContent sends POST /api/v1/content/{id}/publish with an empty body and returns the decoded data and meta payloads, or an *APIError on failure. The server endpoint is idempotent: publishing an already-published post returns 200 with the current projection. Ownership is enforced server-side; a non-admin non-owner call returns 404 (not 403, no disclosure).
func (*Client) UnpublishContent ¶
func (c *Client) UnpublishContent( ctx context.Context, id int, ) (json.RawMessage, json.RawMessage, error)
UnpublishContent sends POST /api/v1/content/{id}/unpublish with an empty body and returns the decoded data and meta payloads, or an *APIError on failure. The server endpoint is idempotent: unpublishing an already-draft post returns 200 with the current projection. Same ownership contract as PublishContent.
func (*Client) UpdateContent ¶
func (c *Client) UpdateContent( ctx context.Context, id int, req UpdateContentRequest, ) (json.RawMessage, json.RawMessage, error)
UpdateContent sends PUT /api/v1/content/{id} with the given request body and returns the decoded data and meta payloads, or an *APIError on failure. The request body is the same shape as CreateContent. The server's update handler preserves the server-managed fields (SEO metadata — metaDescription / ogTitle / ogDescription, allowComments, translationGroupId) from the existing item, so a partial update that omits them is safe; postType / tags / language are now settable and forwarded as-given (the server validates them).
func (*Client) UploadMedia ¶
func (c *Client) UploadMedia( ctx context.Context, req UploadMediaRequest, ) (json.RawMessage, json.RawMessage, error)
UploadMedia sends POST /api/v1/media as multipart/form-data with a `file` part and an optional `metadata` JSON part, then returns the decoded data and meta payloads (the server returns 200 with the media projection in the data envelope) or an *APIError on failure.
The multipart body is buffered in memory; the server enforces its own size limit at r.ParseMultipartForm. The 204/304+envelope defenses from doRequest apply unchanged.
type CreateContentRequest ¶
type CreateContentRequest struct {
Title string `json:"title"`
Body string `json:"body"`
Format string `json:"format,omitempty"`
PostType string `json:"postType,omitempty"`
Tags []string `json:"tags,omitempty"`
Language string `json:"language,omitempty"`
IsPublished bool `json:"isPublished,omitempty"`
}
CreateContentRequest is the agent content-create payload. It mirrors the {data, error, meta} contract documented in docs/api-reference.md — the client hard-codes it (it cannot import the server's DTO types).
All metadata fields (PostType, Tags, Language) use `omitempty` so an unset value is identical on the wire to a default-zero request. Tags must already be normalized by the caller (the CLI's normalizeTags helper trims, drops empties, and dedupes); the server re-validates via contentdomain.ValidateTags. Language is forwarded as-given — the server is the single source of truth for the configured-languages list (it returns ErrInvalidLanguage for an unknown code, mapped to 400 VALIDATION_ERROR by the CLI's exit code map).
type ListContentFilters ¶
type ListContentFilters struct {
Tags []string
Language string
Status string
PostType string
Author string
Search string
}
ListContentFilters is the cmd-layer projection of contentdomain.ContentFilters for the agent List endpoint. The CLI re-declares the shape (it cannot import server-internal types) so the wire contract is the source of truth, and only the fields used by the agent v1 surface are exposed here. Tags is intentionally a slice — the wire format uses repeated ?tag= keys (one per tag, AND-of-tags on the server). An empty / zero struct produces a no-filter call (server returns the unfiltered list).
type UpdateContentRequest ¶
type UpdateContentRequest struct {
Title string `json:"title"`
Body string `json:"body"`
Format string `json:"format,omitempty"`
PostType string `json:"postType,omitempty"`
Tags []string `json:"tags,omitempty"`
Language string `json:"language,omitempty"`
IsPublished bool `json:"isPublished,omitempty"`
}
UpdateContentRequest is the agent content-update payload. It carries the same fields as CreateContentRequest because the server's PUT /api/v1/content/{id} accepts the same ContentRequest shape. The server preserves the server-managed fields (SEO metadata — metaDescription / ogTitle / ogDescription, allowComments, translationGroupId) from the existing item; the client does not surface flags for them. The client cannot import the server's DTO types so the subset is re-declared here.
type UploadMediaRequest ¶
UploadMediaRequest is the multipart payload sent to POST /api/v1/media. It is built in memory by UploadMedia — callers supply the file reader + filename and an optional metadata map (the server reads `altText` today; the map type allows future expansion without a client signature change). The client validates that File is non-nil and Filename is non-empty so a bad call site fails fast with a clear error instead of a runtime panic.