Skip to content

About

A calm, real-time dashboard of your GitHub organisation: every commit, push and pull request, who made it (and with which AI agent), what changed and what shipped. Self-hosted on Cloudflare Workers + D1 or Node.

Topics

Resources

Code of conduct

Contributing

Security policy

Stars

0 stars

Watchers

0 watching

Forks

Track for Git

Track for Git in 45 seconds: the timeline split by people and AI agents, a commit made with Claude and its diff, stuck pull requests, the plain-words Story, light and dark, desktop and phone
45 seconds, no sound. Watch it as a 1080p video.

Every commit, push and pull request across your GitHub organisation, as it happens: who made it (and with which AI agent), what changed, what is stuck, and what shipped. On one calm page that managers and engineers both read.

Track for Git: commits, deploys and releases of 36 repositories on one timeline, who wrote the code, what needs attention, and an activity heatmap

Deploy to Cloudflare

Big organisations push thousands of commits a day across hundreds of repositories. GitHub shows them one repository at a time, in screens built for the person who wrote the code. Track for Git puts the whole organisation on one timeline, in plain words, and stays fast and current while it does: GitHub's webhooks bring a push within seconds, and polling inside GitHub's rate limits fills in the rest.

It is free and open source (Apache-2.0). You host it yourself on Cloudflare Workers + D1 in a few minutes, or in Node or Docker anywhere else. It reads GitHub with read-only permissions. Your code activity stays in your own account, behind your own sign-in.

What you see

  • The whole organisation on one timeline. Every repository (or the ones you choose), with lanes by repository, person or team. Each bar is split by who made the commits. Deploys from GitHub Deployments, releases and tags sit on the same line. Click a bar to read its commits.
  • Who wrote the code, people and agents. Every commit and pull request says who made it, and with which AI agent: Dana Levi with Claude, Copilot, Ruth Ben with Cursor. Claude, Cursor, Codex, Copilot, Grok, Gemini, Devin, Jules, Aider, Windsurf, Amp and others are recognised out of the box, and you can add your own (below). See what share of the code each one wrote, filter by it, and follow it over time.
  • Pull requests a manager can act on. Open, stuck (no activity for 7 days, configurable), merged and closed. Each shows its review state, CI status, age and size. Needs attention lists what is stuck, what fails CI and what waits on requested changes.
  • Readable changes. For every commit and pull request: the files, the lines added and removed, and a clean diff with line numbers. Lock files and generated code start folded. Long diffs draw a few hundred lines at a time, so a 10,000-line change never freezes the page.
  • Activity heatmaps by repository, person or team, per day in each viewer's own time zone (or the team's, with TIME_ZONE). Each one can also be read as a table.
  • What is live now: the commit your newest successful deploy shipped, one click from its diff.
  • The Story, for people who do not read diffs: each day in plain sentences. How much changed and by whom, the busiest repositories, the pull requests merged, what was deployed and released.
  • Filters that stay in the link. Repository, team, person, agent, branch, path, label and free-text search. Any view can be shared as a URL.
A commit by a person working with Claude, with its files and a readable diff Open pull requests with CI and review state; one open with its files
The Story: each day in plain words On a phone: the commit list On a phone: the overview On a phone: a commit's diff

Light and dark, keyboard-navigable throughout, screen-reader labelled, built to WCAG 2.1 AA, English UI with every string in one file for translation. Every picture here comes from the built-in demo organisation: the people, the company and the code are made up.

Quick start

Try it in one minute, with no token:

git clone https://github.com/qderai/track-for-git && cd track-for-git
npm run demo            # http://localhost:8787: Acme, a made-up organisation, with commits arriving live

(Node 22.13 or later; there is nothing to install for the demo.)

Run it for your organisation: press Deploy to Cloudflare above, or:

npm install
npx wrangler login
npm run deploy          # creates the D1 database, applies the migrations, deploys the Worker

Then follow the one-page setup: connect GitHub with a read-only GitHub App (or a fine-grained token), add the webhook, put the dashboard behind Cloudflare Access or "members of this organisation only" GitHub sign-in, and turn the demo off.

Not on Cloudflare? docker compose up, or node server/node.js: the same app on SQLite (built into Node), with the same settings.

Inside an app you already run? Mount it at a path of that app with track-for-git/embed: the page, its API and the sync on your own Worker, database and sign-in, with your own deploys on the timeline and a Live now tile. See Inside an app you already run.

Make your agents visible

Track for Git recognises an AI agent by the marks agents already leave: its own account (copilot-swe-agent[bot], devin-ai-integration[bot]), the Co-authored-by: trailer many agents add (Claude Code does by default), a footer such as "Generated with Claude Code", or, for a member's pull request, the branch prefix it uses (claude/, codex/, cursor/). Names are matched whole, so Claude Monet and Devin Smith stay people. A branch name is never evidence on a public fork.

