bugsink-helper
/bugsink-helper
Obsługuje API REST samodzielnie hostowanego trackera błędów Bugsink: zespoły, projekty, zgłoszenia, zdarzenia, wydania i stacktrace'y.
- Autor
- shepherdjerred ↗
- Repozytorium
- monorepo ↗
- Licencja
- GPL-3.0
- Ostatnia zmiana repozytorium
- 25.10.2026
Ocena i bezpieczeństwo
- Pliki w paczce
- 1
- Skrypty
- 0
- Komentarze HTML
- 0
- Adresy URL w SKILL.md
- 5
Brak sygnałów. Repozytorium zmienione 25.10.2026, bez odwołań do wycofanych modeli i API.
GPL-3.0, otwarta.
Co robi i kiedy
Obsługuje API REST samodzielnie hostowanego trackera błędów Bugsink: zespoły, projekty, zgłoszenia, zdarzenia, wydania i stacktrace'y.
Oryginalny opis (EN)
Bugsink self-hosted error tracking via REST API - teams, projects, issues, events, releases, stacktraces When user mentions Bugsink, self-hosted error tracking, or needs to query Bugsink API for issues, events, stacktraces, or releases
Jak działa
- Overview
- Authentication
- API Endpoints Reference
- Team Operations
- Project Operations
- Issue Operations
- Resolving / Muting Issues (web UI only)
- Event Operations
- Release Operations
- Pagination
Podgląd SKILL.md
---
name: bugsink-helper
description: |
Bugsink self-hosted error tracking via REST API - teams, projects, issues, events, releases, stacktraces
When user mentions Bugsink, self-hosted error tracking, or needs to query Bugsink API for issues, events, stacktraces, or releases
---
# Bugsink Helper Agent
## Overview
Bugsink is a self-hosted error tracking service compatible with Sentry SDKs.
Use `toolkit bugsink` for supported reads; the REST API covers additional
operations.
## Authentication
Prefer `toolkit bugsink` — it resolves `BUGSINK_TOKEN` itself (env, then
`~/.toolkit/config.toml` `[credentials]`, then its registered macOS Keychain
entry), so no token handling is needed. There is no automatic 1Password
fallback after Keychain. An explicit config override can select a 1Password
reference; backend setup is documented in `packages/toolkit/README.md`:
```bash
# Verify authentication by listing issues
toolkit bugsink issues --limit 1
```
For endpoints toolkit does not cover yet, fall back to raw `curl`:
```bash
# Set environment variables
export BUGSINK_URL="https://your-bugsink-instance.example.com"
export BUGSINK_TOKEN="your-api-token"
export API="$BUGSINK_URL/api/canonical/0"
# Auth header used in all requests
AUTH="Authorization: Bearer $BUGSINK_TOKEN"
# Verify authentication by listing teams
curl -s -H "$AUTH" "$API/teams/" | jq .
```
## API Endpoints Reference
| Resource | Method | Path | Required Params |
| ---------- | ------ | -------------------------------------------- | --------------------------- |
| Teams | GET | `/api/canonical/0/teams/` | — |
| Teams | POST | `/api/canonical/0/teams/` | name (body) |
| Team | GET | `/api/canonical/0/teams/{uuid}/` | — |
| Team | PATCH | `/api/canonical/0/teams/{uuid}/` | — |
| Projects | GET | `/api/canonical/0/projects/` | — (optional `?team=<uuid>`) |
| Projects | POST | `/api/canonical/0/projects/` | team, name (body) |
| Project | GET | `/api/canonical/0/projects/{id}/` | — |
| Project | PATCH | `/api/canonical/0/projects/{id}/` | — |
| Issues | GET | `/api/canonical/0/issues/` | `?project=<id>` |
| Issue | GET | `/api/canonical/0/issues/{uuid}/` | — |
| Events | GET | `/api/canonical/0/events/` | `?issue=<uuid>` |
| Event | GET | `/api/canonical/0/events/{uuid}/` | — |
| Stacktrace | GET | `/api/canonical/0/events/{uuid}/stacktrace/` | — |
| Releases | GET | `/api/canonical/0/releases/` | `?project=<id>` |
| Releases | POST | `/api/canonical/0/releases/` | project, version (body) |
| Release | GET | `/api/canonical/0/releases/{uuid}/` | — |
**Notes:**
- Team IDs and issue IDs are UUIDs. Project IDs are integers.
- DELETE is not supported (returns 405) on teams and projects.
- All list endpoints use cursor-based pagination.
---
## Team Operations
### List Teams
```bash
curl -s -H "$AUTH" "$API/teams/" | jq '.results'
# Summary output
curl -s -H "$AUTH" "$API/teams/" | \
jq -r '.results[] | "\(.id)\t\(.name)\t\(.visibility)"'
```
### Create Team
```bash
curl -s -X POST -H "$AUTH" -H "Content-Type: application/json" \
"$API/teams/" \
-d '{
"name": "Backend Team",
"visibility": "joinable"
}' | jq .
```
**Required fields:** `name` (string, max 255 chars)
**Optional fields:** `visibility` (enum: `joinable`, `discoverable`, `hidden`)
### Get Team Detail
```bash
curl -s -H "$AUTH" "$API/teams/$TEAM_UUID/" | jq .
```
### Update Team
```bash
curl -s -X PATCH -H "$AUTH" -H "Content-Type: application/json" \
"$API/teams/$TEAM_UUID/" \
-d '{
"name": "Renamed Team",
"visibility": "hidden"
}' | jq .
```
---
## Project Operations
### List Projects
```bash
curl -s -H "$AUTH" "$API/projects/" | jq '.results'
# Filter by team
curl -s -H "$AUTH" "$API/projects/?team=$TEAM_UUID" | jq '.results'
# Summary output
curl -s -H "$AUTH" "$API/projects/" | \
jq -r '.results[] | "\(.id)\t\(.name)\t\(.slug)\t\(.visibility)"'
```
### Create Project
```bash
curl -s -X POST -H "$AUTH" -H "Content-Type: application/json" \
"$API/projects/" \
-d '{
"team": "'$TEAM_UUID'",
"name": "My App",
"visibility": "team_members"
}' | jq .
```
**Required fields:** `team` (UUID), `name` (string, max 255 chars)
**Optional fields:** `visibility` (enum: `joinable`, `discoverable`, `team_members`), `alert_on_new_issue` (bool), `alert_on_regression` (bool), `alert_on_unmute` (bool), `retention_max_event_count` (int, >= 0)
### Get Project Detail (includes DSN)
```bash
curl -s -H "$AUTH" "$API/projects/$PROJECT_ID/" | jq .
# Get just the DSN
curl -s -H "$AUTH" "$API/projects/$PROJECT_ID/" | jq -r '.dsn'
```
The project detail response includes `dsn`, `slug`, `digested_event_count`, and `stored_event_count` fields not present in the create/update schema.
### Update Project
```bash
curl -s -X PATCH -H "$AUTH" -H "Content-Type: application/json" \
"$API/projects/$PROJECT_ID/" \
-d '{
"name": "Renamed App",
"alert_on_new_issue": true,
"alert_on_regression": true
}' | jq .
```
---
## Issue Operations
### List Issues (requires project filter)
```bash
# List issues for a project (required)
curl -s -H "$AUTH" "$API/issues/?project=$PROJECT_ID" | jq '.results'
# With sort and order
curl -s -H "$AUTH" "$API/issues/?project=$PROJECT_ID&sort=last_seen&order=desc" | jq '.results'
# Summary output
curl -s -H "$AUTH" "$API/issues/?project=$PROJECT_ID" | \
jq -r '.results[:10][] | "\(.id)\t\(.calculated_type): \(.calculated_value)\t\(.digested_event_count) events\t\(.last_seen)"'
```
**Required query param:** `project` (integer project ID)
**Optional query params:**
- `sort`: `digest_order` (default) or `last_seen`
- `order`: `asc` (default) or `desc`
- `cursor`: pagination cursor
### Get Issue Detail
```bash
curl -s -H "$AUTH" "$API/issues/$ISSUE_UUID/" | jq .
# Formatted output
curl -s -H "$AUTH" "$API/issues/$ISSUE_UUID/" | \
jq '{
id,
calculated_type,
calculated_value,
transaction,
digested_event_count,
stored_event_count,
first_seen,
last_seen,
is_resolved,
is_muted
}'
```
---
## Resolving / Muting Issues (web UI only)
The canonical REST API is **read-only** for issues — `PATCH`/`POST` on an issue returns `405` (Allow: GET, HEAD, OPTIONS). To resolve or mute, drive the Django + allauth web-UI bulk-action form:
1. **Log in:** GET `/accounts/login/` for the `csrfmiddlewaretoken` + `csrftoken` cookie, then POST `username`/`password`/`csrfmiddlewaretoken`/`next` to `/accounts/login/` **with `Origin` and `Referer` headers** (Django HTTPS CSRF requires them, else `403 CSRF verification failed`). A `sessionid` cookie means success.
2. **Bulk action:** the issue list is at `/issues/<project_id>/` (integer id); scrape its `issueForm` for a fresh `csrfmiddlewaretoken`, then POST to `/issues/<project_id>/` with `csrfmiddlewaretoken`, `action=resolved_next` (or `mute` / `mute_for:...` / `unmute`), and one `issue_ids[]=<uuid>` per issue (batch allowed). Verify via `GET /api/canonical/0/issues/<uuid>/` → `is_resolved: true`.
Resolving does **not** prevent recurrence — the issue reopens as a regression on the next matching event, so resolve "fixed" issues only after the fix deploys.
---
## Event Operations
### List Events (requires issue filter)
```bash
# List events for an issue (required)
curl -s -H "$AUTH" "$API/events/?issue=$ISSUE_UUID" | jq '.results'
# Ascending order (oldest first)
curl -s -H "$AUTH" "$API/events/?issue=$ISSUE_UUID&order=asc" | jq '.results'
# Summary output
curl -s -H "$AUTH" "$API/events/?issue=$ISSUE_UUID" | \
jq -r '.results[] | "\(.id)\t\(.event_id)\t\(.timestamp)"'
```
**Required query param:** `issue` (UUID)
**Optional query params:** `order` (`asc` or `desc`, default `desc`), `cursor`
**Note:** The list view omits the `data` field for performance. Use the detail endpoint for the full event payload.
### Get Event Detail
```bash
curl -s -H "$AUTH" "$API/events/$EVENT_UUID/" | jq .
# The detail view includes the full `data` payload and `stacktrace_md`
curl -s -H "$AUTH" "$API/events/$EVENT_UUID/" | jq '.data'
```
### Get Event Stacktrace (Markdown)
```bash
# Returns rendered stacktrace as Markdown text (text/markdown content type)
curl -s -H "$AUTH" "$API/events/$EVENT_UUID/stacktrace/"
```
This is the most useful endpoint for debugging. It returns a human-readable markdown rendering of the event's stacktrace including frames, source context, and local variables.
---
## Release Operations
### List Releases (requires project filter)
```bash
# List releases for a project (required)
curl -s -H "$AUTH" "$API/releases/?project=$PROJECT_ID" | jq '.results'
# Summary output
curl -s -H "$AUTH" "$API/releases/?project=$PROJECT_ID" | \
jq -r '.results[] | "\(.id)\t\(.version)\t\(.date_released)"'
```
**Required query param:** `project` (integer project ID)
### Create Release
```bash
curl -s -X POST -H "$AUTH" -H "Content-Type: application/json" \
"$API/releases/" \
-d '{
"project": '$PROJECT_ID',
"version": "1.2.3",
"timestamp": "2025-01-15T12:00:00Z"
}' | jq .
```
**Required fields:** `project` (integer), `version` (string)
**Optional fields:** `timestamp` (datetime)
### Get Release Detail
```bash
curl -s -H "$AUTH" "$API/releases/$RELEASE_UUID/" | jq .
# Detail includes additional fields: semver, is_semver, sort_epoch
curl -s -H "$AUTH" "$API/releases/$RELEASE_UUID/" | \
jq '{id, version, date_released, semver, is_semver, sort_epoch}'
```
---
## Pagination
All list endpoints use cursor-based pagination. The response shape is:
```json
{
"next": "http://bugsink.example.com/api/canonical/0/issues/?cursor=cD00ODY%3D&project=1",
"previous": null,
"results": [...]
}
```
To paginate through results:
```bash
# First page
RESPONSE=$(curl -s -H "$AUTH" "$API/issues/?project=$PROJECT_ID")
echo "$RESPONSE" | jq '.results'
# Get next page URL
NEXT=$(echo "$RESPONSE" | jq -r '.next // empty')
# Fetch next page (if exists)
if [ -n "$NEXT" ]; then
curl -s -H "$AUTH" "$NEXT" | jq '.results'
fi
```
Loop through all pages:
```bash
URL="$API/issues/?project=$PROJECT_ID"
while [ -n "$URL" ] && [ "$URL" != "null" ]; do
RESPONSE=$(curl -s -H "$AUTH" "$URL")
echo "$RESPONSE" | jq '.results[]'
URL=$(echo "$RESPONSE" | jq -r '.next // empty')
done
```
---
## SDK Integration
Bugsink is compatible with Sentry SDKs. Use the DSN from the project detail endpoint.
### Python
```python
import sentry_sdk
sentry_sdk.init(
dsn="http://key@your-bugsink-instance.example.com/1",
send_default_pii=True,
traces_sample_rate=0, # Bugsink does not support tracing
)
```
### JavaScript/TypeScript
```javascript
import * as Sentry from "@sentry/browser";
Sentry.init({
dsn: "http://key@your-bugsink-instance.example.com/1",
sendDefaultPii: true,
tracesSampleRate: 0, // Bugsink does not support tracing
});
```
### Node.js
```javascript
const Sentry = require("@sentry/node");
Sentry.init({
dsn: "http://key@your-bugsink-instance.example.com/1",
sendDefaultPii: true,
tracesSampleRate: 0, // Bugsink does not support tracing
});
```
**Important:** Set `traces_sample_rate=0` (or `tracesSampleRate: 0`) because Bugsink does not support performance tracing. Set `send_default_pii=True` to include user context in error reports.
---
## Common Workflows
### Error Investigation
```bash
#!/bin/bash
# Investigate errors in a Bugsink project
# 1. List recent issues sorted by last_seen
echo "=== Recent Issues ==="
curl -s -H "$AUTH" "$API/issues/?project=$PROJECT_ID&sort=last_seen&order=desc" | \
jq -r '.results[:10][] | "\(.id)\t\(.calculated_type): \(.calculated_value)\t\(.digested_event_count) events"'
# 2. Get details for a specific issue
echo -e "\n=== Issue Details ==="
ISSUE_UUID="${1:-}"
if [ -n "$ISSUE_UUID" ]; then
curl -s -H "$AUTH" "$API/issues/$ISSUE_UUID/" | \
jq '{calculated_type, calculated_value, transaction, digested_event_count, first_seen, last_seen, is_resolved}'
# 3. Get the most recent event
echo -e "\n=== Latest Event ==="
EVENT_UUID=$(curl -s -H "$AUTH" "$API/events/?issue=$ISSUE_UUID&order=desc" | jq -r '.results[0].id')
if [ -n "$EVENT_UUID" ] && [ "$EVENT_UUID" != "null" ]; then
# 4. Get the stacktrace
echo -e "\n=== Stacktrace ==="
curl -s -H "$AUTH" "$API/events/$EVENT_UUID/stacktrace/"
fi
fi
```
### Issue Triage
```bash
#!/bin/bash
# Triage unresolved issues by event count
curl -s -H "$AUTH" "$API/issues/?project=$PROJECT_ID&sort=last_seen&order=desc" | \
jq -r '.results[] | select(.is_resolved == false and .is_muted == false) | "\(.digested_event_count)\t\(.calculated_type): \(.calculated_value)\t\(.last_seen)"' | \
sort -t$'\t' -k1 -nr | \
column -t -s$'\t'
```
### Get DSN for SDK Setup
```bash
# Get the DSN for a project to configure Sentry SDKs
curl -s -H "$AUTH" "$API/projects/$PROJECT_ID/" | jq -r '.dsn'
```
---
## API Schema Reference
### Enums
**ProjectVisibilityEnum:** `joinable` | `discoverable` | `team_members`
**TeamVisibilityEnum:** `joinable` | `discoverable` | `hidden`
### TeamList / TeamDetail
```
{
id: UUID (read-only)
name: string (max 255, required)
visibility: TeamVisibilityEnum (required in detail)
}
```
### TeamCreateUpdate
```
{
id: UUID (read-only)
name: string (max 255, required)
visibility: TeamVisibilityEnum (optional)
}
```
### ProjectList
```
{
id: integer (read-only)
team: UUID | null
name: string (max 255, required)
slug: string (max 50, pattern: ^[-a-zA-Z0-9_]+$, required)
dsn: string (read-only, required)
digested_event_count: integer (read-only, required)
stored_event_count: integer (read-only, required)
alert_on_new_issue: boolean
alert_on_regression: boolean
alert_on_unmute: boolean
visibility: ProjectVisibilityEnum (required)
retention_max_event_count: integer (>= 0)
}
```
### ProjectDetail
Same fields as ProjectList.
### ProjectCreateUpdate
```
{
id: UUID (read-only, required in response)
team: UUID (required)
name: string (max 255, required)
visibility: ProjectVisibilityEnum (optional)
alert_on_new_issue: boolean (optional)
alert_on_regression: boolean (optional)
alert_on_unmute: boolean (optional)
retention_max_event_count: integer (>= 0, optional)
}
```
**Note:** The create/update schema uses UUID for `id`, while ProjectList/Detail uses integer for `id`. The `team` field in create/update is UUID (required), while in list/detail it is UUID | null.
### Issue
```
{
id: UUID (read-only)
project: integer
digest_order: integer (0..2147483647)
last_seen: datetime
first_seen: datetime
digested_event_count: integer
stored_event_count: integer (read-only)
calculated_type: string (max 128)
calculated_value: string (max 1024)
transaction: string (max 200)
is_resolved: boolean
is_resolved_by_next_release: boolean
is_muted: boolean
}
```
**Required:** id, project, digest_order, last_seen, first_seen, digested_event_count, stored_event_count
### EventList
Lightweight list view (excludes the `data` field):
```
{
id: UUID (read-only, Bugsink-internal)
ingested_at: datetime
digested_at: datetime
issue: UUID
grouping: integer
event_id: UUID (read-only, as per the sent data)
project: integer
timestamp: datetime
digest_order: integer (0..2147483647)
}
```
All fields are required.
### EventDetail
Full detail view (includes `data` payload):
```
{
id: UUID (read-only, Bugsink-internal)
ingested_at: datetime
digested_at: datetime
issue: UUID
grouping: integer
event_id: UUID (read-only, as per the sent data)
project: integer
timestamp: datetime
digest_order: integer (0..2147483647)
data: object (read-only, full event payload)
stacktrace_md: string (read-only)
}
```
All fields are required.
### ReleaseList
```
{
id: UUID (read-only)
project: integer (required)
version: string (max 250, required)
date_released: datetime
}
```
### ReleaseDetail
```
{
id: UUID (read-only)
project: integer (required)
version: string (max 250, required)
date_released: datetime
semver: string (read-only)
is_semver: boolean (read-only)
sort_epoch: integer (read-only)
}
```
### ReleaseCreate
```
{
project: integer (required)
version: string (required)
timestamp: datetime (optional)
}
```
### Pagination Envelope
All list endpoints return:
```
{
next: string | null (URI, cursor-based)
previous: string | null (URI, cursor-based)
results: array of resource objects
}
```
### Authentication
All endpoints require Bearer token authentication:
```
Authorization: Bearer <token>
```
---
## When to Ask for Help
Ask the user for clarification when:
- The Bugsink server URL is not known
- The API token is not available or authentication fails
- The project ID (integer) or team UUID is needed but not specified
- It's unclear which issue or event to investigate
- The user needs help setting up SDK integration and the DSN is unknown
Wersje
W bazie nie ma innych skilli o nazwie bugsink-helper.
Migawka bazy z 28.10.2026 · wersja paczki 2d2b29717137 (skrót SHA-256 całej paczki)
Zgłoś problem z tym skillem: szkodliwa treść, błędny opis albo prośba autora o usunięcie.
Podobne skille
- 100sentry-api
Pobiera i przeszukuje błędy z Sentry, czyta ślady stosu, sprawdza wydania i zmienia status problemów przez API.