跳到正文
GitHub·· 7 天前AI 评分62

ApplyPack 开源本地 AI 求职工具发布,监控 33 类招聘来源

applypack/applypack

AI 导读

ApplyPack 是一个免费开源的本地 AI 求职工具,可监控 33 类招聘来源,用 AI 分类器按技术栈、职级、国家和薪资下限筛选岗位,并做岗位真实性核查。

正文

Free, open-source AI job search that runs on your own computer.

It watches 33 kinds of job board around the clock, drops the wrong-fit postings and checks whether one is real, shows which keywords your resume lacks and fixes them with you, writes a cover letter that cannot invent, and tracks the application. Built for software engineers. Bring the AI you already pay for. MIT: no accounts, no subscription, no telemetry, no ads.

CI Live demo License: MIT Node 22+ TypeScript strict Release

Try the live demo → · Install in two minutes ↓ · What it does · What it costs · Bring your own AI · Employer mode

A 33-second tour: the Overview with matches per day, the job list ranked by fit, one posting's verdict, the resume compared with it, Apply all taking the score from 85 to 88, the resume drawn as the document with the changes marked, the fact-checked cover letter, and one resume against three postings scored 90, 85 and 0

Thirty-three seconds, no cuts: what matched this month, the jobs it ranked, one posting's verdict, your resume against it, every suggestion applied in one press with no AI call, your own .docx with the edits marked, the letter, and one resume against three postings. Synthetic resume and companies, real AI calls.

Why it exists

Companies screen resumes with keyword filters and AI now. The filter counts words, not years: "PHP 8, Laravel, Symfony" can miss a requirement that says "PHP", and no recruiter ever sees the fifteen years behind it. Half the postings are noise on top: the wrong stack in paragraph four, "Remote" that means remote in Germany, a listing nobody will ever fill. You end up being the cron job.

I built ApplyPack during my own job search and found my current job with it (the story). It is the same tool you install, unchanged.

What it does

Find real jobs

  • 🔭 33 kinds of job source, most of them checked every hour. Twelve ATS vendors (Greenhouse, Lever, Ashby, Workable, SmartRecruiters, Recruitee, Breezy, BambooHR, Pinpoint, Rippling, Personio, Teamtailor) on the companies you pick; twenty aggregators, from RemoteOK to the monthly HN "Who is hiring" thread; country boards for Ukraine, Poland, Germany, the UK, the Netherlands, Portugal, Sweden and France; any RSS feed you paste. Starter packs add a whole segment of companies in one go.
  • 🧠 A classifier with rules that burned me. AI reads the full description against your stack, role types, seniority, countries and salary floor. "Full-stack" in a title is not a stack match, and "Remote · Germany" is not a US-remote job. Up to eight searches at once (backend and QA, contract and full-time); one AI call per posting scores all of them.
  • 🕵️ "Is it real?" with evidence. A free liveness check first, then a web-search checklist: careers page, company footprint, posting age, named humans. The verdict is legit, suspicious or fake, with the links.
  • 📲 Telegram or Discord only when it matters. An alert when a posting clears your fit threshold, a daily digest, quiet hours if you want them. Paste a posting from anywhere and it gets the same treatment.
  • ⭐ Watch the companies you actually want. Paste their career-page URLs; each resolves to the board or feed behind it and can alert on every posting, threshold or not. A page with nothing machine-readable is watched for changes.

Jobs: fourteen postings ranked by fit from 92 down, each with its stack, company, place, salary, status and when it was fetched

Fix the resume for this posting

  • 📄 A score that cannot flatter you. The model marks facts, unit-tested code computes the number. No core-stack overlap caps it at 30, Vue is not React, and an unknown becomes a question instead of a guess. Score v2 and the "+16 vs v1" is real. Try it in your browser →
  • ✍️ Apply every suggestion in one press. Each rewrite the fact check let through, and every missing keyword your resume backs, lands in one press; the score moves without an AI call, and each edit keeps its own Undo. Or edit side by side, coverage recomputed on each keystroke; disagree with a keyword and re-level, ignore or add it.
  • 💾 Your own .docx, as the document it is. The resume is drawn as your file with the edits written into it and marked; download it as .docx or .pdf, or save it as v2 with the formatting intact. A PDF, or a layout that cannot be patched, is re-typeset as a clean single-column .docx in your own font (ADR 0038, 0039, 0059).

