- Chrome MV3 side-panel architecture, browser integration, draft-state lifecycle, page context capture, cross-page state handling and regression testing.
- Chrome MV3 · Local-first · LLM · Python
- 2059 tests passed
Problem
A local-first AI workflow for turning resumes and live job descriptions into actionable application drafts.
Most AI job-search help happens in a separate chat window. The job posting lives in one tab, the resume in another file, and the model somewhere else.
JobMate moves the assistant next to the job posting, so the context is already there when the user needs it.
Using a general chat assistant for applications forces constant context switching. Every posting means copying the JD out, pasting results back and editing by hand.
Each round trip loses context, and the resume has to be pasted again and again into a cloud chat.
- Job platform
- Copy JD
- ChatGPT
- Copy result
- Back to platform
- Edit
Chrome MV3 side-panel architecture, browser integration, draft-state lifecycle, page context capture, cross-page state handling and regression testing.
Build
A Chrome MV3 native side panel that stays next to the job page. It reads the current job description, combines it with a locally managed resume and generates an application draft — for example a greeting message to the recruiter.
JobMate generates and preserves the draft inside the browser workflow. The user reviews, edits and decides whether to send it on the job platform.
Features
- 01Chrome MV3 native side panel
- 02Reads the JD from the current job page
- 03Local resume management
- 04Resume × JD context assembly
- 05AI greeting-message generation
- 06Draft lifecycle management
- 07Draft review & copy
- 08State kept across page switches
- 09Local-first privacy
- Job Page
- JD ReaderLocal Resume
- Context Assembly
- LLM
- Draft State
- User Review
The side panel is the only UI surface. It survives tab and page changes, so a draft in progress is not lost when the user browses to another posting.
Context is assembled per request from the live JD and locally managed resume rather than being maintained as a persistent chat transcript.
- Job Page
- JD + Resumelocal
- LLM
- Draft
- User Review
- 02› Read the JD; assemble context with the local resume
- 03› Generate a greeting draft
- 04› Draft saved — it survives page switches
- 05… Waiting — the user reviews, edits and decides whether to send
Job Page
Job page open — side panel docked beside it
JD + Resumelocal
Read the JD; assemble context with the local resume
LLM
Generate a greeting draft
Draft
Draft saved — it survives page switches
User Review
Waiting — the user reviews, edits and decides whether to send
- 01
Native side panel, not a popup
A popup closes when focus moves. The MV3 side panel stays open beside the page, which is where the user is actually working.
- 02
Local-first by default
The full resume is personal data. It stays on the user's machine instead of becoming a persistent cloud record.
- 03
Drafts as state, not as chat
Each draft has a lifecycle. The user can come back to it after switching pages instead of scrolling through a transcript.
- 04
Human stays in the loop
JobMate prepares the draft. The user remains in control of reviewing, editing and sending it on the job platform.
Engineering
- Python + Chrome MV3 extension.
- Tested with pytest, linted with ruff.
- Page-switch state handling and draft lifecycle are covered by tests, not only the happy path.
The resume is managed locally. JobMate avoids storing the complete resume as persistent cloud data.
Each generation request assembles only the context needed from the current JD and locally managed resume before passing it to the model.
- tests passed · pytest
- 2059
A working side-panel flow from reading a live JD to a saved draft that the user reviews in the browser.
Notes
The hard part of an AI product is rarely the prompt. It is state: what survives a page switch, what is a draft, what is final.
Privacy is an architecture decision. It has to be made before the first line of storage code, not added later.
- Chrome MV3
- Browser Extension
- Python
- LLM
- Local-first
- pytest
- ruff