wb-jobs
v1.0.1
Published
Human-in-the-loop LinkedIn & Indeed job-application assistant with multi-provider AI scoring and SQLite tracking
Maintainers
Readme
wb-jobs is a production-grade, AI-powered CLI application designed to automate search, harvest detailed metadata, evaluate fit, and orchestrate job applications on LinkedIn and Indeed. By combining Playwright browser automation, SQLite persistence, and state-of-the-art LLMs (Gemini, Groq), wb-jobs removes the tedious aspects of job hunting while keeping you firmly in control.
⚠️ Personal / educational project. Automating LinkedIn or Indeed may violate their Terms of Service — use responsibly, human-in-the-loop, and at your own risk. Not affiliated with, endorsed by, or connected to any platform. See DISCLAIMER.md.
❓ Why Use wb-jobs?
- Anti-Bot Evasion: Operates using a real Chrome instance with randomized human-like delays, mouse curves, and scroll patterns.
- Deep Metadata Extraction: Automatically harvests applicant counts, profile matching status, and hiring team details from job pages.
- Dynamic AI Scoring: Employs configurable system prompts to evaluate job descriptions against your experience, calculating matching scores and selecting resume variants.
- Human-in-the-Loop Safeguards: Handles form filling and uploads automatically, but stops for manual verification before submission, preventing unintended or messy applications.
- Clean Local History: Persists every visited, skipped, and applied position in a local SQLite database, supporting instant data exports to JSON, CSV, and Markdown.
📐 Architecture & Workflow
Here is the high-level workflow of how wb-jobs processes and manages your job applications:
📂 Project Directory Structure
.
├── docs/
│ └── images/
│ └── wb_jobs_logo.png # Application logo
├── bin/
│ └── cli.js # CLI bin entry point
├── profile/
│ └── profile.json.example # Profile credentials and matching weights template
├── prompts/ # LLM Prompts folder
│ ├── match_prompt.txt
│ ├── cover_letter.txt
│ └── screening_questions.txt
├── src/ # Source TypeScript code
│ ├── apply.ts # LinkedIn scraping & application
│ ├── applyIndeed.ts # Indeed scraping & application
│ ├── openJob.ts # LinkedIn detailed page parsing
│ ├── openIndeedJob.ts # Indeed detailed page parsing
│ ├── tracker.ts # SQLite persistence & database migrations
│ └── ...
├── package.json
└── tsconfig.json🚀 Installation & Setup
1. Prerequisites
Ensure you have Node.js (v18+) and Google Chrome installed on your system.
2. Local Development Setup
Clone the repository, install dependencies, and build the TypeScript source:
git clone https://github.com/wissemb11/wb-jobs.git
cd wb-jobs
npm install
npm run build3. Run Globally
To make the CLI command wb-job available globally anywhere in your terminal, link it:
npm link
# or install globally from the local path:
npm install -g .Now you can invoke the CLI globally via wb-job:
wb-job --help[!TIP] Native Addon Troubleshooting (
better-sqlite3error)
If you encounter an error statingCould not locate the bindings filewhen executingwb-job, it means npm's safety mechanism blockedbetter-sqlite3's native C++ compilation script. Fix it by running:# Approve the install script for better-sqlite3 npm install-scripts approve better-sqlite3 # Re-install globally with execution permissions enabled for both npm install -g --allow-scripts=wb-jobs,better-sqlite3 .
⚙️ Configuration & Environment
Step 1: LLM Credentials
Copy the environment template and fill in your API keys in the generated .env file:
cp .env.example .envSupported providers include:
- Gemini:
GEMINI_API_KEY(Recommended default) - Groq:
GROQ_API_KEY - OpenRouter:
OPENROUTER_API_KEY
Step 2: Experience Profile & Resumes
- Copy the profile template:
cp profile/profile.json.example profile/profile.json - Open
profile/profile.jsonand enter your name, target roles, work summary, and core skills. - Place your resume PDF files in the
profile/folder (e.g.profile/resume_fullstack.pdf,profile/resume_ai.pdf).
🛠️ Usage Manual
Step 1: Persist Login Sessions
To scrape and apply as a logged-in user, run the login utility to capture cookies:
wb-job login:linkedin
wb-job login:indeedThis opens a browser window. Once you log in, session details are persisted locally in linkedin.json and indeed.json (automatically ignored by Git).
Step 2: Running Application Pipelines
Run search, metadata harvesting, and human-in-the-loop applications:
# Search & evaluate LinkedIn roles globally
wb-job apply:linkedin --role="Senior Full-Stack Developer" --place="Germany|Remote" --easy --date="week"
# Search and harvest Indeed listings
wb-job apply:indeed --role="AI Engineer" --place="Remote" --date="day"CLI Parameters & Flags:
--role="Role1|Role2": Pipe-separated keywords for roles.--place="Loc1|Loc2": Pipe-separated target locations.--easy: Filter and apply only to Easy Apply / Quick Apply jobs.--date="day" | "week" | "month": Filter jobs by post date.--submit=SCORE: Automatically submit if the match score is above this threshold (e.g.,85). If omitted, the CLI always pauses for review.--save: Save all evaluated jobs and outcome states to the local database.
Step 3: Exporting Saved Data
Extract job statistics and logs from the SQLite database to various formats:
# Export to CSV format
wb-job export-db --as csv
# Export to Markdown, JSON, or Text
wb-job export-db --as md
wb-job export-db --as jsonStep 4: Resetting the Database
To clear logs and start with a clean database:
wb-job purge-db📚 Documentation
For deeper documentation, check the wiki/ directory:
- Architecture & Engine Details
- Comprehensive Command Parameters
- Scoring System & Prompt Tuning
- API Configuration Guide
- LinkedIn Auto-Apply Tutorial
- CLI Commands & Terminal Visualizations
- Global Relocation & Application Strategy