Tailor resume after Apply all: the suggestion cards marked Applied on the left, and on the right the resume drawn as its own .docx with the new title, summary and two bullets highlighted, the missing keywords above it

Send it and track it

  • 💌 A cover letter that cannot invent. Drafted from the posting, your resume and the facts you confirmed, nothing else. A fact gate reads every claim back against that evidence; a number that is not in your resume never reaches the letter. Your angle, your tone, PDF or DOCX.
  • 🗂 One board for the applications. A kanban with columns you name, drag and drop, the resume each application went out with, and a nudge when one goes quiet for two weeks.
  • 📈 The whole search on one page. How many postings matched each day, over a week to six months or for one technology; where the rest of the funnel went; what ran and whether it failed. No AI, no telemetry: the numbers come from your own database.

The Overview: four status cards with their last two weeks, a chart of 138 matches over 30 days up 45 percent, the search funnel from 11,813 read to 138 alerted, pipeline health, recent activity and jobs by stack

Underneath: a five-step first run that ends with your first matches, six AI engines with automatic failover, untrusted-text markers around every posting a model reads (a test fails the build without them), board discovery from HN comments, an alert when a board goes quiet, and an opt-in employer mode.

Install in two minutes

The only thing to install is Node.js 22 or newer. The database comes with ApplyPack: no Docker, no PostgreSQL, no AI key before the first start.

git clone https://github.com/applypack/applypack.git   # or Code → Download ZIP
cd applypack
npm install
npm start    # → http://127.0.0.1:4747 opens on the setup

The setup is five clicks and one file pick:

  1. Connect an AI. Paste a key, or let it detect the CLI you are already logged into. A Test button proves the connection.
  2. Test the search. One button asks the boards and stores what it finds: no AI spent, about twenty seconds.
  3. Upload your resume. The summary it comes back with ("senior backend engineer, PHP, Laravel…") becomes your search profile with one click. No resume handy: three questions instead.
  4. Switch on the boards for your countries. One press.
  5. Read your first matches, then start the hourly watch.

Fetching stays paused until that last click, so a blank profile never burns your AI quota. From then on it runs on its own. Ctrl+C stops it, npm start carries on where it left off, and your data lives outside the folder (~/Library/Application Support/ApplyPack, %APPDATA%\ApplyPack, ~/.local/share/applypack), so an update or a fresh download finds it.

Step by step for macOS, Windows and Linux, with what to do when something goes wrong: docs/install.md. On a server, or always on:

cp .env.example .env
docker compose up -d    # postgres + worker + dashboard → http://localhost:4747

Every page of the dashboard, backups, the worker's schedule, your own Postgres, development and hosting for other people: docs/operations.md.

What it costs

Nothing, except the AI you choose. MIT license, no hosted version, no accounts, no subscription, no telemetry, no ads. You pick the meter:

You have Extra cost
A Claude.ai, ChatGPT or Google subscription $0. The Claude Code, Codex and Gemini CLIs ride it. When the usage window runs dry, the next engine takes over and the first comes back on its own
Gemini CLI's free tier $0 for a typical day of classification
A local model via Ollama or LM Studio $0
An Anthropic API key About $2–10 a month. A classified posting costs ~$0.003 on Haiku 4.5, and the bill follows how many postings your sources produce, not how many you apply to. The two-stage classifier cuts another 30–40%

Postgres, Telegram, Discord and the job boards cost nothing. The AI tab counts which engine served your calls in the last seven days.

Bring your own AI

Seven backends, and you can attach every subscription and key you own:

Engine What it is Billing
Claude Code CLI headless claude -p your Claude.ai Pro/Max subscription
Gemini CLI headless gemini -p your Google account (generous free tier) or an AI Studio key
Antigravity CLI headless agy -p your Google Antigravity account
Codex CLI headless codex exec your ChatGPT Plus/Pro subscription
Anthropic API Messages API per token
OpenAI-compatible API POST /chat/completions to any base URL OpenAI, OpenRouter, Groq, DeepSeek, or a free local model
Local model (Ollama) Ollama's own API on this machine free; the text never leaves it

Enable the ones you have on Settings → AI & costs, order them, and pick models per engine. Engine #1 serves every call; on an error, a rate limit or an empty quota the next one takes over for that call, and #1 is back the moment it recovers. Every card says whether the engine works on this machine, and a Test button runs one real call. A cheap model reads every fetched job; a stronger one handles the few judgment calls a day: resume scans, matches, verification, letters.

