>set display
PHOSPHOR
MODE
BOOT SCREEN
SOUND
← BACK TO PROJECTS
ELECTRON · REACT 19 · SQLITE · CLAUDE

Prospect

A desktop app for running a job search. Eight sources in one inbox, duplicates collapsed, everything scored, the promising ones read in full and graded with citations, all of it in one SQLite file on your own machine.

Shell
Electron, React 19, TypeScript, Tailwind v4
Storage
One local SQLite file via Drizzle, optional SQLCipher
AI
Claude Code CLI or an Anthropic API key, your choice
Sources
Eight, including two through your own browser session
Privacy
No accounts, no cloud, no telemetry
Status
v0.2.2, active development, still buggy
Prospect's Field view: every judged job plotted as a dot, keyword score along the bottom against AI fit up the side, with quadrants labelled hidden gems, sweet spot, long shots and keyword bait

I built this while job hunting, because the searching had turned into the problem.

Ten tabs open, the same three roles reposted across four boards, good postings buried under staffing agency noise. Underneath all of that the applications I'd already sent were going cold, because I'd lost track of who to follow up with and when. Looking for work was eating the time I needed to actually apply for any of it.

So it does one loop: scrape, score, judge, apply, track.

Eight sources, one card per role

Postings come from public feeds, RemoteOK, We Work Remotely, Remotive and web3.career, plus the monthly Hacker News "Who's Hiring" thread, plus a watchlist of Greenhouse, Lever and Ashby boards polled directly. LinkedIn and Indeed come through your own logged in browser session, so you see what you'd see.

A role posted to LinkedIn, Indeed and the company's own Greenhouse board is one job, not three. Prospect clusters on normalized company, title and location, then collapses each cluster into a single card badged with the other boards it turned up on.

The clustering is deliberately conservative, because the two ways of getting it wrong aren't equal. Under-merging shows you a duplicate, which is mildly annoying. Over-merging hides a real job behind a different one and you never find out it happened.

The Jobs triage view: a scored list of postings on the left with a detail pane, filters for source, salary and work mode across the top
Triage. Every posting scored on arrival, filtered by source, salary and mode.

A score you can argue with

Every job gets a 0 to 100 keyword score the moment it lands, worked out from your own skill profile, importance × proficiency, title boosts, penalties, auto-discard rules. It's instant and it's free, which matters when 900 postings show up at once.

The part I cared about is that it isn't a black box. Every job carries a full "why this score" breakdown you can read line by line, so if a number looks wrong you can find the rule that did it and fix the rule, instead of slowly learning not to trust the whole column.

Making the AI show its work

The promising ones get read in full by Claude, which comes back with a verdict of strong, good, weak or skip. An LLM will happily hand you one confident number for anything, and that number is close to meaningless. So the verdict is built out of parts you can check one at a time:

Why two scores instead of one

The keyword score and the AI fit score get computed independently, so they can disagree, and the disagreement is the useful part. The Field view at the top of this page plots one against the other. Off the diagonal is where the two methods don't match. High keyword with low AI fit is usually keyword bait, the other way round is usually a job whose posting undersells it. A tool with one score has nothing to plot.

Rating the resume, not just the job

The keyword score rates a job against your profile. The coverage view runs the other direction: your resume against one specific posting, as a covered / not-covered checklist built from the requirements the judge extracted.

It has a target band instead of a target, aim for about 75, because chasing 100 reads as keyword stuffing to a human and gets you nothing from the machine either. Next to it an ATS linter flags the mechanical failures, table layouts, missing standard headings, a target title that never appears in your resume, bullets with no numbers in them.

Applying, with a memory

Generate a resume reweighted against a specific posting and a cover letter in your voice, both saved per job, editable inline, exported to PDF. Every generation is kept, so you can go back and see what you actually sent where.

The guided apply panel sits next to the real application form and suggests answers out of your profile. Essay questions get matched against every answer you've given before, across every job, and pre-filled with a reused badge, so "why do you want to work here" isn't written from scratch for the ninth time that week.

Not letting leads rot

Stages, typed and dated events, attachments, and a live calendar. Anything that's gone quiet gets flagged, off one cadence you set once, nudge and cold thresholds defaulting to 7 and 21 days, that every screen reads from. Native OS notifications when a follow-up comes due, throttled so it prompts instead of nagging, and .ics export for whatever calendar you actually live in.

My favorite bug in the project is in here. Adding a private note used to count as activity, so writing "still haven't heard anything" to yourself reset the warmth clock and made a dead application look alive again. Notes don't count as contact any more.

Six ways to look at it

ViewWhat it's for
JobsMaster-detail triage of everything scraped
ApplicationsThe full timeline of what you've submitted
CalendarInterviews, follow-ups and deadlines on a month grid
FieldKeyword score against AI fit, where the two disagree
PipelineKanban with per-lead warmth meters that cool as leads go quiet
HorizonThe next two weeks, agenda-style

An MCP server, so other agents can drive it

While Prospect is running, any Claude Code session can get at the job data over local HTTP through a built in Model Context Protocol server. It reads, and it also does things:

ToolWhat it does
list_jobs / get_jobBrowse and read postings, filtered by score, salary, mode, verdict, ghost risk
get_profileSkills, resume, and thumbs history
judge_jobRecord a full structured judgment
record_applicationMark a job applied and open its pipeline row
advance_stage / add_eventMove an application along, log a dated event
add_feedbackRecord a calibration thumbs-up or down
get_statsFunnel, pipeline, and how often the AI agrees with you
find_saved_answerLook up how you answered a similar question before

Which means "review my stale follow-ups and nudge the ones worth nudging" is a sentence an outside Claude session can actually finish instead of just reporting back on.

Stats that question the scoring

More than counts. Stage to stage conversion, so you can see where the funnel leaks instead of just percent of applied. Your response rate against the usual 3 to 13% band. And score against outcome, response rate bucketed by keyword score and again by AI fit score.

That last chart is there to embarrass the rest of the app. If a higher score doesn't actually predict more replies then it says so, and I know the scoring is decoration. Two independent scores to check against reality is the one thing a tool with a single score can't do.

Local, encrypted, recoverable

No accounts, no cloud, no telemetry. Everything is one SQLite file. On top of that, optional password encryption at rest through SQLCipher, backup and restore to a single archive covering every table plus attachments and resume files, and optional folder sync to share jobs between your own machines, last write wins.

If the database ever fails to open, Prospect boots a recovery screen that copies your raw data somewhere safe before it offers to reset anything. A job search is months of accumulated context, and dying on an error box with a Reset button next to it isn't an acceptable way to treat that.

It's still in development

Features move, data shapes change, things break between updates. Kick the tires, file issues, keep a backup of your DB, but don't make it your only system of record yet.