A local-first AI job-search cockpit for matching roles, retrieving career stories, and tracking applications.
ApplyPilot turns a resume, a sanitized local knowledge base, and saved job posts into a daily shortlist with concrete prep assets: resume evidence, reusable stories, answer playbooks, application checklists, and tracker records.
Most job-search tools stop at keyword matching or blind auto-apply. ApplyPilot is built for the slower, more useful middle layer: deciding which roles are worth attention, finding the strongest evidence for each role, and keeping the application pipeline organized without leaking private notes into Git.
This version moves the center of gravity from browser automation alone to the part that can be reliable every day: local knowledge ingestion, retrieval, scoring, prep assets, application workflow preparation, and tracker sync. The LinkedIn/MyCareersFuture extension remains an assisted apply layer, while the core product now works as a usable job-search cockpit even when no external services are configured.
The product is local-first by default, with optional Supabase Auth for real multi-user isolation:
- Public-safe career stories live in
knowledge_base/. - Private interview notes can live in
local_workspace/knowledge_base_private/, which is ignored by Git. - The app works with a gitignored local JSON store by default, so it runs without Supabase or OpenAI.
- When Supabase env is configured, each signed-in user reads and writes rows as
auth.uid()through RLS. - AI calls have deterministic fallbacks, keeping the workflow usable without external services.
| Knowledge base | Daily picks | Application tracker |
|---|---|---|
![]() |
![]() |
| Capability | What it means |
|---|---|
| Role matching | Scores saved jobs against profile, preferences, keywords, skills, region, salary, remote policy, and application friction. |
| Resume and story retrieval | Retrieves resume evidence plus reusable stories, interview notes, job profiles, and answer playbooks for a role. |
| Local Markdown/JSON knowledge base | Reads structured Markdown, JSON sidecars, standalone JSON entries, and private local-only entries. |
| Daily Picks | Ranks saved jobs and attaches prep assets under each role so review starts with evidence, not a blank page. |
| Application workflow | Turns a saved role into a human-reviewable checklist with matched resume evidence, story assets, next actions, and tracker state. |
| Application tracker sync | Manual job saves create drafted tracker records, and repeat saves do not reset existing statuses. |
| Human-in-the-loop automation | The Chrome extension can assist LinkedIn and MyCareersFuture flows, while risky cases route to review. |
flowchart LR
Resume["Resume text"] --> Match["Role matching"]
Jobs["Saved job posts"] --> Match
PublicKB["knowledge_base/ Markdown + JSON"] --> Retrieve["Prep asset retrieval"]
PrivateKB["local_workspace/knowledge_base_private/"] --> Retrieve
Match --> Picks["Daily Picks"]
Retrieve --> Picks
Picks --> Workflow["Application workflow checklist"]
Workflow --> Tracker["Application tracker"]
Tracker --> Notes["Interview notes and reusable stories"]
Notes --> PublicKB
- Upload or parse a resume and confirm job preferences.
- Save a real job into the pool from the Daily Picks page.
- ApplyPilot scores the role and retrieves relevant evidence from resume text and the local knowledge base.
- The job appears in Daily Picks with
Prep assets. - The same saved job is synced into Application tracker as a
draftedapplication record. - Open the application detail page to prepare a checklist, review evidence, and advance tracker state.
See docs/demo-flow.md for a reproducible local demo.
ApplyPilot reads public-safe entries from:
knowledge_base/
βββ interviews/
βββ job_profiles/
βββ playbooks/
βββ stories/
It also reads private local entries from:
local_workspace/knowledge_base_private/
Markdown entries use this structure:
# Title
## Context
## Core facts
## Interview value
## Reusable answer points
## Related roles
## TagsJSON sidecars and standalone JSON entries can add structured retrieval fields such as searchTerms and resumeSignals. Details are documented in knowledge_base/README.md.
applypilot/
βββ apps/
β βββ web/ Next.js dashboard and API routes
β βββ extension/ Chrome MV3 extension for assisted apply flows
βββ packages/
β βββ domain/ Zod schemas, scoring, review routing, pure helpers
β βββ ui/ Shared React primitives
β βββ config/ Environment validation
βββ knowledge_base/ Public-safe Markdown/JSON career knowledge
βββ local_workspace/ Private local-only notes, ignored by Git
βββ tests/ Unit and integration tests
βββ supabase/ Optional Postgres schema
Design choices:
- Keep domain logic framework-agnostic and testable.
- Prefer local Markdown/JSON for early knowledge-base features.
- Treat public and private knowledge folders differently by default.
- Preserve application status when a saved job is refreshed.
- Keep automation assisted and reviewable instead of fire-and-forget.
# Prereqs: Node 22 and pnpm
pnpm install
# Run the dashboard and API
pnpm dev:web
# Optional: build the Chrome extension in watch mode
pnpm dev:extensionOpen http://localhost:3000.
Without Supabase, saved local data is written to local_workspace/applypilot-store.json.
For a database-backed setup, copy .env.example to .env.local, fill in Supabase/OpenAI values as needed, and apply the SQL migrations under supabase/migrations/.
Required env:
NEXT_PUBLIC_SUPABASE_URL=https://your-project.supabase.co
NEXT_PUBLIC_SUPABASE_PUBLISHABLE_KEY=your_publishable_key
SUPABASE_STORAGE_BUCKET=applypilot-assetsNEXT_PUBLIC_SUPABASE_ANON_KEY is still accepted for older projects. SUPABASE_SECRET_KEY or SUPABASE_SERVICE_ROLE_KEY is optional and reserved for trusted background/admin operations; normal web requests use a request-scoped anon client with the signed-in user's JWT so existing RLS policies run.
In Supabase Auth, enable email/password sign-in and add this local redirect URL:
http://localhost:3000/auth/callback
Apply migrations in order, for example with the Supabase CLI or SQL editor:
supabase db push0003_auth_rls_storage_isolation.sql adds explicit Data API grants, binds user-owned rows to auth.uid(), makes the asset bucket private, and limits Storage paths to resumes/{uid}/..., tailored-resumes/{uid}/..., and receipts/{uid}/....
Local auth smoke test:
- Start
pnpm dev:web. - Open
http://localhost:3000/login, create or sign into account A, save a role or upload a resume. - Sign out, sign into account B, and confirm account A's profile, resumes, saved jobs, applications, and local asset URLs are not visible.
- Remove Supabase env values and restart; the app should open in local single-user mode with
local_workspace/applypilot-store.json.
pnpm test # unit and integration tests for scoring, KB retrieval, auth routing, tracker sync, store behavior
pnpm build # production build for all workspace packages
pnpm lint # typecheck and lintCommit only sanitized, reusable material under knowledge_base/. Keep private recruiter details, interview schedules, exact compensation expectations, personal documents, local resume paths, and sensitive application notes under local_workspace/knowledge_base_private/.
local_workspace/ is ignored by Git, including the fallback store at local_workspace/applypilot-store.json.
This is a portfolio-ready slice of the knowledge-backed job-search workflow:
- Match saved jobs.
- Retrieve resume evidence and career-story assets.
- Attach prep assets to Daily Picks.
- Prepare an application checklist from matched materials.
- Sync saved jobs and workflow state into Application tracker.
- Keep public and private knowledge separated.
The next logical branch can focus on tailored output generation: selected resume bullets, a cover-note draft, and a richer application timeline.
Released under the MIT License.

