Skip to content

ShousenZHANG/joblit

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

1,012 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Joblit

An end-to-end job-search workstation. Fetch roles, triage them, tailor a custom resume and cover letter for each JD, auto-fill any ATS form, and export production-grade PDFs — without copy-paste.

Live Demo · Codex Batch Protocol · Domain Context · Report a bug

Next.js React TypeScript Prisma PostgreSQL Chrome Extension Vercel GitHub Actions Vitest License

API Routes API Handlers Test Files Prisma Models Server Modules UI Pages


What is Joblit

Most job-search tools stop at listing or tracking. Joblit closes the loop:

Stage What Joblit does How
Discover Batch-fetch roles from job boards GitHub Actions workers — Seek + LinkedIn (JobSpy), feature-flagged and extensible
Triage Fast scan, filter, status-track Two-pane workspace with search and JD rendering
Tailor Generate targeted resume and cover letter AI prompt engine with versioned rule templates
Apply Auto-fill any ATS application form Chrome extension with self-learning knowledge base
Export Production-grade PDF output LaTeX compile pipeline, EN + CN templates

The product differentiator is the Chrome extension: every correction you make trains a personal knowledge base, so subsequent fills get faster and more accurate.

Joblit is free and open to everyone. Sign in with Google or GitHub; no invitation, manual approval, subscription, or credit card is required.

Table of Contents

Features

Job Intake Pipeline

  • FetchRun tasks with configurable role categories, markets, and filters
  • Dispatched to GitHub Actions workers — a Seek fetcher (tools/fetcher/run_seek.py) and the JobSpy fetcher (LinkedIn + more); each source is feature-flagged (e.g. SEEK_FETCH_ENABLED) and stops on any anti-bot challenge by design
  • Import path with dedupe on userId + jobUrl and tombstone filtering for permanently dismissed URLs
  • Title/description exclusion rules, work-type / classification filters, and an on-demand full-JD enrich for teaser-only Seek listings at tailoring time

Jobs Workspace

  • Two-pane review UI: fast scan on the left, full JD with markdown rendering on the right
  • Search, filter, pagination, and status transitions (NEW / APPLIED / REJECTED)
  • Batch operations and tombstone tracking on delete

Resume Studio

  • Multi-step master-resume editor: basics, summary, experience, projects, education, skills
  • Bullet-level edits with markdown emphasis and live preview
  • Per-locale profiles (en-AU / zh-CN) with localized LaTeX templates

AI Tailoring Engine

  • Versioned PromptRuleTemplate with skill-pack delivery
  • Prompt generation for resume and cover-letter targets
  • Strict schema validation, promptMeta consistency checks, evidence-grounded bullets
  • Manual JSON import path: copy prompt to any external model, import the result back

PDF Export

  • LaTeX-based resume and cover-letter rendering with bilingual templates
  • Optional persistent storage via Vercel Blob

Batch Automation (Codex Workflow)

  • Create NEW-scope batches from filtered jobs
  • Atomic claim-and-complete loop via POST /api/application-batches/:id/run-once
  • Progress tracking via batch summary API
  • Full external orchestration protocol documented in AGENTS.md

Open Access & Service Imports

  • Self-service access — anyone can sign in with Google or GitHub OAuth and start using Joblit immediately
  • No account gate — there is no invitation, manual approval, subscription, or credit-card requirement
  • Internal JobSpy import/api/admin/import is a service-to-service route for the fetch worker, protected by IMPORT_SECRET; it is not a user-facing admin console or an account-access mechanism

Chrome Extension

Manifest V3 extension that auto-fills job application forms using your Joblit resume profile.

ATS Adapters

Purpose-built field detection per ATS:

ATS Adapter Coverage
Workday workday.ts Inputs, dropdowns, custom components
Greenhouse greenhouse.ts Standard application forms
Lever lever.ts Application and referral forms
iCIMS icims.ts Career portal forms
SuccessFactors successFactors.ts SAP-based application flows
Generic generic.ts Fallback for unknown ATS platforms

Self-Learning Knowledge Base

Each application teaches the extension:

  1. Fill — auto-fill detected fields from your resume profile
  2. Review — floating widget shows what was filled; edit any value inline
  3. Learn — each correction auto-saves as a mapping rule (field selector → profile path)
  4. Recall — next time the same field appears, the knowledge base supplies the corrected value

Rule matching priority: user rules → exact form signature → same ATS + domain → same ATS cross-domain. Rules are scoped at three levels (global / ATS-level / site-specific) and managed from the web dashboard.

Technical Notes

  • Shadow DOM widget — vanilla JS, no framework dependency in content script (~39 KB)
  • React-compatible input simulation — dispatches native events to work with React, Angular, and Vue controlled inputs
  • Form signature — djb2 hash of field structure for cross-session form matching
  • Offline queue — submissions queue locally and sync when back online
  • Bilingual UI — English and Chinese via lightweight i18n

