@getkrafter/resume-toolkit 1.0.1

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.
Files changed (53) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +155 -0
  3. package/dist/bin/cli.d.ts +3 -0
  4. package/dist/bin/cli.d.ts.map +1 -0
  5. package/dist/bin/cli.js +4 -0
  6. package/dist/bin/cli.js.map +1 -0
  7. package/dist/krafter/client.d.ts +54 -0
  8. package/dist/krafter/client.d.ts.map +1 -0
  9. package/dist/krafter/client.js +130 -0
  10. package/dist/krafter/client.js.map +1 -0
  11. package/dist/krafter/errors.d.ts +26 -0
  12. package/dist/krafter/errors.d.ts.map +1 -0
  13. package/dist/krafter/errors.js +45 -0
  14. package/dist/krafter/errors.js.map +1 -0
  15. package/dist/lib/ats-scorer.d.ts +12 -0
  16. package/dist/lib/ats-scorer.d.ts.map +1 -0
  17. package/dist/lib/ats-scorer.js +83 -0
  18. package/dist/lib/ats-scorer.js.map +1 -0
  19. package/dist/lib/index.d.ts +6 -0
  20. package/dist/lib/index.d.ts.map +1 -0
  21. package/dist/lib/index.js +8 -0
  22. package/dist/lib/index.js.map +1 -0
  23. package/dist/lib/resume-scorer.d.ts +62 -0
  24. package/dist/lib/resume-scorer.d.ts.map +1 -0
  25. package/dist/lib/resume-scorer.js +236 -0
  26. package/dist/lib/resume-scorer.js.map +1 -0
  27. package/dist/lib/resume-transformer.d.ts +13 -0
  28. package/dist/lib/resume-transformer.d.ts.map +1 -0
  29. package/dist/lib/resume-transformer.js +113 -0
  30. package/dist/lib/resume-transformer.js.map +1 -0
  31. package/dist/lib/text-utils.d.ts +57 -0
  32. package/dist/lib/text-utils.d.ts.map +1 -0
  33. package/dist/lib/text-utils.js +282 -0
  34. package/dist/lib/text-utils.js.map +1 -0
  35. package/dist/lib/types.d.ts +31 -0
  36. package/dist/lib/types.d.ts.map +1 -0
  37. package/dist/lib/types.js +2 -0
  38. package/dist/lib/types.js.map +1 -0
  39. package/dist/mcp/server.d.ts +31 -0
  40. package/dist/mcp/server.d.ts.map +1 -0
  41. package/dist/mcp/server.js +70 -0
  42. package/dist/mcp/server.js.map +1 -0
  43. package/dist/mcp/tools/krafter.d.ts +14 -0
  44. package/dist/mcp/tools/krafter.d.ts.map +1 -0
  45. package/dist/mcp/tools/krafter.js +228 -0
  46. package/dist/mcp/tools/krafter.js.map +1 -0
  47. package/dist/mcp/tools/scoring.d.ts +46 -0
  48. package/dist/mcp/tools/scoring.d.ts.map +1 -0
  49. package/dist/mcp/tools/scoring.js +135 -0
  50. package/dist/mcp/tools/scoring.js.map +1 -0
  51. package/package.json +67 -0
  52. package/skills/score/SKILL.md +185 -0
  53. package/skills/tailor/SKILL.md +211 -0
