github ai-job-search-dev/ai-job-search v1.7.1
v1.7.1 - Cheaper ranking, portals that fail loudly, forks that stop fighting CI

latest releases: v1.7.3, v1.7.2
one month ago

A patch release with one theme: the workflow stops paying for work it does not need and stops hiding work it failed to do. /rank no longer drags your whole job history through the conversation on every run, the portal CLIs now refuse bad input instead of silently returning the wrong thing, and forks get a clean CI and a complete /setup. Seventeen entries, fourteen of them fixes, most of them reported and fixed by contributors within a day of each other.

Highlights

/rank is bounded and keeps its state on disk (#395, #424, #425, #390)

A bare /rank used to score the entire backlog in one go and read the whole of seen_jobs.json into the conversation twice per run - a cost that grew for the life of a workspace and was paid regardless of batch size (one reporter measured a 188 KB state file). --limit <N> now bounds each run to ten jobs by default, independently of --top, and reports what it deferred. tools/rank_state.py owns the state traffic: candidates selects and projects only the fields a scoring agent needs, sweep runs the expiry pass on disk, and apply writes results back atomically. Scoring policy is unchanged, and every existing write-back rule (legacy location migration, null deadlines never erasing a stored one, verbatim strengths and gaps) is pinned by tests. /rank also now flags postings whose stored posted_date is more than 30 days old.

Portal CLIs fail loudly instead of lying (#426, #429, #371, #416, #418, #421)

The sharpest fix of the release: the unknown-flag guard in the four bunli-based CLIs only inspected --long flags, so an undefined short flag was silently discarded and the search ran unfiltered - search -q "sygeplejerske" on jobnet returned 18,210 ads with exit 0 where the correct flag returns 669. Both dash forms are now checked. The detail commands of jobbank, jobdanmark and jobnet accept full posting URLs as the contract always said they should, linkedin-search rejects fractional numeric flags instead of truncating them, and a one-CLI-at-a-time audit closed three crashes where a single null field from a portal API killed the whole run (a jobbank feed date, a jobnet publication date, a jobdanmark autocomplete item).

Forks get a clean CI and a complete /setup (#405, #433, #396)

The python-tests job ran the upstream-only placeholder-integrity tests on every personalised fork and failed permanently; they now skip when GITHUB_REPOSITORY is a fork and still run locally and upstream. /setup now fills the contact blocks inside 05-cv-templates.md and 06-cover-letter-templates.md - the two templates /apply compiles from - which a full run previously left as [YOUR_NAME] and [YOUR_EMAIL]; /reset restores them. And settings.json no longer pre-approves bun run on arbitrary files: the allowlist is one path-scoped entry per shipped portal CLI.

Salary data tools stop failing silently (#414, and the salary_lookup.py null fix)

convert_salary_excel.py could mistake a source-citation line above a real header for the header itself and drop every company's salary data with exit 0; header detection now requires cross-cell corroboration and warns when a sheet yields no salary columns. salary_lookup.py no longer crashes on a null metadata or categories field.

Fork maintainers: what to reconcile

Pull this tag rather than raw master, then check three things:

  1. /rank behaviour changed. A bare run now scores at most 10 jobs and reports the rest as deferred; pass a larger --limit if you relied on scoring everything in one go. State moves through tools/rank_state.py; if you customised rank.md's Step 1 or Step 4, re-read the new versions before merging your changes over them.
  2. .claude/settings.json changed twice. The blanket Bash(bun run:*) entry is gone in favour of one path-scoped line per shipped CLI, and two python tools/rank_state.py lines were added. A fork with its own portal skills needs its own path-scoped bun run line per skill (and the matching tools/security_guards.py entry), or /scrape will prompt once per run.
  3. /setup and /reset cover two more files. If you already personalised 05-cv-templates.md and 06-cover-letter-templates.md by hand, nothing changes; if you have not, re-run /setup --section for the contact blocks or edit them directly.

No framework_version marker changed in this release: the methodology files under job-application-assistant/ are as they were in 1.7.0.

Also in this release

  • A CHANGELOG structure guard runs on every PR (duplicate or unknown headings, orphan entries, conflict markers).
  • /scrape persists each posting's publication date (#391), which /rank now consumes.
  • linkedin-search detail accepts LinkedIn job URLs with trailing slashes, regional subdomains and tracking parameters (#411).
  • The documents/interview/** ignore rule no longer claims interview prep is written there; /interview has always saved under documents/applications/, which was already ignored (#336).

Thanks to everyone who reported and fixed this cycle - ayobamiseun for the null-deref audit across all six CLIs, Na-bra for the salary and flag-guard fixes, InstinctEx for the /rank work and the numbers behind it, iAbhiNaV2005 for the URL normalisation, markvandeven for the fork-CI diagnosis, and shahidbeig-a11y for carrying it.

Don't miss a new ai-job-search release

NewReleases is sending notifications on new releases.