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,276 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Resume Parser โ MCP Server
|
|
4
|
+
*
|
|
5
|
+
* Exposes the resume parsing, analysis, and suggestion tools
|
|
6
|
+
* via the Model Context Protocol (MCP).
|
|
7
|
+
*
|
|
8
|
+
* Tools:
|
|
9
|
+
* - parse_resume: Parse a resume PDF/text and return structured data
|
|
10
|
+
* - analyze_resume: Parse + compute ATS compatibility score
|
|
11
|
+
* - suggest_improvements: Generate actionable fix suggestions
|
|
12
|
+
*
|
|
13
|
+
* Usage:
|
|
14
|
+
* npm run mcp
|
|
15
|
+
*
|
|
16
|
+
* The server communicates via stdio using the MCP protocol.
|
|
17
|
+
*/
|
|
18
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
19
|
+
if (k2 === undefined) k2 = k;
|
|
20
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
21
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
22
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
23
|
+
}
|
|
24
|
+
Object.defineProperty(o, k2, desc);
|
|
25
|
+
}) : (function(o, m, k, k2) {
|
|
26
|
+
if (k2 === undefined) k2 = k;
|
|
27
|
+
o[k2] = m[k];
|
|
28
|
+
}));
|
|
29
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
30
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
31
|
+
}) : function(o, v) {
|
|
32
|
+
o["default"] = v;
|
|
33
|
+
});
|
|
34
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
35
|
+
var ownKeys = function(o) {
|
|
36
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
37
|
+
var ar = [];
|
|
38
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
39
|
+
return ar;
|
|
40
|
+
};
|
|
41
|
+
return ownKeys(o);
|
|
42
|
+
};
|
|
43
|
+
return function (mod) {
|
|
44
|
+
if (mod && mod.__esModule) return mod;
|
|
45
|
+
var result = {};
|
|
46
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
47
|
+
__setModuleDefault(result, mod);
|
|
48
|
+
return result;
|
|
49
|
+
};
|
|
50
|
+
})();
|
|
51
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
52
|
+
const parse_resume_1 = require("../src/tools/parse-resume");
|
|
53
|
+
const analyze_resume_1 = require("../src/tools/analyze-resume");
|
|
54
|
+
const suggest_improvements_1 = require("../src/tools/suggest-improvements");
|
|
55
|
+
const tools = [
|
|
56
|
+
{
|
|
57
|
+
name: "parse_resume",
|
|
58
|
+
description: `Parse a resume (PDF file or raw text) using the 4-step OpenResume algorithm:
|
|
59
|
+
1. Extract text items from PDF
|
|
60
|
+
2. Group text items into lines
|
|
61
|
+
3. Group lines into sections
|
|
62
|
+
4. Extract resume attributes using feature scoring
|
|
63
|
+
|
|
64
|
+
Returns structured resume data including profile, education, experience, skills, and projects.`,
|
|
65
|
+
inputSchema: {
|
|
66
|
+
type: "object",
|
|
67
|
+
properties: {
|
|
68
|
+
filePath: {
|
|
69
|
+
type: "string",
|
|
70
|
+
description: "Path to the resume PDF file",
|
|
71
|
+
},
|
|
72
|
+
rawText: {
|
|
73
|
+
type: "string",
|
|
74
|
+
description: "Raw resume text (use if PDF is not available)",
|
|
75
|
+
},
|
|
76
|
+
},
|
|
77
|
+
},
|
|
78
|
+
handler: async (args) => {
|
|
79
|
+
const result = (0, parse_resume_1.parseResume)({
|
|
80
|
+
filePath: args.filePath,
|
|
81
|
+
rawText: args.rawText,
|
|
82
|
+
});
|
|
83
|
+
return { content: [{ type: "text", text: JSON.stringify(result, null, 2) }] };
|
|
84
|
+
},
|
|
85
|
+
},
|
|
86
|
+
{
|
|
87
|
+
name: "analyze_resume",
|
|
88
|
+
description: `Parse a resume and compute an ATS (Application Tracking System) compatibility score.
|
|
89
|
+
|
|
90
|
+
Returns:
|
|
91
|
+
- ATS compatibility score (0-100) and grade
|
|
92
|
+
- Per-field extraction confidence ratings
|
|
93
|
+
- Section detection analysis
|
|
94
|
+
- Format issues grouped by severity (critical/high/medium/low)`,
|
|
95
|
+
inputSchema: {
|
|
96
|
+
type: "object",
|
|
97
|
+
properties: {
|
|
98
|
+
filePath: {
|
|
99
|
+
type: "string",
|
|
100
|
+
description: "Path to the resume PDF file",
|
|
101
|
+
},
|
|
102
|
+
rawText: {
|
|
103
|
+
type: "string",
|
|
104
|
+
description: "Raw resume text (use if PDF is not available)",
|
|
105
|
+
},
|
|
106
|
+
strictness: {
|
|
107
|
+
type: "string",
|
|
108
|
+
enum: ["lenient", "moderate", "strict"],
|
|
109
|
+
description: "ATS scoring strictness level (default: moderate)",
|
|
110
|
+
},
|
|
111
|
+
},
|
|
112
|
+
},
|
|
113
|
+
handler: async (args) => {
|
|
114
|
+
// First parse
|
|
115
|
+
const parsed = (0, parse_resume_1.parseResume)({
|
|
116
|
+
filePath: args.filePath,
|
|
117
|
+
rawText: args.rawText,
|
|
118
|
+
});
|
|
119
|
+
// Then analyze
|
|
120
|
+
const result = (0, analyze_resume_1.analyzeResume)({
|
|
121
|
+
filePath: args.filePath,
|
|
122
|
+
rawText: args.rawText,
|
|
123
|
+
parsedResume: parsed.data,
|
|
124
|
+
strictness: args.strictness || "moderate",
|
|
125
|
+
});
|
|
126
|
+
return { content: [{ type: "text", text: JSON.stringify(result, null, 2) }] };
|
|
127
|
+
},
|
|
128
|
+
},
|
|
129
|
+
{
|
|
130
|
+
name: "suggest_improvements",
|
|
131
|
+
description: `Parse a resume, analyze it, and generate actionable improvement suggestions.
|
|
132
|
+
|
|
133
|
+
Returns:
|
|
134
|
+
- ATS compatibility score and grade
|
|
135
|
+
- Prioritized list of suggestions (critical โ low)
|
|
136
|
+
- Quick wins for immediate fixes
|
|
137
|
+
- Section-by-section analysis and recommendations
|
|
138
|
+
- Long-term improvement advice`,
|
|
139
|
+
inputSchema: {
|
|
140
|
+
type: "object",
|
|
141
|
+
properties: {
|
|
142
|
+
filePath: {
|
|
143
|
+
type: "string",
|
|
144
|
+
description: "Path to the resume PDF file",
|
|
145
|
+
},
|
|
146
|
+
rawText: {
|
|
147
|
+
type: "string",
|
|
148
|
+
description: "Raw resume text (use if PDF is not available)",
|
|
149
|
+
},
|
|
150
|
+
focusAreas: {
|
|
151
|
+
type: "array",
|
|
152
|
+
items: {
|
|
153
|
+
type: "string",
|
|
154
|
+
enum: ["ats", "content", "formatting", "structure"],
|
|
155
|
+
},
|
|
156
|
+
description: "Areas to focus suggestions on (default: all)",
|
|
157
|
+
},
|
|
158
|
+
},
|
|
159
|
+
},
|
|
160
|
+
handler: async (args) => {
|
|
161
|
+
// Full pipeline
|
|
162
|
+
const parsed = (0, parse_resume_1.parseResume)({
|
|
163
|
+
filePath: args.filePath,
|
|
164
|
+
rawText: args.rawText,
|
|
165
|
+
});
|
|
166
|
+
const analyzed = (0, analyze_resume_1.analyzeResume)({
|
|
167
|
+
filePath: args.filePath,
|
|
168
|
+
rawText: args.rawText,
|
|
169
|
+
parsedResume: parsed.data,
|
|
170
|
+
strictness: "moderate",
|
|
171
|
+
});
|
|
172
|
+
const result = (0, suggest_improvements_1.suggestImprovements)({
|
|
173
|
+
filePath: args.filePath,
|
|
174
|
+
rawText: args.rawText,
|
|
175
|
+
parsedResume: parsed.data,
|
|
176
|
+
analysisResult: analyzed.data,
|
|
177
|
+
focusAreas: args.focusAreas || ["ats", "content", "formatting", "structure"],
|
|
178
|
+
});
|
|
179
|
+
return { content: [{ type: "text", text: JSON.stringify(result, null, 2) }] };
|
|
180
|
+
},
|
|
181
|
+
},
|
|
182
|
+
];
|
|
183
|
+
// ---------------------------------------------------------------------------
|
|
184
|
+
// Stdio MCP Server
|
|
185
|
+
// ---------------------------------------------------------------------------
|
|
186
|
+
async function handleRequest(request) {
|
|
187
|
+
const { method, params, id } = request;
|
|
188
|
+
switch (method) {
|
|
189
|
+
case "initialize":
|
|
190
|
+
return {
|
|
191
|
+
jsonrpc: "2.0",
|
|
192
|
+
id,
|
|
193
|
+
result: {
|
|
194
|
+
protocolVersion: "2024-11-05",
|
|
195
|
+
capabilities: {
|
|
196
|
+
tools: {},
|
|
197
|
+
},
|
|
198
|
+
serverInfo: {
|
|
199
|
+
name: "resume-parser",
|
|
200
|
+
version: "1.0.0",
|
|
201
|
+
},
|
|
202
|
+
},
|
|
203
|
+
};
|
|
204
|
+
case "tools/list":
|
|
205
|
+
return {
|
|
206
|
+
jsonrpc: "2.0",
|
|
207
|
+
id,
|
|
208
|
+
result: {
|
|
209
|
+
tools: tools.map((t) => ({
|
|
210
|
+
name: t.name,
|
|
211
|
+
description: t.description,
|
|
212
|
+
inputSchema: t.inputSchema,
|
|
213
|
+
})),
|
|
214
|
+
},
|
|
215
|
+
};
|
|
216
|
+
case "tools/call": {
|
|
217
|
+
const toolName = params?.name;
|
|
218
|
+
const tool = tools.find((t) => t.name === toolName);
|
|
219
|
+
if (!tool) {
|
|
220
|
+
return {
|
|
221
|
+
jsonrpc: "2.0",
|
|
222
|
+
id,
|
|
223
|
+
error: { code: -32601, message: `Unknown tool: ${toolName}` },
|
|
224
|
+
};
|
|
225
|
+
}
|
|
226
|
+
try {
|
|
227
|
+
const result = await tool.handler(params?.arguments || {});
|
|
228
|
+
return { jsonrpc: "2.0", id, result };
|
|
229
|
+
}
|
|
230
|
+
catch (error) {
|
|
231
|
+
return {
|
|
232
|
+
jsonrpc: "2.0",
|
|
233
|
+
id,
|
|
234
|
+
error: { code: -32603, message: error.message },
|
|
235
|
+
};
|
|
236
|
+
}
|
|
237
|
+
}
|
|
238
|
+
default:
|
|
239
|
+
return {
|
|
240
|
+
jsonrpc: "2.0",
|
|
241
|
+
id,
|
|
242
|
+
error: { code: -32601, message: `Unknown method: ${method}` },
|
|
243
|
+
};
|
|
244
|
+
}
|
|
245
|
+
}
|
|
246
|
+
// Main loop: read JSON-RPC from stdin, write to stdout
|
|
247
|
+
async function main() {
|
|
248
|
+
const readline = await Promise.resolve().then(() => __importStar(require("readline")));
|
|
249
|
+
const rl = readline.createInterface({ input: process.stdin });
|
|
250
|
+
let buffer = "";
|
|
251
|
+
rl.on("line", (line) => {
|
|
252
|
+
buffer += line + "\n";
|
|
253
|
+
// Try to parse as JSON-RPC request
|
|
254
|
+
try {
|
|
255
|
+
const request = JSON.parse(buffer.trim());
|
|
256
|
+
buffer = "";
|
|
257
|
+
handleRequest(request).then((response) => {
|
|
258
|
+
process.stdout.write(JSON.stringify(response) + "\n");
|
|
259
|
+
});
|
|
260
|
+
}
|
|
261
|
+
catch {
|
|
262
|
+
// Not a complete JSON yet, keep buffering
|
|
263
|
+
}
|
|
264
|
+
});
|
|
265
|
+
rl.on("close", () => {
|
|
266
|
+
process.exit(0);
|
|
267
|
+
});
|
|
268
|
+
// Log to stderr so it doesn't interfere with MCP protocol on stdout
|
|
269
|
+
process.stderr.write("Resume Parser MCP Server running on stdio\n");
|
|
270
|
+
process.stderr.write(`Available tools: ${tools.map((t) => t.name).join(", ")}\n`);
|
|
271
|
+
}
|
|
272
|
+
main().catch((err) => {
|
|
273
|
+
process.stderr.write(`Fatal error: ${err.message}\n`);
|
|
274
|
+
process.exit(1);
|
|
275
|
+
});
|
|
276
|
+
//# sourceMappingURL=server.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"server.js","sourceRoot":"","sources":["../../mcp-server/server.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Resume Parser Skill โ Main Entry Point
|
|
3
|
+
*
|
|
4
|
+
* Implements the OpenResume 4-step parsing algorithm:
|
|
5
|
+
* Step 1: Read text items from PDF
|
|
6
|
+
* Step 2: Group text items into lines
|
|
7
|
+
* Step 3: Group lines into sections
|
|
8
|
+
* Step 4: Extract resume attributes from sections
|
|
9
|
+
*/
|
|
10
|
+
import { parseResume, ParseResumeInput, ParseResumeOutput } from "./tools/parse-resume";
|
|
11
|
+
import { analyzeResume, AnalyzeResumeInput, AnalyzeResumeOutput } from "./tools/analyze-resume";
|
|
12
|
+
import { suggestImprovements, SuggestImprovementsInput, SuggestImprovementsOutput } from "./tools/suggest-improvements";
|
|
13
|
+
export { parseResume, analyzeResume, suggestImprovements };
|
|
14
|
+
export type { ParseResumeInput, ParseResumeOutput, AnalyzeResumeInput, AnalyzeResumeOutput, SuggestImprovementsInput, SuggestImprovementsOutput };
|
|
15
|
+
export interface TextItem {
|
|
16
|
+
/** The text content of the item */
|
|
17
|
+
text: string;
|
|
18
|
+
/** Left X position */
|
|
19
|
+
x1: number;
|
|
20
|
+
/** Right X position */
|
|
21
|
+
x2: number;
|
|
22
|
+
/** Y position (from bottom of page) */
|
|
23
|
+
y: number;
|
|
24
|
+
/** Whether the text item is bold */
|
|
25
|
+
bold: boolean;
|
|
26
|
+
/** Whether this item starts a new line */
|
|
27
|
+
newLine: boolean;
|
|
28
|
+
}
|
|
29
|
+
export interface LineItem {
|
|
30
|
+
/** Line number (1-indexed) */
|
|
31
|
+
lineNumber: number;
|
|
32
|
+
/** The concatenated text content of the line */
|
|
33
|
+
text: string;
|
|
34
|
+
/** Constituent text items in this line */
|
|
35
|
+
items: TextItem[];
|
|
36
|
+
/** Y position of this line */
|
|
37
|
+
y: number;
|
|
38
|
+
}
|
|
39
|
+
export interface SectionItem {
|
|
40
|
+
/** Section title (e.g., "EDUCATION", "EXPERIENCE") */
|
|
41
|
+
title: string;
|
|
42
|
+
/** Lines belonging to this section */
|
|
43
|
+
lines: LineItem[];
|
|
44
|
+
}
|
|
45
|
+
export interface ResumeProfile {
|
|
46
|
+
name: string | null;
|
|
47
|
+
email: string | null;
|
|
48
|
+
phone: string | null;
|
|
49
|
+
location: string | null;
|
|
50
|
+
url: string | null;
|
|
51
|
+
summary: string | null;
|
|
52
|
+
}
|
|
53
|
+
export interface ResumeEducation {
|
|
54
|
+
school: string | null;
|
|
55
|
+
degree: string | null;
|
|
56
|
+
gpa: string | null;
|
|
57
|
+
date: string | null;
|
|
58
|
+
descriptions: string[];
|
|
59
|
+
}
|
|
60
|
+
export interface ResumeExperience {
|
|
61
|
+
company: string | null;
|
|
62
|
+
jobTitle: string | null;
|
|
63
|
+
date: string | null;
|
|
64
|
+
descriptions: string[];
|
|
65
|
+
}
|
|
66
|
+
export interface ResumeSkills {
|
|
67
|
+
descriptions: string[];
|
|
68
|
+
}
|
|
69
|
+
export interface ResumeProject {
|
|
70
|
+
name: string | null;
|
|
71
|
+
date: string | null;
|
|
72
|
+
descriptions: string[];
|
|
73
|
+
}
|
|
74
|
+
export interface ParsedResume {
|
|
75
|
+
profile: ResumeProfile;
|
|
76
|
+
education: ResumeEducation[];
|
|
77
|
+
experience: ResumeExperience[];
|
|
78
|
+
skills: ResumeSkills[];
|
|
79
|
+
projects: ResumeProject[];
|
|
80
|
+
sections: SectionItem[];
|
|
81
|
+
rawTextItems: TextItem[];
|
|
82
|
+
lines: LineItem[];
|
|
83
|
+
}
|
|
84
|
+
/**
|
|
85
|
+
* Main function โ orchestrates the full pipeline:
|
|
86
|
+
* parse โ analyze โ suggest
|
|
87
|
+
*/
|
|
88
|
+
export declare function fullPipeline(input: ParseResumeInput & {
|
|
89
|
+
strictness?: string;
|
|
90
|
+
focusAreas?: string[];
|
|
91
|
+
}): {
|
|
92
|
+
parsed: ParseResumeOutput;
|
|
93
|
+
analyzed: AnalyzeResumeOutput;
|
|
94
|
+
suggestions: SuggestImprovementsOutput;
|
|
95
|
+
};
|
|
96
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Resume Parser Skill โ Main Entry Point
|
|
4
|
+
*
|
|
5
|
+
* Implements the OpenResume 4-step parsing algorithm:
|
|
6
|
+
* Step 1: Read text items from PDF
|
|
7
|
+
* Step 2: Group text items into lines
|
|
8
|
+
* Step 3: Group lines into sections
|
|
9
|
+
* Step 4: Extract resume attributes from sections
|
|
10
|
+
*/
|
|
11
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
12
|
+
exports.suggestImprovements = exports.analyzeResume = exports.parseResume = void 0;
|
|
13
|
+
exports.fullPipeline = fullPipeline;
|
|
14
|
+
const parse_resume_1 = require("./tools/parse-resume");
|
|
15
|
+
Object.defineProperty(exports, "parseResume", { enumerable: true, get: function () { return parse_resume_1.parseResume; } });
|
|
16
|
+
const analyze_resume_1 = require("./tools/analyze-resume");
|
|
17
|
+
Object.defineProperty(exports, "analyzeResume", { enumerable: true, get: function () { return analyze_resume_1.analyzeResume; } });
|
|
18
|
+
const suggest_improvements_1 = require("./tools/suggest-improvements");
|
|
19
|
+
Object.defineProperty(exports, "suggestImprovements", { enumerable: true, get: function () { return suggest_improvements_1.suggestImprovements; } });
|
|
20
|
+
/**
|
|
21
|
+
* Main function โ orchestrates the full pipeline:
|
|
22
|
+
* parse โ analyze โ suggest
|
|
23
|
+
*/
|
|
24
|
+
function fullPipeline(input) {
|
|
25
|
+
const parsed = (0, parse_resume_1.parseResume)(input);
|
|
26
|
+
const analyzed = (0, analyze_resume_1.analyzeResume)({
|
|
27
|
+
...input,
|
|
28
|
+
parsedResume: parsed.data,
|
|
29
|
+
strictness: input.strictness ?? "moderate",
|
|
30
|
+
});
|
|
31
|
+
const suggestions = (0, suggest_improvements_1.suggestImprovements)({
|
|
32
|
+
...input,
|
|
33
|
+
parsedResume: parsed.data,
|
|
34
|
+
analysisResult: analyzed.data,
|
|
35
|
+
focusAreas: input.focusAreas ?? ["ats", "content", "formatting", "structure"],
|
|
36
|
+
});
|
|
37
|
+
return { parsed, analyzed, suggestions };
|
|
38
|
+
}
|
|
39
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":";AAAA;;;;;;;;GAQG;;;AA+FH,oCAuBC;AApHD,uDAAwF;AAI/E,4FAJA,0BAAW,OAIA;AAHpB,2DAAgG;AAG1E,8FAHb,8BAAa,OAGa;AAFnC,uEAAwH;AAEnF,oGAF5B,0CAAmB,OAE4B;AAqFxD;;;GAGG;AACH,SAAgB,YAAY,CAC1B,KAAwE;IAMxE,MAAM,MAAM,GAAG,IAAA,0BAAW,EAAC,KAAK,CAAC,CAAC;IAElC,MAAM,QAAQ,GAAG,IAAA,8BAAa,EAAC;QAC7B,GAAG,KAAK;QACR,YAAY,EAAE,MAAM,CAAC,IAAI;QACzB,UAAU,EAAG,KAAK,CAAC,UAAgD,IAAI,UAAU;KAClF,CAAC,CAAC;IAEH,MAAM,WAAW,GAAG,IAAA,0CAAmB,EAAC;QACtC,GAAG,KAAK;QACR,YAAY,EAAE,MAAM,CAAC,IAAI;QACzB,cAAc,EAAE,QAAQ,CAAC,IAAI;QAC7B,UAAU,EAAE,KAAK,CAAC,UAAU,IAAI,CAAC,KAAK,EAAE,SAAS,EAAE,YAAY,EAAE,WAAW,CAAC;KAC9E,CAAC,CAAC;IAEH,OAAO,EAAE,MAAM,EAAE,QAAQ,EAAE,WAAW,EAAE,CAAC;AAC3C,CAAC"}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Insights prompt templates for generating human-readable
|
|
3
|
+
* resume analysis reports and improvement summaries.
|
|
4
|
+
*/
|
|
5
|
+
export declare const REPORT_TEMPLATE = "## \uD83D\uDCCA Resume Parsing Report\n\n### ATS Compatibility Score: {{atsScore}}/100 (Grade: {{atsGrade}})\n\n---\n\n### \u2705 Successfully Parsed Fields\n\n| Field | Parsed Value | Confidence |\n|-------------|-------------------------------|------------|\n{{#each fieldAnalyses}}\n| {{field}} | {{value}} | {{confidence}} |\n{{/each}}\n\n---\n\n### \u26A0\uFE0F Issues Found\n\n| # | Severity | Field | Issue | Suggestion |\n|----|-----------|---------------|------------------------------------|------------------------------------|\n{{#each formatIssues}}\n| {{@index}} | {{severity}} | {{affectedFields}} | {{description}} | {{suggestion}} |\n{{/each}}\n\n---\n\n### \uD83D\uDCDD Priority Fixes\n\n{{#each priorityFixes}}\n{{@index}}. **{{title}}**: {{description}}\n - Before: `{{currentValue}}`\n - After: `{{suggestedValue}}`\n{{/each}}\n\n---\n\n### \uD83D\uDCA1 Structural Suggestions\n\n{{#each structuralSuggestions}}\n- {{this}}\n{{/each}}\n\n---\n\n### \uD83D\uDCCB Section-by-Section Analysis\n\n{{#each sectionAnalyses}}\n#### {{section}}\n- **Present**: {{present}}\n- **Issues**: {{issues}}\n- **Recommendations**: {{recommendations}}\n{{/each}}\n";
|
|
6
|
+
export declare const QUICK_SUMMARY_TEMPLATE = "\n\uD83C\uDFAF **Quick Summary**\n\n- **ATS Score**: {{atsScore}}/100 ({{atsGrade}})\n- **Critical Issues**: {{criticalFixes}}\n- **Total Suggestions**: {{totalSuggestions}}\n\n**Top 3 Quick Wins:**\n{{#each quickWins}}\n{{@index}}. {{this}}\n{{/each}}\n\n**Long-term Improvements:**\n{{#each longTermAdvice}}\n- {{this}}\n{{/each}}\n";
|
|
7
|
+
export declare const SECTION_ANALYSIS_TEMPLATES: {
|
|
8
|
+
profile: string;
|
|
9
|
+
education: string;
|
|
10
|
+
experience: string;
|
|
11
|
+
skills: string;
|
|
12
|
+
};
|
|
13
|
+
declare const _default: {
|
|
14
|
+
REPORT_TEMPLATE: string;
|
|
15
|
+
QUICK_SUMMARY_TEMPLATE: string;
|
|
16
|
+
SECTION_ANALYSIS_TEMPLATES: {
|
|
17
|
+
profile: string;
|
|
18
|
+
education: string;
|
|
19
|
+
experience: string;
|
|
20
|
+
skills: string;
|
|
21
|
+
};
|
|
22
|
+
};
|
|
23
|
+
export default _default;
|
|
24
|
+
//# sourceMappingURL=insights-prompt.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"insights-prompt.d.ts","sourceRoot":"","sources":["../../../src/prompts/insights-prompt.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAMH,eAAO,MAAM,eAAe,swCAoD3B,CAAC;AAMF,eAAO,MAAM,sBAAsB,mVAgBlC,CAAC;AAMF,eAAO,MAAM,0BAA0B;;;;;CAoCtC,CAAC;;;;;;;;;;;AAMF,wBAIE"}
|
|
@@ -0,0 +1,129 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Insights prompt templates for generating human-readable
|
|
4
|
+
* resume analysis reports and improvement summaries.
|
|
5
|
+
*/
|
|
6
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
7
|
+
exports.SECTION_ANALYSIS_TEMPLATES = exports.QUICK_SUMMARY_TEMPLATE = exports.REPORT_TEMPLATE = void 0;
|
|
8
|
+
// ---------------------------------------------------------------------------
|
|
9
|
+
// Report template โ structured output format
|
|
10
|
+
// ---------------------------------------------------------------------------
|
|
11
|
+
exports.REPORT_TEMPLATE = `## ๐ Resume Parsing Report
|
|
12
|
+
|
|
13
|
+
### ATS Compatibility Score: {{atsScore}}/100 (Grade: {{atsGrade}})
|
|
14
|
+
|
|
15
|
+
---
|
|
16
|
+
|
|
17
|
+
### โ
Successfully Parsed Fields
|
|
18
|
+
|
|
19
|
+
| Field | Parsed Value | Confidence |
|
|
20
|
+
|-------------|-------------------------------|------------|
|
|
21
|
+
{{#each fieldAnalyses}}
|
|
22
|
+
| {{field}} | {{value}} | {{confidence}} |
|
|
23
|
+
{{/each}}
|
|
24
|
+
|
|
25
|
+
---
|
|
26
|
+
|
|
27
|
+
### โ ๏ธ Issues Found
|
|
28
|
+
|
|
29
|
+
| # | Severity | Field | Issue | Suggestion |
|
|
30
|
+
|----|-----------|---------------|------------------------------------|------------------------------------|
|
|
31
|
+
{{#each formatIssues}}
|
|
32
|
+
| {{@index}} | {{severity}} | {{affectedFields}} | {{description}} | {{suggestion}} |
|
|
33
|
+
{{/each}}
|
|
34
|
+
|
|
35
|
+
---
|
|
36
|
+
|
|
37
|
+
### ๐ Priority Fixes
|
|
38
|
+
|
|
39
|
+
{{#each priorityFixes}}
|
|
40
|
+
{{@index}}. **{{title}}**: {{description}}
|
|
41
|
+
- Before: \`{{currentValue}}\`
|
|
42
|
+
- After: \`{{suggestedValue}}\`
|
|
43
|
+
{{/each}}
|
|
44
|
+
|
|
45
|
+
---
|
|
46
|
+
|
|
47
|
+
### ๐ก Structural Suggestions
|
|
48
|
+
|
|
49
|
+
{{#each structuralSuggestions}}
|
|
50
|
+
- {{this}}
|
|
51
|
+
{{/each}}
|
|
52
|
+
|
|
53
|
+
---
|
|
54
|
+
|
|
55
|
+
### ๐ Section-by-Section Analysis
|
|
56
|
+
|
|
57
|
+
{{#each sectionAnalyses}}
|
|
58
|
+
#### {{section}}
|
|
59
|
+
- **Present**: {{present}}
|
|
60
|
+
- **Issues**: {{issues}}
|
|
61
|
+
- **Recommendations**: {{recommendations}}
|
|
62
|
+
{{/each}}
|
|
63
|
+
`;
|
|
64
|
+
// ---------------------------------------------------------------------------
|
|
65
|
+
// Quick summary template
|
|
66
|
+
// ---------------------------------------------------------------------------
|
|
67
|
+
exports.QUICK_SUMMARY_TEMPLATE = `
|
|
68
|
+
๐ฏ **Quick Summary**
|
|
69
|
+
|
|
70
|
+
- **ATS Score**: {{atsScore}}/100 ({{atsGrade}})
|
|
71
|
+
- **Critical Issues**: {{criticalFixes}}
|
|
72
|
+
- **Total Suggestions**: {{totalSuggestions}}
|
|
73
|
+
|
|
74
|
+
**Top 3 Quick Wins:**
|
|
75
|
+
{{#each quickWins}}
|
|
76
|
+
{{@index}}. {{this}}
|
|
77
|
+
{{/each}}
|
|
78
|
+
|
|
79
|
+
**Long-term Improvements:**
|
|
80
|
+
{{#each longTermAdvice}}
|
|
81
|
+
- {{this}}
|
|
82
|
+
{{/each}}
|
|
83
|
+
`;
|
|
84
|
+
// ---------------------------------------------------------------------------
|
|
85
|
+
// Detailed section analysis templates
|
|
86
|
+
// ---------------------------------------------------------------------------
|
|
87
|
+
exports.SECTION_ANALYSIS_TEMPLATES = {
|
|
88
|
+
profile: `#### Profile Section Analysis
|
|
89
|
+
The profile section is the first thing an ATS reads. It contains the most critical fields:
|
|
90
|
+
- **Name**: Must be bolded, on the first line, letters only
|
|
91
|
+
- **Email**: Must follow xxx@xxx.xxx format, ideally on its own line
|
|
92
|
+
- **Phone**: Use standard format (123) 456-7890 or 123-456-7890
|
|
93
|
+
- **Location**: Use "City, ST" format for best ATS matching
|
|
94
|
+
`,
|
|
95
|
+
education: `#### Education Section Analysis
|
|
96
|
+
Education sections should be structured with:
|
|
97
|
+
- School name (bolded, with keywords like University, College)
|
|
98
|
+
- Degree and field (include degree keywords like Bachelor, Master)
|
|
99
|
+
- GPA in x.xx format
|
|
100
|
+
- Date with year (e.g., "Expected Graduation: June 2026")
|
|
101
|
+
|
|
102
|
+
Ensure subsections are separated by consistent spacing or bold headers.
|
|
103
|
+
`,
|
|
104
|
+
experience: `#### Work Experience Section Analysis
|
|
105
|
+
Each experience entry should have:
|
|
106
|
+
- Company name (bolded, with location)
|
|
107
|
+
- Job title (include job title keywords)
|
|
108
|
+
- Date range on same line as company (e.g., "June 2022โPresent")
|
|
109
|
+
- 3-5 bullet points with action verbs and quantified results
|
|
110
|
+
|
|
111
|
+
Avoid multi-column layouts that interleave company/title/date.
|
|
112
|
+
`,
|
|
113
|
+
skills: `#### Skills Section Analysis
|
|
114
|
+
A skills section should:
|
|
115
|
+
- Be titled "SKILLS" in bold uppercase
|
|
116
|
+
- Categorize skills (Technical, Languages, Soft Skills)
|
|
117
|
+
- Use comma-separated lists within categories
|
|
118
|
+
- Include keywords from target job descriptions
|
|
119
|
+
`,
|
|
120
|
+
};
|
|
121
|
+
// ---------------------------------------------------------------------------
|
|
122
|
+
// Export all templates
|
|
123
|
+
// ---------------------------------------------------------------------------
|
|
124
|
+
exports.default = {
|
|
125
|
+
REPORT_TEMPLATE: exports.REPORT_TEMPLATE,
|
|
126
|
+
QUICK_SUMMARY_TEMPLATE: exports.QUICK_SUMMARY_TEMPLATE,
|
|
127
|
+
SECTION_ANALYSIS_TEMPLATES: exports.SECTION_ANALYSIS_TEMPLATES,
|
|
128
|
+
};
|
|
129
|
+
//# sourceMappingURL=insights-prompt.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"insights-prompt.js","sourceRoot":"","sources":["../../../src/prompts/insights-prompt.ts"],"names":[],"mappings":";AAAA;;;GAGG;;;AAEH,8EAA8E;AAC9E,6CAA6C;AAC7C,8EAA8E;AAEjE,QAAA,eAAe,GAAG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAoD9B,CAAC;AAEF,8EAA8E;AAC9E,yBAAyB;AACzB,8EAA8E;AAEjE,QAAA,sBAAsB,GAAG;;;;;;;;;;;;;;;;CAgBrC,CAAC;AAEF,8EAA8E;AAC9E,sCAAsC;AACtC,8EAA8E;AAEjE,QAAA,0BAA0B,GAAG;IACxC,OAAO,EAAE;;;;;;CAMV;IAEC,SAAS,EAAE;;;;;;;;CAQZ;IAEC,UAAU,EAAE;;;;;;;;CAQb;IAEC,MAAM,EAAE;;;;;;CAMT;CACA,CAAC;AAEF,8EAA8E;AAC9E,uBAAuB;AACvB,8EAA8E;AAE9E,kBAAe;IACb,eAAe,EAAf,uBAAe;IACf,sBAAsB,EAAtB,8BAAsB;IACtB,0BAA0B,EAA1B,kCAA0B;CAC3B,CAAC"}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Prompt templates for the resume parser skill.
|
|
3
|
+
*
|
|
4
|
+
* These templates guide the agent when using the parser tools
|
|
5
|
+
* and when presenting results to the user.
|
|
6
|
+
*/
|
|
7
|
+
export declare const PARSE_PROMPT = "You are a resume parsing specialist. Your job is to deeply parse the provided resume using the 4-step OpenResume algorithm and return structured, clean results.\n\n## Instructions\n\n1. **Step 1 \u2014 Extract Text Items**: Read the resume content and identify all text items with their positions, boldness, and line breaks.\n2. **Step 2 \u2014 Group into Lines**: Merge adjacent text items on the same line. Group items by Y-coordinate.\n3. **Step 3 \u2014 Group into Sections**: Detect section titles (bold, UPPERCASE, or keyword match). Assign lines to their section.\n4. **Step 4 \u2014 Extract Attributes**: Use the feature scoring system to identify Name, Email, Phone, Location, School, Degree, GPA, Dates, Job Title, Company, and Skills.\n\n## Output Format\n\nPresent the parsed results in this table format:\n\n### Profile\n| Field | Value |\n|-----------|-------|\n| Name | ... |\n| Email | ... |\n| Phone | ... |\n| Location | ... |\n| Link | ... |\n\n### Education\n| School | Degree | GPA | Date | Descriptions |\n|---------|---------|------|-------|-------------|\n\n### Work Experience\n| Company | Job Title | Date | Descriptions |\n|----------|------------|-------|-------------|\n\n### Skills\n| Descriptions |\n|-------------|\n\nIf any field cannot be parsed, mark it as \"Not parsed\" and explain why in a notes section.";
|
|
8
|
+
export declare const ANALYSIS_PROMPT = "You are evaluating how well a resume would be parsed by an Application Tracking System (ATS). Use the parsed resume data to compute an ATS compatibility score.\n\n## Scoring Criteria\n\n| Category | Weight | Description |\n|----------|--------|-------------|\n| Name extraction | 20 pts | Can the parser identify a name? |\n| Email extraction | 20 pts | Can the parser identify an email? |\n| Phone extraction | 10 pts | Can the parser identify a phone number? |\n| Section detection | 15 pts | Are all key sections detected? |\n| Education parsing | 10 pts | Is school/degree/date parsed correctly? |\n| Experience parsing | 15 pts | Is company/title/date parsed correctly? |\n| Skills parsing | 10 pts | Are skills extracted correctly? |\n\n## Scoring Guide\n- **90-100**: Excellent \u2014 resume will parse correctly in nearly all ATS systems\n- **70-89**: Good \u2014 minor issues that won't significantly impact ATS parsing\n- **50-69**: Fair \u2014 significant issues that will cause problems in some ATS\n- **0-49**: Poor \u2014 critical issues that will cause major parsing failures\n\n## Output\n\nProvide:\n1. An ATS Compatibility Score (0-100)\n2. A letter grade (A+ through F)\n3. Per-field extraction confidence (high/medium/low/missing)\n4. A list of format issues grouped by severity (critical/high/medium/low)\n5. Overall notes and recommendations";
|
|
9
|
+
export declare const INSIGHTS_PROMPT = "You are a resume improvement advisor. Based on the parsed resume data and ATS analysis, provide actionable, structured suggestions to improve the resume.\n\n## Suggestion Priorities\n\n1. **CRITICAL**: Name or email cannot be parsed \u2192 Must fix immediately\n2. **HIGH**: Key sections missing, dates/phone not parseable \u2192 Fix before applying\n3. **MEDIUM**: Formatting causes merge issues, skills not extracted cleanly \u2192 Fix soon\n4. **LOW**: Minor inconsistencies, optional enhancements \u2192 Fix when convenient\n\n## Output Format\n\nPresent suggestions in this structured format:\n\n## \uD83D\uDCCA Resume Parsing Report\n\n### ATS Compatibility Score: XX/100 (Grade: X)\n\n### \u2705 Successfully Parsed Fields\n| Field | Parsed Value | Confidence |\n|-------|-------------|------------|\n\n### \u26A0\uFE0F Issues Found\n| # | Severity | Field | Issue | Suggestion |\n|---|----------|-------|-------|------------|\n\n### \uD83D\uDCDD Priority Fixes\n1. **[Fix Title]**: Description\n - Before: current state\n - After: suggested state\n\n### \uD83D\uDCA1 Structural Suggestions\n- Suggestion 1\n- Suggestion 2\n\n### \uD83D\uDCCB Section-by-Section Analysis\n#### Profile\n- Analysis...\n\n#### Education\n- Analysis...\n\n#### Work Experience\n- Analysis...\n\n#### Skills\n- Analysis...\n\nEvery suggestion must be specific and actionable. Don't say \"improve formatting\" \u2014 say \"Move the date to the same line as the company name and use the format 'Month Year\u2013Present'.\"";
|
|
10
|
+
export declare const FULL_PIPELINE_PROMPT = "You are a resume parsing and analysis expert. Run the complete 4-step parsing algorithm on the provided resume, then analyze the results and provide actionable improvement suggestions.\n\n## Pipeline Steps\n\n1. **Parse**: Follow the 4-step OpenResume algorithm (text items \u2192 lines \u2192 sections \u2192 attributes)\n2. **Analyze**: Score ATS compatibility and identify format issues\n3. **Suggest**: Provide prioritized, structured fix suggestions\n\n## Important Rules\n\n- Always run all 4 parsing steps \u2014 do not skip steps\n- Every suggestion must explain WHY it matters in ATS terms\n- Prioritize Name and Email extraction \u2014 if they fail, flag as CRITICAL\n- Compare parsed output vs. likely intended content to surface discrepancies\n- Never modify the original file \u2014 this is a read-only analysis tool\n\nProvide the complete report following the format in the insights prompt template.";
|
|
11
|
+
//# sourceMappingURL=parser-prompt.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"parser-prompt.d.ts","sourceRoot":"","sources":["../../../src/prompts/parser-prompt.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAMH,eAAO,MAAM,YAAY,22CAkCkE,CAAC;AAM5F,eAAO,MAAM,eAAe,w1CA2BS,CAAC;AAMtC,eAAO,MAAM,eAAe,2+CA+CyJ,CAAC;AAMtL,eAAO,MAAM,oBAAoB,u5BAgBiD,CAAC"}
|