resume-parser-ats 1.1.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/LICENSE +21 -0
- package/README.md +294 -0
- package/bin/cli.js +368 -0
- package/dist/mcp-server/server.d.ts +18 -0
- package/dist/mcp-server/server.d.ts.map +1 -0
- package/dist/mcp-server/server.js +276 -0
- package/dist/mcp-server/server.js.map +1 -0
- package/dist/src/index.d.ts +96 -0
- package/dist/src/index.d.ts.map +1 -0
- package/dist/src/index.js +39 -0
- package/dist/src/index.js.map +1 -0
- package/dist/src/prompts/insights-prompt.d.ts +24 -0
- package/dist/src/prompts/insights-prompt.d.ts.map +1 -0
- package/dist/src/prompts/insights-prompt.js +129 -0
- package/dist/src/prompts/insights-prompt.js.map +1 -0
- package/dist/src/prompts/parser-prompt.d.ts +11 -0
- package/dist/src/prompts/parser-prompt.d.ts.map +1 -0
- package/dist/src/prompts/parser-prompt.js +150 -0
- package/dist/src/prompts/parser-prompt.js.map +1 -0
- package/dist/src/tools/analyze-resume.d.ts +52 -0
- package/dist/src/tools/analyze-resume.d.ts.map +1 -0
- package/dist/src/tools/analyze-resume.js +286 -0
- package/dist/src/tools/analyze-resume.js.map +1 -0
- package/dist/src/tools/parse-resume.d.ts +57 -0
- package/dist/src/tools/parse-resume.d.ts.map +1 -0
- package/dist/src/tools/parse-resume.js +608 -0
- package/dist/src/tools/parse-resume.js.map +1 -0
- package/dist/src/tools/suggest-improvements.d.ts +51 -0
- package/dist/src/tools/suggest-improvements.d.ts.map +1 -0
- package/dist/src/tools/suggest-improvements.js +472 -0
- package/dist/src/tools/suggest-improvements.js.map +1 -0
- package/package.json +56 -0
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Resume Improvement Suggestions Tool
|
|
3
|
+
*
|
|
4
|
+
* Takes parsed resume data and analysis results, then generates
|
|
5
|
+
* structured, actionable suggestions organized by priority.
|
|
6
|
+
*/
|
|
7
|
+
import type { ParsedResume } from "../index";
|
|
8
|
+
import type { AnalyzeResumeOutput } from "./analyze-resume";
|
|
9
|
+
export interface SuggestImprovementsInput {
|
|
10
|
+
filePath?: string;
|
|
11
|
+
rawText?: string;
|
|
12
|
+
parsedResume: ParsedResume;
|
|
13
|
+
analysisResult: AnalyzeResumeOutput["data"];
|
|
14
|
+
focusAreas?: string[];
|
|
15
|
+
}
|
|
16
|
+
export interface Suggestion {
|
|
17
|
+
id: string;
|
|
18
|
+
priority: "critical" | "high" | "medium" | "low";
|
|
19
|
+
category: "ats" | "content" | "formatting" | "structure";
|
|
20
|
+
field: string;
|
|
21
|
+
title: string;
|
|
22
|
+
description: string;
|
|
23
|
+
currentValue: string | null;
|
|
24
|
+
suggestedValue: string;
|
|
25
|
+
rationale: string;
|
|
26
|
+
}
|
|
27
|
+
export interface SectionSuggestion {
|
|
28
|
+
section: string;
|
|
29
|
+
present: boolean;
|
|
30
|
+
issues: string[];
|
|
31
|
+
recommendations: string[];
|
|
32
|
+
}
|
|
33
|
+
export interface SuggestImprovementsOutput {
|
|
34
|
+
success: boolean;
|
|
35
|
+
data: {
|
|
36
|
+
overallScore: number;
|
|
37
|
+
overallGrade: string;
|
|
38
|
+
criticalFixes: number;
|
|
39
|
+
totalSuggestions: number;
|
|
40
|
+
suggestions: Suggestion[];
|
|
41
|
+
sectionSuggestions: SectionSuggestion[];
|
|
42
|
+
quickWins: string[];
|
|
43
|
+
longTermAdvice: string[];
|
|
44
|
+
};
|
|
45
|
+
metadata: {
|
|
46
|
+
parserVersion: string;
|
|
47
|
+
focusAreas: string[];
|
|
48
|
+
};
|
|
49
|
+
}
|
|
50
|
+
export declare function suggestImprovements(input: SuggestImprovementsInput): SuggestImprovementsOutput;
|
|
51
|
+
//# sourceMappingURL=suggest-improvements.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"suggest-improvements.d.ts","sourceRoot":"","sources":["../../../src/tools/suggest-improvements.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,UAAU,CAAC;AAC7C,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,kBAAkB,CAAC;AAM5D,MAAM,WAAW,wBAAwB;IACvC,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,YAAY,EAAE,YAAY,CAAC;IAC3B,cAAc,EAAE,mBAAmB,CAAC,MAAM,CAAC,CAAC;IAC5C,UAAU,CAAC,EAAE,MAAM,EAAE,CAAC;CACvB;AAED,MAAM,WAAW,UAAU;IACzB,EAAE,EAAE,MAAM,CAAC;IACX,QAAQ,EAAE,UAAU,GAAG,MAAM,GAAG,QAAQ,GAAG,KAAK,CAAC;IACjD,QAAQ,EAAE,KAAK,GAAG,SAAS,GAAG,YAAY,GAAG,WAAW,CAAC;IACzD,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,MAAM,CAAC;IACd,WAAW,EAAE,MAAM,CAAC;IACpB,YAAY,EAAE,MAAM,GAAG,IAAI,CAAC;IAC5B,cAAc,EAAE,MAAM,CAAC;IACvB,SAAS,EAAE,MAAM,CAAC;CACnB;AAED,MAAM,WAAW,iBAAiB;IAChC,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,EAAE,OAAO,CAAC;IACjB,MAAM,EAAE,MAAM,EAAE,CAAC;IACjB,eAAe,EAAE,MAAM,EAAE,CAAC;CAC3B;AAED,MAAM,WAAW,yBAAyB;IACxC,OAAO,EAAE,OAAO,CAAC;IACjB,IAAI,EAAE;QACJ,YAAY,EAAE,MAAM,CAAC;QACrB,YAAY,EAAE,MAAM,CAAC;QACrB,aAAa,EAAE,MAAM,CAAC;QACtB,gBAAgB,EAAE,MAAM,CAAC;QACzB,WAAW,EAAE,UAAU,EAAE,CAAC;QAC1B,kBAAkB,EAAE,iBAAiB,EAAE,CAAC;QACxC,SAAS,EAAE,MAAM,EAAE,CAAC;QACpB,cAAc,EAAE,MAAM,EAAE,CAAC;KAC1B,CAAC;IACF,QAAQ,EAAE;QACR,aAAa,EAAE,MAAM,CAAC;QACtB,UAAU,EAAE,MAAM,EAAE,CAAC;KACtB,CAAC;CACH;AA0bD,wBAAgB,mBAAmB,CAAC,KAAK,EAAE,wBAAwB,GAAG,yBAAyB,CA4D9F"}
|
|
@@ -0,0 +1,472 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Resume Improvement Suggestions Tool
|
|
4
|
+
*
|
|
5
|
+
* Takes parsed resume data and analysis results, then generates
|
|
6
|
+
* structured, actionable suggestions organized by priority.
|
|
7
|
+
*/
|
|
8
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
9
|
+
exports.suggestImprovements = suggestImprovements;
|
|
10
|
+
// ---------------------------------------------------------------------------
|
|
11
|
+
// Suggestion generators
|
|
12
|
+
// ---------------------------------------------------------------------------
|
|
13
|
+
function profileSuggestions(resume, analysis, focusAreas) {
|
|
14
|
+
const suggestions = [];
|
|
15
|
+
let id = 1;
|
|
16
|
+
// Name
|
|
17
|
+
if (!resume.profile.name) {
|
|
18
|
+
suggestions.push({
|
|
19
|
+
id: `SUG-${id++}`,
|
|
20
|
+
priority: "critical",
|
|
21
|
+
category: "ats",
|
|
22
|
+
field: "name",
|
|
23
|
+
title: "Name is not parseable by ATS",
|
|
24
|
+
description: "Your resume name could not be extracted. ATS systems use your name as the primary identifier — without it, your application may be discarded.",
|
|
25
|
+
currentValue: null,
|
|
26
|
+
suggestedValue: "Place your full name on the first line, in bold, using only letters and spaces (e.g., 'Jane Doe').",
|
|
27
|
+
rationale: "The feature scoring system expects names that contain only letters, spaces, or periods, and are typically bolded on the first line.",
|
|
28
|
+
});
|
|
29
|
+
}
|
|
30
|
+
else if (!/^[a-zA-Z\s\.]+$/.test(resume.profile.name)) {
|
|
31
|
+
suggestions.push({
|
|
32
|
+
id: `SUG-${id++}`,
|
|
33
|
+
priority: "high",
|
|
34
|
+
category: "formatting",
|
|
35
|
+
field: "name",
|
|
36
|
+
title: "Name format may confuse ATS",
|
|
37
|
+
description: `Your name "${resume.profile.name}" contains non-letter characters that may cause parsing errors.`,
|
|
38
|
+
currentValue: resume.profile.name,
|
|
39
|
+
suggestedValue: resume.profile.name.replace(/[^a-zA-Z\s\.]/g, "").trim() || "Your Name Here",
|
|
40
|
+
rationale: "Names with special characters, numbers, or symbols can confuse ATS name extraction algorithms.",
|
|
41
|
+
});
|
|
42
|
+
}
|
|
43
|
+
// Email
|
|
44
|
+
if (!resume.profile.email) {
|
|
45
|
+
suggestions.push({
|
|
46
|
+
id: `SUG-${id++}`,
|
|
47
|
+
priority: "critical",
|
|
48
|
+
category: "ats",
|
|
49
|
+
field: "email",
|
|
50
|
+
title: "Email is not parseable by ATS",
|
|
51
|
+
description: "Your email could not be extracted. Without a parseable email, recruiters cannot contact you through the ATS.",
|
|
52
|
+
currentValue: null,
|
|
53
|
+
suggestedValue: "Add your email on a separate line in the format name@domain.com.",
|
|
54
|
+
rationale: "ATS systems match the pattern xxx@xxx.xxx. Emails embedded in other text or with unusual formatting may be missed.",
|
|
55
|
+
});
|
|
56
|
+
}
|
|
57
|
+
else if (!/^\S+@\S+\.\S+$/.test(resume.profile.email)) {
|
|
58
|
+
suggestions.push({
|
|
59
|
+
id: `SUG-${id++}`,
|
|
60
|
+
priority: "medium",
|
|
61
|
+
category: "formatting",
|
|
62
|
+
field: "email",
|
|
63
|
+
title: "Email format may cause parsing issues",
|
|
64
|
+
description: `Your email "${resume.profile.email}" doesn't match the standard format exactly.`,
|
|
65
|
+
currentValue: resume.profile.email,
|
|
66
|
+
suggestedValue: "Use a simple email format like firstname.lastname@gmail.com",
|
|
67
|
+
rationale: "Non-standard email formatting can cause ATS to misparse or miss the email entirely.",
|
|
68
|
+
});
|
|
69
|
+
}
|
|
70
|
+
// Phone
|
|
71
|
+
if (!resume.profile.phone) {
|
|
72
|
+
suggestions.push({
|
|
73
|
+
id: `SUG-${id++}`,
|
|
74
|
+
priority: "high",
|
|
75
|
+
category: "ats",
|
|
76
|
+
field: "phone",
|
|
77
|
+
title: "Phone number is not parseable",
|
|
78
|
+
description: "Your phone number could not be extracted. Some ATS systems use phone numbers as a secondary identifier.",
|
|
79
|
+
currentValue: null,
|
|
80
|
+
suggestedValue: "Add your phone in format (123) 456-7890 or 123-456-7890 on its own line.",
|
|
81
|
+
rationale: "ATS parsers commonly use regex patterns like \\(\\d{3}\\)[\\s-]?\\d{3}[\\s-]?\\d{4} to identify phone numbers.",
|
|
82
|
+
});
|
|
83
|
+
}
|
|
84
|
+
else if (!/\(?\d{3}\)?[\s-]?\d{3}[\s-]?\d{4}/.test(resume.profile.phone)) {
|
|
85
|
+
suggestions.push({
|
|
86
|
+
id: `SUG-${id++}`,
|
|
87
|
+
priority: "medium",
|
|
88
|
+
category: "formatting",
|
|
89
|
+
field: "phone",
|
|
90
|
+
title: "Phone format is non-standard",
|
|
91
|
+
description: `Your phone "${resume.profile.phone}" may not parse correctly in all ATS systems.`,
|
|
92
|
+
currentValue: resume.profile.phone,
|
|
93
|
+
suggestedValue: resume.profile.phone.replace(/[^\d()\- ]/g, ""),
|
|
94
|
+
rationale: "Standard US phone formats are more reliably parsed by ATS systems.",
|
|
95
|
+
});
|
|
96
|
+
}
|
|
97
|
+
// Location
|
|
98
|
+
if (!resume.profile.location) {
|
|
99
|
+
if (focusAreas.includes("content") || focusAreas.includes("ats")) {
|
|
100
|
+
suggestions.push({
|
|
101
|
+
id: `SUG-${id++}`,
|
|
102
|
+
priority: "medium",
|
|
103
|
+
category: "content",
|
|
104
|
+
field: "location",
|
|
105
|
+
title: "Location (City, State) is missing",
|
|
106
|
+
description: "Adding your location in 'City, ST' format helps ATS match you to local job opportunities.",
|
|
107
|
+
currentValue: null,
|
|
108
|
+
suggestedValue: "Add your location as 'City, ST' (e.g., 'San Francisco, CA')",
|
|
109
|
+
rationale: "ATS systems often filter by location. The format 'City, ST' matches the regex /[A-Z][a-zA-Z\\s]+, [A-Z]{2}/.",
|
|
110
|
+
});
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
return suggestions;
|
|
114
|
+
}
|
|
115
|
+
function educationSuggestions(resume, _focusAreas) {
|
|
116
|
+
const suggestions = [];
|
|
117
|
+
let id = 100;
|
|
118
|
+
if (resume.education.length === 0) {
|
|
119
|
+
suggestions.push({
|
|
120
|
+
id: `SUG-${id++}`,
|
|
121
|
+
priority: "high",
|
|
122
|
+
category: "structure",
|
|
123
|
+
field: "education",
|
|
124
|
+
title: "Education section not detected",
|
|
125
|
+
description: "Your resume does not have a parseable education section. Most ATS systems look for this.",
|
|
126
|
+
currentValue: null,
|
|
127
|
+
suggestedValue: "Add an 'EDUCATION' section in uppercase and bolded. Include school name, degree, GPA, and dates.",
|
|
128
|
+
rationale: "ATS systems detect education sections by looking for section headers that are uppercase and bolded.",
|
|
129
|
+
});
|
|
130
|
+
return suggestions;
|
|
131
|
+
}
|
|
132
|
+
for (let i = 0; i < resume.education.length; i++) {
|
|
133
|
+
const edu = resume.education[i];
|
|
134
|
+
if (!edu.school) {
|
|
135
|
+
suggestions.push({
|
|
136
|
+
id: `SUG-${id++}`,
|
|
137
|
+
priority: "medium",
|
|
138
|
+
category: "content",
|
|
139
|
+
field: "education",
|
|
140
|
+
title: `Education entry #${i + 1}: School name not detected`,
|
|
141
|
+
description: "The school/university name could not be parsed. Include keywords like 'University', 'College', or 'Institute'.",
|
|
142
|
+
currentValue: null,
|
|
143
|
+
suggestedValue: "University of Example, City, ST",
|
|
144
|
+
rationale: "The parser uses school keywords (College, University, School, Institute, Academy) to identify school names.",
|
|
145
|
+
});
|
|
146
|
+
}
|
|
147
|
+
if (!edu.degree) {
|
|
148
|
+
suggestions.push({
|
|
149
|
+
id: `SUG-${id++}`,
|
|
150
|
+
priority: "medium",
|
|
151
|
+
category: "content",
|
|
152
|
+
field: "education",
|
|
153
|
+
title: `Education entry #${i + 1}: Degree not detected`,
|
|
154
|
+
description: "The degree could not be parsed. Include degree keywords like 'Bachelor', 'Master', 'B.S.', 'M.A.', etc.",
|
|
155
|
+
currentValue: null,
|
|
156
|
+
suggestedValue: "Bachelor of Science, Computer Science",
|
|
157
|
+
rationale: "The parser uses degree keywords (Associate, Bachelor, Master, etc.) to identify degree information.",
|
|
158
|
+
});
|
|
159
|
+
}
|
|
160
|
+
if (!edu.date) {
|
|
161
|
+
suggestions.push({
|
|
162
|
+
id: `SUG-${id++}`,
|
|
163
|
+
priority: "low",
|
|
164
|
+
category: "content",
|
|
165
|
+
field: "education",
|
|
166
|
+
title: `Education entry #${i + 1}: Date not detected`,
|
|
167
|
+
description: "The graduation date could not be parsed. Include years (e.g., 'Expected Graduation: June 2026').",
|
|
168
|
+
currentValue: null,
|
|
169
|
+
suggestedValue: "Expected Graduation: June 2026",
|
|
170
|
+
rationale: "ATS systems look for year patterns (e.g., 2024, 2025) to determine recency of education.",
|
|
171
|
+
});
|
|
172
|
+
}
|
|
173
|
+
}
|
|
174
|
+
return suggestions;
|
|
175
|
+
}
|
|
176
|
+
function experienceSuggestions(resume, focusAreas) {
|
|
177
|
+
const suggestions = [];
|
|
178
|
+
let id = 200;
|
|
179
|
+
if (resume.experience.length === 0) {
|
|
180
|
+
suggestions.push({
|
|
181
|
+
id: `SUG-${id++}`,
|
|
182
|
+
priority: "high",
|
|
183
|
+
category: "structure",
|
|
184
|
+
field: "experience",
|
|
185
|
+
title: "Work experience section not detected",
|
|
186
|
+
description: "Your resume does not have a parseable experience section.",
|
|
187
|
+
currentValue: null,
|
|
188
|
+
suggestedValue: "Add a 'WORK EXPERIENCE' or 'EXPERIENCE' section in uppercase and bolded.",
|
|
189
|
+
rationale: "ATS systems rely on section headers to locate work experience.",
|
|
190
|
+
});
|
|
191
|
+
return suggestions;
|
|
192
|
+
}
|
|
193
|
+
for (let i = 0; i < resume.experience.length; i++) {
|
|
194
|
+
const exp = resume.experience[i];
|
|
195
|
+
if (!exp.company) {
|
|
196
|
+
suggestions.push({
|
|
197
|
+
id: `SUG-${id++}`,
|
|
198
|
+
priority: "medium",
|
|
199
|
+
category: "content",
|
|
200
|
+
field: "experience",
|
|
201
|
+
title: `Experience entry #${i + 1}: Company name not detected`,
|
|
202
|
+
description: "The company/organization name could not be parsed. Consider putting it on its own line in bold.",
|
|
203
|
+
currentValue: null,
|
|
204
|
+
suggestedValue: "Company Name, City, ST",
|
|
205
|
+
rationale: "The parser identifies company names by checking bold formatting and proximity to dates.",
|
|
206
|
+
});
|
|
207
|
+
}
|
|
208
|
+
if (!exp.jobTitle) {
|
|
209
|
+
suggestions.push({
|
|
210
|
+
id: `SUG-${id++}`,
|
|
211
|
+
priority: "medium",
|
|
212
|
+
category: "content",
|
|
213
|
+
field: "experience",
|
|
214
|
+
title: `Experience entry #${i + 1}: Job title not detected`,
|
|
215
|
+
description: "The job title could not be parsed. Use common job title keywords (e.g., Engineer, Analyst, Manager).",
|
|
216
|
+
currentValue: null,
|
|
217
|
+
suggestedValue: "Job Title (e.g., Software Engineer, Data Analyst)",
|
|
218
|
+
rationale: "The parser matches job titles against a keyword list including Analyst, Engineer, Manager, etc.",
|
|
219
|
+
});
|
|
220
|
+
}
|
|
221
|
+
if (!exp.date) {
|
|
222
|
+
suggestions.push({
|
|
223
|
+
id: `SUG-${id++}`,
|
|
224
|
+
priority: "low",
|
|
225
|
+
category: "content",
|
|
226
|
+
field: "experience",
|
|
227
|
+
title: `Experience entry #${i + 1}: Date range not detected`,
|
|
228
|
+
description: "Include dates like 'June 2022–Present' on the same line as the company name.",
|
|
229
|
+
currentValue: null,
|
|
230
|
+
suggestedValue: "June 2022–Present",
|
|
231
|
+
rationale: "ATS parsers look for year patterns and 'Present' to establish employment timelines.",
|
|
232
|
+
});
|
|
233
|
+
}
|
|
234
|
+
if (exp.descriptions.length === 0) {
|
|
235
|
+
suggestions.push({
|
|
236
|
+
id: `SUG-${id++}`,
|
|
237
|
+
priority: "medium",
|
|
238
|
+
category: "content",
|
|
239
|
+
field: "experience",
|
|
240
|
+
title: `Experience entry #${i + 1}: No bullet points found`,
|
|
241
|
+
description: "Add bullet point descriptions for your responsibilities and achievements.",
|
|
242
|
+
currentValue: null,
|
|
243
|
+
suggestedValue: "• Led a team of 5 engineers to deliver project X on time\n• Improved system performance by 30%",
|
|
244
|
+
rationale: "Bullet points with action verbs and quantified results improve both ATS parsing and human readability.",
|
|
245
|
+
});
|
|
246
|
+
}
|
|
247
|
+
else if (exp.descriptions.length < 3 && focusAreas.includes("content")) {
|
|
248
|
+
suggestions.push({
|
|
249
|
+
id: `SUG-${id++}`,
|
|
250
|
+
priority: "low",
|
|
251
|
+
category: "content",
|
|
252
|
+
field: "experience",
|
|
253
|
+
title: `Experience entry #${i + 1}: Consider adding more bullet points`,
|
|
254
|
+
description: `Only ${exp.descriptions.length} bullet points found. Aim for 3-5 per role.`,
|
|
255
|
+
currentValue: `${exp.descriptions.length} bullet points`,
|
|
256
|
+
suggestedValue: "3-5 bullet points per role with quantified achievements",
|
|
257
|
+
rationale: "More bullet points with action verbs and metrics improve ATS keyword matching and demonstrate impact.",
|
|
258
|
+
});
|
|
259
|
+
}
|
|
260
|
+
}
|
|
261
|
+
return suggestions;
|
|
262
|
+
}
|
|
263
|
+
function skillsSuggestions(resume, focusAreas) {
|
|
264
|
+
const suggestions = [];
|
|
265
|
+
let id = 300;
|
|
266
|
+
if (resume.skills.length === 0) {
|
|
267
|
+
suggestions.push({
|
|
268
|
+
id: `SUG-${id++}`,
|
|
269
|
+
priority: "medium",
|
|
270
|
+
category: "structure",
|
|
271
|
+
field: "skills",
|
|
272
|
+
title: "Skills section not detected",
|
|
273
|
+
description: "A dedicated skills section helps ATS match your resume to job requirements.",
|
|
274
|
+
currentValue: null,
|
|
275
|
+
suggestedValue: "Add a 'SKILLS' section listing key technical and soft skills.",
|
|
276
|
+
rationale: "ATS systems often extract skills from a dedicated section header. Without one, skills may be missed.",
|
|
277
|
+
});
|
|
278
|
+
}
|
|
279
|
+
else if (resume.skills[0]?.descriptions.length < 3 && focusAreas.includes("content")) {
|
|
280
|
+
suggestions.push({
|
|
281
|
+
id: `SUG-${id++}`,
|
|
282
|
+
priority: "low",
|
|
283
|
+
category: "content",
|
|
284
|
+
field: "skills",
|
|
285
|
+
title: "Skills section appears thin",
|
|
286
|
+
description: `Only ${resume.skills[0]?.descriptions.length} skill items detected. Consider expanding.`,
|
|
287
|
+
currentValue: `${resume.skills[0]?.descriptions.length} items`,
|
|
288
|
+
suggestedValue: "8-15 relevant skills organized by category",
|
|
289
|
+
rationale: "A robust skills section increases keyword match rate in ATS systems.",
|
|
290
|
+
});
|
|
291
|
+
}
|
|
292
|
+
return suggestions;
|
|
293
|
+
}
|
|
294
|
+
function structureSuggestions(resume, analysis, focusAreas) {
|
|
295
|
+
const suggestions = [];
|
|
296
|
+
let id = 400;
|
|
297
|
+
// Check for single-column layout
|
|
298
|
+
if (resume.rawTextItems.length > 0) {
|
|
299
|
+
const textItemCount = resume.rawTextItems.length;
|
|
300
|
+
const lineCount = resume.lines.length;
|
|
301
|
+
if (lineCount > 0 && textItemCount / lineCount > 3) {
|
|
302
|
+
suggestions.push({
|
|
303
|
+
id: `SUG-${id++}`,
|
|
304
|
+
priority: "medium",
|
|
305
|
+
category: "formatting",
|
|
306
|
+
field: "structure",
|
|
307
|
+
title: "Resume may use multi-column layout",
|
|
308
|
+
description: "The text extraction suggests a multi-column layout, which confuses most ATS systems.",
|
|
309
|
+
currentValue: "Possible multi-column layout",
|
|
310
|
+
suggestedValue: "Use a single-column layout to ensure ATS reads content in the correct order.",
|
|
311
|
+
rationale: "ATS systems read resumes left-to-right, top-to-bottom. Multi-column layouts cause content to interleave incorrectly.",
|
|
312
|
+
});
|
|
313
|
+
}
|
|
314
|
+
}
|
|
315
|
+
// Check section ordering
|
|
316
|
+
const sectionTitles = resume.sections.map((s) => s.title);
|
|
317
|
+
const expectedOrder = ["PROFILE", "SUMMARY", "OBJECTIVE", "EDUCATION", "EXPERIENCE", "SKILLS"];
|
|
318
|
+
let orderIssue = false;
|
|
319
|
+
let lastIndex = -1;
|
|
320
|
+
for (const expected of expectedOrder) {
|
|
321
|
+
const idx = sectionTitles.indexOf(expected);
|
|
322
|
+
if (idx >= 0 && idx < lastIndex) {
|
|
323
|
+
orderIssue = true;
|
|
324
|
+
break;
|
|
325
|
+
}
|
|
326
|
+
if (idx >= 0)
|
|
327
|
+
lastIndex = idx;
|
|
328
|
+
}
|
|
329
|
+
if (orderIssue && focusAreas.includes("structure")) {
|
|
330
|
+
suggestions.push({
|
|
331
|
+
id: `SUG-${id++}`,
|
|
332
|
+
priority: "low",
|
|
333
|
+
category: "structure",
|
|
334
|
+
field: "structure",
|
|
335
|
+
title: "Section ordering may not be optimal",
|
|
336
|
+
description: "Consider reordering sections to: Profile/Summary → Education → Experience → Skills.",
|
|
337
|
+
currentValue: `Current order: ${sectionTitles.join(" → ")}`,
|
|
338
|
+
suggestedValue: "Profile → Education → Experience → Skills",
|
|
339
|
+
rationale: "Standard section ordering helps ATS and recruiters find information quickly. Education before Experience is common for recent graduates.",
|
|
340
|
+
});
|
|
341
|
+
}
|
|
342
|
+
// Check for date formatting consistency
|
|
343
|
+
if (focusAreas.includes("formatting")) {
|
|
344
|
+
const allDates = [];
|
|
345
|
+
for (const edu of resume.education) {
|
|
346
|
+
if (edu.date)
|
|
347
|
+
allDates.push(edu.date);
|
|
348
|
+
}
|
|
349
|
+
for (const exp of resume.experience) {
|
|
350
|
+
if (exp.date)
|
|
351
|
+
allDates.push(exp.date);
|
|
352
|
+
}
|
|
353
|
+
const dateFormats = new Set();
|
|
354
|
+
for (const d of allDates) {
|
|
355
|
+
if (/^\d{4}$/.test(d))
|
|
356
|
+
dateFormats.add("year-only");
|
|
357
|
+
else if (/–/.test(d) || /—/.test(d))
|
|
358
|
+
dateFormats.add("en-dash");
|
|
359
|
+
else if (/-/.test(d))
|
|
360
|
+
dateFormats.add("hyphen");
|
|
361
|
+
else
|
|
362
|
+
dateFormats.add("other");
|
|
363
|
+
}
|
|
364
|
+
if (dateFormats.size > 1) {
|
|
365
|
+
suggestions.push({
|
|
366
|
+
id: `SUG-${id++}`,
|
|
367
|
+
priority: "low",
|
|
368
|
+
category: "formatting",
|
|
369
|
+
field: "formatting",
|
|
370
|
+
title: "Date formats are inconsistent",
|
|
371
|
+
description: "Use a consistent date format throughout your resume (e.g., 'Month Year–Month Year').",
|
|
372
|
+
currentValue: `Multiple formats detected: ${Array.from(dateFormats).join(", ")}`,
|
|
373
|
+
suggestedValue: "Consistent format: 'June 2022–Present' or '2022–2024'",
|
|
374
|
+
rationale: "Inconsistent date formatting can cause ATS to misparse employment timelines.",
|
|
375
|
+
});
|
|
376
|
+
}
|
|
377
|
+
}
|
|
378
|
+
return suggestions;
|
|
379
|
+
}
|
|
380
|
+
// ---------------------------------------------------------------------------
|
|
381
|
+
// Section-level suggestions
|
|
382
|
+
// ---------------------------------------------------------------------------
|
|
383
|
+
function generateSectionSuggestions(resume) {
|
|
384
|
+
const result = [];
|
|
385
|
+
const desiredSections = [
|
|
386
|
+
{ title: "PROFILE", label: "Profile" },
|
|
387
|
+
{ title: "EDUCATION", label: "Education" },
|
|
388
|
+
{ title: "EXPERIENCE", label: "Work Experience" },
|
|
389
|
+
{ title: "SKILLS", label: "Skills" },
|
|
390
|
+
];
|
|
391
|
+
for (const desired of desiredSections) {
|
|
392
|
+
const found = resume.sections.find((s) => s.title === desired.title);
|
|
393
|
+
if (found) {
|
|
394
|
+
const issues = [];
|
|
395
|
+
const recs = [];
|
|
396
|
+
if (found.lines.length === 0) {
|
|
397
|
+
issues.push("Section is empty");
|
|
398
|
+
recs.push(`Add content to your ${desired.label} section`);
|
|
399
|
+
}
|
|
400
|
+
result.push({
|
|
401
|
+
section: desired.title,
|
|
402
|
+
present: true,
|
|
403
|
+
issues,
|
|
404
|
+
recommendations: recs,
|
|
405
|
+
});
|
|
406
|
+
}
|
|
407
|
+
else {
|
|
408
|
+
result.push({
|
|
409
|
+
section: desired.title,
|
|
410
|
+
present: false,
|
|
411
|
+
issues: [`Missing ${desired.label} section`],
|
|
412
|
+
recommendations: [`Add a "${desired.title}" header in bold and uppercase`],
|
|
413
|
+
});
|
|
414
|
+
}
|
|
415
|
+
}
|
|
416
|
+
return result;
|
|
417
|
+
}
|
|
418
|
+
// ---------------------------------------------------------------------------
|
|
419
|
+
// Main suggestion function
|
|
420
|
+
// ---------------------------------------------------------------------------
|
|
421
|
+
function suggestImprovements(input) {
|
|
422
|
+
const { parsedResume, analysisResult, focusAreas = ["ats", "content", "formatting", "structure"] } = input;
|
|
423
|
+
// Collect all suggestions
|
|
424
|
+
const allSuggestions = [
|
|
425
|
+
...profileSuggestions(parsedResume, analysisResult, focusAreas),
|
|
426
|
+
...educationSuggestions(parsedResume, focusAreas),
|
|
427
|
+
...experienceSuggestions(parsedResume, focusAreas),
|
|
428
|
+
...skillsSuggestions(parsedResume, focusAreas),
|
|
429
|
+
...structureSuggestions(parsedResume, analysisResult, focusAreas),
|
|
430
|
+
];
|
|
431
|
+
// Filter by focus areas
|
|
432
|
+
const filteredSuggestions = allSuggestions.filter((s) => focusAreas.includes(s.category));
|
|
433
|
+
// Sort by priority
|
|
434
|
+
const priorityOrder = { critical: 0, high: 1, medium: 2, low: 3 };
|
|
435
|
+
filteredSuggestions.sort((a, b) => priorityOrder[a.priority] - priorityOrder[b.priority]);
|
|
436
|
+
// Section suggestions
|
|
437
|
+
const sectionSuggestions = generateSectionSuggestions(parsedResume);
|
|
438
|
+
// Quick wins (high-impact, easy-to-fix)
|
|
439
|
+
const quickWins = filteredSuggestions
|
|
440
|
+
.filter((s) => s.priority === "critical" || s.priority === "high")
|
|
441
|
+
.map((s) => `**${s.title}**: ${s.suggestedValue}`);
|
|
442
|
+
// Long-term advice
|
|
443
|
+
const longTermAdvice = [
|
|
444
|
+
"Tailor your resume keywords to each job description for better ATS matching",
|
|
445
|
+
"Use standard section headers (Education, Experience, Skills) in bold UPPERCASE",
|
|
446
|
+
"Stick to a single-column layout for maximum ATS compatibility",
|
|
447
|
+
"Use standard bullet point characters (•) for descriptions",
|
|
448
|
+
"Avoid headers/footers, images, and tables — ATS often can't read them",
|
|
449
|
+
"Save your resume as a text-based PDF (not scanned/image PDF)",
|
|
450
|
+
"Keep date formats consistent throughout (e.g., 'Month Year–Month Year')",
|
|
451
|
+
"Quantify achievements with numbers and percentages where possible",
|
|
452
|
+
];
|
|
453
|
+
const criticalFixes = filteredSuggestions.filter((s) => s.priority === "critical").length;
|
|
454
|
+
return {
|
|
455
|
+
success: true,
|
|
456
|
+
data: {
|
|
457
|
+
overallScore: analysisResult.atsScore,
|
|
458
|
+
overallGrade: analysisResult.atsGrade,
|
|
459
|
+
criticalFixes,
|
|
460
|
+
totalSuggestions: filteredSuggestions.length,
|
|
461
|
+
suggestions: filteredSuggestions,
|
|
462
|
+
sectionSuggestions,
|
|
463
|
+
quickWins,
|
|
464
|
+
longTermAdvice,
|
|
465
|
+
},
|
|
466
|
+
metadata: {
|
|
467
|
+
parserVersion: "1.0.0",
|
|
468
|
+
focusAreas,
|
|
469
|
+
},
|
|
470
|
+
};
|
|
471
|
+
}
|
|
472
|
+
//# sourceMappingURL=suggest-improvements.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"suggest-improvements.js","sourceRoot":"","sources":["../../../src/tools/suggest-improvements.ts"],"names":[],"mappings":"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"}
|
package/package.json
ADDED
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "resume-parser-ats",
|
|
3
|
+
"version": "1.1.0",
|
|
4
|
+
"description": "An agent skill that deeply parses resumes, extracts structured data, and provides actionable insights to improve ATS compatibility and readability.",
|
|
5
|
+
"main": "dist/src/index.js",
|
|
6
|
+
"types": "dist/src/index.d.ts",
|
|
7
|
+
"bin": {
|
|
8
|
+
"resume-parser": "bin/cli.js"
|
|
9
|
+
},
|
|
10
|
+
"scripts": {
|
|
11
|
+
"build": "tsc",
|
|
12
|
+
"start": "node dist/src/index.js",
|
|
13
|
+
"dev": "ts-node src/index.ts",
|
|
14
|
+
"mcp": "ts-node mcp-server/server.ts",
|
|
15
|
+
"lint": "eslint src/",
|
|
16
|
+
"test": "node --test test/evals/parse-resume.test.mjs test/evals/analyze-resume.test.mjs test/evals/suggest-improvements.test.mjs"
|
|
17
|
+
},
|
|
18
|
+
"files": [
|
|
19
|
+
"dist/",
|
|
20
|
+
"bin/",
|
|
21
|
+
"README.md",
|
|
22
|
+
"LICENSE"
|
|
23
|
+
],
|
|
24
|
+
"keywords": [
|
|
25
|
+
"resume",
|
|
26
|
+
"parser",
|
|
27
|
+
"ATS",
|
|
28
|
+
"agent-skill",
|
|
29
|
+
"resume-parser",
|
|
30
|
+
"career"
|
|
31
|
+
],
|
|
32
|
+
"author": "dhanush",
|
|
33
|
+
"license": "MIT",
|
|
34
|
+
"repository": {
|
|
35
|
+
"type": "git",
|
|
36
|
+
"url": "git+https://github.com/dhanushk-offl/resume-parser-skill.git"
|
|
37
|
+
},
|
|
38
|
+
"publishConfig": {
|
|
39
|
+
"access": "public"
|
|
40
|
+
},
|
|
41
|
+
"dependencies": {
|
|
42
|
+
"pdf-parse": "^1.1.1",
|
|
43
|
+
"pdfjs-dist": "^4.0.379",
|
|
44
|
+
"zod": "^3.22.4"
|
|
45
|
+
},
|
|
46
|
+
"devDependencies": {
|
|
47
|
+
"@types/node": "^20.11.0",
|
|
48
|
+
"@typescript-eslint/eslint-plugin": "^8.59.4",
|
|
49
|
+
"@typescript-eslint/parser": "^8.59.4",
|
|
50
|
+
"eslint": "^10.4.0",
|
|
51
|
+
"globals": "^17.6.0",
|
|
52
|
+
"ts-node": "^10.9.2",
|
|
53
|
+
"typescript": "^5.3.3",
|
|
54
|
+
"typescript-eslint": "^8.59.4"
|
|
55
|
+
}
|
|
56
|
+
}
|