careermate 0.0.8 → 0.0.9
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/AGENTS.md +2 -2
- package/LICENSE +1 -1
- package/README.md +78 -81
- package/bin/careermate.mjs +11 -2
- package/dist/career-os/eop/cover-letter.md +10 -4
- package/dist/career-os/eop/interview-prep.md +1 -0
- package/dist/career-os/knowledge/cover-letter.md +4 -0
- package/dist/career-os/knowledge/verifiers/human-voice.md +7 -2
- package/dist/doctor.mjs +888 -340
- package/dist/mcp.mjs +904 -350
- package/dist/migrate.mjs +208 -16
- package/dist/public/i18n/en/applications.js +19 -0
- package/dist/public/i18n/en/common.js +6 -0
- package/dist/public/i18n/en/jobs.js +17 -0
- package/dist/public/i18n/en/settings.js +5 -2
- package/dist/public/i18n/ko/applications.js +19 -0
- package/dist/public/i18n/ko/common.js +5 -0
- package/dist/public/i18n/ko/jobs.js +17 -0
- package/dist/public/i18n/ko/settings.js +5 -2
- package/dist/public/lib.js +29 -0
- package/dist/public/pages/applications.js +86 -10
- package/dist/public/pages/documents.js +16 -7
- package/dist/public/pages/home.js +12 -0
- package/dist/public/pages/interview.js +11 -4
- package/dist/public/pages/jobs.js +71 -1
- package/dist/public/pages/settings.js +2 -2
- package/dist/public/styles.css +13 -0
- package/dist/web.mjs +544 -199
- package/docs/FAQ.md +13 -3
- package/docs/MCP_TOOLS.md +22 -9
- package/docs/career-os/eop/cover-letter.md +10 -4
- package/docs/career-os/eop/interview-prep.md +1 -0
- package/docs/career-os/knowledge/cover-letter.md +4 -0
- package/docs/career-os/knowledge/verifiers/human-voice.md +7 -2
- package/package.json +3 -1
- package/packages/core/src/index.ts +1 -0
- package/packages/core/src/jobsearch.ts +6 -2
- package/packages/core/src/offers.ts +41 -0
- package/packages/core/src/services.ts +5 -1
- package/packages/core/src/summary.ts +245 -19
- package/packages/db/src/connection.ts +70 -2
- package/packages/db/src/index.ts +1 -0
- package/packages/db/src/repositories.ts +140 -8
- package/packages/db/src/schema.ts +140 -8
- package/packages/mcp-tools/src/result.ts +9 -0
- package/packages/mcp-tools/src/tools.ts +143 -20
- package/packages/parsers/src/documents.ts +7 -1
- package/packages/prompts/src/humanize.ts +4 -0
- package/packages/shared/src/schemas.ts +134 -0
- package/scripts/init.ts +2 -0
package/dist/doctor.mjs
CHANGED
|
@@ -976,8 +976,8 @@ var init_tap = __esm({
|
|
|
976
976
|
});
|
|
977
977
|
|
|
978
978
|
// node_modules/underscore/modules/toPath.js
|
|
979
|
-
function toPath(
|
|
980
|
-
return isArray_default(
|
|
979
|
+
function toPath(path9) {
|
|
980
|
+
return isArray_default(path9) ? path9 : [path9];
|
|
981
981
|
}
|
|
982
982
|
var init_toPath = __esm({
|
|
983
983
|
"node_modules/underscore/modules/toPath.js"() {
|
|
@@ -989,8 +989,8 @@ var init_toPath = __esm({
|
|
|
989
989
|
});
|
|
990
990
|
|
|
991
991
|
// node_modules/underscore/modules/_toPath.js
|
|
992
|
-
function toPath2(
|
|
993
|
-
return _.toPath(
|
|
992
|
+
function toPath2(path9) {
|
|
993
|
+
return _.toPath(path9);
|
|
994
994
|
}
|
|
995
995
|
var init_toPath2 = __esm({
|
|
996
996
|
"node_modules/underscore/modules/_toPath.js"() {
|
|
@@ -1001,11 +1001,11 @@ var init_toPath2 = __esm({
|
|
|
1001
1001
|
});
|
|
1002
1002
|
|
|
1003
1003
|
// node_modules/underscore/modules/_deepGet.js
|
|
1004
|
-
function deepGet(obj2,
|
|
1005
|
-
var length =
|
|
1004
|
+
function deepGet(obj2, path9) {
|
|
1005
|
+
var length = path9.length;
|
|
1006
1006
|
for (var i2 = 0; i2 < length; i2++) {
|
|
1007
1007
|
if (obj2 == null) return void 0;
|
|
1008
|
-
obj2 = obj2[
|
|
1008
|
+
obj2 = obj2[path9[i2]];
|
|
1009
1009
|
}
|
|
1010
1010
|
return length ? obj2 : void 0;
|
|
1011
1011
|
}
|
|
@@ -1016,8 +1016,8 @@ var init_deepGet = __esm({
|
|
|
1016
1016
|
});
|
|
1017
1017
|
|
|
1018
1018
|
// node_modules/underscore/modules/get.js
|
|
1019
|
-
function get(object2,
|
|
1020
|
-
var value = deepGet(object2, toPath2(
|
|
1019
|
+
function get(object2, path9, defaultValue) {
|
|
1020
|
+
var value = deepGet(object2, toPath2(path9));
|
|
1021
1021
|
return isUndefined(value) ? defaultValue : value;
|
|
1022
1022
|
}
|
|
1023
1023
|
var init_get = __esm({
|
|
@@ -1030,11 +1030,11 @@ var init_get = __esm({
|
|
|
1030
1030
|
});
|
|
1031
1031
|
|
|
1032
1032
|
// node_modules/underscore/modules/has.js
|
|
1033
|
-
function has2(obj2,
|
|
1034
|
-
|
|
1035
|
-
var length =
|
|
1033
|
+
function has2(obj2, path9) {
|
|
1034
|
+
path9 = toPath2(path9);
|
|
1035
|
+
var length = path9.length;
|
|
1036
1036
|
for (var i2 = 0; i2 < length; i2++) {
|
|
1037
|
-
var key =
|
|
1037
|
+
var key = path9[i2];
|
|
1038
1038
|
if (!has(obj2, key)) return false;
|
|
1039
1039
|
obj2 = obj2[key];
|
|
1040
1040
|
}
|
|
@@ -1074,10 +1074,10 @@ var init_matcher = __esm({
|
|
|
1074
1074
|
});
|
|
1075
1075
|
|
|
1076
1076
|
// node_modules/underscore/modules/property.js
|
|
1077
|
-
function property(
|
|
1078
|
-
|
|
1077
|
+
function property(path9) {
|
|
1078
|
+
path9 = toPath2(path9);
|
|
1079
1079
|
return function(obj2) {
|
|
1080
|
-
return deepGet(obj2,
|
|
1080
|
+
return deepGet(obj2, path9);
|
|
1081
1081
|
};
|
|
1082
1082
|
}
|
|
1083
1083
|
var init_property = __esm({
|
|
@@ -1193,8 +1193,8 @@ var init_noop = __esm({
|
|
|
1193
1193
|
// node_modules/underscore/modules/propertyOf.js
|
|
1194
1194
|
function propertyOf(obj2) {
|
|
1195
1195
|
if (obj2 == null) return noop2;
|
|
1196
|
-
return function(
|
|
1197
|
-
return get(obj2,
|
|
1196
|
+
return function(path9) {
|
|
1197
|
+
return get(obj2, path9);
|
|
1198
1198
|
};
|
|
1199
1199
|
}
|
|
1200
1200
|
var init_propertyOf = __esm({
|
|
@@ -1342,7 +1342,7 @@ function template(text, settings, oldSettings) {
|
|
|
1342
1342
|
var index = 0;
|
|
1343
1343
|
var source = "__p+='";
|
|
1344
1344
|
text.replace(matcher2, function(match, escape2, interpolate, evaluate, offset) {
|
|
1345
|
-
source += text.slice(index, offset).replace(
|
|
1345
|
+
source += text.slice(index, offset).replace(escapeRegExp2, escapeChar);
|
|
1346
1346
|
index = offset + match.length;
|
|
1347
1347
|
if (escape2) {
|
|
1348
1348
|
source += "'+\n((__t=(" + escape2 + "))==null?'':_.escape(__t))+\n'";
|
|
@@ -1377,7 +1377,7 @@ function template(text, settings, oldSettings) {
|
|
|
1377
1377
|
template2.source = "function(" + argument + "){\n" + source + "}";
|
|
1378
1378
|
return template2;
|
|
1379
1379
|
}
|
|
1380
|
-
var noMatch, escapes,
|
|
1380
|
+
var noMatch, escapes, escapeRegExp2, bareIdentifier;
|
|
1381
1381
|
var init_template = __esm({
|
|
1382
1382
|
"node_modules/underscore/modules/template.js"() {
|
|
1383
1383
|
"use strict";
|
|
@@ -1393,20 +1393,20 @@ var init_template = __esm({
|
|
|
1393
1393
|
"\u2028": "u2028",
|
|
1394
1394
|
"\u2029": "u2029"
|
|
1395
1395
|
};
|
|
1396
|
-
|
|
1396
|
+
escapeRegExp2 = /\\|'|\r|\n|\u2028|\u2029/g;
|
|
1397
1397
|
bareIdentifier = /^\s*(\w|\$)+\s*$/;
|
|
1398
1398
|
}
|
|
1399
1399
|
});
|
|
1400
1400
|
|
|
1401
1401
|
// node_modules/underscore/modules/result.js
|
|
1402
|
-
function result(obj2,
|
|
1403
|
-
|
|
1404
|
-
var length =
|
|
1402
|
+
function result(obj2, path9, fallback) {
|
|
1403
|
+
path9 = toPath2(path9);
|
|
1404
|
+
var length = path9.length;
|
|
1405
1405
|
if (!length) {
|
|
1406
1406
|
return isFunction_default(fallback) ? fallback.call(obj2) : fallback;
|
|
1407
1407
|
}
|
|
1408
1408
|
for (var i2 = 0; i2 < length; i2++) {
|
|
1409
|
-
var prop = obj2 == null ? void 0 : obj2[
|
|
1409
|
+
var prop = obj2 == null ? void 0 : obj2[path9[i2]];
|
|
1410
1410
|
if (prop === void 0) {
|
|
1411
1411
|
prop = fallback;
|
|
1412
1412
|
i2 = length;
|
|
@@ -2130,14 +2130,14 @@ var init_invoke = __esm({
|
|
|
2130
2130
|
init_map();
|
|
2131
2131
|
init_deepGet();
|
|
2132
2132
|
init_toPath2();
|
|
2133
|
-
invoke_default = restArguments(function(obj2,
|
|
2133
|
+
invoke_default = restArguments(function(obj2, path9, args) {
|
|
2134
2134
|
var contextPath, func;
|
|
2135
|
-
if (isFunction_default(
|
|
2136
|
-
func =
|
|
2135
|
+
if (isFunction_default(path9)) {
|
|
2136
|
+
func = path9;
|
|
2137
2137
|
} else {
|
|
2138
|
-
|
|
2139
|
-
contextPath =
|
|
2140
|
-
|
|
2138
|
+
path9 = toPath2(path9);
|
|
2139
|
+
contextPath = path9.slice(0, -1);
|
|
2140
|
+
path9 = path9[path9.length - 1];
|
|
2141
2141
|
}
|
|
2142
2142
|
return map(obj2, function(context) {
|
|
2143
2143
|
var method = func;
|
|
@@ -2146,7 +2146,7 @@ var init_invoke = __esm({
|
|
|
2146
2146
|
context = deepGet(context, contextPath);
|
|
2147
2147
|
}
|
|
2148
2148
|
if (context == null) return void 0;
|
|
2149
|
-
method = context[
|
|
2149
|
+
method = context[path9];
|
|
2150
2150
|
}
|
|
2151
2151
|
return method == null ? method : method.apply(context, args);
|
|
2152
2152
|
});
|
|
@@ -11664,8 +11664,8 @@ var require_utils2 = __commonJS({
|
|
|
11664
11664
|
var result2 = transform[inputType][outputType](input);
|
|
11665
11665
|
return result2;
|
|
11666
11666
|
};
|
|
11667
|
-
exports2.resolve = function(
|
|
11668
|
-
var parts =
|
|
11667
|
+
exports2.resolve = function(path9) {
|
|
11668
|
+
var parts = path9.split("/");
|
|
11669
11669
|
var result2 = [];
|
|
11670
11670
|
for (var index = 0; index < parts.length; index++) {
|
|
11671
11671
|
var part = parts[index];
|
|
@@ -17518,18 +17518,18 @@ var require_object = __commonJS({
|
|
|
17518
17518
|
var object2 = new ZipObject(name, zipObjectContent, o);
|
|
17519
17519
|
this.files[name] = object2;
|
|
17520
17520
|
};
|
|
17521
|
-
var parentFolder = function(
|
|
17522
|
-
if (
|
|
17523
|
-
|
|
17521
|
+
var parentFolder = function(path9) {
|
|
17522
|
+
if (path9.slice(-1) === "/") {
|
|
17523
|
+
path9 = path9.substring(0, path9.length - 1);
|
|
17524
17524
|
}
|
|
17525
|
-
var lastSlash =
|
|
17526
|
-
return lastSlash > 0 ?
|
|
17525
|
+
var lastSlash = path9.lastIndexOf("/");
|
|
17526
|
+
return lastSlash > 0 ? path9.substring(0, lastSlash) : "";
|
|
17527
17527
|
};
|
|
17528
|
-
var forceTrailingSlash = function(
|
|
17529
|
-
if (
|
|
17530
|
-
|
|
17528
|
+
var forceTrailingSlash = function(path9) {
|
|
17529
|
+
if (path9.slice(-1) !== "/") {
|
|
17530
|
+
path9 += "/";
|
|
17531
17531
|
}
|
|
17532
|
-
return
|
|
17532
|
+
return path9;
|
|
17533
17533
|
};
|
|
17534
17534
|
var folderAdd = function(name, createFolders) {
|
|
17535
17535
|
createFolders = typeof createFolders !== "undefined" ? createFolders : defaults.createFolders;
|
|
@@ -18568,27 +18568,27 @@ var require_zipfile = __commonJS({
|
|
|
18568
18568
|
};
|
|
18569
18569
|
});
|
|
18570
18570
|
}
|
|
18571
|
-
function splitPath(
|
|
18572
|
-
var lastIndex =
|
|
18571
|
+
function splitPath(path9) {
|
|
18572
|
+
var lastIndex = path9.lastIndexOf("/");
|
|
18573
18573
|
if (lastIndex === -1) {
|
|
18574
|
-
return { dirname: "", basename:
|
|
18574
|
+
return { dirname: "", basename: path9 };
|
|
18575
18575
|
} else {
|
|
18576
18576
|
return {
|
|
18577
|
-
dirname:
|
|
18578
|
-
basename:
|
|
18577
|
+
dirname: path9.substring(0, lastIndex),
|
|
18578
|
+
basename: path9.substring(lastIndex + 1)
|
|
18579
18579
|
};
|
|
18580
18580
|
}
|
|
18581
18581
|
}
|
|
18582
18582
|
function joinPath() {
|
|
18583
|
-
var nonEmptyPaths = Array.prototype.filter.call(arguments, function(
|
|
18584
|
-
return
|
|
18583
|
+
var nonEmptyPaths = Array.prototype.filter.call(arguments, function(path9) {
|
|
18584
|
+
return path9;
|
|
18585
18585
|
});
|
|
18586
18586
|
var relevantPaths = [];
|
|
18587
|
-
nonEmptyPaths.forEach(function(
|
|
18588
|
-
if (/^\//.test(
|
|
18589
|
-
relevantPaths = [
|
|
18587
|
+
nonEmptyPaths.forEach(function(path9) {
|
|
18588
|
+
if (/^\//.test(path9)) {
|
|
18589
|
+
relevantPaths = [path9];
|
|
18590
18590
|
} else {
|
|
18591
|
-
relevantPaths.push(
|
|
18591
|
+
relevantPaths.push(path9);
|
|
18592
18592
|
}
|
|
18593
18593
|
});
|
|
18594
18594
|
return relevantPaths.join("/");
|
|
@@ -26013,9 +26013,9 @@ var require_office_xml_reader = __commonJS({
|
|
|
26013
26013
|
return collapseAlternateContent(document2)[0];
|
|
26014
26014
|
});
|
|
26015
26015
|
}
|
|
26016
|
-
function readXmlFromZipFile(docxFile,
|
|
26017
|
-
if (docxFile.exists(
|
|
26018
|
-
return docxFile.read(
|
|
26016
|
+
function readXmlFromZipFile(docxFile, path9) {
|
|
26017
|
+
if (docxFile.exists(path9)) {
|
|
26018
|
+
return docxFile.read(path9, "utf-8").then(stripUtf8Bom).then(read);
|
|
26019
26019
|
} else {
|
|
26020
26020
|
return promises.resolve(null);
|
|
26021
26021
|
}
|
|
@@ -27782,10 +27782,10 @@ var require_body_reader = __commonJS({
|
|
|
27782
27782
|
}
|
|
27783
27783
|
}
|
|
27784
27784
|
function findEmbeddedImageFile(relationshipId) {
|
|
27785
|
-
var
|
|
27785
|
+
var path9 = uris.uriToZipEntryName("word", relationships.findTargetByRelationshipId(relationshipId));
|
|
27786
27786
|
return {
|
|
27787
|
-
path:
|
|
27788
|
-
read: docxFile.read.bind(docxFile,
|
|
27787
|
+
path: path9,
|
|
27788
|
+
read: docxFile.read.bind(docxFile, path9)
|
|
27789
27789
|
};
|
|
27790
27790
|
}
|
|
27791
27791
|
function readImage(imageFile, altText) {
|
|
@@ -28025,12 +28025,12 @@ var require_content_types_reader = __commonJS({
|
|
|
28025
28025
|
}
|
|
28026
28026
|
function contentTypes(overrides, extensionDefaults) {
|
|
28027
28027
|
return {
|
|
28028
|
-
findContentType: function(
|
|
28029
|
-
var overrideContentType = overrides[
|
|
28028
|
+
findContentType: function(path9) {
|
|
28029
|
+
var overrideContentType = overrides[path9];
|
|
28030
28030
|
if (overrideContentType) {
|
|
28031
28031
|
return overrideContentType;
|
|
28032
28032
|
} else {
|
|
28033
|
-
var pathParts =
|
|
28033
|
+
var pathParts = path9.split(".");
|
|
28034
28034
|
var extension = pathParts[pathParts.length - 1];
|
|
28035
28035
|
if (extensionDefaults.hasOwnProperty(extension)) {
|
|
28036
28036
|
return extensionDefaults[extension];
|
|
@@ -28277,12 +28277,12 @@ var require_comments_reader = __commonJS({
|
|
|
28277
28277
|
var require_path_is_absolute = __commonJS({
|
|
28278
28278
|
"node_modules/path-is-absolute/index.js"(exports2, module2) {
|
|
28279
28279
|
"use strict";
|
|
28280
|
-
function posix(
|
|
28281
|
-
return
|
|
28280
|
+
function posix(path9) {
|
|
28281
|
+
return path9.charAt(0) === "/";
|
|
28282
28282
|
}
|
|
28283
|
-
function win32(
|
|
28283
|
+
function win32(path9) {
|
|
28284
28284
|
var splitDeviceRe = /^([a-zA-Z]:|[\\\/]{2}[^\\\/]+[\\\/]+[^\\\/]+)?([\\\/])?([\s\S]*?)$/;
|
|
28285
|
-
var result2 = splitDeviceRe.exec(
|
|
28285
|
+
var result2 = splitDeviceRe.exec(path9);
|
|
28286
28286
|
var device = result2[1] || "";
|
|
28287
28287
|
var isUnc = Boolean(device && device.charAt(1) !== ":");
|
|
28288
28288
|
return Boolean(result2[2] || isUnc);
|
|
@@ -28297,7 +28297,7 @@ var require_path_is_absolute = __commonJS({
|
|
|
28297
28297
|
var require_files = __commonJS({
|
|
28298
28298
|
"node_modules/mammoth/lib/docx/files.js"(exports2) {
|
|
28299
28299
|
"use strict";
|
|
28300
|
-
var
|
|
28300
|
+
var fs10 = __require("fs");
|
|
28301
28301
|
var url = __require("url");
|
|
28302
28302
|
var os3 = __require("os");
|
|
28303
28303
|
var dirname = __require("path").dirname;
|
|
@@ -28317,19 +28317,19 @@ var require_files = __commonJS({
|
|
|
28317
28317
|
}
|
|
28318
28318
|
var base = options.relativeToFile ? dirname(options.relativeToFile) : null;
|
|
28319
28319
|
function read(uri, encoding) {
|
|
28320
|
-
return resolveUri(uri).then(function(
|
|
28321
|
-
return readFile(
|
|
28320
|
+
return resolveUri(uri).then(function(path9) {
|
|
28321
|
+
return readFile(path9, encoding).caught(function(error) {
|
|
28322
28322
|
var message = "could not open external image: '" + uri + "' (document directory: '" + base + "')\n" + error.message;
|
|
28323
28323
|
return promises.reject(new Error(message));
|
|
28324
28324
|
});
|
|
28325
28325
|
});
|
|
28326
28326
|
}
|
|
28327
28327
|
function resolveUri(uri) {
|
|
28328
|
-
var
|
|
28329
|
-
if (isAbsolutePath(
|
|
28330
|
-
return promises.resolve(
|
|
28328
|
+
var path9 = uriToPath(uri);
|
|
28329
|
+
if (isAbsolutePath(path9)) {
|
|
28330
|
+
return promises.resolve(path9);
|
|
28331
28331
|
} else if (base) {
|
|
28332
|
-
return promises.resolve(resolvePath(base,
|
|
28332
|
+
return promises.resolve(resolvePath(base, path9));
|
|
28333
28333
|
} else {
|
|
28334
28334
|
return promises.reject(new Error("could not find external image '" + uri + "', path of input document is unknown"));
|
|
28335
28335
|
}
|
|
@@ -28338,18 +28338,18 @@ var require_files = __commonJS({
|
|
|
28338
28338
|
read
|
|
28339
28339
|
};
|
|
28340
28340
|
}
|
|
28341
|
-
var readFile = promises.promisify(
|
|
28341
|
+
var readFile = promises.promisify(fs10.readFile.bind(fs10));
|
|
28342
28342
|
function uriToPath(uriString, platform) {
|
|
28343
28343
|
if (!platform) {
|
|
28344
28344
|
platform = os3.platform();
|
|
28345
28345
|
}
|
|
28346
28346
|
var uri = url.parse(uriString);
|
|
28347
28347
|
if (isLocalFileUri(uri) || isRelativeUri(uri)) {
|
|
28348
|
-
var
|
|
28349
|
-
if (platform === "win32" && /^\/[a-z]:/i.test(
|
|
28350
|
-
return
|
|
28348
|
+
var path9 = decodeURIComponent(uri.path);
|
|
28349
|
+
if (platform === "win32" && /^\/[a-z]:/i.test(path9)) {
|
|
28350
|
+
return path9.slice(1);
|
|
28351
28351
|
} else {
|
|
28352
|
-
return
|
|
28352
|
+
return path9;
|
|
28353
28353
|
}
|
|
28354
28354
|
} else {
|
|
28355
28355
|
throw new Error("Could not convert URI to path: " + uriString);
|
|
@@ -28550,18 +28550,18 @@ var require_docx_reader = __commonJS({
|
|
|
28550
28550
|
readElement: contentTypesReader.readContentTypesFromXml,
|
|
28551
28551
|
defaultValue: contentTypesReader.defaultContentTypes
|
|
28552
28552
|
});
|
|
28553
|
-
function readNumberingFromZipFile(zipFile,
|
|
28553
|
+
function readNumberingFromZipFile(zipFile, path9, styles) {
|
|
28554
28554
|
return xmlFileReader({
|
|
28555
|
-
filename:
|
|
28555
|
+
filename: path9,
|
|
28556
28556
|
readElement: function(element) {
|
|
28557
28557
|
return numberingXml.readNumberingXml(element, { styles });
|
|
28558
28558
|
},
|
|
28559
28559
|
defaultValue: numberingXml.defaultNumbering
|
|
28560
28560
|
})(zipFile);
|
|
28561
28561
|
}
|
|
28562
|
-
function readStylesFromZipFile(zipFile,
|
|
28562
|
+
function readStylesFromZipFile(zipFile, path9) {
|
|
28563
28563
|
return xmlFileReader({
|
|
28564
|
-
filename:
|
|
28564
|
+
filename: path9,
|
|
28565
28565
|
readElement: stylesReader.readStylesXml,
|
|
28566
28566
|
defaultValue: stylesReader.defaultStyles
|
|
28567
28567
|
})(zipFile);
|
|
@@ -28593,10 +28593,10 @@ var require_style_map = __commonJS({
|
|
|
28593
28593
|
});
|
|
28594
28594
|
}
|
|
28595
28595
|
function updateRelationships(docxFile) {
|
|
28596
|
-
var
|
|
28596
|
+
var path9 = "word/_rels/document.xml.rels";
|
|
28597
28597
|
var relationshipsUri = "http://schemas.openxmlformats.org/package/2006/relationships";
|
|
28598
28598
|
var relationshipElementName = "{" + relationshipsUri + "}Relationship";
|
|
28599
|
-
return docxFile.read(
|
|
28599
|
+
return docxFile.read(path9, "utf8").then(xml.readString).then(function(relationshipsContainer) {
|
|
28600
28600
|
var relationships = relationshipsContainer.children;
|
|
28601
28601
|
addOrUpdateElement(relationships, relationshipElementName, "Id", {
|
|
28602
28602
|
"Id": "rMammothStyleMap",
|
|
@@ -28604,21 +28604,21 @@ var require_style_map = __commonJS({
|
|
|
28604
28604
|
"Target": styleMapAbsolutePath
|
|
28605
28605
|
});
|
|
28606
28606
|
var namespaces = { "": relationshipsUri };
|
|
28607
|
-
return docxFile.write(
|
|
28607
|
+
return docxFile.write(path9, xml.writeString(relationshipsContainer, namespaces));
|
|
28608
28608
|
});
|
|
28609
28609
|
}
|
|
28610
28610
|
function updateContentTypes(docxFile) {
|
|
28611
|
-
var
|
|
28611
|
+
var path9 = "[Content_Types].xml";
|
|
28612
28612
|
var contentTypesUri = "http://schemas.openxmlformats.org/package/2006/content-types";
|
|
28613
28613
|
var overrideName = "{" + contentTypesUri + "}Override";
|
|
28614
|
-
return docxFile.read(
|
|
28614
|
+
return docxFile.read(path9, "utf8").then(xml.readString).then(function(typesElement) {
|
|
28615
28615
|
var children = typesElement.children;
|
|
28616
28616
|
addOrUpdateElement(children, overrideName, "PartName", {
|
|
28617
28617
|
"PartName": styleMapAbsolutePath,
|
|
28618
28618
|
"ContentType": "text/prs.mammoth.style-map"
|
|
28619
28619
|
});
|
|
28620
28620
|
var namespaces = { "": contentTypesUri };
|
|
28621
|
-
return docxFile.write(
|
|
28621
|
+
return docxFile.write(path9, xml.writeString(typesElement, namespaces));
|
|
28622
28622
|
});
|
|
28623
28623
|
}
|
|
28624
28624
|
function addOrUpdateElement(elements, name, identifyingAttribute, attributes) {
|
|
@@ -29315,9 +29315,9 @@ var require_document_to_html = __commonJS({
|
|
|
29315
29315
|
};
|
|
29316
29316
|
var paths = [];
|
|
29317
29317
|
if (run.highlight !== null) {
|
|
29318
|
-
var
|
|
29319
|
-
if (
|
|
29320
|
-
paths.push(
|
|
29318
|
+
var path9 = findHtmlPath({ type: "highlight", color: run.highlight });
|
|
29319
|
+
if (path9) {
|
|
29320
|
+
paths.push(path9);
|
|
29321
29321
|
}
|
|
29322
29322
|
}
|
|
29323
29323
|
if (run.isSmallCaps) {
|
|
@@ -29352,15 +29352,15 @@ var require_document_to_html = __commonJS({
|
|
|
29352
29352
|
messages.push(unrecognisedStyleWarning("run", run));
|
|
29353
29353
|
}
|
|
29354
29354
|
paths.push(stylePath);
|
|
29355
|
-
paths.forEach(function(
|
|
29356
|
-
nodes =
|
|
29355
|
+
paths.forEach(function(path10) {
|
|
29356
|
+
nodes = path10.wrap.bind(path10, nodes);
|
|
29357
29357
|
});
|
|
29358
29358
|
return nodes();
|
|
29359
29359
|
}
|
|
29360
29360
|
function findHtmlPathForRunProperty(elementType, defaultTagName) {
|
|
29361
|
-
var
|
|
29362
|
-
if (
|
|
29363
|
-
return
|
|
29361
|
+
var path9 = findHtmlPath({ type: elementType });
|
|
29362
|
+
if (path9) {
|
|
29363
|
+
return path9;
|
|
29364
29364
|
} else if (defaultTagName) {
|
|
29365
29365
|
return htmlPaths.element(defaultTagName, {}, { fresh: false });
|
|
29366
29366
|
} else {
|
|
@@ -31080,11 +31080,11 @@ var require_options_reader = __commonJS({
|
|
|
31080
31080
|
var require_unzip = __commonJS({
|
|
31081
31081
|
"node_modules/mammoth/lib/unzip.js"(exports2) {
|
|
31082
31082
|
"use strict";
|
|
31083
|
-
var
|
|
31083
|
+
var fs10 = __require("fs");
|
|
31084
31084
|
var promises = require_promises();
|
|
31085
31085
|
var zipfile = require_zipfile();
|
|
31086
31086
|
exports2.openZip = openZip;
|
|
31087
|
-
var readFile = promises.promisify(
|
|
31087
|
+
var readFile = promises.promisify(fs10.readFile);
|
|
31088
31088
|
function openZip(options) {
|
|
31089
31089
|
if (options.path) {
|
|
31090
31090
|
return readFile(options.path).then(zipfile.openArrayBuffer);
|
|
@@ -31401,8 +31401,8 @@ var require_cjs = __commonJS({
|
|
|
31401
31401
|
return module3 = {
|
|
31402
31402
|
path: basedir,
|
|
31403
31403
|
exports: {},
|
|
31404
|
-
require: function(
|
|
31405
|
-
return commonjsRequire(
|
|
31404
|
+
require: function(path9, base) {
|
|
31405
|
+
return commonjsRequire(path9, base === void 0 || base === null ? module3.path : base);
|
|
31406
31406
|
}
|
|
31407
31407
|
}, fn(module3, module3.exports), module3.exports;
|
|
31408
31408
|
}
|
|
@@ -31809,9 +31809,9 @@ var require_cjs = __commonJS({
|
|
|
31809
31809
|
}
|
|
31810
31810
|
return o;
|
|
31811
31811
|
}
|
|
31812
|
-
var
|
|
31812
|
+
var fs10;
|
|
31813
31813
|
function get_fs() {
|
|
31814
|
-
return
|
|
31814
|
+
return fs10 || (fs10 = require$$0__default["default"]);
|
|
31815
31815
|
}
|
|
31816
31816
|
function parse2(file, options) {
|
|
31817
31817
|
if (file[0] == 80 && file[1] == 75) return parse_zip(file, options);
|
|
@@ -32096,7 +32096,7 @@ var require_cjs = __commonJS({
|
|
|
32096
32096
|
}
|
|
32097
32097
|
function read_file(filename2, options) {
|
|
32098
32098
|
get_fs();
|
|
32099
|
-
return parse2(
|
|
32099
|
+
return parse2(fs10.readFileSync(filename2), options);
|
|
32100
32100
|
}
|
|
32101
32101
|
function read(blob, options) {
|
|
32102
32102
|
switch (options && options.type || "base64") {
|
|
@@ -32362,7 +32362,7 @@ var require_cjs = __commonJS({
|
|
|
32362
32362
|
while (o.l < o.length) o.write_shift(1, 0);
|
|
32363
32363
|
return o;
|
|
32364
32364
|
}
|
|
32365
|
-
function find2(cfb2,
|
|
32365
|
+
function find2(cfb2, path9) {
|
|
32366
32366
|
var UCFullPaths = cfb2.FullPaths.map(function(x2) {
|
|
32367
32367
|
return x2.toUpperCase();
|
|
32368
32368
|
});
|
|
@@ -32371,11 +32371,11 @@ var require_cjs = __commonJS({
|
|
|
32371
32371
|
return y[y.length - (x2.slice(-1) == "/" ? 2 : 1)];
|
|
32372
32372
|
});
|
|
32373
32373
|
var k = false;
|
|
32374
|
-
if (
|
|
32374
|
+
if (path9.charCodeAt(0) === 47) {
|
|
32375
32375
|
k = true;
|
|
32376
|
-
|
|
32377
|
-
} else k =
|
|
32378
|
-
var UCPath =
|
|
32376
|
+
path9 = UCFullPaths[0].slice(0, -1) + path9;
|
|
32377
|
+
} else k = path9.indexOf("/") !== -1;
|
|
32378
|
+
var UCPath = path9.toUpperCase();
|
|
32379
32379
|
var w = k === true ? UCFullPaths.indexOf(UCPath) : UCPaths.indexOf(UCPath);
|
|
32380
32380
|
if (w !== -1) return cfb2.FileIndex[w];
|
|
32381
32381
|
var m = !UCPath.match(chr1);
|
|
@@ -32411,7 +32411,7 @@ var require_cjs = __commonJS({
|
|
|
32411
32411
|
function write_file(cfb2, filename2, options) {
|
|
32412
32412
|
get_fs();
|
|
32413
32413
|
var o = _write(cfb2, options);
|
|
32414
|
-
|
|
32414
|
+
fs10.writeFileSync(filename2, o);
|
|
32415
32415
|
}
|
|
32416
32416
|
function a2s(o) {
|
|
32417
32417
|
var out = new Array(o.length);
|
|
@@ -32423,7 +32423,7 @@ var require_cjs = __commonJS({
|
|
|
32423
32423
|
switch (options && options.type || "buffer") {
|
|
32424
32424
|
case "file":
|
|
32425
32425
|
get_fs();
|
|
32426
|
-
|
|
32426
|
+
fs10.writeFileSync(options.filename, o);
|
|
32427
32427
|
return o;
|
|
32428
32428
|
case "binary":
|
|
32429
32429
|
return typeof o == "string" ? o : a2s(o);
|
|
@@ -37848,8 +37848,8 @@ var require_cjs = __commonJS({
|
|
|
37848
37848
|
reader.readUInt16();
|
|
37849
37849
|
var id2 = reader.readUInt16();
|
|
37850
37850
|
var extension = reader.readString();
|
|
37851
|
-
var
|
|
37852
|
-
var payload = cfb.find(this.container,
|
|
37851
|
+
var path9 = "Root Entry/BinData/BIN".concat("".concat(id2.toString(16).toUpperCase()).padStart(4, "0"), ".").concat(extension);
|
|
37852
|
+
var payload = cfb.find(this.container, path9).content;
|
|
37853
37853
|
this.result.binData.push(new BinData(extension, pako_1.inflate(payload, {
|
|
37854
37854
|
windowBits: -15
|
|
37855
37855
|
})));
|
|
@@ -39982,33 +39982,33 @@ function renderRichText({
|
|
|
39982
39982
|
container.append(fragment);
|
|
39983
39983
|
}
|
|
39984
39984
|
function makePathFromDrawOPS(data) {
|
|
39985
|
-
const
|
|
39985
|
+
const path9 = new Path2D();
|
|
39986
39986
|
if (!data) {
|
|
39987
|
-
return
|
|
39987
|
+
return path9;
|
|
39988
39988
|
}
|
|
39989
39989
|
for (let i2 = 0, ii = data.length; i2 < ii; ) {
|
|
39990
39990
|
switch (data[i2++]) {
|
|
39991
39991
|
case DrawOPS.moveTo:
|
|
39992
|
-
|
|
39992
|
+
path9.moveTo(data[i2++], data[i2++]);
|
|
39993
39993
|
break;
|
|
39994
39994
|
case DrawOPS.lineTo:
|
|
39995
|
-
|
|
39995
|
+
path9.lineTo(data[i2++], data[i2++]);
|
|
39996
39996
|
break;
|
|
39997
39997
|
case DrawOPS.curveTo:
|
|
39998
|
-
|
|
39998
|
+
path9.bezierCurveTo(data[i2++], data[i2++], data[i2++], data[i2++], data[i2++], data[i2++]);
|
|
39999
39999
|
break;
|
|
40000
40000
|
case DrawOPS.quadraticCurveTo:
|
|
40001
|
-
|
|
40001
|
+
path9.quadraticCurveTo(data[i2++], data[i2++], data[i2++], data[i2++]);
|
|
40002
40002
|
break;
|
|
40003
40003
|
case DrawOPS.closePath:
|
|
40004
|
-
|
|
40004
|
+
path9.closePath();
|
|
40005
40005
|
break;
|
|
40006
40006
|
default:
|
|
40007
40007
|
warn(`Unrecognized drawing path operator: ${data[i2 - 1]}`);
|
|
40008
40008
|
break;
|
|
40009
40009
|
}
|
|
40010
40010
|
}
|
|
40011
|
-
return
|
|
40011
|
+
return path9;
|
|
40012
40012
|
}
|
|
40013
40013
|
function bindEvents(obj2, element, names) {
|
|
40014
40014
|
for (const name of names) {
|
|
@@ -40116,8 +40116,8 @@ function blend(fg, bg, alpha) {
|
|
|
40116
40116
|
return Math.round(alpha * fg + (1 - alpha) * bg);
|
|
40117
40117
|
}
|
|
40118
40118
|
async function node_utils_fetchData(url) {
|
|
40119
|
-
const
|
|
40120
|
-
const data = await
|
|
40119
|
+
const fs10 = process.getBuiltinModule("fs/promises");
|
|
40120
|
+
const data = await fs10.readFile(url);
|
|
40121
40121
|
return new Uint8Array(data);
|
|
40122
40122
|
}
|
|
40123
40123
|
function initGPU() {
|
|
@@ -40746,11 +40746,11 @@ function network_getArrayBuffer(val) {
|
|
|
40746
40746
|
return typeof val !== "string" ? val : stringToBytes(val).buffer;
|
|
40747
40747
|
}
|
|
40748
40748
|
function getReadableStream(url, opts = null) {
|
|
40749
|
-
const
|
|
40749
|
+
const fs10 = process.getBuiltinModule("fs");
|
|
40750
40750
|
const {
|
|
40751
40751
|
Readable
|
|
40752
40752
|
} = process.getBuiltinModule("stream");
|
|
40753
|
-
const readStream =
|
|
40753
|
+
const readStream = fs10.createReadStream(url, opts);
|
|
40754
40754
|
return Readable.toWeb(readStream);
|
|
40755
40755
|
}
|
|
40756
40756
|
function getNetworkStream(url) {
|
|
@@ -52554,11 +52554,11 @@ var init_pdf = __esm({
|
|
|
52554
52554
|
} catch (ex) {
|
|
52555
52555
|
warn(`getPathGenerator - ignoring character: "${ex}".`);
|
|
52556
52556
|
}
|
|
52557
|
-
const
|
|
52557
|
+
const path9 = makePathFromDrawOPS(cmds?.path);
|
|
52558
52558
|
if (!this.fontExtraProperties) {
|
|
52559
52559
|
objs.delete(objId);
|
|
52560
52560
|
}
|
|
52561
|
-
return this.compiledGlyphs[character] =
|
|
52561
|
+
return this.compiledGlyphs[character] = path9;
|
|
52562
52562
|
}
|
|
52563
52563
|
get black() {
|
|
52564
52564
|
return this.#fontData.black;
|
|
@@ -54456,7 +54456,7 @@ fn fs_main(in : VertexOutput) -> @location(0) vec4<f32> {
|
|
|
54456
54456
|
Util.singularValueDecompose2dScale(this.baseTransform, scale);
|
|
54457
54457
|
return [matrixScaleX * scale[0], matrixScaleY * scale[1]];
|
|
54458
54458
|
}
|
|
54459
|
-
drawPattern(owner,
|
|
54459
|
+
drawPattern(owner, path9, useEOFill = false, [n, m], opIdx) {
|
|
54460
54460
|
const [x0, y0, x1, y1] = this.bbox;
|
|
54461
54461
|
const dependencyTracker = owner.dependencyTracker;
|
|
54462
54462
|
if (dependencyTracker) {
|
|
@@ -54464,9 +54464,9 @@ fn fs_main(in : VertexOutput) -> @location(0) vec4<f32> {
|
|
|
54464
54464
|
}
|
|
54465
54465
|
owner.save();
|
|
54466
54466
|
if (useEOFill) {
|
|
54467
|
-
owner.ctx.clip(
|
|
54467
|
+
owner.ctx.clip(path9, "evenodd");
|
|
54468
54468
|
} else {
|
|
54469
|
-
owner.ctx.clip(
|
|
54469
|
+
owner.ctx.clip(path9);
|
|
54470
54470
|
}
|
|
54471
54471
|
owner.ctx.setTransform(...this.patternBaseMatrix);
|
|
54472
54472
|
owner.ctx.translate(n * this.xstep, m * this.ystep);
|
|
@@ -55561,15 +55561,15 @@ fn fs_main(in : VertexOutput) -> @location(0) vec4<f32> {
|
|
|
55561
55561
|
if (hasInnerCutout && maskX0 === layerOffsetX && maskY0 === layerOffsetY && maskX1 === layerOffsetX + layerWidth && maskY1 === layerOffsetY + layerHeight) {
|
|
55562
55562
|
return;
|
|
55563
55563
|
}
|
|
55564
|
-
const
|
|
55565
|
-
|
|
55564
|
+
const path9 = new Path2D();
|
|
55565
|
+
path9.rect(layerOffsetX, layerOffsetY, layerWidth, layerHeight);
|
|
55566
55566
|
if (hasInnerCutout) {
|
|
55567
|
-
|
|
55567
|
+
path9.rect(maskX0, maskY0, maskX1 - maskX0, maskY1 - maskY0);
|
|
55568
55568
|
}
|
|
55569
55569
|
layerCtx.save();
|
|
55570
55570
|
layerCtx.globalAlpha = alpha / 255;
|
|
55571
55571
|
layerCtx.setTransform(1, 0, 0, 1, 0, 0);
|
|
55572
|
-
layerCtx.clip(
|
|
55572
|
+
layerCtx.clip(path9, "evenodd");
|
|
55573
55573
|
layerCtx.globalCompositeOperation = "destination-in";
|
|
55574
55574
|
layerCtx.fillStyle = "#000000";
|
|
55575
55575
|
layerCtx.fillRect(layerOffsetX, layerOffsetY, layerWidth, layerHeight);
|
|
@@ -55627,21 +55627,21 @@ fn fs_main(in : VertexOutput) -> @location(0) vec4<f32> {
|
|
|
55627
55627
|
this._cachedGetSinglePixelWidth = null;
|
|
55628
55628
|
}
|
|
55629
55629
|
constructPath(opIdx, op, data, minMax) {
|
|
55630
|
-
let [
|
|
55630
|
+
let [path9] = data;
|
|
55631
55631
|
if (!minMax) {
|
|
55632
|
-
|
|
55632
|
+
path9 ||= data[0] = new Path2D();
|
|
55633
55633
|
if (op !== OPS.stroke && op !== OPS.closeStroke) {
|
|
55634
55634
|
this.current.tilingPatternDims = null;
|
|
55635
55635
|
}
|
|
55636
|
-
this[op](opIdx,
|
|
55636
|
+
this[op](opIdx, path9);
|
|
55637
55637
|
return;
|
|
55638
55638
|
}
|
|
55639
55639
|
if (this.dependencyTracker !== null) {
|
|
55640
55640
|
const outerExtraSize = op === OPS.stroke ? this.current.lineWidth / 2 : 0;
|
|
55641
55641
|
this.dependencyTracker.resetBBox(opIdx).recordBBox(opIdx, this.ctx, minMax[0] - outerExtraSize, minMax[2] + outerExtraSize, minMax[1] - outerExtraSize, minMax[3] + outerExtraSize).recordDependencies(opIdx, ["transform"]);
|
|
55642
55642
|
}
|
|
55643
|
-
if (!(
|
|
55644
|
-
|
|
55643
|
+
if (!(path9 instanceof Path2D)) {
|
|
55644
|
+
path9 = data[0] = makePathFromDrawOPS(path9);
|
|
55645
55645
|
}
|
|
55646
55646
|
Util.axialAlignedBoundingBox(minMax, getCurrentTransform(this.ctx), this.current.minMax);
|
|
55647
55647
|
const tilingDims = this.current.tilingPatternDims;
|
|
@@ -55653,13 +55653,13 @@ fn fs_main(in : VertexOutput) -> @location(0) vec4<f32> {
|
|
|
55653
55653
|
this.current.fillColor.updatePatternDims(clippedBBox, tilingDims);
|
|
55654
55654
|
}
|
|
55655
55655
|
}
|
|
55656
|
-
this[op](opIdx,
|
|
55656
|
+
this[op](opIdx, path9);
|
|
55657
55657
|
this._pathStartIdx = opIdx;
|
|
55658
55658
|
}
|
|
55659
55659
|
closePath(opIdx) {
|
|
55660
55660
|
this.ctx.closePath();
|
|
55661
55661
|
}
|
|
55662
|
-
stroke(opIdx,
|
|
55662
|
+
stroke(opIdx, path9, consumePath = true) {
|
|
55663
55663
|
const started = consumePath && this.#beginKnockoutElement(this.current.strokeAlpha);
|
|
55664
55664
|
const ctx = this.ctx;
|
|
55665
55665
|
const strokeColor = this.current.strokeColor;
|
|
@@ -55671,26 +55671,26 @@ fn fs_main(in : VertexOutput) -> @location(0) vec4<f32> {
|
|
|
55671
55671
|
ctx.strokeStyle = strokeColor.getPattern(ctx, this, getCurrentTransformInverse(ctx), PathType.STROKE, opIdx);
|
|
55672
55672
|
if (baseTransform) {
|
|
55673
55673
|
const newPath = new Path2D();
|
|
55674
|
-
newPath.addPath(
|
|
55675
|
-
|
|
55674
|
+
newPath.addPath(path9, ctx.getTransform().invertSelf().multiplySelf(baseTransform));
|
|
55675
|
+
path9 = newPath;
|
|
55676
55676
|
}
|
|
55677
|
-
this.rescaleAndStroke(
|
|
55677
|
+
this.rescaleAndStroke(path9, false);
|
|
55678
55678
|
ctx.restore();
|
|
55679
55679
|
} else {
|
|
55680
|
-
this.rescaleAndStroke(
|
|
55680
|
+
this.rescaleAndStroke(path9, true);
|
|
55681
55681
|
}
|
|
55682
55682
|
}
|
|
55683
55683
|
this.dependencyTracker?.recordDependencies(opIdx, Dependencies.stroke);
|
|
55684
55684
|
if (consumePath) {
|
|
55685
|
-
this.consumePath(opIdx,
|
|
55685
|
+
this.consumePath(opIdx, path9, this.current.getClippedPathBoundingBox(PathType.STROKE, getCurrentTransform(this.ctx)));
|
|
55686
55686
|
}
|
|
55687
55687
|
ctx.globalAlpha = this.current.fillAlpha;
|
|
55688
55688
|
this.#endKnockoutElement(started);
|
|
55689
55689
|
}
|
|
55690
|
-
closeStroke(opIdx,
|
|
55691
|
-
this.stroke(opIdx,
|
|
55690
|
+
closeStroke(opIdx, path9) {
|
|
55691
|
+
this.stroke(opIdx, path9);
|
|
55692
55692
|
}
|
|
55693
|
-
fill(opIdx,
|
|
55693
|
+
fill(opIdx, path9, consumePath = true) {
|
|
55694
55694
|
const started = consumePath && this.#beginKnockoutElement(this.current.fillAlpha);
|
|
55695
55695
|
const ctx = this.ctx;
|
|
55696
55696
|
const fillColor = this.current.fillColor;
|
|
@@ -55702,10 +55702,10 @@ fn fs_main(in : VertexOutput) -> @location(0) vec4<f32> {
|
|
|
55702
55702
|
const dims = this.current.tilingPatternDims;
|
|
55703
55703
|
const tileIdx = dims && fillColor.canSkipPatternCanvas(dims);
|
|
55704
55704
|
if (tileIdx) {
|
|
55705
|
-
fillColor.drawPattern(this,
|
|
55705
|
+
fillColor.drawPattern(this, path9, this.pendingEOFill, tileIdx, opIdx);
|
|
55706
55706
|
this.pendingEOFill = false;
|
|
55707
55707
|
if (consumePath) {
|
|
55708
|
-
this.consumePath(opIdx,
|
|
55708
|
+
this.consumePath(opIdx, path9, intersect);
|
|
55709
55709
|
}
|
|
55710
55710
|
this.current.tilingPatternDims = null;
|
|
55711
55711
|
this.#endKnockoutElement(started);
|
|
@@ -55717,17 +55717,17 @@ fn fs_main(in : VertexOutput) -> @location(0) vec4<f32> {
|
|
|
55717
55717
|
ctx.fillStyle = fillColor.getPattern(ctx, this, getCurrentTransformInverse(ctx), PathType.FILL, opIdx);
|
|
55718
55718
|
if (baseTransform) {
|
|
55719
55719
|
const newPath = new Path2D();
|
|
55720
|
-
newPath.addPath(
|
|
55721
|
-
|
|
55720
|
+
newPath.addPath(path9, ctx.getTransform().invertSelf().multiplySelf(baseTransform));
|
|
55721
|
+
path9 = newPath;
|
|
55722
55722
|
}
|
|
55723
55723
|
needRestore = true;
|
|
55724
55724
|
}
|
|
55725
55725
|
if (this.contentVisible && intersect !== null) {
|
|
55726
55726
|
if (this.pendingEOFill) {
|
|
55727
|
-
ctx.fill(
|
|
55727
|
+
ctx.fill(path9, "evenodd");
|
|
55728
55728
|
this.pendingEOFill = false;
|
|
55729
55729
|
} else {
|
|
55730
|
-
ctx.fill(
|
|
55730
|
+
ctx.fill(path9);
|
|
55731
55731
|
}
|
|
55732
55732
|
}
|
|
55733
55733
|
if (needRestore) {
|
|
@@ -55735,38 +55735,38 @@ fn fs_main(in : VertexOutput) -> @location(0) vec4<f32> {
|
|
|
55735
55735
|
this.dependencyTracker?.restore(opIdx);
|
|
55736
55736
|
}
|
|
55737
55737
|
if (consumePath) {
|
|
55738
|
-
this.consumePath(opIdx,
|
|
55738
|
+
this.consumePath(opIdx, path9, intersect);
|
|
55739
55739
|
}
|
|
55740
55740
|
this.#endKnockoutElement(started);
|
|
55741
55741
|
}
|
|
55742
|
-
eoFill(opIdx,
|
|
55742
|
+
eoFill(opIdx, path9) {
|
|
55743
55743
|
this.pendingEOFill = true;
|
|
55744
|
-
this.fill(opIdx,
|
|
55744
|
+
this.fill(opIdx, path9);
|
|
55745
55745
|
}
|
|
55746
|
-
fillStroke(opIdx,
|
|
55746
|
+
fillStroke(opIdx, path9) {
|
|
55747
55747
|
const started = this.#beginKnockoutElement(Math.min(this.current.fillAlpha, this.current.strokeAlpha));
|
|
55748
|
-
this.fill(opIdx,
|
|
55749
|
-
this.stroke(opIdx,
|
|
55750
|
-
this.consumePath(opIdx,
|
|
55748
|
+
this.fill(opIdx, path9, false);
|
|
55749
|
+
this.stroke(opIdx, path9, false);
|
|
55750
|
+
this.consumePath(opIdx, path9);
|
|
55751
55751
|
this.#endKnockoutElement(started);
|
|
55752
55752
|
}
|
|
55753
|
-
eoFillStroke(opIdx,
|
|
55753
|
+
eoFillStroke(opIdx, path9) {
|
|
55754
55754
|
this.pendingEOFill = true;
|
|
55755
|
-
this.fillStroke(opIdx,
|
|
55755
|
+
this.fillStroke(opIdx, path9);
|
|
55756
55756
|
}
|
|
55757
|
-
closeFillStroke(opIdx,
|
|
55758
|
-
this.fillStroke(opIdx,
|
|
55757
|
+
closeFillStroke(opIdx, path9) {
|
|
55758
|
+
this.fillStroke(opIdx, path9);
|
|
55759
55759
|
}
|
|
55760
|
-
closeEOFillStroke(opIdx,
|
|
55760
|
+
closeEOFillStroke(opIdx, path9) {
|
|
55761
55761
|
this.pendingEOFill = true;
|
|
55762
|
-
this.fillStroke(opIdx,
|
|
55762
|
+
this.fillStroke(opIdx, path9);
|
|
55763
55763
|
}
|
|
55764
|
-
endPath(opIdx,
|
|
55765
|
-
this.consumePath(opIdx,
|
|
55764
|
+
endPath(opIdx, path9) {
|
|
55765
|
+
this.consumePath(opIdx, path9);
|
|
55766
55766
|
}
|
|
55767
|
-
rawFillPath(opIdx,
|
|
55767
|
+
rawFillPath(opIdx, path9) {
|
|
55768
55768
|
const started = this.#beginKnockoutElement(this.current.fillAlpha);
|
|
55769
|
-
this.ctx.fill(
|
|
55769
|
+
this.ctx.fill(path9);
|
|
55770
55770
|
this.dependencyTracker?.recordDependencies(opIdx, Dependencies.rawFillPath).recordOperation(opIdx);
|
|
55771
55771
|
this.#endKnockoutElement(started);
|
|
55772
55772
|
}
|
|
@@ -55805,12 +55805,12 @@ fn fs_main(in : VertexOutput) -> @location(0) vec4<f32> {
|
|
|
55805
55805
|
x: x2,
|
|
55806
55806
|
y,
|
|
55807
55807
|
fontSize,
|
|
55808
|
-
path:
|
|
55808
|
+
path: path9
|
|
55809
55809
|
} of paths) {
|
|
55810
|
-
if (!
|
|
55810
|
+
if (!path9) {
|
|
55811
55811
|
continue;
|
|
55812
55812
|
}
|
|
55813
|
-
newPath.addPath(
|
|
55813
|
+
newPath.addPath(path9, new DOMMatrix(transform).preMultiplySelf(invTransf).translate(x2, y).scale(fontSize, -fontSize));
|
|
55814
55814
|
}
|
|
55815
55815
|
ctx.clip(newPath);
|
|
55816
55816
|
}
|
|
@@ -55903,9 +55903,9 @@ fn fs_main(in : VertexOutput) -> @location(0) vec4<f32> {
|
|
|
55903
55903
|
this.moveText(opIdx, 0, this.current.leading);
|
|
55904
55904
|
this.dependencyTracker?.recordIncrementalData("moveText", this.dependencyTracker.getSimpleIndex("leading") ?? opIdx);
|
|
55905
55905
|
}
|
|
55906
|
-
#getScaledPath(
|
|
55906
|
+
#getScaledPath(path9, currentTransform, transform) {
|
|
55907
55907
|
const newPath = new Path2D();
|
|
55908
|
-
newPath.addPath(
|
|
55908
|
+
newPath.addPath(path9, new DOMMatrix(transform).invertSelf().multiplySelf(currentTransform));
|
|
55909
55909
|
return newPath;
|
|
55910
55910
|
}
|
|
55911
55911
|
paintChar(opIdx, character, x2, y, patternFillTransform, patternStrokeTransform) {
|
|
@@ -55918,11 +55918,11 @@ fn fs_main(in : VertexOutput) -> @location(0) vec4<f32> {
|
|
|
55918
55918
|
const isAddToPathSet = !!(textRenderingMode & TextRenderingMode.ADD_TO_PATH_FLAG);
|
|
55919
55919
|
const patternFill = current.patternFill && !font.missingFile;
|
|
55920
55920
|
const patternStroke = current.patternStroke && !font.missingFile;
|
|
55921
|
-
let
|
|
55921
|
+
let path9;
|
|
55922
55922
|
if ((font.disableFontFace || isAddToPathSet || patternFill || patternStroke) && !font.missingFile) {
|
|
55923
|
-
|
|
55923
|
+
path9 = font.getPathGenerator(this.commonObjs, character);
|
|
55924
55924
|
}
|
|
55925
|
-
if (
|
|
55925
|
+
if (path9 && (font.disableFontFace || patternFill || patternStroke)) {
|
|
55926
55926
|
ctx.save();
|
|
55927
55927
|
ctx.translate(x2, y);
|
|
55928
55928
|
ctx.scale(fontSize, -fontSize);
|
|
@@ -55932,10 +55932,10 @@ fn fs_main(in : VertexOutput) -> @location(0) vec4<f32> {
|
|
|
55932
55932
|
if (patternFillTransform) {
|
|
55933
55933
|
currentTransform = ctx.getTransform();
|
|
55934
55934
|
ctx.setTransform(...patternFillTransform);
|
|
55935
|
-
const scaledPath = this.#getScaledPath(
|
|
55935
|
+
const scaledPath = this.#getScaledPath(path9, currentTransform, patternFillTransform);
|
|
55936
55936
|
ctx.fill(scaledPath);
|
|
55937
55937
|
} else {
|
|
55938
|
-
ctx.fill(
|
|
55938
|
+
ctx.fill(path9);
|
|
55939
55939
|
}
|
|
55940
55940
|
}
|
|
55941
55941
|
if (fillStrokeMode === TextRenderingMode.STROKE || fillStrokeMode === TextRenderingMode.FILL_STROKE) {
|
|
@@ -55952,10 +55952,10 @@ fn fs_main(in : VertexOutput) -> @location(0) vec4<f32> {
|
|
|
55952
55952
|
const transf = Util.transform([a, b, c, d, 0, 0], invPatternTransform);
|
|
55953
55953
|
Util.singularValueDecompose2dScale(transf, XY);
|
|
55954
55954
|
ctx.lineWidth *= Math.max(XY[0], XY[1]) / fontSize;
|
|
55955
|
-
ctx.stroke(this.#getScaledPath(
|
|
55955
|
+
ctx.stroke(this.#getScaledPath(path9, currentTransform, patternStrokeTransform));
|
|
55956
55956
|
} else {
|
|
55957
55957
|
ctx.lineWidth /= fontSize;
|
|
55958
|
-
ctx.stroke(
|
|
55958
|
+
ctx.stroke(path9);
|
|
55959
55959
|
}
|
|
55960
55960
|
}
|
|
55961
55961
|
ctx.restore();
|
|
@@ -55978,7 +55978,7 @@ fn fs_main(in : VertexOutput) -> @location(0) vec4<f32> {
|
|
|
55978
55978
|
x: x2,
|
|
55979
55979
|
y,
|
|
55980
55980
|
fontSize,
|
|
55981
|
-
path:
|
|
55981
|
+
path: path9
|
|
55982
55982
|
});
|
|
55983
55983
|
this.dependencyTracker?.recordCharacterBBox(opIdx, ctx, font, fontSize, x2, y);
|
|
55984
55984
|
}
|
|
@@ -56374,9 +56374,9 @@ fn fs_main(in : VertexOutput) -> @location(0) vec4<f32> {
|
|
|
56374
56374
|
const [x0, y0, x1, y1] = group2.bbox;
|
|
56375
56375
|
clip.rect(x0, y0, x1 - x0, y1 - y0);
|
|
56376
56376
|
if (group2.matrix) {
|
|
56377
|
-
const
|
|
56378
|
-
|
|
56379
|
-
clip =
|
|
56377
|
+
const path9 = new Path2D();
|
|
56378
|
+
path9.addPath(clip, new DOMMatrix(group2.matrix));
|
|
56379
|
+
clip = path9;
|
|
56380
56380
|
}
|
|
56381
56381
|
currentCtx.clip(clip);
|
|
56382
56382
|
}
|
|
@@ -56430,9 +56430,9 @@ fn fs_main(in : VertexOutput) -> @location(0) vec4<f32> {
|
|
|
56430
56430
|
const [x0, y0, x1, y1] = group2.bbox;
|
|
56431
56431
|
clip.rect(x0, y0, x1 - x0, y1 - y0);
|
|
56432
56432
|
if (group2.matrix) {
|
|
56433
|
-
const
|
|
56434
|
-
|
|
56435
|
-
clip =
|
|
56433
|
+
const path9 = new Path2D();
|
|
56434
|
+
path9.addPath(clip, new DOMMatrix(group2.matrix));
|
|
56435
|
+
clip = path9;
|
|
56436
56436
|
}
|
|
56437
56437
|
groupCtx.clip(clip);
|
|
56438
56438
|
}
|
|
@@ -56911,7 +56911,7 @@ fn fs_main(in : VertexOutput) -> @location(0) vec4<f32> {
|
|
|
56911
56911
|
}
|
|
56912
56912
|
endCompat(opIdx) {
|
|
56913
56913
|
}
|
|
56914
|
-
consumePath(opIdx,
|
|
56914
|
+
consumePath(opIdx, path9, clipBox) {
|
|
56915
56915
|
const isEmpty2 = this.current.isEmptyClip();
|
|
56916
56916
|
if (this.pendingClip) {
|
|
56917
56917
|
this.current.updateClipFromPath();
|
|
@@ -56923,9 +56923,9 @@ fn fs_main(in : VertexOutput) -> @location(0) vec4<f32> {
|
|
|
56923
56923
|
if (this.pendingClip) {
|
|
56924
56924
|
if (!isEmpty2) {
|
|
56925
56925
|
if (this.pendingClip === EO_CLIP) {
|
|
56926
|
-
ctx.clip(
|
|
56926
|
+
ctx.clip(path9, "evenodd");
|
|
56927
56927
|
} else {
|
|
56928
|
-
ctx.clip(
|
|
56928
|
+
ctx.clip(path9);
|
|
56929
56929
|
}
|
|
56930
56930
|
}
|
|
56931
56931
|
this.pendingClip = null;
|
|
@@ -56998,7 +56998,7 @@ fn fs_main(in : VertexOutput) -> @location(0) vec4<f32> {
|
|
|
56998
56998
|
}
|
|
56999
56999
|
return this._cachedScaleForStroking;
|
|
57000
57000
|
}
|
|
57001
|
-
rescaleAndStroke(
|
|
57001
|
+
rescaleAndStroke(path9, saveRestore) {
|
|
57002
57002
|
const {
|
|
57003
57003
|
ctx,
|
|
57004
57004
|
current: {
|
|
@@ -57008,7 +57008,7 @@ fn fs_main(in : VertexOutput) -> @location(0) vec4<f32> {
|
|
|
57008
57008
|
const [scaleX, scaleY] = this.getScaleForStroking();
|
|
57009
57009
|
if (scaleX === scaleY) {
|
|
57010
57010
|
ctx.lineWidth = (lineWidth || 1) * scaleX;
|
|
57011
|
-
ctx.stroke(
|
|
57011
|
+
ctx.stroke(path9);
|
|
57012
57012
|
return;
|
|
57013
57013
|
}
|
|
57014
57014
|
const dashes = ctx.getLineDash();
|
|
@@ -57019,7 +57019,7 @@ fn fs_main(in : VertexOutput) -> @location(0) vec4<f32> {
|
|
|
57019
57019
|
SCALE_MATRIX.a = 1 / scaleX;
|
|
57020
57020
|
SCALE_MATRIX.d = 1 / scaleY;
|
|
57021
57021
|
const newPath = new Path2D();
|
|
57022
|
-
newPath.addPath(
|
|
57022
|
+
newPath.addPath(path9, SCALE_MATRIX);
|
|
57023
57023
|
if (dashes.length > 0) {
|
|
57024
57024
|
const scale = Math.max(scaleX, scaleY);
|
|
57025
57025
|
ctx.setLineDash(dashes.map((x2) => x2 / scale));
|
|
@@ -57747,8 +57747,8 @@ fn fs_main(in : VertexOutput) -> @location(0) vec4<f32> {
|
|
|
57747
57747
|
url
|
|
57748
57748
|
} = stream._source;
|
|
57749
57749
|
this._isStreamingSupported = !disableStream;
|
|
57750
|
-
const
|
|
57751
|
-
|
|
57750
|
+
const fs10 = process.getBuiltinModule("fs/promises");
|
|
57751
|
+
fs10.lstat(url).then((stat) => {
|
|
57752
57752
|
const readableStream = getReadableStream(url);
|
|
57753
57753
|
this._reader = readableStream.getReader();
|
|
57754
57754
|
const {
|
|
@@ -67942,11 +67942,11 @@ fn fs_main(in : VertexOutput) -> @location(0) vec4<f32> {
|
|
|
67942
67942
|
};
|
|
67943
67943
|
ContourDrawOutline = class extends InkDrawOutline {
|
|
67944
67944
|
toSVGPath() {
|
|
67945
|
-
let
|
|
67946
|
-
if (!
|
|
67947
|
-
|
|
67945
|
+
let path9 = super.toSVGPath();
|
|
67946
|
+
if (!path9.endsWith("Z")) {
|
|
67947
|
+
path9 += "Z";
|
|
67948
67948
|
}
|
|
67949
|
-
return
|
|
67949
|
+
return path9;
|
|
67950
67950
|
}
|
|
67951
67951
|
};
|
|
67952
67952
|
es_uint8_array_from_base64 = __webpack_require__(5213);
|
|
@@ -70651,7 +70651,7 @@ fn fs_main(in : VertexOutput) -> @location(0) vec4<f32> {
|
|
|
70651
70651
|
}
|
|
70652
70652
|
const drawLayer = textLayerData.drawLayer;
|
|
70653
70653
|
let div = textLayerData.selectionDiv;
|
|
70654
|
-
let
|
|
70654
|
+
let path9 = textLayerData.path;
|
|
70655
70655
|
if (!div) {
|
|
70656
70656
|
const clipPathId = `clip_selection_${_DrawLayer.#selectionId++}`;
|
|
70657
70657
|
div = document.createElement("div");
|
|
@@ -70670,18 +70670,18 @@ fn fs_main(in : VertexOutput) -> @location(0) vec4<f32> {
|
|
|
70670
70670
|
const clipPath = _DrawLayer._svgFactory.createElement("clipPath");
|
|
70671
70671
|
clipPath.setAttribute("id", clipPathId);
|
|
70672
70672
|
clipPath.setAttribute("clipPathUnits", "objectBoundingBox");
|
|
70673
|
-
|
|
70674
|
-
clipPath.append(
|
|
70673
|
+
path9 = _DrawLayer._svgFactory.createElement("path");
|
|
70674
|
+
clipPath.append(path9);
|
|
70675
70675
|
svg.append(clipPath);
|
|
70676
70676
|
div.append(svg);
|
|
70677
|
-
textLayerData.path =
|
|
70677
|
+
textLayerData.path = path9;
|
|
70678
70678
|
textLayerData.selectionDiv = div;
|
|
70679
70679
|
}
|
|
70680
70680
|
if (!div.parentNode && drawLayer.#parent) {
|
|
70681
70681
|
drawLayer.#parent.append(div);
|
|
70682
70682
|
this.#selections.add(div);
|
|
70683
70683
|
}
|
|
70684
|
-
|
|
70684
|
+
path9.setAttribute("d", boxes.join(" "));
|
|
70685
70685
|
}
|
|
70686
70686
|
}
|
|
70687
70687
|
static get _svgFactory() {
|
|
@@ -70728,13 +70728,13 @@ fn fs_main(in : VertexOutput) -> @location(0) vec4<f32> {
|
|
|
70728
70728
|
const root2 = this.#createSVG();
|
|
70729
70729
|
const defs = _DrawLayer._svgFactory.createElement("defs");
|
|
70730
70730
|
root2.append(defs);
|
|
70731
|
-
const
|
|
70732
|
-
defs.append(
|
|
70731
|
+
const path9 = _DrawLayer._svgFactory.createElement("path");
|
|
70732
|
+
defs.append(path9);
|
|
70733
70733
|
const pathId = `path_${id2}`;
|
|
70734
|
-
|
|
70735
|
-
|
|
70734
|
+
path9.setAttribute("id", pathId);
|
|
70735
|
+
path9.setAttribute("vector-effect", "non-scaling-stroke");
|
|
70736
70736
|
if (isPathUpdatable) {
|
|
70737
|
-
this.#toUpdate.set(id2,
|
|
70737
|
+
this.#toUpdate.set(id2, path9);
|
|
70738
70738
|
}
|
|
70739
70739
|
const clipPathId = hasClip ? this.#createClipPath(defs, pathId) : null;
|
|
70740
70740
|
const use = _DrawLayer._svgFactory.createElement("use");
|
|
@@ -70752,11 +70752,11 @@ fn fs_main(in : VertexOutput) -> @location(0) vec4<f32> {
|
|
|
70752
70752
|
const root2 = this.#createSVG();
|
|
70753
70753
|
const defs = _DrawLayer._svgFactory.createElement("defs");
|
|
70754
70754
|
root2.append(defs);
|
|
70755
|
-
const
|
|
70756
|
-
defs.append(
|
|
70755
|
+
const path9 = _DrawLayer._svgFactory.createElement("path");
|
|
70756
|
+
defs.append(path9);
|
|
70757
70757
|
const pathId = `path_${id2}`;
|
|
70758
|
-
|
|
70759
|
-
|
|
70758
|
+
path9.setAttribute("id", pathId);
|
|
70759
|
+
path9.setAttribute("vector-effect", "non-scaling-stroke");
|
|
70760
70760
|
let maskId;
|
|
70761
70761
|
if (mustRemoveSelfIntersections) {
|
|
70762
70762
|
const mask = _DrawLayer._svgFactory.createElement("mask");
|
|
@@ -70803,7 +70803,7 @@ fn fs_main(in : VertexOutput) -> @location(0) vec4<f32> {
|
|
|
70803
70803
|
root: root2,
|
|
70804
70804
|
bbox,
|
|
70805
70805
|
rootClass,
|
|
70806
|
-
path:
|
|
70806
|
+
path: path9
|
|
70807
70807
|
} = properties;
|
|
70808
70808
|
const element = typeof elementOrId === "number" ? this.#mapping.get(elementOrId) : elementOrId;
|
|
70809
70809
|
if (!element) {
|
|
@@ -70823,10 +70823,10 @@ fn fs_main(in : VertexOutput) -> @location(0) vec4<f32> {
|
|
|
70823
70823
|
classList.toggle(className, value);
|
|
70824
70824
|
}
|
|
70825
70825
|
}
|
|
70826
|
-
if (
|
|
70826
|
+
if (path9) {
|
|
70827
70827
|
const defs = element.firstElementChild;
|
|
70828
70828
|
const pathElement = defs.firstElementChild;
|
|
70829
|
-
this.#updateProperties(pathElement,
|
|
70829
|
+
this.#updateProperties(pathElement, path9);
|
|
70830
70830
|
}
|
|
70831
70831
|
}
|
|
70832
70832
|
updateParent(id2, layer) {
|
|
@@ -71040,7 +71040,7 @@ fn fs_main(in : VertexOutput) -> @location(0) vec4<f32> {
|
|
|
71040
71040
|
});
|
|
71041
71041
|
|
|
71042
71042
|
// scripts/doctor.ts
|
|
71043
|
-
import
|
|
71043
|
+
import fs9 from "node:fs";
|
|
71044
71044
|
|
|
71045
71045
|
// packages/db/src/paths.ts
|
|
71046
71046
|
import os from "node:os";
|
|
@@ -71065,6 +71065,11 @@ function getInboxDir() {
|
|
|
71065
71065
|
fs.mkdirSync(dir, { recursive: true });
|
|
71066
71066
|
return dir;
|
|
71067
71067
|
}
|
|
71068
|
+
function getBackupsDir() {
|
|
71069
|
+
const dir = path.join(getDataDir(), "backups");
|
|
71070
|
+
fs.mkdirSync(dir, { recursive: true });
|
|
71071
|
+
return dir;
|
|
71072
|
+
}
|
|
71068
71073
|
|
|
71069
71074
|
// packages/db/src/runtime.ts
|
|
71070
71075
|
import fs2 from "node:fs";
|
|
@@ -71090,6 +71095,8 @@ function isProcessAlive(pid) {
|
|
|
71090
71095
|
}
|
|
71091
71096
|
|
|
71092
71097
|
// packages/db/src/connection.ts
|
|
71098
|
+
import fs3 from "node:fs";
|
|
71099
|
+
import path3 from "node:path";
|
|
71093
71100
|
import { DatabaseSync } from "node:sqlite";
|
|
71094
71101
|
|
|
71095
71102
|
// packages/db/src/schema.ts
|
|
@@ -71408,33 +71415,155 @@ var MIGRATIONS = [
|
|
|
71408
71415
|
// idempotent. Feeds next-round prep and consistency (lessons carry into later interviews).
|
|
71409
71416
|
`
|
|
71410
71417
|
ALTER TABLE interview_preps ADD COLUMN debrief TEXT NOT NULL DEFAULT '{}';
|
|
71418
|
+
`,
|
|
71419
|
+
// v7 — offer comparison (한국 총보상 필드) + company reputation research field on jobs.
|
|
71420
|
+
// offers: one per job (UNIQUE job_id, mirrors interview_preps). Cash pieces are numeric (만원) so
|
|
71421
|
+
// the server can deterministically sum an annual estimate; equity/other stay free-text (comp is
|
|
71422
|
+
// messy). ai_score/verdict are written by the connected AI at save time (no LLM here) and rendered
|
|
71423
|
+
// by the dashboard, so it never needs to call an LLM. jobs.reputation: AI-researched company
|
|
71424
|
+
// reputation summary (same pattern as company_overview) — feeds offer verdicts + offer-evaluation.
|
|
71425
|
+
`
|
|
71426
|
+
CREATE TABLE IF NOT EXISTS offers (
|
|
71427
|
+
id TEXT PRIMARY KEY,
|
|
71428
|
+
job_id TEXT NOT NULL UNIQUE REFERENCES jobs(id) ON DELETE CASCADE,
|
|
71429
|
+
base_salary INTEGER,
|
|
71430
|
+
bonus_amount INTEGER,
|
|
71431
|
+
welfare_amount INTEGER,
|
|
71432
|
+
signing_amount INTEGER,
|
|
71433
|
+
equity_note TEXT,
|
|
71434
|
+
comp_note TEXT,
|
|
71435
|
+
work_arrangement TEXT,
|
|
71436
|
+
contract_type TEXT,
|
|
71437
|
+
accept_deadline TEXT,
|
|
71438
|
+
ai_score INTEGER,
|
|
71439
|
+
verdict TEXT,
|
|
71440
|
+
notes TEXT,
|
|
71441
|
+
created_at TEXT NOT NULL,
|
|
71442
|
+
updated_at TEXT NOT NULL
|
|
71443
|
+
);
|
|
71444
|
+
CREATE INDEX IF NOT EXISTS idx_offers_job ON offers(job_id);
|
|
71445
|
+
ALTER TABLE jobs ADD COLUMN reputation TEXT;
|
|
71446
|
+
`,
|
|
71447
|
+
// v8 — offer lifecycle status. 지원 상태(전형 깔때기 = 회사의 프로세스)와 직교하는
|
|
71448
|
+
// "내 응답" 축: open(진행)/accepted(수락)/declined(거절). declined여도 행을 지우지
|
|
71449
|
+
// 않는다 — 조건(연봉·처우) 히스토리는 다음 협상의 자산이라, 대시보드가 접힌
|
|
71450
|
+
// '지난 오퍼'로 강등해 보여줄 뿐이다. Additive ALTER (runner가 멱등 처리).
|
|
71451
|
+
`
|
|
71452
|
+
ALTER TABLE offers ADD COLUMN offer_status TEXT NOT NULL DEFAULT 'open';
|
|
71453
|
+
`,
|
|
71454
|
+
// v9 — 한국 문항형 자소서: 회사가 지정한 문항·글자수를 공고에 구조화 보관. 한국 자소서는
|
|
71455
|
+
// 회사별 문항형(항목·글자수 제한)이 지배적이라, AI가 문항별로 답변을 쓰고 글자수를 점검할 때
|
|
71456
|
+
// 참조할 원본을 공고 옆에 둔다(별도 엔티티가 아니라 job 컨텍스트에 함께 실린다). JSON 배열을
|
|
71457
|
+
// TEXT에 저장(다른 JSON 필드와 동일). Additive ALTER (runner가 멱등 처리).
|
|
71458
|
+
`
|
|
71459
|
+
ALTER TABLE jobs ADD COLUMN questions TEXT NOT NULL DEFAULT '[]';
|
|
71460
|
+
`,
|
|
71461
|
+
// v10 — 탈락 회고: 어느 전형 단계에서 떨어졌는지 자가 기록. 탈락 사유를 고지하는 기업은 6%뿐이고
|
|
71462
|
+
// 지원자 83%가 알고 싶어하므로, 이 자가 기록이 "서류는 붙는데 면접에서 떨어진다" 같은 패턴을 로컬
|
|
71463
|
+
// 데이터로 드러내는 유일한 신호다. 탈락이 아니거나 미기록이면 NULL. Additive ALTER (runner가 멱등 처리).
|
|
71464
|
+
`
|
|
71465
|
+
ALTER TABLE applications ADD COLUMN rejected_stage TEXT;
|
|
71466
|
+
`,
|
|
71467
|
+
// v11 — 전형 일정: 서류마감→인적성·AI역검→1·2차 면접→발표로 이어지는 단계별 날짜를 공고에
|
|
71468
|
+
// 구조화 보관. 일정을 jobs에 두는 이유: 서류마감(deadline)이 이미 jobs에 있고, save_job_posting
|
|
71469
|
+
// 업서트를 그대로 재사용해 도구 신설 없이 갱신할 수 있다. 면접초대 메일·발표 공지를 사용자가
|
|
71470
|
+
// 붙여넣으면 AI가 날짜를 추출해 저장하고, 서버가 D-day·같은 날짜 충돌을 결정론으로 계산한다.
|
|
71471
|
+
// JSON 배열을 TEXT에 저장(다른 JSON 필드와 동일). Additive ALTER (runner가 멱등 처리).
|
|
71472
|
+
`
|
|
71473
|
+
ALTER TABLE jobs ADD COLUMN schedule TEXT NOT NULL DEFAULT '[]';
|
|
71411
71474
|
`
|
|
71412
71475
|
];
|
|
71413
71476
|
function migrate(db) {
|
|
71414
71477
|
db.exec(`CREATE TABLE IF NOT EXISTS _meta (key TEXT PRIMARY KEY, value TEXT NOT NULL);`);
|
|
71415
71478
|
const row = db.prepare(`SELECT value FROM _meta WHERE key = 'schema_version'`).get();
|
|
71416
71479
|
const from = row ? Number(row.value) : 0;
|
|
71480
|
+
if (from >= MIGRATIONS.length) return { from, to: from };
|
|
71417
71481
|
for (let v = from; v < MIGRATIONS.length; v++) {
|
|
71418
|
-
db
|
|
71482
|
+
applyMigration(db, v);
|
|
71419
71483
|
}
|
|
71420
|
-
|
|
71421
|
-
|
|
71422
|
-
|
|
71423
|
-
|
|
71424
|
-
|
|
71425
|
-
|
|
71484
|
+
return { from, to: MIGRATIONS.length };
|
|
71485
|
+
}
|
|
71486
|
+
function stampVersion(db, version2) {
|
|
71487
|
+
db.prepare(
|
|
71488
|
+
`INSERT INTO _meta (key, value) VALUES ('schema_version', ?)
|
|
71489
|
+
ON CONFLICT(key) DO UPDATE SET value = excluded.value`
|
|
71490
|
+
).run(String(version2));
|
|
71491
|
+
}
|
|
71492
|
+
function columnExists(db, table, column) {
|
|
71493
|
+
const rows = db.prepare(`PRAGMA table_info("${table.replaceAll('"', '""')}")`).all();
|
|
71494
|
+
return rows.some((r) => r.name === column);
|
|
71495
|
+
}
|
|
71496
|
+
var SELF_TRANSACTIONAL_MIGRATIONS = /* @__PURE__ */ new Set([1]);
|
|
71497
|
+
var ALTER_ADD_COLUMN_RE = /^[ \t]*ALTER TABLE\s+(\w+)\s+ADD COLUMN\s+(\w+)[^;]*;[ \t]*$/gm;
|
|
71498
|
+
function skipExistingColumns(db, sql) {
|
|
71499
|
+
return sql.replace(
|
|
71500
|
+
ALTER_ADD_COLUMN_RE,
|
|
71501
|
+
(stmt, table, column) => columnExists(db, table, column) ? "" : stmt
|
|
71502
|
+
);
|
|
71503
|
+
}
|
|
71504
|
+
function applyMigration(db, v) {
|
|
71505
|
+
const sql = MIGRATIONS[v];
|
|
71506
|
+
if (SELF_TRANSACTIONAL_MIGRATIONS.has(v)) {
|
|
71507
|
+
db.exec(sql);
|
|
71508
|
+
stampVersion(db, v + 1);
|
|
71509
|
+
return;
|
|
71510
|
+
}
|
|
71511
|
+
db.exec("BEGIN");
|
|
71512
|
+
try {
|
|
71513
|
+
db.exec(skipExistingColumns(db, sql));
|
|
71514
|
+
stampVersion(db, v + 1);
|
|
71515
|
+
db.exec("COMMIT");
|
|
71516
|
+
} catch (err2) {
|
|
71517
|
+
try {
|
|
71518
|
+
db.exec("ROLLBACK");
|
|
71519
|
+
} catch {
|
|
71520
|
+
}
|
|
71521
|
+
throw err2;
|
|
71426
71522
|
}
|
|
71427
|
-
return { from, to };
|
|
71428
71523
|
}
|
|
71429
71524
|
|
|
71430
71525
|
// packages/db/src/connection.ts
|
|
71431
71526
|
var _db = null;
|
|
71527
|
+
var PRE_MIGRATE_KEEP = 5;
|
|
71528
|
+
function vacuumInto(db, destPath) {
|
|
71529
|
+
if (/[\0\n\r]/.test(destPath)) throw new Error("backup path not safe for SQL literal");
|
|
71530
|
+
db.exec(`VACUUM INTO '${destPath.replace(/'/g, "''")}'`);
|
|
71531
|
+
}
|
|
71532
|
+
function preMigrationBackup(db) {
|
|
71533
|
+
try {
|
|
71534
|
+
const hasMeta = db.prepare(`SELECT name FROM sqlite_master WHERE type='table' AND name='_meta'`).get();
|
|
71535
|
+
if (!hasMeta) return;
|
|
71536
|
+
const row = db.prepare(`SELECT value FROM _meta WHERE key = 'schema_version'`).get();
|
|
71537
|
+
const from = row ? Number(row.value) : 0;
|
|
71538
|
+
if (from === 0 || from >= MIGRATIONS.length) return;
|
|
71539
|
+
const dir = getBackupsDir();
|
|
71540
|
+
const stamp = (/* @__PURE__ */ new Date()).toISOString().replace(/[:.]/g, "-");
|
|
71541
|
+
const dest = path3.join(dir, `pre-migrate-v${from}-${stamp}.sqlite`);
|
|
71542
|
+
try {
|
|
71543
|
+
vacuumInto(db, dest);
|
|
71544
|
+
} catch {
|
|
71545
|
+
fs3.copyFileSync(getDbPath(), dest);
|
|
71546
|
+
}
|
|
71547
|
+
const stale = fs3.readdirSync(dir).filter((f) => f.startsWith("pre-migrate-") && f.endsWith(".sqlite")).sort().reverse().slice(PRE_MIGRATE_KEEP);
|
|
71548
|
+
for (const f of stale) {
|
|
71549
|
+
try {
|
|
71550
|
+
fs3.unlinkSync(path3.join(dir, f));
|
|
71551
|
+
} catch {
|
|
71552
|
+
}
|
|
71553
|
+
}
|
|
71554
|
+
} catch (err2) {
|
|
71555
|
+
console.error(
|
|
71556
|
+
`[careermate] \uC5C5\uADF8\uB808\uC774\uB4DC \uC804 \uC790\uB3D9 \uBC31\uC5C5 \uC2E4\uD328(\uB9C8\uC774\uADF8\uB808\uC774\uC158\uC740 \uACC4\uC18D \uC9C4\uD589): ${err2 instanceof Error ? err2.message : String(err2)}`
|
|
71557
|
+
);
|
|
71558
|
+
}
|
|
71559
|
+
}
|
|
71432
71560
|
function getDb() {
|
|
71433
71561
|
if (_db) return _db;
|
|
71434
71562
|
const db = new DatabaseSync(getDbPath());
|
|
71435
71563
|
db.exec("PRAGMA journal_mode = WAL;");
|
|
71436
71564
|
db.exec("PRAGMA foreign_keys = ON;");
|
|
71437
71565
|
db.exec("PRAGMA busy_timeout = 5000;");
|
|
71566
|
+
preMigrationBackup(db);
|
|
71438
71567
|
migrate(db);
|
|
71439
71568
|
_db = db;
|
|
71440
71569
|
return db;
|
|
@@ -72084,8 +72213,8 @@ function getErrorMap() {
|
|
|
72084
72213
|
|
|
72085
72214
|
// node_modules/zod/v3/helpers/parseUtil.js
|
|
72086
72215
|
var makeIssue = (params) => {
|
|
72087
|
-
const { data, path:
|
|
72088
|
-
const fullPath = [...
|
|
72216
|
+
const { data, path: path9, errorMaps, issueData } = params;
|
|
72217
|
+
const fullPath = [...path9, ...issueData.path || []];
|
|
72089
72218
|
const fullIssue = {
|
|
72090
72219
|
...issueData,
|
|
72091
72220
|
path: fullPath
|
|
@@ -72201,11 +72330,11 @@ var errorUtil;
|
|
|
72201
72330
|
|
|
72202
72331
|
// node_modules/zod/v3/types.js
|
|
72203
72332
|
var ParseInputLazyPath = class {
|
|
72204
|
-
constructor(parent, value,
|
|
72333
|
+
constructor(parent, value, path9, key) {
|
|
72205
72334
|
this._cachedPath = [];
|
|
72206
72335
|
this.parent = parent;
|
|
72207
72336
|
this.data = value;
|
|
72208
|
-
this._path =
|
|
72337
|
+
this._path = path9;
|
|
72209
72338
|
this._key = key;
|
|
72210
72339
|
}
|
|
72211
72340
|
get path() {
|
|
@@ -75881,6 +76010,22 @@ var CoverLetterRecordSchema = external_exports.object({
|
|
|
75881
76010
|
current_content: external_exports.string().nullable(),
|
|
75882
76011
|
versions: external_exports.array(CoverLetterVersionRecordSchema).optional()
|
|
75883
76012
|
});
|
|
76013
|
+
var JobQuestionSchema = external_exports.object({
|
|
76014
|
+
no: external_exports.number().int().positive().optional().describe("\uBB38\uD56D \uBC88\uD638(\uC788\uC73C\uBA74)"),
|
|
76015
|
+
question: external_exports.string().max(MAX_BODY).describe("\uBB38\uD56D \uD14D\uC2A4\uD2B8(\uD68C\uC0AC\uAC00 \uC81C\uC2DC\uD55C \uC790\uC18C\uC11C \uD56D\uBAA9)"),
|
|
76016
|
+
min_chars: external_exports.number().int().positive().optional().describe("\uAE00\uC790\uC218 \uD558\uD55C(\uC788\uC73C\uBA74)"),
|
|
76017
|
+
max_chars: external_exports.number().int().positive().optional().describe("\uAE00\uC790\uC218 \uC0C1\uD55C(\uC788\uC73C\uBA74)"),
|
|
76018
|
+
count_mode: external_exports.enum(["with_space", "no_space", "byte"]).optional().describe("\uAE00\uC790\uC218 \uAE30\uC900: with_space=\uACF5\uBC31\uD3EC\uD568(\uAE30\uBCF8)\xB7no_space=\uACF5\uBC31\uC81C\uC678\xB7byte=UTF-8 \uBC14\uC774\uD2B8"),
|
|
76019
|
+
note: optLine.describe('\uBD80\uAC00 \uBA54\uBAA8(\uC608: "\uD544\uC218", "\uACBD\uD5D8 \uC911\uC2EC")')
|
|
76020
|
+
});
|
|
76021
|
+
var SCHEDULE_DATE_RE = /^\d{4}-\d{2}-\d{2}$/;
|
|
76022
|
+
var SCHEDULE_TIME_RE = /^([01]\d|2[0-3]):[0-5]\d$/;
|
|
76023
|
+
var JobScheduleItemSchema = external_exports.object({
|
|
76024
|
+
label: reqLine.describe("\uC77C\uC815 \uC774\uB984 (\uC608: 1\uCC28 \uBA74\uC811\xB7AI\uC5ED\uAC80\xB7\uC11C\uB958 \uBC1C\uD45C)"),
|
|
76025
|
+
date: external_exports.string().regex(SCHEDULE_DATE_RE, "YYYY-MM-DD \uD615\uC2DD\uC774\uC5B4\uC57C \uD569\uB2C8\uB2E4").describe("\uC77C\uC815 \uB0A0\uC9DC YYYY-MM-DD"),
|
|
76026
|
+
time: external_exports.string().regex(SCHEDULE_TIME_RE, "HH:MM(24\uC2DC\uAC04) \uD615\uC2DD\uC774\uC5B4\uC57C \uD569\uB2C8\uB2E4").optional().describe("\uC2DC\uAC01 HH:MM(24\uC2DC\uAC04, \uC120\uD0DD)"),
|
|
76027
|
+
note: optLine.describe("\uBD80\uAC00 \uBA54\uBAA8(\uC608: \uC7A5\uC18C\xB7\uC900\uBE44\uBB3C, \uC120\uD0DD)")
|
|
76028
|
+
});
|
|
75884
76029
|
var JobInputSchema = external_exports.object({
|
|
75885
76030
|
company: reqLine,
|
|
75886
76031
|
position: reqLine.describe("\uC9C1\uBB34/\uD3EC\uC9C0\uC158\uBA85"),
|
|
@@ -75894,7 +76039,10 @@ var JobInputSchema = external_exports.object({
|
|
|
75894
76039
|
source: external_exports.string().max(MAX_LINE).optional().describe("\uCD9C\uCC98 (\uC0AC\uB78C\uC778/\uC6D0\uD2F0\uB4DC/\uC9C1\uC811 \uC785\uB825 \uB4F1)"),
|
|
75895
76040
|
company_overview: optBody.describe("\uD68C\uC0AC \uC0AC\uC5C5\uAC1C\uC694\xB7\uBBF8\uC158\xB7\uC8FC\uC694 \uC81C\uD488\xB7\uCD5C\uADFC \uD65C\uB3D9 (AI\uAC00 \uB9AC\uC11C\uCE58\uD574 \uCC44\uC6C0)"),
|
|
75896
76041
|
talent_profile: optBody.describe("\uD68C\uC0AC\uAC00 \uAC15\uC870\uD558\uB294 \uC778\uC7AC\uC0C1 (\uD55C\uAD6D \uC790\uC18C\uC11C\xB7\uBA74\uC811\uC5D0\uC11C \uC815\uB82C \uAE30\uC900)"),
|
|
75897
|
-
core_values: strList.optional().describe("\uD68C\uC0AC \uD575\uC2EC\uAC00\uCE58 (\uD0A4\uC6CC\uB4DC \uBC30\uC5F4)")
|
|
76042
|
+
core_values: strList.optional().describe("\uD68C\uC0AC \uD575\uC2EC\uAC00\uCE58 (\uD0A4\uC6CC\uB4DC \uBC30\uC5F4)"),
|
|
76043
|
+
reputation: optBody.describe("\uD68C\uC0AC \uD3C9\uD310 \uC694\uC57D \u2014 \uD3C9\uC810\xB7\uC6CC\uB77C\uBC38\xB7\uBB38\uD654 \uB9AC\uC2A4\uD06C \uB4F1 (AI\uAC00 company-research \uD50C\uB808\uC774\uBD81\uC73C\uB85C \uB9AC\uC11C\uCE58\uD574 \uCC44\uC6C0; \uCD9C\uCC98\xB7\uCD5C\uADFC\uC131 \uD45C\uAE30)"),
|
|
76044
|
+
questions: external_exports.array(JobQuestionSchema).max(MAX_ITEMS).optional().describe("\uD68C\uC0AC \uC9C0\uC815 \uC790\uC18C\uC11C \uBB38\uD56D\xB7\uAE00\uC790\uC218 \u2014 \uC0AC\uC6A9\uC790\uAC00 \uBB38\uD56D\uC744 \uC8FC\uBA74 \uAD6C\uC870\uD654 \uC800\uC7A5"),
|
|
76045
|
+
schedule: external_exports.array(JobScheduleItemSchema).max(MAX_ITEMS).optional().describe("\uC804\uD615 \uC77C\uC815 \u2014 \uBA74\uC811\uCD08\uB300 \uBA54\uC77C\xB7\uBC1C\uD45C \uACF5\uC9C0\uB97C \uBC1B\uC73C\uBA74 \uAD6C\uC870\uD654 \uC800\uC7A5(label\xB7date \uD544\uC218, time \uC120\uD0DD). \uC11C\uB958 \uB9C8\uAC10\uC740 deadline \uD544\uB4DC\uB97C \uC4F0\uC138\uC694.")
|
|
75898
76046
|
});
|
|
75899
76047
|
var JobRecordSchema = external_exports.object({
|
|
75900
76048
|
...baseRecord,
|
|
@@ -75910,7 +76058,46 @@ var JobRecordSchema = external_exports.object({
|
|
|
75910
76058
|
source: external_exports.string().nullable(),
|
|
75911
76059
|
company_overview: external_exports.string().nullable(),
|
|
75912
76060
|
talent_profile: external_exports.string().nullable(),
|
|
75913
|
-
core_values: external_exports.array(external_exports.string())
|
|
76061
|
+
core_values: external_exports.array(external_exports.string()),
|
|
76062
|
+
reputation: external_exports.string().nullable(),
|
|
76063
|
+
questions: external_exports.array(JobQuestionSchema),
|
|
76064
|
+
schedule: external_exports.array(JobScheduleItemSchema)
|
|
76065
|
+
});
|
|
76066
|
+
var OFFER_STATUSES = ["open", "accepted", "declined"];
|
|
76067
|
+
var OfferInputSchema = external_exports.object({
|
|
76068
|
+
job_id: reqLine,
|
|
76069
|
+
offer_status: external_exports.enum(OFFER_STATUSES).optional().describe("\uC624\uD37C \uC0C1\uD0DC \u2014 open(\uC9C4\uD589 \uC911)/accepted(\uC218\uB77D)/declined(\uAC70\uC808). \uC0DD\uB7B5 \uC2DC \uAE30\uC874 \uAC12 \uC720\uC9C0(\uC2E0\uADDC \uC800\uC7A5\uC740 open)"),
|
|
76070
|
+
base_salary: external_exports.number().nonnegative().optional().describe("\uAE30\uBCF8\uAE09/\uC5F0\uBD09 (\uB9CC\uC6D0)"),
|
|
76071
|
+
bonus_amount: external_exports.number().nonnegative().optional().describe("\uC5F0 \uC131\uACFC\uAE09\xB7\uC0C1\uC5EC \uAE30\uB300\uC561 (\uB9CC\uC6D0)"),
|
|
76072
|
+
welfare_amount: external_exports.number().nonnegative().optional().describe("\uBCF5\uC9C0\uD3EC\uC778\uD2B8 \uB4F1 \uC5F0\uD658\uC0B0 (\uB9CC\uC6D0)"),
|
|
76073
|
+
signing_amount: external_exports.number().nonnegative().optional().describe("\uC0AC\uC774\uB2DD\uBCF4\uB108\uC2A4 \uC77C\uC2DC\uAE08 (\uB9CC\uC6D0)"),
|
|
76074
|
+
equity_note: optNote.describe("\uC8FC\uC2DD/\uC2A4\uD1A1\uC635\uC158 (\uC815\uC131 \uC11C\uC220 \u2014 \uAC00\uCE58\uD3C9\uAC00\uAC00 \uBAA8\uD638\uD558\uBBC0\uB85C \uD14D\uC2A4\uD2B8)"),
|
|
76075
|
+
comp_note: optBody.describe("\uAE30\uD0C0 \uBCF4\uC0C1 \uC790\uC720 \uC11C\uC220"),
|
|
76076
|
+
work_arrangement: optLine.describe("\uADFC\uBB34\uD615\uD0DC (\uC7AC\uD0DD/\uD558\uC774\uBE0C\uB9AC\uB4DC/\uCD9C\uADFC)"),
|
|
76077
|
+
contract_type: optLine.describe("\uACC4\uC57D\uD615\uD0DC (\uC815\uADDC/\uACC4\uC57D \uB4F1)"),
|
|
76078
|
+
accept_deadline: optLine.describe("\uC218\uB77D \uB9C8\uAC10\uC77C YYYY-MM-DD"),
|
|
76079
|
+
ai_score: external_exports.number().min(0).max(100).optional().describe("AI\uAC00 \uB9E4\uAE34 \uC885\uD569 \uC810\uC218 0~100 (\uC800\uC7A5 \uC2DC AI\uAC00 \uCC44\uC6C0)"),
|
|
76080
|
+
verdict: optBody.describe("\uCD5C\uC885\uD3C9 \u2014 \uC5B4\uB5A4 \uC0C1\uD669\uC774\uBA74 \uC5B4\uB514\uAC00 \uC88B\uC740\uC9C0 \uB4F1 (AI\uAC00 \uC800\uC7A5 \uC2DC \uC791\uC131)"),
|
|
76081
|
+
notes: optNote
|
|
76082
|
+
});
|
|
76083
|
+
var OfferRecordSchema = external_exports.object({
|
|
76084
|
+
...baseRecord,
|
|
76085
|
+
job_id: external_exports.string(),
|
|
76086
|
+
offer_status: external_exports.enum(OFFER_STATUSES),
|
|
76087
|
+
base_salary: external_exports.number().nullable(),
|
|
76088
|
+
bonus_amount: external_exports.number().nullable(),
|
|
76089
|
+
welfare_amount: external_exports.number().nullable(),
|
|
76090
|
+
signing_amount: external_exports.number().nullable(),
|
|
76091
|
+
equity_note: external_exports.string().nullable(),
|
|
76092
|
+
comp_note: external_exports.string().nullable(),
|
|
76093
|
+
work_arrangement: external_exports.string().nullable(),
|
|
76094
|
+
contract_type: external_exports.string().nullable(),
|
|
76095
|
+
accept_deadline: external_exports.string().nullable(),
|
|
76096
|
+
ai_score: external_exports.number().nullable(),
|
|
76097
|
+
verdict: external_exports.string().nullable(),
|
|
76098
|
+
notes: external_exports.string().nullable(),
|
|
76099
|
+
/** Server-computed annual cash estimate = base + bonus + welfare (signing is one-time, excluded). Null if no numeric pieces. */
|
|
76100
|
+
total_comp_annual_est: external_exports.number().nullable()
|
|
75914
76101
|
});
|
|
75915
76102
|
var FitAnalysisInputSchema = external_exports.object({
|
|
75916
76103
|
job_id: reqLine.describe("\uBD84\uC11D \uB300\uC0C1 \uACF5\uACE0 ID"),
|
|
@@ -75933,6 +76120,14 @@ var FitAnalysisRecordSchema = external_exports.object({
|
|
|
75933
76120
|
missing_keywords: external_exports.array(external_exports.string()),
|
|
75934
76121
|
recommendations: external_exports.array(external_exports.string())
|
|
75935
76122
|
});
|
|
76123
|
+
var REJECTED_STAGES = ["document", "assessment", "interview", "final", "other"];
|
|
76124
|
+
var REJECTED_STAGE_LABELS = {
|
|
76125
|
+
document: "\uC11C\uB958",
|
|
76126
|
+
assessment: "\uC778\uC801\uC131\xB7AI\uC5ED\uAC80",
|
|
76127
|
+
interview: "\uBA74\uC811",
|
|
76128
|
+
final: "\uCD5C\uC885\xB7\uCC98\uC6B0",
|
|
76129
|
+
other: "\uAE30\uD0C0"
|
|
76130
|
+
};
|
|
75936
76131
|
var ApplicationInputSchema = external_exports.object({
|
|
75937
76132
|
job_id: reqLine,
|
|
75938
76133
|
status: external_exports.enum(APPLICATION_STATUSES).optional(),
|
|
@@ -75953,7 +76148,10 @@ var ApplicationStatusUpdateSchema = external_exports.object({
|
|
|
75953
76148
|
application_id: optLine,
|
|
75954
76149
|
status: external_exports.enum(APPLICATION_STATUSES),
|
|
75955
76150
|
note: optNote.describe("\uC0C1\uD0DC \uBCC0\uACBD \uC0AC\uC720/\uBA54\uBAA8"),
|
|
75956
|
-
submission: ApplicationSubmissionSchema.optional().describe("\uC9C0\uC6D0 \uC644\uB8CC \uAE30\uB85D\uC5D0 \uB0A8\uAE38 \uC81C\uCD9C \uC790\uB8CC \uC2A4\uB0C5\uC0F7")
|
|
76151
|
+
submission: ApplicationSubmissionSchema.optional().describe("\uC9C0\uC6D0 \uC644\uB8CC \uAE30\uB85D\uC5D0 \uB0A8\uAE38 \uC81C\uCD9C \uC790\uB8CC \uC2A4\uB0C5\uC0F7"),
|
|
76152
|
+
rejected_stage: external_exports.enum(REJECTED_STAGES).optional().describe(
|
|
76153
|
+
"\uD0C8\uB77D \uD68C\uACE0 \u2014 'rejected'\uB85C \uBC14\uAFC0 \uB54C \uC5B4\uB290 \uB2E8\uACC4\uC5D0\uC11C \uB5A8\uC5B4\uC84C\uB294\uC9C0: \uC11C\uB958=document, \uC778\uC801\uC131\xB7AI\uC5ED\uAC80=assessment, \uBA74\uC811=interview, \uCD5C\uC885\xB7\uCC98\uC6B0=final, \uAE30\uD0C0=other. rejected\uAC00 \uC544\uB2CC \uC0C1\uD0DC\uC5D0\uB294 \uC800\uC7A5\uB418\uC9C0 \uC54A\uC2B5\uB2C8\uB2E4."
|
|
76154
|
+
)
|
|
75957
76155
|
});
|
|
75958
76156
|
var ApplicationRecordSchema = external_exports.object({
|
|
75959
76157
|
...baseRecord,
|
|
@@ -75962,7 +76160,8 @@ var ApplicationRecordSchema = external_exports.object({
|
|
|
75962
76160
|
resume_id: external_exports.string().nullable(),
|
|
75963
76161
|
cover_letter_id: external_exports.string().nullable(),
|
|
75964
76162
|
applied_at: external_exports.string().nullable(),
|
|
75965
|
-
notes: external_exports.string().nullable()
|
|
76163
|
+
notes: external_exports.string().nullable(),
|
|
76164
|
+
rejected_stage: external_exports.enum(REJECTED_STAGES).nullable()
|
|
75966
76165
|
});
|
|
75967
76166
|
var StarGuideSchema = external_exports.object({
|
|
75968
76167
|
question: external_exports.string().max(MAX_NOTE),
|
|
@@ -76066,7 +76265,7 @@ var ApplicationContextSchema = external_exports.object({
|
|
|
76066
76265
|
});
|
|
76067
76266
|
|
|
76068
76267
|
// packages/shared/src/build-info.ts
|
|
76069
|
-
var APP_VERSION = true ? "0.0.
|
|
76268
|
+
var APP_VERSION = true ? "0.0.9" : "0.0.0-dev";
|
|
76070
76269
|
var BUNDLED = true;
|
|
76071
76270
|
|
|
76072
76271
|
// packages/shared/src/index.ts
|
|
@@ -76614,6 +76813,9 @@ function mapJob(r) {
|
|
|
76614
76813
|
company_overview: r.company_overview ?? null,
|
|
76615
76814
|
talent_profile: r.talent_profile ?? null,
|
|
76616
76815
|
core_values: fromJson(r.core_values, []),
|
|
76816
|
+
reputation: r.reputation ?? null,
|
|
76817
|
+
questions: fromJson(r.questions, []),
|
|
76818
|
+
schedule: fromJson(r.schedule, []),
|
|
76617
76819
|
created_at: r.created_at,
|
|
76618
76820
|
updated_at: r.updated_at
|
|
76619
76821
|
};
|
|
@@ -76643,7 +76845,7 @@ var jobRepo = {
|
|
|
76643
76845
|
if (existing) {
|
|
76644
76846
|
const m = { ...existing, ...input };
|
|
76645
76847
|
db.prepare(
|
|
76646
|
-
`UPDATE jobs SET company=?,position=?,url=?,location=?,employment_type=?,description=?,requirements=?,keywords=?,deadline=?,source=?,company_overview=?,talent_profile=?,core_values=?,updated_at=? WHERE id=?`
|
|
76848
|
+
`UPDATE jobs SET company=?,position=?,url=?,location=?,employment_type=?,description=?,requirements=?,keywords=?,deadline=?,source=?,company_overview=?,talent_profile=?,core_values=?,reputation=?,questions=?,schedule=?,updated_at=? WHERE id=?`
|
|
76647
76849
|
).run(
|
|
76648
76850
|
m.company,
|
|
76649
76851
|
m.position,
|
|
@@ -76658,6 +76860,12 @@ var jobRepo = {
|
|
|
76658
76860
|
m.company_overview ?? null,
|
|
76659
76861
|
m.talent_profile ?? null,
|
|
76660
76862
|
toJson(m.core_values ?? []),
|
|
76863
|
+
m.reputation ?? null,
|
|
76864
|
+
// questions omitted from input → m keeps existing.questions (preserved);
|
|
76865
|
+
// provided → replaced. Same merge semantics as the other JSON fields.
|
|
76866
|
+
toJson(m.questions ?? []),
|
|
76867
|
+
// schedule follows the same preserve-on-omit merge (v11 전형 일정).
|
|
76868
|
+
toJson(m.schedule ?? []),
|
|
76661
76869
|
ts,
|
|
76662
76870
|
existing.id
|
|
76663
76871
|
);
|
|
@@ -76665,8 +76873,8 @@ var jobRepo = {
|
|
|
76665
76873
|
}
|
|
76666
76874
|
const newJobId = id2 ?? newId("job_");
|
|
76667
76875
|
db.prepare(
|
|
76668
|
-
`INSERT INTO jobs (id,company,position,url,location,employment_type,description,requirements,keywords,deadline,source,company_overview,talent_profile,core_values,created_at,updated_at)
|
|
76669
|
-
VALUES (
|
|
76876
|
+
`INSERT INTO jobs (id,company,position,url,location,employment_type,description,requirements,keywords,deadline,source,company_overview,talent_profile,core_values,reputation,questions,schedule,created_at,updated_at)
|
|
76877
|
+
VALUES (?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)`
|
|
76670
76878
|
).run(
|
|
76671
76879
|
newJobId,
|
|
76672
76880
|
input.company,
|
|
@@ -76682,6 +76890,9 @@ var jobRepo = {
|
|
|
76682
76890
|
input.company_overview ?? null,
|
|
76683
76891
|
input.talent_profile ?? null,
|
|
76684
76892
|
toJson(input.core_values ?? []),
|
|
76893
|
+
input.reputation ?? null,
|
|
76894
|
+
toJson(input.questions ?? []),
|
|
76895
|
+
toJson(input.schedule ?? []),
|
|
76685
76896
|
ts,
|
|
76686
76897
|
ts
|
|
76687
76898
|
);
|
|
@@ -76695,6 +76906,7 @@ var jobRepo = {
|
|
|
76695
76906
|
db.prepare(`DELETE FROM applications WHERE job_id=?`).run(id2);
|
|
76696
76907
|
db.prepare(`DELETE FROM interview_preps WHERE job_id=?`).run(id2);
|
|
76697
76908
|
db.prepare(`DELETE FROM application_timeline_events WHERE job_id=?`).run(id2);
|
|
76909
|
+
db.prepare(`DELETE FROM offers WHERE job_id=?`).run(id2);
|
|
76698
76910
|
return db.prepare(`DELETE FROM jobs WHERE id=?`).run(id2).changes > 0;
|
|
76699
76911
|
});
|
|
76700
76912
|
}
|
|
@@ -76769,6 +76981,8 @@ function mapApplication(r) {
|
|
|
76769
76981
|
cover_letter_id: r.cover_letter_id,
|
|
76770
76982
|
applied_at: r.applied_at,
|
|
76771
76983
|
notes: r.notes,
|
|
76984
|
+
// 탈락 회고: 탈락이 아니거나 미기록이면 NULL(v10 이전 DB는 컬럼이 없어 undefined → null 정규화).
|
|
76985
|
+
rejected_stage: r.rejected_stage ?? null,
|
|
76772
76986
|
created_at: r.created_at,
|
|
76773
76987
|
updated_at: r.updated_at
|
|
76774
76988
|
};
|
|
@@ -76805,17 +77019,19 @@ var applicationRepo = {
|
|
|
76805
77019
|
const app = this.ensure(input.job_id, input.status ?? "draft");
|
|
76806
77020
|
if (input.status && input.status !== app.status) assertStatusTransition(app.status, input.status);
|
|
76807
77021
|
const m = { ...app, ...input };
|
|
77022
|
+
const rejectedStageValue = m.status === "rejected" ? m.rejected_stage ?? null : null;
|
|
76808
77023
|
getDb().prepare(
|
|
76809
|
-
`UPDATE applications SET status=?,resume_id=?,cover_letter_id=?,applied_at=?,notes=?,updated_at=? WHERE id=?`
|
|
76810
|
-
).run(m.status, m.resume_id ?? null, m.cover_letter_id ?? null, m.applied_at ?? null, m.notes ?? null, now(), app.id);
|
|
77024
|
+
`UPDATE applications SET status=?,resume_id=?,cover_letter_id=?,applied_at=?,notes=?,rejected_stage=?,updated_at=? WHERE id=?`
|
|
77025
|
+
).run(m.status, m.resume_id ?? null, m.cover_letter_id ?? null, m.applied_at ?? null, m.notes ?? null, rejectedStageValue, now(), app.id);
|
|
76811
77026
|
return this.get(app.id);
|
|
76812
77027
|
},
|
|
76813
|
-
setStatus(jobId, status, note) {
|
|
77028
|
+
setStatus(jobId, status, note, rejectedStage) {
|
|
76814
77029
|
const app = this.ensure(jobId);
|
|
76815
77030
|
assertStatusTransition(app.status, status);
|
|
76816
77031
|
const appliedAt = status === "applied" && !app.applied_at ? now() : app.applied_at;
|
|
76817
77032
|
const notes = note ? [app.notes, note].filter(Boolean).join("\n") : app.notes;
|
|
76818
|
-
|
|
77033
|
+
const rejectedStageValue = status === "rejected" ? rejectedStage ?? app.rejected_stage ?? null : null;
|
|
77034
|
+
getDb().prepare(`UPDATE applications SET status=?, applied_at=?, notes=?, rejected_stage=?, updated_at=? WHERE id=?`).run(status, appliedAt, notes, rejectedStageValue, now(), app.id);
|
|
76819
77035
|
return this.get(app.id);
|
|
76820
77036
|
}
|
|
76821
77037
|
};
|
|
@@ -76935,10 +77151,100 @@ var timelineRepo = {
|
|
|
76935
77151
|
return getDb().prepare(`DELETE FROM application_timeline_events WHERE id=?`).run(id2).changes > 0;
|
|
76936
77152
|
}
|
|
76937
77153
|
};
|
|
77154
|
+
function mapOffer(r) {
|
|
77155
|
+
const base = r.base_salary ?? null;
|
|
77156
|
+
const bonus = r.bonus_amount ?? null;
|
|
77157
|
+
const welfare = r.welfare_amount ?? null;
|
|
77158
|
+
const hasAny = base != null || bonus != null || welfare != null;
|
|
77159
|
+
const total = hasAny ? (base ?? 0) + (bonus ?? 0) + (welfare ?? 0) : null;
|
|
77160
|
+
return {
|
|
77161
|
+
id: r.id,
|
|
77162
|
+
job_id: r.job_id,
|
|
77163
|
+
offer_status: r.offer_status ?? "open",
|
|
77164
|
+
base_salary: base,
|
|
77165
|
+
bonus_amount: bonus,
|
|
77166
|
+
welfare_amount: welfare,
|
|
77167
|
+
signing_amount: r.signing_amount ?? null,
|
|
77168
|
+
equity_note: r.equity_note ?? null,
|
|
77169
|
+
comp_note: r.comp_note ?? null,
|
|
77170
|
+
work_arrangement: r.work_arrangement ?? null,
|
|
77171
|
+
contract_type: r.contract_type ?? null,
|
|
77172
|
+
accept_deadline: r.accept_deadline ?? null,
|
|
77173
|
+
ai_score: r.ai_score ?? null,
|
|
77174
|
+
verdict: r.verdict ?? null,
|
|
77175
|
+
notes: r.notes ?? null,
|
|
77176
|
+
total_comp_annual_est: total,
|
|
77177
|
+
created_at: r.created_at,
|
|
77178
|
+
updated_at: r.updated_at
|
|
77179
|
+
};
|
|
77180
|
+
}
|
|
77181
|
+
var offerRepo = {
|
|
77182
|
+
getByJob(jobId) {
|
|
77183
|
+
const r = getDb().prepare(`SELECT * FROM offers WHERE job_id=?`).get(jobId);
|
|
77184
|
+
return r ? mapOffer(r) : null;
|
|
77185
|
+
},
|
|
77186
|
+
list() {
|
|
77187
|
+
return getDb().prepare(`SELECT * FROM offers ORDER BY ai_score IS NULL, ai_score DESC, updated_at DESC`).all().map(mapOffer);
|
|
77188
|
+
},
|
|
77189
|
+
/** Upsert by job_id (one offer per job). Missing fields are preserved on update (partial-safe). */
|
|
77190
|
+
save(input) {
|
|
77191
|
+
const db = getDb();
|
|
77192
|
+
const existing = this.getByJob(input.job_id);
|
|
77193
|
+
const ts = now();
|
|
77194
|
+
const n = (v, prev) => v ?? prev ?? null;
|
|
77195
|
+
const s = (v, prev) => v ?? prev ?? null;
|
|
77196
|
+
if (existing) {
|
|
77197
|
+
db.prepare(
|
|
77198
|
+
`UPDATE offers SET offer_status=?,base_salary=?,bonus_amount=?,welfare_amount=?,signing_amount=?,equity_note=?,comp_note=?,work_arrangement=?,contract_type=?,accept_deadline=?,ai_score=?,verdict=?,notes=?,updated_at=? WHERE id=?`
|
|
77199
|
+
).run(
|
|
77200
|
+
input.offer_status ?? existing.offer_status,
|
|
77201
|
+
n(input.base_salary, existing.base_salary),
|
|
77202
|
+
n(input.bonus_amount, existing.bonus_amount),
|
|
77203
|
+
n(input.welfare_amount, existing.welfare_amount),
|
|
77204
|
+
n(input.signing_amount, existing.signing_amount),
|
|
77205
|
+
s(input.equity_note, existing.equity_note),
|
|
77206
|
+
s(input.comp_note, existing.comp_note),
|
|
77207
|
+
s(input.work_arrangement, existing.work_arrangement),
|
|
77208
|
+
s(input.contract_type, existing.contract_type),
|
|
77209
|
+
s(input.accept_deadline, existing.accept_deadline),
|
|
77210
|
+
n(input.ai_score, existing.ai_score),
|
|
77211
|
+
s(input.verdict, existing.verdict),
|
|
77212
|
+
s(input.notes, existing.notes),
|
|
77213
|
+
ts,
|
|
77214
|
+
existing.id
|
|
77215
|
+
);
|
|
77216
|
+
return this.getByJob(input.job_id);
|
|
77217
|
+
}
|
|
77218
|
+
const id2 = newId("ofr_");
|
|
77219
|
+
db.prepare(
|
|
77220
|
+
`INSERT INTO offers (id,job_id,offer_status,base_salary,bonus_amount,welfare_amount,signing_amount,equity_note,comp_note,work_arrangement,contract_type,accept_deadline,ai_score,verdict,notes,created_at,updated_at)
|
|
77221
|
+
VALUES (?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)`
|
|
77222
|
+
).run(
|
|
77223
|
+
id2,
|
|
77224
|
+
input.job_id,
|
|
77225
|
+
input.offer_status ?? "open",
|
|
77226
|
+
input.base_salary ?? null,
|
|
77227
|
+
input.bonus_amount ?? null,
|
|
77228
|
+
input.welfare_amount ?? null,
|
|
77229
|
+
input.signing_amount ?? null,
|
|
77230
|
+
input.equity_note ?? null,
|
|
77231
|
+
input.comp_note ?? null,
|
|
77232
|
+
input.work_arrangement ?? null,
|
|
77233
|
+
input.contract_type ?? null,
|
|
77234
|
+
input.accept_deadline ?? null,
|
|
77235
|
+
input.ai_score ?? null,
|
|
77236
|
+
input.verdict ?? null,
|
|
77237
|
+
input.notes ?? null,
|
|
77238
|
+
ts,
|
|
77239
|
+
ts
|
|
77240
|
+
);
|
|
77241
|
+
return this.getByJob(input.job_id);
|
|
77242
|
+
}
|
|
77243
|
+
};
|
|
76938
77244
|
|
|
76939
77245
|
// packages/mcp-tools/src/tools.ts
|
|
76940
|
-
import
|
|
76941
|
-
import
|
|
77246
|
+
import fs8 from "node:fs";
|
|
77247
|
+
import path8 from "node:path";
|
|
76942
77248
|
|
|
76943
77249
|
// packages/core/src/onboarding.ts
|
|
76944
77250
|
function profileCompleteness(p) {
|
|
@@ -77563,12 +77869,12 @@ function saveCoverLetterVersion(input) {
|
|
|
77563
77869
|
}
|
|
77564
77870
|
return { coverLetter, version: version2, verification, forced };
|
|
77565
77871
|
}
|
|
77566
|
-
function updateApplicationStatus(jobId, status, note, submission) {
|
|
77872
|
+
function updateApplicationStatus(jobId, status, note, submission, rejectedStage) {
|
|
77567
77873
|
const job = jobRepo.get(jobId);
|
|
77568
77874
|
if (!job) throw notFound("\uACF5\uACE0\uB97C \uCC3E\uC744 \uC218 \uC5C6\uC2B5\uB2C8\uB2E4.");
|
|
77569
77875
|
const before2 = applicationRepo.getByJob(jobId);
|
|
77570
77876
|
const application = tx(() => {
|
|
77571
|
-
let application2 = applicationRepo.setStatus(jobId, status, note);
|
|
77877
|
+
let application2 = applicationRepo.setStatus(jobId, status, note, rejectedStage);
|
|
77572
77878
|
const submittedDocs = (submission?.document_ids ?? []).map((docId) => documentRepo.get(docId)).filter((doc) => !!doc);
|
|
77573
77879
|
const submittedCoverLetter = submission?.cover_letter_id ? coverLetterRepo.get(submission.cover_letter_id, true) : null;
|
|
77574
77880
|
if (status === "applied" && submission) {
|
|
@@ -77604,7 +77910,9 @@ function updateApplicationStatus(jobId, status, note, submission) {
|
|
|
77604
77910
|
status,
|
|
77605
77911
|
status_label: APPLICATION_STATUS_LABELS[status],
|
|
77606
77912
|
note: note ?? null,
|
|
77607
|
-
submission: submissionPayload
|
|
77913
|
+
submission: submissionPayload,
|
|
77914
|
+
// 탈락 회고: rejected로 넘어갈 때 실제 저장된 단계(setStatus가 정합성 처리한 값)를 타임라인에도 남긴다.
|
|
77915
|
+
rejected_stage: application2.rejected_stage
|
|
77608
77916
|
},
|
|
77609
77917
|
occurred_at: submittedAtToOccurrence(submittedAt)
|
|
77610
77918
|
});
|
|
@@ -77637,8 +77945,21 @@ function saveInterviewPrep(input) {
|
|
|
77637
77945
|
// packages/core/src/summary.ts
|
|
77638
77946
|
var DEADLINE_ACTIONABLE = ["draft", "planned"];
|
|
77639
77947
|
var DEADLINE_SOON_DAYS = 14;
|
|
77640
|
-
var
|
|
77948
|
+
var SCHEDULE_SOON_DAYS = 7;
|
|
77641
77949
|
var DAY_MS = 864e5;
|
|
77950
|
+
function collectFutureSchedule(jobs, now2) {
|
|
77951
|
+
const items = [];
|
|
77952
|
+
for (const job of jobs) {
|
|
77953
|
+
for (const s of job.schedule ?? []) {
|
|
77954
|
+
const d_day = daysUntilDate(s.date, now2);
|
|
77955
|
+
if (d_day == null || d_day < 0) continue;
|
|
77956
|
+
items.push({ job, label: s.label, date: s.date, time: s.time, d_day });
|
|
77957
|
+
}
|
|
77958
|
+
}
|
|
77959
|
+
return items.sort(
|
|
77960
|
+
(a, b) => a.date < b.date ? -1 : a.date > b.date ? 1 : (a.time || "99:99").localeCompare(b.time || "99:99")
|
|
77961
|
+
);
|
|
77962
|
+
}
|
|
77642
77963
|
function daysUntilDate(dateStr, now2) {
|
|
77643
77964
|
if (!dateStr) return null;
|
|
77644
77965
|
const d = /* @__PURE__ */ new Date(`${dateStr}T00:00:00`);
|
|
@@ -77653,6 +77974,24 @@ function daysSinceTimestamp(iso, now2) {
|
|
|
77653
77974
|
if (isNaN(d.getTime())) return null;
|
|
77654
77975
|
return Math.floor((now2.getTime() - d.getTime()) / DAY_MS);
|
|
77655
77976
|
}
|
|
77977
|
+
function businessDaysSince(iso, now2) {
|
|
77978
|
+
if (!iso) return null;
|
|
77979
|
+
const start = new Date(iso);
|
|
77980
|
+
if (isNaN(start.getTime())) return null;
|
|
77981
|
+
const s = new Date(start);
|
|
77982
|
+
s.setHours(0, 0, 0, 0);
|
|
77983
|
+
const e = new Date(now2);
|
|
77984
|
+
e.setHours(0, 0, 0, 0);
|
|
77985
|
+
if (e.getTime() <= s.getTime()) return 0;
|
|
77986
|
+
let count = 0;
|
|
77987
|
+
const cursor = new Date(s);
|
|
77988
|
+
while (cursor.getTime() < e.getTime()) {
|
|
77989
|
+
cursor.setDate(cursor.getDate() + 1);
|
|
77990
|
+
const dow = cursor.getDay();
|
|
77991
|
+
if (dow !== 0 && dow !== 6) count++;
|
|
77992
|
+
}
|
|
77993
|
+
return count;
|
|
77994
|
+
}
|
|
77656
77995
|
function jobWithMeta(job) {
|
|
77657
77996
|
const app = applicationRepo.getByJob(job.id);
|
|
77658
77997
|
const fit = fitRepo.getByJob(job.id);
|
|
@@ -77664,18 +78003,36 @@ function listRecentActivity(limit = 20) {
|
|
|
77664
78003
|
}
|
|
77665
78004
|
var POST_PASS_STALE_DAYS = 7;
|
|
77666
78005
|
var POST_INTERVIEW_STALE_DAYS = 7;
|
|
78006
|
+
var FOLLOWUP_DUE_BIZ_DAYS = 5;
|
|
78007
|
+
var FOLLOWUP_OVERDUE_BIZ_DAYS = 8;
|
|
78008
|
+
var FOLLOWUP_ONHOLD_CAL_DAYS = 45;
|
|
77667
78009
|
function getActionDigest(now2 = /* @__PURE__ */ new Date()) {
|
|
77668
78010
|
const applications = applicationRepo.list();
|
|
77669
78011
|
const jobs = jobRepo.list();
|
|
77670
78012
|
const statusByJob = new Map(applications.map((a) => [a.job_id, a]));
|
|
78013
|
+
const jobById = new Map(jobs.map((j) => [j.id, j]));
|
|
78014
|
+
const preppedJobIds = new Set(interviewRepo.list().map((p) => p.job_id));
|
|
77671
78015
|
const followups = [];
|
|
77672
78016
|
for (const a of applications) {
|
|
77673
|
-
const job =
|
|
78017
|
+
const job = jobById.get(a.job_id);
|
|
77674
78018
|
if (!job) continue;
|
|
77675
78019
|
if (a.status === "applied") {
|
|
77676
|
-
const
|
|
77677
|
-
|
|
77678
|
-
|
|
78020
|
+
const cal = daysSinceTimestamp(a.applied_at, now2);
|
|
78021
|
+
const biz = businessDaysSince(a.applied_at, now2);
|
|
78022
|
+
if (biz != null && biz >= FOLLOWUP_DUE_BIZ_DAYS) {
|
|
78023
|
+
const overdue = biz >= FOLLOWUP_OVERDUE_BIZ_DAYS;
|
|
78024
|
+
const item = {
|
|
78025
|
+
job,
|
|
78026
|
+
status: a.status,
|
|
78027
|
+
status_label: APPLICATION_STATUS_LABELS[a.status],
|
|
78028
|
+
days_since: cal ?? 0,
|
|
78029
|
+
business_days_since: biz,
|
|
78030
|
+
followup_timing: overdue ? "overdue" : "due",
|
|
78031
|
+
reason: overdue ? `\uC9C0\uC6D0 \uD6C4 ${biz}\uC601\uC5C5\uC77C \uACBD\uACFC \u2014 \uD6C4\uC18D \uBB38\uC758 \uC801\uAE30\uAC00 \uC9C0\uB0AC\uC2B5\uB2C8\uB2E4(\uBB34\uB9AC\uD55C \uB3C5\uCD09\uC740 \uC5ED\uD6A8\uACFC\uC774\uB2C8 \uC544\uC9C1 \uC548 \uD588\uB2E4\uBA74 \uC815\uC911\uD788 1\uD68C\uB9CC)` : `\uC9C0\uC6D0 \uD6C4 ${biz}\uC601\uC5C5\uC77C \u2014 \uD314\uB85C\uC5C5 \uC801\uAE30(\uBB38\uC758\uB294 \uC815\uC911\uD788 1\uD68C)`
|
|
78032
|
+
};
|
|
78033
|
+
if (cal != null && cal >= FOLLOWUP_ONHOLD_CAL_DAYS) item.suggest_on_hold = true;
|
|
78034
|
+
followups.push(item);
|
|
78035
|
+
}
|
|
77679
78036
|
} else if (a.status === "document_passed") {
|
|
77680
78037
|
const days = daysSinceTimestamp(a.updated_at, now2);
|
|
77681
78038
|
if (days != null && days >= POST_PASS_STALE_DAYS)
|
|
@@ -77694,14 +78051,52 @@ function getActionDigest(now2 = /* @__PURE__ */ new Date()) {
|
|
|
77694
78051
|
if (days_left == null || days_left > DEADLINE_SOON_DAYS) return null;
|
|
77695
78052
|
return { job, status, status_label: APPLICATION_STATUS_LABELS[status], days_left };
|
|
77696
78053
|
}).filter((x2) => x2 !== null).sort((a, b) => a.days_left - b.days_left);
|
|
77697
|
-
const interview_todo = applications.filter((a) => INTERVIEW_UNLOCK_STATUSES.includes(a.status) && !
|
|
77698
|
-
const job =
|
|
78054
|
+
const interview_todo = applications.filter((a) => INTERVIEW_UNLOCK_STATUSES.includes(a.status) && !preppedJobIds.has(a.job_id)).map((a) => {
|
|
78055
|
+
const job = jobById.get(a.job_id);
|
|
77699
78056
|
return job ? { job, status_label: APPLICATION_STATUS_LABELS[a.status] } : null;
|
|
77700
78057
|
}).filter((x2) => x2 !== null);
|
|
78058
|
+
const futureSchedule = collectFutureSchedule(jobs, now2);
|
|
78059
|
+
const upcoming_schedule = futureSchedule.filter((x2) => x2.d_day <= SCHEDULE_SOON_DAYS).map((x2) => ({
|
|
78060
|
+
job_id: x2.job.id,
|
|
78061
|
+
company: x2.job.company,
|
|
78062
|
+
position: x2.job.position,
|
|
78063
|
+
label: x2.label,
|
|
78064
|
+
...x2.time ? { time: x2.time } : {},
|
|
78065
|
+
date: x2.date,
|
|
78066
|
+
d_day: x2.d_day
|
|
78067
|
+
}));
|
|
78068
|
+
const byDate = /* @__PURE__ */ new Map();
|
|
78069
|
+
for (const x2 of futureSchedule) {
|
|
78070
|
+
const arr = byDate.get(x2.date) ?? [];
|
|
78071
|
+
arr.push(x2);
|
|
78072
|
+
byDate.set(x2.date, arr);
|
|
78073
|
+
}
|
|
78074
|
+
const schedule_conflicts = [];
|
|
78075
|
+
for (const [date, items] of byDate) {
|
|
78076
|
+
const distinctJobs = new Set(items.map((x2) => x2.job.id));
|
|
78077
|
+
if (distinctJobs.size < 2) continue;
|
|
78078
|
+
schedule_conflicts.push({
|
|
78079
|
+
date,
|
|
78080
|
+
items: items.map((x2) => ({
|
|
78081
|
+
job_id: x2.job.id,
|
|
78082
|
+
company: x2.job.company,
|
|
78083
|
+
position: x2.job.position,
|
|
78084
|
+
label: x2.label,
|
|
78085
|
+
...x2.time ? { time: x2.time } : {}
|
|
78086
|
+
}))
|
|
78087
|
+
});
|
|
78088
|
+
}
|
|
78089
|
+
schedule_conflicts.sort((a, b) => a.date < b.date ? -1 : a.date > b.date ? 1 : 0);
|
|
77701
78090
|
const today = `${now2.getFullYear()}-${String(now2.getMonth() + 1).padStart(2, "0")}-${String(now2.getDate()).padStart(2, "0")}`;
|
|
77702
|
-
return { today, followups, deadlines, interview_todo };
|
|
78091
|
+
return { today, followups, deadlines, interview_todo, upcoming_schedule, schedule_conflicts };
|
|
77703
78092
|
}
|
|
77704
78093
|
var normToken = (s) => s.toLowerCase().trim().replace(/^[.,/()\s]+|[.,/()\s]+$/g, "");
|
|
78094
|
+
var ASCII_TOKEN_RE = /^[a-z0-9+#.]+$/;
|
|
78095
|
+
var escapeRegExp = (s) => s.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
78096
|
+
function resumeBodyHasToken(text, token) {
|
|
78097
|
+
if (!ASCII_TOKEN_RE.test(token)) return text.includes(token);
|
|
78098
|
+
return new RegExp(`(?<![a-z0-9])${escapeRegExp(token)}(?![a-z0-9])`, "i").test(text);
|
|
78099
|
+
}
|
|
77705
78100
|
function prescreenJob(jobId) {
|
|
77706
78101
|
const job = jobRepo.get(jobId);
|
|
77707
78102
|
if (!job) return null;
|
|
@@ -77710,17 +78105,36 @@ function prescreenJob(jobId) {
|
|
|
77710
78105
|
for (const e of experienceRepo.list()) for (const t of e.tech ?? []) userTokens.add(normToken(t));
|
|
77711
78106
|
for (const p of projectRepo.list()) for (const t of p.tech ?? []) userTokens.add(normToken(t));
|
|
77712
78107
|
userTokens.delete("");
|
|
78108
|
+
const resume = documentRepo.primary("resume");
|
|
78109
|
+
const resume_checked = resume != null;
|
|
78110
|
+
const resumeText = (resume?.content ?? "").toLowerCase();
|
|
77713
78111
|
const keywords = (job.keywords ?? []).filter((k) => k && k.trim());
|
|
77714
78112
|
const matched = [];
|
|
77715
78113
|
const missing = [];
|
|
78114
|
+
const resume_matched = [];
|
|
77716
78115
|
for (const kw of keywords) {
|
|
77717
78116
|
const n = normToken(kw);
|
|
77718
|
-
const
|
|
78117
|
+
const skillHit = userTokens.has(n) || // substring match only for tokens ≥3 chars (avoid "c"/"r" matching everything).
|
|
77719
78118
|
n.length >= 3 && [...userTokens].some((u) => u.length >= 3 && (u.includes(n) || n.includes(u)));
|
|
77720
|
-
(
|
|
78119
|
+
(skillHit ? matched : missing).push(kw);
|
|
78120
|
+
if (resume_checked && n.length >= 2 && resumeBodyHasToken(resumeText, n)) resume_matched.push(kw);
|
|
77721
78121
|
}
|
|
77722
78122
|
const coverage = keywords.length ? matched.length / keywords.length : null;
|
|
77723
|
-
|
|
78123
|
+
const combinedSet = /* @__PURE__ */ new Set([...matched, ...resume_matched]);
|
|
78124
|
+
const combined_matched = keywords.filter((k) => combinedSet.has(k));
|
|
78125
|
+
const combined_coverage = keywords.length ? combined_matched.length / keywords.length : null;
|
|
78126
|
+
return {
|
|
78127
|
+
job_id: jobId,
|
|
78128
|
+
job_keywords: keywords,
|
|
78129
|
+
matched,
|
|
78130
|
+
missing,
|
|
78131
|
+
coverage,
|
|
78132
|
+
user_skill_count: userTokens.size,
|
|
78133
|
+
resume_matched,
|
|
78134
|
+
combined_matched,
|
|
78135
|
+
combined_coverage,
|
|
78136
|
+
resume_checked
|
|
78137
|
+
};
|
|
77724
78138
|
}
|
|
77725
78139
|
var PROGRESSION = ["applied", "document_passed", "interview", "final_passed"];
|
|
77726
78140
|
function getPipelineStats() {
|
|
@@ -77749,6 +78163,12 @@ function getPipelineStats() {
|
|
|
77749
78163
|
}
|
|
77750
78164
|
const pct = (n, d) => d > 0 ? Math.round(n / d * 1e3) / 10 : null;
|
|
77751
78165
|
const cur = (s) => applications.filter((a) => a.status === s).length;
|
|
78166
|
+
const rejectedApps = applications.filter((a) => a.status === "rejected");
|
|
78167
|
+
const rejected_by_stage = REJECTED_STAGES.map((stage) => ({
|
|
78168
|
+
stage,
|
|
78169
|
+
count: rejectedApps.filter((a) => a.rejected_stage === stage).length
|
|
78170
|
+
})).filter((s) => s.count > 0);
|
|
78171
|
+
const rejected_unrecorded = rejectedApps.filter((a) => !a.rejected_stage).length;
|
|
77752
78172
|
return {
|
|
77753
78173
|
total: applications.length,
|
|
77754
78174
|
by_status,
|
|
@@ -77760,12 +78180,14 @@ function getPipelineStats() {
|
|
|
77760
78180
|
in_progress: cur("applied") + cur("document_passed") + cur("interview"),
|
|
77761
78181
|
on_hold: cur("on_hold")
|
|
77762
78182
|
},
|
|
78183
|
+
rejected_by_stage,
|
|
78184
|
+
rejected_unrecorded,
|
|
77763
78185
|
note: "\uB2E8\uACC4\uBCC4 \uB3C4\uB2EC \uAE54\uB54C\uAE30\uB294 \uC0C1\uD0DC \uBCC0\uACBD \uC774\uB825(\uD0C0\uC784\uB77C\uC778)\uC73C\uB85C \uBCF5\uC6D0\uD55C \uC2E4\uCE21\uCE58\uC785\uB2C8\uB2E4(\uD604\uC7AC rejected\uC5EC\uB3C4 \uAC70\uCCD0\uAC04 \uCD5C\uACE0 \uB2E8\uACC4\uAE4C\uC9C0 \uC9D1\uACC4). \uBE44\uC728\uC740 \uC124\uBA85\uC6A9\uC774\uBA70 \uD45C\uBCF8\uC774 \uC791\uC73C\uBA74 \uC608\uCE21\uB825\uC774 \uB0AE\uC2B5\uB2C8\uB2E4 \u2014 \uCD94\uC138 \uCC38\uACE0\uB85C\uB9CC \uC4F0\uC138\uC694."
|
|
77764
78186
|
};
|
|
77765
78187
|
}
|
|
77766
78188
|
|
|
77767
78189
|
// packages/core/src/jobsearch.ts
|
|
77768
|
-
var UA =
|
|
78190
|
+
var UA = `careermate/${APP_VERSION} (+https://careermate.life)`;
|
|
77769
78191
|
function toYmd(v) {
|
|
77770
78192
|
if (typeof v !== "string" || v.length < 10) return void 0;
|
|
77771
78193
|
const m = v.match(/^(\d{4}-\d{2}-\d{2})/);
|
|
@@ -77855,6 +78277,24 @@ async function searchJobs(query, opts = {}) {
|
|
|
77855
78277
|
};
|
|
77856
78278
|
}
|
|
77857
78279
|
|
|
78280
|
+
// packages/core/src/offers.ts
|
|
78281
|
+
function withJob(offer, job) {
|
|
78282
|
+
return { ...offer, company: job?.company ?? "\u2014", position: job?.position ?? "\u2014" };
|
|
78283
|
+
}
|
|
78284
|
+
function saveOffer(input) {
|
|
78285
|
+
const job = jobRepo.get(input.job_id);
|
|
78286
|
+
if (!job) throw new Error("\uACF5\uACE0\uB97C \uCC3E\uC744 \uC218 \uC5C6\uC2B5\uB2C8\uB2E4. \uBA3C\uC800 save_job_posting\uC73C\uB85C \uACF5\uACE0\uB97C \uC800\uC7A5\uD558\uC138\uC694.");
|
|
78287
|
+
return withJob(offerRepo.save(input), job);
|
|
78288
|
+
}
|
|
78289
|
+
function getOffer(jobId) {
|
|
78290
|
+
const offer = offerRepo.getByJob(jobId);
|
|
78291
|
+
if (!offer) return null;
|
|
78292
|
+
return withJob(offer, jobRepo.get(jobId));
|
|
78293
|
+
}
|
|
78294
|
+
function compareOffers() {
|
|
78295
|
+
return offerRepo.list().map((o) => withJob(o, jobRepo.get(o.job_id)));
|
|
78296
|
+
}
|
|
78297
|
+
|
|
77858
78298
|
// packages/prompts/src/humanize.ts
|
|
77859
78299
|
var HUMANIZE_WRITING_GUIDE = `# \uC0AC\uB78C\uC774 \uC4F4 \uAC83\uCC98\uB7FC: \uC790\uAE30\uC18C\uAC1C\uC11C\xB7\uCEE4\uB9AC\uC5B4 \uAE00\uC4F0\uAE30 \uADDC\uCE59
|
|
77860
78300
|
|
|
@@ -77883,12 +78323,15 @@ var HUMANIZE_WRITING_GUIDE = `# \uC0AC\uB78C\uC774 \uC4F4 \uAC83\uCC98\uB7FC: \u
|
|
|
77883
78323
|
3. \uAE30\uACC4\uC801 \uBCD1\uB82C\uAD6C\uC870 \u2014 \uC138 \uAC1C\uC529 \uB098\uC5F4(rule of three), \uBAA8\uB4E0 \uBB38\uB2E8\uC774 \uB611\uAC19\uC740 \uACE8\uACA9.
|
|
77884
78324
|
- "\uCCAB\uC9F8\u2026\uB458\uC9F8\u2026\uC14B\uC9F8", "A\uD558\uACE0 B\uD558\uBA70 C\uD558\uB294" \uAC19\uC740 \uADE0\uC77C\uD55C \uB098\uC5F4\uC744 \uBC18\uBCF5\uD558\uC9C0 \uC54A\uB294\uB2E4.
|
|
77885
78325
|
- \uBB38\uB2E8\uB9C8\uB2E4 \uAE38\uC774\uC640 \uC2DC\uC791 \uBC29\uC2DD\uC744 \uC77C\uBD80\uB7EC \uB2E4\uB974\uAC8C \uD55C\uB2E4.
|
|
78326
|
+
- \uAC19\uC740 \uCE90\uCE58\uD504\uB808\uC774\uC988\xB7\uBAA8\uD2F0\uD504(\uC608: "1\uC6D0\uB3C4 \uD2C0\uB9AC\uC9C0 \uC54A\uB294")\uB97C \uBB38\uC11C \uC804\uCCB4\uC5D0\uC11C **\uCD5C\uB300 2\uD68C**\uAE4C\uC9C0\uB9CC \uC4F4\uB2E4. 3\uD68C\uBD80\uD130\uB294 \uC778\uC704\uC801 \uC7A5\uCE58\uB85C \uC77D\uD600 \uC624\uD788\uB824 \uC0AC\uB78C \uB0C4\uC0C8\uB97C \uC9C0\uC6B4\uB2E4 \u2014 \uBC18\uBCF5\uD558\uACE0 \uC2F6\uC73C\uBA74 \uB9E4\uBC88 \uB2E4\uB978 \uB9D0\uB85C \uBC14\uAFD4 \uD45C\uD604\uD55C\uB2E4.
|
|
77886
78327
|
|
|
77887
78328
|
4. \uC0C1\uD22C\uC801 \uC5F0\uACB0\uC5B4 \uB0A8\uBC1C \u2014 "\uB610\uD55C", "\uBFD0\uB9CC \uC544\uB2C8\uB77C", "\uB354 \uB098\uC544\uAC00", "\uC774\uB97C \uD1B5\uD574", "\uACB0\uB860\uC801\uC73C\uB85C".
|
|
77888
78329
|
- \uC811\uC18D\uC5B4 \uC5C6\uC774 \uBB38\uC7A5\uC744 \uC787\uAC70\uB098, \uC0AC\uAC74\uC758 \uD750\uB984 \uC790\uCCB4\uB85C \uC5F0\uACB0\uD55C\uB2E4.
|
|
77889
78330
|
|
|
77890
78331
|
5. \uADE0\uC77C\uD55C \uBB38\uC7A5 \uB9AC\uB4EC \u2014 \uBAA8\uB4E0 \uBB38\uC7A5\uC774 \uBE44\uC2B7\uD55C \uAE38\uC774.
|
|
77891
78332
|
- \uC9E7\uC740 \uBB38\uC7A5\uACFC \uAE34 \uBB38\uC7A5\uC744 \uC11E\uB294\uB2E4. \uAC00\uB054 \uC544\uC8FC \uC9E7\uAC8C \uB04A\uB294\uB2E4. \uC774\uB807\uAC8C.
|
|
78333
|
+
- \uBE44\uC2B7\uD55C \uAE38\uC774\uC758 \uBB38\uC7A5\uC744 \uC138 \uAC1C \uC5F0\uC18D\uC73C\uB85C \uC4F0\uC9C0 \uC54A\uB294\uB2E4. \uD558\uB098\uB294 \uAE38\uAC8C \uD480\uACE0 \uB2E4\uC74C\uC740 \uD22D \uB04A\uB294 \uC2DD\uC73C\uB85C \uD638\uD761\uC744 \uBC14\uAFBC\uB2E4.
|
|
78334
|
+
- \uBB38\uB2E8\uB9C8\uB2E4 \uD55C \uD638\uD761\uC5D0 \uC77D\uD788\uB294 \uC9E7\uC740 \uB2E8\uD0C0 \uBB38\uC7A5(8\uB2E8\uC5B4 \uC548\uD30E \uC774\uD558)\uC744 \uCD5C\uC18C \uD558\uB098 \uB123\uB294\uB2E4.
|
|
77892
78335
|
|
|
77893
78336
|
6. \uACFC\uC7A5\uB41C \uC218\uC2DD\xB7\uC218\uB3D9\uD0DC \u2014 "\uB9E4\uC6B0", "\uC815\uB9D0\uB85C", "\uD0C1\uC6D4\uD55C", "\uC131\uACF5\uC801\uC73C\uB85C", "~\uB418\uC5B4\uC84C\uC2B5\uB2C8\uB2E4".
|
|
77894
78337
|
- \uBD80\uC0AC\uB97C \uBE7C\uACE0 \uB3D9\uC0AC\xB7\uBA85\uC0AC\uB97C \uAD6C\uCCB4\uD654\uD55C\uB2E4. \uB2A5\uB3D9\uD0DC\uB97C \uAE30\uBCF8\uC73C\uB85C \uD55C\uB2E4.
|
|
@@ -77916,6 +78359,7 @@ var STRUCTURED_DOC_WRITING_GUIDE = `# \uAD6C\uC870\uD615 \uBB38\uC11C(\uACBD\uB8
|
|
|
77916
78359
|
- \uAC01 \uBD88\uB9BF\uC740 \uB3D9\uC0AC\uB098 \uC218\uCE58\uB85C \uC2DC\uC791\uD558\uACE0, \uAC80\uC99D \uAC00\uB2A5\uD55C \uC0AC\uC2E4(\uC22B\uC790\xB7\uAE30\uAC04\xB7\uB3C4\uAD6C\xB7\uC5ED\uD560\xB7\uACB0\uACFC)\uC744 \uD55C \uC904\uC5D0 \uB2F4\uB294\uB2E4.
|
|
77917
78360
|
- \uBD88\uB9BF \uC548\uC758 \uBC88\uC5ED\uD22C\xB7\uD074\uB9AC\uC170\xB7\uACF5\uD5C8\uD55C \uC77C\uBC18\uB860\xB7\uC218\uB3D9\uD0DC\uB294 \uC790\uAE30\uC18C\uAC1C\uC11C\uC640 \uB611\uAC19\uC774 \uC81C\uAC70\uD55C\uB2E4. (\uC608: "\uBD84\uC11D\uC744 \uC9C4\uD589\uD558\uC600\uC2B5\uB2C8\uB2E4" \u2192 "\uBD84\uC11D\uD588\uB2E4", "\uB9CE\uC740 \uC131\uACFC\uB97C \uB0C8\uC2B5\uB2C8\uB2E4" \u2192 \uC2E4\uC81C \uC218\uCE58)
|
|
77918
78361
|
- STAR\uC744 \uD55C\uB450 \uC904\uB85C \uC555\uCD95\uD55C\uB2E4: \uBB34\uC5C7\uC744 \uC65C \uD588\uACE0 \uACB0\uACFC \uC218\uCE58\uAC00 \uC5B4\uB5BB\uAC8C \uB410\uB294\uC9C0.
|
|
78362
|
+
- \uC0B0\uBB38\uD615 \uBD88\uB9BF\uC774 \uC5EC\uB7EC \uBB38\uC7A5\uC73C\uB85C \uAE38\uC5B4\uC9C0\uBA74, \uB9E8 \uC55E\uC5D0 "\uBC29\uBC95\u2192\uC131\uACFC"\uB97C \uC555\uCD95\uD55C \uB9AC\uB4DC \uAD6C\uB97C **\uAD75\uAC8C \uD55C \uC904** \uC5B9\uC5B4 30\uCD08 \uC2A4\uCE94\uC5D0\uC11C \uBC29\uBC95\uC774 \uBB38\uC7A5 \uC18D\uC5D0 \uBB3B\uD788\uC9C0 \uC54A\uAC8C \uD55C\uB2E4. (\uC608: **"\uC81C\uD488\uAD70\uBCC4 \uC18C\uC9C4\uC8FC\uAE30 \uCC28\uB4F1 \u2192 90\uC77C \uC7AC\uAD6C\uB9E4 18%\u219227%"** \u2014 \uC774\uC5B4\uC11C \uC0C1\uC138 \uC124\uBA85.) \uB2E8 \uC815\uC9C1 \uC7A5\uCE58(\uADC0\uC18D \uB2E8\uC11C\xB7\uACFC\uC7A5 \uC5C6\uB294 \uD558\uD5A5 \uC815\uB82C)\uB294 \uB9AC\uB4DC \uAD6C\uC5D0\uC11C\uB3C4 \uADF8\uB300\uB85C \uC720\uC9C0\uD55C\uB2E4 \u2014 \uB9AC\uB4DC \uAD6C\uAC00 \uC131\uACFC\uB97C \uBD80\uD480\uB9AC\uB294 \uD5E4\uB4DC\uB77C\uC778\uC774 \uB418\uBA74 \uC548 \uB41C\uB2E4.
|
|
77919
78363
|
|
|
77920
78364
|
## Do / Don't
|
|
77921
78365
|
- Do: \uB450\uAD04\uC2DD \uBD88\uB9BF(\uACB0\uACFC\xB7\uC218\uCE58\uB97C \uC55E\uC138\uC6C0), \uC9C1\uBB34\xB7\uAE30\uAC04\xB7\uC5ED\uD560 \uAD6C\uBD84, \uC131\uACFC\uB97C \uC22B\uC790\uB85C.
|
|
@@ -78067,11 +78511,11 @@ function renderWorkflowMarkdown(id2) {
|
|
|
78067
78511
|
}
|
|
78068
78512
|
|
|
78069
78513
|
// packages/knowledge/src/index.ts
|
|
78070
|
-
import
|
|
78071
|
-
import
|
|
78514
|
+
import fs4 from "node:fs";
|
|
78515
|
+
import path4 from "node:path";
|
|
78072
78516
|
import { fileURLToPath } from "node:url";
|
|
78073
|
-
var here =
|
|
78074
|
-
var CAREER_OS_DIR = BUNDLED ?
|
|
78517
|
+
var here = path4.dirname(fileURLToPath(import.meta.url));
|
|
78518
|
+
var CAREER_OS_DIR = BUNDLED ? path4.join(here, "career-os") : path4.resolve(here, "..", "..", "..", "docs", "career-os");
|
|
78075
78519
|
var EXPERT_DOMAINS = [
|
|
78076
78520
|
"resume",
|
|
78077
78521
|
"ats",
|
|
@@ -78103,7 +78547,7 @@ var cache = /* @__PURE__ */ new Map();
|
|
|
78103
78547
|
function readDoc(rel) {
|
|
78104
78548
|
let cached = cache.get(rel);
|
|
78105
78549
|
if (cached === void 0) {
|
|
78106
|
-
cached =
|
|
78550
|
+
cached = fs4.readFileSync(path4.join(CAREER_OS_DIR, rel), "utf8");
|
|
78107
78551
|
cache.set(rel, cached);
|
|
78108
78552
|
}
|
|
78109
78553
|
return cached;
|
|
@@ -78112,7 +78556,7 @@ function getPlaybook(domain) {
|
|
|
78112
78556
|
return readDoc(`knowledge/${domain}.md`);
|
|
78113
78557
|
}
|
|
78114
78558
|
function getVerifier(id2) {
|
|
78115
|
-
return readDoc(
|
|
78559
|
+
return readDoc(path4.join("knowledge", "verifiers", `${id2}.md`));
|
|
78116
78560
|
}
|
|
78117
78561
|
function getEop(feature) {
|
|
78118
78562
|
return readDoc(`eop/${feature}.md`);
|
|
@@ -95735,16 +96179,16 @@ var replacer = ({ json, patch, patchText, context, keepOriginalStyles = true })
|
|
|
95735
96179
|
didFindOccurrence: true
|
|
95736
96180
|
};
|
|
95737
96181
|
};
|
|
95738
|
-
var goToElementFromPath = (json,
|
|
96182
|
+
var goToElementFromPath = (json, path9) => {
|
|
95739
96183
|
let element = json;
|
|
95740
|
-
for (let i2 = 1; i2 <
|
|
95741
|
-
const index =
|
|
96184
|
+
for (let i2 = 1; i2 < path9.length; i2++) {
|
|
96185
|
+
const index = path9[i2];
|
|
95742
96186
|
element = element.elements[index];
|
|
95743
96187
|
}
|
|
95744
96188
|
return element;
|
|
95745
96189
|
};
|
|
95746
|
-
var goToParentElementFromPath = (json,
|
|
95747
|
-
var getLastElementIndexFromPath = (
|
|
96190
|
+
var goToParentElementFromPath = (json, path9) => goToElementFromPath(json, path9.slice(0, path9.length - 1));
|
|
96191
|
+
var getLastElementIndexFromPath = (path9) => path9[path9.length - 1];
|
|
95748
96192
|
var PatchType = {
|
|
95749
96193
|
/** Replace entire file-level elements (e.g., whole paragraphs) */
|
|
95750
96194
|
DOCUMENT: "file",
|
|
@@ -96304,8 +96748,8 @@ function decodeEntities(input) {
|
|
|
96304
96748
|
}
|
|
96305
96749
|
|
|
96306
96750
|
// packages/parsers/src/documents.ts
|
|
96307
|
-
import
|
|
96308
|
-
import
|
|
96751
|
+
import fs5 from "node:fs";
|
|
96752
|
+
import path5 from "node:path";
|
|
96309
96753
|
import os2 from "node:os";
|
|
96310
96754
|
|
|
96311
96755
|
// node_modules/fflate/esm/index.mjs
|
|
@@ -96796,7 +97240,7 @@ var import_mammoth = __toESM(require_lib6(), 1);
|
|
|
96796
97240
|
var import_hwp = __toESM(require_cjs(), 1);
|
|
96797
97241
|
var parseHwp = import_hwp.default?.parse ?? import_hwp.default?.default?.parse;
|
|
96798
97242
|
var MAX_BYTES = 25 * 1024 * 1024;
|
|
96799
|
-
var SENSITIVE_PATH_RE = /(^|[/\\])\.(ssh|aws|gnupg)([/\\]|$)|(^|[/\\])id_(rsa|dsa|ecdsa|ed25519)(\.[\w]+)?$|\.(pem|ppk)$|(^|[/\\])\.env(\.[\w-]+)?$|(^|[/\\])\.(npmrc|netrc|git-credentials)$/i;
|
|
97243
|
+
var SENSITIVE_PATH_RE = /(^|[/\\])\.(ssh|aws|gnupg|kube|docker|azure|boto)([/\\]|$)|[/\\]\.config[/\\]gcloud([/\\]|$)|(^|[/\\])id_(rsa|dsa|ecdsa|ed25519)(\.[\w]+)?$|\.(pem|ppk)$|(^|[/\\])\.env(\.[\w-]+)?$|(^|[/\\])\.(npmrc|netrc|git-credentials)$|(^|[/\\])(login data|web data|cookies|key4\.db|logins\.json|wallet\.dat)$/i;
|
|
96800
97244
|
var MAX_HWPX_ENTRY_BYTES = 40 * 1024 * 1024;
|
|
96801
97245
|
var MAX_HWPX_TOTAL_BYTES = 80 * 1024 * 1024;
|
|
96802
97246
|
var MAX_PDF_PAGES = 300;
|
|
@@ -96810,8 +97254,8 @@ var MD_RE = /\.(md|markdown|mdown|mkd)$/i;
|
|
|
96810
97254
|
var LEGACY_BINARY_RE = /\.(docm?|dot[xm]?|pptx?|ppt|xlsx?|xls|odt|ods|odp|rtf|pages|key|numbers)$/i;
|
|
96811
97255
|
function resolveDocumentPath(input, baseDir) {
|
|
96812
97256
|
let p = (input ?? "").trim().replace(/^["']|["']$/g, "");
|
|
96813
|
-
if (p === "~" || p.startsWith("~/") || p.startsWith("~\\")) p =
|
|
96814
|
-
if (!
|
|
97257
|
+
if (p === "~" || p.startsWith("~/") || p.startsWith("~\\")) p = path5.join(os2.homedir(), p.slice(1));
|
|
97258
|
+
if (!path5.isAbsolute(p)) p = path5.resolve(baseDir ?? process.cwd(), p);
|
|
96815
97259
|
return p;
|
|
96816
97260
|
}
|
|
96817
97261
|
async function extractDocument(input, baseDir) {
|
|
@@ -96828,7 +97272,7 @@ async function extractDocument(input, baseDir) {
|
|
|
96828
97272
|
});
|
|
96829
97273
|
let realPath = filePath;
|
|
96830
97274
|
try {
|
|
96831
|
-
realPath =
|
|
97275
|
+
realPath = fs5.realpathSync.native(filePath);
|
|
96832
97276
|
} catch {
|
|
96833
97277
|
}
|
|
96834
97278
|
if (SENSITIVE_PATH_RE.test(filePath) || SENSITIVE_PATH_RE.test(realPath)) {
|
|
@@ -96842,7 +97286,7 @@ async function extractDocument(input, baseDir) {
|
|
|
96842
97286
|
}
|
|
96843
97287
|
let stat;
|
|
96844
97288
|
try {
|
|
96845
|
-
stat =
|
|
97289
|
+
stat = fs5.statSync(filePath);
|
|
96846
97290
|
} catch {
|
|
96847
97291
|
return base("unsupported", { warnings: [`\uD30C\uC77C\uC744 \uCC3E\uC744 \uC218 \uC5C6\uC2B5\uB2C8\uB2E4: ${filePath}`], unsupported: true, errored: true });
|
|
96848
97292
|
}
|
|
@@ -96861,7 +97305,7 @@ async function extractDocument(input, baseDir) {
|
|
|
96861
97305
|
warnings: ["\uD30C\uC77C\uC774 \uBE44\uC5B4 \uC788\uC2B5\uB2C8\uB2E4(0\uBC14\uC774\uD2B8). \uB0B4\uC6A9\uC774 \uC788\uB294 \uD30C\uC77C\uC744 \uC9C0\uC815\uD574 \uC8FC\uC138\uC694."],
|
|
96862
97306
|
unsupported: true
|
|
96863
97307
|
});
|
|
96864
|
-
const name =
|
|
97308
|
+
const name = path5.basename(filePath);
|
|
96865
97309
|
const bytes = stat.size;
|
|
96866
97310
|
if (IMAGE_RE.test(name)) {
|
|
96867
97311
|
return base("image", {
|
|
@@ -96875,7 +97319,7 @@ async function extractDocument(input, baseDir) {
|
|
|
96875
97319
|
if (TEXT_RE.test(name) || MD_RE.test(name)) {
|
|
96876
97320
|
let textBuf;
|
|
96877
97321
|
try {
|
|
96878
|
-
textBuf =
|
|
97322
|
+
textBuf = fs5.readFileSync(filePath);
|
|
96879
97323
|
} catch (e) {
|
|
96880
97324
|
return base("unsupported", { bytes, warnings: [`\uD14D\uC2A4\uD2B8 \uD30C\uC77C\uC744 \uC77D\uC9C0 \uBABB\uD588\uC2B5\uB2C8\uB2E4: ${errMsg(e)}`], unsupported: true, errored: true });
|
|
96881
97325
|
}
|
|
@@ -96890,7 +97334,7 @@ async function extractDocument(input, baseDir) {
|
|
|
96890
97334
|
}
|
|
96891
97335
|
let buf;
|
|
96892
97336
|
try {
|
|
96893
|
-
buf =
|
|
97337
|
+
buf = fs5.readFileSync(filePath);
|
|
96894
97338
|
} catch (e) {
|
|
96895
97339
|
return base("unsupported", { bytes, warnings: [`\uD30C\uC77C\uC744 \uC77D\uC9C0 \uBABB\uD588\uC2B5\uB2C8\uB2E4: ${errMsg(e)}`], unsupported: true, errored: true });
|
|
96896
97340
|
}
|
|
@@ -96902,7 +97346,7 @@ async function extractDocument(input, baseDir) {
|
|
|
96902
97346
|
return base("unsupported", {
|
|
96903
97347
|
bytes,
|
|
96904
97348
|
warnings: [
|
|
96905
|
-
`${
|
|
97349
|
+
`${path5.extname(name) || "\uC774 \uD615\uC2DD"}\uC740 \uC790\uB3D9 \uCD94\uCD9C\uC744 \uC9C0\uC6D0\uD558\uC9C0 \uC54A\uC2B5\uB2C8\uB2E4. PDF \uB610\uB294 .docx/.hwp/.hwpx\uB85C \uB2E4\uC2DC \uC800\uC7A5\uD558\uAC70\uB098, \uB0B4\uC6A9\uC744 \uD14D\uC2A4\uD2B8\uB85C \uBCF5\uC0AC\uD574 \uBD99\uC5EC\uB123\uC5B4 \uC8FC\uC138\uC694.`
|
|
96906
97350
|
],
|
|
96907
97351
|
unsupported: true
|
|
96908
97352
|
});
|
|
@@ -97157,18 +97601,18 @@ function fail(text) {
|
|
|
97157
97601
|
|
|
97158
97602
|
// packages/mcp-tools/src/bridge.ts
|
|
97159
97603
|
import { spawn, spawnSync } from "node:child_process";
|
|
97160
|
-
import
|
|
97161
|
-
import
|
|
97604
|
+
import fs6 from "node:fs";
|
|
97605
|
+
import path6 from "node:path";
|
|
97162
97606
|
import { fileURLToPath as fileURLToPath2 } from "node:url";
|
|
97163
|
-
var __dirname =
|
|
97164
|
-
var REPO_ROOT =
|
|
97607
|
+
var __dirname = path6.dirname(fileURLToPath2(import.meta.url));
|
|
97608
|
+
var REPO_ROOT = path6.resolve(__dirname, "..", "..", "..");
|
|
97165
97609
|
var HEALTH_TIMEOUT_MS = 800;
|
|
97166
97610
|
var pendingStart = null;
|
|
97167
97611
|
function dashboardLogPath() {
|
|
97168
|
-
return
|
|
97612
|
+
return path6.join(getDataDir(), "server.log");
|
|
97169
97613
|
}
|
|
97170
97614
|
function launchdPlistPath() {
|
|
97171
|
-
return
|
|
97615
|
+
return path6.join(getDataDir(), "dashboard.launchd.plist");
|
|
97172
97616
|
}
|
|
97173
97617
|
function launchdLabel() {
|
|
97174
97618
|
let hash = 5381;
|
|
@@ -97264,18 +97708,18 @@ function spawnViaLaunchd(bin, args, cwd, log) {
|
|
|
97264
97708
|
const label = launchdLabel();
|
|
97265
97709
|
const plist = launchdPlistPath();
|
|
97266
97710
|
try {
|
|
97267
|
-
|
|
97711
|
+
fs6.writeFileSync(plist, renderLaunchdPlist(bin, args, cwd, log), "utf8");
|
|
97268
97712
|
spawnSync("launchctl", ["bootout", `${domain}/${label}`], { stdio: "ignore" });
|
|
97269
97713
|
const res = spawnSync("launchctl", ["bootstrap", domain, plist], {
|
|
97270
97714
|
encoding: "utf8",
|
|
97271
97715
|
timeout: 5e3
|
|
97272
97716
|
});
|
|
97273
97717
|
if (res.status === 0) return true;
|
|
97274
|
-
|
|
97718
|
+
fs6.appendFileSync(log, `[${(/* @__PURE__ */ new Date()).toISOString()}] launchctl bootstrap failed: ${res.stderr || res.stdout || res.status}
|
|
97275
97719
|
`);
|
|
97276
97720
|
} catch (e) {
|
|
97277
97721
|
try {
|
|
97278
|
-
|
|
97722
|
+
fs6.appendFileSync(log, `[${(/* @__PURE__ */ new Date()).toISOString()}] launchctl launch failed: ${e instanceof Error ? e.message : String(e)}
|
|
97279
97723
|
`);
|
|
97280
97724
|
} catch {
|
|
97281
97725
|
}
|
|
@@ -97301,16 +97745,16 @@ async function ensureServer(timeoutMs = 12e3) {
|
|
|
97301
97745
|
}
|
|
97302
97746
|
}
|
|
97303
97747
|
async function startServerBackground(timeoutMs) {
|
|
97304
|
-
const [bin, args, cwd] = BUNDLED ? [process.execPath, ["--experimental-sqlite",
|
|
97748
|
+
const [bin, args, cwd] = BUNDLED ? [process.execPath, ["--experimental-sqlite", path6.join(__dirname, "web.mjs")], __dirname] : [
|
|
97305
97749
|
process.execPath,
|
|
97306
|
-
["--no-warnings", "--experimental-sqlite", "--import", "tsx",
|
|
97750
|
+
["--no-warnings", "--experimental-sqlite", "--import", "tsx", path6.join(REPO_ROOT, "apps/web/src/index.ts")],
|
|
97307
97751
|
REPO_ROOT
|
|
97308
97752
|
];
|
|
97309
97753
|
const log = dashboardLogPath();
|
|
97310
97754
|
let logFd = null;
|
|
97311
97755
|
try {
|
|
97312
|
-
logFd =
|
|
97313
|
-
|
|
97756
|
+
logFd = fs6.openSync(log, "a");
|
|
97757
|
+
fs6.writeSync(logFd, `
|
|
97314
97758
|
[${(/* @__PURE__ */ new Date()).toISOString()}] CareerMate dashboard background launch
|
|
97315
97759
|
`);
|
|
97316
97760
|
} catch {
|
|
@@ -97323,7 +97767,7 @@ async function startServerBackground(timeoutMs) {
|
|
|
97323
97767
|
} finally {
|
|
97324
97768
|
if (logFd !== null) {
|
|
97325
97769
|
try {
|
|
97326
|
-
|
|
97770
|
+
fs6.closeSync(logFd);
|
|
97327
97771
|
} catch {
|
|
97328
97772
|
}
|
|
97329
97773
|
}
|
|
@@ -97336,7 +97780,7 @@ async function startServerBackground(timeoutMs) {
|
|
|
97336
97780
|
}
|
|
97337
97781
|
if (launchedViaLaunchd) {
|
|
97338
97782
|
try {
|
|
97339
|
-
|
|
97783
|
+
fs6.appendFileSync(log, `[${(/* @__PURE__ */ new Date()).toISOString()}] launchd did not produce a healthy server; falling back to detached spawn
|
|
97340
97784
|
`);
|
|
97341
97785
|
} catch {
|
|
97342
97786
|
}
|
|
@@ -97378,8 +97822,8 @@ async function resolveDashboardUrl(hash = "") {
|
|
|
97378
97822
|
}
|
|
97379
97823
|
|
|
97380
97824
|
// packages/mcp-tools/src/update.ts
|
|
97381
|
-
import
|
|
97382
|
-
import
|
|
97825
|
+
import fs7 from "node:fs";
|
|
97826
|
+
import path7 from "node:path";
|
|
97383
97827
|
import { fileURLToPath as fileURLToPath3 } from "node:url";
|
|
97384
97828
|
import { spawn as spawn2 } from "node:child_process";
|
|
97385
97829
|
var REGISTRY_URL = "https://registry.npmjs.org/careermate/latest";
|
|
@@ -97387,7 +97831,7 @@ var CACHE_TTL_MS = 24 * 60 * 60 * 1e3;
|
|
|
97387
97831
|
var NULL_CACHE_TTL_MS = 30 * 60 * 1e3;
|
|
97388
97832
|
var FETCH_TIMEOUT_MS = 1500;
|
|
97389
97833
|
var INSTALL_TIMEOUT_MS = 12e4;
|
|
97390
|
-
var cacheFile = () =>
|
|
97834
|
+
var cacheFile = () => path7.join(getDataDir(), ".update-check.json");
|
|
97391
97835
|
function checkDisabled() {
|
|
97392
97836
|
const v = process.env.CAREERMATE_NO_UPDATE_CHECK?.trim().toLowerCase();
|
|
97393
97837
|
return v === "1" || v === "true";
|
|
@@ -97435,14 +97879,14 @@ function comparePrerelease(a, b) {
|
|
|
97435
97879
|
}
|
|
97436
97880
|
function readCache() {
|
|
97437
97881
|
try {
|
|
97438
|
-
return JSON.parse(
|
|
97882
|
+
return JSON.parse(fs7.readFileSync(cacheFile(), "utf8"));
|
|
97439
97883
|
} catch {
|
|
97440
97884
|
return null;
|
|
97441
97885
|
}
|
|
97442
97886
|
}
|
|
97443
97887
|
function writeCache(c) {
|
|
97444
97888
|
try {
|
|
97445
|
-
|
|
97889
|
+
fs7.writeFileSync(cacheFile(), JSON.stringify(c), "utf8");
|
|
97446
97890
|
} catch {
|
|
97447
97891
|
}
|
|
97448
97892
|
}
|
|
@@ -97473,13 +97917,13 @@ function refreshInBackground() {
|
|
|
97473
97917
|
refreshing = false;
|
|
97474
97918
|
});
|
|
97475
97919
|
}
|
|
97476
|
-
var __dirname2 =
|
|
97920
|
+
var __dirname2 = path7.dirname(fileURLToPath3(import.meta.url));
|
|
97477
97921
|
function installPrefix() {
|
|
97478
97922
|
if (!BUNDLED) return null;
|
|
97479
|
-
const pkgRoot =
|
|
97480
|
-
const parent =
|
|
97481
|
-
if (
|
|
97482
|
-
return
|
|
97923
|
+
const pkgRoot = path7.resolve(__dirname2, "..");
|
|
97924
|
+
const parent = path7.dirname(pkgRoot);
|
|
97925
|
+
if (path7.basename(parent) !== "node_modules") return null;
|
|
97926
|
+
return path7.dirname(parent);
|
|
97483
97927
|
}
|
|
97484
97928
|
function manualCommand() {
|
|
97485
97929
|
const prefix = installPrefix();
|
|
@@ -97612,13 +98056,13 @@ var DASHBOARD_URL = "http://127.0.0.1:4319";
|
|
|
97612
98056
|
function listInboxFiles(dir) {
|
|
97613
98057
|
let names;
|
|
97614
98058
|
try {
|
|
97615
|
-
names =
|
|
98059
|
+
names = fs8.readdirSync(dir);
|
|
97616
98060
|
} catch {
|
|
97617
98061
|
return [];
|
|
97618
98062
|
}
|
|
97619
98063
|
let realDir;
|
|
97620
98064
|
try {
|
|
97621
|
-
realDir =
|
|
98065
|
+
realDir = fs8.realpathSync.native(dir);
|
|
97622
98066
|
} catch {
|
|
97623
98067
|
realDir = dir;
|
|
97624
98068
|
}
|
|
@@ -97626,12 +98070,12 @@ function listInboxFiles(dir) {
|
|
|
97626
98070
|
const out = [];
|
|
97627
98071
|
for (const name of names) {
|
|
97628
98072
|
if (SKIP.test(name)) continue;
|
|
97629
|
-
const p =
|
|
98073
|
+
const p = path8.join(dir, name);
|
|
97630
98074
|
try {
|
|
97631
|
-
if (!
|
|
97632
|
-
const real =
|
|
97633
|
-
const rel =
|
|
97634
|
-
if (rel.startsWith("..") ||
|
|
98075
|
+
if (!fs8.statSync(p).isFile()) continue;
|
|
98076
|
+
const real = fs8.realpathSync.native(p);
|
|
98077
|
+
const rel = path8.relative(realDir, real);
|
|
98078
|
+
if (rel.startsWith("..") || path8.isAbsolute(rel)) continue;
|
|
97635
98079
|
out.push({ name, path: p });
|
|
97636
98080
|
} catch {
|
|
97637
98081
|
}
|
|
@@ -97659,10 +98103,10 @@ function pickRoute(ctx) {
|
|
|
97659
98103
|
return "write_cover_letter";
|
|
97660
98104
|
}
|
|
97661
98105
|
function writeExport(result2) {
|
|
97662
|
-
const filePath =
|
|
98106
|
+
const filePath = path8.join(getExportsDir(), result2.filename);
|
|
97663
98107
|
try {
|
|
97664
|
-
if (result2.bytes)
|
|
97665
|
-
else
|
|
98108
|
+
if (result2.bytes) fs8.writeFileSync(filePath, result2.bytes);
|
|
98109
|
+
else fs8.writeFileSync(filePath, result2.content, "utf8");
|
|
97666
98110
|
return { path: filePath };
|
|
97667
98111
|
} catch (e) {
|
|
97668
98112
|
return { error: `\uD30C\uC77C \uC800\uC7A5 \uC2E4\uD328: ${e instanceof Error ? e.message : e}` };
|
|
@@ -97682,11 +98126,11 @@ var TOOLS = [
|
|
|
97682
98126
|
handler: async (args) => {
|
|
97683
98127
|
const r = await extractDocument(args.path);
|
|
97684
98128
|
if (r.errored) {
|
|
97685
|
-
return fail(`'${
|
|
98129
|
+
return fail(`'${path8.basename(r.path)}'\uC744(\uB97C) \uC77D\uC9C0 \uBABB\uD588\uC2B5\uB2C8\uB2E4.
|
|
97686
98130
|
${r.warnings.join("\n")}`);
|
|
97687
98131
|
}
|
|
97688
98132
|
if (r.unsupported) {
|
|
97689
|
-
return ok(`'${
|
|
98133
|
+
return ok(`'${path8.basename(r.path)}'\uC740(\uB294) \uD14D\uC2A4\uD2B8\uB85C \uCD94\uCD9C\uD560 \uC218 \uC5C6\uC2B5\uB2C8\uB2E4.
|
|
97690
98134
|
${r.warnings.join("\n")}`, {
|
|
97691
98135
|
path: r.path,
|
|
97692
98136
|
format: r.format,
|
|
@@ -97701,7 +98145,7 @@ ${r.warnings.join("\n")}`, {
|
|
|
97701
98145
|
truncated = true;
|
|
97702
98146
|
}
|
|
97703
98147
|
const head = [
|
|
97704
|
-
`'${
|
|
98148
|
+
`'${path8.basename(r.path)}'\uC5D0\uC11C \uD14D\uC2A4\uD2B8\uB97C \uCD94\uCD9C\uD588\uC2B5\uB2C8\uB2E4 (${r.format.toUpperCase()}, ${text.length.toLocaleString()}\uC790${truncated ? ", \uC798\uB9BC" : ""}).`,
|
|
97705
98149
|
...r.warnings,
|
|
97706
98150
|
"\uC774 \uB0B4\uC6A9\uC744 \uADFC\uAC70\uB85C \uC791\uC5C5\uD55C \uB4A4 \uACB0\uACFC\uB97C \uC54C\uB9DE\uC740 CareerMate \uB3C4\uAD6C\uB85C \uC800\uC7A5\uD558\uC138\uC694."
|
|
97707
98151
|
].join("\n");
|
|
@@ -97831,6 +98275,8 @@ ${lines}`;
|
|
|
97831
98275
|
},
|
|
97832
98276
|
{
|
|
97833
98277
|
name: "save_profile",
|
|
98278
|
+
idempotent: true,
|
|
98279
|
+
// 부분 업서트 — 같은 인자 재호출은 같은 결과
|
|
97834
98280
|
title: "\uD504\uB85C\uD544 \uC800\uC7A5",
|
|
97835
98281
|
description: "\uC0AC\uC6A9\uC790 \uD504\uB85C\uD544\uC744 \uC800\uC7A5\uD569\uB2C8\uB2E4. \uC804\uB2EC\uD55C \uD544\uB4DC\uB9CC \uAC31\uC2E0\uB418\uACE0 \uB098\uBA38\uC9C0\uB294 \uC720\uC9C0\uB429\uB2C8\uB2E4(\uBD80\uBD84 \uC800\uC7A5 \uC548\uC804). \uC774\uB825\uC11C\uB97C \uAD6C\uC870\uD654\uD55C \uB4A4 \uC774\uB984/\uD55C \uC904 \uC18C\uAC1C/\uD76C\uB9DD \uC9C1\uBB34/\uC120\uD638 \uBB38\uCCB4/\uAC15\uC870 \uD3EC\uC778\uD2B8 \uB4F1\uC744 \uCC44\uC6CC \uC800\uC7A5\uD558\uC138\uC694. \uC120\uD638 \uBB38\uCCB4(preferred_tone)\uC640 \uAC15\uC870 \uD3EC\uC778\uD2B8(emphasis_points)\uB294 \uC774\uD6C4 \uC790\uAE30\uC18C\uAC1C\uC11C \uC791\uC131 \uD488\uC9C8\uC5D0 \uC9C1\uC811 \uC601\uD5A5\uC744 \uC90D\uB2C8\uB2E4. \uD559\uB825(education)\xB7\uC790\uACA9\uC99D(certifications)\xB7\uC5B4\uD559\uC810\uC218(language_scores: \uD1A0\uC775\xB7\uC624\uD53D \uB4F1)\xB7\uC218\uC0C1(awards)\uC774 \uC774\uB825\uC11C\uC5D0 \uC788\uC73C\uBA74 \uAD6C\uC870\uD654\uD574 \uC800\uC7A5\uD558\uC138\uC694 \u2014 \uD55C\uAD6D \uC774\uB825\uC11C \uD575\uC2EC \uC2A4\uD399\uC774\uACE0, \uC800\uC7A5\uD558\uBA74 \uC774\uD6C4 \uC790\uC18C\uC11C\xB7\uC774\uB825\uC11C\uC5D0\uC11C \uC815\uD655\uD55C \uC218\uCE58(\uD559\uC810 3.8, \uD1A0\uC775 920)\uB97C \uC9C0\uC5B4\uB0B4\uC9C0 \uC54A\uACE0 \uADF8\uB300\uB85C \uC778\uC6A9\uD569\uB2C8\uB2E4.",
|
|
97836
98282
|
inputSchema: ProfileInputSchema.shape,
|
|
@@ -97869,6 +98315,7 @@ ${lines}`;
|
|
|
97869
98315
|
},
|
|
97870
98316
|
{
|
|
97871
98317
|
name: "delete_resume",
|
|
98318
|
+
destructive: true,
|
|
97872
98319
|
title: "\uC774\uB825\uC11C/\uBB38\uC11C \uC0AD\uC81C",
|
|
97873
98320
|
description: "\uC800\uC7A5\uB41C \uC774\uB825\uC11C\xB7\uACBD\uB825\uAE30\uC220\uC11C\xB7\uD3EC\uD2B8\uD3F4\uB9AC\uC624 \uB4F1 \uBB38\uC11C\uB97C \uC0AD\uC81C\uD569\uB2C8\uB2E4. \uC0AC\uC6A9\uC790\uAC00 \uBA85\uD655\uD788 \uC0AD\uC81C\uB97C \uC694\uCCAD\uD588\uC744 \uB54C\uB9CC \uC0AC\uC6A9\uD558\uC138\uC694. \uBA3C\uC800 get_resumes\uB85C \uBAA9\uB85D\uC744 \uD655\uC778\uD558\uACE0 \uC5B4\uB5A4 \uBB38\uC11C\uC778\uC9C0 \uC0AC\uC6A9\uC790\uC640 \uD655\uC778\uD55C \uB4A4 \uD638\uCD9C\uD569\uB2C8\uB2E4. confirm\uC5D0\uB294 DELETE\uB97C \uB123\uC73C\uC138\uC694.",
|
|
97874
98321
|
inputSchema: {
|
|
@@ -97887,6 +98334,8 @@ ${lines}`;
|
|
|
97887
98334
|
/* ----------------------------------------------------------- experiences */
|
|
97888
98335
|
{
|
|
97889
98336
|
name: "add_experience",
|
|
98337
|
+
idempotent: true,
|
|
98338
|
+
// 회사·직무·입사일 키 업서트(adr_0003) — 재호출 안전
|
|
97890
98339
|
title: "\uACBD\uB825 \uCD94\uAC00",
|
|
97891
98340
|
description: "\uAD6C\uC870\uD654\uB41C \uACBD\uB825(\uC9C1\uC7A5 \uB2E8\uC704)\uC744 \uC800\uC7A5\uD569\uB2C8\uB2E4. \uC774\uB825\uC11C\uC5D0\uC11C \uD30C\uC545\uD55C \uACBD\uB825\uC744 experiences \uBC30\uC5F4\uC5D0 \uD55C \uBC88\uC5D0 \uB2F4\uC544 \uD638\uCD9C\uD558\uC138\uC694(\uD55C \uAC74\uC774\uC5B4\uB3C4 \uBC30\uC5F4\uB85C \u2014 \uD56D\uBAA9\uB9C8\uB2E4 \uB3C4\uAD6C\uB97C \uBC18\uBCF5 \uD638\uCD9C\uD558\uC9C0 \uB9C8\uC138\uC694). \uC774\uB825\uC11C \uBCF8\uBB38(add_resume)\uACFC \uB2EC\uB9AC \uD68C\uC0AC\xB7\uC9C1\uBB34\xB7\uAE30\uAC04\xB7\uC131\uACFC\uB97C \uD544\uB4DC\uB85C \uB098\uB220 \uC800\uC7A5\uD574 \uC801\uD569\uB3C4 \uBD84\uC11D/\uC790\uC18C\uC11C \uC791\uC131 \uC2DC \uC815\uBC00\uD558\uAC8C \uD65C\uC6A9\uB429\uB2C8\uB2E4. \uAC01 \uD56D\uBAA9\uC740 company\uAC00 \uD544\uC218\uC774\uBA70, achievements\uC5D0\uB294 \uC815\uB7C9 \uC9C0\uD45C\uAC00 \uB2F4\uAE34 \uC131\uACFC\uB97C, tech\uC5D0\uB294 \uC0AC\uC6A9 \uAE30\uC220\uC744 \uBC30\uC5F4\uB85C \uB123\uC73C\uC138\uC694. \uAC19\uC740 \uD68C\uC0AC\xB7\uC9C1\uBB34\xB7\uC785\uC0AC\uC77C(start_date)\uC774 \uC77C\uCE58\uD558\uBA74 \uAC31\uC2E0\uB418\uACE0 \uC911\uBCF5 \uC0DD\uC131\uB418\uC9C0 \uC54A\uC73C\uB2C8 \uC5EC\uB7EC \uBC88 \uC800\uC7A5\uD574\uB3C4 \uC548\uC804\uD569\uB2C8\uB2E4. \uC628\uBCF4\uB529 \uC644\uC131\uB3C4(get_onboarding_status)\uC758 has_experience\uB97C \uCC44\uC6B0\uB824\uBA74 1\uAC74 \uC774\uC0C1 \uCD94\uAC00\uD558\uC138\uC694.",
|
|
97892
98341
|
inputSchema: ExperienceBatchInputSchema.shape,
|
|
@@ -97910,6 +98359,8 @@ ${lines}`;
|
|
|
97910
98359
|
/* -------------------------------------------------------------- projects */
|
|
97911
98360
|
{
|
|
97912
98361
|
name: "add_project",
|
|
98362
|
+
idempotent: true,
|
|
98363
|
+
// 이름 키 업서트 — 재호출 안전
|
|
97913
98364
|
title: "\uD504\uB85C\uC81D\uD2B8 \uCD94\uAC00",
|
|
97914
98365
|
description: "\uB300\uD45C \uD504\uB85C\uC81D\uD2B8\uB97C \uC800\uC7A5\uD569\uB2C8\uB2E4. projects \uBC30\uC5F4\uC5D0 \uC5EC\uB7EC \uAC1C\uB97C \uD55C \uBC88\uC5D0 \uB2F4\uC544 \uD638\uCD9C\uD558\uC138\uC694(\uD55C \uAC1C\uC5EC\uB3C4 \uBC30\uC5F4\uB85C \u2014 \uD56D\uBAA9\uB9C8\uB2E4 \uBC18\uBCF5 \uD638\uCD9C\uD558\uC9C0 \uB9C8\uC138\uC694). \uAC01 \uD56D\uBAA9\uC740 name\uC774 \uD544\uC218\uC774\uBA70, highlights(\uD575\uC2EC \uC131\uACFC)\uC640 tech(\uC0AC\uC6A9 \uAE30\uC220)\uB97C \uBC30\uC5F4\uB85C \uB123\uC73C\uBA74 \uC790\uC18C\uC11C\xB7\uBA74\uC811 \uC900\uBE44\uC5D0\uC11C \uADFC\uAC70\uB85C \uD65C\uC6A9\uB429\uB2C8\uB2E4. url\uC5D0 \uACB0\uACFC\uBB3C \uB9C1\uD06C\uB97C \uB123\uC744 \uC218 \uC788\uC2B5\uB2C8\uB2E4. \uAC19\uC740 \uC774\uB984\uC758 \uD504\uB85C\uC81D\uD2B8\uB294 \uAC31\uC2E0\uB418\uACE0 \uC911\uBCF5 \uC0DD\uC131\uB418\uC9C0 \uC54A\uC73C\uB2C8 \uC5EC\uB7EC \uBC88 \uC800\uC7A5\uD574\uB3C4 \uC548\uC804\uD569\uB2C8\uB2E4.",
|
|
97915
98366
|
inputSchema: ProjectBatchInputSchema.shape,
|
|
@@ -97933,6 +98384,8 @@ ${lines}`;
|
|
|
97933
98384
|
/* ---------------------------------------------------------------- skills */
|
|
97934
98385
|
{
|
|
97935
98386
|
name: "add_skill",
|
|
98387
|
+
idempotent: true,
|
|
98388
|
+
// 이름 키 업서트 — 재호출 안전
|
|
97936
98389
|
title: "\uAE30\uC220\uC2A4\uD0DD \uCD94\uAC00",
|
|
97937
98390
|
description: "\uBCF4\uC720 \uAE30\uC220\uC2A4\uD0DD\uC744 \uC800\uC7A5\uD569\uB2C8\uB2E4. \uC5EC\uB7EC \uAC1C\uB97C skills \uBC30\uC5F4\uC5D0 \uD55C \uBC88\uC5D0 \uB2F4\uC544 \uD638\uCD9C\uD558\uC138\uC694(\uD55C \uAC1C\uC5EC\uB3C4 \uBC30\uC5F4\uB85C \u2014 \uAE30\uC220\uB9C8\uB2E4 \uB3C4\uAD6C\uB97C \uBC18\uBCF5 \uD638\uCD9C\uD558\uC9C0 \uB9C8\uC138\uC694). \uAC01 \uD56D\uBAA9\uC740 name\uC774 \uD544\uC218\uC774\uBA70, category(\uC5B8\uC5B4/\uD504\uB808\uC784\uC6CC\uD06C/\uD234/\uC18C\uD504\uD2B8\uC2A4\uD0AC \uB4F1)\xB7level\xB7years\uB85C \uC219\uB828\uB3C4\uB97C \uD568\uAED8 \uAE30\uB85D\uD558\uBA74 \uACF5\uACE0 \uD0A4\uC6CC\uB4DC \uB9E4\uCE6D\uC774 \uC815\uD655\uD574\uC9D1\uB2C8\uB2E4. \uAC19\uC740 \uC774\uB984\uC758 \uAE30\uC220\uC740 \uAC31\uC2E0\uB418\uACE0 \uC911\uBCF5 \uC0DD\uC131\uB418\uC9C0 \uC54A\uC73C\uB2C8 \uC5EC\uB7EC \uBC88 \uC800\uC7A5\uD574\uB3C4 \uC548\uC804\uD569\uB2C8\uB2E4. \uC628\uBCF4\uB529 \uC644\uC131\uB3C4\uC758 has_skills\uB97C \uCC44\uC6B0\uB824\uBA74 1\uAC1C \uC774\uC0C1 \uCD94\uAC00\uD558\uC138\uC694.",
|
|
97938
98391
|
inputSchema: SkillBatchInputSchema.shape,
|
|
@@ -97955,6 +98408,7 @@ ${lines}`;
|
|
|
97955
98408
|
},
|
|
97956
98409
|
{
|
|
97957
98410
|
name: "delete_experience",
|
|
98411
|
+
destructive: true,
|
|
97958
98412
|
title: "\uACBD\uB825 \uD56D\uBAA9 \uC0AD\uC81C",
|
|
97959
98413
|
description: "\uAD6C\uC870\uD654\uB41C \uACBD\uB825(\uC9C1\uC7A5) \uD56D\uBAA9 \uD558\uB098\uB97C \uC0AD\uC81C\uD569\uB2C8\uB2E4. \uC798\uBABB \uCD94\uCD9C/\uC785\uB825\uB41C \uACBD\uB825\uC744 \uC9C0\uC6B8 \uB54C \uC0AC\uC6A9\uD558\uC138\uC694. \uBA3C\uC800 get_experiences\uB85C \uBAA9\uB85D\uACFC id\uB97C \uD655\uC778\uD558\uACE0 \uC0AC\uC6A9\uC790\uC640 \uD655\uC778\uD55C \uB4A4 \uD638\uCD9C\uD569\uB2C8\uB2E4. (\uB0B4\uC6A9 \uC218\uC815\uC740 add_experience\uB85C \uAC19\uC740 \uD56D\uBAA9\uC744 \uB2E4\uC2DC \uC800\uC7A5\uD558\uBA74 \uAC31\uC2E0\uB429\uB2C8\uB2E4.) confirm\uC5D0\uB294 DELETE\uB97C \uB123\uC73C\uC138\uC694.",
|
|
97960
98414
|
inputSchema: {
|
|
@@ -97972,6 +98426,7 @@ ${lines}`;
|
|
|
97972
98426
|
},
|
|
97973
98427
|
{
|
|
97974
98428
|
name: "delete_project",
|
|
98429
|
+
destructive: true,
|
|
97975
98430
|
title: "\uD504\uB85C\uC81D\uD2B8 \uD56D\uBAA9 \uC0AD\uC81C",
|
|
97976
98431
|
description: "\uAD6C\uC870\uD654\uB41C \uD504\uB85C\uC81D\uD2B8 \uD56D\uBAA9 \uD558\uB098\uB97C \uC0AD\uC81C\uD569\uB2C8\uB2E4. \uC798\uBABB \uCD94\uCD9C/\uC785\uB825\uB41C \uD504\uB85C\uC81D\uD2B8\uB97C \uC9C0\uC6B8 \uB54C \uC0AC\uC6A9\uD558\uC138\uC694. \uBA3C\uC800 get_projects\uB85C \uBAA9\uB85D\uACFC id\uB97C \uD655\uC778\uD558\uACE0 \uC0AC\uC6A9\uC790\uC640 \uD655\uC778\uD55C \uB4A4 \uD638\uCD9C\uD569\uB2C8\uB2E4. (\uB0B4\uC6A9 \uC218\uC815\uC740 add_project\uB85C \uAC19\uC740 \uD56D\uBAA9\uC744 \uB2E4\uC2DC \uC800\uC7A5\uD558\uBA74 \uAC31\uC2E0\uB429\uB2C8\uB2E4.) confirm\uC5D0\uB294 DELETE\uB97C \uB123\uC73C\uC138\uC694.",
|
|
97977
98432
|
inputSchema: {
|
|
@@ -97989,6 +98444,7 @@ ${lines}`;
|
|
|
97989
98444
|
},
|
|
97990
98445
|
{
|
|
97991
98446
|
name: "delete_skill",
|
|
98447
|
+
destructive: true,
|
|
97992
98448
|
title: "\uAE30\uC220\uC2A4\uD0DD \uD56D\uBAA9 \uC0AD\uC81C",
|
|
97993
98449
|
description: "\uAD6C\uC870\uD654\uB41C \uAE30\uC220\uC2A4\uD0DD \uD56D\uBAA9 \uD558\uB098\uB97C \uC0AD\uC81C\uD569\uB2C8\uB2E4. \uC798\uBABB \uCD94\uCD9C/\uC785\uB825\uB41C \uAE30\uC220\uC744 \uC9C0\uC6B8 \uB54C \uC0AC\uC6A9\uD558\uC138\uC694. \uBA3C\uC800 get_skills\uB85C \uBAA9\uB85D\uACFC id\uB97C \uD655\uC778\uD558\uACE0 \uC0AC\uC6A9\uC790\uC640 \uD655\uC778\uD55C \uB4A4 \uD638\uCD9C\uD569\uB2C8\uB2E4. (\uB0B4\uC6A9 \uC218\uC815\uC740 add_skill\uB85C \uAC19\uC740 \uD56D\uBAA9\uC744 \uB2E4\uC2DC \uC800\uC7A5\uD558\uBA74 \uAC31\uC2E0\uB429\uB2C8\uB2E4.) confirm\uC5D0\uB294 DELETE\uB97C \uB123\uC73C\uC138\uC694.",
|
|
97994
98450
|
inputSchema: {
|
|
@@ -98037,6 +98493,7 @@ ${lines}`;
|
|
|
98037
98493
|
},
|
|
98038
98494
|
{
|
|
98039
98495
|
name: "delete_cover_letter",
|
|
98496
|
+
destructive: true,
|
|
98040
98497
|
title: "\uC790\uAE30\uC18C\uAC1C\uC11C \uC0AD\uC81C",
|
|
98041
98498
|
description: "\uC0AC\uC6A9\uC790\uAC00 \uC800\uC7A5\uB41C \uC790\uAE30\uC18C\uAC1C\uC11C \uC0AD\uC81C\uB97C \uBA85\uD655\uD788 \uC694\uCCAD\uD588\uC744 \uB54C\uB9CC \uC0AC\uC6A9\uD569\uB2C8\uB2E4. \uBA3C\uC800 get_cover_letters\uB85C \uC804\uCCB4 \uBAA9\uB85D \uB610\uB294 \uACF5\uACE0\uBCC4 \uBAA9\uB85D\uC744 \uD655\uC778\uD558\uACE0, \uC0AD\uC81C\uD560 \uD56D\uBAA9\uC744 \uC0AC\uC6A9\uC790\uAC00 \uD655\uC778\uD55C \uB4A4 \uD638\uCD9C\uD558\uC138\uC694. \uC0AD\uC81C\uD558\uBA74 \uD574\uB2F9 \uC790\uAE30\uC18C\uAC1C\uC11C\uC758 \uBAA8\uB4E0 \uBC84\uC804\uC774 \uD568\uAED8 \uC0AD\uC81C\uB418\uBA70 \uB418\uB3CC\uB9B4 \uC218 \uC5C6\uC2B5\uB2C8\uB2E4. confirm\uC5D0\uB294 DELETE\uB97C \uB123\uC73C\uC138\uC694.",
|
|
98042
98499
|
inputSchema: {
|
|
@@ -98063,8 +98520,10 @@ ${lines}`;
|
|
|
98063
98520
|
/* ------------------------------------------------------------------ jobs */
|
|
98064
98521
|
{
|
|
98065
98522
|
name: "save_job_posting",
|
|
98523
|
+
idempotent: true,
|
|
98524
|
+
// 같은 url 업서트 — 재호출 안전
|
|
98066
98525
|
title: "\uCC44\uC6A9\uACF5\uACE0 \uC800\uC7A5",
|
|
98067
|
-
description: "\uCC44\uC6A9\uACF5\uACE0\uB97C \uC800\uC7A5\uD569\uB2C8\uB2E4(\uC788\uC73C\uBA74 \uAC31\uC2E0). company\uC640 position\uC740 \uD544\uC218\uC785\uB2C8\uB2E4. \uACF5\uACE0 \uC6D0\uBB38\uC740 description\uC5D0, \uD575\uC2EC \uC790\uACA9\uC694\uAC74/\uC6B0\uB300\uC0AC\uD56D\uC740 requirements \uBC30\uC5F4\uC5D0, \uD575\uC2EC \uD0A4\uC6CC\uB4DC\uB294 keywords\uC5D0 \uC815\uB9AC\uD574 \uB123\uC73C\uBA74 \uC774\uD6C4 \uC801\uD569\uB3C4 \uBD84\uC11D/\uC790\uC18C\uC11C \uC791\uC131\uC5D0 \uD65C\uC6A9\uB429\uB2C8\uB2E4. \uD68C\uC0AC\uB97C \uB9AC\uC11C\uCE58\uD588\uB2E4\uBA74 \uC0AC\uC5C5\uAC1C\uC694\xB7\uBBF8\uC158\uC740 company_overview, \uD68C\uC0AC\uAC00 \uAC15\uC870\uD558\uB294 \uC778\uC7AC\uC0C1\uC740 talent_profile, \uD575\uC2EC\uAC00\uCE58\uB294 core_values\uC5D0 \uB123\uC73C\uC138\uC694 \u2014 \uD55C\uAD6D \uC790\uC18C\uC11C\xB7\uBA74\uC811\uC740 \uC778\uC7AC\uC0C1/\uD575\uC2EC\uAC00\uCE58 \uC815\uB82C\uC774 \uD575\uC2EC\uC774\uB77C \uC800\uC7A5\uD574\uB450\uBA74 \uC774\uD6C4 \uC791\uC131\xB7\uBA74\uC811 \uC900\uBE44\uC5D0\uC11C \uADF8\uB300\uB85C \uB04C\uC5B4\uB2E4 \uC501\uB2C8\uB2E4. \uAC19\uC740 url\uC774\uBA74 \uC911\uBCF5 \uC0DD\uC131 \uC5C6\uC774 \uAC31\uC2E0\uB429\uB2C8\uB2E4. \uC800\uC7A5 \uC2DC \uC9C0\uC6D0(application) \uD56D\uBAA9\uC774 \uC790\uB3D9\uC73C\uB85C \uC0DD\uC131\uB429\uB2C8\uB2E4.",
|
|
98526
|
+
description: "\uCC44\uC6A9\uACF5\uACE0\uB97C \uC800\uC7A5\uD569\uB2C8\uB2E4(\uC788\uC73C\uBA74 \uAC31\uC2E0). company\uC640 position\uC740 \uD544\uC218\uC785\uB2C8\uB2E4. \uACF5\uACE0 \uC6D0\uBB38\uC740 description\uC5D0, \uD575\uC2EC \uC790\uACA9\uC694\uAC74/\uC6B0\uB300\uC0AC\uD56D\uC740 requirements \uBC30\uC5F4\uC5D0, \uD575\uC2EC \uD0A4\uC6CC\uB4DC\uB294 keywords\uC5D0 \uC815\uB9AC\uD574 \uB123\uC73C\uBA74 \uC774\uD6C4 \uC801\uD569\uB3C4 \uBD84\uC11D/\uC790\uC18C\uC11C \uC791\uC131\uC5D0 \uD65C\uC6A9\uB429\uB2C8\uB2E4. \uD68C\uC0AC\uB97C \uB9AC\uC11C\uCE58\uD588\uB2E4\uBA74 \uC0AC\uC5C5\uAC1C\uC694\xB7\uBBF8\uC158\uC740 company_overview, \uD68C\uC0AC\uAC00 \uAC15\uC870\uD558\uB294 \uC778\uC7AC\uC0C1\uC740 talent_profile, \uD575\uC2EC\uAC00\uCE58\uB294 core_values\uC5D0 \uB123\uC73C\uC138\uC694 \u2014 \uD55C\uAD6D \uC790\uC18C\uC11C\xB7\uBA74\uC811\uC740 \uC778\uC7AC\uC0C1/\uD575\uC2EC\uAC00\uCE58 \uC815\uB82C\uC774 \uD575\uC2EC\uC774\uB77C \uC800\uC7A5\uD574\uB450\uBA74 \uC774\uD6C4 \uC791\uC131\xB7\uBA74\uC811 \uC900\uBE44\uC5D0\uC11C \uADF8\uB300\uB85C \uB04C\uC5B4\uB2E4 \uC501\uB2C8\uB2E4. \uD68C\uC0AC \uD3C9\uD310(\uD3C9\uC810\xB7\uC6CC\uB77C\uBC38\xB7\uBB38\uD654 \uB9AC\uC2A4\uD06C \uB4F1)\uC744 \uB9AC\uC11C\uCE58\uD588\uB2E4\uBA74 reputation\uC5D0 \uC694\uC57D(\uCD9C\uCC98\xB7\uCD5C\uADFC\uC131 \uD45C\uAE30)\uC744 \uB123\uC73C\uBA74 \uC624\uD37C \uD310\uB2E8\xB7\uBA74\uC811\uC5D0 \uD65C\uC6A9\uB429\uB2C8\uB2E4. \uD68C\uC0AC \uC9C0\uC815 \uC790\uC18C\uC11C \uBB38\uD56D\xB7\uAE00\uC790\uC218\uAC00 \uC788\uC73C\uBA74 questions \uBC30\uC5F4\uC5D0 \uAD6C\uC870\uD654 \uC800\uC7A5\uD558\uC138\uC694(question \uD544\uC218, max_chars/min_chars/count_mode). \uC774\uD6C4 \uC790\uC18C\uC11C \uC791\uC131 \uC2DC \uBB38\uD56D\uBCC4\uB85C validate_cover_letter(min_chars/max_chars/count_mode)\uB85C \uD55C\uB3C4\uB97C \uC810\uAC80\uD569\uB2C8\uB2E4. \uBA74\uC811\xB7\uC778\uC801\uC131\xB7\uBC1C\uD45C \uB4F1 \uC804\uD615 \uC77C\uC815\uC744 \uBC1B\uC73C\uBA74 schedule \uBC30\uC5F4\uC5D0 \uAD6C\uC870\uD654 \uC800\uC7A5\uD558\uC138\uC694(label\xB7date \uD544\uC218, time \uC120\uD0DD; \uC11C\uB958 \uB9C8\uAC10\uC740 deadline \uD544\uB4DC). \uBA74\uC811\uCD08\uB300 \uBA54\uC77C\uC744 \uC0AC\uC6A9\uC790\uAC00 \uBD99\uC5EC\uB123\uC73C\uBA74 \uB0A0\uC9DC\xB7\uC2DC\uAC04\uC744 \uCD94\uCD9C\uD574 \uC800\uC7A5\uD558\uACE0, \uAC19\uC740 \uB0A0 \uB2E4\uB978 \uC77C\uC815\uACFC \uACB9\uCE58\uBA74 \uC54C\uB824\uC8FC\uC138\uC694. \uAC19\uC740 url\uC774\uBA74 \uC911\uBCF5 \uC0DD\uC131 \uC5C6\uC774 \uAC31\uC2E0\uB429\uB2C8\uB2E4. \uC800\uC7A5 \uC2DC \uC9C0\uC6D0(application) \uD56D\uBAA9\uC774 \uC790\uB3D9\uC73C\uB85C \uC0DD\uC131\uB429\uB2C8\uB2E4.",
|
|
98068
98527
|
inputSchema: JobInputSchema.shape,
|
|
98069
98528
|
handler: (args) => {
|
|
98070
98529
|
const { job } = saveJobPosting(args);
|
|
@@ -98110,6 +98569,7 @@ ${lines}`;
|
|
|
98110
98569
|
},
|
|
98111
98570
|
{
|
|
98112
98571
|
name: "delete_job_posting",
|
|
98572
|
+
destructive: true,
|
|
98113
98573
|
title: "\uCC44\uC6A9\uACF5\uACE0 \uC0AD\uC81C",
|
|
98114
98574
|
description: "\uC0AC\uC6A9\uC790\uAC00 \uC800\uC7A5\uB41C \uCC44\uC6A9\uACF5\uACE0 \uC0AD\uC81C\uB97C \uBA85\uD655\uD788 \uC694\uCCAD\uD588\uC744 \uB54C\uB9CC \uC0AC\uC6A9\uD569\uB2C8\uB2E4. \uBA3C\uC800 list_jobs\uB85C \uC804\uCCB4 \uACF5\uACE0 \uBAA9\uB85D\uC744 \uD655\uC778\uD558\uACE0, \uC0AD\uC81C\uD560 \uACF5\uACE0\uB97C \uC0AC\uC6A9\uC790\uAC00 \uD655\uC778\uD55C \uB4A4 \uD638\uCD9C\uD558\uC138\uC694. \uC0AD\uC81C\uD558\uBA74 \uC5F0\uACB0\uB41C \uC9C0\uC6D0 \uC0C1\uD0DC\xB7\uC801\uD569\uB3C4 \uBD84\uC11D\xB7\uBA74\uC811 \uC900\uBE44\uAC00 \uD568\uAED8 \uC0AD\uC81C\uB429\uB2C8\uB2E4. \uC5F0\uACB0\uB41C \uC790\uAE30\uC18C\uAC1C\uC11C\uB294 \uC0AD\uC81C\uD558\uC9C0 \uC54A\uACE0 \uACF5\uACE0 \uC5F0\uACB0\uB9CC \uD574\uC81C\uD569\uB2C8\uB2E4. confirm\uC5D0\uB294 DELETE\uB97C \uB123\uC73C\uC138\uC694.",
|
|
98115
98575
|
inputSchema: {
|
|
@@ -98195,6 +98655,8 @@ ${lines}`;
|
|
|
98195
98655
|
},
|
|
98196
98656
|
{
|
|
98197
98657
|
name: "save_fit_analysis",
|
|
98658
|
+
idempotent: true,
|
|
98659
|
+
// 공고당 1건 업서트
|
|
98198
98660
|
title: "\uC801\uD569\uB3C4 \uBD84\uC11D \uACB0\uACFC \uC800\uC7A5",
|
|
98199
98661
|
description: "\uACF5\uACE0\uC640 \uC0AC\uC6A9\uC790 \uC815\uBCF4\uB97C \uBE44\uAD50\uD574 \uB2F9\uC2E0(AI)\uC774 \uB3C4\uCD9C\uD55C \uC801\uD569\uB3C4 \uBD84\uC11D\uC744 \uC800\uC7A5\uD569\uB2C8\uB2E4. job_id\uB294 \uD544\uC218\uC774\uBA70 \uBA3C\uC800 save_job_posting\uC73C\uB85C \uACF5\uACE0\uAC00 \uC800\uC7A5\uB418\uC5B4 \uC788\uC5B4\uC57C \uD569\uB2C8\uB2E4. score(0~100), summary, strengths(\uAC15\uC810), gaps(\uBCF4\uC644 \uD544\uC694), matched/missing_keywords, recommendations(\uC790\uC18C\uC11C\xB7\uC9C0\uC6D0 \uC804\uB7B5 \uC81C\uC548)\uB97C \uCC44\uC6CC \uC800\uC7A5\uD558\uC138\uC694. \uAC19\uC740 \uACF5\uACE0\uC5D0 \uB2E4\uC2DC \uC800\uC7A5\uD558\uBA74 \uAC31\uC2E0\uB429\uB2C8\uB2E4.",
|
|
98200
98662
|
inputSchema: FitAnalysisInputSchema.shape,
|
|
@@ -98239,27 +98701,41 @@ ${lines}`;
|
|
|
98239
98701
|
{
|
|
98240
98702
|
name: "update_application_status",
|
|
98241
98703
|
title: "\uC9C0\uC6D0 \uC0C1\uD0DC \uBCC0\uACBD",
|
|
98242
|
-
description: `\uC9C0\uC6D0 \uC0C1\uD0DC\uB97C \uBCC0\uACBD\uD569\uB2C8\uB2E4. \uAC00\uB2A5\uD55C \uC0C1\uD0DC: ${STATUS_LIST}. '\uC11C\uB958 \uD569\uACA9(document_passed)' \uC774\uC0C1\uC73C\uB85C \uBC14\uB00C\uBA74 \uBA74\uC811 \uC900\uBE44\uB97C \uC81C\uC548\uD558\uB294 \uD78C\uD2B8\uB97C \uD568\uAED8 \uB3CC\uB824\uC90D\uB2C8\uB2E4. note\uC5D0 \uBCC0\uACBD \uC0AC\uC720\uB97C \uB0A8\uAE38 \uC218 \uC788\uC2B5\uB2C8\uB2E4.`,
|
|
98704
|
+
description: `\uC9C0\uC6D0 \uC0C1\uD0DC\uB97C \uBCC0\uACBD\uD569\uB2C8\uB2E4. \uAC00\uB2A5\uD55C \uC0C1\uD0DC: ${STATUS_LIST}. '\uC11C\uB958 \uD569\uACA9(document_passed)' \uC774\uC0C1\uC73C\uB85C \uBC14\uB00C\uBA74 \uBA74\uC811 \uC900\uBE44\uB97C \uC81C\uC548\uD558\uB294 \uD78C\uD2B8\uB97C \uD568\uAED8 \uB3CC\uB824\uC90D\uB2C8\uB2E4. note\uC5D0 \uBCC0\uACBD \uC0AC\uC720\uB97C \uB0A8\uAE38 \uC218 \uC788\uC2B5\uB2C8\uB2E4. '\uBD88\uD569\uACA9(rejected)'\uC73C\uB85C \uBC14\uAFC0 \uB54C\uB294 rejected_stage\uC5D0 \uC5B4\uB290 \uB2E8\uACC4\uC5D0\uC11C \uC544\uC27D\uAC8C \uB410\uB294\uC9C0 \uD568\uAED8 \uB0A8\uAE30\uC138\uC694 \u2014 \uC11C\uB958=document, \uC778\uC801\uC131\xB7AI\uC5ED\uAC80=assessment, \uBA74\uC811=interview, \uCD5C\uC885\xB7\uCC98\uC6B0=final, \uAE30\uD0C0=other. \uD0C8\uB77D \uC0AC\uC720\uB97C \uC54C\uB824\uC8FC\uB294 \uAE30\uC5C5\uC740 \uB4DC\uBB3C\uC5B4, \uC774 \uC790\uAC00 \uAE30\uB85D\uC774 \uC313\uC774\uBA74 '\uC11C\uB958\uB294 \uBD99\uB294\uB370 \uBA74\uC811\uC5D0\uC11C \uB5A8\uC5B4\uC9C4\uB2E4' \uAC19\uC740 \uD328\uD134\uC774 \uB85C\uCEEC \uB370\uC774\uD130\uB85C \uB4DC\uB7EC\uB0A9\uB2C8\uB2E4(get_pipeline_stats).`,
|
|
98243
98705
|
inputSchema: {
|
|
98244
98706
|
job_id: external_exports.string(),
|
|
98245
98707
|
status: external_exports.enum(APPLICATION_STATUSES),
|
|
98246
98708
|
note: external_exports.string().optional(),
|
|
98247
|
-
submission: ApplicationSubmissionSchema.optional()
|
|
98709
|
+
submission: ApplicationSubmissionSchema.optional(),
|
|
98710
|
+
rejected_stage: external_exports.enum(REJECTED_STAGES).optional().describe(
|
|
98711
|
+
"\uD0C8\uB77D \uD68C\uACE0 \u2014 'rejected'\uB85C \uBC14\uAFC0 \uB54C \uC5B4\uB290 \uB2E8\uACC4\uC5D0\uC11C \uD0C8\uB77D\uD588\uB294\uC9C0: \uC11C\uB958=document, \uC778\uC801\uC131\xB7AI\uC5ED\uAC80=assessment, \uBA74\uC811=interview, \uCD5C\uC885\xB7\uCC98\uC6B0=final, \uAE30\uD0C0=other"
|
|
98712
|
+
)
|
|
98248
98713
|
},
|
|
98249
98714
|
handler: (args) => {
|
|
98250
98715
|
try {
|
|
98251
|
-
const res = updateApplicationStatus(args.job_id, args.status, args.note, args.submission);
|
|
98252
|
-
const
|
|
98716
|
+
const res = updateApplicationStatus(args.job_id, args.status, args.note, args.submission, args.rejected_stage);
|
|
98717
|
+
const needsRetro = args.status === "rejected" && !res.application.rejected_stage;
|
|
98718
|
+
const retro_prompt = "\uC5B4\uB290 \uB2E8\uACC4\uC5D0\uC11C \uC544\uC27D\uAC8C \uB410\uB294\uC9C0(\uC11C\uB958/\uC778\uC801\uC131/\uBA74\uC811/\uCD5C\uC885)\uC640 \uBC30\uC6B4 \uC810\uC744 \uB0A8\uACA8\uB450\uBA74 \uB2E4\uC74C \uC9C0\uC6D0 \uC804\uB7B5\uC5D0 \uC4F8 \uC218 \uC788\uC5B4\uC694. \uAE30\uB85D\uD560\uAE4C\uC694?";
|
|
98719
|
+
const base = `\uC9C0\uC6D0 \uC0C1\uD0DC\uB97C '${APPLICATION_STATUS_LABELS[args.status]}'(\uC73C)\uB85C \uBC14\uAFE8\uC5B4\uC694.`;
|
|
98720
|
+
const user_message = base + (res.hint ? `
|
|
98721
|
+
|
|
98722
|
+
${res.hint}` : needsRetro ? `
|
|
98723
|
+
|
|
98724
|
+
${retro_prompt}` : "");
|
|
98725
|
+
const text = needsRetro ? `${user_message}
|
|
98253
98726
|
|
|
98254
|
-
|
|
98727
|
+
(AI \uC548\uB0B4: \uC0AC\uC6A9\uC790\uC5D0\uAC8C \uC5B4\uB290 \uB2E8\uACC4\uC5D0\uC11C \uB5A8\uC5B4\uC84C\uB294\uC9C0\uC640 \uBC30\uC6B4 \uC810\uC744 \uBB3C\uC5B4, rejected_stage\uC640 note\uB85C \uD568\uAED8 \uAE30\uB85D\uD558\uB3C4\uB85D \uC81C\uC548\uD558\uC138\uC694.)` : user_message;
|
|
98255
98728
|
return ok(
|
|
98256
|
-
|
|
98729
|
+
text,
|
|
98257
98730
|
{
|
|
98258
98731
|
...res,
|
|
98259
98732
|
user_message,
|
|
98260
98733
|
suggested_next_action: res.hint ? {
|
|
98261
98734
|
prompt: res.hint,
|
|
98262
98735
|
next_workflow: "prepare_interview"
|
|
98736
|
+
} : needsRetro ? {
|
|
98737
|
+
prompt: retro_prompt,
|
|
98738
|
+
next_tool: "update_application_status"
|
|
98263
98739
|
} : null
|
|
98264
98740
|
}
|
|
98265
98741
|
);
|
|
@@ -98271,6 +98747,8 @@ ${res.hint}` : "");
|
|
|
98271
98747
|
/* ---------------------------------------------------------- interview prep */
|
|
98272
98748
|
{
|
|
98273
98749
|
name: "save_interview_prep",
|
|
98750
|
+
idempotent: true,
|
|
98751
|
+
// 공고당 1건 업서트(debrief는 병합)
|
|
98274
98752
|
title: "\uBA74\uC811 \uC900\uBE44 \uC790\uB8CC \uC800\uC7A5",
|
|
98275
98753
|
description: "\uC608\uC0C1 \uBA74\uC811 \uC9C8\uBB38, \uAF2C\uB9AC \uC9C8\uBB38, STAR \uB2F5\uBCC0 \uAC00\uC774\uB4DC, 1\uBD84 \uC790\uAE30\uC18C\uAC1C \uCD08\uC548 \uB4F1 \uD574\uB2F9 \uACF5\uACE0 \uAE30\uC900 \uBA74\uC811 \uC900\uBE44 \uC790\uB8CC\uB97C \uC800\uC7A5\uD569\uB2C8\uB2E4. \uACF5\uACE0/\uC9C1\uBB34/\uC790\uAE30\uC18C\uAC1C\uC11C\uB97C \uADFC\uAC70\uB85C \uB2F9\uC2E0(AI)\uC774 \uC0DD\uC131\uD55C \uC790\uB8CC\uB97C \uC800\uC7A5\uD558\uB294 \uB370 \uC0AC\uC6A9\uD569\uB2C8\uB2E4. \uC9C8\uBB38\uC740 \uB450 \uAC08\uB798\uB85C \uC900\uBE44\uD558\uC138\uC694 \u2014 \uAC01 \uC9C8\uBB38\uC758 category\uB97C 'technical'(\uAE30\uC220\xB7\uC9C1\uBB34 1\uCC28 \uBA74\uC811) \uB610\uB294 'behavioral'(\uC778\uC131\xB7\uCEEC\uCC98\uD54F\xB7\uC784\uC6D0 2\uCC28 \uBA74\uC811, \uC790\uAE30\uC18C\uAC1C\uC11C\xB7\uD504\uB85C\uD544 \uAE30\uBC18)\uB85C \uC9C0\uC815\uD569\uB2C8\uB2E4. \uAC00\uB2A5\uD558\uBA74 \uB450 \uAC08\uB798 \uBAA8\uB450 \uCC44\uC6CC \uD55C \uBC88\uC5D0 \uC800\uC7A5\uD558\uC138\uC694(\uB300\uC2DC\uBCF4\uB4DC\uAC00 \uAE30\uC220/\uC778\uC131\xB7\uCEEC\uCC98\uD54F \uD0ED\uC73C\uB85C \uB098\uB220 \uBCF4\uC5EC\uC90D\uB2C8\uB2E4). \uBA74\uC811\uC744 \uBCF8 \uB4A4\uC5D0\uB294 \uAC19\uC740 \uB3C4\uAD6C\uC5D0 debrief(\uBC1B\uC740 \uC9C8\uBB38 asked_questions\xB7\uC798\uB41C \uC810 went_well\xB7\uAC1C\uC120\uC810 to_improve\xB7\uB2E4\uC74C \uB77C\uC6B4\uB4DC \uD3EC\uCEE4\uC2A4 next_round_focus\xB7\uCCB4\uAC10 \uBD84\uC704\uAE30 sentiment)\uB97C \uCC44\uC6CC \uC800\uC7A5\uD558\uBA74 \uB2E4\uC74C \uB77C\uC6B4\uB4DC \uC900\uBE44\uC640 \uC77C\uAD00\uC131 \uC810\uAC80\uC5D0 \uADF8\uB300\uB85C \uC774\uC5B4\uC9D1\uB2C8\uB2E4(\uBA74\uC811 \uC804 \uC900\uBE44\uC640 \uBA74\uC811 \uD6C4 \uB514\uBE0C\uB9AC\uD504\uAC00 \uD55C \uACF5\uACE0\uC5D0 \uD568\uAED8 \uC313\uC785\uB2C8\uB2E4). job_id\uB294 \uD544\uC218\uC785\uB2C8\uB2E4. \uAC19\uC740 \uACF5\uACE0\uC5D0 \uB2E4\uC2DC \uC800\uC7A5\uD558\uBA74 \uAC31\uC2E0\uB429\uB2C8\uB2E4(debrief\uB294 \uAE30\uC874 \uAC12\uACFC \uBCD1\uD569\uB418\uC5B4 \uAE30\uC874 \uD544\uB4DC\uB97C \uC9C0\uC6B0\uC9C0 \uC54A\uC2B5\uB2C8\uB2E4).",
|
|
98276
98754
|
inputSchema: InterviewPrepInputSchema.shape,
|
|
@@ -98404,20 +98882,22 @@ ${res.hint}` : "");
|
|
|
98404
98882
|
{
|
|
98405
98883
|
name: "get_followups",
|
|
98406
98884
|
title: "\uD6C4\uC18D \uC870\uCE58 \uC54C\uB9BC(\uB193\uCE5C \uC9C0\uC6D0\xB7\uB9C8\uAC10\xB7\uBA74\uC811\uC900\uBE44)",
|
|
98407
|
-
description: '\uC9C0\uAE08 \uCC59\uACA8\uC57C \uD560 \uAC83\uB4E4\uC744 \uD55C \uBC88\uC5D0 \uB3CC\uB824\uC90D\uB2C8\uB2E4: \u2460 \uC751\uB2F5 \uC5C6\uC774 \uC624\uB798\uB41C \uC9C0\uC6D0(\uC9C0\uC6D0 \uD6C4 \uBB34\uC751\uB2F5\xB7\uC11C\uB958\uD569\uACA9 \uD6C4 \uC77C\uC815\uB300\uAE30\xB7\uBA74\uC811 \uD6C4 \uACB0\uACFC\uB300\uAE30) \u2461 \uC784\uBC15\uD588\uAC70\uB098 \uC9C0\uB09C \uC9C0\uC6D0 \uB9C8\uAC10(\uC9C0\uC6D0 \uC804 \uB2E8\uACC4) \u2462 \uD569\uACA9\uD588\uB294\uB370 \uC544\uC9C1 \uBA74\uC811 \uC900\uBE44\uAC00 \uC5C6\uB294 \uACF5\uACE0. \uC0AC\uC6A9\uC790\uAC00 "\uB0B4 \uC9C0\uC6D0 \uD604\uD669 \uC5B4\uB54C?", "\uBB50 \uCC59\uACA8\uC57C \uD574?", "\uD6C4\uC18D \uC5F0\uB77D\uD560 \uAC70 \uC788\uC5B4?"\uB77C\uACE0 \uBB3B\uAC70\uB098, \uC138\uC158\uC744 \uC774\uC5B4\uAC00\uBA70 \uB193\uCE5C \uAC8C \uC5C6\uB294\uC9C0 \uBA3C\uC800 \uC810\uAC80\uD560 \uB54C \uC0AC\uC6A9\uD558\uC138\uC694. \uC77D\uAE30 \uC804\uC6A9\uC785\uB2C8\uB2E4. \uC751\uB2F5\uC758 reason\uC740 \uC0AC\uC6A9\uC790 \uC5B8\uC5B4\uB85C \uD480\uC5B4 \uC804\uD558\uACE0, \uD6C4\uC18D \uBB38\uC758\uB294 \uAC15\uC694\uD558\uC9C0 \uB9D0\uACE0 \uC120\uD0DD\uC9C0\uB85C \uC81C\uC548\uD558\uC138\uC694(\uCC44\uC6A9 \uAD00\uD589\uC0C1 \uACFC\uD55C \uB3C5\uCD09\uC740 \uC5ED\uD6A8\uACFC).',
|
|
98885
|
+
description: '\uC9C0\uAE08 \uCC59\uACA8\uC57C \uD560 \uAC83\uB4E4\uC744 \uD55C \uBC88\uC5D0 \uB3CC\uB824\uC90D\uB2C8\uB2E4: \u2460 \uC751\uB2F5 \uC5C6\uC774 \uC624\uB798\uB41C \uC9C0\uC6D0(\uC9C0\uC6D0 \uD6C4 \uBB34\uC751\uB2F5\xB7\uC11C\uB958\uD569\uACA9 \uD6C4 \uC77C\uC815\uB300\uAE30\xB7\uBA74\uC811 \uD6C4 \uACB0\uACFC\uB300\uAE30) \u2461 \uC784\uBC15\uD588\uAC70\uB098 \uC9C0\uB09C \uC9C0\uC6D0 \uB9C8\uAC10(\uC9C0\uC6D0 \uC804 \uB2E8\uACC4) \u2462 \uD569\uACA9\uD588\uB294\uB370 \uC544\uC9C1 \uBA74\uC811 \uC900\uBE44\uAC00 \uC5C6\uB294 \uACF5\uACE0 \u2463 \uC624\uB298~7\uC77C \uB0B4 \uB2E4\uAC00\uC624\uB294 \uC804\uD615 \uC77C\uC815(\uBA74\uC811\xB7\uC778\uC801\uC131\xB7\uBC1C\uD45C; `upcoming_schedule`\uC5D0 \uAC01 \uC77C\uC815\uC758 D-day) \u2464 \uC11C\uB85C \uB2E4\uB978 \uACF5\uACE0\uC758 \uC77C\uC815\uC774 \uAC19\uC740 \uB0A0\uC9DC\uC5D0 \uACB9\uCE60 \uB54C(`schedule_conflicts` \u2014 \uAC19\uC740 \uACF5\uACE0\uC758 \uC5F0\uC18D \uB2E8\uACC4\uB294 \uCDA9\uB3CC\uC774 \uC544\uB2C8\uACE0, \uC11C\uB85C \uB2E4\uB978 \uACF5\uACE0 2\uAC74 \uC774\uC0C1\uC774 \uD55C \uB0A0\uC5D0 \uBAB0\uB9B4 \uB54C\uB9CC; \uC788\uC73C\uBA74 \uC0AC\uC6A9\uC790\uC5D0\uAC8C \uC54C\uB824 \uC870\uC815 \uC81C\uC548). \uC0AC\uC6A9\uC790\uAC00 "\uB0B4 \uC9C0\uC6D0 \uD604\uD669 \uC5B4\uB54C?", "\uBB50 \uCC59\uACA8\uC57C \uD574?", "\uC774\uBC88 \uC8FC \uC77C\uC815 \uBB50 \uC788\uC5B4?", "\uD6C4\uC18D \uC5F0\uB77D\uD560 \uAC70 \uC788\uC5B4?"\uB77C\uACE0 \uBB3B\uAC70\uB098, \uC138\uC158\uC744 \uC774\uC5B4\uAC00\uBA70 \uB193\uCE5C \uAC8C \uC5C6\uB294\uC9C0 \uBA3C\uC800 \uC810\uAC80\uD560 \uB54C \uC0AC\uC6A9\uD558\uC138\uC694. \uC77D\uAE30 \uC804\uC6A9\uC785\uB2C8\uB2E4. \uC9C0\uC6D0(applied) \uD56D\uBAA9\uC5D0\uB294 \uACB0\uC815\uB860 \uD314\uB85C\uC5C5 \uD0C0\uC774\uBC0D\uC774 \uBD99\uC2B5\uB2C8\uB2E4: `followup_timing="due"`\uB294 \uC9C0\uC6D0 \uD6C4 5~7\uC601\uC5C5\uC77C(\uC8FC\uB9D0 \uC81C\uC678)\uB85C \uC815\uC911\uD55C \uD6C4\uC18D \uBB38\uC758 \uC801\uAE30, `"overdue"`\uB294 8\uC601\uC5C5\uC77C \uC774\uC0C1\uC73C\uB85C \uC801\uAE30\uAC00 \uC9C0\uB0AC\uB2E4\uB294 \uB73B\uC774\uBA70, `business_days_since`\uB294 \uACBD\uACFC \uC601\uC5C5\uC77C \uC218\uC785\uB2C8\uB2E4. \uB2EC\uB825\uC77C 45\uC77C \uC774\uC0C1 \uBB34\uC751\uB2F5\uC774\uBA74 `suggest_on_hold=true`\uAC00 \uBD99\uC73C\uB2C8 "\uBCF4\uB958(on_hold)\uB85C \uC62E\uAE38\uAE4C\uC694?"\uB77C\uACE0 \uC81C\uC548\uD558\uC138\uC694. \uC751\uB2F5\uC758 reason\uC740 \uC0AC\uC6A9\uC790 \uC5B8\uC5B4\uB85C \uD480\uC5B4 \uC804\uD558\uACE0, \uD6C4\uC18D \uBB38\uC758\uB294 \uAC15\uC694\uD558\uC9C0 \uB9D0\uACE0 \uC120\uD0DD\uC9C0\uB85C \uC81C\uC548\uD558\uC138\uC694(\uCC44\uC6A9 \uAD00\uD589\uC0C1 \uACFC\uD55C \uB3C5\uCD09\uC740 \uC5ED\uD6A8\uACFC \u2014 \uBB38\uC758\uB294 \uC815\uC911\uD788 1\uD68C).',
|
|
98408
98886
|
inputSchema: {},
|
|
98409
98887
|
readOnly: true,
|
|
98410
98888
|
handler: () => {
|
|
98411
98889
|
const d = getActionDigest();
|
|
98412
|
-
const n = d.followups.length + d.deadlines.length + d.interview_todo.length;
|
|
98413
|
-
const
|
|
98890
|
+
const n = d.followups.length + d.deadlines.length + d.interview_todo.length + d.upcoming_schedule.length;
|
|
98891
|
+
const parts = [`\uD6C4\uC18D ${d.followups.length}`, `\uB9C8\uAC10 ${d.deadlines.length}`, `\uBA74\uC811\uC900\uBE44 ${d.interview_todo.length}`, `\uC77C\uC815 ${d.upcoming_schedule.length}`];
|
|
98892
|
+
if (d.schedule_conflicts.length) parts.push(`\uC77C\uC815\uCDA9\uB3CC ${d.schedule_conflicts.length}`);
|
|
98893
|
+
const msg = n === 0 && d.schedule_conflicts.length === 0 ? "\uC9C0\uAE08 \uB2F9\uC7A5 \uCC59\uAE38 \uD6C4\uC18D \uD56D\uBAA9\uC774 \uC5C6\uC2B5\uB2C8\uB2E4(\uBB34\uC751\uB2F5 \uC9C0\uC6D0\xB7\uC784\uBC15 \uB9C8\uAC10\xB7\uBA74\uC811 \uC900\uBE44 \uB300\uAE30\xB7\uB2E4\uAC00\uC624\uB294 \uC77C\uC815 \uC5C6\uC74C)." : `\uCC59\uAE38 \uD56D\uBAA9: ${parts.join(" \xB7 ")}`;
|
|
98414
98894
|
return ok(msg, d);
|
|
98415
98895
|
}
|
|
98416
98896
|
},
|
|
98417
98897
|
{
|
|
98418
98898
|
name: "get_pipeline_stats",
|
|
98419
98899
|
title: "\uC9C0\uC6D0 \uD30C\uC774\uD504\uB77C\uC778 \uBD84\uC11D(\uAE54\uB54C\uAE30\xB7\uD569\uACA9\uB960)",
|
|
98420
|
-
description: '\uC804\uCCB4 \uC9C0\uC6D0 \uD604\uD669\uC744 \uBD84\uC11D\uD574 \uB3CC\uB824\uC90D\uB2C8\uB2E4: \uD604\uC7AC \uC0C1\uD0DC \uBD84\uD3EC(by_status), \uB2E8\uACC4\uBCC4 \uB3C4\uB2EC \uAE54\uB54C\uAE30(funnel: \uC9C0\uC6D0\u2192\uC11C\uB958\uD569\uACA9\u2192\uBA74\uC811\u2192\uCD5C\uC885, \uC0C1\uD0DC \uBCC0\uACBD \uC774\uB825\uC73C\uB85C \uBCF5\uC6D0\uD55C \uC2E4\uCE21\uCE58\uB77C \uD604\uC7AC \uBD88\uD569\uACA9\uC774\uC5B4\uB3C4 \uAC70\uCCD0\uAC04 \uCD5C\uACE0 \uB2E8\uACC4\uAE4C\uC9C0 \uC9D1\uACC4), \uD1B5\uACFC\uC728(rates: \uC11C\uB958\xB7\uBA74\uC811\xB7\uCD5C\uC885, \uC9C0\uC6D0 \uB300\uBE44 %), \uACB0\uACFC \uC694\uC57D(outcomes). \uC0AC\uC6A9\uC790\uAC00 "\uB0B4 \uD569\uACA9\uB960 \uC5B4\uB54C?", "\uC9C0\uC6D0 \uD1B5\uACC4 \uBCF4\uC5EC\uC918", "\uC5B4\uB290 \uB2E8\uACC4\uC5D0\uC11C \uB9CE\uC774 \uB5A8\uC5B4\uC838?"\uB77C\uACE0 \uBB3C\uC744 \uB54C \uC0AC\uC6A9\uD558\uC138\uC694. \uBE44\uC728\uC740 \uC124\uBA85\uC6A9\uC774\uBA70 \uD45C\uBCF8\uC774 \uC791\uC73C\uBA74 \uC608\uCE21\uB825\uC774 \uB0AE\uB2E4\uB294 \uC810\uC744 \uD568\uAED8 \uC804\uD558\uC138\uC694(note \uCC38\uACE0). \uC77D\uAE30 \uC804\uC6A9\uC785\uB2C8\uB2E4.',
|
|
98900
|
+
description: '\uC804\uCCB4 \uC9C0\uC6D0 \uD604\uD669\uC744 \uBD84\uC11D\uD574 \uB3CC\uB824\uC90D\uB2C8\uB2E4: \uD604\uC7AC \uC0C1\uD0DC \uBD84\uD3EC(by_status), \uB2E8\uACC4\uBCC4 \uB3C4\uB2EC \uAE54\uB54C\uAE30(funnel: \uC9C0\uC6D0\u2192\uC11C\uB958\uD569\uACA9\u2192\uBA74\uC811\u2192\uCD5C\uC885, \uC0C1\uD0DC \uBCC0\uACBD \uC774\uB825\uC73C\uB85C \uBCF5\uC6D0\uD55C \uC2E4\uCE21\uCE58\uB77C \uD604\uC7AC \uBD88\uD569\uACA9\uC774\uC5B4\uB3C4 \uAC70\uCCD0\uAC04 \uCD5C\uACE0 \uB2E8\uACC4\uAE4C\uC9C0 \uC9D1\uACC4), \uD1B5\uACFC\uC728(rates: \uC11C\uB958\xB7\uBA74\uC811\xB7\uCD5C\uC885, \uC9C0\uC6D0 \uB300\uBE44 %), \uACB0\uACFC \uC694\uC57D(outcomes), \uD0C8\uB77D \uB2E8\uACC4 \uBD84\uD3EC(rejected_by_stage: \uC11C\uB958\xB7\uC778\uC801\uC131\xB7\uBA74\uC811\xB7\uCD5C\uC885\xB7\uAE30\uD0C0\uBCC4 \uD0C8\uB77D \uAC74\uC218 + rejected_unrecorded: \uB2E8\uACC4 \uBBF8\uAE30\uB85D \uC218). \uC0AC\uC6A9\uC790\uAC00 "\uB0B4 \uD569\uACA9\uB960 \uC5B4\uB54C?", "\uC9C0\uC6D0 \uD1B5\uACC4 \uBCF4\uC5EC\uC918", "\uC5B4\uB290 \uB2E8\uACC4\uC5D0\uC11C \uB9CE\uC774 \uB5A8\uC5B4\uC838?"\uB77C\uACE0 \uBB3C\uC744 \uB54C \uC0AC\uC6A9\uD558\uC138\uC694. \uBE44\uC728\uC740 \uC124\uBA85\uC6A9\uC774\uBA70 \uD45C\uBCF8\uC774 \uC791\uC73C\uBA74 \uC608\uCE21\uB825\uC774 \uB0AE\uB2E4\uB294 \uC810\uC744 \uD568\uAED8 \uC804\uD558\uC138\uC694(note \uCC38\uACE0). \uC77D\uAE30 \uC804\uC6A9\uC785\uB2C8\uB2E4.',
|
|
98421
98901
|
inputSchema: {},
|
|
98422
98902
|
readOnly: true,
|
|
98423
98903
|
handler: () => {
|
|
@@ -98425,14 +98905,19 @@ ${res.hint}` : "");
|
|
|
98425
98905
|
if (s.total === 0) return ok("\uC544\uC9C1 \uC9C0\uC6D0 \uB0B4\uC5ED\uC774 \uC5C6\uC5B4 \uBD84\uC11D\uD560 \uD1B5\uACC4\uAC00 \uC5C6\uC2B5\uB2C8\uB2E4.", s);
|
|
98426
98906
|
const r = s.rates;
|
|
98427
98907
|
const fmt = (v) => v == null ? "\u2014" : `${v}%`;
|
|
98908
|
+
const rejParts = s.rejected_by_stage.map((x2) => `${REJECTED_STAGE_LABELS[x2.stage]} ${x2.count}`);
|
|
98909
|
+
if (s.rejected_unrecorded > 0) rejParts.push(`\uBBF8\uAE30\uB85D ${s.rejected_unrecorded}\uAC74 \u2014 \uAE30\uB85D\uD558\uBA74 \uD328\uD134\uC774 \uBCF4\uC785\uB2C8\uB2E4`);
|
|
98910
|
+
const rejLine = rejParts.length ? ` \xB7 \uD0C8\uB77D \uBD84\uD3EC: ${rejParts.join("\xB7")}` : "";
|
|
98428
98911
|
return ok(
|
|
98429
|
-
`\uC9C0\uC6D0 ${s.total}\uAC74 \xB7 \uAE54\uB54C\uAE30 \uC9C0\uC6D0 ${s.funnel.applied}\u2192\uC11C\uB958 ${s.funnel.document_passed}\u2192\uBA74\uC811 ${s.funnel.interview}\u2192\uCD5C\uC885 ${s.funnel.final_passed} \xB7 \uD1B5\uACFC\uC728 \uC11C\uB958 ${fmt(r.document_pass)}\xB7\uBA74\uC811 ${fmt(r.interview)}\xB7\uCD5C\uC885 ${fmt(r.offer)} (\uD45C\uBCF8 \uC791\uC73C\uBA74 \uCD94\uC138 \uCC38\uACE0\uB85C\uB9CC)`,
|
|
98912
|
+
`\uC9C0\uC6D0 ${s.total}\uAC74 \xB7 \uAE54\uB54C\uAE30 \uC9C0\uC6D0 ${s.funnel.applied}\u2192\uC11C\uB958 ${s.funnel.document_passed}\u2192\uBA74\uC811 ${s.funnel.interview}\u2192\uCD5C\uC885 ${s.funnel.final_passed} \xB7 \uD1B5\uACFC\uC728 \uC11C\uB958 ${fmt(r.document_pass)}\xB7\uBA74\uC811 ${fmt(r.interview)}\xB7\uCD5C\uC885 ${fmt(r.offer)}${rejLine} (\uD45C\uBCF8 \uC791\uC73C\uBA74 \uCD94\uC138 \uCC38\uACE0\uB85C\uB9CC)`,
|
|
98430
98913
|
s
|
|
98431
98914
|
);
|
|
98432
98915
|
}
|
|
98433
98916
|
},
|
|
98434
98917
|
{
|
|
98435
98918
|
name: "search_jobs",
|
|
98919
|
+
// 외부 공개 잡보드(원티드·점핏)로 검색어가 나간다 — openWorld를 정직하게 표시.
|
|
98920
|
+
openWorld: true,
|
|
98436
98921
|
title: "\uACF5\uACE0 \uAC80\uC0C9\xB7\uAC00\uC838\uC624\uAE30(\uD0A4\uC6CC\uB4DC)",
|
|
98437
98922
|
description: `\uD0A4\uC6CC\uB4DC\uB85C \uBB34\uC778\uC99D \uACF5\uAC1C \uCC44\uC6A9 \uC0AC\uC774\uD2B8(${JOB_SEARCH_SOURCES.join("\xB7")})\uC5D0\uC11C \uCC44\uC6A9 \uACF5\uACE0\uB97C \uAC00\uC838\uC635\uB2C8\uB2E4. \uC0AC\uC6A9\uC790\uAC00 "\uBC31\uC5D4\uB4DC \uC2E0\uC785 \uACF5\uACE0 \uCC3E\uC544\uC918", "React \uACF5\uACE0 \uAC00\uC838\uC640"\uCC98\uB7FC \uACF5\uACE0\uB97C \uCC3E\uC544 \uB2EC\uB77C\uACE0 \uD560 \uB54C \uC0AC\uC6A9\uD558\uC138\uC694. \uACB0\uACFC(\uD68C\uC0AC\xB7\uC9C1\uBB34\xB7\uB9C1\uD06C\xB7\uC9C0\uC5ED\xB7\uACBD\uB825\xB7\uAE30\uC220\uC2A4\uD0DD\xB7\uB9C8\uAC10)\uB97C \uC0AC\uC6A9\uC790\uC5D0\uAC8C \uBCF4\uAE30 \uC88B\uAC8C \uBCF4\uC5EC \uC8FC\uACE0, **\uC0AC\uC6A9\uC790\uAC00 \uAD00\uC2EC \uC788\uB2E4\uACE0 \uACE0\uB978 \uAC83\uB9CC** save_job_posting\uC73C\uB85C \uC800\uC7A5\uD558\uC138\uC694(\uC804\uBD80 \uC790\uB3D9 \uC800\uC7A5\uD558\uC9C0 \uB9C8\uC138\uC694). \uC800\uC7A5\uD55C \uACF5\uACE0\uB294 \uC774\uC5B4\uC11C get_application_context\uB85C \uBD84\uC11D\xB7\uC790\uC18C\uC11C\uB85C \uC5F0\uACB0\uB429\uB2C8\uB2E4. \uCC38\uACE0: \uC774 \uB3C4\uAD6C\uB294 \uC678\uBD80 \uACF5\uAC1C \uD398\uC774\uC9C0\uC5D0\uC11C \uACF5\uACE0\uB97C \uAC00\uC838\uC624\uAE30\uB9CC \uD558\uBA70(\uBCF4\uB0B4\uB294 \uAC83\uC740 \uAC80\uC0C9 \uD0A4\uC6CC\uB4DC\uBFD0, \uC0AC\uC6A9\uC790 \uB370\uC774\uD130\uB294 \uC808\uB300 \uC804\uC1A1\uD558\uC9C0 \uC54A\uC74C), \uBD07 \uCC28\uB2E8 \uC6B0\uD68C\uB294 \uD558\uC9C0 \uC54A\uC2B5\uB2C8\uB2E4. \uC0AC\uB78C\uC778\xB7\uC7A1\uCF54\uB9AC\uC544\uB294 \uD0A4 \uBC1C\uAE09 \uB610\uB294 \uC57D\uAD00 \uC81C\uC57D\uC73C\uB85C \uC5EC\uAE30 \uD3EC\uD568\uB418\uC9C0 \uC54A\uC2B5\uB2C8\uB2E4. \uACB0\uACFC\uAC00 \uBE44\uC5B4 \uC788\uC73C\uBA74 \uD0A4\uC6CC\uB4DC\uB97C \uBC14\uAFB8\uAC70\uB098 \uC0AC\uC6A9\uC790\uC5D0\uAC8C \uACF5\uACE0 URL/\uBCF8\uBB38\uC744 \uBC1B\uC544 save_job_posting\uC73C\uB85C \uC800\uC7A5\uD558\uC138\uC694.`,
|
|
98438
98923
|
inputSchema: {
|
|
@@ -98454,16 +98939,72 @@ ${res.hint}` : "");
|
|
|
98454
98939
|
{
|
|
98455
98940
|
name: "prescreen_job",
|
|
98456
98941
|
title: "\uACF5\uACE0 \uC0AC\uC804 \uD504\uB9AC\uC2A4\uD06C\uB9B0(\uD0A4\uC6CC\uB4DC \uACB9\uCE68)",
|
|
98457
|
-
description: '\uC800\uC7A5\uB41C \uACF5\uACE0\uC758 \uD575\uC2EC \uD0A4\uC6CC\uB4DC\uB97C
|
|
98942
|
+
description: '\uC800\uC7A5\uB41C \uACF5\uACE0\uC758 \uD575\uC2EC \uD0A4\uC6CC\uB4DC\uB97C **\uC0AC\uC6A9\uC790\uC758 \uBCF4\uC720 \uAE30\uC220\xB7\uD504\uB85C\uC81D\uD2B8/\uACBD\uB825 \uAE30\uC220\uC2A4\uD0DD(\uAD6C\uC870\uD654 \uC2A4\uD0AC)\uACFC \uB300\uD45C \uC774\uB825\uC11C \uBCF8\uBB38 \uC591\uCABD**\uC5D0 \uB300\uC870\uD574 "\uC774 \uACF5\uACE0\uB97C \uAE4A\uAC8C \uBCFC \uAC00\uCE58\uAC00 \uC788\uB294\uC9C0"\uB97C \uBE60\uB974\uAC8C \uAC00\uB2A0\uD569\uB2C8\uB2E4. LLM \uC5C6\uC774 \uC140 \uC218 \uC788\uB294 \uD0A4\uC6CC\uB4DC \uACB9\uCE68\uB9CC \uB3CC\uB824\uC8FC\uB294 \uAC12\uC2FC \uC0AC\uC804 \uD544\uD130\uC785\uB2C8\uB2E4: `matched`(\uC2A4\uD0AC \uBAA9\uB85D\uC5D0\uC11C \uBC1C\uACAC)\xB7`resume_matched`(\uC774\uB825\uC11C \uBCF8\uBB38\uC5D0\uC11C \uBC1C\uACAC)\xB7`combined_matched`(\uB458\uC758 \uD569\uC9D1\uD569)\xB7`combined_coverage`(\uD569\uC9D1\uD569 \uCEE4\uBC84\uB9AC\uC9C0 0~1)\xB7`resume_checked`(\uB300\uD45C \uC774\uB825\uC11C \uC874\uC7AC \uC5EC\uBD80). **\uC9C4\uC9DC \uC801\uD569\uB3C4 \uD310\uB2E8\uC740 \uB2F9\uC2E0(AI)\uC774 get_application_context\uB85C \uB9E5\uB77D\uC744 \uBC1B\uC544 \uC9C1\uC811 \uC218\uD589**\uD569\uB2C8\uB2E4(\uC774 \uB3C4\uAD6C\uB294 \uADF8 \uB300\uCCB4\uAC00 \uC544\uB2D9\uB2C8\uB2E4). \uC0AC\uC6A9\uC790\uAC00 \uACF5\uACE0\uB97C \uC5EC\uB7EC \uAC1C \uD6D1\uC73C\uBA70 \uC6B0\uC120\uC21C\uC704\uB97C \uC815\uD558\uAC70\uB098 "\uC774\uAC70 \uC9C0\uC6D0\uD560 \uB9CC\uD574?"\uB77C\uACE0 \uBB3C\uC744 \uB54C \uBCF8\uACA9 \uBD84\uC11D \uC804\uC5D0 \uAC00\uBCCD\uAC8C \uD638\uCD9C\uD558\uC138\uC694. **combined_coverage\uAC00 \uB0AE\uC740\uB370 \uC2E4\uC81C\uB85C\uB294 \uBCF4\uC720\uD55C \uC5ED\uB7C9\uC774\uB77C\uBA74, \uC774\uB825\uC11C \uBCF8\uBB38\uC5D0 \uADF8 \uD0A4\uC6CC\uB4DC\uAC00 \uC548 \uB4DC\uB7EC\uB098\uB294 \uAC83\uC774\uB2C8 \uC774\uB825\uC11C \uBCF4\uAC15(\uD574\uB2F9 \uD0A4\uC6CC\uB4DC \uB178\uCD9C)\uC744 \uC81C\uC548\uD558\uC138\uC694**(ATS \uD0A4\uC6CC\uB4DC \uB9E4\uCE6D\uC5D0 \uC720\uD6A8). coverage\uAC00 \uB0AE\uC544\uB3C4 \uD0A4\uC6CC\uB4DC \uBBF8\uAE30\uC7AC\uC77C \uC218 \uC788\uC73C\uB2C8 \uB2E8\uC815\uD558\uC9C0 \uB9D0\uACE0, \uD45C\uAE30\uB418\uC9C0 \uC54A\uC740 \uC5ED\uB7C9\uC740 \uC0AC\uC6A9\uC790\uC5D0\uAC8C \uD655\uC778\uD558\uC138\uC694. \uC77D\uAE30 \uC804\uC6A9\uC785\uB2C8\uB2E4.',
|
|
98458
98943
|
inputSchema: { job_id: external_exports.string() },
|
|
98459
98944
|
readOnly: true,
|
|
98460
98945
|
handler: (args) => {
|
|
98461
98946
|
const r = prescreenJob(args.job_id);
|
|
98462
98947
|
if (!r) return fail("\uACF5\uACE0\uB97C \uCC3E\uC744 \uC218 \uC5C6\uC2B5\uB2C8\uB2E4. \uBA3C\uC800 save_job_posting\uC73C\uB85C \uC800\uC7A5\uD558\uC138\uC694.");
|
|
98463
|
-
if (r.
|
|
98948
|
+
if (r.combined_coverage == null)
|
|
98464
98949
|
return ok("\uC774 \uACF5\uACE0\uC5D0 \uC800\uC7A5\uB41C \uD575\uC2EC \uD0A4\uC6CC\uB4DC\uAC00 \uC5C6\uC5B4 \uACB9\uCE68\uC744 \uC140 \uC218 \uC5C6\uC2B5\uB2C8\uB2E4. save_job_posting\uC758 keywords\uC5D0 \uD575\uC2EC \uD0A4\uC6CC\uB4DC\uB97C \uC815\uB9AC\uD574 \uB123\uC73C\uBA74 \uD504\uB9AC\uC2A4\uD06C\uB9B0\uC774 \uAC00\uB2A5\uD569\uB2C8\uB2E4.", r);
|
|
98465
|
-
const pct = Math.round(r.
|
|
98466
|
-
|
|
98950
|
+
const pct = Math.round(r.combined_coverage * 100);
|
|
98951
|
+
const combinedMissing = r.job_keywords.filter((k) => !r.combined_matched.includes(k));
|
|
98952
|
+
const resumeNote = r.resume_checked ? "" : " (\uB300\uD45C \uC774\uB825\uC11C\uAC00 \uC5C6\uC5B4 \uC2A4\uD0AC \uBAA9\uB85D\uB9CC \uB300\uC870\uD588\uC5B4\uC694 \u2014 \uC774\uB825\uC11C\uB97C \uC800\uC7A5\uD558\uBA74 \uBCF8\uBB38 \uD0A4\uC6CC\uB4DC\uAE4C\uC9C0 \uB300\uC870\uD569\uB2C8\uB2E4.)";
|
|
98953
|
+
return ok(
|
|
98954
|
+
`\uD0A4\uC6CC\uB4DC \uCEE4\uBC84\uB9AC\uC9C0 ${pct}% \u2014 \uC2A4\uD0AC+\uB300\uD45C \uC774\uB825\uC11C \uBCF8\uBB38\uC5D0\uC11C ${r.combined_matched.length}/${r.job_keywords.length}\uAC1C \uD655\uC778.${resumeNote} \uC544\uC9C1 \uC548 \uB4DC\uB7EC\uB09C \uD0A4\uC6CC\uB4DC: ${combinedMissing.join(", ") || "\uC5C6\uC74C"}. (\uC140 \uC218 \uC788\uB294 \uACB9\uCE68\uC77C \uBFD0 \uC2E4\uC81C \uC801\uD569\uB3C4\uB294 \uC9C1\uC811 \uD310\uB2E8\uD558\uC138\uC694. \uBCF4\uC720 \uC5ED\uB7C9\uC778\uB370 \uC548 \uB4DC\uB7EC\uB0AC\uB2E4\uBA74 \uC774\uB825\uC11C \uBCF4\uAC15\uC744 \uC81C\uC548\uD558\uC138\uC694.)`,
|
|
98955
|
+
r
|
|
98956
|
+
);
|
|
98957
|
+
}
|
|
98958
|
+
},
|
|
98959
|
+
{
|
|
98960
|
+
name: "save_offer",
|
|
98961
|
+
idempotent: true,
|
|
98962
|
+
// 공고당 1건 업서트
|
|
98963
|
+
title: "\uC624\uD37C(\uC81C\uC548) \uC800\uC7A5",
|
|
98964
|
+
description: '\uBC1B\uC740 \uCC44\uC6A9 \uC81C\uC548(\uC624\uD37C)\uC744 \uACF5\uACE0\uC5D0 \uC5F0\uACB0\uD574 \uC800\uC7A5\uD569\uB2C8\uB2E4(\uACF5\uACE0\uB2F9 1\uAC74, \uB2E4\uC2DC \uC800\uC7A5\uD558\uBA74 \uAC31\uC2E0). \uD604\uAE08\uC131 \uD56D\uBAA9\uC740 **\uB9CC\uC6D0 \uB2E8\uC704 \uC22B\uC790**\uB85C \u2014 base_salary(\uAE30\uBCF8\uAE09/\uC5F0\uBD09)\xB7bonus_amount(\uC5F0 \uC131\uACFC\uAE09\xB7\uC0C1\uC5EC \uAE30\uB300\uC561)\xB7welfare_amount(\uBCF5\uC9C0\uD3EC\uC778\uD2B8 \uB4F1 \uC5F0\uD658\uC0B0)\xB7signing_amount(\uC0AC\uC774\uB2DD \uC77C\uC2DC\uAE08). \uC8FC\uC2DD/\uC2A4\uD1A1\uC635\uC158\uC740 \uAC00\uCE58\uD3C9\uAC00\uAC00 \uBAA8\uD638\uD558\uB2C8 equity_note\uC5D0 \uD14D\uC2A4\uD2B8\uB85C, \uADF8 \uC678 \uBCF4\uC0C1\uC740 comp_note\uC5D0. \uADFC\uBB34\uD615\uD0DC\xB7\uACC4\uC57D\uD615\uD0DC\xB7\uC218\uB77D \uB9C8\uAC10\uC77C(accept_deadline)\uB3C4 \uC800\uC7A5\uD558\uC138\uC694. **\uB2F9\uC2E0(AI)\uC774 \uC774 \uC624\uD37C\uB97C \uC885\uD569 \uD3C9\uAC00\uD574 ai_score(0~100)\uC640 verdict(\uCD5C\uC885\uD3C9 \u2014 "\uC5B4\uB5A4 \uC0C1\uD669\uC774\uBA74 \uC774 \uD68C\uC0AC\uAC00 \uC88B\uB2E4" \uC2DD \uD55C\uB450 \uBB38\uC7A5)\uB97C \uD568\uAED8 \uCC44\uC6CC \uC800\uC7A5\uD558\uC138\uC694** \u2014 CareerMate\uC5D4 LLM\uC774 \uC5C6\uC5B4 \uC774 \uC810\uC218\xB7\uD3C9\uC774 \uB300\uC2DC\uBCF4\uB4DC\uC5D0 \uADF8\uB300\uB85C \uD45C\uC2DC\uB429\uB2C8\uB2E4. \uD68C\uC0AC \uD3C9\uD310\uC774 \uD310\uB2E8\uC5D0 \uD544\uC694\uD558\uBA74 \uACF5\uACE0\uC758 reputation\uC744 \uBA3C\uC800 \uCC44\uC6CC\uB450\uC138\uC694. \uC5EC\uB7EC \uC624\uD37C\uC758 \uC815\uBC00 \uBE44\uAD50\uB294 compare_offers\uB85C \uB370\uC774\uD130\uB97C \uBC1B\uC544 \uB2F9\uC2E0\uC774 \uC9C1\uC811 \uD558\uC138\uC694(\uCD1D\uBCF4\uC0C1\xB7\uC131\uC7A5\xB7\uC548\uC815\uC131\xB7\uC6CC\uB77C\uBC38). **\uC624\uD37C\uC758 \uC9C4\uD589 \uC0C1\uD0DC\uB294 offer_status\uB85C \uAE30\uB85D\uD558\uC138\uC694** \u2014 open(\uAE30\uBCF8, \uC9C4\uD589 \uC911)/accepted(\uC218\uB77D)/declined(\uAC70\uC808). \uC0AC\uC6A9\uC790\uAC00 "\uADF8 \uC624\uD37C \uAC70\uC808\uD588\uC5B4/\uC218\uB77D\uD558\uAE30\uB85C \uD588\uC5B4"\uB77C\uACE0 \uD558\uBA74 \uC774 \uB3C4\uAD6C\uB85C offer_status\uB9CC \uAC31\uC2E0\uD558\uBA74 \uB429\uB2C8\uB2E4 \u2014 \uC0AD\uC81C\uD558\uC9C0 \uC54A\uC2B5\uB2C8\uB2E4(\uC5F0\uBD09\xB7\uC870\uAC74 \uAE30\uB85D\uC740 \uB2E4\uC74C \uD611\uC0C1\uC758 \uC790\uC0B0\uC774\uACE0, \uB300\uC2DC\uBCF4\uB4DC\uAC00 \uC9C0\uB09C \uC624\uD37C\uB85C \uC811\uC5B4\uC11C \uBCF4\uC5EC\uC90D\uB2C8\uB2E4). accepted\uB85C \uC800\uC7A5\uD558\uBA74 \uC9C0\uC6D0 \uC0C1\uD0DC(\uCD5C\uC885 \uD569\uACA9) \uAC31\uC2E0\uB3C4 \uD568\uAED8 \uC81C\uC548\uD558\uC138\uC694.',
|
|
98965
|
+
inputSchema: OfferInputSchema.shape,
|
|
98966
|
+
handler: (args) => {
|
|
98967
|
+
try {
|
|
98968
|
+
const offer = saveOffer(args);
|
|
98969
|
+
const total = offer.total_comp_annual_est;
|
|
98970
|
+
const statusLabel = offer.offer_status === "accepted" ? " \xB7 \uC218\uB77D" : offer.offer_status === "declined" ? " \xB7 \uAC70\uC808" : "";
|
|
98971
|
+
const user_message = `'${offer.company}' \uC624\uD37C\uB97C \uC800\uC7A5\uD588\uC5B4\uC694` + (offer.ai_score != null ? ` (\uC810\uC218 ${offer.ai_score})` : "") + (total != null ? ` \xB7 \uCD94\uC815 \uC5F0 \uD604\uAE08\uC131 ${total.toLocaleString()}\uB9CC\uC6D0` : "") + statusLabel + ".";
|
|
98972
|
+
const app = applicationRepo.getByJob(offer.job_id);
|
|
98973
|
+
const suggested_next_action = offer.offer_status === "accepted" && app?.status !== "final_passed" ? {
|
|
98974
|
+
prompt: "\uC9C0\uC6D0 \uC0C1\uD0DC\uB3C4 '\uCD5C\uC885 \uD569\uACA9'\uC73C\uB85C \uBC14\uAFC0\uAE4C\uC694?",
|
|
98975
|
+
next_tool: "update_application_status"
|
|
98976
|
+
} : null;
|
|
98977
|
+
const msg = suggested_next_action ? `${user_message}
|
|
98978
|
+
|
|
98979
|
+
\uC0AC\uC6A9\uC790\uC5D0\uAC8C \uC9C0\uC6D0 \uC0C1\uD0DC\uB97C '\uCD5C\uC885 \uD569\uACA9'\uC73C\uB85C \uD568\uAED8 \uBC14\uAFC0\uC9C0 \uBB3C\uC5B4\uBCF4\uC138\uC694.` : user_message;
|
|
98980
|
+
return ok(msg, { ...offer, user_message, suggested_next_action });
|
|
98981
|
+
} catch (e) {
|
|
98982
|
+
return fail(e instanceof Error ? e.message : "\uC800\uC7A5 \uC2E4\uD328");
|
|
98983
|
+
}
|
|
98984
|
+
}
|
|
98985
|
+
},
|
|
98986
|
+
{
|
|
98987
|
+
name: "compare_offers",
|
|
98988
|
+
title: "\uC624\uD37C \uBE44\uAD50",
|
|
98989
|
+
description: '\uC800\uC7A5\uB41C \uBAA8\uB4E0 \uC624\uD37C\uB97C **\uC810\uC218\uC21C(\uB2F9\uC2E0\uC774 \uB9E4\uAE34 ai_score)** \uC73C\uB85C \uD68C\uC0AC\xB7\uC9C1\uBB34\xB7\uCD94\uC815 \uC5F0 \uD604\uAE08\uC131 \uCD1D\uC561\xB7\uADFC\uBB34\uD615\uD0DC\xB7\uC218\uB77D\uB9C8\uAC10\xB7\uCD5C\uC885\uD3C9\uACFC \uD568\uAED8 \uB3CC\uB824\uC90D\uB2C8\uB2E4. total_comp_annual_est\uB294 CareerMate\uAC00 \uACB0\uC815\uB860\uC73C\uB85C \uD569\uC0B0\uD55C \uCD94\uC815\uCE58(\uAE30\uBCF8\uAE09+\uC131\uACFC\uAE09+\uBCF5\uC9C0, \uC77C\uC2DC\uAE08 \uC81C\uC678)\uC785\uB2C8\uB2E4. \uAC01 \uC624\uD37C\uC5D0\uB294 offer_status(open/accepted/declined)\uAC00 \uD3EC\uD568\uB418\uB2C8 **\uBE44\uAD50\uB294 \uC9C4\uD589 \uC911(open) \uC624\uD37C \uC704\uC8FC\uB85C** \uD558\uACE0, \uC218\uB77D\xB7\uAC70\uC808\uB41C \uC9C0\uB09C \uC624\uD37C\uB294 \uAE30\uC900\uC810(\uACFC\uAC70 \uC870\uAC74)\uC73C\uB85C\uB9CC \uCC38\uACE0\uD558\uC138\uC694. "\uC5B4\uB290 \uC624\uD37C\uAC00 \uB098\uC740\uC9C0"\uC758 \uC815\uBC00 \uD310\uB2E8\uC740 \uC774 \uB370\uC774\uD130\uB97C \uBC1B\uC544 \uB2F9\uC2E0\uC774 offer-evaluation\xB7salary-negotiation \uAD00\uC810(\uCD1D\uBCF4\uC0C1\xB7\uC131\uC7A5\xB7\uC548\uC815\uC131\xB7\uC6CC\uB77C\uBC38\xB7\uD68C\uC0AC \uD3C9\uD310)\uC73C\uB85C \uC9C1\uC811 \uD558\uC138\uC694. \uC0AC\uC6A9\uC790\uAC00 "\uC624\uD37C \uBE44\uAD50\uD574\uC918"\uB77C\uACE0 \uD560 \uB54C \uC0AC\uC6A9\uD569\uB2C8\uB2E4. \uC77D\uAE30 \uC804\uC6A9\uC785\uB2C8\uB2E4.',
|
|
98990
|
+
inputSchema: {},
|
|
98991
|
+
readOnly: true,
|
|
98992
|
+
handler: () => {
|
|
98993
|
+
const offers = compareOffers();
|
|
98994
|
+
if (offers.length === 0) return ok("\uC800\uC7A5\uB41C \uC624\uD37C\uAC00 \uC5C6\uC2B5\uB2C8\uB2E4. save_offer\uB85C \uBA3C\uC800 \uC800\uC7A5\uD558\uC138\uC694.", offers);
|
|
98995
|
+
return ok(`\uC624\uD37C ${offers.length}\uAC74(\uC810\uC218\uC21C).`, offers);
|
|
98996
|
+
}
|
|
98997
|
+
},
|
|
98998
|
+
{
|
|
98999
|
+
name: "get_offer",
|
|
99000
|
+
title: "\uC624\uD37C \uC870\uD68C(\uACF5\uACE0\uBCC4)",
|
|
99001
|
+
description: "\uD2B9\uC815 \uACF5\uACE0\uC5D0 \uC800\uC7A5\uB41C \uC624\uD37C 1\uAC74\uC744 \uB3CC\uB824\uC90D\uB2C8\uB2E4(\uC5C6\uC73C\uBA74 null). \uC77D\uAE30 \uC804\uC6A9\uC785\uB2C8\uB2E4.",
|
|
99002
|
+
inputSchema: { job_id: external_exports.string() },
|
|
99003
|
+
readOnly: true,
|
|
99004
|
+
handler: (args) => {
|
|
99005
|
+
const offer = getOffer(args.job_id);
|
|
99006
|
+
if (!offer) return ok("\uC774 \uACF5\uACE0\uC5D0 \uC800\uC7A5\uB41C \uC624\uD37C\uAC00 \uC5C6\uC2B5\uB2C8\uB2E4.", null);
|
|
99007
|
+
return ok(`'${offer.company}' \uC624\uD37C.`, offer);
|
|
98467
99008
|
}
|
|
98468
99009
|
},
|
|
98469
99010
|
/* ------------------------------------------------------- workflow guide */
|
|
@@ -98537,7 +99078,7 @@ ${res.hint}` : "");
|
|
|
98537
99078
|
{
|
|
98538
99079
|
name: "validate_cover_letter",
|
|
98539
99080
|
title: "\uC790\uAE30\uC18C\uAC1C\uC11C \uC790\uB3D9 \uC810\uAC80 (\uC800\uC7A5 \uC804 \uBBF8\uB9AC\uBCF4\uAE30)",
|
|
98540
|
-
description: "\uC790\uAE30\uC18C\uAC1C\uC11C\uB97C save_cover_letter_version\uC73C\uB85C \uC800\uC7A5\uD558\uAE30 \uC9C1\uC804\uC5D0 \uD638\uCD9C\uD558\uBA74, \uC800\uC7A5\uD558\uC9C0 \uC54A\uACE0 \uBBF8\uB9AC \uC810\uAC80\uB9CC \uD569\uB2C8\uB2E4. CareerMate\uAC00 LLM \uC5C6\uC774 \uACB0\uC815\uB860\uC73C\uB85C (1) \uBCF8\uBB38\uC758 \uC815\uB7C9 \uC218\uCE58\uAC00 \uC800\uC7A5\uB41C \uACBD\uB825\xB7\uC774\uB825\uC11C\xB7\uD504\uB85C\uC81D\uD2B8\uC5D0 \uADFC\uAC70\uAC00 \uC788\uB294\uC9C0(\uC5C6\uC73C\uBA74 \uD658\uAC01 \uC758\uC2EC \u2192 \uC800\uC7A5 \uC2DC \uCC28\uB2E8\uB428), (2) \uACF5\uACE0\uC5D0\uC11C \uAC00\uC838\uC628 \uC218\uCE58\uB97C \uBCF8\uC778 \uC131\uACFC\uCC98\uB7FC \uC4F0\uC9C0 \uC54A\uC558\uB294\uC9C0, (3) \uBC88\uC5ED\uD22C\xB7\uC81C\uB108\uB9AD \uB3C4\uC785\xB7\uBE48 \uD615\uC6A9\uC0AC\xB7\uBE14\uB77C\uC778\uB4DC \uC704\uBC18 \uAC19\uC740 \uBB38\uCCB4 \uC2E0\uD638\uB97C \uC138\uC5B4 \uB3CC\uB824\uC90D\uB2C8\uB2E4. \uB610 (4) \uAE00\uC790\uC218\uB97C \uACF5\uBC31\uD3EC\uD568\xB7\uACF5\uBC31\uC81C\uC678\xB7UTF-8 byte \uC138 \uAE30\uC900\uC73C\uB85C \uC815\uD655\uD788 \uC138\uACE0, min_chars/max_chars\uB97C \uC8FC\uBA74 \uC0C1\xB7\uD558\uD55C \uCDA9\uC871 \uC5EC\uBD80\uAE4C\uC9C0 \uB3CC\uB824\uC90D\uB2C8\uB2E4(LLM\uC740 \uAE00\uC790\uC218\uB97C \uC815\uD655\uD788 \uBABB \uC138\uBBC0\uB85C \uC774 \uAE30\uB2A5\uC744 \uC4F0\uC138\uC694). \uC810\uAC80\uC740 \uC140 \uC218 \uC788\uB294 \uAC83\uB9CC \uBD05\uB2C8\uB2E4 \u2014 \uC0AC\uC2E4\uC131\xB7\uB3D9\uBB38\uC11C\uB2F5 \uAC19\uC740 \uC758\uBBF8 \uD310\uB2E8\uC740 \uB2F9\uC2E0(AI)\uC774 \uC9C1\uC811 \uD558\uC138\uC694. \uD55C\uAD6D \uBB38\uD56D\uD615 \uC790\uC18C\uC11C\uB294 \uBB38\uD56D\uB9C8\uB2E4 \uAE00\uC790\uC218 \uD55C\uB3C4\uAC00 \uB2E4\uB974\uB2C8 \uAC01 \uBB38\uD56D \uBCF8\uBB38\uC744 \uADF8 \uBB38\uD56D\uC758 \uD55C\uB3C4\uB85C \uB530\uB85C \uC810\uAC80\uD558\uC138\uC694. job_id\uB97C \uC8FC\uBA74 \uACF5\uACE0 \uC218\uCE58\uAE4C\uC9C0 \uBE44\uAD50\uD569\uB2C8\uB2E4.",
|
|
99081
|
+
description: "\uC790\uAE30\uC18C\uAC1C\uC11C\uB97C save_cover_letter_version\uC73C\uB85C \uC800\uC7A5\uD558\uAE30 \uC9C1\uC804\uC5D0 \uD638\uCD9C\uD558\uBA74, \uC800\uC7A5\uD558\uC9C0 \uC54A\uACE0 \uBBF8\uB9AC \uC810\uAC80\uB9CC \uD569\uB2C8\uB2E4. CareerMate\uAC00 LLM \uC5C6\uC774 \uACB0\uC815\uB860\uC73C\uB85C (1) \uBCF8\uBB38\uC758 \uC815\uB7C9 \uC218\uCE58\uAC00 \uC800\uC7A5\uB41C \uACBD\uB825\xB7\uC774\uB825\uC11C\xB7\uD504\uB85C\uC81D\uD2B8\uC5D0 \uADFC\uAC70\uAC00 \uC788\uB294\uC9C0(\uC5C6\uC73C\uBA74 \uD658\uAC01 \uC758\uC2EC \u2192 \uC800\uC7A5 \uC2DC \uCC28\uB2E8\uB428), (2) \uACF5\uACE0\uC5D0\uC11C \uAC00\uC838\uC628 \uC218\uCE58\uB97C \uBCF8\uC778 \uC131\uACFC\uCC98\uB7FC \uC4F0\uC9C0 \uC54A\uC558\uB294\uC9C0, (3) \uBC88\uC5ED\uD22C\xB7\uC81C\uB108\uB9AD \uB3C4\uC785\xB7\uBE48 \uD615\uC6A9\uC0AC\xB7\uBE14\uB77C\uC778\uB4DC \uC704\uBC18 \uAC19\uC740 \uBB38\uCCB4 \uC2E0\uD638\uB97C \uC138\uC5B4 \uB3CC\uB824\uC90D\uB2C8\uB2E4. \uB610 (4) \uAE00\uC790\uC218\uB97C \uACF5\uBC31\uD3EC\uD568\xB7\uACF5\uBC31\uC81C\uC678\xB7UTF-8 byte \uC138 \uAE30\uC900\uC73C\uB85C \uC815\uD655\uD788 \uC138\uACE0, min_chars/max_chars\uB97C \uC8FC\uBA74 \uC0C1\xB7\uD558\uD55C \uCDA9\uC871 \uC5EC\uBD80\uAE4C\uC9C0 \uB3CC\uB824\uC90D\uB2C8\uB2E4(LLM\uC740 \uAE00\uC790\uC218\uB97C \uC815\uD655\uD788 \uBABB \uC138\uBBC0\uB85C \uC774 \uAE30\uB2A5\uC744 \uC4F0\uC138\uC694). \uC810\uAC80\uC740 \uC140 \uC218 \uC788\uB294 \uAC83\uB9CC \uBD05\uB2C8\uB2E4 \u2014 \uC0AC\uC2E4\uC131\xB7\uB3D9\uBB38\uC11C\uB2F5 \uAC19\uC740 \uC758\uBBF8 \uD310\uB2E8\uC740 \uB2F9\uC2E0(AI)\uC774 \uC9C1\uC811 \uD558\uC138\uC694. \uD55C\uAD6D \uBB38\uD56D\uD615 \uC790\uC18C\uC11C\uB294 \uBB38\uD56D\uB9C8\uB2E4 \uAE00\uC790\uC218 \uD55C\uB3C4\uAC00 \uB2E4\uB974\uB2C8 \uAC01 \uBB38\uD56D \uBCF8\uBB38\uC744 \uADF8 \uBB38\uD56D\uC758 \uD55C\uB3C4\uB85C \uB530\uB85C \uC810\uAC80\uD558\uC138\uC694. \uACF5\uACE0\uC5D0 questions\uAC00 \uC800\uC7A5\uB3FC \uC788\uC73C\uBA74 \uADF8 \uBB38\uD56D\uC758 \uD55C\uB3C4\uB97C min_chars/max_chars/count_mode\uB85C \uB118\uACA8 \uC810\uAC80\uD558\uC138\uC694. job_id\uB97C \uC8FC\uBA74 \uACF5\uACE0 \uC218\uCE58\uAE4C\uC9C0 \uBE44\uAD50\uD569\uB2C8\uB2E4.",
|
|
98541
99082
|
inputSchema: {
|
|
98542
99083
|
text: external_exports.string().max(2e5).describe("\uC810\uAC80\uD560 \uC790\uAE30\uC18C\uAC1C\uC11C \uBCF8\uBB38(\uBB38\uD56D\uD615\uC774\uBA74 \uD55C \uBB38\uD56D \uBCF8\uBB38)"),
|
|
98543
99084
|
job_id: external_exports.string().optional().describe("\uC5F0\uACB0\uD560 \uACF5\uACE0(\uC788\uC73C\uBA74 \uACF5\uACE0 \uC218\uCE58\uAE4C\uC9C0 \uBE44\uAD50)"),
|
|
@@ -98581,6 +99122,8 @@ ${report.disclaimer}`, {
|
|
|
98581
99122
|
},
|
|
98582
99123
|
{
|
|
98583
99124
|
name: "set_verify_mode",
|
|
99125
|
+
idempotent: true,
|
|
99126
|
+
// 같은 값 재설정은 무해
|
|
98584
99127
|
title: "\uC810\uAC80 \uBAA8\uB4DC \uC124\uC815 (\uAE30\uBCF8/\uC5C4\uACA9)",
|
|
98585
99128
|
description: '\uC800\uC7A5 \uC804 \uC790\uB3D9 \uC810\uAC80\uC758 \uC5C4\uACA9\uB3C4\uB97C \uBC14\uAFC9\uB2C8\uB2E4. \uC5C4\uACA9 \uBAA8\uB4DC(strict=true)\uB97C \uCF1C\uBA74, \uC774\uD6C4 \uBAA8\uB4E0 \uC790\uC18C\uC11C \uC800\uC7A5\uC5D0\uC11C "\uC774\uB825\uC11C \uBCF8\uBB38\uC5D0 \uADFC\uAC70 \uC5C6\uB294 \uC218\uCE58"(\uAD6C\uC870\uD654 \uACBD\uB825 \uD56D\uBAA9\uC5D0\uB9CC \uC788\uB294 \uAC12)\uAE4C\uC9C0 \uCC28\uB2E8\uD569\uB2C8\uB2E4. \uAE30\uBCF8 \uBAA8\uB4DC\uB294 \uCD9C\uCC98\uAC00 \uC544\uC608 \uC5C6\uB294 \uC218\uCE58\uB9CC \uCC28\uB2E8\uD569\uB2C8\uB2E4. \uC0AC\uC6A9\uC790\uAC00 "\uC5C4\uACA9\uD558\uAC8C \uBD10\uC918"\uB77C\uACE0 \uD558\uBA74 \uBC14\uB85C \uCF1C\uC9C0 \uB9D0\uACE0 "\uC55E\uC73C\uB85C \uD56D\uC0C1 \uC5C4\uACA9\uD558\uAC8C \uBCFC\uAE4C\uC694?"\uB77C\uACE0 \uBA3C\uC800 \uD655\uC778\uD55C \uB4A4 \uB3D9\uC758\uD558\uBA74 strict=true\uB85C \uD638\uCD9C\uD558\uC138\uC694. \uB044\uAE30(strict=false)\uB294 \uC548\uC804\uC7A5\uCE58\uB97C \uC57D\uD558\uAC8C \uB9CC\uB4DC\uB294 \uAC83\uC774\uBBC0\uB85C, \uC0AC\uC6A9\uC790\uAC00 \uBA85\uD655\uD788 \uB044\uACA0\uB2E4\uACE0 \uD560 \uB54C\uB9CC \uD638\uCD9C\uD558\uC138\uC694. \uC774\uBC88 \uD55C \uAC74\uB9CC \uC5C4\uACA9\uD558\uAC8C \uBCF4\uB824\uBA74 \uBAA8\uB4DC\uB97C \uBC14\uAFB8\uC9C0 \uB9D0\uACE0 validate_cover_letter / save_cover_letter_version\uC5D0 strict:true\uB97C \uD55C \uBC88\uB9CC \uB118\uAE30\uC138\uC694.',
|
|
98586
99129
|
inputSchema: {
|
|
@@ -98619,6 +99162,8 @@ ${report.disclaimer}`, {
|
|
|
98619
99162
|
/* ----------------------------------------------------------------- update */
|
|
98620
99163
|
{
|
|
98621
99164
|
name: "check_for_update",
|
|
99165
|
+
// npm 레지스트리로 버전 조회가 나간다(사용자 데이터 미전송).
|
|
99166
|
+
openWorld: true,
|
|
98622
99167
|
title: "\uC5C5\uB370\uC774\uD2B8 \uD655\uC778",
|
|
98623
99168
|
description: 'CareerMate\uC5D0 \uC0C8 \uBC84\uC804\uC774 \uC788\uB294\uC9C0 npm \uB808\uC9C0\uC2A4\uD2B8\uB9AC\uC5D0\uC11C \uC9C0\uAE08 \uD655\uC778\uD569\uB2C8\uB2E4(\uACF5\uAC1C \uBC84\uC804 \uC815\uBCF4\uB9CC GET\uD558\uBA70 \uC0AC\uC6A9\uC790 \uB370\uC774\uD130\uB294 \uC804\uC1A1\uD558\uC9C0 \uC54A\uC2B5\uB2C8\uB2E4). \uD604\uC7AC \uBC84\uC804\xB7\uCD5C\uC2E0 \uBC84\uC804\xB7\uC5C5\uB370\uC774\uD2B8 \uAC00\uB2A5 \uC5EC\uBD80\uB97C \uB3CC\uB824\uC90D\uB2C8\uB2E4. \uC0AC\uC6A9\uC790\uAC00 "\uCD5C\uC2E0\uC774\uC57C?/\uC5C5\uB370\uC774\uD2B8 \uC788\uC5B4?"\uB77C\uACE0 \uBB3B\uAC70\uB098, get_onboarding_status\uAC00 \uC0C8 \uBC84\uC804\uC744 \uC54C\uB9B4 \uB54C \uD638\uCD9C\uD558\uC138\uC694. \uD655\uC778\uB9CC \uD558\uACE0 \uC124\uCE58\uB294 \uD558\uC9C0 \uC54A\uC2B5\uB2C8\uB2E4. \uC0AC\uC6A9\uC790\uAC00 "\uC5C5\uB370\uC774\uD2B8\uD574\uC918/\uCD5C\uC2E0\uC73C\uB85C \uC62C\uB824\uC918"\uCC98\uB7FC \uBA85\uC2DC\uC801\uC73C\uB85C \uC694\uCCAD\uD558\uBA74 update_careermate\uB97C \uD638\uCD9C\uD558\uC138\uC694.',
|
|
98624
99169
|
inputSchema: {},
|
|
@@ -98642,6 +99187,9 @@ ${report.disclaimer}`, {
|
|
|
98642
99187
|
},
|
|
98643
99188
|
{
|
|
98644
99189
|
name: "update_careermate",
|
|
99190
|
+
// npm에서 패키지를 내려받아 설치 폴더의 코드를 교체한다.
|
|
99191
|
+
openWorld: true,
|
|
99192
|
+
destructive: true,
|
|
98645
99193
|
title: "CareerMate \uC5C5\uB370\uC774\uD2B8",
|
|
98646
99194
|
description: 'CareerMate\uB97C \uCD5C\uC2E0 \uBC84\uC804\uC73C\uB85C \uC5C5\uB370\uC774\uD2B8\uD569\uB2C8\uB2E4(\uC124\uCE58 \uD3F4\uB354\uC5D0 npm\uC73C\uB85C careermate@latest \uC124\uCE58). \uC0AC\uC6A9\uC790\uAC00 \uBA85\uC2DC\uC801\uC73C\uB85C "\uC5C5\uB370\uC774\uD2B8\uD574\uC918", "CareerMate \uC5C5\uB370\uC774\uD2B8\uD574\uC918", "\uCD5C\uC2E0\uC73C\uB85C \uC62C\uB824\uC918"\uB77C\uACE0 \uD560 \uB54C \uD638\uCD9C\uD558\uC138\uC694. \uC774 \uB3C4\uAD6C\uAC00 \uCD5C\uC2E0 \uBC84\uC804 \uD655\uC778\uB3C4 \uD568\uAED8 \uD558\uBBC0\uB85C \uBCC4\uB3C4 \uD655\uC778 \uC9C8\uBB38 \uC5C6\uC774 \uC2E4\uD589\uD574\uB3C4 \uB429\uB2C8\uB2E4. \uC131\uACF5\uD558\uBA74 \uC801\uC6A9\uC744 \uC704\uD574 AI \uC571(\uB610\uB294 MCP \uC5F0\uACB0) \uC7AC\uC2DC\uC791\uC774 \uD544\uC694\uD558\uBA70, \uC7AC\uC2DC\uC791 \uC2DC \uB370\uC774\uD130\uBCA0\uC774\uC2A4\uB294 \uC790\uB3D9 \uB9C8\uC774\uADF8\uB808\uC774\uC158\uB418\uC5B4 \uAE30\uC874 \uB370\uC774\uD130\uB294 \uBCF4\uC874\uB429\uB2C8\uB2E4. \uC790\uB3D9 \uC124\uCE58\uAC00 \uB9C9\uD788\uBA74(\uAC1C\uBC1C \uBAA8\uB4DC\xB7\uBE44\uD45C\uC900 \uC124\uCE58) \uC9C1\uC811 \uCE60 \uBA85\uB839\uC744 \uC548\uB0B4\uD569\uB2C8\uB2E4.',
|
|
98647
99195
|
inputSchema: {},
|
|
@@ -98671,7 +99219,7 @@ async function main() {
|
|
|
98671
99219
|
const nodeOk = checkNode();
|
|
98672
99220
|
const dir = getDataDir();
|
|
98673
99221
|
try {
|
|
98674
|
-
|
|
99222
|
+
fs9.accessSync(dir, fs9.constants.W_OK);
|
|
98675
99223
|
ok2(`\uB370\uC774\uD130 \uD3F4\uB354 \uC4F0\uAE30 \uAC00\uB2A5: ${dir}`);
|
|
98676
99224
|
} catch {
|
|
98677
99225
|
warn2(`\uB370\uC774\uD130 \uD3F4\uB354\uC5D0 \uC4F8 \uC218 \uC5C6\uC2B5\uB2C8\uB2E4: ${dir}`);
|