{"id":50275417,"url":"https://github.com/debba/gitdeck","last_synced_at":"2026-05-27T20:01:50.996Z","repository":{"id":354579272,"uuid":"1224251504","full_name":"debba/gitdeck","owner":"debba","description":"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.","archived":false,"fork":false,"pushed_at":"2026-05-21T15:51:19.000Z","size":32282,"stargazers_count":330,"open_issues_count":2,"forks_count":35,"subscribers_count":2,"default_branch":"main","last_synced_at":"2026-05-21T22:19:18.921Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":"","language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/debba.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":"AGENTS.md","dco":null,"cla":null}},"created_at":"2026-04-29T05:21:26.000Z","updated_at":"2026-05-21T18:27:18.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/debba/gitdeck","commit_stats":null,"previous_names":["debba/gh-dashboard","debba/gitdeck"],"tags_count":4,"template":false,"template_full_name":null,"purl":"pkg:github/debba/gitdeck","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/debba%2Fgitdeck","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/debba%2Fgitdeck/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/debba%2Fgitdeck/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/debba%2Fgitdeck/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/debba","download_url":"https://codeload.github.com/debba/gitdeck/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/debba%2Fgitdeck/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":33581559,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-26T15:22:16.424Z","status":"online","status_checked_at":"2026-05-27T02:00:06.184Z","response_time":53,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2026-05-27T20:01:50.214Z","updated_at":"2026-05-27T20:01:50.985Z","avatar_url":"https://github.com/debba.png","language":"TypeScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Gitdeck\n\n\u003e 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.\n\n\u003cp align=\"center\"\u003e\n  \u003ca href=\"https://discord.gg/YrZPHAwMSG\"\u003e\u003cimg src=\"https://img.shields.io/discord/1470772941296894128?color=5865F2\u0026logo=discord\u0026logoColor=white\u0026label=Discord\" alt=\"Discord\" /\u003e\u003c/a\u003e\n\u003c/p\u003e\n\n\u003cp align=\"center\"\u003e\n  \u003ca href=\"https://repostars.dev/?repos=debba%2Fgh-dashboard\u0026theme=dark\"\u003e\u003cimg src=\"https://repostars.dev/api/embed?repo=debba%2Fgh-dashboard\u0026theme=dark\" alt=\"RepoStars\" /\u003e\u003c/a\u003e\n\u003c/p\u003e\n\nAn 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.\n\n## Demo\n\n\u003cdiv align=\"center\"\u003e\n  \u003cimg src=\"public/demo.gif\" alt=\"Gitdeck demo\" /\u003e\n\u003c/div\u003e\n\n## What it does\n\nThe dashboard pulls data from the GitHub REST and GraphQL APIs and organizes it into a few different views:\n\n- **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.\n- **Issues / Pull Requests** — cross-repo lists with the same filter sidebar, useful for triage across many projects.\n- **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).\n- **Alerts** — dedicated security-alert view for Dependabot and code scanning findings, so you can jump straight to the repos that need attention.\n- **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.\n- **Board** — Kanban-style view that groups issues into columns (Backlog, To-do, In progress, Ready, In review, etc.).\n\n### Per-repository view\n\nOpen any repository to see:\n\n- **Overview** — stars, forks, open issues, owner, license, default branch, last push.\n- **Security and quality** — Dependabot and code scanning alert summaries for the repository, with a fallback note when GitHub does not expose the data.\n- **Actions** — recent workflow runs.\n- **PRs** and **Issues** — open and recent items, paginated.\n- **Releases** — release history.\n- **Forks** — list of forks, sortable by most stars or recent push.\n- **Traffic** — views and clones for the last 14 days, unique visitors/cloners, top referrers, popular paths.\n- **Mentions** — references to the repo found via GitHub code/issue search, including previous names of the project.\n- **Dependents** — repository relationships, where available.\n- **Languages and trend charts** — language breakdown and stars/forks history.\n- **Contributors** — paginated list with commit counts.\n\n## Architecture\n\nThe app is a single repository with two cooperating processes:\n\n- **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**.\n- **Frontend** — a React 19 + Vite SPA (`src/main.tsx`, `src/App.tsx`, `src/components/*`, `src/api/*`) that consumes the backend's `/api/*` endpoints.\n\nIn 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.\n\n### Tech stack\n\n| Layer       | Tech                                           |\n| ----------- | ---------------------------------------------- |\n| Language    | TypeScript                                     |\n| Frontend    | React 19, Vite 8                               |\n| Backend     | Node `http` + `tsx` watch (dev), compiled JS in production |\n| Tests       | Vitest + jsdom                                 |\n| Tooling     | `concurrently`, `tsc`                          |\n\n### Translations\n\nUI 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.\n\n## Prerequisites\n\n- **Node.js 20+** (anything that supports native `fetch` and ESM is fine).\n- A **GitHub OAuth App** with **Device Flow enabled** (see next section).\n- (Optional) An **OpenAI API key** if you want AI-generated daily digest summaries.\n\n## Configure GitHub\n\nThe 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.\n\n### 1. Create the OAuth App\n\n1. Go to \u003chttps://github.com/settings/developers\u003e → **OAuth Apps** → **New OAuth App**.\n   (For an org-owned app, use **Settings → Developer settings → OAuth Apps** on the organization instead.)\n2. Fill in the form:\n   - **Application name** — anything, e.g. `Gitdeck (local)`.\n   - **Homepage URL** — `http://127.0.0.1:8765` (or any URL you control; this is informational).\n   - **Authorization callback URL** — `http://127.0.0.1:8765` will do. Device Flow does not actually use a redirect, but GitHub requires the field.\n3. Click **Register application**.\n\n### 2. Enable Device Flow\n\nOn 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`.\n\n### 3. Copy the Client ID\n\nYou 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.\n\n### 4. Export it before starting the server\n\n```bash\nexport GITHUB_CLIENT_ID=Iv1.xxxxxxxxxxxxxxxx\n```\n\nYou 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.\n\n### 5. Sign in from the UI\n\nWhen you open the dashboard for the first time, it will:\n\n1. call the backend, which asks GitHub for a **device code**;\n2. show you a short **user code** and a verification URL (typically \u003chttps://github.com/login/device\u003e);\n3. you paste the code on GitHub and approve the requested scopes;\n4. the backend exchanges the device code for an access token and stores it in `~/.gitdeck/` — **the token never reaches the browser**.\n\nGranted 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 \u003chttps://github.com/settings/applications\u003e and delete the local token file under `~/.gitdeck/`.\n\n## Configuration\n\nThe server reads its configuration from environment variables:\n\n| Variable               | Required | Default                                        | Purpose                                          |\n| ---------------------- | -------- | ---------------------------------------------- | ------------------------------------------------ |\n| `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`. |\n| `GITHUB_CLIENT_ID`     | only `device` | —                                         | Client ID of your GitHub OAuth App (Device Flow) |\n| `GITHUB_OAUTH_SCOPES`  | no       | `repo read:org project read:user user:email`   | OAuth scopes requested at sign-in (Device Flow)  |\n| `GITHUB_TOKEN`         | only `token` | —                                          | Personal access token used when `GH_AUTH_MODE=token` |\n| `HOST`                 | no       | `127.0.0.1`                                    | Interface the server binds to                    |\n| `PORT`                 | no       | `8765`                                         | Port the server listens on                       |\n| `OPENAI_API_KEY`       | no       | —                                              | Enables AI-generated daily digest narratives     |\n| `OPENAI_DIGEST_MODEL`  | no       | `gpt-4.1-mini`                                 | Model used for digest narratives                 |\n\n### Authentication modes\n\nThe dashboard can obtain a GitHub token in three different ways. Pick the one that fits your setup:\n\n- **`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`.\n- **`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.\n- **`token`** — bring-your-own personal access token. Set `GH_AUTH_MODE=token` and export `GITHUB_TOKEN=\u003cyour-pat\u003e`. Useful for headless / CI-style deployments.\n\nIn `gh-cli` and `token` modes the device-flow sign-in screen is hidden; the server treats the configured source as authoritative.\n\nTokens 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.\n\n### Quick env setup\n\n```bash\nexport GITHUB_CLIENT_ID=Iv1.xxxxxxxxxxxxxxxx\n# optional\nexport OPENAI_API_KEY=sk-...\n```\n\n## Install\n\n```bash\nnpm install\n```\n\n## Run in development\n\nStarts 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`.\n\n```bash\nnpm run dev\n```\n\nThen open \u003chttp://127.0.0.1:5173\u003e. On first launch the UI will walk you through the GitHub Device Flow sign-in.\n\nIf you only want one of the two processes:\n\n```bash\nnpm run api    # backend only, on http://127.0.0.1:8765\n```\n\n## Build\n\nType-checks the server, compiles it to `dist/`, and produces the production frontend bundle under `dist/client/`:\n\n```bash\nnpm run build\n```\n\n## Run the production build\n\nAfter `npm run build`, the Node server can serve both the API and the built SPA from a single port:\n\n```bash\nnpm start\n# or, equivalently\nnpm run serve\n```\n\nThen open \u003chttp://127.0.0.1:8765\u003e.\n\n`npm run preview` is also available if you want to preview only the static frontend through Vite (no backend).\n\n## Run with Docker\n\nA 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`.\n\nIf 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.\n\nWith Docker Compose (recommended):\n\n```bash\ncat \u003e .env \u003c\u003c'EOF'\nGITHUB_CLIENT_ID=Iv1.xxxxxxxxxxxxxxxx\n# Optional — enables AI-generated daily digest narratives\nOPENAI_API_KEY=sk-...\n# Optional overrides\n# OPENAI_DIGEST_MODEL=gpt-4.1-mini\n# GITHUB_OAUTH_SCOPES=repo read:org project read:user user:email\nEOF\ndocker compose up -d --build\n# open http://127.0.0.1:8765\n```\n\nWith plain Docker:\n\n```bash\ndocker build -t gitdeck .\ndocker run -d --name gitdeck \\\n  -p 8765:8765 \\\n  -e GITHUB_CLIENT_ID=Iv1.xxxxxxxxxxxxxxxx \\\n  -e OPENAI_API_KEY=sk-... \\\n  -v gitdeck-data:/home/node/.gitdeck \\\n  gitdeck\n```\n\nThe 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`.\n\n## Test \u0026 type-check\n\n```bash\nnpm test          # vitest run\nnpm run typecheck # tsc --noEmit\n```\n\nTests live under `tests/` and mirror the structure of `src/` (see [AGENTS.md](AGENTS.md)).\n\n## Project layout\n\n```\n.\n├── index.html                 # SPA entrypoint consumed by Vite\n├── src/\n│   ├── main.tsx               # React bootstrap\n│   ├── App.tsx                # Top-level component \u0026 routing\n│   ├── api/                   # Browser-side API client (calls /api/*)\n│   ├── components/            # UI: views, modals, common, sidebar, top bar\n│   ├── styles/                # CSS modules (tokens, layout, views, modals, …)\n│   ├── server.ts              # Node HTTP server entrypoint\n│   ├── server/                # OAuth, GitHub client, caches, digests, insights\n│   ├── types/github.ts        # Shared TypeScript types\n│   └── utils/                 # Pure logic (covered by unit tests)\n├── tests/                     # Vitest suites mirroring src/\n├── docs/                      # Contributor documentation\n├── public/                    # Static assets (demo media)\n├── vite.config.ts\n├── tsconfig.json              # Frontend TS config\n└── tsconfig.server.json       # Server TS config (build → dist/)\n```\n\n## Status\n\nEarly scaffolding. APIs, modules, and the UI are still being shaped — expect rapid changes. Star the repo and join Discord to follow along.\n\n## Community\n\n- [Discord server](https://discord.gg/YrZPHAwMSG) — suggest features, report issues, or just say hi.\n\n## Contributing\n\nBefore 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`.\n\n## License\n\nMIT License — see [LICENSE](LICENSE).\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdebba%2Fgitdeck","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fdebba%2Fgitdeck","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdebba%2Fgitdeck/lists"}