Skill Usage Tracking via Direct Supabase Ping
Architecture
flowchart LR subgraph cursor [Cursor Agent] skill[Skill / Command / Rule] ping["scripts/skill-ping.sh"] end subgraph supabase [Supabase REST API] rest["POST /rest/v1/skill_usage_events"] table[(skill_usage_events)] end skill -->|"bash scripts/skill-ping.sh name type"| ping ping -->|"curl --max-time 3 || true"| rest rest --> table
No MCP. No SDK. Plain curl over HTTPS — same transport Supabase JS SDK uses internally.
Env vars
Reuses the env vars already set up by cursor history sync (in each user’s .env.local):
CURSOR_HISTORY_API_URL(falls back toBF_SUPABASE_URL)CURSOR_HISTORY_API_KEY(falls back toBF_SUPABASE_SERVICE_KEY)CURSOR_USER_EMAIL(falls back togit config user.email)
Files to Create
1. [supabase/migrations/20260320000000_skill_usage_events.sql](supabase/migrations/20260320000000_skill_usage_events.sql)
New table in the same Supabase project as cursor history:
CREATE TABLE public.skill_usage_events (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
type TEXT NOT NULL, -- 'skill' | 'command' | 'rule'
name TEXT NOT NULL, -- e.g. 'meeting-prep', 'linear-audit'
user_email TEXT NOT NULL,
workspace TEXT,
invoked_at TIMESTAMP WITH TIME ZONE DEFAULT now() NOT NULL
);
CREATE INDEX ON public.skill_usage_events (user_email);
CREATE INDEX ON public.skill_usage_events (name);
CREATE INDEX ON public.skill_usage_events (invoked_at);
ALTER TABLE public.skill_usage_events ENABLE ROW LEVEL SECURITY;
CREATE POLICY "Enable read for all" ON public.skill_usage_events FOR SELECT USING (true);
CREATE POLICY "Enable insert for all" ON public.skill_usage_events FOR INSERT WITH CHECK (true);2. [scripts/skill-ping.sh](scripts/skill-ping.sh)
Single shared script all assets call. Key properties:
--max-time 3: never blocks the skill for more than 3s|| true: never propagates failure- Silently exits if env vars are not configured
- Resolves user email from env → git config → fallback
#!/bin/bash
# Usage: bash scripts/skill-ping.sh <name> <type: skill|command|rule>
NAME="${1:-unknown}"
TYPE="${2:-skill}"
USER_EMAIL="${CURSOR_USER_EMAIL:-$(git config user.email 2>/dev/null)}"
USER_EMAIL="${USER_EMAIL:-unknown@brainforge.ai}"
WORKSPACE=$(basename "$(git rev-parse --show-toplevel 2>/dev/null)" 2>/dev/null || basename "$PWD")
URL="${CURSOR_HISTORY_API_URL:-${BF_SUPABASE_URL:-}}"
KEY="${CURSOR_HISTORY_API_KEY:-${BF_SUPABASE_SERVICE_KEY:-}}"
[ -z "$URL" ] || [ -z "$KEY" ] && exit 0
curl -s -o /dev/null --max-time 3 \
-X POST "${URL}/rest/v1/skill_usage_events" \
-H "apikey: ${KEY}" \
-H "Authorization: Bearer ${KEY}" \
-H "Content-Type: application/json" \
-d "{\"type\":\"${TYPE}\",\"name\":\"${NAME}\",\"user_email\":\"${USER_EMAIL}\",\"workspace\":\"${WORKSPACE}\",\"invoked_at\":\"$(date -u +%Y-%m-%dT%H:%M:%SZ)\"}" || trueFiles to Modify
3. All Skills — ~60 SKILL.md files
Add a tracking block at the very top of the workflow body (before Step 1 / any user interaction), using the skill’s folder name as name:
## Tracking
Fire a silent usage ping before starting (non-blocking):
Run shell: `bash scripts/skill-ping.sh "meeting-prep" "skill"`Skills to update — in priority order:
- Phase A (high-traffic, update first):
meeting-prep,linear-audit(command + rule),end-of-week-update,weekly-kick-off-update,standup-deck,client-health-scorecard,client-touchpoint-drafter,gtm-ticket-creation,linear-sow-alignment,instagantt-linear-sync - Phase B (remaining Brainforge skills): all other
.cursor/skills/{name}/SKILL.mdfiles - Phase C (Anthropic skills): all
.cursor/skills/anthropic-skills/skills/{name}/SKILL.mdfiles
4. All Commands — 13 .cursor/commands/*.md files
Add one line at the very top before all other instructions:
Before starting, fire a silent ping: `bash scripts/skill-ping.sh "linear-audit" "command"`All 13 files: linear-audit.md, end-of-week-update.md, weekly-kick-off-update.md, post-call-to-tickets.md, draft-client-follow-up-email.md, client-email-context.md, prepare-standup-deck.md, enrich-ops-ticket.md, eod-updates-review.md, eow-updates-review.md, archive-client.md, iterate-browser.md, council.md
5. Agent-Requestable Rules — ~25 .cursor/rules/*.mdc files
Only rules that are consciously followed (agent-requestable, not always-applied). Add one line at the top of the rule body:
When following this rule, first fire a silent ping: `bash scripts/skill-ping.sh "end-of-week-update" "rule"`Covers rules like: end-of-week-update.mdc, linear-audit.mdc, weekly-kick-off-update.mdc, client-health-scorecard.mdc, client-touchpoint-drafter.mdc, data-platform-doc-update.mdc, data-platform-doc-kickoff.mdc, data-platform-doc-backfill.mdc, sow-vs-delivered-audit.mdc, email-client-follow-up.mdc, email-client-context.mdc, monthly-executive-brief.mdc, expansion-signals-digest.mdc, escalation-triage.mdc, standup-deck-workflow.mdc, instagantt-linear-sync.mdc, enrich-ops-ticket.mdc, client-engagement-kickoff.mdc, linear-mcp-ticket-standards.mdc, supabase-slack-context.mdc, hubspot-logging.mdc
Always-applied rules (e.g. knowledge-standards.mdc, commit-messages.mdc, no-secrets-in-repo.mdc) are not modified — they are ambient context, not invocations.
6. Skill Template + Skill Creator
[skills/anthropic-skills/template/SKILL.md](skills/anthropic-skills/template/SKILL.md)— add the tracking block so all new skills include it by default[.cursor/skills/skill-creator/SKILL.md](.cursor/skills/skill-creator/SKILL.md)— add instruction to always include the tracking block when generating new skills
7. Playbook Doc
Update [standards/01-onboarding/setup-cursor-history-sync.md](standards/01-onboarding/setup-cursor-history-sync.md) to document the new skill_usage_events table and that the same env vars power both the history sync and the skill ping.