@@ -0,0 +1,282 @@
1
+ /**
2
+ * Shared text processing utilities for resume analysis.
3
+ *
4
+ * Built on the `natural` NLP library, these helpers handle stemming,
5
+ * tokenization, normalisation (with resume-domain synonym expansion),
6
+ * and term extraction (unigrams + bigrams) used by the ATS scorer.
7
+ */
8
+ import natural from 'natural';
9
+ const porterStemmer = natural.PorterStemmer;
10
+ const wordTokenizer = new natural.WordTokenizer();
11
+ // ---------------------------------------------------------------------------
12
+ // Constants
13
+ // ---------------------------------------------------------------------------
14
+ /**
15
+ * Comprehensive English stop words (~179 words) that carry little semantic
16
+ * meaning and should be filtered out during term extraction.
17
+ */
18
+ export const STOP_WORDS = new Set([
19
+ // Articles & determiners
20
+ 'a', 'an', 'the', 'this', 'that', 'these', 'those',
21
+ // Conjunctions & prepositions
22
+ 'and', 'or', 'but', 'nor', 'so', 'yet', 'for', 'at', 'by', 'in', 'of',
23
+ 'on', 'to', 'with', 'from', 'into', 'over', 'about', 'up', 'out', 'if',
24
+ 'then', 'than', 'as', 'between', 'through', 'under', 'above', 'below',
25
+ 'during', 'before', 'after', 'until', 'while', 'because', 'against',
26
+ 'again', 'further', 'once',
27
+ // Pronouns
28
+ 'i', 'me', 'my', 'we', 'our', 'us', 'you', 'your', 'he', 'him', 'his',
29
+ 'she', 'her', 'it', 'its', 'they', 'their', 'them', 'who', 'which',
30
+ 'what', 'where', 'when', 'how', 'whom', 'whose',
31
+ // Be / have / do / modals
32
+ 'is', 'am', 'are', 'was', 'were', 'be', 'been', 'being',
33
+ 'have', 'has', 'had', 'having',
34
+ 'do', 'does', 'did',
35
+ 'will', 'would', 'could', 'should', 'may', 'might', 'can', 'shall',
36
+ 'must', 'need', 'ought',
37
+ // Common adverbs & adjectives used as function words
38
+ 'not', 'no', 'very', 'just', 'also', 'too', 'only', 'own', 'same',
39
+ 'such', 'more', 'most', 'other', 'some', 'any', 'each', 'every',
40
+ 'all', 'both', 'few', 'many', 'much', 'several',
41
+ // Misc function words
42
+ 'here', 'there', 'now', 'already', 'still', 'even', 'well',
43
+ 'back', 'away', 'off', 'down',
44
+ // Additional common stop words
45
+ 'been', 'being', 'had', 'having', 'did', 'doing',
46
+ 'would', 'could', 'should',
47
+ 'able', 'across', 'almost', 'along', 'among', 'another',
48
+ 'around', 'away', 'become', 'becomes', 'began', 'behind',
49
+ 'beside', 'besides', 'beyond', 'came', 'cannot', 'come',
50
+ 'comes', 'could', 'done', 'either', 'else', 'enough',
51
+ 'etc', 'ever', 'everything', 'find', 'first', 'found',
52
+ 'get', 'gets', 'give', 'given', 'goes', 'going', 'gone',
53
+ 'got', 'great', 'however', 'just', 'keep', 'keeps', 'kept',
54
+ 'know', 'known', 'last', 'later', 'least', 'less', 'let',
55
+ 'like', 'likely', 'long', 'look', 'made', 'make', 'makes',
56
+ 'making', 'may', 'maybe', 'might', 'mine', 'more', 'most',
57
+ 'mostly', 'must', 'never', 'new', 'next', 'none', 'nothing',
58
+ 'often', 'old', 'one', 'ones', 'others', 'part', 'per',
59
+ 'perhaps', 'put', 'quite', 'rather', 'really', 'right',
60
+ 'said', 'say', 'says', 'seem', 'seemed', 'seems', 'show',
61
+ 'since', 'something', 'still', 'take', 'taken', 'tell',
62
+ 'thing', 'things', 'think', 'three', 'thus', 'together',
63
+ 'told', 'took', 'toward', 'towards', 'try', 'turn', 'turned',
64
+ 'two', 'upon', 'use', 'used', 'using', 'want', 'wants',
65
+ 'way', 'ways', 'went', 'whether', 'within', 'without',
66
+ 'work', 'works', 'worked', 'working', 'year', 'years',
67
+ 'yet', 'also',
68
+ ]);
69
+ /**
70
+ * Resume-domain synonym map. Multi-word phrases and framework names are
71
+ * normalised to their canonical short forms. Keys are sorted by length
72
+ * descending at module load time so that longer phrases match first
73
+ * (e.g. "amazon web services" before "amazon").
74
+ */
75
+ export const SYNONYMS = {
76
+ // Cloud platforms (multi-word first)
77
+ 'amazon web services': 'aws',
78
+ 'google cloud platform': 'gcp',
79
+ // DevOps / CI-CD
80
+ 'continuous integration': 'ci',
81
+ 'continuous deployment': 'cd',
82
+ 'continuous delivery': 'cd',
83
+ // AI / ML
84
+ 'artificial intelligence': 'ai',
85
+ 'machine learning': 'ml',
86
+ // UX / UI
87
+ 'user experience': 'ux',
88
+ 'user interface': 'ui',
89
+ // Languages
90
+ 'javascript': 'js',
91
+ 'typescript': 'ts',
92
+ // Frameworks (dot-notation and concatenated forms)
93
+ 'react.js': 'react',
94
+ 'reactjs': 'react',
95
+ 'node.js': 'node',
96
+ 'nodejs': 'node',
97
+ 'vue.js': 'vue',
98
+ 'vuejs': 'vue',
99
+ 'next.js': 'next',
100
+ 'nextjs': 'next',
101
+ // Container orchestration
102
+ 'kubernetes': 'k8s',
103
+ };
104
+ /**
105
+ * Pre-sorted synonym keys (longest first) so multi-word synonyms are
106
+ * matched before their sub-strings.
107
+ */
108
+ const SORTED_SYNONYM_KEYS = Object.keys(SYNONYMS).sort((a, b) => b.length - a.length);
109
+ /**
110
+ * Action verb tiers for resume bullet quality assessment.
111
+ *
112
+ * - tier1: strong leadership / impact verbs
113
+ * - tier2: solid, active verbs
114
+ * - tier3: weak, passive, or vague verbs
115
+ */
116
+ export const VERB_TIERS = {
117
+ tier1: [
118
+ 'spearheaded',
119
+ 'orchestrated',
120
+ 'pioneered',
121
+ 'transformed',
122
+ 'revolutionized',
123
+ 'architected',
124
+ 'championed',
125
+ 'negotiated',
126
+ 'overhauled',
127
+ 'launched',
128
+ ],
129
+ tier2: [
130
+ 'managed',
131
+ 'developed',
132
+ 'implemented',
133
+ 'designed',
134
+ 'created',
135
+ 'built',
136
+ 'led',
137
+ 'established',
138
+ 'delivered',
139
+ 'improved',
140
+ 'optimized',
141
+ 'reduced',
142
+ 'increased',
143
+ 'automated',
144
+ 'streamlined',
145
+ 'coordinated',
146
+ 'directed',
147
+ 'executed',
148
+ 'analyzed',
149
+ 'resolved',
150
+ ],
151
+ tier3: [
152
+ 'helped',
153
+ 'assisted',
154
+ 'participated',
155
+ 'contributed',
156
+ 'supported',
157
+ 'worked',
158
+ 'responsible',
159
+ 'involved',
160
+ 'utilized',
161
+ 'handled',
162
+ ],
163
+ };
164
+ // ---------------------------------------------------------------------------
165
+ // Stem overrides — fixes for known Porter Stemmer issues
166
+ // ---------------------------------------------------------------------------
167
+ /**
168
+ * Words where the standard Porter Stemmer produces an incorrect or
169
+ * unhelpful result. Map from lowercase input to desired stem.
170
+ */
171
+ const STEM_OVERRIDES = {
172
+ // Porter strips trailing 's' from '-sis' words yielding '-si'
173
+ 'analysis': 'analysis',
174
+ 'basis': 'basis',
175
+ 'diagnosis': 'diagnosis',
176
+ 'synthesis': 'synthesis',
177
+ 'thesis': 'thesis',
178
+ 'hypothesis': 'hypothesis',
179
+ 'parenthesis': 'parenthesis',
180
+ 'emphasis': 'emphasis',
181
+ // Keep common tech acronyms intact
182
+ 'aws': 'aws',
183
+ 'gcp': 'gcp',
184
+ 'api': 'api',
185
+ 'apis': 'api',
186
+ 'css': 'css',
187
+ 'sql': 'sql',
188
+ 'html': 'html',
189
+ 'url': 'url',
190
+ 'urls': 'url',
191
+ // Ensure kubernetes and k8s stem to the same canonical form
192
+ 'kubernetes': 'k8s',
193
+ 'k8s': 'k8s',
194
+ };
195
+ // ---------------------------------------------------------------------------
196
+ // Public functions
197
+ // ---------------------------------------------------------------------------
198
+ /**
199
+ * Stem a single word using the Porter Stemmer, with overrides for known
200
+ * problem words. Input is lowercased before stemming.
201
+ */
202
+ export function stem(word) {
203
+ const lower = word.toLowerCase();
204
+ // Check overrides first
205
+ if (STEM_OVERRIDES[lower] !== undefined) {
206
+ return STEM_OVERRIDES[lower];
207
+ }
208
+ // Short words (<=3 chars) are unlikely to benefit from stemming and
209
+ // risk being mangled (e.g. "aws" -> "aw").
210
+ if (lower.length <= 3) {
211
+ return lower;
212
+ }
213
+ return porterStemmer.stem(lower);
214
+ }
215
+ /**
216
+ * Tokenize text into an array of lowercase word tokens.
217
+ * Returns an empty array for empty / whitespace-only input.
218
+ */
219
+ export function tokenize(text) {
220
+ const lower = text.toLowerCase();
221
+ const tokens = wordTokenizer.tokenize(lower);
222
+ return tokens ?? [];
223
+ }
224
+ /**
225
+ * Normalise text for matching: lowercase, trim, collapse whitespace,
226
+ * and apply synonym replacement. Synonyms are applied as whole-word
227
+ * replacements on the lowercased string before any tokenization.
228
+ *
229
+ * Multi-word synonyms are matched via simple `includes` + `replaceAll`,
230
+ * while single-word synonyms use regex word-boundary matching. Keys are
231
+ * processed longest-first to prevent partial matches.
232
+ */
233
+ export function normalise(text) {
234
+ // Lowercase, trim, collapse whitespace
235
+ let result = text.toLowerCase().trim().replace(/\s+/g, ' ');
236
+ // Apply synonyms longest-first
237
+ for (const key of SORTED_SYNONYM_KEYS) {
238
+ const value = SYNONYMS[key];
239
+ if (key.includes(' ')) {
240
+ // Multi-word synonym: simple string replacement
241
+ result = result.replaceAll(key, value);
242
+ }
243
+ else {
244
+ // Single-word synonym: word-boundary regex to avoid partial matches.
245
+ // Escape dots in keys like "react.js" for regex safety.
246
+ const escaped = key.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
247
+ const regex = new RegExp(`\\b${escaped}\\b`, 'g');
248
+ result = result.replace(regex, value);
249
+ }
250
+ }
251
+ // Re-collapse whitespace in case synonym replacement left gaps
252
+ result = result.trim().replace(/\s+/g, ' ');
253
+ return result;
254
+ }
255
+ /**
256
+ * Extract a set of search terms from text. The pipeline:
257
+ *
258
+ * 1. Normalise (lowercase + synonyms)
259
+ * 2. Tokenize
260
+ * 3. Filter out stop words
261
+ * 4. Build stemmed unigrams from the filtered list
262
+ * 5. Build raw bigrams from adjacent pairs in the filtered list
263
+ *
264
+ * Returns a Set containing both stemmed unigrams and raw bigrams.
265
+ */
266
+ export function extractTerms(text) {
267
+ const normalised = normalise(text);
268
+ const tokens = tokenize(normalised);
269
+ // Filter stop words
270
+ const filtered = tokens.filter((t) => !STOP_WORDS.has(t));
271
+ const terms = new Set();
272
+ // Add stemmed unigrams
273
+ for (const token of filtered) {
274
+ terms.add(stem(token));
275
+ }
276
+ // Add raw bigrams from adjacent filtered tokens
277
+ for (let i = 0; i < filtered.length - 1; i++) {
278
+ terms.add(`${filtered[i]} ${filtered[i + 1]}`);
279
+ }
280
+ return terms;
281
+ }
282
+ //# sourceMappingURL=text-utils.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"text-utils.js","sourceRoot":"","sources":["../../src/lib/text-utils.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,31 @@
1
+ export interface ResumeData {
2
+ rawText: string;
3
+ bullets: string[];
4
+ sections: string[];
5
+ }
6
+ export interface ATSResult {
7
+ score: number;
8
+ matched: string[];
9
+ missing: string[];
10
+ details: {
11
+ bigramsMatched: string[];
12
+ unigramsMatched: string[];
13
+ bigramsMissing: string[];
14
+ unigramsMissing: string[];
15
+ };
16
+ }
17
+ export interface ScoreDimension {
18
+ score: number;
19
+ weight: number;
20
+ weightedScore: number;
21
+ }
22
+ export type ScoreMode = 'with-jd' | 'without-jd';
23
+ export interface ResumeScore {
24
+ total: number;
25
+ mode: ScoreMode;
26
+ breakdown: Record<string, ScoreDimension>;
27
+ ats: ATSResult | null;
28
+ flags: string[];
29
+ }
30
+ export type VerbTier = 1 | 2 | 3 | null;
31
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/lib/types.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,UAAU;IACzB,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,EAAE,MAAM,EAAE,CAAC;IAClB,QAAQ,EAAE,MAAM,EAAE,CAAC;CACpB;AAED,MAAM,WAAW,SAAS;IACxB,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,EAAE,MAAM,EAAE,CAAC;IAClB,OAAO,EAAE,MAAM,EAAE,CAAC;IAClB,OAAO,EAAE;QACP,cAAc,EAAE,MAAM,EAAE,CAAC;QACzB,eAAe,EAAE,MAAM,EAAE,CAAC;QAC1B,cAAc,EAAE,MAAM,EAAE,CAAC;QACzB,eAAe,EAAE,MAAM,EAAE,CAAC;KAC3B,CAAC;CACH;AAED,MAAM,WAAW,cAAc;IAC7B,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,CAAC;IACf,aAAa,EAAE,MAAM,CAAC;CACvB;AAED,MAAM,MAAM,SAAS,GAAG,SAAS,GAAG,YAAY,CAAC;AAEjD,MAAM,WAAW,WAAW;IAC1B,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,SAAS,CAAC;IAChB,SAAS,EAAE,MAAM,CAAC,MAAM,EAAE,cAAc,CAAC,CAAC;IAC1C,GAAG,EAAE,SAAS,GAAG,IAAI,CAAC;IACtB,KAAK,EAAE,MAAM,EAAE,CAAC;CACjB;AAED,MAAM,MAAM,QAAQ,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,IAAI,CAAC"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/lib/types.ts"],"names":[],"mappings":""}
@@ -0,0 +1,31 @@
1
+ /**
2
+ * MCP server for the Krafter Resume Toolkit.
3
+ *
4
+ * Creates a Model Context Protocol server exposing resume scoring tools
5
+ * over stdio transport. The server registers all scoring tools at startup
6
+ * and is designed to be extended with additional tool categories (e.g.
7
+ * Krafter integration tools) in future tasks.
8
+ *
9
+ * Usage:
10
+ * import { startServer } from './server.js';
11
+ * await startServer();
12
+ */
13
+ import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
14
+ /**
15
+ * Create and configure the MCP server with all available tools.
16
+ *
17
+ * Scoring tools (score_resume, score_ats) are always registered.
18
+ * Additional tool categories (e.g. Krafter tools) will be registered
19
+ * conditionally in future tasks.
20
+ *
21
+ * @returns A configured {@link McpServer} instance ready to connect.
22
+ */
23
+ export declare function createServer(): McpServer;
24
+ /**
25
+ * Start the MCP server with stdio transport.
26
+ *
27
+ * This connects the server to stdin/stdout for communication with
28
+ * MCP clients (e.g. Claude Desktop, IDE extensions).
29
+ */
30
+ export declare function startServer(): Promise<void>;
31
+ //# sourceMappingURL=server.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../../src/mcp/server.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AACH,OAAO,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AAMpE;;;;;;;;GAQG;AACH,wBAAgB,YAAY,IAAI,SAAS,CA0CxC;AAED;;;;;GAKG;AACH,wBAAsB,WAAW,IAAI,OAAO,CAAC,IAAI,CAAC,CAIjD"}
@@ -0,0 +1,70 @@
1
+ /**
2
+ * MCP server for the Krafter Resume Toolkit.
3
+ *
4
+ * Creates a Model Context Protocol server exposing resume scoring tools
5
+ * over stdio transport. The server registers all scoring tools at startup
6
+ * and is designed to be extended with additional tool categories (e.g.
7
+ * Krafter integration tools) in future tasks.
8
+ *
9
+ * Usage:
10
+ * import { startServer } from './server.js';
11
+ * await startServer();
12
+ */
13
+ import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
14
+ import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js';
15
+ import { KrafterClient } from '../krafter/client.js';
16
+ import { getScoringTools } from './tools/scoring.js';
17
+ import { getKrafterTools } from './tools/krafter.js';
18
+ /**
19
+ * Create and configure the MCP server with all available tools.
20
+ *
21
+ * Scoring tools (score_resume, score_ats) are always registered.
22
+ * Additional tool categories (e.g. Krafter tools) will be registered
23
+ * conditionally in future tasks.
24
+ *
25
+ * @returns A configured {@link McpServer} instance ready to connect.
26
+ */
27
+ export function createServer() {
28
+ const server = new McpServer({
29
+ name: 'krafter-toolkit',
30
+ version: '1.0.0',
31
+ });
32
+ // Register scoring tools (always available).
33
+ // Uses the non-deprecated registerTool API which accepts a config object
34
+ // with an inputSchema (a Zod shape or full schema).
35
+ for (const tool of getScoringTools()) {
36
+ server.registerTool(tool.name, {
37
+ description: tool.description,
38
+ inputSchema: tool.inputSchema.shape,
39
+ }, async (args) => {
40
+ return tool.handler(args);
41
+ });
42
+ }
43
+ // Register Krafter tools when an API key is configured.
44
+ const apiKey = process.env['KRAFTER_API_KEY'];
45
+ if (apiKey) {
46
+ const baseUrl = process.env['KRAFTER_API_URL'];
47
+ const client = new KrafterClient(apiKey, baseUrl);
48
+ for (const tool of getKrafterTools(client)) {
49
+ server.registerTool(tool.name, {
50
+ description: tool.description,
51
+ inputSchema: tool.inputSchema.shape,
52
+ }, async (args) => {
53
+ return tool.handler(args);
54
+ });
55
+ }
56
+ }
57
+ return server;
58
+ }
59
+ /**
60
+ * Start the MCP server with stdio transport.
61
+ *
62
+ * This connects the server to stdin/stdout for communication with
63
+ * MCP clients (e.g. Claude Desktop, IDE extensions).
64
+ */
65
+ export async function startServer() {
66
+ const server = createServer();
67
+ const transport = new StdioServerTransport();
68
+ await server.connect(transport);
69
+ }
70
+ //# sourceMappingURL=server.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"server.js","sourceRoot":"","sources":["../../src/mcp/server.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AACH,OAAO,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AACpE,OAAO,EAAE,oBAAoB,EAAE,MAAM,2CAA2C,CAAC;AACjF,OAAO,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAC;AACrD,OAAO,EAAE,eAAe,EAAE,MAAM,oBAAoB,CAAC;AACrD,OAAO,EAAE,eAAe,EAAE,MAAM,oBAAoB,CAAC;AAErD;;;;;;;;GAQG;AACH,MAAM,UAAU,YAAY;IAC1B,MAAM,MAAM,GAAG,IAAI,SAAS,CAAC;QAC3B,IAAI,EAAE,iBAAiB;QACvB,OAAO,EAAE,OAAO;KACjB,CAAC,CAAC;IAEH,6CAA6C;IAC7C,yEAAyE;IACzE,oDAAoD;IACpD,KAAK,MAAM,IAAI,IAAI,eAAe,EAAE,EAAE,CAAC;QACrC,MAAM,CAAC,YAAY,CACjB,IAAI,CAAC,IAAI,EACT;YACE,WAAW,EAAE,IAAI,CAAC,WAAW;YAC7B,WAAW,EAAE,IAAI,CAAC,WAAW,CAAC,KAAK;SACpC,EACD,KAAK,EAAE,IAA6B,EAAE,EAAE;YACtC,OAAO,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC;QAC5B,CAAC,CACF,CAAC;IACJ,CAAC;IAED,wDAAwD;IACxD,MAAM,MAAM,GAAG,OAAO,CAAC,GAAG,CAAC,iBAAiB,CAAC,CAAC;IAC9C,IAAI,MAAM,EAAE,CAAC;QACX,MAAM,OAAO,GAAG,OAAO,CAAC,GAAG,CAAC,iBAAiB,CAAC,CAAC;QAC/C,MAAM,MAAM,GAAG,IAAI,aAAa,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;QAClD,KAAK,MAAM,IAAI,IAAI,eAAe,CAAC,MAAM,CAAC,EAAE,CAAC;YAC3C,MAAM,CAAC,YAAY,CACjB,IAAI,CAAC,IAAI,EACT;gBACE,WAAW,EAAE,IAAI,CAAC,WAAW;gBAC7B,WAAW,EAAE,IAAI,CAAC,WAAW,CAAC,KAAK;aACpC,EACD,KAAK,EAAE,IAA6B,EAAE,EAAE;gBACtC,OAAO,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC;YAC5B,CAAC,CACF,CAAC;QACJ,CAAC;IACH,CAAC;IAED,OAAO,MAAM,CAAC;AAChB,CAAC;AAED;;;;;GAKG;AACH,MAAM,CAAC,KAAK,UAAU,WAAW;IAC/B,MAAM,MAAM,GAAG,YAAY,EAAE,CAAC;IAC9B,MAAM,SAAS,GAAG,IAAI,oBAAoB,EAAE,CAAC;IAC7C,MAAM,MAAM,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC;AAClC,CAAC"}
@@ -0,0 +1,14 @@
1
+ import type { KrafterClient } from '../../krafter/client.js';
2
+ import type { ScoringTool } from './scoring.js';
3
+ /**
4
+ * Build and return the array of Krafter tool descriptors.
5
+ *
6
+ * Each tool wraps a {@link KrafterClient} method with MCP-formatted
7
+ * error handling. The tools use the same {@link ScoringTool} interface
8
+ * as the scoring tools so they can be registered uniformly.
9
+ *
10
+ * @param client - A configured {@link KrafterClient} instance.
11
+ * @returns An array of tool descriptors ready for MCP server registration.
12
+ */
13
+ export declare function getKrafterTools(client: KrafterClient): ScoringTool[];
14
+ //# sourceMappingURL=krafter.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"krafter.d.ts","sourceRoot":"","sources":["../../../src/mcp/tools/krafter.ts"],"names":[],"mappings":"AAYA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,yBAAyB,CAAC;AAI7D,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,cAAc,CAAC;AAgFhD;;;;;;;;;GASG;AACH,wBAAgB,eAAe,CAAC,MAAM,EAAE,aAAa,GAAG,WAAW,EAAE,CAkKpE"}