t1k:my-score
| Field | Value |
|---|---|
| Module | t1k-extended |
| Version | 3.5.0 |
| Effort | low |
| Tools | — |
Keywords: contribution score, contributor rank, daily score, how am i doing, leaderboard, monthly score, my contributions, my rank, my score, score today, weekly score
How to invoke
Section titled “How to invoke”/t1k:my-score[--user gh-login]t1k:my-score — Contribution Score & Rank
Section titled “t1k:my-score — Contribution Score & Rank”Shows your daily / weekly / monthly contribution score and rank, the monthly leaderboard, recent contributions, and 3 suggested next actions.
/t1k:my-score/t1k:my-score --user aliceWorkflow
Section titled “Workflow”Step 0 — Flush pending contributions first
Section titled “Step 0 — Flush pending contributions first”Lifetime totals should reflect work done this session. Before fetching, invoke
t1k:contribution-flush (fire-and-forget) so any refs the contribution-capture
hook tracked but never recorded are AI-scored + POSTed first. Skip silently if it
reports nothing pending or no endpoint — never block the score read on it.
Step 1 — Resolve user
Section titled “Step 1 — Resolve user”# If --user flag provided, use it directly.# Otherwise resolve from gh CLI:gh api user --jq .loginStore result as GH_LOGIN.
Step 2 — Fetch score data
Section titled “Step 2 — Fetch score data”TOKEN=$(gh auth token)curl -sf -H "Authorization: Bearer $TOKEN" \ "${T1K_TELEMETRY_ENDPOINT}/api/contributors/me?user=${GH_LOGIN}"
# Monthly leaderboard — `period=monthly` is the CALENDAR month (since the 1st).# Do NOT use `?days=30`, which is a different, rolling window (see Notes).curl -sf -H "Authorization: Bearer $TOKEN" \ "${T1K_TELEMETRY_ENDPOINT}/api/contributors/leaderboard?period=monthly&limit=10"A leaderboard fetch failure is non-fatal: render the score table anyway and note
Leaderboard unavailable. Never let it block the personal score.
If T1K_TELEMETRY_ENDPOINT is not set, output:
Error: T1K_TELEMETRY_ENDPOINT is not configured.Set it via: export T1K_TELEMETRY_ENDPOINT=https://your-worker.workers.devIf curl fails or returns non-200, output:
Could not fetch score for {GH_LOGIN}. Check your GitHub token and org membership.Step 3 — Render response
Section titled “Step 3 — Render response”Parse the JSON response and render as markdown:
## Contribution Score — {user}
| Period | Since | Score | Rank ||---------|-------|-------|-------|| Daily | today 00:00 | {daily_score} | #{daily_rank ?? 'N/A'} || Weekly | Monday 00:00 | {weekly_score} | #{weekly_rank ?? 'N/A'} || Monthly | 1st 00:00 | {monthly_score} | #{monthly_rank ?? 'N/A'} |
### Monthly Leaderboard — since the 1st| # | User | Score | Contribs | Badges ||---|------|-------|----------|--------|| {rank} | {user} | {score} | {contributions} | {badges_count} |...
### Recent Contributions (last 5)| Type | Repo | Date | Score |...
### Suggested Next Actions1. {suggestion[0].reason}2. {suggestion[1].reason}3. {suggestion[2].reason}Round scores to 1 decimal place — the endpoint returns raw floats
(343.59999999999997), and rendering that verbatim reads as a bug.
Always show the caller’s own row. If {GH_LOGIN} is not in the top 10,
append their row beneath a … separator so rank is visible at any position — a
leaderboard that hides the reader is the one thing it must not do. Mark the
caller’s row (bold or a ← marker) wherever it appears.
Ranks are competition-style: ties share a rank and the next rank skips
(#4, #4, #6). That is correct output, not a missing row.
If recent is empty, show: “No contributions recorded yet. Start contributing to climb the leaderboard!”
If suggestions is empty, show: “Great work — no specific suggestions right now. Keep it up!”
- Suggestions are generated server-side from static MVP rules (score vs median, recent activity patterns). Future versions will use AI-enriched recommendations.
- Periods are LOCAL calendar windows, not rolling ones. The response’s
window: "calendar"confirms this. Boundaries are SSOT’d in the worker’ssrc/contributors/time-window.ts:DAY_START= start of day,WEEK_START= the current ISO week’s Monday,MONTH_START= the 1st. So the daily figure resets at midnight, not 24h ago. - Local means UTC+7 (
TZ_OFFSET_HOURS, the team timezone), so “Monday” and “the 1st” are team-local, not UTC. A contribution made at 04:00 UTC Monday already counts toward that week. - The badge/digest aggregate cron runs separately (weekly Mon 01:00 UTC, monthly 1st 00:00 UTC);
it does NOT gate
/me, which computes its windows live per request. period=monthlyis the calendar month;days=30is NOT. The leaderboard accepts both, and they are different windows —period=monthlymaps toMONTH_START(since the 1st) while?days=Ntakes the legacy rolling path. Measured 2026-09-04, four days into the month:period=monthlyreturned 6 contributors / 183 contributions,days=30returned 19 / 2482 — a 13.6x difference, with a different #1. Always passperiod=monthly.days: 30in aperiod=monthlyRESPONSE is a nominal label, not the window. The handler setsdays = 30purely for display while usingMONTH_STARTas the SQL threshold. Trustwindow: "calendar", never thedaysfield, when checking which window you got.- Only The1Studio org members can query this endpoint.
Gotchas
Section titled “Gotchas”gh auth tokenfails ifghis not authenticated. Rungh auth loginfirst.- If a
*_rankis null, the user has no contributions in that window.daily_rankis null far more often than the others — an ordinary day with no merged work — so render it asN/Arather than treating it as an error or a zero. - A rank can look better on a shorter window than a longer one (e.g. daily #1, monthly #2): fewer contributors are active today than this month. That is expected, not a bug.
- The endpoint caches responses for 60s — very recent contributions may not appear immediately.