Local AI with stock Hermes (Beta)

Joblit can generate a grounded CV or cover letter through the official Hermes client on the user's own computer. The website sends only a job ID and target to the extension; the extension fetches the canonical Joblit prompt, calls the loopback Hermes Runs API, and returns a strict JSON result to the existing DRAFT editor.

  • Uses an unmodified Hermes installation and the user's own openai-codex / ChatGPT OAuth session
  • Binds only to 127.0.0.1; Joblit and Hermes API keys never enter page JavaScript
  • Disables Hermes memory, MCP, and executable toolsets for the Joblit profile
  • Keeps a verified persistent local distribution source so official profile updates remain repeatable
  • Reuses an existing openai-codex login and opens OAuth only when Hermes reports logged out
  • Preserves the existing manual Skill/copy/paste method as fallback

Windows setup is user-launched and isolated from existing Hermes profiles:

pwsh -File tools/hermes/bootstrap/Install-JoblitHermes.ps1 `
  -PackagePath <verified-package.zip> `
  -ProfileName joblit-<opaque-account-hash> `
  -ExpectedArchiveSha256 <published-sha256>

After bootstrap succeeds, paste the one-time local API key into Extension settings → Local AI Beta. Production profile releases require a trusted Ed25519 signature; the current empty key registry intentionally fails closed until a real release key is provisioned.

Architecture

flowchart LR
  U[User] --> FE[Next.js UI]
  U --> EXT[Chrome Extension]

  FE --> API[Next.js API Routes]
  API --> DB[(PostgreSQL via Prisma)]
  FE --> AUTH[NextAuth]

  EXT --> EXTAPI[Extension API Routes]
  EXTAPI --> DB
  EXT -->|auto-fill| ATS[ATS Application Forms]
  EXT -->|learn| KB[Knowledge Base]
  KB --> DB

  FE --> FR[Create FetchRun]
  FR --> GH[GitHub Actions]
  GH --> PY[Seek + JobSpy fetchers]
  PY --> IMP[Secret-gated JobSpy Import API]
  IMP --> DB

  FE --> AIPATH[AI Tailoring APIs]
  AIPATH --> PDF[LaTeX Render]
  PDF --> DL[PDF Download]

  FE --> BATCH[Batch Automation APIs]
  BATCH --> AIPATH
Loading

Domain vocabulary lives in CONTEXT.md, while durable architecture decisions live in docs/adr/.

Project Structure

app/
  (marketing)/        Landing, privacy, terms, get-extension
  (auth)/             Login
  (app)/              Protected workspace
    fetch/            Job intake pipeline
    jobs/             Jobs triage workspace
    resume/           Resume studio + prompt rules
    discover/         Curated learning videos
    extension/        Token + knowledge-base dashboard
  api/                Backend routes
    ext/              Extension-specific APIs
    admin/import/     Internal JobSpy import route (IMPORT_SECRET-protected)
chrome-extension/
  src/
    background/       Service worker, auth, API client, sync queue
    content/          Content script, form detection, filling, widget
      detector/       Field classifier, ATS adapters, form signature
      filler/         Input simulator, form filler
      widget/         Shadow DOM floating widget
      recorder/       Submission recorder
    popup/            Extension popup UI (React)
    shared/           Constants, i18n, types, field taxonomy
lib/
  api/                Client-side fetch helper
  server/             Domain services (AI, PDF, prompts, persistence, observability)
  shared/             Zod schemas, market/locale seam, shared config
prisma/               Schema + migrations
tools/                Fetcher integration (Seek + JobSpy), readme metrics, CI policy checks
test/                 API + server test suites

Quick Start

Prerequisites

  • Node.js >= 20.10
  • npm >= 10
  • PostgreSQL database (Neon recommended; any Postgres 14+ works)
  • Optional: Gemini API key, Vercel Blob token, Chrome 120+ for the extension

Setup

# 1. Clone and install
git clone https://github.com/ShousenZHANG/joblit.git
cd joblit
npm install

# 2. Configure environment
cp .env.example .env
# Edit .env: fill DATABASE_URL, AUTH_SECRET, OAuth credentials, etc.

# 3. Initialize database
npx prisma migrate deploy
npx prisma generate

# 4. Run dev server
npm run dev

Open http://localhost:3000.

Chrome Extension (optional)

cd chrome-extension
npm install
npm run dev        # HMR for active development
npm run build      # Production build → chrome-extension/dist

Load chrome-extension/dist as an unpacked extension at chrome://extensions.

Scripts

Command Description
npm run dev Start Next.js dev server
npm run build Production build
npm test Run all tests once (Vitest)
npm run test:watch Tests in watch mode
npm run lint ESLint
npm run readme:metrics Refresh auto-metrics badges in this README
npm run deps:policy Check repository dependency policy
npm run deps:audit npm audit (production deps, high severity)
npm run hermes:profile:test Validate the minimal stock-Hermes Joblit profile
npm run hermes:package:test Test deterministic packaging and Ed25519 verification
npm run hermes:package:build -- --staging <dir> --source-commit <sha> Build a deterministic profile package
npm run hermes:package:verify -- --root <dir> --mode <integrity|digest|production> Verify profile package trust and content
npx prisma migrate dev Apply database migrations in development
npx prisma studio Database GUI

Run a single test file:

npx vitest run path/to/file.test.ts

Environment Variables

A complete template lives in .env.example.

Required

Variable Purpose
DATABASE_URL PostgreSQL connection string (Neon serverless adapter)
AUTH_SECRET NextAuth session signing secret
GOOGLE_CLIENT_ID / GOOGLE_CLIENT_SECRET Google OAuth
GITHUB_ID / GITHUB_SECRET GitHub OAuth
IMPORT_SECRET Service secret for the internal JobSpy import route (/api/admin/import)
FETCH_RUN_SECRET Auth for the fetch-run config callback
APP_ENC_KEY Extension token encryption key (base64)
LATEX_RENDER_URL / LATEX_RENDER_TOKEN External LaTeX render service

Optional

Variable Purpose
SEEK_FETCH_ENABLED Kill-switch for server-side Seek fetching (1 / true to enable). Off by default — Seek is unreachable from datacenter / CI IPs (Cloudflare blocks every endpoint); the supported path is the browser extension. See ADR-0003.
GEMINI_API_KEY / GEMINI_MODEL AI provider
BLOB_READ_WRITE_TOKEN Vercel Blob storage
GITHUB_OWNER / GITHUB_REPO / GITHUB_TOKEN / GITHUB_WORKFLOW_FILE Fetch workflow dispatch
JOBLIT_WEB_URL Public URL for the extension callback
YOUTUBE_API_KEY Discover-page video pipeline
CRON_SECRET Cron endpoint auth
RSSHUB_URL / RSSHUB_JOB_ROUTES / GITHUB_CN_JOB_REPOS China job sources
SENTRY_DSN Error reporting (when SDK is installed)

Codex Batch Workflow

External orchestration protocol for AI-assisted batch tailoring is documented in AGENTS.md. Summary:

  1. Fetch jobs and keep target roles as NEW.
  2. POST /api/application-batches with scope NEW.
  3. Loop POST /api/application-batches/:id/run-once (atomic claim + complete).
  4. For each task: generate prompt, run external model, import result.
  5. Track progress with GET /api/application-batches/:id/summary.

Testing

  • 750+ tests across the web suites (Vitest), green on every push
  • Test files live alongside sources (*.test.ts / *.test.tsx) or in test/
  • test/api/ covers API routes, test/server/ covers domain modules
  • 80%+ coverage target for new code
  • E2E with Playwright for critical user flows (planned; see docs/plans/)

CI runs lint, dependency policy, full test suite, and (per-PR) Lighthouse against the Vercel preview URL with the budget defined in .lighthouserc.json.

Deployment

  • Recommended: Vercel + Neon (PostgreSQL)
  • Configure all environment variables in the deployment platform
  • Chrome extension is distributed as a .zip for sideloading or via the Chrome Web Store

Existing-environment cutover

The migration that removes the obsolete access-request schema is destructive, so existing environments must use a code-first drain sequence:

  1. Deploy the current application code without running the drop migration.
  2. Wait for every old application instance and serverless deployment version to drain.
  3. Run npx prisma migrate deploy against the environment database.
  4. Remove the obsolete ADMIN_EMAILS environment setting.

Fresh environments may run all migrations during initial provisioning because no older application instance can still reference the removed schema.

Troubleshooting

Symptom Fix
GITHUB_DISPATCH_FAILED Verify GITHUB_TOKEN workflow permissions on the fetch repo
Low import volume Increase fetch breadth or relax title/description excludes
PROMPT_META_MISMATCH Re-download skill pack and re-copy the prompt
Extension fields not filling Check token validity on the Extension page
403 Forbidden on Vercel preview Disable Vercel deployment protection or use the custom domain

Contributing

Issues and pull requests are welcome. See CONTRIBUTING.md for the development workflow, commit conventions, and review expectations. Architectural decisions are tracked in docs/adr/ once a decision needs to outlive the PR thread.

Security

If you find a security vulnerability, please follow the responsible disclosure process documented in SECURITY.md. Do not open a public GitHub issue for security reports.

Acknowledgments

Joblit is built on top of excellent open-source work:

License

Apache License 2.0. See LICENSE and NOTICE.

About

Resources

License

Contributing

Security policy

Stars

0 stars

Watchers

0 watching

Forks

Packages

 
 
 

Contributors