{"id":51040067,"url":"https://github.com/neeilya/upwork-toolkit","last_synced_at":"2026-07-04T23:00:35.223Z","repository":{"id":11742952,"uuid":"70398829","full_name":"neeilya/upwork-toolkit","owner":"neeilya","description":"Chrome extension helping with project bidding on Upwork","archived":false,"fork":false,"pushed_at":"2026-06-19T12:39:59.000Z","size":1476,"stargazers_count":172,"open_issues_count":0,"forks_count":50,"subscribers_count":10,"default_branch":"master","last_synced_at":"2026-06-19T14:26:20.416Z","etag":null,"topics":["chrome-extension","freelance","react","upwork","wxt"],"latest_commit_sha":null,"homepage":"","language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"gpl-3.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/neeilya.png","metadata":{"files":{"readme":"README.md","changelog":null,"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":null,"dco":null,"cla":null}},"created_at":"2016-10-09T11:32:10.000Z","updated_at":"2026-06-19T13:26:57.000Z","dependencies_parsed_at":"2025-03-28T05:31:30.249Z","dependency_job_id":"2890a13f-be5f-48a7-9e24-4d7daddf8ee9","html_url":"https://github.com/neeilya/upwork-toolkit","commit_stats":null,"previous_names":["neeilya/upwork-toolkit"],"tags_count":2,"template":false,"template_full_name":null,"purl":"pkg:github/neeilya/upwork-toolkit","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/neeilya%2Fupwork-toolkit","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/neeilya%2Fupwork-toolkit/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/neeilya%2Fupwork-toolkit/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/neeilya%2Fupwork-toolkit/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/neeilya","download_url":"https://codeload.github.com/neeilya/upwork-toolkit/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/neeilya%2Fupwork-toolkit/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":35138078,"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-07-04T02:00:05.987Z","response_time":113,"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":["chrome-extension","freelance","react","upwork","wxt"],"created_at":"2026-06-22T10:00:28.918Z","updated_at":"2026-07-04T23:00:35.197Z","avatar_url":"https://github.com/neeilya.png","language":"TypeScript","funding_links":[],"categories":["TypeScript"],"sub_categories":[],"readme":"![alt tag](https://github.com/neeilya/upwork-toolkit/blob/master/cover.png?raw=true)\n\nA browser extension that monitors your Upwork job feed in real time and notifies you the\ninstant new jobs appear, so you never miss an opportunity while you're away from the screen.\n\nThis is the React + TypeScript rewrite of the original Vue extension that previously lived in\nthis repository.\n\n## Install\n\nInstall the ready-to-use extension from the\n[Chrome Web Store](https://chrome.google.com/webstore/detail/upwork-toolkit-your-own-f/gcjmekbfkkmaccloaoccfiohjnmgkddm).\n\nFeedback and contributions are highly appreciated!\n\n## Note to freelancers\n\nThe extension reads items from your **personal** job feed. If you're new to the platform, that\nfeed may be empty at first. To personalize it, run a job search on Upwork with some criteria\n(keywords, minimum budget, etc.) and **save the search** — the extension will then track matching\njobs as they appear.\n\nMore details about the job feed and other common concerns can be found in the **FAQ** section\ninside the extension.\n\n## Features\n\n- **Real-time job monitoring** across three feeds: _My Feed / Saved Searches_, _Best Matches_,\n  and _Most Recent_.\n- **Desktop notifications** that are clickable, with optional **sound** and volume control, an\n  **unseen-jobs badge** on the toolbar icon, and **deduplication** so you're never notified twice\n  about the same job.\n- **Scheduled notifications** — define working-hours windows per day of the week (12- or 24-hour\n  format); jobs found outside your schedule are cached silently.\n- **Cover-letter templates** — save reusable cover-letter text that auto-fills the proposal form\n  when you open a job's apply page.\n- **Job browsing UI** — job cards with compact/detailed toggle and dark mode (On / Off / System).\n- **Settings** — master on/off switch, feed source selection, sound preferences, and an option to\n  auto-open the proposal page for new jobs.\n\n## Tech stack\n\n- [React 19](https://react.dev/) + [TypeScript](https://www.typescriptlang.org/)\n- [WXT](https://wxt.dev/) — browser-extension framework (Chrome MV3)\n- [Material UI 9](https://mui.com/) + [Emotion](https://emotion.sh/)\n- [Axios](https://axios-http.com/), [date-fns](https://date-fns.org/)\n- [Sentry](https://sentry.io/) for error tracking\n- Google Analytics 4 for extension internal usage only\n\nNode 22 is recommended (see `.nvmrc`); Node 20 is the minimum supported version.\n\n## Getting started\n\nBuild the extension from source and load it as an unpacked extension:\n\n```bash\n# 1. Install dependencies (Node \u003e= 20)\nnpm install\n\n# 2a. Run a live-reload dev build...\nnpm run dev\n\n# 2b. ...or produce a production build\nnpm run build\n```\n\n`npm run build` writes the extension to `build/chrome-mv3`. To load it:\n\n1. Open `chrome://extensions` in Chrome.\n2. Enable **Developer mode** (top-right).\n3. Click **Load unpacked** and select the `build/chrome-mv3` directory.\n\n## Scripts\n\n| Script            | Description                                   |\n| ----------------- | --------------------------------------------- |\n| `npm run dev`     | Start a live-reload development build         |\n| `npm run build`   | Produce a production build in `build/`        |\n| `npm run zip`     | Package the build into a distributable `.zip` |\n| `npm run compile` | Type-check the project (`tsc --noEmit`)       |\n| `npm run format`  | Format the codebase with Prettier             |\n\nExperimental Firefox variants (`dev:firefox`, `build:firefox`, `zip:firefox`) exist, but Chrome\nMV3 is the supported target.\n\n## Environment variables\n\nAll variables are **optional** for local development — the core job-tracking features work without\nthem. Copy `.env.example` to `.env` to configure them. Analytics and error reporting are simply\ndisabled when their variables are unset.\n\n| Variable                | Purpose                                               |\n| ----------------------- | ----------------------------------------------------- |\n| `WXT_GA_API_SECRET`     | Google Analytics 4 API secret                         |\n| `WXT_GA_MEASUREMENT_ID` | Google Analytics 4 measurement ID                     |\n| `WXT_SENTRY_DSN`        | Sentry DSN for runtime error reporting                |\n| `SENTRY_AUTH_TOKEN`     | Sentry auth token for source-map upload at build time |\n| `SENTRY_ORGANISATION`   | Sentry organization slug                              |\n| `SENTRY_PROJECT`        | Sentry project slug                                   |\n\n## How it works\n\n- **Authentication** — the extension uses your existing Upwork session via cookies; there's no\n  separate login or OAuth flow. It calls the Upwork GraphQL API at\n  `https://www.upwork.com/api/graphql/v1`.\n- **Background polling** — a service worker runs on Chrome alarms, fetching jobs roughly once a\n  minute (every few seconds in dev mode).\n- **Sound** — notification sounds are played through an offscreen document (required for audio in\n  Manifest V3 service workers).\n- **Analytics** — Google Analytics is used only to understand how the extension itself is used. It\n  does not track your activity on the Upwork website or anywhere else.\n\n## Permissions\n\n| Permission              | Why it's needed                                          |\n| ----------------------- | -------------------------------------------------------- |\n| `idle`                  | Detect user activity for scheduling                      |\n| `alarms`                | Schedule periodic background job fetches                 |\n| `storage`               | Persist settings, schedules, and cached jobs             |\n| `cookies`               | Use your existing Upwork session for API requests        |\n| `offscreen`             | Play notification sounds in Manifest V3                  |\n| `notifications`         | Show desktop notifications for new jobs                  |\n| `declarativeNetRequest` | Adjust request headers needed to call the Upwork API     |\n| `https://*.upwork.com/` | Host access for reading your job feed and proposal pages |\n\n## Project structure\n\n```\nuptoolkit/\n├── entrypoints/        # Extension contexts\n│   ├── background/     # Service worker (alarms, job fetching)\n│   ├── content/        # Content scripts (Upwork proposal pages)\n│   ├── offscreen/      # Audio playback document\n│   └── options/        # Settings \u0026 dashboard UI (pages, components)\n├── api/                # Upwork GraphQL API + GraphQL queries\n├── utils/              # State, notifications, analytics, logging, etc.\n├── components/         # Shared UI components\n├── hooks/              # Custom React hooks\n├── contexts/           # React contexts (storage)\n├── icons/              # Icon components\n└── public/             # Static assets (icons, sound, HTML)\n```\n\n## License\n\nThis project is licensed under the [GNU General Public License v3.0](LICENSE).\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fneeilya%2Fupwork-toolkit","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fneeilya%2Fupwork-toolkit","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fneeilya%2Fupwork-toolkit/lists"}