TreeMap
A free, open-source disk-space visualizer. Squarified treemap, duplicate hunting, disk-full forecasting, and cleanup that only ever moves files to the Trash.
翻译准备中
根据任何职位描述定制您的简历——为角色重写,绝不捏造。会话内处理;除非登录并保存版本,否则不存储。免费且开源。
AI 翻译
Tailor your resume to any job description — rewritten for the role, never fabricated. Processed in-session; nothing stored unless you sign in and save a version. Free & open source.
效率工具TypeScript · JavaScriptGitHub @dukesky在线运营者未确认
试用过了吗? 点一下就好,无需登录。
尚未检测到更新。GitHub 发布版本后会显示在这里。
个人 GitHub 账号下公开仓库的所有者可以登录并验证所有权,自行管理介绍,无需管理员批准。
登录并生成验证文件,在 30 分钟内将其提交到此仓库的默认分支。其他分支或分叉仓库中的文件无效。然后在下方检查文件,即可无需管理员批准直接管理项目。请保留文件以维持管理权限。
如需登录,将前往登录页面。登录后请回到此处,再次点击所选的验证按钮。
在项目文件夹中运行 /nomorevibe verify,即可验证所有权并自行管理介绍。
一分钟完成验证正在加载完整 README。 以下为已保存的摘录。
Tailor your resume to any job description — in 30 seconds, without lying.
Upload your resume, paste a job link, and get it rewritten for that specific role —
plus an honest gap analysis of where you fall short. Your data is processed
in-session and never stored unless you sign in and explicitly save a version.
▶ Try the live demo · ⭐ Star this repo · Report an issue
Same method — an honest rewrite from your real experience, plus a gap analysis —
in whichever place you already are.查看完整 README ↗Upload your resume, paste a job link, and get it rewritten for that specific role — plus an honest gap analysis of where you fall short. Your data is processed in-session and never stored unless you sign in and explicitly save a version.
▶ Try the live demo · ⭐ Star this repo · Report an issue
Same method — an honest rewrite from your real experience, plus a gap analysis — in whichever place you already are.
| What it is | Best when | |
|---|---|---|
| 🌐 Web app | career-allpath.com — paste a link, text, or screenshots and work through the result in a full editor. | You want the diff view, inline editing, and saved versions. |
| 🧩 Chrome extension | A side panel that reads the posting on the tab you're already looking at. | You're browsing LinkedIn, Greenhouse, Lever, Ashby or Workday and don't want to copy-paste. |
| 💻 CLI skill | resume-tailor — a free, open-source Agent Skill that runs inside Claude Code, Codex, or any skills-capable tool. | You live in a terminal and want no upload and no API keys. |
Built with Next.js 15 (App Router), TypeScript, and Tailwind CSS.
A four-step pipeline — all in one session, nothing stored by default.
unpdf / mammoth).Name_Company_Resume.pdf) + copy as Markdown| Route | Description |
|---|---|
/ | Landing page — value prop and a 3-step overview. |
/app | Workspace — resume + JD inputs, then the analysis/tailored-resume results view. |
/app/saved | My resumes — versions a signed-in user chose to save (preview / export / delete). |
/demo | No-backend preview of the results UI with sample data (no API calls). |
POST /api/parse-resume | Multipart PDF/DOCX (≤5MB) or a text field → extracted (unpdf/mammoth) → structured resume JSON. |
POST /api/fetch-jd | { url } → server-side fetch + Readability extraction. { ok:false, reason } on failure. |
POST /api/ocr-jd | 1–4 image uploads (PNG/JPG, ≤4MB each) → single vision call → transcribed JD text. |
POST /api/parse-jd | { text } → structured JD JSON. |
POST /api/analyze | { structuredResume, structuredJD, extraInfo } → gap analysis (score, requirements matrix, strengths, gaps). |
POST /api/tailor | analyze inputs + analysis → rewritten resume (same schema) + change_log. Never fabricates facts. Quota-gated (returns 402 when exhausted). |
GET /api/quota | Current free-tailor quota for the caller — signed-in, extension device, or anonymous ({ remaining, used, limit }). |
POST /api/device-token | Mints a server-signed, 24h device identity for a signed-out extension client. |
GET/POST /api/saved | Signed-in only. List saved versions, or save the current one (per-user Redis hash, capped at 50). |
DELETE /api/saved/[id] | Signed-in only. Delete one saved version. |
POST /api/waitlist | { email } → appended to an Upstash Redis list (early-access signup). |
Two independent concerns, two modules:
src/lib/quota.ts) — business logic. One "run" = one analyze +
tailor flow, charged once via a client-supplied runId and only on success
(see src/lib/auth.ts for how a caller is identified). Allowances by
caller: 5 per day signed in (quota:user:<userId>:<YYYY-MM-DD>, 48h
TTL); 3 per 30-day window for a signed-out extension device
(quota:device:<deviceId>); 5 per 30-day window for a signed-out web
visitor, keyed on the x-anon-id header when it's sent
(quota:anon:<anonId>, unchanged from before the extension work) or on IP
when it's absent (quota:anon:ip:<ip>). A per-IP ceiling of 20 per day
(quota:ip:<ip>:<YYYY-MM-DD>) applies on top of every tier, and a caller is
blocked when either its tier counter or the IP counter is exhausted.
Beta testers with a code in BETA_ACCESS_CODES (via ?code= →
x-access-code header) bypass the quota entirely (rate limiting still
applies). Extension callers are identified by a server-signed device JWT
(Authorization: Bearer <token>, minted by POST /api/device-token)
rather than a client-generated id, so clearing extension storage alone
doesn't reset the trial.src/lib/rate-limit.ts) — abuse protection. Per-IP fixed
window (30 requests / 60s) on the API routes.Both share a small KV abstraction (src/lib/kv.ts) backed by Upstash Redis,
falling back to an in-memory store when Upstash isn't configured. Server-side
input caps: resume 15k chars, JD 10k chars, extra info 5k chars.
Auth is handled by Clerk and is entirely optional —
the full tailoring flow works signed-out and stores nothing. Signing in unlocks a
single feature: opt-in saving. Clicking Save this version writes the current
tailored resume to a per-user Redis hash (saved:<userId>, capped at 50 versions)
via src/lib/saved.ts; those versions appear at /app/saved ("My resumes"),
each with a link back to the original posting when the JD came from a URL. Nothing
is written unless the user explicitly saves. (Clerk v7 removed the
<SignedIn>/<SignedOut> control components; src/components/clerk-auth.tsx is
a small shim that re-exposes them on top of the new <Show> primitive.)
All model choices live in one place — src/lib/llm.ts (MODEL_MAP /
QUALITY_MODELS). Calls go through OpenRouter via the openai package. A
quality flag ("fast" | "quality") overrides the analyze/tailor model; OCR is
pinned to a vision-capable model regardless.
# 1. Install dependencies
npm install
# 2. Set up environment variables
cp .env.example .env.local
# then open .env.local and add your OPENROUTER_API_KEY
# 3. Start the dev server
npm run dev
Open http://localhost:3000. The workspace lives at http://localhost:3000/app.
| Command | What it does |
|---|---|
npm run dev | Start the dev server with hot reload. |
npm run build | Create a production build. |
npm run start | Serve the production build locally. |
npm run lint | Run ESLint. |
npm test | Run this app's Vitest suite. |
npm run test:extension | Run the Chrome extension's Vitest suite (extension/). |
npm run test:all | Run both suites. |
test:extension and test:all shell out to npm --prefix extension. Since
extension/ is a separate package rather than an npm workspace, its
dependencies aren't pulled in by the root npm install — run
npm --prefix extension install once (see Chrome extension)
before either of those on a fresh clone, or they'll fail with a missing
extension/node_modules.
| Variable | Required | Description |
|---|---|---|
OPENROUTER_API_KEY | Yes | OpenRouter API key for parse/analyze/tailor/OCR (used server-side). The model is served via OpenRouter. |
NEXT_PUBLIC_CLERK_PUBLISHABLE_KEY | Yes | Clerk publishable key — required for the app to render (auth provider). Get one at clerk.com. |
CLERK_SECRET_KEY | Yes | Clerk secret key (server-side) — backs sign-in and the saved-versions API. |
UPSTASH_REDIS_REST_URL | Prod | Upstash Redis REST URL — backs quota, rate limiting, saved versions, and the waitlist. |
UPSTASH_REDIS_REST_TOKEN | Prod | Upstash Redis REST token. |
NEXT_PUBLIC_SITE_URL | Optional | Canonical site URL for absolute OG/Twitter share-image links. Falls back to the Vercel production URL, then localhost. |
BETA_ACCESS_CODES | Optional | Comma-separated codes granting unlimited tailors (via ?code=). |
DEVICE_TOKEN_SECRET | Prod | Secret for signing Chrome-extension device tokens (HS256). Generate with openssl rand -base64 32. |
ALLOWED_EXTENSION_IDS | Optional | Comma-separated Chrome extension IDs permitted to call the API (CORS). Empty means no extension origin is accepted. |
Keep the secret values server-side only — never expose them with a
NEXT_PUBLIC_ prefix (the two NEXT_PUBLIC_ vars above are intentionally
client-safe). Without the Upstash vars the app still runs, but quota/rate-limit/
saved-versions/waitlist use a per-process in-memory store that is not shared
across serverless instances — so set them for any real deployment. The Clerk
keys are required for the app to boot; grab free test keys from the Clerk
dashboard for local development.
OPENROUTER_API_KEY, the two
Clerk keys (NEXT_PUBLIC_CLERK_PUBLISHABLE_KEY, CLERK_SECRET_KEY), and — for
real deployments — the Upstash Redis vars, for the Production (and Preview)
environments.npm i -g vercel
vercel # first run links the project and creates a preview
vercel --prod # promote to production
Pull the project's environment variables into your local .env.local at any
time with:
vercel env pull .env.local
extension/ is a separate, thin-client package (its own package.json, not an
npm workspace) that lets you tailor your resume against the job posting in
your active tab without leaving it. It talks to the same API as the web app —
no prompts or model choices live in the extension itself.
Not a browser person? resume-tailor runs the same method as an Agent Skill in Claude Code, Codex, and other skills-capable tools — no upload, no API keys.
/app/saved page shows.# 1. Install its dependencies (separate from the root install)
npm --prefix extension install
# 2. Build it — against production...
npm --prefix extension run build
# ...or against a local API (http://localhost:3000)
npm --prefix extension run build:dev
# 3. Run its tests
npm --prefix extension run test
Then load it unpacked:
chrome://extensions, enable Developer mode (top right).extension/dist.The manifest pins a key — the public key the Chrome Web Store generated at
first upload — so a locally loaded unpacked build and the store-installed
extension share one ID: epofgiefihhmbjhojdeffkdkhocjfpaf. Add it to the
server's ALLOWED_EXTENSION_IDS environment variable (comma-separated) so
the API's CORS layer recognizes it. That check is defense-in-depth, not the
thing making requests work: in MV3, a fetch from an extension page to a
host listed in the manifest's host_permissions bypasses CORS regardless of
ALLOWED_EXTENSION_IDS. (npm run package strips the key field from
store uploads, which the store requires on a first upload and ignores after.)
Sign-in uses Clerk's own client directly inside the extension — a dedicated
sign-in page, not the web app's session (Clerk's Sync Host doesn't work on
side panels, so signing in on the website does not carry over into the
extension). See CHANGELOG.md for what's shipped so far, and
/privacy for exactly what the
extension stores locally versus sends to the server.
career-path is designed to keep your data in your session. The parse → analyze → tailor pipeline is stateless: resume files and job descriptions are not written to any database or persistent store, whether or not you're signed in. A tailored result is persisted only when a signed-in user explicitly saves it (stored per-user in Redis, deletable from My resumes).
The server does keep a small amount of operational data for every caller, signed in or not, to enforce the free allowances and watch for abuse: usage counters, rate-limit counters, and aggregate model timing/token counts with no user content attached. None of it is your resume, your job description, or a tailored result you didn't explicitly save.
The complete list lives at /privacy.