TreeMap
무료 오픈소스 디스크 사용량 시각화 도구로, 사각형 트리맵·중복 파일 탐색·디스크 가득 예측·정리 시 파일을 휴지통으로만 이동한다
이력서를 업로드하고 채용 공고를 붙여넣으면 키워드에 맞춰 즉시 맞춤 이력서를 생성합니다
Tailor your resume to match the keywords in any job description to boost your chances. Upload your resume, paste a job description, and get a perfectly customized resume instantly.
생산성Python · TypeScriptGitHub @ManasAyyalaraju온라인운영자 미확인
써 보셨어요? 한 번만 눌러 주세요. 로그인은 필요 없어요.
아직 감지된 업데이트가 없습니다. GitHub 릴리스가 나오면 여기에 보입니다.
개인 계정의 공개 저장소 소유자는 GitHub로 로그인해 운영자를 확인하고 소개를 직접 관리할 수 있습니다. 관리자 승인은 필요하지 않습니다.
로그인한 뒤 확인 파일을 만들어 이 저장소의 기본 브랜치에 30분 안에 커밋해 주세요. 다른 브랜치나 포크의 파일은 인정하지 않습니다. 파일을 올린 뒤 아래에서 확인하면 관리자 승인 없이 관리할 수 있습니다. 자격을 유지하려면 파일을 남겨 두세요.
로그인이 필요하면 로그인 화면으로 이동합니다. 로그인 후 이곳으로 돌아와 원하는 확인 버튼을 다시 눌러 주세요.
프로젝트 폴더에서 /nomorevibe verify를 실행하면 소유권을 확인하고 소개를 직접 관리할 수 있습니다.
1분 만에 확인하기Using AI to update resume to new job descriptions automatically
저장소 README에서 가져옴
README 전체를 불러오는 중입니다. 아래는 저장된 발췌입니다.
Tailor your resume to any job in seconds — from a web app, or straight off the job posting.
Upload a resume once. Tailor it against a job description or reformat it into a clean, ATS-friendly PDF — either from the web app or directly on LinkedIn, Indeed, Glassdoor, or Handshake via the refactr Chrome extension.README 전문 보기 ↗Tailor your resume to any job in seconds — from a web app, or straight off the job posting.
Upload a resume once. Tailor it against a job description or reformat it into a clean, ATS-friendly PDF — either from the web app or directly on LinkedIn, Indeed, Glassdoor, or Handshake via the refactr Chrome extension.
Live app: refactrapp.com
refactr is three coordinated pieces, deliberately kept loosely coupled:
| Piece | Stack | Role |
|---|---|---|
Web app (frontend/) | Next.js 16, React 19, TypeScript, Tailwind | Upload, tailor, reformat, dashboard — talks to Supabase directly |
Chrome extension (extension/) | Manifest V3, TypeScript, esbuild | Same tailor/reformat flow, triggered from job board pages |
Backend (backend/) | FastAPI, OpenAI, LaTeX | Stateless — parses, tailors, reformats, and renders PDFs. Nothing else. |
┌──────────────┐
│ Web app │──────┐
│ (Next.js) │ │
└──────────────┘ ▼
┌──────────────────┐
│ Supabase │ Auth · Postgres · private Storage
┌──────────────┐│ (RLS on auth.uid)│
│ Extension │──────┐
│ (Manifest V3) │ │
└───────┬──────┘ ▼
│ (auth/storage is 100% frontend-driven)
│ PDF + JD text only — no credentials, no user data
▼
┌──────────────┐
│ Backend │ Parse → Tailor / Reformat → Render PDF
│ (FastAPI) │ (OpenAI + LaTeX — fully stateless)
└──────────────┘
The backend never talks to Supabase and never sees a service-role key. Auth, persistence, and file storage all happen frontend-driven — the web app and the extension both talk to Supabase directly via supabase-js, protected by row-level security scoped to auth.uid(). This means the extension reuses the exact same auth/storage logic as the web app instead of duplicating it across two codebases, and it keeps the backend's blast radius small: a Supabase outage never takes down the core tailor/reformat pipeline.
The part that actually does the work is built as a small pipeline of specialized steps rather than one giant prompt:
Every stage is timed and surfaced via an X-Pipeline-Timings response header for observability.
brew install --cask mactex-no-guisudo apt-get install texlive-latex-base texlive-fonts-recommended texlive-latex-extracd backend
python -m venv venv
source venv/bin/activate # Windows: venv\Scripts\activate
pip install -r requirements.txt
Create backend/.env (see backend/.env.example):
OPENAI_API_KEY=your_api_key_here
# Optional — model tiering and retry behavior, see .env.example for defaults
# OPENAI_MODEL_FAST=gpt-4o-mini
# OPENAI_MODEL_GENERATE=gpt-4o-mini
# OPENAI_MAX_RETRIES=2
Install LaTeX (see LATEX_SETUP.md), then start the server:
uvicorn app:app --reload
Backend runs on http://localhost:8000 — API docs at http://localhost:8000/docs.
cd frontend
npm install
Create frontend/.env.local:
NEXT_PUBLIC_API_URL=http://localhost:8000
NEXT_PUBLIC_SUPABASE_URL=your_supabase_project_url
NEXT_PUBLIC_SUPABASE_ANON_KEY=your_supabase_anon_key
npm run dev
Frontend runs on http://localhost:3000.
cd extension
npm install
npm run build
Then in chrome://extensions: enable Developer Mode → Load unpacked → select extension/dist. By default the extension points at the deployed backend/web app (see extension/src/lib/config.ts); point it at localhost for local development.
| Endpoint | Purpose |
|---|---|
POST /api/tailor/pdf | Multipart {pdf, jd_text, output: json|pdf, resume_format: regular|technical} — tailor a resume against a job description |
POST /api/reformat/pdf | Multipart {pdf, resume_format} — reformat a resume with no content rewriting |
GET /api/templates/preview?format=regular|technical | Static example resume rendered through the real pipeline — no upload, no AI call |
GET /health | Health check |
Example:
curl -X POST "http://localhost:8000/api/tailor/pdf" \
-F "[email protected]" \
-F "jd_text=$(cat job_description.txt)" \
-F "output=json"
cd backend
python cli_demo.py
refactr/
├── backend/
│ ├── core/
│ │ ├── config.py # Settings (API key, model tiering, retries)
│ │ ├── exceptions.py # TailoringGenerationError
│ │ └── timing.py # Per-stage pipeline timing helper
│ ├── models/
│ │ ├── resume_models.py # Resume data models
│ │ └── job_models.py # Job description models
│ ├── routers/
│ │ ├── tailor_routes.py # POST /api/tailor/pdf
│ │ ├── reformat_routes.py # POST /api/reformat/pdf
│ │ └── template_preview_routes.py
│ ├── services/
│ │ ├── llm_client.py # OpenAI calls (structured outputs, async)
│ │ ├── job_parser.py # JD parsing + domain classification
│ │ ├── domain_prompts.py # Domain-specific tailoring guidance
│ │ ├── bullet_verifier.py # Truthfulness guardrail on tailored bullets
│ │ ├── pdf_resume_parser.py # Resume PDF → structured data
│ │ ├── pdf_writer.py # PDF generation (LaTeX)
│ │ ├── tailor_engine.py # Core tailoring orchestration
│ │ └── reformat_engine.py # Core reformatting orchestration
│ ├── templates/
│ │ └── resume_template.tex # LaTeX resume template
│ ├── app.py # FastAPI application
│ ├── requirements.txt
│ └── Dockerfile
├── frontend/
│ ├── app/
│ │ ├── (landing) page.tsx, login/, signup/, auth/
│ │ ├── dashboard/ # Current resume, history, stats
│ │ ├── resumes/ # Upload → template choice → save
│ │ ├── tailor/, results/ # Tailor flow + results view
│ │ ├── extension/connect/ # Session handoff to the Chrome extension
│ │ └── profile/
│ ├── components/, lib/, types/
│ └── package.json
├── extension/
│ ├── src/
│ │ ├── background.ts, content-script.ts, panel-app.ts
│ │ └── lib/ # Supabase client, API client, config
│ ├── manifest.json # Manifest V3, matches LinkedIn/Indeed/Glassdoor/Handshake
│ └── package.json
├── data/
│ └── sample_jd.txt
├── CLAUDE.md # Architecture reference
├── memory.md # Decision log — the "why" behind non-obvious choices
├── DEPLOYMENT.md # Production deployment guide
├── LATEX_SETUP.md # LaTeX installation guide
└── README.md
backend/Dockerfile and render.yaml)Full step-by-step instructions, environment variable reference, and troubleshooting are in DEPLOYMENT.md.
auth.uid(){user_id}/...Manas Ayyalaraju
Need help? API docs live at http://localhost:8000/docs once the backend is running.