resuml 3.0.0 → 3.2.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 CHANGED
@@ -8,6 +8,7 @@
8
8
  - [Installation](#installation)
9
9
  - [CLI commands and options](#cli-commands-and-options)
10
10
  - [ATS analysis](#ats-analysis)
11
+ - [Job search](#job-search)
11
12
  - [Themes](#themes)
12
13
  - [Example YAML structure](#example-yaml-structure)
13
14
  - [CI/CD integration](#cicd-auto-build-on-push)
@@ -47,21 +48,32 @@ Requires Node.js ≥ 20 and npm ≥ 10.
47
48
  | `pdf` | Render to PDF |
48
49
  | `dev` | Dev server with hot-reload |
49
50
  | `mcp` | Start the MCP server for AI agents |
51
+ | `jobs search` | Discover and rank job postings from free sources |
52
+ | `jobs score` | Score a single posting against your resume |
53
+ | `jobs tailor` | Generate a tailoring prompt for a posting |
50
54
 
51
55
  ### Options
52
56
 
53
57
  | Option | Alias | Description |
54
58
  | ----------------- | ----- | -------------------------------------------- |
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` |
59
+ | `--resume` | `-r` | Input YAML file(s) or directory |
60
+ | `--output` | `-o` | Output file path |
61
+ | `--theme` | `-t` | Theme name |
62
+ | `--port` | `-p` | Dev server port (default: 3000) |
63
+ | `--language` | | Locale (default: `en`) |
64
+ | `--debug` | | Detailed errors |
65
+ | `--ats` | | Run ATS analysis (with `validate`) |
66
+ | `--jd` | | Path to job description file (with `--ats`) |
67
+ | `--ats-threshold` | | Minimum score (0-100); exits 1 if below |
68
+ | `--format` | | Output format for validate: `text` or `json` |
69
+ | `--location` | | Override candidate location as `"City, CC"` (with `jobs search`) |
70
+ | `--min-score` | | Minimum ATS score for results (default 85, with `jobs search`) |
71
+ | `--limit` | | Max postings returned after ranking (default 20, with `jobs search`) |
72
+ | `--providers` | | Comma-separated provider list (with `jobs search`) |
73
+ | `--remote` | | Restrict to remote-friendly postings (with `jobs search`) |
74
+ | `--posting` | | Posting YAML/JSON file for `jobs score` / `jobs tailor` |
75
+ | `--body` | | Posting body text; use `-` for stdin (with `jobs tailor`) |
76
+ | `--json` | | Machine-readable JSON output (with `jobs search`, `score`, `tailor`) |
65
77
 
66
78
  ### Quick start
67
79
 
@@ -141,6 +153,49 @@ Supports English and German (language-specific action verbs and pronouns). Use `
141
153
  resuml validate --resume lebenslauf.yaml --ats --language de
142
154
  ```
143
155
 
156
+ ## Job search
157
+
158
+ Discover, score, and tailor job postings against your resume — all offline, no API keys.
159
+
160
+ ```bash
161
+ # Search free job sources and rank results against your resume (default minScore: 85)
162
+ resuml jobs search -r resume.yaml
163
+
164
+ # Filter to remote-friendly postings in your country
165
+ resuml jobs search -r resume.yaml --remote --location "Zürich, CH"
166
+
167
+ # Score a single posting (full per-tier ATS breakdown)
168
+ resuml jobs score -r resume.yaml --posting posting.yaml
169
+
170
+ # Generate a tailoring prompt for a posting (pipe output to Claude)
171
+ resuml jobs tailor --posting posting.yaml
172
+ resuml jobs tailor --body - < jd.txt # read body from stdin
173
+
174
+ # Machine-readable output
175
+ resuml jobs search -r resume.yaml --json
176
+ ```
177
+
178
+ ### Posting file format (`--posting posting.yaml`)
179
+
180
+ ```yaml
181
+ company: Acme Corp
182
+ title: Senior Backend Engineer
183
+ url: https://acme.com/jobs/123
184
+ body: |
185
+ We are looking for a backend engineer with 5+ years of experience...
186
+ location: Berlin, DE # optional
187
+ remote: false # optional
188
+ ```
189
+
190
+ ### How search works
191
+
192
+ 1. Derives a query from your resume (seniority, top skills, location).
193
+ 2. Fetches postings from free sources in parallel (Greenhouse, Lever, Ashby, Workable, RemoteOK, WWR, Remotive, HN Who's Hiring).
194
+ 3. Drops on-site postings in the wrong country when `--location` is set.
195
+ 4. Scores every posting with the full ATS engine; dedupes by `(company, title, location)`.
196
+ 5. Removes postings below `--min-score` (default 85) and caps to `--limit` (default 20).
197
+ 6. Off-specialty roles (e.g. a backend JD for a frontend CV) are capped at 45 and filtered out automatically.
198
+
144
199
  ## Themes
145
200
 
146
201
  resuml supports any `jsonresume-theme-*` package from npm. Install a theme, then pass its name to `--theme`:
@@ -277,14 +332,18 @@ Claude Code will:
277
332
 
278
333
  ### Tools
279
334
 
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`) |
335
+ | Tool | Purpose |
336
+ | ---------------------- | ------------------------------------------------------------------------------- |
337
+ | `resuml_init_resume` | Generate a starter YAML template |
338
+ | `resuml_validate` | Validate resume YAML against the JSON Resume schema |
339
+ | `resuml_ats_check` | Tiered ATS analysis (Parsing / Match / Recruiter) with knockout signals |
340
+ | `resuml_ats_explain` | Return the rubric entry for a specific check id |
341
+ | `resuml_render` | Render to HTML using a theme (supports `locale`) |
342
+ | `resuml_list_themes` | List available themes and install status |
343
+ | `resuml_export_pdf` | Export as PDF (supports `margin`, `locale`) |
344
+ | `resuml_jobs_search` | Discover and rank job postings from free sources against the resume |
345
+ | `resuml_jobs_score` | Score a single job posting against the resume; returns full ATS breakdown |
346
+ | `resuml_jobs_tailor` | Build a tailoring prompt for a specific posting (returns prompt text) |
288
347
 
289
348
  ### Resources
290
349
 
package/README.md CHANGED
@@ -72,6 +72,11 @@ npm install -g jsonresume-theme-stackoverflow
72
72
  resuml validate --resume resume.yaml --ats --jd job.txt
73
73
  resuml render --resume resume.yaml --theme stackoverflow --output resume.html
74
74
  resuml pdf --resume resume.yaml --theme stackoverflow --output resume.pdf
75
+
76
+ # discover and rank job postings from free sources
77
+ resuml jobs search --resume resume.yaml --location "Zürich, CH"
78
+ resuml jobs score --resume resume.yaml --posting posting.yaml
79
+ resuml jobs tailor --posting posting.yaml
75
80
  ```
76
81
 
77
82
  `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).
package/bin/resuml CHANGED
@@ -6,13 +6,14 @@ import { dirname, join } from 'path';
6
6
  import { fileURLToPath, pathToFileURL } from 'url';
7
7
 
8
8
  const currentDir = dirname(fileURLToPath(import.meta.url));
9
- const distPath = join(currentDir, '../dist/index.js');
9
+ const distPath = join(currentDir, '../dist/cli.js');
10
10
 
11
11
  try {
12
12
  if (!existsSync(distPath)) {
13
13
  throw new Error('CLI not built. Please run "npm run build" first.');
14
14
  }
15
- await import(pathToFileURL(distPath).href);
15
+ const { main } = await import(pathToFileURL(distPath).href);
16
+ await main();
16
17
  } catch (err) {
17
18
  console.error('Error starting resuml CLI:', err);
18
19
  process.exit(1);
@@ -0,0 +1,76 @@
1
+ {
2
+ "_comment": "Seed allowlists for ATS-direct providers. Slugs are the board-id segment of each company's public ATS URL. Curated from public job boards as of 2026-05. Add to this list via the --extra-companies CLI flag or extraCompanies SearchOption.",
3
+ "greenhouse": [
4
+ "airbnb",
5
+ "stripe",
6
+ "anthropic",
7
+ "openai",
8
+ "datadog",
9
+ "discord",
10
+ "duolingo",
11
+ "elastic",
12
+ "figma",
13
+ "gitlab",
14
+ "instacart",
15
+ "linear",
16
+ "lyft",
17
+ "mongodb",
18
+ "notion",
19
+ "nubank",
20
+ "pinterest",
21
+ "plaid",
22
+ "ramp",
23
+ "reddit",
24
+ "robinhood",
25
+ "samsara",
26
+ "scaleai",
27
+ "snowflake",
28
+ "squareup",
29
+ "twilio",
30
+ "vercel",
31
+ "wise",
32
+ "zapier"
33
+ ],
34
+ "lever": [
35
+ "netflix",
36
+ "spotify",
37
+ "shopify",
38
+ "github",
39
+ "palantir",
40
+ "asana",
41
+ "intercom",
42
+ "kraken",
43
+ "leetcode",
44
+ "miro",
45
+ "patreon",
46
+ "showpad",
47
+ "thumbtack"
48
+ ],
49
+ "ashby": [
50
+ "ashbyhq",
51
+ "openai",
52
+ "anthropic",
53
+ "ramp",
54
+ "linear",
55
+ "vercel",
56
+ "posthog",
57
+ "modal",
58
+ "replicate",
59
+ "perplexity",
60
+ "supabase",
61
+ "huggingface",
62
+ "ironclad",
63
+ "warp",
64
+ "writer"
65
+ ],
66
+ "workable": [
67
+ "deliveroo",
68
+ "getyourguide",
69
+ "n26",
70
+ "personio",
71
+ "celonis",
72
+ "tier",
73
+ "wefox",
74
+ "blinkist"
75
+ ]
76
+ }
@@ -0,0 +1,7 @@
1
+ import { Resume as ResumeSchema } from '../types/index.js';
2
+ import { A as AtsOptions, T as TieredAtsResult } from '../types-B_jASYU4.js';
3
+ export { C as CheckResult, K as KnockoutSignal, a as TierResult } from '../types-B_jASYU4.js';
4
+
5
+ declare function analyzeAts(resume: ResumeSchema, options?: AtsOptions): TieredAtsResult;
6
+
7
+ export { AtsOptions, TieredAtsResult, analyzeAts };
@@ -0,0 +1,8 @@
1
+ import {
2
+ analyzeAts
3
+ } from "../chunk-C2JG5KF4.js";
4
+ import "../chunk-QR77BRMN.js";
5
+ export {
6
+ analyzeAts
7
+ };
8
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":[],"sourcesContent":[],"mappings":"","names":[]}