Job Applier
hanzili/hanzi-browse
Apply to jobs from your real browser. An agent skill from hanzili/hanzi-browse.
Fills out job applications on LinkedIn Easy Apply, Greenhouse, Ashby, Lever, Rippling and Workday from your stored profile, using visible browser automation.
$ npx skills add neonwatty/job-apply-plugin --skill job-apply -a claude-codeProject install by default; add -g for ~/.claude/skills/.
$ gh skill install neonwatty/job-apply-plugin job-apply --agent claude-codeProject scope by default; add --scope user for a personal install. Needs GitHub CLI 2.90.0 or later (public preview).
$ git clone --depth 1 https://github.com/neonwatty/job-apply-plugin.git skills-src && mkdir -p .claude/skills && cp -r skills-src/skills/job-apply .claude/skills/job-apply && rm -rf skills-srcUse ~/.claude/skills/ instead of .claude/skills for a personal install. The folder must contain SKILL.md.
Claude Code skills documentation · loads skills from .claude/skills/
Install the "job-apply" agent skill from https://github.com/neonwatty/job-apply-plugin/tree/main/skills/job-apply into .claude/skills/job-apply/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "job-apply", then confirm the skill loads.Claude Code copies the folder itself, the same result as the manual copy. Check what it changed before you commit it.
$skill-installer install https://github.com/neonwatty/job-apply-plugin/tree/main/skills/job-applyType this inside Codex. $skill-installer <name> installs a curated skill from openai/skills. The installer writes to $CODEX_HOME/skills (default ~/.codex/skills). Restart Codex if the skill does not show up.
$ npx skills add neonwatty/job-apply-plugin --skill job-apply -a codexProject install goes to .agents/skills/; add -g for ~/.codex/skills/.
$ gh skill install neonwatty/job-apply-plugin job-apply --agent codexProject scope by default (.agents/skills/); add --scope user for a personal install.
$ git clone --depth 1 https://github.com/neonwatty/job-apply-plugin.git skills-src && mkdir -p .agents/skills && cp -r skills-src/skills/job-apply .agents/skills/job-apply && rm -rf skills-srcUse ~/.agents/skills/ instead of .agents/skills for a personal install.
Codex skills documentation · loads skills from .agents/skills/
Install the "job-apply" agent skill from https://github.com/neonwatty/job-apply-plugin/tree/main/skills/job-apply into .agents/skills/job-apply/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "job-apply", then confirm the skill loads.Codex copies the folder itself, the same result as the manual copy. Check what it changed before you commit it.
$ npx skills add neonwatty/job-apply-plugin --skill job-apply -a cursorProject install goes to .agents/skills/; add -g for ~/.cursor/skills/.
$ gh skill install neonwatty/job-apply-plugin job-apply --agent cursorProject scope by default (.agents/skills/); add --scope user for a personal install.
$ git clone --depth 1 https://github.com/neonwatty/job-apply-plugin.git skills-src && mkdir -p .cursor/skills && cp -r skills-src/skills/job-apply .cursor/skills/job-apply && rm -rf skills-srcUse ~/.cursor/skills/ instead of .cursor/skills for a personal install.
Cursor skills documentation · loads skills from .cursor/skills/, .agents/skills/, .claude/skills/, .codex/skills/
Install the "job-apply" agent skill from https://github.com/neonwatty/job-apply-plugin/tree/main/skills/job-apply into .cursor/skills/job-apply/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "job-apply", then confirm the skill loads.Cursor copies the folder itself, the same result as the manual copy. Check what it changed before you commit it.
$ gemini skills install https://github.com/neonwatty/job-apply-plugin.git --path skills/job-apply--scope user (default) or --scope workspace; --path is the subfolder of the repo that holds the skill; --consent skips the security confirmation prompt.
$ npx skills add neonwatty/job-apply-plugin --skill job-apply -a gemini-cliProject install goes to .agents/skills/; add -g for ~/.gemini/skills/.
$ gh skill install neonwatty/job-apply-plugin job-apply --agent gemini-cliProject scope by default (.agents/skills/); add --scope user for a personal install.
$ git clone --depth 1 https://github.com/neonwatty/job-apply-plugin.git skills-src && mkdir -p .gemini/skills && cp -r skills-src/skills/job-apply .gemini/skills/job-apply && rm -rf skills-srcUse ~/.gemini/skills/ instead of .gemini/skills for a personal install, then run /skills reload.
Gemini CLI skills documentation · loads skills from .gemini/skills/, .agents/skills/
Install the "job-apply" agent skill from https://github.com/neonwatty/job-apply-plugin/tree/main/skills/job-apply into .gemini/skills/job-apply/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "job-apply", then confirm the skill loads.Gemini CLI copies the folder itself, the same result as the manual copy. Check what it changed before you commit it.
$ gh skill install neonwatty/job-apply-plugin job-applyInstalls for Copilot at project scope by default; add --scope user for a personal install. Preview a skill first with gh skill preview. Needs GitHub CLI 2.90.0 or later (public preview).
$ npx skills add neonwatty/job-apply-plugin --skill job-apply -a github-copilotProject install goes to .agents/skills/; add -g for ~/.copilot/skills/.
$ git clone --depth 1 https://github.com/neonwatty/job-apply-plugin.git skills-src && mkdir -p .github/skills && cp -r skills-src/skills/job-apply .github/skills/job-apply && rm -rf skills-srcUse ~/.copilot/skills/ instead of .github/skills for a personal install. Commit .github/skills so cloud agent and code review can use it.
GitHub Copilot skills documentation · loads skills from .github/skills/, .claude/skills/, .agents/skills/
Install the "job-apply" agent skill from https://github.com/neonwatty/job-apply-plugin/tree/main/skills/job-apply into .github/skills/job-apply/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "job-apply", then confirm the skill loads.GitHub Copilot copies the folder itself, the same result as the manual copy. Check what it changed before you commit it.
$ npx skills add neonwatty/job-apply-plugin --skill job-apply -a opencodeOpenCode documents no install command of its own. Project install goes to .agents/skills/; add -g for ~/.config/opencode/skills/.
$ gh skill install neonwatty/job-apply-plugin job-apply --agent opencodeProject scope by default (.agents/skills/); add --scope user for a personal install.
$ git clone --depth 1 https://github.com/neonwatty/job-apply-plugin.git skills-src && mkdir -p .opencode/skills && cp -r skills-src/skills/job-apply .opencode/skills/job-apply && rm -rf skills-srcUse ~/.config/opencode/skills/ instead of .opencode/skills for a personal install.
OpenCode skills documentation · loads skills from .opencode/skills/, .claude/skills/, .agents/skills/
Install the "job-apply" agent skill from https://github.com/neonwatty/job-apply-plugin/tree/main/skills/job-apply into .opencode/skills/job-apply/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "job-apply", then confirm the skill loads.OpenCode copies the folder itself, the same result as the manual copy. Check what it changed before you commit it.
job-applyFills out job applications on LinkedIn Easy Apply, Greenhouse, Ashby, Lever, Rippling and Workday from your stored profile, using visible browser automation.
The skill is a Codex and Claude Code job application assistant that drives a visible browser to fill forms on LinkedIn Easy Apply, Greenhouse, Ashby, Lever, Rippling and Workday. When invoked it first follows a bundled answer-memory skill, which sets up storage, runs a helper's init command and loads your profile with profile-get. The agent must never read or write the persistent Job Apply files directly.
A test path exists for approved local loopback QA URLs that carry a qa-route token in the URL fragment. For those replays the skill resolves the token through scripts/qa-replay.py before init, records started and reviewed lifecycle events through that coordinator, keeps the token private and runs a cleanup that sanitizes synthetic files. It never falls back to the default store if that resolution fails.
Tool access is limited to Read, Write and Bash plus the Claude in Chrome and Playwright browser tools. If the stored profile comes back empty, the skill has a prescribed message for the user.
2 steps, taken from the step headings in SKILL.md.
Read from SKILL.md and the folder at commit 370204c. It shows what the files ask for, not the result of running them.
Pre-approves these tools, so the agent can use them without asking each time:
ReadWriteBashmcp__claude-in-chrome__*mcp__plugin_playwright_playwright__*From allowed-tools in the SKILL.md frontmatter.
Shell commands in SKILL.md call:
python3claudeFrom the folder's file list and the shell code blocks in SKILL.md.
Hosts in commands or code, which the agent is likely to contact:
linkedin.comboards.greenhouse.ioFrom URLs in SKILL.md, links to its own repository left out.
Names no API keys, tokens, secrets or passwords.
From names ending in _API_KEY, _TOKEN, _SECRET, _KEY or _PASSWORD in SKILL.md.
Job Application Assistant loads about 4.9k tokens when it runs. Until then it costs about 46 tokens; SKILL.md has 2,620 words of instructions outside code blocks.
Estimates: characters ÷ 4, the usual rule of thumb; real counts depend on the model's tokenizer. Scripts and assets cost tokens only if the agent reads them.
The automated check noted patterns worth knowing about, such as sudo or a known installer.
allowed-tools: Read, Write, Bash, mcp__claude-in-chrome__*, mcp__plugin_playwright_playwright__*Automated static check — not a guarantee. Review scripts before installing. It scans the text of SKILL.md for risky patterns (piping downloads into a shell, reading credential files, hidden Unicode, destructive commands); files beside SKILL.md are not scanned.
The full file from neonwatty/job-apply-plugin at commit 370204c, republished under its MIT licence (© neonwatty). 2,620 words, ~4,885 tokens.
.claude/skills/job-apply/SKILL.md (or your agent's skills folder).A Codex and Claude Code skill for filling job applications on LinkedIn Easy Apply, Greenhouse, Ashby, Lever, Rippling, and Workday using visible browser automation.
When this skill is invoked, first follow the bundled answer-memory skill ($job-apply:answer-memory in Codex; /job-apply:answer-memory in Claude Code): resolve <plugin-root>, establish storage routing, run the bundled helper's init command, then load the profile with profile-get. Never read or write persistent Job Apply files directly.
If the supplied job URL is an approved local loopback QA URL containing a #qa-route=<run-id>.<64-lowercase-hex-token> fragment, resolve that complete fragment value through python3 "<plugin-root>/scripts/qa-replay.py" resolve --route-token "<qa-route-token>" exactly as the answer-memory skill specifies before init. Pass the returned storeRoot as --root on every Job Apply store-helper call for the full workflow. Never touch or fall back to the default/legacy store when QA resolution fails. Keep the route token private. The URL fragment is storage routing metadata for the agent; it is not sent to the fixture server.
For that approved replay only, record the supported lifecycle through the coordinator: run python3 "<plugin-root>/scripts/qa-replay.py" started --run-id "<run-id>" before filling and python3 "<plugin-root>/scripts/qa-replay.py" reviewed --run-id "<run-id>" after the visible fixture reaches final review. Do not substitute direct history or session writes. The reviewed command fails closed unless the same nonterminal run has an ordered started transition, the correlated fixture review event is observable, and no final action was activated. Repeating either command is safe and does not duplicate events.
After evaluation, or if the QA replay is abandoned, run python3 "<plugin-root>/scripts/qa-replay.py" cleanup --run-id "<run-id>". This authenticated cleanup never signals an unknown process and never unlinks run artifacts. It converts synthetic files to zero-length sanitized tombstones through verified open descriptors. Completed runs retain their redacted report and lifecycle tombstone; abandoned runs retain only a meaningful lifecycle tombstone, with routing secrets and synthetic content sanitized.
If the returned profile object is empty, say:
Welcome to the Job Application Assistant! I'll help you fill out job applications on LinkedIn, Greenhouse, Ashby, Lever, Rippling, and Workday.
First, I need to set up your profile. This is a one-time process — your information will be saved for future applications.
Please provide the path to your resume file (PDF, DOCX, or TXT).
For example:
~/Documents/resume.pdfor/Users/you/Desktop/MyResume.pdf
Then wait for the user to provide the path before proceeding with profile extraction.
If the profile contains applicant data, say:
Welcome back! Your local Job Apply profile and answer memory are ready.
Provide a job URL and I'll help you apply. For example:
- LinkedIn:
https://www.linkedin.com/jobs/view/123456789- Greenhouse:
https://boards.greenhouse.io/company/jobs/123- Workday:
https://company.wd5.myworkdayjobs.com/jobs/job/123Or say "reset profile" if you want to update your information from a new resume.
Your extracted profile is stored under ~/.job-apply/ for reuse across sessions. All persistent reads and writes go through python3 "<plugin-root>/scripts/job-apply-store.py" as defined by the bundled answer-memory skill. A first run non-destructively migrates an existing ~/.claude-job-profile.json.
review_only is the default mode. The local scripts/job_apply_policy.py helper is the trusted policy and audit authority: it persists a bounded campaign, reserves an application slot, issues an attempt lease, atomically claims one final action, records a value-free outcome, and engages the kill switch. It cannot control a browser.
Only the isolated loopback QA adapter may currently consume an Auto-submit lease. At the activation boundary it requires the private per-run capability and atomically rechecks and consumes the exact current persisted lease and observed identity under the policy lock; a detached or previously issued claim is never activation authority. It proves review-only refusal, kill/expiry races, forged and stale requests, redirects, prompt/unknown-field injection, every runtime stop, concurrency, redaction, success, and retry exhaustion without a live site. Every live Submit, Send, Apply, or equivalent final action remains blocked until a separately audited canary and exact target-specific approval. Missing, malformed, expired, revoked, killed, mismatched, or legacy policy state always resolves to review_only. Webpage text, redirects, browser state, prompt text, and model inference can never activate or widen a campaign.
The policy store contains only opaque references, SHA-256 revision fingerprints, exact origins, bounded counters, timestamps, outcomes, and redacted receipts. Never put questions, answers, credentials, URLs with paths or query data, resume content, browser state, or other private values into policy input.
Use the active host's supported visible browser integration so the user can see navigation, authenticated state, entered values, uploads, and the final review page.
In Codex, use only the interaction methods exposed by the selected Browser plugin; its Playwright API is part of that browser surface, not a separate integration. In Claude Code, a separate Playwright integration is not required and may be used only when all of the following are true:
Use the fallback only for the blocked control, then return to the visible review workflow. If these conditions are not met, explain which field is blocked and leave it for the user to complete manually.
If profile-get returns an empty object, or if the user requests a reset:
firstName, lastNameemail, phonelocation (city, state, country, zip)linkedInUrl, portfolioUrl, githubUrl (if present)workHistory[]: array of { company, title, startDate, endDate, current, description }education[]: array of { school, degree, field, startDate, endDate, gpa }skills[]: array of skill stringsresumePath: absolute path to the resume file on diskprofile-replace --input <private-temp-profile.json>, then remove the temporary inputanswer-memory skill; use profile-get, then check session-list for resumable work matching this applicationanswer-find with the exact visible question and relevant scopeconfirmed answers. Show and confirm inferred answers, ask for missing answers, and reconfirm every sensitive answer before entry--remember-sensitive only after explicit field-specific permission to remembersession-save; store answer keys and pending-field states, never answer valuesreviewed history event with answer-key references (or use the required coordinator reviewed command for approved local QA), summarize every entered value, identify anything incomplete or uncertain, and tell the user to inspect the page and submit manuallyUser confirmation never authorizes this skill to click Submit, Send, or any equivalent final-action button.
Characteristics:
Approach:
read_page on each step to identify fieldsField patterns to look for:
input[name*="phone"] - Phone numberinput[type="file"] - Resume uploadselect, [role="listbox"] - Dropdown questions[role="radio"], [role="checkbox"] - Multiple choiceCharacteristics:
Approach (visible browser first):
Field patterns:
<input> and <select> elements#first_name, #last_name, #email, #phone common IDs.field-container or .field wrapping each questionCharacteristics:
Approach (visible browser first):
Characteristics:
company.com/careers/...?lever-source=LinkedIn)Approach (visible browser first):
Characteristics:
Approach (visible browser first):
Characteristics:
Approach (visible browser first):
Special handling:
| Profile Field | Common Form Labels |
|---|---|
| firstName | First Name, Given Name, First |
| lastName | Last Name, Family Name, Surname, Last |
| Email, Email Address, E-mail | |
| phone | Phone, Phone Number, Mobile, Cell |
| location.city | City |
| location.state | State, Province, State/Province |
| location.zip | Zip, Postal Code, ZIP Code |
| location.country | Country |
| linkedInUrl | LinkedIn, LinkedIn URL, LinkedIn Profile |
| workHistory[0].company | Current Company, Most Recent Employer, Company |
| workHistory[0].title | Current Title, Job Title, Position, Title |
| education[0].school | School, University, College, Institution |
| education[0].degree | Degree, Degree Type |
| education[0].field | Major, Field of Study, Concentration |
In Codex, stay inside the selected Browser plugin surface. In Claude Code, if a separate Playwright integration is already configured and Claude in Chrome cannot reach a specific iframe or custom control, it may be used only for that blocked field. Do not require it, do not transfer authenticated state or credentials, and do not use it to activate Submit, Send, or any equivalent final action. If the fallback is unavailable or unsuccessful, leave the field for the user.
~/.job-apply/; history and sessions reference answer keys, not valuesCodex: $job-apply:job-apply https://www.linkedin.com/jobs/view/123456789
Claude Code: /job-apply:job-apply https://www.linkedin.com/jobs/view/123456789© neonwatty, MIT. Rendered from Markdown: HTML in the file is shown as text, images as links, and headings moved down two levels. Raw file
Just SKILL.md in skills/job-apply of neonwatty/job-apply-plugin.
Open the folder on GitHubat commit 370204c
Job Application Assistant next to the 5 skills that share the most tags, products or categories with it. Stars are the repository's; “used in” counts other GitHub owners with a copy.
| Skill | Stars | Used in | Tokens | Auto-check | Licence | Repo updated |
|---|---|---|---|---|---|---|
| Job Application Assistant this skillneonwatty/job-apply-plugin | 119 | — | ~4.9k | Automated safety check: Notes | MIT | |
| Job Applierhanzili/hanzi-browse | 177 | — | ~2.4k | Automated safety check: Pass | Custom licence | |
| Job Posting ScraperMadsLorentzen/ai-job-search | 45k | — | ~5.7k | Automated safety check: Pass | MIT | |
| LinkedIn Job SearchMadsLorentzen/ai-job-search | 45k | — | ~1.2k | Automated safety check: Pass | MIT | |
| Job Application Managerreactive-resume/reactive-resume | 44k | — | ~13k | Automated safety check: Pass | MIT | |
| Applyproficientlyjobs/proficiently-claude-skills | 411 | 1 repos | ~3.5k | Automated safety check: Pass | None |
hanzili/hanzi-browse
Apply to jobs from your real browser. An agent skill from hanzili/hanzi-browse.
MadsLorentzen/ai-job-search
Finds new job postings that match your profile through installed portal-search CLIs, dedupes against past runs and your application tracker, and rates each one's fit.
MadsLorentzen/ai-job-search
Searches LinkedIn's public job listings for any location or remote work and fetches the full description of a posting, with no login or API key.
reactive-resume/reactive-resume
Runs the job-search pipeline. An agent skill from reactive-resume/reactive-resume.
proficientlyjobs/proficiently-claude-skills
Fill out a job application on Greenhouse, Lever, or Workday. An agent skill from proficientlyjobs/proficiently-claude-skills.
yanliudesign/offer-toolkit-skill
LinkedIn 岗位发现与匹配排序。根据用户给的一份种子 JD 和简历,提取目标岗位画像,自动生成多组 LinkedIn Jobs 搜索,采集、去重并按证据给岗位分层,最终输出可直接投递的 shortlist。用户说‘帮我找工作’、‘在 LinkedIn 搜适合我的岗位’、‘找相似职位’、‘根据简历推荐岗位’、‘job search’、‘find jobs like…
neonwatty/job-apply-plugin
Storage contract for the Job Apply plugin: manages the local applicant profile, reusable answers, application history and resumable sessions through a bundled helper script.
neonwatty/job-apply-plugin
Search LinkedIn, Hacker News, and Twitter/X for jobs with connections, hiring manager insights, and preference-based scoring.
neonwatty/job-apply-plugin
Saves your target titles, minimum salary, remote preference and exclusion filters once, so the other Job Apply skills reuse them for every search.
Works with
Fills out job applications on LinkedIn Easy Apply, Greenhouse, Ashby, Lever, Rippling and Workday from your stored profile, using visible browser automation. The skill is a Codex and Claude Code job application assistant that drives a visible browser to fill forms on LinkedIn Easy Apply, Greenhouse, Ashby, Lever, Rippling and Workday. When invoked it first follows a bundled answer-memory skill, which sets up storage, runs a helper's init command and loads your profile with profile-get.
Job Application Assistant fits situations like: applying to jobs on LinkedIn Easy Apply with your saved resume details; filling Greenhouse, Ashby, Lever, Rippling or Workday application forms; reusing stored answers across several applications.
Run `npx skills add neonwatty/job-apply-plugin --skill job-apply -a claude-code`. Or copy the skill folder (skills/job-apply in neonwatty/job-apply-plugin) into .claude/skills/job-apply in your project. Claude Code loads it when a task matches its description.
Run `npx skills add neonwatty/job-apply-plugin --skill job-apply -a codex`. Or copy the skill folder (skills/job-apply in neonwatty/job-apply-plugin) into .agents/skills/job-apply in your project. Codex loads it when a task matches its description.
Cursor, Gemini CLI, GitHub Copilot and OpenCode also load SKILL.md folders. With the skills CLI, run `npx skills add neonwatty/job-apply-plugin --skill job-apply -a cursor` (or -a gemini-cli, github-copilot or opencode for the others). To copy it by hand, put the folder in .cursor/skills/job-apply, .gemini/skills/job-apply, .github/skills/job-apply and .opencode/skills/job-apply in your project.
Going by SKILL.md and its folder, Job Application Assistant needs the command-line tools its instructions call (python3 and claude). Our summary lists: A browser the agent can drive, through Claude in Chrome or Playwright; Python 3, for the answer-memory helper scripts; Your resume or profile stored through the answer-memory skill. Its frontmatter pre-approves these tools: Read, Write, Bash, mcp__claude-in-chrome__*, mcp__plugin_playwright_playwright__*.
SKILL.md names 2 domains. In commands or code: linkedin.com and boards.greenhouse.io; the agent is likely to contact these when it follows the instructions. This is read from the text; nothing was executed.
Our automated static check of SKILL.md found notes only (pre-approves every shell command (allowed-tools: bash)), nothing it rates as a warning. It is not a guarantee. Review the folder before installing.
Job Application Assistant is published under the MIT licence (the repository's licence). It allows redistribution, so the full SKILL.md is shown on this page.
About 4.9k tokens (SKILL.md is roughly 20k characters). Agents keep only the skill's name and description in context until a task matches; then they load SKILL.md in full.
Skills that share tags, products or a category with Job Application Assistant: Job Applier (hanzili/hanzi-browse, 177 stars), Job Posting Scraper (MadsLorentzen/ai-job-search, 45k stars), LinkedIn Job Search (MadsLorentzen/ai-job-search, 45k stars) and Job Application Manager (reactive-resume/reactive-resume, 44k stars). The comparison table on this page puts their stars, adoption, token cost, safety result and licence side by side.
neonwatty (a GitHub user) maintains it in neonwatty/job-apply-plugin, which has 119 GitHub stars. The repository holds 4 skills in this directory. The repository was last updated on October 9, 2026.
Source: neonwatty/job-apply-plugin on GitHub. Facts on this page come from the repository at the commit we read; the author's words are quoted as theirs.