Any other agent shows up under its own name when its commits carry one of these trailers:

Assisted-by: Acme Coder
Generated-by: Acme Coder
AI-Agent: Acme Coder

Your company's own agents, with their own accounts or addresses, go in the AGENTS setting:

[{ "id": "forge", "name": "Forge", "logins": ["forge-agent[bot]"], "emails": ["@agents.acme.example"], "names": ["Forge"], "branches": ["forge/"] }]

The six most common agents keep fixed colours, so a colour always means the same agent. Others share "Other agents" in the charts but keep their own names everywhere else. The rules are in src/agents.js: a pull request adding an agent is very welcome.

Qubi: a code reviewer on your own key

The Qubi tab: switching Qubi on, turning on fix PRs, choosing the model and the spend cap, starting a bug hunt, and the runs and findings it records
51 seconds, the demo organisation.

Qubi is the reviewer built into Track for Git. Give it your own model API key and a GitHub App of yours, switch it on in the dashboard's Qubi tab, and it:

  • reviews every pull request and every push to the default branch (after the branch has been quiet for a few minutes, so a burst of pushes is one review), and posts a review with a comment on each line it found a bug on;
  • runs bug hunts over a whole repository, or one folder of it, on a schedule (daily or weekly) or from Run now;
  • opens a pull request with the fix for a finding it is sure of, when you turn that on (it is off by default). Nothing is merged, and nothing is run: a person reviews the fix.

