Commit Graph
11 Commits
Author SHA1 Message Date
Rasika d1e707ef1f feat(job-scraper): referral-contact LinkedIn search links for high/medium-fit jobs (#149)
* added contact skill

* refactor(job-scraper): fold referral-contacts into Step 4.5, drop contacts cache
2026-07-15 07:52:04 +02:00
Yash Rajeshbhai DarjiandCursor 0a8fc194e5 docs: sync onboarding with linkedin-search + freehire-search reality (#150)
/setup still told non-DK users that built-in CLIs are Denmark-specific.
Align setup, /add-portal, and search-queries.md with shipped country-agnostic
CLIs and /scrape auto-discovery (post #85 / #95 / #102).

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-07-14 14:30:49 +02:00
Erik Pastor RiosandClaude Opus 4.8 7e8df35819 docs(job-scraper): make search queries market-neutral (#95)
Rebased onto current master. The SKILL.md description and "How It Works"
copy were already generalized by #102, so this drops those now-redundant
edits and keeps only the unique remaining value: replacing the hardcoded
Danish job boards (jobindex.dk, karriere.dk, jobfinder.dk, akademikernes.dk)
and Danish location terms in search-queries.md with configurable
placeholders and an /add-portal pointer, so the query templates apply to
any market.

Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-10 08:06:54 +02:00
Sai Sridhar Tarra fea59fd8df docs: document complete seen_jobs.json schema including rank fields (#107) (#111) 2026-07-09 21:32:43 +02:00
Yash Rajeshbhai DarjiandCursor 3bb4688e5d Use CLI detail in scraper Step 2; broaden skill description (#102)
Follow-up to #65 feedback after #52 merged CLI-first search. Step 2 now
uses each portal's detail command for CLI-sourced jobs (WebFetch only for
WebSearch fallbacks). Skill description reflects market-agnostic portal
CLIs instead of Danish-only wording.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-07-09 21:12:15 +02:00
Mads LorentzenandClaude Fable 5 a558c8593b fix: rename job-scraper skill to 'scrape' so /scrape resolves natively (#74)
The docs instruct users to run /scrape, but the skill's name was
job-scraper, so /scrape never resolved as a command - it only worked
via fuzzy trigger matching on the description. Renaming the skill's
name field makes /scrape a real, autocompleted command, consistent
with /upskill (whose skill is named upskill). Folder path unchanged.

Fixes #68. No wrapper command per the single-source-of-truth
precedent (#52).

Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
2026-07-08 18:51:18 +02:00
Mads LorentzenandClaude Fable 5 a5ffcc39ff chore: untrack tracker CSV, scope scraper Bash permission, fix portal SKILL.md paths (#71)
- Untrack job_search_tracker.csv: it was both tracked and listed in
  .gitignore (same inconsistency class as the settings.local.json fix
  in #27). Users' personal rows risked merge conflicts on every pull;
  commands already create the file with the standard header when it
  is missing.
- Scope job-scraper's allowed-tools Bash entry (from #52) to
  'bun --version' and the portal-CLI invocation pattern, adopting the
  tighter form proposed in #65.
- Fix all five portal SKILL.mds documenting 'bun run skills/...'
  paths that do not resolve from the repo root ('.agents/skills/...'
  is correct) - now load-bearing since #52 wired /scrape to read
  these docs for CLI invocations. Surfaced in #66.
- Teach tools/lint_skills.py to glob-expand allowed-tools bun run
  targets so scoped wildcard permissions lint correctly.

Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
2026-07-08 17:14:39 +02:00
PRATHAM KUMARandrajpratham1 1ac677dd7d This PR fixes two genuine gaps in the framework — a documented command with no backing file, and CLI tools that were installed but never called. (#52)
* feat: add /upskill command file to wire the upskill skill into Claude Code

The upskill skill and its full SKILL.md workflow already existed in
.claude/skills/upskill/SKILL.md, but there was no corresponding command
file in .claude/commands/. Without it, running /upskill in Claude Code
had zero structured behaviour — Claude would improvise with no defined
steps, mode detection, or output format.

This commit adds .claude/commands/upskill.md as the thin orchestration
layer that was missing:

- Step 0: Parses \ to determine aggregate mode (no args,
  analyses all jobs in job_search_tracker.csv) vs. targeted mode
  (a URL is passed, analyses that single posting). Unrecognised input
  triggers a clarifying prompt rather than silently misbehaving.

- Step 1: In aggregate mode, reads the tracker and exits early with a
  helpful message if it is empty, so the user is never dropped into a
  broken analysis with no data.

- Step 2: Delegates all analysis work to the existing upskill SKILL.md
  (hard skill diff, LLM synthesis, heatmap, web-searched resources,
  study order, report save). No analysis logic is duplicated here.

- Step 3: Presents a concise post-run summary — critical/high gaps,
  total estimated study time, and next-step suggestions (/scrape,
  /apply, review the saved report).

Design principle: the command is intentionally a thin driver. All
substantive logic lives in SKILL.md so it remains in one place and
is easy to update independently of the command shell.

* fix: wire CLI tools into /scrape as primary search mechanism

The repo ships five Bun CLI search tools under .agents/skills/:
  - jobindex-search   (Jobindex.dk — largest Danish board)
  - jobbank-search    (Akademikernes Jobbank — academic/professional)
  - jobdanmark-search (Jobdanmark.dk — broad coverage)
  - jobnet-search     (Jobnet.dk — government portal)
  - linkedin-search   (LinkedIn public jobs-guest API — country-agnostic)

Before this fix, none of them were ever called during /scrape. The
job-scraper SKILL.md told Claude to run WebSearch for everything,
meaning the CLIs were installed and documented but sat in dead-code
limbo with no callers.

Changes to .claude/skills/job-scraper/SKILL.md:

1. Added Bash to allowed-tools so the bun CLI commands are permitted
   by Claude Code's tool-permission system. Without this, any attempt
   to shell out would be blocked regardless of the instruction text.

2. Replaced the single WebSearch-only Step 1 with a three-part search
   strategy:

   Step 1a — bun availability check
   Runs \un --version\ first. If bun is not installed the skill
   gracefully degrades to WebSearch for all portals (Step 1c) and
   notes the fallback in the results output, rather than crashing.

   Step 1b — CLI tools as primary mechanism
   For each query term extracted from search-queries.md, runs all five
   CLIs with \--jobage 14 --limit 20 --format json\. Flags are
   consistent with each tool's documented contract so output is
   predictable. Each CLI call is independent: a non-zero exit or empty
   result on one portal does not abort searches on the others. Results
   are collected and merged before deduplication.

   Step 1c — WebSearch fallback
   Used for portals without a CLI skill (karriere.dk, jobfinder.dk,
   company career pages via site: searches) and as the universal
   fallback when bun is unavailable. This preserves backwards
   compatibility for users who have not installed bun yet.

The net effect: /scrape now actually uses the CLI infrastructure the
repo was built around. WebSearch remains available for portals outside
the shipped skill set and for users on environments without bun.

* fix: rework /scrape CLI wiring + drop /upskill command file

Two changes addressing maintainer feedback on PR #52.

--- /scrape: use portal SKILL.md as source of truth ---

The previous approach hardcoded per-portal bun invocations directly
in job-scraper/SKILL.md. This broke in practice:
  - jobbank requires --key (not --query); --query is not a valid flag
  - jobnet uses --search-string and region/occupation filters; passing
    --query silently returns the full unfiltered job firehose
  - --sort date and uniform --jobage 14 are not supported by all portals

The fix removes all hardcoded per-portal flag examples. Instead, Step
1b now instructs the agent to:
  1. Discover installed portal skills via .agents/skills/*/SKILL.md
  2. Read each portal's own SKILL.md for its documented CLI interface
  3. Translate search-queries.md terms into that portal's flag format
  4. Use each portal's supported recency and limit flags

This makes the scraper self-maintaining: new portals added via
/add-portal are automatically included without any changes to this
file, and the scraper can never drift from the CLIs again.

The bun availability check (Step 1a) and Bash in allowed-tools are
preserved - both are still needed. The WebSearch fallback (Step 1c)
is preserved and cleaned up to cover: portals without a CLI skill,
any portal whose CLI fails at runtime, and the bun-unavailable case.

--- /upskill: drop command file ---

.claude/commands/upskill.md is removed. /upskill is deliberately
skill-hosted: .claude/skills/upskill/SKILL.md is the backing file
and parses its own /upskill vs /upskill <URL> modes (same pattern
as /scrape, which also has no command file). The command file created
a second entry point that duplicated the skill's argument parsing,
violating the single-source-of-truth principle established in #44
and #49.

---------

Co-authored-by: rajpratham1 <your-email@example.com>
2026-07-08 17:08:12 +02:00
Ayobami Adegoke fce2cf23c0 feat: add /rank command to triage scraped jobs into a ranked shortlist (#43)
/scrape finds and dedupes postings; /apply evaluates one at a time in
depth. Nothing connects the two ends: after a scrape returns 20 jobs, the
user eyeballs a table to decide where to spend /apply effort. /rank is the
bridge: batch-score every new posting against the fit framework and return
a ranked shortlist.

How it works:

- Selects jobs with status "new" from job_scraper/seen_jobs.json (--all
  re-ranks everything unapplied; a focus argument filters), excluding
  anything already in job_search_tracker.csv
- Dispatches parallel general-purpose agents (~5 jobs each) that WebFetch
  each posting and score the five dimensions from 04-job-evaluation.md.
  The rubric (skill match areas, career goals, deal-breakers) is passed
  inline per the same token-efficiency rules /apply uses; agents score
  only from actually fetched content and mark dead postings expired,
  never guessing from a title
- Triage depth by design: posting text vs. profile only - no company
  research, no salary lookups. /apply's Step 1 evaluation stays
  authoritative and always re-runs on handoff
- Aggregates with the framework's 30/25/15/30 weighting and verdict
  bands; location deal-breakers veto regardless of score; deadlines
  within 7 days get urgency flags and win ties
- Updates seen_jobs.json additively (status "ranked"/"expired" plus
  rank_score/rank_verdict/rank_date) so /scrape dedup keeps working;
  the tracker is read-only. Re-running is idempotent

Integration: job-scraper SKILL.md documents the new status values and
suggests /rank after large scrape batches; README (commands list, file
tree, quick-start step 4).
2026-07-07 17:31:31 +02:00
Deepak Dhungel 37a0eed6e7 fix(skills): replace bold markdown with proper YAML Frontmatter (#16) 2026-06-15 21:41:10 +02:00
AI Job SearchandClaude Opus 4.6 c66d599d75 Initial release: AI-powered job application framework
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-23 08:34:06 +01:00