shepherdjerred/monorepo/bugsink-helper

Claude Code and agent skill by shepherdjerred/monorepo

Trust tier 2
  • community
  • ext:[{"type":"config","description":"Configuration overrides"}]
LLM review pending
Source check pending

Checking that the SKILL.md file is still in the repository.

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

Install

npx vskill@latest install shepherdjerred/monorepo/bugsink-helper

Semi-extensibleMentions customization, but needs skill-specific knowledge. Read the extensible skills standard

SKILL.md

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

ResourceMethodPathRequired Params
TeamsGET/api/canonical/0/teams/—
TeamsPOST/api/canonical/0/teams/name (body)
TeamGET/api/canonical/0/teams/{uuid}/—
TeamPATCH/api/canonical/0/teams/{uuid}/—
ProjectsGET/api/canonical/0/projects/— (optional ?team=<uuid>)
ProjectsPOST/api/canonical/0/projects/team, name (body)
ProjectGET/api/canonical/0/projects/{id}/—
ProjectPATCH/api/canonical/0/projects/{id}/—
IssuesGET/api/canonical/0/issues/?project=<id>
IssueGET/api/canonical/0/issues/{uuid}/—
EventsGET/api/canonical/0/events/?issue=<uuid>
EventGET/api/canonical/0/events/{uuid}/—
StacktraceGET/api/canonical/0/events/{uuid}/stacktrace/—
ReleasesGET/api/canonical/0/releases/?project=<id>
ReleasesPOST/api/canonical/0/releases/project, version (body)
ReleaseGET/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.

In the monorepo, applications do not build these options by hand. Bun services spread bugsinkServerOptions({ dsn, environment, release }) from @shepherdjerred/bugsink-config/server, and browser apps use bugsinkBrowserOptions from @shepherdjerred/bugsink-config. Both apply the shared privacy policy (bugsinkDataCollection()), and the server helper rejects SENTRY_* environment variables.

Python
python
import sentry_sdk
sentry_sdk.init(
dsn="http://key@your-bugsink-instance.example.com/1",
send_default_pii=False,
)
JavaScript/TypeScript
javascript
import * as Sentry from "@sentry/browser";
Sentry.init({
dsn: "http://key@your-bugsink-instance.example.com/1",
sendDefaultPii: false,
});
Node.js
javascript
const Sentry = require("@sentry/node");
Sentry.init({
dsn: "http://key@your-bugsink-instance.example.com/1",
sendDefaultPii: false,
});

Important: Bugsink does not support performance tracing. Leave traces_sample_rate / tracesSampleRate unset: any value, including 0, turns on SDK span recording. Keep send_default_pii off; attach user context explicitly when an error needs it.


Common Workflows

Error Investigation

This is the start of the file. Read the full SKILL.md on GitHub.

Security

  • Security scanPassed, 100 of 100Pattern checks on the skill's files.
  • Model reviewNot runA model review is scheduled for the next rescan.

Quality evaluation

  • Task evaluationNot runNo evaluation yet. Run one in Skill Studio.

Source

Popularity

7-day trend score
5

Not refreshed yet.

Extension points

  • configConfiguration overrides

Works with

Any agent vskill installs to: 56 targets in all. These 39 have a page on this site.

  • Claude Code
  • Cursor
  • GitHub Copilot
  • Windsurf
  • Codex
  • Gemini CLI
  • Cline
  • Amp
  • Roo Code
  • Goose
  • Continue
  • Kilo Code
  • Junie
  • Trae
  • OpenHands
  • Qwen Code
  • AI Agent
  • Tabnine Chat
  • Sourcegraph Cody
  • Amazon Q
  • Firebase Genkit
  • Sweep
  • Devin
  • Phind
  • Mentat
  • Claude Desktop
  • Aider
  • GPT Pilot
  • Plandex
  • bolt.new
  • v0
  • Replit Agent
  • Anse
  • TypingMind
  • BetterChatGPT
  • LibreChat
  • Warp AI
  • Pieces
  • Fig AI
Embed badge
vskill VERIFIED badge
[![vskill VERIFIED](https://verified-skill.com/api/v1/skills/shepherdjerred/monorepo/bugsink-helper/badge)](https://verified-skill.com/skills/shepherdjerred/monorepo/bugsink-helper)

Something wrong with this skill or its page? Tell us.