It stays quiet about style. The prompt (src/qubi/prompt.js) asks for bugs and security holes only, each with the file and line, a concrete failing input, what goes wrong, the fix and a severity, and tells the model to read the callers and the validation in front of the code before it reports anything, to drop what it cannot show a failing case for, and that finding nothing is a good result. Every finding must then quote its line word for word: Qubi looks the quote up in the file at the reviewed commit and leaves out any finding whose quote is not there (it also moves a finding to the right line when the model's line number was off). The review says how many it left out.

Money. Every run has a cap, and so does every 7 days; pull requests from outside the organisation (forks, strangers) have a smaller allowance of their own, per author and in total. The caps are checked on the server before any run starts, each call to the model is limited to what the run's cap has left, and the cost is recorded after every call, so a run that fails still counts. You set the caps in the dashboard, and the ceilings they cannot pass in the environment (QUBI_MAX_RUN_USD, QUBI_MAX_WEEK_USD). With the defaults (Claude Haiku 5.5 for reviews, $0.25 a run, $5 a week) a typical pull request review costs about a cent.

What it can touch. The model gets three tools: read a file, list a folder, and search the code, all at the reviewed commit. With a GitHub App, they read through a token minted for that one repository with read permissions only; posting the review, and opening a fix PR, use a second token after the model is done. Text from the pull request (its title, description, diff and code) reaches the model as material to review, never as instructions, and outside authors never get a fix PR. These measures reduce the room for prompt injection; they do not make a model's judgement infallible, so treat Qubi's findings and fixes as a reviewer's suggestions.

Set it up (the details are in docs/setup.md):

npx wrangler d1 migrations apply DB --remote      # migration 0002 adds Qubi's tables (npm run deploy does this)
npx wrangler secret put QUBI_API_KEY              # your Claude API key
npx wrangler secret put QUBI_GITHUB_APP_ID        # a second GitHub App: Contents and Pull requests read & write
npx wrangler secret put QUBI_GITHUB_APP_PRIVATE_KEY
npx wrangler secret put QUBI_ADMINS               # who may change Qubi and start paid runs: logins or emails

Qubi uses the dashboard's own webhook (pushes and pull requests), so its App needs no webhook of its own. The key is never shown in the page, in the API or in a log; the Qubi tab shows only whether it is set.

Which model. QUBI_PROVIDER picks the API, and the key is QUBI_API_KEY (or the provider's usual variable):

QUBI_PROVIDER API Models and prices
anthropic (default) Claude API Built in: Claude Haiku 5.5, Sonnet 5.5, Opus 5.5, Fable 5.1
openai OpenAI You name them in QUBI_MODELS
xai xAI (Grok) QUBI_MODELS
gemini Google Gemini (its OpenAI-compatible endpoint) QUBI_MODELS
mistral, deepseek, groq Mistral, DeepSeek, Groq QUBI_MODELS
openrouter OpenRouter: many providers behind one key QUBI_MODELS
openai-compatible Anything else with OpenAI's Chat Completions: Ollama, vLLM, LM Studio, a gateway (QUBI_API_URL) QUBI_MODELS

QUBI_MODELS lists each model with its price in US dollars per million tokens, input/output and optionally cached input, for example (made-up names and prices) QUBI_MODELS="model-large:3/15, model-small:0.3/0.5/0.075". The first is the default for reviews, the second for bug hunts; a local model is free (llama3:0/0). Qubi does not run without prices, because the caps are only as good as they are. Copy them from your provider's price page and update them when it changes.

Cursor has no model API of its own to point Qubi at (inside Cursor, "your own key" means Cursor calling your provider), so it is not a QUBI_PROVIDER. Another API fits in one file (src/qubi/providers/): a pull request adding one is welcome.

How it works

GitHub ──webhook (HMAC-SHA256)──▶ ┐
                                  ├──▶ Worker ──▶ D1 (metadata only) ──▶ the page (static, no framework)
GitHub ◀──GraphQL + REST, read-only, every minute──┘        └──▶ diffs on demand, cached, never stored
  • Real time: webhooks for pushes, pull requests, reviews, checks, deploys, releases and tags. Every delivery is checked against its signature. Redeliveries are handled once. Repositories you do not watch are ignored.
  • Polling as the fallback and the backfill, from a cron trigger once a minute. It lists the organisation's repositories newest-push first (an unchanged list costs nothing thanks to ETags), and touches only the repositories that changed. It asks GraphQL about five at a time in one request: their new commits with line counts, their pull requests with review decision and CI, their deploys, releases and tags. REST then fetches the pushes to other branches. Every answer's rate limit is read, a 10% reserve is kept for people opening diffs, and on a 403/429 it waits for the reset. With hundreds of repositories, a quiet minute usually costs one conditional request, which GitHub does not count against the limit.
  • Stored: commit and pull request metadata (who, when, which repository and branch, how many lines, which paths), for 180 days by default. Never stored: diffs and file contents. They are fetched from GitHub when someone opens a commit and kept only in the HTTP cache.
  • Fast with thousands of commits a day: every list is paginated with a keyset cursor and virtualised in the page (only the rows on screen exist). Answers are computed once every few seconds for everyone. Charts are aggregated in SQL, in the viewer's time zone, daylight saving included.

Security and privacy

  • Read-only GitHub permissions. The only POSTs to GitHub are GraphQL queries, the App's token exchange and the sign-in's code exchange. Qubi, the optional reviewer, writes (reviews, comments and, when allowed, fix PRs) through a GitHub App of its own, never through the dashboard's credentials.
  • The dashboard refuses to show any data until you choose who may open it (AUTH). With Cloudflare Access, the Worker also verifies Access's signed token on every API request. With GitHub sign-in, membership is checked with the dashboard's own credentials, and the person's GitHub token is dropped after sign-in.
  • Secrets are only ever environment secrets. They are never shown, logged or stored in the database.
  • A strict Content Security Policy: the page loads nothing from any other origin (no CDN, no fonts, no avatars), and every message, name and line of code is inserted as text.
  • Found a problem? See SECURITY.md.

Development

npm test                 # node:test, against real SQLite with the real migrations
npm run demo             # the app on Node with the demo
npm run dev              # the app on wrangler dev with a local D1 (DEMO=1 by default)
npm run screenshots      # the README's pictures (needs playwright-core and Chrome)
npm run build:embed      # after changing public/: src/embed-assets.js, the page for track-for-git/embed
src/          the Worker: app.js (routes), sync.js (polling), webhook.js, queries.js (the read side), agents.js,
              auth.js, demo.js, embed.js (mounting inside another app), github/ (client, App sign-in, GraphQL,
              payloads into rows)
public/       the page: no framework, no build; js/, styles.css, locales/en.js (every word)
server/       Node and Docker
migrations/   D1 / SQLite schema

To translate the page, copy public/locales/en.js, translate the values, and add the language in public/js/i18n.js.

License

Apache-2.0, copyright 2026 Qder AI. See LICENSE and NOTICE. The Qder.ai name and logo are trademarks of Qder AI and are not covered by the license.

Track for Git is not affiliated with or endorsed by the Git project or GitHub. Git is a trademark of the Software Freedom Conservancy; GitHub is a trademark of GitHub, Inc.


Built by Qder.ai
Built by Qder.ai. We built it for ourselves first, to watch our own engineers and agents ship, then opened it up.

About

A calm, real-time dashboard of your GitHub organisation: every commit, push and pull request, who made it (and with which AI agent), what changed and what shipped. Self-hosted on Cloudflare Workers + D1 or Node.

Topics

Resources

Code of conduct

Contributing

Security policy

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages