https://github.com/debba/gitdeck
Open-source Git dashboard built for GIthub and Forejo on REST and GraphQL APIs: repositories, issues, pull requests, traffic, Actions, contributors, dependents, and a kanban board view.
https://github.com/debba/gitdeck
Last synced: about 1 month ago
JSON representation
Open-source Git dashboard built for GIthub and Forejo on REST and GraphQL APIs: repositories, issues, pull requests, traffic, Actions, contributors, dependents, and a kanban board view.
- Host: GitHub
- URL: https://github.com/debba/gitdeck
- Owner: debba
- License: mit
- Created: 2026-04-29T05:21:26.000Z (2 months ago)
- Default Branch: main
- Last Pushed: 2026-05-21T15:51:19.000Z (about 1 month ago)
- Last Synced: 2026-05-21T22:19:18.921Z (about 1 month ago)
- Language: TypeScript
- Homepage:
- Size: 30.8 MB
- Stars: 330
- Watchers: 2
- Forks: 35
- Open Issues: 2
-
Metadata Files:
- Readme: README.md
- Changelog: CHANGELOG.md
- License: LICENSE
- Agents: AGENTS.md
Awesome Lists containing this project
README
# Gitdeck
> The initial scaffolding of this repository was produced in an AI-assisted session with [Claude Code](https://claude.com/claude-code). From here on, code is reviewed and maintained by humans, and contributions are welcome.
An open-source, local dashboard to explore repositories, issues, pull requests, traffic, and CI activity across multiple accounts on GitHub and Forgejo-compatible forges (Codeberg, self-hosted) — from a single interface.
## Demo
## What it does
The dashboard pulls data from the GitHub REST and GraphQL APIs and organizes it into a few different views:
- **Repositories** — paginated grid with description, language, stars, forks, open issues, last push and a per-repo health score. Filter by organization, language, visibility, forks/archived; sort by stars, recent activity, etc.
- **Issues / Pull Requests** — cross-repo lists with the same filter sidebar, useful for triage across many projects.
- **Insights** — overview of all repos with alerts ("issues need attention", "security alerts need attention", "no push for X days"), opportunities, and correlations between traffic and recent activity. Each repo gets a status (Strong / Watch / Risky).
- **Alerts** — dedicated security-alert view for Dependabot and code scanning findings, so you can jump straight to the repos that need attention.
- **Daily digest** — short per-repo summary of the day's movement (stars, forks, issues), with an executive summary you can copy as Markdown. Optionally augmented by an OpenAI-generated narrative when `OPENAI_API_KEY` is configured.
- **Board** — Kanban-style view that groups issues into columns (Backlog, To-do, In progress, Ready, In review, etc.).
### Per-repository view
Open any repository to see:
- **Overview** — stars, forks, open issues, owner, license, default branch, last push.
- **Security and quality** — Dependabot and code scanning alert summaries for the repository, with a fallback note when GitHub does not expose the data.
- **Actions** — recent workflow runs.
- **PRs** and **Issues** — open and recent items, paginated.
- **Releases** — release history.
- **Forks** — list of forks, sortable by most stars or recent push.
- **Traffic** — views and clones for the last 14 days, unique visitors/cloners, top referrers, popular paths.
- **Mentions** — references to the repo found via GitHub code/issue search, including previous names of the project.
- **Dependents** — repository relationships, where available.
- **Languages and trend charts** — language breakdown and stars/forks history.
- **Contributors** — paginated list with commit counts.
## Architecture
The app is a single repository with two cooperating processes:
- **Backend** — a Node HTTP server (`src/server.ts` + `src/server/*`) that handles GitHub OAuth (Device Flow), proxies all REST/GraphQL calls, caches responses on disk, and exposes a small JSON API under `/api/*`. The GitHub token is stored locally under `~/.gitdeck/` and **never exposed to the browser**.
- **Frontend** — a React 19 + Vite SPA (`src/main.tsx`, `src/App.tsx`, `src/components/*`, `src/api/*`) that consumes the backend's `/api/*` endpoints.
In production both are served by the Node process: Vite builds the SPA into `dist/client/` and the server falls back to `index.html` for non-API routes.
### Tech stack
| Layer | Tech |
| ----------- | ---------------------------------------------- |
| Language | TypeScript |
| Frontend | React 19, Vite 8 |
| Backend | Node `http` + `tsx` watch (dev), compiled JS in production |
| Tests | Vitest + jsdom |
| Tooling | `concurrently`, `tsc` |
### Translations
UI translations live in `src/i18n/`, with one dictionary file per language. See [docs/translations.md](docs/translations.md) for the workflow to edit text or add another language.
## Prerequisites
- **Node.js 20+** (anything that supports native `fetch` and ESM is fine).
- A **GitHub OAuth App** with **Device Flow enabled** (see next section).
- (Optional) An **OpenAI API key** if you want AI-generated daily digest summaries.
## Configure GitHub
The dashboard talks to GitHub using a personal **OAuth App** with the **Device Authorization Flow**. This means you keep ownership of the credentials and there is no client secret to manage. You only have to do this once.
### 1. Create the OAuth App
1. Go to → **OAuth Apps** → **New OAuth App**.
(For an org-owned app, use **Settings → Developer settings → OAuth Apps** on the organization instead.)
2. Fill in the form:
- **Application name** — anything, e.g. `Gitdeck (local)`.
- **Homepage URL** — `http://127.0.0.1:8765` (or any URL you control; this is informational).
- **Authorization callback URL** — `http://127.0.0.1:8765` will do. Device Flow does not actually use a redirect, but GitHub requires the field.
3. Click **Register application**.
### 2. Enable Device Flow
On the OAuth App's settings page, tick **Enable Device Flow** and **Update application**. This is required — without it, sign-in will fail with `unsupported_grant_type`.
### 3. Copy the Client ID
You only need the **Client ID** (it looks like `Iv1.xxxxxxxxxxxxxxxx` or `Ov23li...`). **Do not** generate a client secret — Device Flow does not use one, and the dashboard never reads it.
### 4. Export it before starting the server
```bash
export GITHUB_CLIENT_ID=Iv1.xxxxxxxxxxxxxxxx
```
You can also put it in a `.env` file or your shell profile. The server reads `process.env.GITHUB_CLIENT_ID` at startup and will refuse to start the OAuth flow without it.
### 5. Sign in from the UI
When you open the dashboard for the first time, it will:
1. call the backend, which asks GitHub for a **device code**;
2. show you a short **user code** and a verification URL (typically );
3. you paste the code on GitHub and approve the requested scopes;
4. the backend exchanges the device code for an access token and stores it in `~/.gitdeck/` — **the token never reaches the browser**.
Granted scopes default to `repo read:org project read:user user:email`. To narrow them, set `GITHUB_OAUTH_SCOPES` (see [Configuration](#configuration)). If you ever want to revoke access, remove the app from and delete the local token file under `~/.gitdeck/`.
## Configuration
The server reads its configuration from environment variables:
| Variable | Required | Default | Purpose |
| ---------------------- | -------- | ---------------------------------------------- | ------------------------------------------------ |
| `GH_AUTH_MODE` | no | `device` | Auth source: `device` (OAuth Device Flow), `gh-cli` (reuse local `gh` CLI), or `token` (use `GITHUB_TOKEN`). Aliases accepted: `GITHUB_AUTH_MODE`, `GITHUB_MODE`. |
| `GITHUB_CLIENT_ID` | only `device` | — | Client ID of your GitHub OAuth App (Device Flow) |
| `GITHUB_OAUTH_SCOPES` | no | `repo read:org project read:user user:email` | OAuth scopes requested at sign-in (Device Flow) |
| `GITHUB_TOKEN` | only `token` | — | Personal access token used when `GH_AUTH_MODE=token` |
| `HOST` | no | `127.0.0.1` | Interface the server binds to |
| `PORT` | no | `8765` | Port the server listens on |
| `OPENAI_API_KEY` | no | — | Enables AI-generated daily digest narratives |
| `OPENAI_DIGEST_MODEL` | no | `gpt-4.1-mini` | Model used for digest narratives |
### Authentication modes
The dashboard can obtain a GitHub token in three different ways. Pick the one that fits your setup:
- **`device` (default)** — OAuth App + Device Flow, as described above. The token is stored under `~/.gitdeck/` and refreshed via the in-app sign-in screen. Requires `GITHUB_CLIENT_ID`.
- **`gh-cli`** — if you already use the [GitHub CLI](https://cli.github.com/), set `GH_AUTH_MODE=gh-cli` and the server will read the token by running `gh auth token` on each request (cached in-process for 60s). No OAuth App is needed; the scopes are whatever your `gh` session already has. Run `gh auth refresh -h github.com -s repo,read:org,project` if you need extra scopes.
- **`token`** — bring-your-own personal access token. Set `GH_AUTH_MODE=token` and export `GITHUB_TOKEN=`. Useful for headless / CI-style deployments.
In `gh-cli` and `token` modes the device-flow sign-in screen is hidden; the server treats the configured source as authoritative.
Tokens and snapshots are persisted under `~/.gitdeck/`. If you previously ran an older build that stored data in `~/.gh-issues-dashboard/`, the server migrates it automatically on first start.
### Quick env setup
```bash
export GITHUB_CLIENT_ID=Iv1.xxxxxxxxxxxxxxxx
# optional
export OPENAI_API_KEY=sk-...
```
## Install
```bash
npm install
```
## Run in development
Starts the API server (with file-watch reload) and the Vite dev server in parallel. The Vite dev server proxies `/api` to the backend on port `8765`.
```bash
npm run dev
```
Then open . On first launch the UI will walk you through the GitHub Device Flow sign-in.
If you only want one of the two processes:
```bash
npm run api # backend only, on http://127.0.0.1:8765
```
## Build
Type-checks the server, compiles it to `dist/`, and produces the production frontend bundle under `dist/client/`:
```bash
npm run build
```
## Run the production build
After `npm run build`, the Node server can serve both the API and the built SPA from a single port:
```bash
npm start
# or, equivalently
npm run serve
```
Then open .
`npm run preview` is also available if you want to preview only the static frontend through Vite (no backend).
## Run with Docker
A multi-stage `Dockerfile` and a `docker-compose.yml` are provided. The image builds the server + SPA bundle and runs as a non-root user; tokens and snapshots are persisted to a named volume mounted at `/home/node/.gitdeck`.
If you already have an older compose file, make sure the persistent volume is mounted at `/home/node/.gitdeck` and not the legacy `/home/node/.gh-issues-dashboard` path, otherwise the login state will not survive restarts.
With Docker Compose (recommended):
```bash
cat > .env <<'EOF'
GITHUB_CLIENT_ID=Iv1.xxxxxxxxxxxxxxxx
# Optional — enables AI-generated daily digest narratives
OPENAI_API_KEY=sk-...
# Optional overrides
# OPENAI_DIGEST_MODEL=gpt-4.1-mini
# GITHUB_OAUTH_SCOPES=repo read:org project read:user user:email
EOF
docker compose up -d --build
# open http://127.0.0.1:8765
```
With plain Docker:
```bash
docker build -t gitdeck .
docker run -d --name gitdeck \
-p 8765:8765 \
-e GITHUB_CLIENT_ID=Iv1.xxxxxxxxxxxxxxxx \
-e OPENAI_API_KEY=sk-... \
-v gitdeck-data:/home/node/.gitdeck \
gitdeck
```
The container forwards `GITHUB_CLIENT_ID`, `GITHUB_OAUTH_SCOPES`, `OPENAI_API_KEY` and `OPENAI_DIGEST_MODEL` from the host environment (or `.env` with Compose) — see [Configuration](#configuration) for the full list. It sets `HOST=0.0.0.0` so the server is reachable from outside. To wipe the stored token (full logout) remove the volume: `docker volume rm gitdeck-data`.
## Test & type-check
```bash
npm test # vitest run
npm run typecheck # tsc --noEmit
```
Tests live under `tests/` and mirror the structure of `src/` (see [AGENTS.md](AGENTS.md)).
## Project layout
```
.
├── index.html # SPA entrypoint consumed by Vite
├── src/
│ ├── main.tsx # React bootstrap
│ ├── App.tsx # Top-level component & routing
│ ├── api/ # Browser-side API client (calls /api/*)
│ ├── components/ # UI: views, modals, common, sidebar, top bar
│ ├── styles/ # CSS modules (tokens, layout, views, modals, …)
│ ├── server.ts # Node HTTP server entrypoint
│ ├── server/ # OAuth, GitHub client, caches, digests, insights
│ ├── types/github.ts # Shared TypeScript types
│ └── utils/ # Pure logic (covered by unit tests)
├── tests/ # Vitest suites mirroring src/
├── docs/ # Contributor documentation
├── public/ # Static assets (demo media)
├── vite.config.ts
├── tsconfig.json # Frontend TS config
└── tsconfig.server.json # Server TS config (build → dist/)
```
## Status
Early scaffolding. APIs, modules, and the UI are still being shaped — expect rapid changes. Star the repo and join Discord to follow along.
## Community
- [Discord server](https://discord.gg/YrZPHAwMSG) — suggest features, report issues, or just say hi.
## Contributing
Before opening a PR, please skim [AGENTS.md](AGENTS.md) for the project conventions (English-only identifiers, pure logic in `src/utils/` with mirrored tests, no GitHub tokens on the browser, etc.) and run `npm test` + `npm run build`.
## License
MIT License — see [LICENSE](LICENSE).