From linkedin-apply
Scrape a LinkedIn job offer and score it against your profile using Claude LLM — produces APPLY / REVIEW / SKIP decision with 4-dimension scores. Triggers: "linkedin apply" | "analyze job" | "job match" | "linkedin-apply" | "score this job" | "should i apply for this job" | "evaluate this job posting" | "is this job a good fit" | "check this job offer" | "rate this job".
npx claudepluginhub roxabi/roxabi-plugins --plugin linkedin-applyThis skill is limited to using the following tools:
Analyze a LinkedIn job offer against your candidate profile and get an LLM-powered decision: **APPLY**, **REVIEW**, or **SKIP**.
Evaluates job postings (JD text or URL) against your profile with A-F match score, archetype analysis, compensation research, positioning strategy, and interview prep.
Analyzes CV-job description fit by scoring skills match (40%), tools/tech (25%), seniority (15%), keywords (10%), and soft skills (10%). Identifies gaps, computes percentage, and recommends apply/skip. Triggers on 'job fit', 'skill gap'.
Audits job postings for quality, realism, internal consistency, and market alignment using a 100-point scoring rubric identifying red flags and unrealistic expectations.
Share bugs, ideas, or general feedback.
Analyze a LinkedIn job offer against your candidate profile and get an LLM-powered decision: APPLY, REVIEW, or SKIP.
Let:
VL := ~/.roxabi-vault/linkedin-apply/
SD := $CLAUDE_PLUGIN_ROOT/../../scripts/
Extract LinkedIn URL from $ARGUMENTS. ¬URL → "Usage: /linkedin-apply " → stop.
URL valid ⟺ contains linkedin.com ∧ (/jobs/view/ ∨ /jobs/).
Check prerequisites:
VL/candidate.yaml exists — ¬exists → run /linkedin-apply-init firstpython3 -c "import playwright, playwright_stealth, jinja2" 2>&1 — missing → pip install playwright playwright-stealth jinja2 pyyamlplaywright install chromiumcd <scripts_dir> && python3 scraper.py "<url>"
Capture stdout (JSON) + stderr (logs). Errors: SessionExpiredError → run /linkedin-apply-init; PlaywrightNotAvailableError → install playwright; JobNotFoundError → job no longer available; other → show message. Parse JSON output → job data dict.
cat ~/.roxabi-vault/linkedin-apply/candidate.yaml
Criteria (user override ≻ plugin default): VL/criteria.yaml if ∃, else <plugin_dir>/config/criteria.yaml.
CV path: ~/.roxabi-vault/cv/cv_data.json if ∃, else construct minimal JSON from candidate.yaml.
echo '<job_json>' > /tmp/linkedin_job_<job_id>.json
cd <scripts_dir> && python3 matcher.py \
--job-json /tmp/linkedin_job_<job_id>.json \
--cv-json <cv_data_path> \
--criteria-yaml <criteria_path> \
--output json
cd <scripts_dir> && python3 -c "
import json, sys
sys.path.insert(0, '_lib')
from storage import save_analysis
# reconstruct dataclasses and call save_analysis(job, match)
"
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
DECISION: APPLY | Score: 7.8/10
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
Job: <title> at <company>
URL: <url>
Type: <Easy Apply / External (ATS: greenhouse)>
Scores:
Tech: 8/10
Seniority: 7/10
Culture: 8/10
Responsibilities: 8/10
Dealbreakers: PASS
Highlights:
+ <highlight 1>
+ <highlight 2>
Prepare for:
? <expected question 1>
? <expected question 2>
Summary: <analysis_summary>
Saved to: ~/.roxabi-vault/linkedin-apply/applications/<path>
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
SKIP → show dealbreaker issues clearly. REVIEW → highlight what's uncertain/missing.
~/.config/linkedin_browser_profile persists session between runsVL/applications/YYYY-MM/$ARGUMENTS