Documentation
¶
Index ¶
- Constants
- func BuildQuery(params map[string]string) string
- func CreateSentryCommands() *cobra.Command
- func DecodeJSON(body []byte, v any) error
- func ParseNextCursor(resp *http.Response) string
- func ResolveAuthToken() string
- func ResolveDefaultProject() string
- func ResolveHost() string
- func ResolveOrgSlug() string
- type APIError
- type AccountStatus
- type Client
- func (c *Client) AssignIssue(ctx context.Context, orgSlug, issueID, assignee string) error
- func (c *Client) BaseURL() string
- func (c *Client) CreateIssueAlertRule(ctx context.Context, orgSlug, projectSlug string, rule any) (*IssueAlertRule, error)
- func (c *Client) Debug() bool
- func (c *Client) DeleteIssueAlertRule(ctx context.Context, orgSlug, projectSlug, ruleID string) error
- func (c *Client) Do(ctx context.Context, method, path string, body any) (*http.Response, []byte, error)
- func (c *Client) GetEvent(ctx context.Context, orgSlug, projectSlug, eventID string) (*Event, error)
- func (c *Client) GetIssue(ctx context.Context, issueID string) (*Issue, error)
- func (c *Client) GetIssueEvents(ctx context.Context, issueID string, limit int) ([]Event, error)
- func (c *Client) GetMonitor(ctx context.Context, orgSlug, monitorSlug string) (*Monitor, error)
- func (c *Client) GetMonitorCheckins(ctx context.Context, orgSlug, monitorSlug string, limit int) ([]MonitorCheckin, error)
- func (c *Client) GetOrganization(ctx context.Context, slug string) (*Organization, error)
- func (c *Client) GetProject(ctx context.Context, orgSlug, projectSlug string) (*Project, error)
- func (c *Client) GetProjectStats(ctx context.Context, orgSlug, projectSlug, stat, resolution string) ([]ProjectStatsPoint, error)
- func (c *Client) GetRelease(ctx context.Context, orgSlug, projectSlug, version string) (*Release, error)
- func (c *Client) GetReleaseHealth(ctx context.Context, orgSlug, projectSlug, version string) (*SessionsResponse, error)
- func (c *Client) Host() string
- func (c *Client) IgnoreIssues(ctx context.Context, orgSlug string, ids []string) error
- func (c *Client) ListIssueAlertRules(ctx context.Context, orgSlug, projectSlug string) ([]IssueAlertRule, error)
- func (c *Client) ListIssues(ctx context.Context, orgSlug string, opts IssueListOptions) ([]Issue, string, error)
- func (c *Client) ListMembers(ctx context.Context, orgSlug string) ([]Member, error)
- func (c *Client) ListMetricAlertRules(ctx context.Context, orgSlug string) ([]MetricAlertRule, error)
- func (c *Client) ListMonitors(ctx context.Context, orgSlug string) ([]Monitor, error)
- func (c *Client) ListOrganizations(ctx context.Context) ([]Organization, error)
- func (c *Client) ListProjectEvents(ctx context.Context, orgSlug, projectSlug string, limit int) ([]Event, error)
- func (c *Client) ListProjects(ctx context.Context, orgSlug string) ([]Project, error)
- func (c *Client) ListReleases(ctx context.Context, orgSlug, projectSlug string) ([]Release, error)
- func (c *Client) ListTeams(ctx context.Context, orgSlug string) ([]Team, error)
- func (c *Client) MuteMonitor(ctx context.Context, orgSlug, monitorSlug string) error
- func (c *Client) OrgSlug() string
- func (c *Client) ResolveIssues(ctx context.Context, orgSlug string, ids []string) error
- func (c *Client) SetHTTPClient(hc *http.Client)
- func (c *Client) UnmuteMonitor(ctx context.Context, orgSlug, monitorSlug string) error
- func (c *Client) UpdateIssueAlertRule(ctx context.Context, orgSlug, projectSlug, ruleID string, rule any) (*IssueAlertRule, error)
- func (c *Client) UpdateIssues(ctx context.Context, orgSlug string, ids []string, update IssueUpdate) error
- type ConversationEntry
- type ConversationHistory
- func (h *ConversationHistory) AddEntry(question, answer, orgSlug string)
- func (h *ConversationHistory) GetAccountStatusContext() string
- func (h *ConversationHistory) GetRecentContext(maxEntries int) string
- func (h *ConversationHistory) Load() error
- func (h *ConversationHistory) Save() error
- func (h *ConversationHistory) UpdateAccountStatus(status *AccountStatus)
- type Event
- type EventEntry
- type Issue
- type IssueAlertRule
- type IssueListOptions
- type IssueStatus
- type IssueUpdate
- type Member
- type MetricAlertRule
- type Monitor
- type MonitorCheckin
- type Organization
- type Project
- type ProjectStatsPoint
- type Release
- type SessionGroup
- type SessionsResponse
- type Tag
- type Team
Constants ¶
const ( MaxHistoryEntries = 20 MaxAnswerLengthInContext = 500 )
Variables ¶
This section is empty.
Functions ¶
func BuildQuery ¶
BuildQuery formats a Sentry endpoint query string from a values bag, stripping empty values so we don't send `?query=`-style noise.
func CreateSentryCommands ¶
CreateSentryCommands builds the `clanker sentry` command tree. The ask subcommand is added separately by cmd/sentry.go (so cmd/ keeps its dependency on internal/ai out of this package).
func DecodeJSON ¶
DecodeJSON unmarshals body into v, returning a clearer error than the raw json package message when the response is e.g. an HTML login redirect.
func ParseNextCursor ¶
func ResolveAuthToken ¶
func ResolveAuthToken() string
ResolveAuthToken returns the configured Sentry User Auth Token, checking config first then environment, mirroring how cloudflare/client.go resolves its credentials.
func ResolveDefaultProject ¶
func ResolveDefaultProject() string
func ResolveHost ¶
func ResolveHost() string
ResolveHost returns the Sentry host, defaulting to sentry.io. Self-hosted users set this to their on-prem URL host; EU single-tenant users to `<org>.sentry.io`.
func ResolveOrgSlug ¶
func ResolveOrgSlug() string
Types ¶
type AccountStatus ¶
type AccountStatus struct {
Timestamp time.Time `json:"timestamp"`
OrganizationSlug string `json:"organization_slug"`
ProjectCount int `json:"project_count"`
UnresolvedCount int `json:"unresolved_count"`
ErrorCount24h int `json:"error_count_24h"`
}
AccountStatus is the at-a-glance snapshot the ask command stashes in conversation history so follow-up questions can be answered with orientation context (project count, recent error volume) without re-fetching everything.
func GatherAccountStatus ¶
GatherAccountStatus collects an at-a-glance snapshot for the conversation history. The three Sentry calls run concurrently — `ask` cold-start latency is dominated by these network round-trips and they're independent. Errors are non-fatal: we want a partial snapshot rather than blocking the ask command on a single flaky endpoint.
type Client ¶
type Client struct {
// contains filtered or unexported fields
}
Client is a thin REST wrapper around the Sentry management API.
Auth is Bearer-token via the User Auth Token (Settings → Account → API). We hit https://{host}/api/0/ directly with net/http — there is no official Go management SDK; getsentry/sentry-go is for error reporting only.
func NewClient ¶
NewClient returns a Client. orgSlug is optional — many endpoints scope by org but a handful (list orgs) don't. Empty host falls back to sentry.io.
func (*Client) AssignIssue ¶
AssignIssue assigns a single issue to a username.
func (*Client) BaseURL ¶
BaseURL returns the canonical base for Sentry REST calls. Always trailing `/api/0` with no slash; callers prepend `/...` paths.
func (*Client) CreateIssueAlertRule ¶
func (c *Client) CreateIssueAlertRule(ctx context.Context, orgSlug, projectSlug string, rule any) (*IssueAlertRule, error)
CreateIssueAlertRule posts a new issue alert rule. The body is passed through as-is — the upstream schema for conditions/filters/actions is large enough that we don't model it strictly, leaving callers free to construct the payload from documentation.
func (*Client) DeleteIssueAlertRule ¶
func (c *Client) DeleteIssueAlertRule(ctx context.Context, orgSlug, projectSlug, ruleID string) error
DeleteIssueAlertRule removes an issue alert rule.
func (*Client) Do ¶
func (c *Client) Do(ctx context.Context, method, path string, body any) (*http.Response, []byte, error)
Do executes a Sentry API call with exponential backoff on 429s, honoring Retry-After and X-Sentry-Rate-Limit-Reset. path must begin with `/`. If body is non-nil it is JSON-marshalled.
func (*Client) GetEvent ¶
func (c *Client) GetEvent(ctx context.Context, orgSlug, projectSlug, eventID string) (*Event, error)
GetEvent fetches a single event by eventID within a project. eventID is the 32-char hex string (not the numeric primary key).
func (*Client) GetIssueEvents ¶
GetIssueEvents returns events for a given issue, newest first. Limit caps the number returned (Sentry's per-page max is 100).
func (*Client) GetMonitor ¶
GetMonitor fetches a single monitor by slug.
func (*Client) GetMonitorCheckins ¶
func (c *Client) GetMonitorCheckins(ctx context.Context, orgSlug, monitorSlug string, limit int) ([]MonitorCheckin, error)
GetMonitorCheckins returns recent check-ins for a monitor.
func (*Client) GetOrganization ¶
GetOrganization fetches a single org by slug.
func (*Client) GetProject ¶
GetProject fetches a single project.
func (*Client) GetProjectStats ¶
func (c *Client) GetProjectStats(ctx context.Context, orgSlug, projectSlug, stat, resolution string) ([]ProjectStatsPoint, error)
GetProjectStats returns event-volume buckets for a project. `stat` is typically "received" or "rejected"; `resolution` is "10s" | "1h" | "1d".
func (*Client) GetRelease ¶
func (c *Client) GetRelease(ctx context.Context, orgSlug, projectSlug, version string) (*Release, error)
GetRelease fetches a single release by version.
func (*Client) GetReleaseHealth ¶
func (c *Client) GetReleaseHealth(ctx context.Context, orgSlug, projectSlug, version string) (*SessionsResponse, error)
GetReleaseHealth returns crash-free session/user metrics for a release. Uses /organizations/{org}/sessions/ with the v2 sessions endpoint.
func (*Client) IgnoreIssues ¶
IgnoreIssues marks issues as ignored.
func (*Client) ListIssueAlertRules ¶
func (c *Client) ListIssueAlertRules(ctx context.Context, orgSlug, projectSlug string) ([]IssueAlertRule, error)
ListIssueAlertRules returns project-scoped issue alert rules (the legacy /rules/ endpoint). For metric alerts, use ListMetricAlertRules.
func (*Client) ListIssues ¶
func (c *Client) ListIssues(ctx context.Context, orgSlug string, opts IssueListOptions) ([]Issue, string, error)
ListIssues fetches a page of issues. Pagination is exposed via the returned NextCursor — callers that want all pages can iterate.
func (*Client) ListMembers ¶
ListMembers returns members in an org.
func (*Client) ListMetricAlertRules ¶
func (c *Client) ListMetricAlertRules(ctx context.Context, orgSlug string) ([]MetricAlertRule, error)
ListMetricAlertRules returns org-scoped metric alert rules.
func (*Client) ListMonitors ¶
ListMonitors returns Sentry Crons monitors for an org.
func (*Client) ListOrganizations ¶
func (c *Client) ListOrganizations(ctx context.Context) ([]Organization, error)
ListOrganizations returns the auth-token holder's accessible orgs. Paginates internally and accumulates all pages.
func (*Client) ListProjectEvents ¶
func (c *Client) ListProjectEvents(ctx context.Context, orgSlug, projectSlug string, limit int) ([]Event, error)
ListProjectEvents returns recent events for a project (newest first). limit caps the page size (max 100 per Sentry's API).
func (*Client) ListProjects ¶
ListProjects returns all projects in the client's org. orgSlug overrides the client's default when non-empty.
func (*Client) ListReleases ¶
ListReleases returns recent releases for a project (newest first).
func (*Client) MuteMonitor ¶
MuteMonitor marks a monitor as muted (no alerts on missed check-ins).
func (*Client) ResolveIssues ¶
ResolveIssues is a convenience wrapper.
func (*Client) SetHTTPClient ¶
SetHTTPClient lets tests swap in an httptest.Server-backed client.
func (*Client) UnmuteMonitor ¶
UnmuteMonitor restores alerting on a previously muted monitor.
func (*Client) UpdateIssueAlertRule ¶
func (c *Client) UpdateIssueAlertRule(ctx context.Context, orgSlug, projectSlug, ruleID string, rule any) (*IssueAlertRule, error)
UpdateIssueAlertRule replaces an existing issue alert rule.
func (*Client) UpdateIssues ¶
func (c *Client) UpdateIssues(ctx context.Context, orgSlug string, ids []string, update IssueUpdate) error
UpdateIssues bulk-mutates issues. IDs are passed as repeated `id=` query params; the body carries the new status/assignment.
type ConversationEntry ¶
type ConversationEntry struct {
Timestamp time.Time `json:"timestamp"`
Question string `json:"question"`
Answer string `json:"answer"`
OrgSlug string `json:"org_slug"`
}
ConversationEntry is a single Q&A turn against the Sentry ask agent.
type ConversationHistory ¶
type ConversationHistory struct {
Entries []ConversationEntry `json:"entries"`
OrgSlug string `json:"org_slug"`
LastStatus *AccountStatus `json:"last_status,omitempty"`
// contains filtered or unexported fields
}
ConversationHistory persists Sentry ask sessions per-org under ~/.clanker/sentry-{orgSlug}.json — same pattern as the Cloudflare history.
func NewConversationHistory ¶
func NewConversationHistory(orgSlug string) *ConversationHistory
func (*ConversationHistory) AddEntry ¶
func (h *ConversationHistory) AddEntry(question, answer, orgSlug string)
func (*ConversationHistory) GetAccountStatusContext ¶
func (h *ConversationHistory) GetAccountStatusContext() string
func (*ConversationHistory) GetRecentContext ¶
func (h *ConversationHistory) GetRecentContext(maxEntries int) string
GetRecentContext renders the last maxEntries turns as a single string suitable for prepending to an LLM prompt. Answers are truncated so a single long response can't crowd out the user's actual question.
func (*ConversationHistory) Load ¶
func (h *ConversationHistory) Load() error
func (*ConversationHistory) Save ¶
func (h *ConversationHistory) Save() error
func (*ConversationHistory) UpdateAccountStatus ¶
func (h *ConversationHistory) UpdateAccountStatus(status *AccountStatus)
UpdateAccountStatus stashes the latest snapshot so follow-up questions can reference orientation context (project count, unresolved count) without re-fetching.
type Event ¶
type Event struct {
ID string `json:"id"`
EventID string `json:"eventID"`
GroupID string `json:"groupID"`
ProjectID string `json:"projectID"`
Title string `json:"title"`
Message string `json:"message"`
Platform string `json:"platform"`
Type string `json:"type"`
DateCreated time.Time `json:"dateCreated"`
DateReceived time.Time `json:"dateReceived"`
Tags []Tag `json:"tags"`
User json.RawMessage `json:"user"`
Entries []EventEntry `json:"entries"`
Contexts map[string]json.RawMessage `json:"contexts"`
}
type EventEntry ¶
type EventEntry struct {
Type string `json:"type"`
Data json.RawMessage `json:"data"`
}
Event entries are a polymorphic array — each entry has a `type` field (exception, breadcrumbs, request, message, ...) and a `data` payload whose shape depends on the type. Callers that need to introspect should dispatch on Type and unmarshal Data with the appropriate concrete struct.
type Issue ¶
type Issue struct {
ID string `json:"id"`
ShortID string `json:"shortId"`
Title string `json:"title"`
Culprit string `json:"culprit"`
Permalink string `json:"permalink"`
Logger string `json:"logger"`
Level string `json:"level"`
Status string `json:"status"`
StatusDetails json.RawMessage `json:"statusDetails"`
IsPublic bool `json:"isPublic"`
Platform string `json:"platform"`
Project *Project `json:"project,omitempty"`
Type string `json:"type"`
Metadata map[string]any `json:"metadata"`
NumComments int `json:"numComments"`
AssignedTo json.RawMessage `json:"assignedTo"`
IsBookmarked bool `json:"isBookmarked"`
IsSubscribed bool `json:"isSubscribed"`
HasSeen bool `json:"hasSeen"`
FirstSeen time.Time `json:"firstSeen"`
LastSeen time.Time `json:"lastSeen"`
Count string `json:"count"`
UserCount int `json:"userCount"`
}
type IssueAlertRule ¶
type IssueAlertRule struct {
ID string `json:"id"`
Name string `json:"name"`
Environment string `json:"environment"`
Frequency int `json:"frequency"`
ActionMatch string `json:"actionMatch"`
FilterMatch string `json:"filterMatch"`
Conditions []json.RawMessage `json:"conditions"`
Filters []json.RawMessage `json:"filters"`
Actions []json.RawMessage `json:"actions"`
DateCreated time.Time `json:"dateCreated"`
CreatedBy json.RawMessage `json:"createdBy"`
}
IssueAlertRule is a Sentry issue alert rule (the legacy /rules/ endpoint). MetricAlertRule (the newer /alert-rules/ endpoint) has a different shape.
type IssueListOptions ¶
type IssueListOptions struct {
Query string
Environment string
StatsPeriod string // e.g. "24h", "14d"
Project string // project ID (numeric string) — multiple allowed via repeated params; we keep single for simplicity
Sort string // "new" | "priority" | "freq" | "user"
Limit int
Cursor string
}
IssueListOptions controls /organizations/{org}/issues/. Query is Sentry's search-syntax string (e.g. `is:unresolved level:error environment:prod`) and is passed verbatim — we do no client-side parsing.
type IssueStatus ¶
type IssueStatus string
IssueStatus is the set of accepted values for IssueUpdate.Status. Defining them as constants prevents typos (`"resolve"` would silently no-op against Sentry) and lets callers refer to them by name.
const ( IssueStatusResolved IssueStatus = "resolved" IssueStatusIgnored IssueStatus = "ignored" IssueStatusUnresolved IssueStatus = "unresolved" )
type IssueUpdate ¶
type IssueUpdate struct {
Status IssueStatus `json:"status,omitempty"`
AssignedTo string `json:"assignedTo,omitempty"`
}
IssueUpdate is the payload Sentry expects on PUT /organizations/{org}/issues/. AssignedTo is a username string (or "" to clear).
type MetricAlertRule ¶
type MetricAlertRule struct {
ID string `json:"id"`
Name string `json:"name"`
Environment string `json:"environment"`
DataSet string `json:"dataset"`
Query string `json:"query"`
Aggregate string `json:"aggregate"`
TimeWindow float64 `json:"timeWindow"`
Threshold float64 `json:"threshold"`
Triggers []json.RawMessage `json:"triggers"`
Projects []string `json:"projects"`
DateCreated time.Time `json:"dateCreated"`
}
type Monitor ¶
type Monitor struct {
Slug string `json:"slug"`
Name string `json:"name"`
Status string `json:"status"`
Type string `json:"type"`
IsMuted bool `json:"isMuted"`
Config json.RawMessage `json:"config"`
Project struct {
Slug string `json:"slug"`
Name string `json:"name"`
} `json:"project"`
DateCreated time.Time `json:"dateCreated"`
}
type MonitorCheckin ¶
type Organization ¶
type ProjectStatsPoint ¶
ProjectStatsPoint is one bucket of `/projects/{org}/{project}/stats/`. The endpoint returns tuples of [unix_seconds, count].
func (ProjectStatsPoint) MarshalJSON ¶
func (p ProjectStatsPoint) MarshalJSON() ([]byte, error)
MarshalJSON keeps round-trip parity with the upstream tuple format so tests that re-encode a fixture and diff against the input don't drift.
func (*ProjectStatsPoint) UnmarshalJSON ¶
func (p *ProjectStatsPoint) UnmarshalJSON(data []byte) error
UnmarshalJSON handles the tuple shape `[<unix>, <count>]`.
type Release ¶
type Release struct {
Version string `json:"version"`
ShortVersion string `json:"shortVersion"`
Ref string `json:"ref"`
URL string `json:"url"`
DateCreated time.Time `json:"dateCreated"`
DateReleased *time.Time `json:"dateReleased"`
NewGroups int `json:"newGroups"`
Projects []struct {
Slug string `json:"slug"`
Name string `json:"name"`
} `json:"projects"`
}
type SessionGroup ¶
type SessionGroup struct {
By map[string]string `json:"by"`
Totals map[string]float64 `json:"totals"`
Series map[string][]float64 `json:"series"`
}
SessionGroup carries release-health rollups returned by /organizations/{org}/sessions/. The shape is a tuple-array under `groups`; caller selects fields via the `field=` query (e.g. `sum(session)`).