{"id":51179081,"url":"https://github.com/mhdnazrul/codeforcessync","last_synced_at":"2026-06-27T06:01:03.992Z","repository":{"id":344544328,"uuid":"1182156314","full_name":"mhdnazrul/CodeforcesSync","owner":"mhdnazrul","description":"Automatically sync your Codeforces accepted solutions to GitHub using a Chrome Extension.","archived":false,"fork":false,"pushed_at":"2026-06-26T05:52:23.000Z","size":1334,"stargazers_count":5,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2026-06-26T07:20:35.044Z","etag":null,"topics":["automation","chrome-extension","codeforces","competitive-programming","developer-tools","github-api","javascript","manifest-v3"],"latest_commit_sha":null,"homepage":"https://github.com/mhdnazrul/CodeforcesSync/releases/","language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/mhdnazrul.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"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":null,"dco":null,"cla":null}},"created_at":"2026-03-15T05:38:50.000Z","updated_at":"2026-06-26T05:52:28.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/mhdnazrul/CodeforcesSync","commit_stats":null,"previous_names":["mhdnazrul/codeforcessync"],"tags_count":5,"template":false,"template_full_name":null,"purl":"pkg:github/mhdnazrul/CodeforcesSync","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mhdnazrul%2FCodeforcesSync","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mhdnazrul%2FCodeforcesSync/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mhdnazrul%2FCodeforcesSync/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mhdnazrul%2FCodeforcesSync/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/mhdnazrul","download_url":"https://codeload.github.com/mhdnazrul/CodeforcesSync/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mhdnazrul%2FCodeforcesSync/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":34843147,"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-06-27T02:00:06.362Z","response_time":126,"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":["automation","chrome-extension","codeforces","competitive-programming","developer-tools","github-api","javascript","manifest-v3"],"created_at":"2026-06-27T06:00:53.460Z","updated_at":"2026-06-27T06:01:03.984Z","avatar_url":"https://github.com/mhdnazrul.png","language":"TypeScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"\u003cdiv align=\"center\"\u003e\n  \u003cimg src=\"public/icons/icon128.png\" alt=\"CodeforcesSync Logo\" width=\"128\" /\u003e\n  \u003ch1\u003eCodeforcesSync\u003c/h1\u003e\n  \u003cp\u003e\u003cstrong\u003eAutomatically sync your accepted Codeforces solutions to GitHub in real-time.\u003c/strong\u003e\u003c/p\u003e\n\n  \u003cp\u003e\n    \u003ca href=\"https://github.com/mhdnazrul/CodeforcesSync/releases\"\u003e\u003cimg src=\"https://img.shields.io/github/v/release/mhdnazrul/CodeforcesSync?style=for-the-badge\u0026color=blue\" alt=\"Release Badge\"/\u003e\u003c/a\u003e\n    \u003ca href=\"https://github.com/mhdnazrul/CodeforcesSync/blob/main/LICENSE\"\u003e\u003cimg src=\"https://img.shields.io/badge/License-MIT-success.svg?style=for-the-badge\" alt=\"License Badge\"/\u003e\u003c/a\u003e\n    \u003ca href=\"https://www.typescriptlang.org\"\u003e\u003cimg src=\"https://img.shields.io/badge/TypeScript-5.9-3178C6?style=for-the-badge\u0026logo=typescript\" alt=\"TypeScript\"/\u003e\u003c/a\u003e\n    \u003ca href=\"https://react.dev\"\u003e\u003cimg src=\"https://img.shields.io/badge/React-19-61DAFB?style=for-the-badge\u0026logo=react\" alt=\"React\"/\u003e\u003c/a\u003e\n    \u003ca href=\"https://developer.chrome.com/docs/extensions/mv3/\"\u003e\u003cimg src=\"https://img.shields.io/badge/Chrome%20Extension-MV3-4285F4?style=for-the-badge\u0026logo=googlechrome\" alt=\"Chrome Extension MV3\"/\u003e\u003c/a\u003e\n    \u003ca href=\"https://github.com/mhdnazrul/CodeforcesSync/stargazers\"\u003e\u003cimg src=\"https://img.shields.io/github/stars/mhdnazrul/CodeforcesSync?style=for-the-badge\u0026color=yellow\" alt=\"Stars Badge\"/\u003e\u003c/a\u003e\n    \u003ca href=\"https://github.com/mhdnazrul/CodeforcesSync/network/members\"\u003e\u003cimg src=\"https://img.shields.io/github/forks/mhdnazrul/CodeforcesSync?style=for-the-badge\u0026color=orange\" alt=\"Forks Badge\"/\u003e\u003c/a\u003e\n  \u003c/p\u003e\n\u003c/div\u003e\n\n---\n\n## Quick Start\n\n```bash\n# 1. Download the latest release\n#    https://github.com/mhdnazrul/CodeforcesSync/releases\n\n# 2. Extract the ZIP and load it in your browser\n#    chrome://extensions → Developer mode → Load unpacked\n\n# 3. Open the extension → connect GitHub → enter Codeforces handle → link repo\n# 4. Solve a problem on Codeforces — it appears on GitHub within 1 minute\n```\n\n\u003e No manual copying, no manual committing. The extension runs in the background.\n\n---\n\n## Overview\n\n**CodeforcesSync** is a Chrome extension for competitive programmers. It bridges your Codeforces solving activity with your GitHub profile by automatically detecting accepted (\"Accepted\") verdicts and pushing the source code to a repository of your choice.\n\nThe extension runs entirely in the background — no manual copying, no manual committing. Solve a problem, and it appears on GitHub.\n\n---\n\n## Features\n\n- **Automated syncing** — Accepted submissions are detected and pushed to GitHub automatically.\n- **Real-time streak tracking** — Built-in dashboard shows your current streak, best streak, and weekly calendar.\n- **Smart language detection** — Parses Codeforces language tags (GNU C++20, PyPy 3, etc.) and maps them to standard file extensions (.cpp, .py, .js, ...).\n- **Cloudflare bypass** — Uses your active Codeforces tab session to fetch source code without triggering Cloudflare blocks.\n- **Custom subdirectories** — Organize solutions into a specific folder (e.g., `solutions/`) via the popup settings.\n- **Rate-limit aware** — Respects GitHub secondary rate limits and Codeforces API limits with automatic backoff.\n- **OAuth authentication** — Secure GitHub OAuth flow via a stateless Vercel broker (no third-party servers see your token).\n- **Dashboard analytics** — View your solving stats: current streak, best streak, weekly progress, and Codeforces statistics (rating, rank, problems solved).\n\n---\n\n## Screenshots\n\n| Welcome | GitHub Auth | Repository Setup |\n|:-------:|:-----------:|:----------------:|\n| ![Welcome](public/UI/page%201%20-%20Welcome.png) | ![GitHub Auth](public/UI/Page%202%20-%20Github%20Connection.png) | ![Repository](public/UI/Page%204%20-%20Repository%20Setup.png) |\n\n| Codeforces Auth | Dashboard | Settings |\n|:---------------:|:---------:|:--------:|\n| ![Codeforces](public/UI/page%203-%20Codeforces%20Connection.png) | ![Dashboard](public/UI/page%205%20-%20finish%20to%20main%20Dashboard.png) | ![Settings](public/UI/Page%206%20-%20main%20page%20to%20setting%20page.png) |\n\n---\n\n## Installation\n\n### Prerequisites\n\n- **Google Chrome** (102+, required for `chrome.storage.session`) or **Mozilla Firefox** (128+, required for `storage.session` in Firefox) or **Microsoft Edge** (Chromium-based)\n- **A GitHub account** with a repository to store solutions\n- **A Codeforces account** (the handle you solve problems under)\n\n### Option 1: GitHub Releases (Recommended)\n\n1. Go to the [Releases page](https://github.com/mhdnazrul/CodeforcesSync/releases).\n2. Download the latest `CodeforcesSync-vX.X.X.zip`.\n3. Extract the ZIP file to a folder on your computer.\n4. Open Chrome and navigate to `chrome://extensions`.\n5. Enable **Developer mode** (top-right toggle).\n6. Click **Load unpacked** and select the extracted folder.\n7. The extension is now installed. Pin it to your toolbar for easy access.\n\n### Option 2: Build from Source\n\n```bash\n# Clone the repository\ngit clone https://github.com/mhdnazrul/CodeforcesSync.git\ncd CodeforcesSync\n\n# Install dependencies\nnpm install\n\n# Build the extension\nnpm run build\n\n# Load dist/ as an unpacked extension in Chrome\n```\n\n---\n\n## Configuration\n\n### 1. Create a GitHub Repository\n\nCreate a new public or private repository on GitHub (e.g., `Codeforces-Solutions`). This is where your solutions will be uploaded.\n\n### 2. Set Up OAuth\n\nThe extension uses GitHub OAuth to authenticate. You need to register an OAuth App:\n\n1. Go to **GitHub Settings → Developer settings → OAuth Apps → New OAuth App**.\n2. Set **Application name** to `CodeforcesSync`.\n3. Set **Homepage URL** to `https://github.com/\u003cyour-username\u003e/CodeforcesSync`.\n4. Set **Authorization callback URL** to `https://\u003cyour-vercel-deployment\u003e.vercel.app/api/oauth/callback`.\n5. Generate a **Client Secret** and note the **Client ID**.\n6. Deploy the Vercel broker with these as environment variables (see [Deployment](docs/Deployment.md)).\n\n### 3. Link Your Accounts\n\nClick the CodeforcesSync icon in your Chrome toolbar and follow the onboarding wizard:\n\n1. **Connect GitHub** — Click \"Login with GitHub\" to start OAuth.\n2. **Connect Codeforces** — Enter your Codeforces handle.\n3. **Link Repository** — Enter your GitHub repository URL (e.g., `https://github.com/owner/repo` or `owner/repo`).\n4. **Done** — The dashboard appears with your stats.\n\n### 4. Start Solving\n\nKeep a Codeforces tab open in your browser while solving. The extension uses your active session to fetch source code and bypass Cloudflare. Solved problems will appear in your repository automatically.\n\n---\n\n## Usage\n\n### Dashboard\n\nThe dashboard shows:\n\n- **Current streak** — Consecutive days with at least one accepted submission.\n- **Best streak** — Your longest streak ever recorded.\n- **Weekly calendar** — A 7-day grid showing which days you solved problems.\n- **Codeforces statistics** — Rating, rank, total problems solved, contributions, and friend count (fetched from the official API, cached for 10 minutes).\n\n### Syncing\n\n- The background service worker polls the Codeforces API (`user.status`) every **60 seconds** via Chrome Alarms.\n- New accepted submissions are detected, their source code is fetched (via your active CF tab or the RSS feed), and uploaded to your GitHub repository.\n- Already-synced submissions are tracked to avoid duplicates.\n- If a GitHub API call fails (network error, rate limit), the sync engine retries up to **3 times** with exponential backoff.\n\n### Settings\n\nAccess settings from the gear icon in the header:\n\n- **Change repository** — Update the linked GitHub repository.\n- **Set subdirectory** — Store solutions in a specific folder.\n- **Reset all** — Clear all data and sign out.\n\n---\n\n## Architecture Overview\n\n```\n┌─────────────────────────────────────────────────────────────┐\n│                   Chrome Extension (MV3)                     │\n│                                                             │\n│  ┌──────────┐   ┌───────────┐   ┌───────────────────────┐  │\n│  │  Popup   │   │  Service   │   │    Content Scripts    │  │\n│  │ (React)  │◄──┤  Worker   │──►│  (injected into CF)   │  │\n│  └────┬─────┘   └─────┬─────┘   └───────────────────────┘  │\n│       │               │                                     │\n│       ▼               ▼                                     │\n│  ┌──────────┐   ┌───────────┐                               │\n│  │ Settings │   │   Sync    │   ┌──────────────────┐        │\n│  │  Store   │   │  Engine   │──►│  GitHub REST API  │        │\n│  └──────────┘   └─────┬─────┘   └──────────────────┘        │\n│                       │                                     │\n│                       ▼                                     │\n│              ┌──────────────────┐                            │\n│              │  Codeforces API  │                            │\n│              │  + RSS Feed      │                            │\n│              └──────────────────┘                            │\n└─────────────────────────────────────────────────────────────┘\n           │\n           ▼\n  ┌──────────────────┐\n  │  Vercel OAuth    │\n  │  Broker (auth)   │\n  └──────────────────┘\n```\n\n### Key Modules\n\n| Module | Location | Purpose |\n|--------|----------|---------|\n| Background | `src/background/` | Service worker lifecycle, alarm scheduling, message routing |\n| Sync Engine | `src/sync/` | Submission polling, deduplication, retry with exponential backoff |\n| GitHub | `src/github/` | GitHub REST API client, token management, file upload |\n| Codeforces | `src/codeforces/` | Codeforces API client, RSS feed parser |\n| Storage | `src/storage/` | Settings persistence with schema versioning |\n| Statistics | `src/statistics/` | Streak calculation, weekly calendar computation |\n| Browser | `src/browser/` | Abstracts `chrome.*` APIs behind typed interfaces |\n| Popup UI | `src/ui/` | React application (dashboard, settings, onboarding) |\n\nSee [Architecture](docs/Architecture.md) for detailed documentation.\n\n---\n\n## Project Structure\n\n```\nCodeforcesSync/\n├── api/oauth/           # Vercel serverless functions for OAuth broker\n├── docs/                # Documentation\n│   ├── Architecture.md\n│   ├── OAuth.md\n│   ├── GitHub-Integration.md\n│   ├── Codeforces-Integration.md\n│   ├── Sync-Engine.md\n│   ├── Statistics.md\n│   ├── Caching.md\n│   ├── Repository-Validation.md\n│   ├── Security.md\n│   ├── Deployment.md\n│   ├── Development.md\n│   ├── Release-Guide.md\n│   ├── Troubleshooting.md\n│   ├── FAQ.md\n│   └── Roadmap.md\n├── public/              # Static assets (icons, screenshots)\n├── src/                 # Source code\n│   ├── background/      # Service worker\n│   ├── browser/         # Browser API abstraction\n│   ├── cfstats/         # Codeforces statistics module\n│   ├── codeforces/      # Codeforces API client\n│   ├── content/         # Injected content scripts\n│   ├── github/          # GitHub API client\n│   ├── shared/          # Shared utilities, types, helpers\n│   ├── statistics/      # Streak and calendar computation\n│   ├── storage/         # Settings persistence\n│   ├── sync/            # Sync engine\n│   └── ui/              # React popup application\n├── .github/             # Issue templates, community files\n├── vite.config.ts       # Vite build configuration\n├── tsconfig.json        # TypeScript configuration\n└── package.json         # Dependencies and scripts\n```\n\n---\n\n## Development\n\n```bash\n# Install dependencies\nnpm install\n\n# Development build (watch mode)\nnpm run dev\n\n# Production build\nnpm run build\n\n# Lint\nnpm run lint\n```\n\n### Environment Variables\n\nCreate a `.env` file in the project root:\n\n```env\nVITE_OAUTH_BROKER_URL=https://\u003cyour-vercel-deployment\u003e.vercel.app\n```\n\nSee [Development](docs/Development.md) for detailed setup instructions.\n\n---\n\n## Troubleshooting\n\n| Problem | Solution |\n|---------|----------|\n| **Code not syncing** | Ensure a Codeforces tab is open in your browser. The extension needs your active session to fetch source code. |\n| **Cloudflare blocked** | Keep `codeforces.com` actively open. The content script requires the live DOM to extract submission source. |\n| **OAuth fails** | Verify your Vercel broker is deployed and environment variables (`GITHUB_CLIENT_ID`, `GITHUB_CLIENT_SECRET`) are set correctly. |\n| **Statistics not loading** | CF stats are fetched from the official Codeforces API. If the API is down, stats will not load. The extension retries on next poll cycle. |\n\nSee [Troubleshooting](docs/Troubleshooting.md) for more details.\n\n---\n\n## FAQ\n\n**Q: Does this work on Firefox?**  \nA: Yes. Firefox is fully supported (version 128+).\n\n**Q: Is my GitHub token safe?**  \nA: Yes. The token is stored in `chrome.storage.local` and is only accessible to the extension. The OAuth broker is stateless and never stores your token.\n\n**Q: Can I choose which submissions get synced?**  \nA: Currently, all accepted verdicts are synced. Selective syncing is on the roadmap.\n\n**Q: What if I solve a problem without a Codeforces tab open?**  \nA: The submission won't be synced until the next poll cycle detects it. If the source cannot be fetched via your active tab, the extension falls back to the RSS feed (which does not include source code, only metadata).\n\nSee [FAQ](docs/FAQ.md) for more answers.\n\n---\n\n## Limitations\n\n- **Active tab required** for source code fetching — the extension relies on your Codeforces session.\n- **Accepted verdicts only** — Only \"Accepted\" (OK) submissions are synced. Other verdicts are ignored.\n- **100K submission limit** — Codeforces API returns a maximum of 100,000 recent submissions. Users with more may see partial statistics.\n- **No bulk backfill** — Only submissions made after installation are synced. Historical submissions are not backfilled.\n\n---\n\n## Roadmap\n\n- [ ] Selective syncing (per-contest, per-problem)\n- [ ] \"Sync Now\" button for manual refresh\n- [ ] All Submissions Sync (sync all accepted submissions, not just recent)\n- [ ] Custom commit messages\n- [ ] Chrome Web Store and Firefox Add-ons (AMO) submission\n- [ ] Support for other platforms (LeetCode, AtCoder, CodeChef)\n\nSee [Roadmap](docs/Roadmap.md) for details.\n\n---\n\n## Security\n\n- GitHub tokens are stored in `chrome.storage.local` — accessible only to the extension.\n- OAuth uses PKCE (S256) with a stateless Vercel broker — the broker never sees your access token.\n- All communications are HTTPS.\n- The extension requests the minimum required permissions (`storage`, `alarms`, `identity`, `scripting`, host permissions).\n- No third-party analytics, tracking, or telemetry.\n\nSee [Security](docs/Security.md) for the full security model.\n\n---\n\n## Contributing\n\nContributions are welcome. Please read [CONTRIBUTING.md](CONTRIBUTING.md) and the [Engineering Constitution](docs/ENGINEERING_CONSTITUTION.md) before starting.\n\n1. Fork the repository.\n2. Create a feature branch (`git checkout -b feature/amazing-feature`).\n3. Commit your changes (`git commit -m 'Add amazing feature'`).\n4. Push to the branch (`git push origin feature/amazing-feature`).\n5. Open a Pull Request.\n\n---\n\n## License\n\nDistributed under the MIT License. See [LICENSE](LICENSE) for details.\n\n---\n\n\u003cdiv align=\"center\"\u003e\n  \u003cp\u003eMade with ❤️ by \u003ca href=\"https://github.com/mhdnazrul\"\u003eNazrul\u003c/a\u003e\u003c/p\u003e\n  \u003cp\u003e\n    \u003ca href=\"https://github.com/mhdnazrul/CodeforcesSync\"\u003eGitHub\u003c/a\u003e •\n    \u003ca href=\"https://github.com/mhdnazrul/CodeforcesSync/issues\"\u003eIssues\u003c/a\u003e •\n    \u003ca href=\"https://github.com/mhdnazrul/CodeforcesSync/discussions\"\u003eDiscussions\u003c/a\u003e\n  \u003c/p\u003e\n\u003c/div\u003e\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmhdnazrul%2Fcodeforcessync","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fmhdnazrul%2Fcodeforcessync","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmhdnazrul%2Fcodeforcessync/lists"}