Setup for every engine, local and Docker: docs/ai-engines.md. One honest note: consumer-subscription terms do not spell out background services, so read yours before making a subscription your primary engine.

How it works

 33 kinds of source ──▶ normalize ──▶ base filter ──▶ AI classifier ──▶ Postgres ──▶ Telegram
   mostly hourly          + dedupe      pure code,      one call, a       dashboard    or Discord,
   fetch                                zero cost       score per search               fit ≥ threshold

Cheap deterministic filters drop the obvious misses first, so the AI only reads postings that might be for you. Everything it reads arrives inside untrusted-text markers, so a posting cannot hijack the prompt.

Coverage is two-tier, because the HR vendors have no "all jobs" API: direct boards for the companies you track (paste a board URL; the form probes it live and refuses one that does not resolve) and aggregators: RemoteOK, Remotive, We Work Remotely, Jobicy, Working Nomads, Himalayas, Laravel Jobs, Golang Projects, Arbeitnow, 4 Day Week, DOU, Djinni, solid.jobs, DevITjobs, Landing.jobs, JobTech, the HN feeds, and Adzuna and France Travail with your own free key. Leave the aggregators on: a dozen tracked companies do not post a matching role every week, and your profile keeps the long tail quiet.

Sourcing is deliberately clean: official public APIs and RSS only, never scraping. LinkedIn, Indeed, Glassdoor, Workday and Wellfound are permanently out of scope (ADR 0005). Everything runs on your machine, the dashboard binds to 127.0.0.1, and nothing leaves it but the calls to the AI engine you chose and to your own Telegram bot or Discord webhook.

Employer mode: screening a folder of resumes

The other side of the table, off by default: one switch on Settings → Screening. A folder of resumes against one position, screened against criteria in your own words ("Playwright / Cypress !", "0–2 years", "fintech: 3+"). Names, contacts and personal details are removed before any model reads a word; every answer carries its quote from the resume; the score is arithmetic in code; a shortlist is compared side by side and head to head; and a person makes the decision, with a calibration card that says whether the table ranks the way they do.

Screening other people's resumes with AI is regulated (the EU AI Act, GDPR, several US laws). The mode is built to be the tool and not the decision, and two duties stay yours: tell applicants, and run it on an engine with a data-processing agreement or on a local model. The full description, the screenshots and the legal note: docs/employer-mode.md.

Under the hood

TypeScript strict, Node 24, Prisma + Postgres 16, Hono with server-side JSX, node-cron. No Redis, no queues, no client framework; the only build step is tsc and a committed Tailwind CSS, and no page fetches anything from a third party. Every external byte (env vars, API responses, AI output) passes through zod. The worker and the dashboard are separate processes on one database, and npm start runs both beside a built-in Postgres 16 (ADR 0054).

npm run lint:types   # tsc --noEmit
npm test             # 2,700+ unit tests on the pure modules, in a few seconds

Docs map: docs/install.md — installing, per system · docs/ai-engines.md — AI setup, local + Docker · docs/operations.md — the pages, data, schedule, hosting · docs/employer-mode.md — screening · SPEC.md — current behaviour · ARCHITECTURE.md — data flow + file map · CLAUDE.md — conventions, gotchas, where-to-look tables · docs/adr/ — every non-obvious decision, with reasons · CHANGELOG.md — releases · SECURITY.md — reporting a vulnerability.

Contributing

Ideas are as welcome as patches, and the roadmap is the issue tracker. Three good entry points:

  • Add a job source. The highest-value contribution and close to a one-file change: CLAUDE.md ships copy-paste fetcher templates, one per feed shape. Unsure it fits the sourcing policy? Open a source proposal first.
  • Pick an open issue. Comment on it before you start, and ask there when the scope is unclear.
  • Break it and report. A fresh-machine setup that stumbled, an ATS edge case, a resume that parses badly: issues with logs are gold.

CONTRIBUTING.md is a five-minute read covering setup, tests and conventions. The sourcing policy is non-negotiable: official public APIs and RSS only, never scraping.

Contributors

License

MIT — see LICENSE. Built and maintained by Nazar Boyko; every decision that was not obvious is written down in docs/adr/.

来源:GitHub · github.com