resuml 1.21.0 → 3.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/DOCS.md ADDED
@@ -0,0 +1,320 @@
1
+ # resuml: detailed documentation
2
+
3
+ > For the short intro, see [README.md](README.md). For the web app, go to [resuml.app](https://resuml.app).
4
+
5
+ ## Table of contents
6
+
7
+ - [Why YAML](#why-yaml)
8
+ - [Installation](#installation)
9
+ - [CLI commands and options](#cli-commands-and-options)
10
+ - [ATS analysis](#ats-analysis)
11
+ - [Themes](#themes)
12
+ - [Example YAML structure](#example-yaml-structure)
13
+ - [CI/CD integration](#cicd-auto-build-on-push)
14
+ - [AI agent integration (MCP)](#ai-agent-integration-mcp)
15
+ - [Troubleshooting](#troubleshooting)
16
+
17
+ ---
18
+
19
+ ## Why YAML
20
+
21
+ | | YAML | JSON |
22
+ | ---------------------- | ----------------------------- | ------------------------------- |
23
+ | **Comments** | ✅ `# explain your choices` | ❌ Not supported |
24
+ | **Multi-line strings** | ✅ `summary: >-` block syntax | ❌ Escape everything |
25
+ | **Readability** | ✅ Clean, minimal syntax | ⚠️ Brackets & quotes everywhere |
26
+ | **Diffing** | ✅ Clean git diffs | ⚠️ Noisy diffs |
27
+ | **Compatibility** | ✅ Valid JSON Resume schema | ✅ Native |
28
+
29
+ YAML is a superset of JSON, so your resume stays fully compatible with the [JSON Resume](https://jsonresume.org/) ecosystem.
30
+
31
+ ## Installation
32
+
33
+ ```bash
34
+ npm install -g resuml
35
+ ```
36
+
37
+ Requires Node.js ≥ 20 and npm ≥ 10.
38
+
39
+ ## CLI commands and options
40
+
41
+ | Command | Description |
42
+ | ---------------- | --------------------------------------------------- |
43
+ | `validate` | Validate resume data against the JSON Resume schema |
44
+ | `validate --ats` | Run ATS compatibility analysis |
45
+ | `tojson` | Convert YAML to JSON |
46
+ | `render` | Render the resume to HTML using a theme |
47
+ | `pdf` | Render to PDF |
48
+ | `dev` | Dev server with hot-reload |
49
+ | `mcp` | Start the MCP server for AI agents |
50
+
51
+ ### Options
52
+
53
+ | Option | Alias | Description |
54
+ | ----------------- | ----- | -------------------------------------------- |
55
+ | `--resume` | `-r` | Input YAML file(s) or directory |
56
+ | `--output` | `-o` | Output file path |
57
+ | `--theme` | `-t` | Theme name |
58
+ | `--port` | `-p` | Dev server port (default: 3000) |
59
+ | `--language` | | Locale (default: `en`) |
60
+ | `--debug` | | Detailed errors |
61
+ | `--ats` | | Run ATS analysis (with `validate`) |
62
+ | `--jd` | | Path to job description file (with `--ats`) |
63
+ | `--ats-threshold` | | Minimum score (0-100); exits 1 if below |
64
+ | `--format` | | Output format for validate: `text` or `json` |
65
+
66
+ ### Quick start
67
+
68
+ ```bash
69
+ resuml validate --resume resume.yaml
70
+ resuml tojson --resume resume.yaml --output resume.json
71
+ resuml render --resume resume.yaml --theme stackoverflow --output resume.html
72
+ ```
73
+
74
+ ## ATS analysis
75
+
76
+ Deterministic, offline ATS (Applicant Tracking System) checks. No API keys, no LLMs.
77
+
78
+ ```bash
79
+ # Basic ATS score
80
+ resuml validate --resume resume.yaml --ats
81
+
82
+ # Match against a job description
83
+ resuml validate --resume resume.yaml --ats --jd job-description.txt
84
+
85
+ # CI gate: fail if below threshold
86
+ resuml validate --resume resume.yaml --ats --ats-threshold 75
87
+
88
+ # Machine-readable output
89
+ resuml validate --resume resume.yaml --ats --format json
90
+ ```
91
+
92
+ ### What it checks
93
+
94
+ 11 deterministic checks across 3 categories.
95
+
96
+ **Contact information**
97
+
98
+ - Complete contact details (name, email, phone, city)
99
+ - LinkedIn profile present
100
+
101
+ **Content quality**
102
+
103
+ - Professional summary (length and presence)
104
+ - Work highlights (≥ 2 per entry)
105
+ - Action verbs (highlights start with strong verbs)
106
+ - Quantified impact (numbers / percentages / metrics)
107
+ - No first-person pronouns
108
+
109
+ **Resume structure**
110
+
111
+ - Date consistency (no unexplained gaps > 6 months)
112
+ - Skills populated (≥ 3 categories with keywords)
113
+ - Education completeness
114
+ - Essential sections present
115
+
116
+ ### Job description matching
117
+
118
+ Passing `--jd` extracts keywords from the job description using TF-based ranking with stem matching, then compares to your resume. You get:
119
+
120
+ - **Match percentage**: how many JD keywords appear in your resume
121
+ - **Matched keywords**: what you already cover
122
+ - **Missing keywords**: what to consider adding
123
+ - **Extra keywords**: skills in your resume the JD didn't mention
124
+
125
+ ### Scoring
126
+
127
+ | Score | Rating | Meaning |
128
+ | ------ | ---------- | ------------------------------- |
129
+ | 90-100 | Excellent | Well-optimized for ATS |
130
+ | 75-89 | Good | Minor improvements possible |
131
+ | 60-74 | Needs Work | Several issues to address |
132
+ | 0-59 | Poor | Significant improvements needed |
133
+
134
+ With a JD: final score = 60% generic checks + 40% keyword match.
135
+
136
+ ### Multi-language
137
+
138
+ Supports English and German (language-specific action verbs and pronouns). Use `--language`:
139
+
140
+ ```bash
141
+ resuml validate --resume lebenslauf.yaml --ats --language de
142
+ ```
143
+
144
+ ## Themes
145
+
146
+ resuml supports any `jsonresume-theme-*` package from npm. Install a theme, then pass its name to `--theme`:
147
+
148
+ ```bash
149
+ npm install jsonresume-theme-stackoverflow
150
+ resuml render --resume resume.yaml --theme stackoverflow
151
+ ```
152
+
153
+ | Theme | Install | Style |
154
+ | ---------------------------------------------------------------------------------- | -------------------------------------- | ------------------- |
155
+ | [stackoverflow](https://github.com/francoislaberge/jsonresume-theme-stackoverflow) | `npm i jsonresume-theme-stackoverflow` | Clean, professional |
156
+ | [elegant](https://github.com/mudassir0909/jsonresume-theme-elegant) | `npm i jsonresume-theme-elegant` | Modern |
157
+ | [kendall](https://github.com/LinuxBozo/jsonresume-theme-kendall) | `npm i jsonresume-theme-kendall` | Minimal |
158
+ | [flat](https://github.com/erming/jsonresume-theme-flat) | `npm i jsonresume-theme-flat` | Flat |
159
+ | [onepage](https://github.com/aonemd/jsonresume-theme-onepage) | `npm i jsonresume-theme-onepage` | Single-page |
160
+
161
+ Browse all at [jsonresume.org/themes](https://jsonresume.org/themes/). The web app at [resuml.app](https://resuml.app) bundles 300+ of them and renders live.
162
+
163
+ ## Example YAML structure
164
+
165
+ ```yaml
166
+ basics:
167
+ name: John Doe
168
+ label: Software Engineer
169
+ email: john@example.com
170
+ summary: Experienced software engineer...
171
+ location:
172
+ city: San Francisco
173
+ countryCode: US
174
+ profiles:
175
+ - network: GitHub
176
+ url: https://github.com/johndoe
177
+
178
+ work:
179
+ - name: Tech Corp
180
+ position: Senior Engineer
181
+ startDate: 2020-01-15
182
+ endDate: 2023-12-31
183
+ summary: Led development of...
184
+ highlights:
185
+ - Reduced latency by 40%
186
+ - Led team of 8 engineers
187
+
188
+ education:
189
+ - institution: University
190
+ area: Computer Science
191
+ studyType: Bachelor
192
+ startDate: 2014-09-01
193
+ endDate: 2018-06-01
194
+
195
+ skills:
196
+ - name: Languages
197
+ level: Expert
198
+ keywords: [TypeScript, Python, Go]
199
+ ```
200
+
201
+ See [examples/](examples/) for more.
202
+
203
+ ## CI/CD: Auto-build on push
204
+
205
+ ```yaml
206
+ # .github/workflows/resume.yml
207
+ name: Build Resume
208
+
209
+ on:
210
+ push:
211
+ paths: ['resume.yaml', 'resume/*.yaml']
212
+
213
+ jobs:
214
+ build:
215
+ runs-on: ubuntu-latest
216
+ steps:
217
+ - uses: actions/checkout@v4
218
+ - uses: actions/setup-node@v4
219
+ with:
220
+ node-version: 20
221
+
222
+ - run: npm install -g resuml
223
+ - run: npm install jsonresume-theme-stackoverflow
224
+
225
+ # Fail the job if ATS score < 75
226
+ - run: resuml validate --resume resume.yaml --ats --ats-threshold 75
227
+
228
+ - run: resuml render --resume resume.yaml --theme stackoverflow --output resume.html
229
+ - run: resuml tojson --resume resume.yaml --output resume.json
230
+
231
+ - uses: actions/upload-artifact@v4
232
+ with:
233
+ name: resume
234
+ path: |
235
+ resume.html
236
+ resume.json
237
+ ```
238
+
239
+ ## AI agent integration (MCP)
240
+
241
+ resuml ships with a [Model Context Protocol](https://modelcontextprotocol.io/) server so Claude Code, Claude Desktop, Cursor, Copilot, or any MCP-compatible client can use it directly.
242
+
243
+ ### Setup
244
+
245
+ Add to your MCP client config:
246
+
247
+ ```json
248
+ {
249
+ "mcpServers": {
250
+ "resuml": {
251
+ "command": "npx",
252
+ "args": ["resuml", "mcp"]
253
+ }
254
+ }
255
+ }
256
+ ```
257
+
258
+ Or run standalone:
259
+
260
+ ```bash
261
+ resuml mcp
262
+ ```
263
+
264
+ ### Using it from Claude Code
265
+
266
+ Once configured, Claude Code can call every resuml capability through natural language. For example:
267
+
268
+ > "I saved the job ad as `jd.txt`. Tailor my resume at `resume.yaml` to match it, iterate until the ATS score is ≥ 80, render with the stackoverflow theme, and export a PDF."
269
+
270
+ Claude Code will:
271
+
272
+ 1. Validate the current YAML.
273
+ 2. Run the ATS check with the JD.
274
+ 3. Edit the YAML to close keyword gaps.
275
+ 4. Re-check until the target score is met.
276
+ 5. Render the HTML and export the PDF.
277
+
278
+ ### Tools
279
+
280
+ | Tool | Purpose |
281
+ | -------------------- | --------------------------------------------------- |
282
+ | `resuml_init_resume` | Generate a starter YAML template |
283
+ | `resuml_validate` | Validate resume YAML against the JSON Resume schema |
284
+ | `resuml_ats_check` | ATS analysis + JD keyword matching |
285
+ | `resuml_render` | Render to HTML using a theme (supports `locale`) |
286
+ | `resuml_list_themes` | List available themes and install status |
287
+ | `resuml_export_pdf` | Export as PDF (supports `margin`, `locale`) |
288
+
289
+ ### Resources
290
+
291
+ | URI | Description |
292
+ | ----------------------------- | --------------------------------------------- |
293
+ | `resuml://schema/json-resume` | Full JSON Resume schema reference |
294
+ | `resuml://docs/ats-scoring` | ATS scoring rubric, checks, weights, and tips |
295
+ | `resuml://themes/catalog` | Available themes with descriptions |
296
+
297
+ ### Prompts
298
+
299
+ | Prompt | Description |
300
+ | --------------------- | -------------------------------------------------- |
301
+ | `tailor-resume-to-jd` | Tailor a resume for a specific job description |
302
+ | `optimize-ats-score` | Analyze and improve an existing resume's ATS score |
303
+ | `review-resume` | Comprehensive review + improvement suggestions |
304
+
305
+ ## Troubleshooting
306
+
307
+ **Validation errors**
308
+
309
+ - Check YAML indentation and required fields
310
+ - Run with `--debug` for stack traces
311
+
312
+ **Theme rendering issues**
313
+
314
+ - Ensure the theme is installed (`npm install jsonresume-theme-<name>`)
315
+ - Third-party themes may have their own bugs. Try a different theme.
316
+ - The web app at [resuml.app](https://resuml.app) pre-checks themes and flags broken ones
317
+
318
+ **Dev server issues**
319
+
320
+ - The default port is 3000. Pass `--port` to override.
package/README.md CHANGED
@@ -66,11 +66,16 @@ Claude will generate the YAML, validate it, iterate until the score clears, and
66
66
  ```bash
67
67
  npm install -g resuml
68
68
 
69
+ # install a theme on demand (any jsonresume-theme-* package)
70
+ npm install -g jsonresume-theme-stackoverflow
71
+
69
72
  resuml validate --resume resume.yaml --ats --jd job.txt
70
73
  resuml render --resume resume.yaml --theme stackoverflow --output resume.html
71
74
  resuml pdf --resume resume.yaml --theme stackoverflow --output resume.pdf
72
75
  ```
73
76
 
77
+ `resuml pdf` and snapshot rendering need Playwright. Install it once with `npm install -g playwright` (it's an optional peer dep so the base install stays slim).
78
+
74
79
  **Minimal `resume.yaml`:**
75
80
 
76
81
  ```yaml
@@ -89,14 +94,14 @@ work:
89
94
  - Led team of 12 engineers
90
95
  ```
91
96
 
92
- Full CLI reference, Node.js API, ATS rubric, CI/CD setup, and every MCP tool live in **[DOCS.md](DOCS.md)**.
97
+ Full CLI reference, ATS rubric, CI/CD setup, and every MCP tool live in **[DOCS.md](DOCS.md)**.
93
98
 
94
99
  ---
95
100
 
96
101
  ## Requirements
97
102
 
98
103
  - Node.js ≥ 20, npm ≥ 10
99
- - Nothing else. Validation, ATS, rendering, and PDF all run locally
104
+ - Optional: `playwright` for `resuml pdf`
100
105
 
101
106
  ## Contributing
102
107
 
@@ -28,14 +28,23 @@
28
28
  { "canonical": "Jotai", "type": "library" },
29
29
  { "canonical": "Recoil", "type": "library" },
30
30
  { "canonical": "MobX", "type": "library" },
31
- { "canonical": "React Query", "aliases": ["TanStack Query", "tanstack-query"], "type": "library" },
31
+ {
32
+ "canonical": "React Query",
33
+ "aliases": ["TanStack Query", "tanstack-query"],
34
+ "type": "library"
35
+ },
32
36
  { "canonical": "TanStack", "type": "library" },
33
37
  { "canonical": "SWR", "type": "library" },
34
38
  { "canonical": "tRPC", "type": "library" },
35
39
  { "canonical": "GraphQL", "type": "library", "hot": true },
36
40
  { "canonical": "Apollo", "aliases": ["Apollo Client", "Apollo GraphQL"], "type": "library" },
37
41
  { "canonical": "Relay", "type": "library" },
38
- { "canonical": "Tailwind CSS", "aliases": ["Tailwind", "TailwindCSS"], "type": "framework", "hot": true },
42
+ {
43
+ "canonical": "Tailwind CSS",
44
+ "aliases": ["Tailwind", "TailwindCSS"],
45
+ "type": "framework",
46
+ "hot": true
47
+ },
39
48
  { "canonical": "shadcn/ui", "aliases": ["shadcn", "shadcn ui"], "type": "library" },
40
49
  { "canonical": "Radix UI", "aliases": ["Radix"], "type": "library" },
41
50
  { "canonical": "Headless UI", "type": "library" },
@@ -69,7 +78,11 @@
69
78
  { "canonical": "Vitest", "type": "tool" },
70
79
  { "canonical": "Playwright", "type": "tool" },
71
80
  { "canonical": "Cypress", "type": "tool" },
72
- { "canonical": "Testing Library", "aliases": ["React Testing Library", "RTL"], "type": "library" },
81
+ {
82
+ "canonical": "Testing Library",
83
+ "aliases": ["React Testing Library", "RTL"],
84
+ "type": "library"
85
+ },
73
86
  { "canonical": "Mocha", "type": "tool" },
74
87
  { "canonical": "Chai", "type": "tool" },
75
88
 
@@ -113,7 +126,12 @@
113
126
  { "canonical": "NoSQL", "type": "language" },
114
127
 
115
128
  { "canonical": "AWS", "aliases": ["Amazon Web Services"], "type": "platform", "hot": true },
116
- { "canonical": "Google Cloud", "aliases": ["GCP", "Google Cloud Platform"], "type": "platform", "hot": true },
129
+ {
130
+ "canonical": "Google Cloud",
131
+ "aliases": ["GCP", "Google Cloud Platform"],
132
+ "type": "platform",
133
+ "hot": true
134
+ },
117
135
  { "canonical": "Microsoft Azure", "aliases": ["Azure"], "type": "platform", "hot": true },
118
136
  { "canonical": "Vercel", "type": "platform" },
119
137
  { "canonical": "Netlify", "type": "platform" },
@@ -157,7 +175,11 @@
157
175
  { "canonical": "dbt", "aliases": ["data build tool"], "type": "tool" },
158
176
  { "canonical": "Spark", "aliases": ["Apache Spark", "PySpark"], "type": "framework" },
159
177
  { "canonical": "Kafka", "aliases": ["Apache Kafka"], "type": "platform" },
160
- { "canonical": "RAG", "aliases": ["Retrieval Augmented Generation", "retrieval-augmented generation"], "type": "practice" },
178
+ {
179
+ "canonical": "RAG",
180
+ "aliases": ["Retrieval Augmented Generation", "retrieval-augmented generation"],
181
+ "type": "practice"
182
+ },
161
183
  { "canonical": "Vector Search", "type": "practice" },
162
184
  { "canonical": "Embeddings", "type": "practice" },
163
185
 
@@ -173,15 +195,28 @@
173
195
  { "canonical": "Sketch", "type": "tool" },
174
196
  { "canonical": "Miro", "type": "tool" },
175
197
 
176
- { "canonical": "CI/CD", "aliases": ["CICD", "Continuous Integration", "Continuous Delivery", "Continuous Deployment"], "type": "practice", "hot": true },
177
- { "canonical": "REST API", "aliases": ["RESTful API", "REST APIs", "REST"], "type": "practice" },
198
+ {
199
+ "canonical": "CI/CD",
200
+ "aliases": ["CICD", "Continuous Integration", "Continuous Delivery", "Continuous Deployment"],
201
+ "type": "practice",
202
+ "hot": true
203
+ },
204
+ {
205
+ "canonical": "REST API",
206
+ "aliases": ["RESTful API", "REST APIs", "REST"],
207
+ "type": "practice"
208
+ },
178
209
  { "canonical": "gRPC", "type": "practice" },
179
210
  { "canonical": "WebSockets", "aliases": ["WebSocket"], "type": "practice" },
180
211
  { "canonical": "Microservices", "type": "practice", "hot": true },
181
212
  { "canonical": "Monorepo", "aliases": ["monorepos"], "type": "practice" },
182
213
  { "canonical": "Serverless", "type": "practice" },
183
214
  { "canonical": "Edge Computing", "aliases": ["edge functions"], "type": "practice" },
184
- { "canonical": "Event-Driven Architecture", "aliases": ["EDA", "event-driven"], "type": "practice" },
215
+ {
216
+ "canonical": "Event-Driven Architecture",
217
+ "aliases": ["EDA", "event-driven"],
218
+ "type": "practice"
219
+ },
185
220
  { "canonical": "Domain-Driven Design", "aliases": ["DDD"], "type": "practice" },
186
221
  { "canonical": "Test-Driven Development", "aliases": ["TDD"], "type": "practice" },
187
222
  { "canonical": "Agile", "aliases": ["Scrum", "Kanban"], "type": "practice" },
@@ -196,12 +231,25 @@
196
231
  { "canonical": "Accessibility", "aliases": ["a11y", "WCAG"], "type": "practice", "hot": true },
197
232
  { "canonical": "Internationalization", "aliases": ["i18n"], "type": "practice" },
198
233
  { "canonical": "Observability", "type": "practice" },
199
- { "canonical": "Design Systems", "aliases": ["Design System"], "type": "practice", "hot": true },
234
+ {
235
+ "canonical": "Design Systems",
236
+ "aliases": ["Design System"],
237
+ "type": "practice",
238
+ "hot": true
239
+ },
200
240
  { "canonical": "Data Modeling", "aliases": ["Data Model", "Data Models"], "type": "practice" },
201
- { "canonical": "Technical Leadership", "aliases": ["Tech Lead", "Tech Leadership"], "type": "practice" },
241
+ {
242
+ "canonical": "Technical Leadership",
243
+ "aliases": ["Tech Lead", "Tech Leadership"],
244
+ "type": "practice"
245
+ },
202
246
  { "canonical": "Mentoring", "type": "practice" },
203
247
  { "canonical": "Code Review", "aliases": ["Code Reviews"], "type": "practice" },
204
248
  { "canonical": "Stakeholder Management", "type": "practice" },
205
- { "canonical": "Cross-functional Collaboration", "aliases": ["cross-functional"], "type": "practice" }
249
+ {
250
+ "canonical": "Cross-functional Collaboration",
251
+ "aliases": ["cross-functional"],
252
+ "type": "practice"
253
+ }
206
254
  ]
207
255
  }