Adds extractor packages: arbeitnow, ashby, careerjet, fourdayweek,
greenhouse, himalayas, jobicy, jooble, lever, reed, remoteok, remotive,
themuse, usajobs, weworkremotely, workday — each with manifest, package
metadata and README.
Pipeline / shared:
- shared/job-fingerprint: stable hash for cross-source dedup, with tests
- discover-jobs: dedup via fingerprint and richer per-source merging
- jobs repository: fingerprint-aware upsert / lookup
- settings-registry, settings types/routes, demo-defaults: knobs for the
new sources
- shared extractors index: register the new manifests
- location-support, profiles route: small fixes for the new sources
Tooling:
- scripts/smoke-extractors.ts to sanity-check each source locally
- scripts/jobber-cron-{cherepaha,dobkin}.env.example: per-host cron
templates (CHANGEME placeholders only)
- .env.example: documented env vars for the new extractors
- .gitignore: ignore extractors/*/storage/ runtime caches (was ukvisajobs only)
Co-authored-by: Cursor <cursoragent@cursor.com>
JobOps
Self-hosted job search orchestration: discover roles from multiple sources, score fit with your profile, draft tailored resumes and cover letters, export PDFs, and track application email—you still submit applications yourself; JobOps prepares the work and keeps state organized.
Licensed under AGPLv3 + Commons Clause — see LICENSE.
What’s in this repo
| Area | Role |
|---|---|
orchestrator/ |
Express API, SQLite + Drizzle, pipeline, React (Vite) UI, LLM integrations, Reactive Resume PDF flow |
shared/ |
Shared TypeScript types and settings registry |
docs-site/ |
Docusaurus user and developer documentation |
extractors/ |
Per-source crawlers (Adzuna, Gradcracker, UK Visa Jobs, Hiring Café, Startup Jobs, JobSpy helpers, etc.) |
Root package.json is an npm workspace root; day-to-day app commands usually run under orchestrator/.
Features (high level)
- Sources: Multiple boards and aggregators (exact list evolves; see docs and extractor packages).
- Scoring & tailoring: LLM compares jobs to your resume profile; optional drafts for summary, headline, skills, and project selection. The scorer enforces hard caps when deal-breakers fire (e.g. clearance/citizenship conflicts cap score to 0-15) and includes candidate name and location in the profile sent to the model.
- Cover letters: LLM-generated, profile-aware cover letters. The prompt uses the full job-search profile (experience level, target roles, must-have and nice-to-have skills, work arrangement, location, salary, industries, deal-breakers) and produces 4-5 paragraphs (~550 words) signed with the candidate's name.
- Job notes: Per-listing personal notes with debounced auto-save, available in Discovered, Ready, and detail panels.
- PDFs: Tailored exports via Reactive Resume (v4 or v5 API). Optional local JSON resume (
JOBOPS_LOCAL_RESUME_PATHor Settings) as the base document for profile/tailoring; PDF export still uses RxResume when configured. - Pipeline: Scheduled or manual runs (
POST /api/pipeline/run, webhook trigger). - Post-application: Optional Gmail-based inbox for interview/offer/rejection signals.
- Job list filters (orchestrator UI): Narrow the pipeline job list by multiple sources and countries (country is inferred from each listing’s location text). Filters sync to the URL (
source,sourceExclude,countries,countriesExclude). Each source/country chip cycles off → include → exclude (exclude shows in red); listings marked remote still pass country include/exclude rules. - Bulk actions: Select-all / batch actions support up to 2 500 jobs per request (raised from 100).
- Data: SQLite and generated artifacts under
./data(default in Docker).
Requirements
- Node.js 22 (see
package.json/ Volta pin) for local development. - Docker + Compose v2 for the recommended production-style run.
Quick start (Docker)
git clone <your-repo-url>
cd Jobber
cp .env.example .env
# Edit .env: MODEL / LLM keys, Reactive Resume or local resume path, optional BASIC_AUTH, etc.
docker compose up -d --build
- UI:
http://localhost:3005(host port mapped indocker-compose.yml; app listens on 3001 inside the container). - Health:
GET /healthon the same origin.
Persist data by backing up the mounted ./data directory.
Local development
From the repository root:
npm install
Then use the orchestrator workspace (see orchestrator/README.md for API tables and scripts):
cd orchestrator
cp .env.example .env
npm run db:migrate
npm run dev
Typical dev URLs: API http://localhost:3001, Vite client http://localhost:5173.
Configuration notes
- LLM: Configurable provider (OpenRouter default; also OpenAI, OpenAI-compatible endpoints, Gemini, Ollama, LM Studio, etc.). Keys can be set in
.envor onboarding. - Reactive Resume: v5 API key or v4 email/password; optional self-hosted
RXRESUME_URL. Full behavior is documented in the docs site under Reactive Resume. - Local resume JSON: Set
JOBOPS_LOCAL_RESUME_PATH(or the Settings field) to a Reactive Resume–shaped export so you do not need a selected cloud “base resume” for profile and tailoring. PDF generation still performs a temporary import/print through RxResume when credentials are present.
Documentation
| Resource | Contents |
|---|---|
docs-site/ |
User-facing guides (build with npm run docs:dev from repo root) |
orchestrator/README.md |
Orchestrator layout, endpoints, dev commands |
DEPLOY_GITEA_VM_CRON_TELEGRAM.md |
VM/container deploy, cron, optional Telegram |
AGENTS.md |
API/logging/SSE conventions for contributors and automation |
Deploy, cron, Telegram
See DEPLOY_GITEA_VM_CRON_TELEGRAM.md for production deploy, scheduling POST /api/pipeline/run, and optional notifications.
Verification (CI parity)
From the repo root, before merging substantial changes:
./orchestrator/node_modules/.bin/biome ci .
npm run check:types:shared
npm --workspace orchestrator run check:types
npm --workspace orchestrator run build:client
npm --workspace orchestrator run test:run
(Additional workspace typechecks apply in CI; see AGENTS.md.)
License
AGPLv3 + Commons Clause — you may self-host, use, and modify; you may not sell the software or offer paid hosting or support whose value substantially comes from this codebase. See LICENSE.