careermate 0.0.4 → 0.0.6
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 +11 -7
- package/INSTALL.md +18 -16
- package/README.md +28 -26
- package/THIRD_PARTY_NOTICES.md +2 -3
- package/bin/careermate.mjs +8 -1
- package/dist/career-os/README.md +8 -3
- package/dist/career-os/eop/career-description.md +136 -0
- package/dist/career-os/eop/cover-letter.md +7 -5
- package/dist/career-os/eop/fit-analysis.md +15 -5
- package/dist/career-os/eop/interview-prep.md +209 -21
- package/dist/career-os/eop/job-analysis.md +5 -3
- package/dist/career-os/eop/profile-extraction.md +5 -4
- package/dist/career-os/knowledge/cover-letter.md +4 -4
- package/dist/career-os/knowledge/fit-matching.md +8 -8
- package/dist/career-os/knowledge/interview-behavioral.md +76 -8
- package/dist/career-os/knowledge/interview-technical.md +106 -4
- package/dist/career-os/knowledge/linkedin-profile.md +1 -1
- package/dist/career-os/knowledge/networking-referrals.md +1 -1
- package/dist/career-os/knowledge/offer-evaluation-decision.md +10 -10
- package/dist/career-os/knowledge/portfolio.md +3 -3
- package/dist/career-os/knowledge/verifiers/ats-compat.md +8 -4
- package/dist/career-os/knowledge/verifiers/human-voice.md +2 -2
- package/dist/career-os/knowledge/verifiers/recency-staleness.md +1 -1
- package/dist/career-os/knowledge/verifiers/responsiveness-on-target.md +2 -2
- package/dist/career-os/knowledge/verifiers/truthfulness.md +1 -1
- package/dist/doctor.mjs +1019 -127
- package/dist/mcp.mjs +1036 -126
- package/dist/migrate.mjs +52 -1
- package/dist/public/app.js +42 -16
- package/dist/public/i18n/en/applications.js +23 -0
- package/dist/public/i18n/en/common.js +22 -0
- package/dist/public/i18n/en/documents.js +133 -0
- package/dist/public/i18n/en/home.js +75 -0
- package/dist/public/i18n/en/interview.js +69 -0
- package/dist/public/i18n/en/jobs.js +152 -0
- package/dist/public/i18n/en/nav.js +18 -0
- package/dist/public/i18n/en/profile.js +201 -0
- package/dist/public/i18n/en/settings.js +127 -0
- package/dist/public/i18n/en/status.js +22 -0
- package/dist/public/i18n/en.js +17 -0
- package/dist/public/i18n/ko/applications.js +23 -0
- package/dist/public/i18n/ko/common.js +22 -0
- package/dist/public/i18n/ko/documents.js +133 -0
- package/dist/public/i18n/ko/home.js +63 -0
- package/dist/public/i18n/ko/interview.js +69 -0
- package/dist/public/i18n/ko/jobs.js +152 -0
- package/dist/public/i18n/ko/nav.js +18 -0
- package/dist/public/i18n/ko/profile.js +201 -0
- package/dist/public/i18n/ko/settings.js +127 -0
- package/dist/public/i18n/ko/status.js +23 -0
- package/dist/public/i18n/ko.js +18 -0
- package/dist/public/i18n.js +55 -0
- package/dist/public/index.html +1 -0
- package/dist/public/lib.js +25 -17
- package/dist/public/pages/applications.js +17 -21
- package/dist/public/pages/documents.js +153 -107
- package/dist/public/pages/home.js +88 -53
- package/dist/public/pages/interview.js +105 -51
- package/dist/public/pages/jobs.js +330 -106
- package/dist/public/pages/profile.js +157 -152
- package/dist/public/pages/settings.js +270 -72
- package/dist/public/styles.css +38 -3
- package/dist/web.mjs +859 -103
- package/docs/FAQ.md +26 -5
- package/docs/MCP_TOOLS.md +26 -12
- package/docs/START_WORKFLOW.md +2 -2
- package/docs/SUPPORTED_AI_APPS.md +13 -0
- package/docs/WORKFLOWS.md +80 -23
- package/docs/career-os/README.md +8 -3
- package/docs/career-os/eop/career-description.md +136 -0
- package/docs/career-os/eop/cover-letter.md +7 -5
- package/docs/career-os/eop/fit-analysis.md +15 -5
- package/docs/career-os/eop/interview-prep.md +209 -21
- package/docs/career-os/eop/job-analysis.md +5 -3
- package/docs/career-os/eop/profile-extraction.md +5 -4
- package/docs/career-os/knowledge/cover-letter.md +4 -4
- package/docs/career-os/knowledge/fit-matching.md +8 -8
- package/docs/career-os/knowledge/interview-behavioral.md +76 -8
- package/docs/career-os/knowledge/interview-technical.md +106 -4
- package/docs/career-os/knowledge/linkedin-profile.md +1 -1
- package/docs/career-os/knowledge/networking-referrals.md +1 -1
- package/docs/career-os/knowledge/offer-evaluation-decision.md +10 -10
- package/docs/career-os/knowledge/portfolio.md +3 -3
- package/docs/career-os/knowledge/verifiers/ats-compat.md +8 -4
- package/docs/career-os/knowledge/verifiers/human-voice.md +2 -2
- package/docs/career-os/knowledge/verifiers/recency-staleness.md +1 -1
- package/docs/career-os/knowledge/verifiers/responsiveness-on-target.md +2 -2
- package/docs/career-os/knowledge/verifiers/truthfulness.md +1 -1
- package/package.json +2 -2
- package/packages/core/src/onboarding.ts +2 -1
- package/packages/core/src/services.ts +138 -21
- package/packages/core/src/summary.ts +59 -1
- package/packages/core/src/verify/lint.ts +4 -0
- package/packages/db/src/index.ts +1 -0
- package/packages/db/src/repositories.ts +0 -0
- package/packages/db/src/schema.ts +17 -0
- package/packages/exporters/src/index.ts +28 -17
- package/packages/knowledge/src/index.ts +46 -7
- package/packages/mcp-tools/src/bridge.ts +194 -13
- package/packages/mcp-tools/src/tools.ts +390 -38
- package/packages/mcp-tools/src/update.ts +31 -16
- package/packages/parsers/src/documents.ts +12 -1
- package/packages/prompts/src/humanize.ts +46 -0
- package/packages/prompts/src/index.ts +5 -1
- package/packages/prompts/src/install.ts +4 -4
- package/packages/prompts/src/onboarding.ts +4 -4
- package/packages/prompts/src/system.ts +17 -8
- package/packages/shared/src/enums.ts +14 -4
- package/packages/shared/src/schemas.ts +41 -0
- package/packages/workflows/src/definitions.ts +47 -10
- package/scripts/init.ts +284 -13
- package/dist/site/analytics.js +0 -97
- package/dist/site/favicon.svg +0 -1
- package/dist/site/fonts/PretendardVariable.woff2 +0 -0
- package/dist/site/icon-180.png +0 -0
- package/dist/site/icon-512.png +0 -0
- package/dist/site/index.html +0 -565
- package/dist/site/landing.js +0 -54
- package/dist/site/llms-install.txt +0 -218
- package/dist/site/robots.txt +0 -4
- package/dist/site/sitemap.xml +0 -21
- package/dist/site/start.html +0 -353
- package/dist/site/style.css +0 -559
- package/dist/site/vercel.json +0 -20
package/dist/mcp.mjs
CHANGED
|
@@ -6891,12 +6891,12 @@ var require_dist = __commonJS({
|
|
|
6891
6891
|
throw new Error(`Unknown format "${name}"`);
|
|
6892
6892
|
return f;
|
|
6893
6893
|
};
|
|
6894
|
-
function addFormats(ajv, list,
|
|
6894
|
+
function addFormats(ajv, list, fs8, exportName) {
|
|
6895
6895
|
var _a2;
|
|
6896
6896
|
var _b2;
|
|
6897
6897
|
(_a2 = (_b2 = ajv.opts.code).formats) !== null && _a2 !== void 0 ? _a2 : _b2.formats = (0, codegen_1._)`require("ajv-formats/dist/formats").${exportName}`;
|
|
6898
6898
|
for (const f of list)
|
|
6899
|
-
ajv.addFormat(f,
|
|
6899
|
+
ajv.addFormat(f, fs8[f]);
|
|
6900
6900
|
}
|
|
6901
6901
|
module2.exports = exports2 = formatsPlugin;
|
|
6902
6902
|
Object.defineProperty(exports2, "__esModule", { value: true });
|
|
@@ -13333,9 +13333,9 @@ var require_timers = __commonJS({
|
|
|
13333
13333
|
clearTimeout(this.handle);
|
|
13334
13334
|
};
|
|
13335
13335
|
var afterValue = function(value) {
|
|
13336
|
-
return
|
|
13336
|
+
return delay2(+this).thenReturn(value);
|
|
13337
13337
|
};
|
|
13338
|
-
var
|
|
13338
|
+
var delay2 = Promise2.delay = function(ms, value) {
|
|
13339
13339
|
var ret2;
|
|
13340
13340
|
var handle;
|
|
13341
13341
|
if (value !== void 0) {
|
|
@@ -13357,7 +13357,7 @@ var require_timers = __commonJS({
|
|
|
13357
13357
|
return ret2;
|
|
13358
13358
|
};
|
|
13359
13359
|
Promise2.prototype.delay = function(ms) {
|
|
13360
|
-
return
|
|
13360
|
+
return delay2(ms, this);
|
|
13361
13361
|
};
|
|
13362
13362
|
var afterTimeout = function(promise, message, parent) {
|
|
13363
13363
|
var err2;
|
|
@@ -35153,7 +35153,7 @@ var require_path_is_absolute = __commonJS({
|
|
|
35153
35153
|
var require_files = __commonJS({
|
|
35154
35154
|
"node_modules/mammoth/lib/docx/files.js"(exports2) {
|
|
35155
35155
|
"use strict";
|
|
35156
|
-
var
|
|
35156
|
+
var fs8 = __require("fs");
|
|
35157
35157
|
var url = __require("url");
|
|
35158
35158
|
var os3 = __require("os");
|
|
35159
35159
|
var dirname = __require("path").dirname;
|
|
@@ -35194,7 +35194,7 @@ var require_files = __commonJS({
|
|
|
35194
35194
|
read
|
|
35195
35195
|
};
|
|
35196
35196
|
}
|
|
35197
|
-
var readFile = promises.promisify(
|
|
35197
|
+
var readFile = promises.promisify(fs8.readFile.bind(fs8));
|
|
35198
35198
|
function uriToPath(uriString, platform) {
|
|
35199
35199
|
if (!platform) {
|
|
35200
35200
|
platform = os3.platform();
|
|
@@ -37936,11 +37936,11 @@ var require_options_reader = __commonJS({
|
|
|
37936
37936
|
var require_unzip = __commonJS({
|
|
37937
37937
|
"node_modules/mammoth/lib/unzip.js"(exports2) {
|
|
37938
37938
|
"use strict";
|
|
37939
|
-
var
|
|
37939
|
+
var fs8 = __require("fs");
|
|
37940
37940
|
var promises = require_promises();
|
|
37941
37941
|
var zipfile = require_zipfile();
|
|
37942
37942
|
exports2.openZip = openZip;
|
|
37943
|
-
var readFile = promises.promisify(
|
|
37943
|
+
var readFile = promises.promisify(fs8.readFile);
|
|
37944
37944
|
function openZip(options) {
|
|
37945
37945
|
if (options.path) {
|
|
37946
37946
|
return readFile(options.path).then(zipfile.openArrayBuffer);
|
|
@@ -38665,9 +38665,9 @@ var require_cjs = __commonJS({
|
|
|
38665
38665
|
}
|
|
38666
38666
|
return o;
|
|
38667
38667
|
}
|
|
38668
|
-
var
|
|
38668
|
+
var fs8;
|
|
38669
38669
|
function get_fs() {
|
|
38670
|
-
return
|
|
38670
|
+
return fs8 || (fs8 = require$$0__default["default"]);
|
|
38671
38671
|
}
|
|
38672
38672
|
function parse4(file, options) {
|
|
38673
38673
|
if (file[0] == 80 && file[1] == 75) return parse_zip(file, options);
|
|
@@ -38952,7 +38952,7 @@ var require_cjs = __commonJS({
|
|
|
38952
38952
|
}
|
|
38953
38953
|
function read_file(filename2, options) {
|
|
38954
38954
|
get_fs();
|
|
38955
|
-
return parse4(
|
|
38955
|
+
return parse4(fs8.readFileSync(filename2), options);
|
|
38956
38956
|
}
|
|
38957
38957
|
function read(blob, options) {
|
|
38958
38958
|
switch (options && options.type || "base64") {
|
|
@@ -39267,7 +39267,7 @@ var require_cjs = __commonJS({
|
|
|
39267
39267
|
function write_file(cfb2, filename2, options) {
|
|
39268
39268
|
get_fs();
|
|
39269
39269
|
var o = _write(cfb2, options);
|
|
39270
|
-
|
|
39270
|
+
fs8.writeFileSync(filename2, o);
|
|
39271
39271
|
}
|
|
39272
39272
|
function a2s(o) {
|
|
39273
39273
|
var out = new Array(o.length);
|
|
@@ -39279,7 +39279,7 @@ var require_cjs = __commonJS({
|
|
|
39279
39279
|
switch (options && options.type || "buffer") {
|
|
39280
39280
|
case "file":
|
|
39281
39281
|
get_fs();
|
|
39282
|
-
|
|
39282
|
+
fs8.writeFileSync(options.filename, o);
|
|
39283
39283
|
return o;
|
|
39284
39284
|
case "binary":
|
|
39285
39285
|
return typeof o == "string" ? o : a2s(o);
|
|
@@ -46972,8 +46972,8 @@ function blend(fg, bg, alpha) {
|
|
|
46972
46972
|
return Math.round(alpha * fg + (1 - alpha) * bg);
|
|
46973
46973
|
}
|
|
46974
46974
|
async function node_utils_fetchData(url) {
|
|
46975
|
-
const
|
|
46976
|
-
const data = await
|
|
46975
|
+
const fs8 = process.getBuiltinModule("fs/promises");
|
|
46976
|
+
const data = await fs8.readFile(url);
|
|
46977
46977
|
return new Uint8Array(data);
|
|
46978
46978
|
}
|
|
46979
46979
|
function initGPU() {
|
|
@@ -47602,11 +47602,11 @@ function network_getArrayBuffer(val) {
|
|
|
47602
47602
|
return typeof val !== "string" ? val : stringToBytes(val).buffer;
|
|
47603
47603
|
}
|
|
47604
47604
|
function getReadableStream(url, opts = null) {
|
|
47605
|
-
const
|
|
47605
|
+
const fs8 = process.getBuiltinModule("fs");
|
|
47606
47606
|
const {
|
|
47607
47607
|
Readable
|
|
47608
47608
|
} = process.getBuiltinModule("stream");
|
|
47609
|
-
const readStream =
|
|
47609
|
+
const readStream = fs8.createReadStream(url, opts);
|
|
47610
47610
|
return Readable.toWeb(readStream);
|
|
47611
47611
|
}
|
|
47612
47612
|
function getNetworkStream(url) {
|
|
@@ -64603,8 +64603,8 @@ fn fs_main(in : VertexOutput) -> @location(0) vec4<f32> {
|
|
|
64603
64603
|
url
|
|
64604
64604
|
} = stream._source;
|
|
64605
64605
|
this._isStreamingSupported = !disableStream;
|
|
64606
|
-
const
|
|
64607
|
-
|
|
64606
|
+
const fs8 = process.getBuiltinModule("fs/promises");
|
|
64607
|
+
fs8.lstat(url).then((stat) => {
|
|
64608
64608
|
const readableStream = getReadableStream(url);
|
|
64609
64609
|
this._reader = readableStream.getReader();
|
|
64610
64610
|
const {
|
|
@@ -66250,9 +66250,9 @@ fn fs_main(in : VertexOutput) -> @location(0) vec4<f32> {
|
|
|
66250
66250
|
return;
|
|
66251
66251
|
}
|
|
66252
66252
|
if (reason instanceof RenderingCancelledException) {
|
|
66253
|
-
let
|
|
66253
|
+
let delay2 = RENDERING_CANCELLED_TIMEOUT;
|
|
66254
66254
|
if (reason.extraDelay > 0 && reason.extraDelay < 1e3) {
|
|
66255
|
-
|
|
66255
|
+
delay2 += reason.extraDelay;
|
|
66256
66256
|
}
|
|
66257
66257
|
intentState.streamReaderCancelTimeout = setTimeout(() => {
|
|
66258
66258
|
intentState.streamReaderCancelTimeout = null;
|
|
@@ -66261,7 +66261,7 @@ fn fs_main(in : VertexOutput) -> @location(0) vec4<f32> {
|
|
|
66261
66261
|
reason,
|
|
66262
66262
|
force: true
|
|
66263
66263
|
});
|
|
66264
|
-
},
|
|
66264
|
+
}, delay2);
|
|
66265
66265
|
return;
|
|
66266
66266
|
}
|
|
66267
66267
|
}
|
|
@@ -92431,6 +92431,22 @@ var MIGRATIONS = [
|
|
|
92431
92431
|
|
|
92432
92432
|
COMMIT;
|
|
92433
92433
|
PRAGMA foreign_keys=ON;
|
|
92434
|
+
`,
|
|
92435
|
+
// v3 — per-job timeline entries. Document/cover-letter refs live in payload
|
|
92436
|
+
// snapshots instead of FKs so deleting a document does not erase the history.
|
|
92437
|
+
`
|
|
92438
|
+
CREATE TABLE IF NOT EXISTS application_timeline_events (
|
|
92439
|
+
id TEXT PRIMARY KEY,
|
|
92440
|
+
job_id TEXT NOT NULL REFERENCES jobs(id) ON DELETE CASCADE,
|
|
92441
|
+
type TEXT NOT NULL,
|
|
92442
|
+
title TEXT NOT NULL,
|
|
92443
|
+
summary TEXT,
|
|
92444
|
+
payload TEXT NOT NULL DEFAULT '{}',
|
|
92445
|
+
occurred_at TEXT NOT NULL,
|
|
92446
|
+
created_at TEXT NOT NULL
|
|
92447
|
+
);
|
|
92448
|
+
|
|
92449
|
+
CREATE INDEX IF NOT EXISTS idx_timeline_job ON application_timeline_events(job_id, occurred_at ASC);
|
|
92434
92450
|
`
|
|
92435
92451
|
];
|
|
92436
92452
|
function migrate(db) {
|
|
@@ -92462,6 +92478,12 @@ function getDb() {
|
|
|
92462
92478
|
_db = db;
|
|
92463
92479
|
return db;
|
|
92464
92480
|
}
|
|
92481
|
+
function closeDb() {
|
|
92482
|
+
if (_db) {
|
|
92483
|
+
_db.close();
|
|
92484
|
+
_db = null;
|
|
92485
|
+
}
|
|
92486
|
+
}
|
|
92465
92487
|
var _inTx = false;
|
|
92466
92488
|
function tx(fn) {
|
|
92467
92489
|
if (_inTx) return fn();
|
|
@@ -92591,6 +92613,12 @@ function assertStatusTransition(from, to) {
|
|
|
92591
92613
|
}
|
|
92592
92614
|
}
|
|
92593
92615
|
var DOCUMENT_KINDS = ["resume", "career_description", "portfolio", "other"];
|
|
92616
|
+
var DOCUMENT_KIND_LABELS = {
|
|
92617
|
+
resume: "\uC774\uB825\uC11C",
|
|
92618
|
+
career_description: "\uACBD\uB825\uAE30\uC220\uC11C",
|
|
92619
|
+
portfolio: "\uD3EC\uD2B8\uD3F4\uB9AC\uC624",
|
|
92620
|
+
other: "\uAE30\uD0C0 \uBB38\uC11C"
|
|
92621
|
+
};
|
|
92594
92622
|
var CONTENT_SOURCES = ["manual", "upload", "ai", "edit"];
|
|
92595
92623
|
var ACTIVITY_TYPES = [
|
|
92596
92624
|
"profile_updated",
|
|
@@ -92603,6 +92631,13 @@ var ACTIVITY_TYPES = [
|
|
|
92603
92631
|
"interview_prep_saved",
|
|
92604
92632
|
"document_exported"
|
|
92605
92633
|
];
|
|
92634
|
+
var APPLICATION_TIMELINE_TYPES = [
|
|
92635
|
+
"job_saved",
|
|
92636
|
+
"fit_analysis_saved",
|
|
92637
|
+
"cover_letter_version_saved",
|
|
92638
|
+
"application_status_changed",
|
|
92639
|
+
"interview_prep_saved"
|
|
92640
|
+
];
|
|
92606
92641
|
var ENTITY_TYPES = [
|
|
92607
92642
|
"profile",
|
|
92608
92643
|
"experience",
|
|
@@ -92869,11 +92904,19 @@ var ApplicationInputSchema = external_exports.object({
|
|
|
92869
92904
|
applied_at: optLine,
|
|
92870
92905
|
notes: optNote
|
|
92871
92906
|
});
|
|
92907
|
+
var ApplicationSubmissionSchema = external_exports.object({
|
|
92908
|
+
submitted_at: optLine.describe("\uC2E4\uC81C \uC81C\uCD9C\uC77C YYYY-MM-DD"),
|
|
92909
|
+
channel: optLine.describe("\uC81C\uCD9C \uCC44\uB110(\uC6D0\uD2F0\uB4DC/\uC0AC\uB78C\uC778/\uD68C\uC0AC \uCC44\uC6A9\uD398\uC774\uC9C0 \uB4F1)"),
|
|
92910
|
+
cover_letter_id: optLine,
|
|
92911
|
+
cover_letter_version_id: optLine,
|
|
92912
|
+
document_ids: strList.optional().describe("\uC81C\uCD9C\uD55C \uC774\uB825\uC11C\xB7\uACBD\uB825\uAE30\uC220\uC11C\xB7\uD3EC\uD2B8\uD3F4\uB9AC\uC624 \uBB38\uC11C ID \uBAA9\uB85D")
|
|
92913
|
+
});
|
|
92872
92914
|
var ApplicationStatusUpdateSchema = external_exports.object({
|
|
92873
92915
|
job_id: optLine,
|
|
92874
92916
|
application_id: optLine,
|
|
92875
92917
|
status: external_exports.enum(APPLICATION_STATUSES),
|
|
92876
|
-
note: optNote.describe("\uC0C1\uD0DC \uBCC0\uACBD \uC0AC\uC720/\uBA54\uBAA8")
|
|
92918
|
+
note: optNote.describe("\uC0C1\uD0DC \uBCC0\uACBD \uC0AC\uC720/\uBA54\uBAA8"),
|
|
92919
|
+
submission: ApplicationSubmissionSchema.optional().describe("\uC9C0\uC6D0 \uC644\uB8CC \uAE30\uB85D\uC5D0 \uB0A8\uAE38 \uC81C\uCD9C \uC790\uB8CC \uC2A4\uB0C5\uC0F7")
|
|
92877
92920
|
});
|
|
92878
92921
|
var ApplicationRecordSchema = external_exports.object({
|
|
92879
92922
|
...baseRecord,
|
|
@@ -92891,8 +92934,10 @@ var StarGuideSchema = external_exports.object({
|
|
|
92891
92934
|
action: optNote,
|
|
92892
92935
|
result: optNote
|
|
92893
92936
|
});
|
|
92937
|
+
var INTERVIEW_CATEGORIES = ["technical", "behavioral"];
|
|
92894
92938
|
var InterviewQuestionSchema = external_exports.object({
|
|
92895
92939
|
question: external_exports.string().max(MAX_NOTE),
|
|
92940
|
+
category: external_exports.enum(INTERVIEW_CATEGORIES).optional().describe("\uC9C8\uBB38 \uAC08\uB798: 'technical'(\uAE30\uC220\xB7\uC9C1\uBB34 1\uCC28) | 'behavioral'(\uC778\uC131\xB7\uCEEC\uCC98\uD54F\xB7\uC784\uC6D0 2\uCC28, \uC790\uAE30\uC18C\uAC1C\uC11C \uAE30\uBC18). \uC0DD\uB7B5 \uC2DC \uAE30\uC220\uB85C \uAC04\uC8FC."),
|
|
92896
92941
|
intent: external_exports.string().max(MAX_NOTE).optional().describe("\uC9C8\uBB38 \uC758\uB3C4"),
|
|
92897
92942
|
followups: strList.optional().describe("\uC608\uC0C1 \uAF2C\uB9AC \uC9C8\uBB38"),
|
|
92898
92943
|
answer_outline: optBody.describe("\uB2F5\uBCC0 \uAC00\uC774\uB4DC/\uD575\uC2EC \uD3EC\uC778\uD2B8")
|
|
@@ -92920,6 +92965,24 @@ var ActivityRecordSchema = external_exports.object({
|
|
|
92920
92965
|
summary: external_exports.string(),
|
|
92921
92966
|
created_at: isoDateTime
|
|
92922
92967
|
});
|
|
92968
|
+
var ApplicationTimelineInputSchema = external_exports.object({
|
|
92969
|
+
job_id: reqLine,
|
|
92970
|
+
type: external_exports.enum(APPLICATION_TIMELINE_TYPES),
|
|
92971
|
+
title: reqLine,
|
|
92972
|
+
summary: optNote,
|
|
92973
|
+
payload: external_exports.record(external_exports.string(), external_exports.unknown()).optional(),
|
|
92974
|
+
occurred_at: optLine
|
|
92975
|
+
});
|
|
92976
|
+
var ApplicationTimelineRecordSchema = external_exports.object({
|
|
92977
|
+
id,
|
|
92978
|
+
job_id: external_exports.string(),
|
|
92979
|
+
type: external_exports.enum(APPLICATION_TIMELINE_TYPES),
|
|
92980
|
+
title: external_exports.string(),
|
|
92981
|
+
summary: external_exports.string().nullable(),
|
|
92982
|
+
payload: external_exports.record(external_exports.string(), external_exports.unknown()),
|
|
92983
|
+
occurred_at: isoDateTime,
|
|
92984
|
+
created_at: isoDateTime
|
|
92985
|
+
});
|
|
92923
92986
|
var OnboardingStatusSchema = external_exports.object({
|
|
92924
92987
|
completed: external_exports.boolean(),
|
|
92925
92988
|
has_profile: external_exports.boolean(),
|
|
@@ -92956,7 +93019,7 @@ var ApplicationContextSchema = external_exports.object({
|
|
|
92956
93019
|
});
|
|
92957
93020
|
|
|
92958
93021
|
// packages/shared/src/build-info.ts
|
|
92959
|
-
var APP_VERSION = true ? "0.0.
|
|
93022
|
+
var APP_VERSION = true ? "0.0.6" : "0.0.0-dev";
|
|
92960
93023
|
var BUNDLED = true;
|
|
92961
93024
|
|
|
92962
93025
|
// packages/shared/src/index.ts
|
|
@@ -93050,7 +93113,7 @@ function mapExperience(r) {
|
|
|
93050
93113
|
};
|
|
93051
93114
|
}
|
|
93052
93115
|
function expKey(company, role, start) {
|
|
93053
|
-
return [norm(company), norm(role), norm(start)].join("
|
|
93116
|
+
return [norm(company), norm(role), norm(start)].join("");
|
|
93054
93117
|
}
|
|
93055
93118
|
var experienceRepo = {
|
|
93056
93119
|
list() {
|
|
@@ -93468,6 +93531,7 @@ var coverLetterRepo = {
|
|
|
93468
93531
|
remove(id2) {
|
|
93469
93532
|
const db = getDb();
|
|
93470
93533
|
return tx(() => {
|
|
93534
|
+
db.prepare(`UPDATE applications SET cover_letter_id=NULL, updated_at=? WHERE cover_letter_id=?`).run(now(), id2);
|
|
93471
93535
|
db.prepare(`DELETE FROM cover_letter_versions WHERE cover_letter_id=?`).run(id2);
|
|
93472
93536
|
return db.prepare(`DELETE FROM cover_letters WHERE id=?`).run(id2).changes > 0;
|
|
93473
93537
|
});
|
|
@@ -93556,9 +93620,11 @@ var jobRepo = {
|
|
|
93556
93620
|
remove(id2) {
|
|
93557
93621
|
const db = getDb();
|
|
93558
93622
|
return tx(() => {
|
|
93623
|
+
db.prepare(`UPDATE cover_letters SET job_id=NULL, updated_at=? WHERE job_id=?`).run(now(), id2);
|
|
93559
93624
|
db.prepare(`DELETE FROM fit_analyses WHERE job_id=?`).run(id2);
|
|
93560
93625
|
db.prepare(`DELETE FROM applications WHERE job_id=?`).run(id2);
|
|
93561
93626
|
db.prepare(`DELETE FROM interview_preps WHERE job_id=?`).run(id2);
|
|
93627
|
+
db.prepare(`DELETE FROM application_timeline_events WHERE job_id=?`).run(id2);
|
|
93562
93628
|
return db.prepare(`DELETE FROM jobs WHERE id=?`).run(id2).changes > 0;
|
|
93563
93629
|
});
|
|
93564
93630
|
}
|
|
@@ -93671,7 +93737,7 @@ var applicationRepo = {
|
|
|
93671
93737
|
const m = { ...app, ...input };
|
|
93672
93738
|
getDb().prepare(
|
|
93673
93739
|
`UPDATE applications SET status=?,resume_id=?,cover_letter_id=?,applied_at=?,notes=?,updated_at=? WHERE id=?`
|
|
93674
|
-
).run(m.status, m.resume_id, m.cover_letter_id, m.applied_at, m.notes, now(), app.id);
|
|
93740
|
+
).run(m.status, m.resume_id ?? null, m.cover_letter_id ?? null, m.applied_at ?? null, m.notes ?? null, now(), app.id);
|
|
93675
93741
|
return this.get(app.id);
|
|
93676
93742
|
},
|
|
93677
93743
|
setStatus(jobId, status, note) {
|
|
@@ -93752,9 +93818,51 @@ var activityRepo = {
|
|
|
93752
93818
|
return getDb().prepare(`SELECT * FROM activities ORDER BY created_at DESC LIMIT ?`).all(limit);
|
|
93753
93819
|
}
|
|
93754
93820
|
};
|
|
93821
|
+
function mapTimelineEvent(r) {
|
|
93822
|
+
return {
|
|
93823
|
+
id: r.id,
|
|
93824
|
+
job_id: r.job_id,
|
|
93825
|
+
type: r.type,
|
|
93826
|
+
title: r.title,
|
|
93827
|
+
summary: r.summary,
|
|
93828
|
+
payload: fromJson(r.payload, {}),
|
|
93829
|
+
occurred_at: r.occurred_at,
|
|
93830
|
+
created_at: r.created_at
|
|
93831
|
+
};
|
|
93832
|
+
}
|
|
93833
|
+
var timelineRepo = {
|
|
93834
|
+
add(input) {
|
|
93835
|
+
const ts = now();
|
|
93836
|
+
const id2 = newId("tl_");
|
|
93837
|
+
getDb().prepare(
|
|
93838
|
+
`INSERT INTO application_timeline_events (id,job_id,type,title,summary,payload,occurred_at,created_at)
|
|
93839
|
+
VALUES (?,?,?,?,?,?,?,?)`
|
|
93840
|
+
).run(
|
|
93841
|
+
id2,
|
|
93842
|
+
input.job_id,
|
|
93843
|
+
input.type,
|
|
93844
|
+
input.title,
|
|
93845
|
+
input.summary ?? null,
|
|
93846
|
+
toJson(input.payload ?? {}),
|
|
93847
|
+
input.occurred_at ?? ts,
|
|
93848
|
+
ts
|
|
93849
|
+
);
|
|
93850
|
+
return this.get(id2);
|
|
93851
|
+
},
|
|
93852
|
+
get(id2) {
|
|
93853
|
+
const r = getDb().prepare(`SELECT * FROM application_timeline_events WHERE id=?`).get(id2);
|
|
93854
|
+
return r ? mapTimelineEvent(r) : null;
|
|
93855
|
+
},
|
|
93856
|
+
listByJob(jobId) {
|
|
93857
|
+
return getDb().prepare(`SELECT * FROM application_timeline_events WHERE job_id=? ORDER BY occurred_at ASC, created_at ASC`).all(jobId).map(mapTimelineEvent);
|
|
93858
|
+
},
|
|
93859
|
+
remove(id2) {
|
|
93860
|
+
return getDb().prepare(`DELETE FROM application_timeline_events WHERE id=?`).run(id2).changes > 0;
|
|
93861
|
+
}
|
|
93862
|
+
};
|
|
93755
93863
|
|
|
93756
93864
|
// packages/mcp-tools/src/tools.ts
|
|
93757
|
-
import
|
|
93865
|
+
import fs7 from "node:fs";
|
|
93758
93866
|
import path7 from "node:path";
|
|
93759
93867
|
|
|
93760
93868
|
// packages/core/src/onboarding.ts
|
|
@@ -93778,12 +93886,13 @@ function profileCompleteness(p) {
|
|
|
93778
93886
|
function getOnboardingStatus() {
|
|
93779
93887
|
const profile = profileRepo.get();
|
|
93780
93888
|
const resumes = documentRepo.list("resume");
|
|
93889
|
+
const careerDescriptions = documentRepo.list("career_description");
|
|
93781
93890
|
const coverLetters = coverLetterRepo.list();
|
|
93782
93891
|
const experiences = experienceRepo.list();
|
|
93783
93892
|
const skills = skillRepo.list();
|
|
93784
93893
|
const jobs = jobRepo.list();
|
|
93785
93894
|
const has_profile = !!(profile && profile.name);
|
|
93786
|
-
const has_resume = resumes.length > 0;
|
|
93895
|
+
const has_resume = resumes.length > 0 || careerDescriptions.length > 0;
|
|
93787
93896
|
const has_cover_letter = coverLetters.length > 0;
|
|
93788
93897
|
const has_experience = experiences.length > 0;
|
|
93789
93898
|
const has_skills = skills.length > 0;
|
|
@@ -94196,6 +94305,29 @@ function batchNames(names) {
|
|
|
94196
94305
|
if (!shown) return "";
|
|
94197
94306
|
return `: ${shown}${names.length > 8 ? " \uC678" : ""}`;
|
|
94198
94307
|
}
|
|
94308
|
+
function coverLetterTimelineRef(coverLetter, version3, requestedVersionId) {
|
|
94309
|
+
const resolvedVersion = version3 ?? coverLetter.versions?.find((v) => v.id === requestedVersionId || v.id === coverLetter.current_version_id) ?? null;
|
|
94310
|
+
return {
|
|
94311
|
+
kind: "cover_letter",
|
|
94312
|
+
id: coverLetter.id,
|
|
94313
|
+
title: coverLetter.title,
|
|
94314
|
+
version_id: resolvedVersion?.id ?? requestedVersionId ?? coverLetter.current_version_id,
|
|
94315
|
+
version_no: resolvedVersion?.version_no ?? coverLetter.version_count
|
|
94316
|
+
};
|
|
94317
|
+
}
|
|
94318
|
+
function documentTimelineRef(doc) {
|
|
94319
|
+
return {
|
|
94320
|
+
kind: "document",
|
|
94321
|
+
id: doc.id,
|
|
94322
|
+
title: doc.title,
|
|
94323
|
+
document_kind: doc.kind
|
|
94324
|
+
};
|
|
94325
|
+
}
|
|
94326
|
+
function submittedAtToOccurrence(value) {
|
|
94327
|
+
if (!value) return void 0;
|
|
94328
|
+
if (/^\d{4}-\d{2}-\d{2}$/.test(value)) return `${value}T00:00:00.000Z`;
|
|
94329
|
+
return void 0;
|
|
94330
|
+
}
|
|
94199
94331
|
function addExperiences(inputs) {
|
|
94200
94332
|
const res = experienceRepo.addMany(inputs);
|
|
94201
94333
|
activityRepo.log(
|
|
@@ -94234,11 +94366,22 @@ function saveJobPosting(input, id2) {
|
|
|
94234
94366
|
}
|
|
94235
94367
|
function saveFitAnalysis(input) {
|
|
94236
94368
|
const job = jobRepo.get(input.job_id);
|
|
94237
|
-
if (!job) throw notFound(
|
|
94369
|
+
if (!job) throw notFound("\uACF5\uACE0\uB97C \uCC3E\uC744 \uC218 \uC5C6\uC2B5\uB2C8\uB2E4. \uBA3C\uC800 \uACF5\uACE0\uB97C \uC800\uC7A5\uD55C \uB4A4 \uB2E4\uC2DC \uC2DC\uB3C4\uD558\uC138\uC694.");
|
|
94238
94370
|
applicationRepo.ensure(job.id, "draft");
|
|
94239
94371
|
const fit = fitRepo.save(input);
|
|
94240
94372
|
const scoreText = fit.score != null ? ` (\uC801\uD569\uB3C4 ${fit.score}\uC810)` : "";
|
|
94241
94373
|
activityRepo.log("fit_analysis_saved", `${job.company} \xB7 ${job.position} \uC801\uD569\uB3C4 \uBD84\uC11D\uC744 \uC800\uC7A5\uD588\uC2B5\uB2C8\uB2E4${scoreText}.`, "fit_analysis", fit.id);
|
|
94374
|
+
timelineRepo.add({
|
|
94375
|
+
job_id: job.id,
|
|
94376
|
+
type: "fit_analysis_saved",
|
|
94377
|
+
title: "\uC801\uD569\uB3C4 \uBD84\uC11D",
|
|
94378
|
+
summary: fit.score != null ? `\uC885\uD569 ${fit.score}\uC810` : fit.summary ?? void 0,
|
|
94379
|
+
payload: {
|
|
94380
|
+
fit_id: fit.id,
|
|
94381
|
+
score: fit.score
|
|
94382
|
+
},
|
|
94383
|
+
occurred_at: fit.updated_at
|
|
94384
|
+
});
|
|
94242
94385
|
return fit;
|
|
94243
94386
|
}
|
|
94244
94387
|
function saveCoverLetterVersion(input) {
|
|
@@ -94272,35 +94415,88 @@ function saveCoverLetterVersion(input) {
|
|
|
94272
94415
|
"cover_letter",
|
|
94273
94416
|
coverLetter.id
|
|
94274
94417
|
);
|
|
94418
|
+
if (coverLetter.job_id) {
|
|
94419
|
+
timelineRepo.add({
|
|
94420
|
+
job_id: coverLetter.job_id,
|
|
94421
|
+
type: "cover_letter_version_saved",
|
|
94422
|
+
title: "\uC790\uAE30\uC18C\uAC1C\uC11C \uC791\uC131",
|
|
94423
|
+
summary: `${coverLetter.title} v${version3.version_no}`,
|
|
94424
|
+
payload: {
|
|
94425
|
+
cover_letter: coverLetterTimelineRef(coverLetter, version3)
|
|
94426
|
+
},
|
|
94427
|
+
occurred_at: version3.created_at
|
|
94428
|
+
});
|
|
94429
|
+
}
|
|
94275
94430
|
return { coverLetter, version: version3, verification, forced };
|
|
94276
94431
|
}
|
|
94277
|
-
function updateApplicationStatus(jobId, status, note) {
|
|
94432
|
+
function updateApplicationStatus(jobId, status, note, submission) {
|
|
94278
94433
|
const job = jobRepo.get(jobId);
|
|
94279
|
-
if (!job) throw notFound(
|
|
94280
|
-
const
|
|
94281
|
-
|
|
94282
|
-
|
|
94283
|
-
|
|
94284
|
-
|
|
94285
|
-
|
|
94286
|
-
|
|
94434
|
+
if (!job) throw notFound("\uACF5\uACE0\uB97C \uCC3E\uC744 \uC218 \uC5C6\uC2B5\uB2C8\uB2E4.");
|
|
94435
|
+
const before2 = applicationRepo.getByJob(jobId);
|
|
94436
|
+
const application = tx(() => {
|
|
94437
|
+
let application2 = applicationRepo.setStatus(jobId, status, note);
|
|
94438
|
+
const submittedDocs = (submission?.document_ids ?? []).map((docId) => documentRepo.get(docId)).filter((doc) => !!doc);
|
|
94439
|
+
const submittedCoverLetter = submission?.cover_letter_id ? coverLetterRepo.get(submission.cover_letter_id, true) : null;
|
|
94440
|
+
if (status === "applied" && submission) {
|
|
94441
|
+
const resumeLike = submittedDocs.find((doc) => doc.kind === "resume" || doc.kind === "career_description") ?? submittedDocs[0] ?? null;
|
|
94442
|
+
application2 = applicationRepo.upsert({
|
|
94443
|
+
job_id: jobId,
|
|
94444
|
+
resume_id: resumeLike?.id ?? application2.resume_id ?? void 0,
|
|
94445
|
+
cover_letter_id: submittedCoverLetter?.id ?? application2.cover_letter_id ?? void 0,
|
|
94446
|
+
applied_at: submission.submitted_at ?? application2.applied_at ?? void 0
|
|
94447
|
+
});
|
|
94448
|
+
}
|
|
94449
|
+
activityRepo.log(
|
|
94450
|
+
"application_status_changed",
|
|
94451
|
+
`${job.company} \xB7 ${job.position} \uC0C1\uD0DC\uB97C '${APPLICATION_STATUS_LABELS[status]}'(\uC73C)\uB85C \uBCC0\uACBD\uD588\uC2B5\uB2C8\uB2E4.`,
|
|
94452
|
+
"application",
|
|
94453
|
+
application2.id
|
|
94454
|
+
);
|
|
94455
|
+
const submittedAt = submission?.submitted_at?.trim();
|
|
94456
|
+
const channel = submission?.channel?.trim();
|
|
94457
|
+
const submissionPayload = submission && (submittedAt || channel || submittedCoverLetter || submittedDocs.length > 0) ? {
|
|
94458
|
+
submitted_at: submittedAt || null,
|
|
94459
|
+
channel: channel || null,
|
|
94460
|
+
cover_letter: submittedCoverLetter ? coverLetterTimelineRef(submittedCoverLetter, null, submission.cover_letter_version_id) : null,
|
|
94461
|
+
documents: submittedDocs.map(documentTimelineRef)
|
|
94462
|
+
} : null;
|
|
94463
|
+
timelineRepo.add({
|
|
94464
|
+
job_id: job.id,
|
|
94465
|
+
type: "application_status_changed",
|
|
94466
|
+
title: APPLICATION_STATUS_LABELS[status],
|
|
94467
|
+
summary: channel && status === "applied" ? `${channel}\uB85C \uC81C\uCD9C` : note ?? void 0,
|
|
94468
|
+
payload: {
|
|
94469
|
+
from_status: before2?.status ?? null,
|
|
94470
|
+
status,
|
|
94471
|
+
status_label: APPLICATION_STATUS_LABELS[status],
|
|
94472
|
+
note: note ?? null,
|
|
94473
|
+
submission: submissionPayload
|
|
94474
|
+
},
|
|
94475
|
+
occurred_at: submittedAtToOccurrence(submittedAt)
|
|
94476
|
+
});
|
|
94477
|
+
return application2;
|
|
94478
|
+
});
|
|
94287
94479
|
const interview_unlocked = INTERVIEW_UNLOCK_STATUSES.includes(status);
|
|
94288
94480
|
const hasPrep = !!interviewRepo.getByJob(jobId);
|
|
94289
|
-
const hint = interview_unlocked && !hasPrep ? "\uC11C\uB958 \uB2E8\uACC4\uB97C \uD1B5\uACFC\uD588\uC5B4\uC694. \uC774 \uACF5\uACE0 \uAE30\uC900\uC73C\uB85C \uC608\uC0C1 \uBA74\uC811 \uC9C8\uBB38\uACFC 1\uBD84 \uC790\uAE30\uC18C\uAC1C\uB97C \uC900\uBE44\uD560\uAE4C\uC694?
|
|
94481
|
+
const hint = interview_unlocked && !hasPrep ? "\uC11C\uB958 \uB2E8\uACC4\uB97C \uD1B5\uACFC\uD588\uC5B4\uC694. \uC774 \uACF5\uACE0 \uAE30\uC900\uC73C\uB85C \uC608\uC0C1 \uBA74\uC811 \uC9C8\uBB38\uACFC 1\uBD84 \uC790\uAE30\uC18C\uAC1C\uB97C \uC900\uBE44\uD560\uAE4C\uC694?" : null;
|
|
94290
94482
|
return { application, job, interview_unlocked, hint };
|
|
94291
94483
|
}
|
|
94292
94484
|
function saveInterviewPrep(input) {
|
|
94293
94485
|
const job = jobRepo.get(input.job_id);
|
|
94294
|
-
if (!job) throw notFound(
|
|
94295
|
-
const app = applicationRepo.getByJob(job.id);
|
|
94296
|
-
if (!app || !INTERVIEW_UNLOCK_STATUSES.includes(app.status)) {
|
|
94297
|
-
const current = app ? APPLICATION_STATUS_LABELS[app.status] : "\uBBF8\uC9C0\uC6D0";
|
|
94298
|
-
throw conflict(
|
|
94299
|
-
`\uBA74\uC811 \uC900\uBE44\uB294 '\uC11C\uB958 \uD569\uACA9' \uC774\uC0C1 \uC0C1\uD0DC\uC5D0\uC11C\uB9CC \uC800\uC7A5\uD560 \uC218 \uC788\uC2B5\uB2C8\uB2E4. \uD604\uC7AC \uC0C1\uD0DC: '${current}'. \uBA3C\uC800 update_application_status\uB85C \uC0C1\uD0DC\uB97C \uC62C\uB9B0 \uB4A4 \uB2E4\uC2DC \uC2DC\uB3C4\uD558\uC138\uC694.`
|
|
94300
|
-
);
|
|
94301
|
-
}
|
|
94486
|
+
if (!job) throw notFound("\uACF5\uACE0\uB97C \uCC3E\uC744 \uC218 \uC5C6\uC2B5\uB2C8\uB2E4.");
|
|
94302
94487
|
const prep = interviewRepo.save(input);
|
|
94303
94488
|
activityRepo.log("interview_prep_saved", `${job.company} \xB7 ${job.position} \uBA74\uC811 \uC900\uBE44 \uC790\uB8CC\uB97C \uC800\uC7A5\uD588\uC2B5\uB2C8\uB2E4.`, "interview_prep", prep.id);
|
|
94489
|
+
timelineRepo.add({
|
|
94490
|
+
job_id: job.id,
|
|
94491
|
+
type: "interview_prep_saved",
|
|
94492
|
+
title: "\uBA74\uC811 \uC900\uBE44",
|
|
94493
|
+
summary: prep.questions.length > 0 ? `\uC608\uC0C1 \uC9C8\uBB38 ${prep.questions.length}\uAC1C` : prep.notes ?? void 0,
|
|
94494
|
+
payload: {
|
|
94495
|
+
interview_prep_id: prep.id,
|
|
94496
|
+
question_count: prep.questions.length
|
|
94497
|
+
},
|
|
94498
|
+
occurred_at: prep.updated_at
|
|
94499
|
+
});
|
|
94304
94500
|
return prep;
|
|
94305
94501
|
}
|
|
94306
94502
|
|
|
@@ -94321,6 +94517,8 @@ var HUMANIZE_WRITING_GUIDE = `# \uC0AC\uB78C\uC774 \uC4F4 \uAC83\uCC98\uB7FC: \u
|
|
|
94321
94517
|
\uBAA9\uD45C: \uC0AC\uC2E4\uACFC \uACBD\uD5D8\uC740 100% \uADF8\uB300\uB85C \uB450\uBA74\uC11C, "AI\uAC00 \uC4F4 \uD2F0"\uAC00 \uB098\uB294 \uBB38\uC7A5 \uC2B5\uAD00\uB9CC \uC81C\uAC70\uD55C\uB2E4.
|
|
94322
94518
|
\uAC80\uC5F4\uAE30\uB97C \uC18D\uC774\uB294 \uAC8C \uC544\uB2C8\uB77C, \uCC44\uC6A9 \uB2F4\uB2F9\uC790\uAC00 \uC77D\uAE30\uC5D0 \uC790\uC5F0\uC2A4\uB7FD\uACE0 \uC0AC\uB78C \uB0C4\uC0C8 \uB098\uB294 \uAE00\uC744 \uC4F0\uB294 \uAC83\uC774 \uBAA9\uC801\uC774\uB2E4.
|
|
94323
94519
|
|
|
94520
|
+
> **\uC5B8\uC5B4 \uBC94\uC704:** \uC544\uB798 AI-tell \uBAA9\uB85D\uC740 \uD55C\uAD6D\uC5B4 \uAE00 \uAE30\uC900\uC774\uB2E4. \uC601\uC5B4 \uB4F1 \uB2E4\uB978 \uC5B8\uC5B4\uB85C \uC4F8 \uB54C\uB294 \uC774 \uBAA9\uB85D\uC744 \uADF8\uB300\uB85C \uC801\uC6A9\uD558\uC9C0 \uB9D0\uACE0, **\uAC19\uC740 \uC6D0\uB9AC**(\uD074\uB9AC\uC170\xB7\uAE30\uACC4\uC801 \uBCD1\uB82C\xB7\uACFC\uC7A5 \uC218\uC2DD\xB7\uACF5\uD5C8\uD55C \uC77C\uBC18\uB860 \uC81C\uAC70, \uAD6C\uCCB4\uC131, \uC0AC\uC2E4\xB7\uC218\uCE58 \uBCF4\uC874)\uB97C \uADF8 \uC5B8\uC5B4\uC758 \uC790\uC5F0\uC2A4\uB7EC\uC6B4 \uAD00\uC2B5\uC73C\uB85C \uC801\uC6A9\uD55C\uB2E4. \uACB0\uACFC\uBB3C\uC758 \uC5B8\uC5B4\uB294 \uB300\uC0C1 \uACF5\uACE0\xB7\uC2DC\uC7A5\uC744 \uB530\uB978\uB2E4.
|
|
94521
|
+
|
|
94324
94522
|
## \uC808\uB300 \uC6D0\uCE59
|
|
94325
94523
|
- \uC800\uC7A5\uB41C \uC2E4\uC81C \uACBD\uD5D8\xB7\uC218\uCE58\xB7\uD68C\uC0AC\uBA85\xB7\uACE0\uC720\uBA85\uC0AC\xB7\uC9C1\uC811 \uC778\uC6A9\uC740 \uC808\uB300 \uBC14\uAFB8\uAC70\uB098 \uC9C0\uC5B4\uB0B4\uC9C0 \uC54A\uB294\uB2E4. \uBB38\uC7A5 \uACB0\uB9CC \uB2E4\uB4EC\uB294\uB2E4.
|
|
94326
94524
|
- \uBE48\uCE78\uC774\uB098 \uD655\uC778\uC774 \uD544\uC694\uD55C \uBD80\uBD84\uC740 \uB9E4\uB044\uB7FD\uAC8C \uCC44\uC6CC \uB123\uC9C0 \uB9D0\uACE0 \uADF8\uB300\uB85C \uD45C\uC2DC\uD574 \uC0AC\uC6A9\uC790\uC5D0\uAC8C \uBB3B\uB294\uB2E4.
|
|
@@ -94362,6 +94560,33 @@ var HUMANIZE_WRITING_GUIDE = `# \uC0AC\uB78C\uC774 \uC4F4 \uAC83\uCC98\uB7FC: \u
|
|
|
94362
94560
|
- \uC18C\uB9AC \uB0B4\uC5B4 \uC77D\uC5C8\uC744 \uB54C \uC5B4\uC0C9\uD558\uAC70\uB098 "\uC0AC\uB78C\uC774 \uC774\uB807\uAC8C \uB9D0 \uC548 \uD558\uB294\uB370" \uC2F6\uC740 \uACF3\uC744 \uB2E4\uB4EC\uB294\uB2E4.
|
|
94363
94561
|
- \uC0AC\uC2E4\xB7\uC218\uCE58\xB7\uACE0\uC720\uBA85\uC0AC\uAC00 \uC6D0\uBCF8\uACFC 100% \uC77C\uCE58\uD558\uB294\uAC00?
|
|
94364
94562
|
- \uC0AC\uC6A9\uC790\uC758 \uD1A4\uACFC \uAC15\uC870 \uD3EC\uC778\uD2B8\uAC00 \uC0B4\uC544 \uC788\uB294\uAC00?`;
|
|
94563
|
+
var STRUCTURED_DOC_WRITING_GUIDE = `# \uAD6C\uC870\uD615 \uBB38\uC11C(\uACBD\uB825\uAE30\uC220\uC11C\xB7\uC774\uB825\uC11C\xB7\uD3EC\uD2B8\uD3F4\uB9AC\uC624) \uBCF4\uC815
|
|
94564
|
+
|
|
94565
|
+
\uACBD\uB825\uAE30\uC220\uC11C\xB7\uC774\uB825\uC11C\xB7\uD3EC\uD2B8\uD3F4\uB9AC\uC624\uB294 \uCC44\uC6A9 \uB2F4\uB2F9\uC790\uAC00 \uCC98\uC74C\uBD80\uD130 \uB05D\uAE4C\uC9C0 \uC77D\uB294 \uAE00\uC774 \uC544\uB2C8\uB77C \uBA87 \uCD08 \uC548\uC5D0 "\uC2A4\uCE94"\uD558\uB294 \uBB38\uC11C\uB2E4. \uBD88\uB9BF, \uBC88\uD638 \uB9E4\uAE34 \uC131\uACFC, \uC9C1\uBB34\xB7\uAE30\uAC04\xB7\uC5ED\uD560\uC744 \uAD6C\uBD84\uD55C \uC139\uC158 \uAD6C\uC870\uB294 AI\uAC00 \uC4F4 \uD2F0\uAC00 \uC544\uB2C8\uB77C \uC774 \uBB38\uC11C\uC758 \uC815\uC11D\uC774\uB2E4. \uC790\uAE30\uC18C\uAC1C\uC11C\uCC98\uB7FC \uC904\uAE00(\uC0B0\uBB38)\uB85C \uD480\uC9C0 \uB9D0\uACE0 \uAD6C\uC870\uB97C \uBCF4\uC874\uD55C\uB2E4.
|
|
94566
|
+
|
|
94567
|
+
## \uC704 8\uAC1C AI-tell \uC911 \uAD6C\uC870\uD615\uC5D0\uC11C \uB2E4\uB974\uAC8C \uC801\uC6A9\uD558\uB294 \uAC83
|
|
94568
|
+
- 3\uBC88(\uAE30\uACC4\uC801 \uBCD1\uB82C)\xB78\uBC88(\uD615\uC2DD \uACFC\uC6A9)\uC740 \uC0B0\uBB38 \uBB38\uC7A5\uC5D0\uB9CC \uC801\uC6A9\uD55C\uB2E4. \uC131\uACFC\uB97C \uB098\uC5F4\uD558\uB294 \uBD88\uB9BF\xB7\uBC88\uD638 \uBAA9\uB85D \uAD6C\uC870 \uC790\uCCB4\uC5D0\uB294 \uC801\uC6A9\uD558\uC9C0 \uC54A\uB294\uB2E4 \u2014 \uBD88\uB9BF\uB85C \uB04A\uC5B4 \uC4F0\uB294 \uAC83\uC740 \uAC00\uB3C5\uC131\uC744 \uC704\uD55C \uC815\uC0C1 \uAD6C\uC870\uB2E4.
|
|
94569
|
+
- \uB2E8 \uC758\uBBF8 \uC5C6\uB294 "\uCCAB\uC9F8\xB7\uB458\uC9F8\xB7\uC14B\uC9F8" \uC11C\uC218 \uB098\uC5F4, \uBAA8\uB4E0 \uBD88\uB9BF\uC744 \uB611\uAC19\uC740 \uACE8\uACA9("~\uC744 \uD1B5\uD574 ~\uC744 \uD568")\uC73C\uB85C \uCC0D\uC5B4\uB0B4\uB294 \uAC83, \uACFC\uD55C \uAD75\uAC8C\xB7\uC774\uBAA8\uC9C0\xB7\uAC00\uC6B4\uB383\uC810 \uB5A1\uCE60\uC740 \uAD6C\uC870\uD615\uC5D0\uC11C\uB3C4 \uC81C\uAC70\uD55C\uB2E4.
|
|
94570
|
+
|
|
94571
|
+
## \uAD6C\uC870\uB294 \uC0B4\uB9AC\uACE0, \uBD88\uB9BF '\uC548\uC758 \uC5B8\uC5B4'\uB9CC \uC0AC\uB78C\uB2F5\uAC8C
|
|
94572
|
+
- \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.
|
|
94573
|
+
- \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)
|
|
94574
|
+
- 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.
|
|
94575
|
+
|
|
94576
|
+
## Do / Don't
|
|
94577
|
+
- 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.
|
|
94578
|
+
- Don't: \uACBD\uB825\uAE30\uC220\uC11C\uB97C \uC790\uAE30\uC18C\uAC1C\uC11C\uCC98\uB7FC \uC904\uAE00\uB85C \uD3C9\uD0C4\uD654\uD558\uC9C0 \uC54A\uB294\uB2E4. \uBD88\uB9BF\uC744 \uC5C6\uC560 \uC2A4\uCE94\uD558\uAE30 \uC5B4\uB835\uAC8C \uB9CC\uB4E4\uC9C0 \uC54A\uB294\uB2E4. \uB77C\uBCA8\xB7\uAD6C\uC870\uB97C \uB2E4 \uAC77\uC5B4\uB0B4 \uAC00\uB3C5\uC131\uC744 \uB5A8\uC5B4\uB728\uB9AC\uC9C0 \uC54A\uB294\uB2E4.
|
|
94579
|
+
|
|
94580
|
+
\uD575\uC2EC: \uC790\uAE30\uC18C\uAC1C\uC11C\uB294 \uC0AC\uB78C\uC758 \uBAA9\uC18C\uB9AC(\uC0B0\uBB38)\uB85C, \uACBD\uB825\uAE30\uC220\uC11C\xB7\uC774\uB825\uC11C\uB294 \uC0AC\uB78C\uC758 \uC5B8\uC5B4\uB85C \uC4F4 \uAE54\uB054\uD55C \uAD6C\uC870\uB85C. \uB458 \uB2E4 \uC0AC\uC2E4\xB7\uC218\uCE58\xB7\uACE0\uC720\uBA85\uC0AC\uB294 100% \uBCF4\uC874\uD55C\uB2E4.`;
|
|
94581
|
+
var STRUCTURED_DOC_TYPES = /* @__PURE__ */ new Set(["career_description", "resume", "portfolio"]);
|
|
94582
|
+
function getWritingStyleGuide(docType) {
|
|
94583
|
+
if (docType && STRUCTURED_DOC_TYPES.has(docType)) {
|
|
94584
|
+
return `${HUMANIZE_WRITING_GUIDE}
|
|
94585
|
+
|
|
94586
|
+
${STRUCTURED_DOC_WRITING_GUIDE}`;
|
|
94587
|
+
}
|
|
94588
|
+
return HUMANIZE_WRITING_GUIDE;
|
|
94589
|
+
}
|
|
94365
94590
|
|
|
94366
94591
|
// packages/workflows/src/definitions.ts
|
|
94367
94592
|
var WORKFLOWS = [
|
|
@@ -94372,7 +94597,7 @@ var WORKFLOWS = [
|
|
|
94372
94597
|
trigger: '\uC0AC\uC6A9\uC790\uAC00 \uCC98\uC74C CareerMate\uC5D0 \uC5F0\uACB0\uD588\uAC70\uB098, "\uC2DC\uC791\uD558\uC790 / \uC14B\uC5C5\uD574\uC918 / \uD504\uB85C\uD544 \uB4F1\uB85D"\uC774\uB77C\uACE0 \uC694\uCCAD\uD560 \uB54C.',
|
|
94373
94598
|
steps: [
|
|
94374
94599
|
"`get_onboarding_status`\uB97C \uD638\uCD9C\uD574 \uD604\uC7AC \uB4F1\uB85D \uC0C1\uD0DC(has_profile, has_resume, has_cover_letter, has_experience, has_skills, profile_completeness, next_steps)\uB97C \uD655\uC778\uD55C\uB2E4.",
|
|
94375
|
-
'\uBE44\uC5B4 \uC788\uB294 \uD56D\uBAA9\uC744 \uC0AC\uC6A9\uC790\
|
|
94600
|
+
'\uBE44\uC5B4 \uC788\uB294 \uD56D\uBAA9\uC744 \uC0AC\uC6A9\uC790\uC758 \uC5B8\uC5B4\uB85C \uC27D\uAC8C \uC548\uB0B4\uD558\uACE0, \uBA3C\uC800 "\uAE30\uC874\uC5D0 \uC791\uC131\uD574 \uB454 \uC774\uB825\uC11C\xB7\uACBD\uB825\uAE30\uC220\uC11C\xB7\uC790\uAE30\uC18C\uAC1C\uC11C \uD30C\uC77C\uC774 \uC788\uB294\uC9C0" \uBB3B\uB294\uB2E4(hwp/docx/pdf \uBAA8\uB450 \uAC00\uB2A5).',
|
|
94376
94601
|
'\uD30C\uC77C \uC785\uB825 \uBD84\uAE30: \u2460 \uC0AC\uC6A9\uC790\uAC00 "\uD30C\uC77C\uC774 \uC788\uB2E4"\uACE0 \uD558\uBA74 `open_inbox`\uB85C \uC778\uC785 \uD3F4\uB354\uB97C \uC5F4\uC5B4 \uD30C\uC77C\uC744 \uB123\uAC8C \uD558\uACE0, "\uB2E4 \uB123\uC5C8\uB2E4"\uACE0 \uD558\uBA74 `read_inbox`\uB85C \uBCF8\uBB38\uC744 \uC77D\uB294\uB2E4(pdf\xB7\uC774\uBBF8\uC9C0\uB294 read_inbox\uAC00 \uACBD\uB85C\uB9CC \uC8FC\uBBC0\uB85C \uD074\uB77C\uC774\uC5B8\uD2B8\uC758 \uD30C\uC77C \uC77D\uAE30\uB85C \uC9C1\uC811 \uC77D\uB294\uB2E4). \u2461 \uC0AC\uC6A9\uC790\uAC00 \uD30C\uC77C \uACBD\uB85C\uB97C \uC9C1\uC811 \uC54C\uB824\uC8FC\uBA74 `read_document`\uB85C \uC77D\uB294\uB2E4. \u2462 "\uC5C6\uB2E4/\uC9C1\uC811 \uC785\uB825/\uD14D\uC2A4\uD2B8\uB85C \uBD99\uC5EC\uB123\uAE30"\uBA74 \uD3F4\uB354\uB97C \uC5F4\uC9C0 \uB9D0\uACE0 \uBC1B\uC740 \uD14D\uC2A4\uD2B8\uB97C \uADF8\uB300\uB85C \uC4F4\uB2E4. (\uBB3B\uC9C0\uB3C4 \uC54A\uACE0 open_inbox\uB85C \uD3F4\uB354\uB97C \uC790\uB3D9\uC73C\uB85C \uC5F4\uC9C0 \uC54A\uB294\uB2E4.)',
|
|
94377
94602
|
"\uC218\uC9D1\uD55C \uC815\uBCF4\uB97C \uAD6C\uC870\uD654\uD574 `save_profile`\uB85C \uC800\uC7A5\uD55C\uB2E4(\uC774\uB984\xB7\uC5F0\uB77D\uCC98\xB7headline\xB7summary\xB7desired_roles\xB7desired_conditions, \uADF8\uB9AC\uACE0 \uAE00\uC4F0\uAE30 \uC120\uD638\uC778 preferred_tone\uACFC emphasis_points \uD3EC\uD568). \uD30C\uC77C \uCD9C\uCC98\uB294 source=upload, \uC9C1\uC811 \uC785\uB825\uC740 manual.",
|
|
94378
94603
|
"\uC5C5\uB85C\uB4DC\uD55C \uC774\uB825\uC11C/\uACBD\uB825\uAE30\uC220\uC11C/\uD3EC\uD2B8\uD3F4\uB9AC\uC624 \uBCF8\uBB38\uC744 `add_resume`\uB85C \uC800\uC7A5\uD55C\uB2E4(kind\xB7title \uC9C0\uC815, \uB300\uD45C \uBB38\uC11C\uB294 is_primary=true).",
|
|
@@ -94393,9 +94618,9 @@ var WORKFLOWS = [
|
|
|
94393
94618
|
"\uACF5\uACE0 \uC694\uAD6C\uC0AC\uD56D\uACFC \uC0AC\uC6A9\uC790 \uACBD\uB825/\uC2A4\uD0AC/\uD504\uB85C\uC81D\uD2B8\uB97C \uBE44\uAD50\uD55C\uB2E4: \uC77C\uCE58\uD558\uB294 \uAC15\uC810(strengths)\uACFC \uBD80\uC871\uD55C \uBD80\uBD84(gaps), \uB9E4\uCE6D \uD0A4\uC6CC\uB4DC(matched_keywords)\uC640 \uB204\uB77D \uD0A4\uC6CC\uB4DC(missing_keywords)\uB97C \uB3C4\uCD9C\uD558\uACE0, \uC885\uD569 \uC801\uD569\uB3C4 \uC810\uC218(score 0~100)\uC640 \uC694\uC57D(summary), \uC9C0\uC6D0 \uC804\uB7B5 \uC81C\uC548(recommendations)\uC744 \uC815\uB9AC\uD55C\uB2E4. \uC5C6\uB294 \uACBD\uD5D8\uC744 \uC9C0\uC5B4\uB0B4\uC9C0 \uC54A\uB294\uB2E4.",
|
|
94394
94619
|
"\uC544\uC9C1 \uC800\uC7A5\uB418\uC9C0 \uC54A\uC740 \uACF5\uACE0\uB77C\uBA74 `save_job_posting`\uC73C\uB85C \uACF5\uACE0\uB97C \uC800\uC7A5\uD558\uACE0 job_id\uB97C \uD655\uBCF4\uD55C\uB2E4.",
|
|
94395
94620
|
"\uB3C4\uCD9C\uD55C \uBD84\uC11D \uACB0\uACFC\uB97C `save_fit_analysis`\uB85C \uC800\uC7A5\uD55C\uB2E4(job_id, score, summary, strengths, gaps, matched_keywords, missing_keywords, recommendations).",
|
|
94396
|
-
"\uBD84\uC11D \uACB0\uACFC\uB97C \uC0AC\uC6A9\uC790\
|
|
94397
|
-
'"\uC774 \uACF5\uACE0\uC5D0 \uB9DE\uCD98 \uC790\uAE30\uC18C\uAC1C\uC11C\uB97C \uC368\uB4DC\uB9B4\uAE4C\uC694?"\uB77C\uACE0 \uC790\uAE30\uC18C\uAC1C\uC11C \
|
|
94398
|
-
'\uC0AC\uC6A9\uC790\uAC00 \
|
|
94621
|
+
"\uBD84\uC11D \uACB0\uACFC\uB97C \uC0AC\uC6A9\uC790\uC758 \uC5B8\uC5B4\uB85C \uC27D\uAC8C \uC124\uBA85\uD55C\uB2E4(\uC798 \uB9DE\uB294 \uC810, \uBCF4\uC644\uD560 \uC810, \uCD94\uCC9C \uC804\uB7B5). \uAE30\uC220 \uC6A9\uC5B4\uB294 \uBE7C\uACE0 \uC804\uB2EC\uD55C\uB2E4.",
|
|
94622
|
+
'\uBD84\uC11D \uB4A4 \uACE7\uC7A5 \uC790\uAE30\uC18C\uAC1C\uC11C\uB97C \uC4F0\uC9C0 \uB9D0\uACE0, "\uC774 \uACF5\uACE0\uC5D0 \uB9DE\uCD98 \uC790\uAE30\uC18C\uAC1C\uC11C\uB97C \uC368\uB4DC\uB9B4\uAE4C\uC694?"\uB77C\uACE0 \uBB3B\uACE0 \uC120\uD0DD\uC9C0\uB97C \uC81C\uC2DC\uD55C\uB2E4: \u2460 "\uB124, \uC774 \uACF5\uACE0\uC5D0 \uB9DE\uCD98 \uC790\uAE30\uC18C\uAC1C\uC11C\uB97C \uC368\uC918" \u2461 "\uC544\uB2C8\uC694, \uBD84\uC11D\uB9CC \uC800\uC7A5\uD574\uC918".',
|
|
94623
|
+
'\uC0AC\uC6A9\uC790\uAC00 \u2460\uC744 \uC120\uD0DD\uD558\uBA74 \uC790\uAE30\uC18C\uAC1C\uC11C\uB97C \uC791\uC131\uD558\uAE30 \uC9C1\uC804\uC5D0 `get_writing_style_guide`\uB97C \uD638\uCD9C\uD574 "AI \uD2F0 \uC548 \uB098\uB294 \uAE00\uC4F0\uAE30 \uADDC\uCE59"\uC744 \uAC00\uC838\uC628\uB2E4. \u2461\uB97C \uC120\uD0DD\uD558\uBA74 \uC790\uC18C\uC11C \uC791\uC131 \uC5C6\uC774 \uBA48\uCD94\uACE0 \uC800\uC7A5 \uACB0\uACFC\uC640 \uB300\uC2DC\uBCF4\uB4DC \uD655\uC778\uB9CC \uC548\uB0B4\uD55C\uB2E4.',
|
|
94399
94624
|
"\uC801\uD569\uB3C4 \uBD84\uC11D\xB7\uAE00\uC4F0\uAE30 \uC120\uD638\uC640 \uAE00\uC4F0\uAE30 \uADDC\uCE59\uC744 \uD568\uAED8 \uBC18\uC601\uD574 \uC790\uAE30\uC18C\uAC1C\uC11C\uB97C \uC791\uC131\uD558\uACE0(\uBC88\uC5ED\uD22C\xB7\uD074\uB9AC\uC170\xB7\uAE30\uACC4\uC801 \uBCD1\uB82C \uC81C\uAC70, \uC0AC\uC2E4\xB7\uC218\uCE58\uB294 \uADF8\uB300\uB85C), `save_cover_letter_version`\uC73C\uB85C \uC800\uC7A5\uD55C\uB2E4(job_id \uC5F0\uACB0, note\uC5D0 \uC791\uC131 \uC758\uB3C4 \uC694\uC57D).",
|
|
94400
94625
|
"`open_application`\uC73C\uB85C \uD574\uB2F9 \uC9C0\uC6D0 \uAC74\uC744 \uC5F4\uC5B4 \uC0AC\uC6A9\uC790\uAC00 \uACB0\uACFC\uB97C \uD655\uC778\uD558\uAC8C \uD558\uACE0, \uC9C0\uC6D0 \uC0C1\uD0DC \uBCC0\uACBD(\uC608: \uC9C0\uC6D0 \uC608\uC815/\uC9C0\uC6D0 \uC644\uB8CC)\uC744 \uC81C\uC548\uD55C\uB2E4."
|
|
94401
94626
|
]
|
|
@@ -94412,7 +94637,24 @@ var WORKFLOWS = [
|
|
|
94412
94637
|
"\uC800\uC7A5\uB41C \uC2E4\uC81C \uACBD\uD5D8\xB7\uC131\uACFC\uB9CC\uC73C\uB85C \uC790\uAE30\uC18C\uAC1C\uC11C\uB97C \uC791\uC131\uD558\uB418, \uC704 \uAE00\uC4F0\uAE30 \uADDC\uCE59\uC744 \uC801\uC6A9\uD574 \uC0AC\uB78C\uC774 \uC4F4 \uB4EF \uC790\uC5F0\uC2A4\uB7FD\uAC8C \uC4F4\uB2E4(\uC0AC\uC2E4\xB7\uC218\uCE58\xB7\uACE0\uC720\uBA85\uC0AC\uB294 \uADF8\uB300\uB85C). \uBE48\uCE78\uC774\uB098 \uD655\uC778\uC774 \uD544\uC694\uD55C \uBD80\uBD84\uC740 \uCD94\uCE21\uD558\uC9C0 \uB9D0\uACE0 \uD45C\uC2DC\uD574 \uC0AC\uC6A9\uC790\uC5D0\uAC8C \uBB3B\uB294\uB2E4.",
|
|
94413
94638
|
"\uC644\uC131\uBCF8\uC744 `save_cover_letter_version`\uC73C\uB85C \uC800\uC7A5\uD55C\uB2E4(\uAE30\uC874 \uC790\uAE30\uC18C\uAC1C\uC11C\uBA74 cover_letter_id, \uC0C8\uB85C \uB9CC\uB4E4\uBA74 title, \uACF5\uACE0\uC6A9\uC774\uBA74 job_id, \uBCC0\uACBD \uC694\uC57D\uC740 note, source=ai).",
|
|
94414
94639
|
"\uC0AC\uC6A9\uC790\uAC00 \uC6D0\uD558\uBA74 `export_cover_letter`\uB85C \uD30C\uC77C\uB85C \uB0B4\uBCF4\uB0B4\uACE0, \uCD94\uAC00 \uC218\uC815 \uC694\uCCAD\uC774 \uC788\uC73C\uBA74 \uC0C8 \uBC84\uC804\uC73C\uB85C \uB2E4\uC2DC \uC800\uC7A5\uD55C\uB2E4.",
|
|
94415
|
-
"\uC800\uC7A5 \uACB0\uACFC\uB97C \
|
|
94640
|
+
"\uC800\uC7A5 \uACB0\uACFC\uB97C \uC0AC\uC6A9\uC790\uC758 \uC5B8\uC5B4\uB85C \uC54C\uB9AC\uACE0, \uC9C0\uC6D0 \uC0C1\uD0DC \uC5C5\uB370\uC774\uD2B8(`update_application_status`)\uB098 \uBA74\uC811 \uC900\uBE44 \uB4F1 \uB2E4\uC74C \uB2E8\uACC4\uB97C \uC81C\uC548\uD55C\uB2E4."
|
|
94641
|
+
]
|
|
94642
|
+
},
|
|
94643
|
+
{
|
|
94644
|
+
id: "write_career_description",
|
|
94645
|
+
title: "\uACBD\uB825\uAE30\uC220\uC11C \uC791\uC131",
|
|
94646
|
+
description: "\uD504\uB85C\uD544\xB7\uC774\uB825\uC11C\xB7\uACBD\uB825\xB7\uD504\uB85C\uC81D\uD2B8\xB7\uC2A4\uD0AC\uC744 \uADFC\uAC70\uB85C \uC2E4\uC81C \uC81C\uCD9C \uAC00\uB2A5\uD55C \uACBD\uB825\uAE30\uC220\uC11C\uB97C \uC791\uC131\uD558\uACE0 \uBB38\uC11C\uD568\uC5D0 \uC800\uC7A5\uD558\uB294 \uD750\uB984.",
|
|
94647
|
+
trigger: '\uC0AC\uC6A9\uC790\uAC00 "\uACBD\uB825\uAE30\uC220\uC11C \uC368\uC918 / \uACBD\uB825\uAE30\uC220\uC11C \uB9CC\uB4E4\uC5B4\uC918 / \uB0B4 \uACBD\uB825 \uC815\uB9AC\uD574\uC918"\uB77C\uACE0 \uC694\uCCAD\uD560 \uB54C.',
|
|
94648
|
+
steps: [
|
|
94649
|
+
"`get_onboarding_status`\uB85C \uC900\uBE44 \uC0C1\uD0DC\uB97C \uD655\uC778\uD558\uACE0, `get_profile`\xB7`get_resumes`\xB7`get_experiences`\xB7`get_projects`\xB7`get_skills`\uB97C \uD638\uCD9C\uD574 \uAE30\uC874 \uD504\uB85C\uD544, \uC774\uB825\uC11C, \uACBD\uB825\uAE30\uC220\uC11C(kind=career_description), \uACBD\uB825, \uD504\uB85C\uC81D\uD2B8, \uAE30\uC220\uC2A4\uD0DD\uC744 \uBAA8\uB450 \uD655\uC778\uD55C\uB2E4.",
|
|
94650
|
+
"\uC0AC\uC6A9\uC790\uAC00 \uD30C\uC77C \uACBD\uB85C\uB97C \uC8FC\uBA74 `read_document`\uB85C \uC77D\uACE0, \uC778\uC785 \uD3F4\uB354\uB97C \uC0AC\uC6A9\uD588\uB2E4\uBA74 `read_inbox`\uB85C \uBCF8\uBB38\uC744 \uC77D\uB294\uB2E4. \uC774\uBBF8 \uC800\uC7A5\uB41C \uC790\uB8CC\uC640 \uC0C8 \uD30C\uC77C\uC744 \uBE44\uAD50\uD574 \uC911\uBCF5\xB7\uC0C1\uCDA9\uB418\uB294 \uC0AC\uC2E4\uC740 \uD45C\uC2DC\uD558\uACE0 \uCD94\uCE21\uD558\uC9C0 \uC54A\uB294\uB2E4.",
|
|
94651
|
+
'`get_workflow_guide({ workflow_id: "write_career_description" })`\uAC00 \uC548\uB0B4\uD558\uB294 \uC804\uBB38\uAC00 \uC808\uCC28\uB97C \uB530\uB978\uB2E4. \uC791\uC131 \uC9C1\uC804 `get_playbook({ domain: "resume" })`\uC640 `get_playbook({ domain: "ats" })`\uB97C \uBC1B\uC544 \uC2E4\uC81C \uACBD\uB825\uAE30\uC220\uC11C \uD615\uC2DD\uACFC ATS \uCE5C\uD654\uC131\uC744 \uC801\uC6A9\uD55C\uB2E4.',
|
|
94652
|
+
"\uC791\uC131 \uC804\uC5D0 \uBAA9\uC801\uC744 \uD655\uC778\uD55C\uB2E4: \uBC94\uC6A9 \uB9C8\uC2A4\uD130\uBCF8\uC778\uC9C0, \uD2B9\uC815 \uC9C1\uBB34/\uACF5\uACE0\uC6A9\uC778\uC9C0, \uC2E0\uC785/\uBB34\uACBD\uB825\uC774\uB77C \uD504\uB85C\uC81D\uD2B8\xB7\uAD50\uC721\xB7\uD65C\uB3D9 \uC911\uC2EC \uC5ED\uB7C9\uAE30\uC220\uC11C\uB85C \uC4F8\uC9C0, \uBD84\uB7C9\uACFC \uD1A4\uC740 \uC5B4\uB5BB\uAC8C \uD560\uC9C0 \uBB3B\uB294\uB2E4.",
|
|
94653
|
+
"\uACBD\uB825\uAE30\uC220\uC11C\uB294 \uC790\uAE30\uC18C\uAC1C\uC11C\uCC98\uB7FC \uC11C\uC0AC\uB85C \uC4F0\uC9C0 \uC54A\uB294\uB2E4. \uC81C\uBAA9, \uD575\uC2EC \uC694\uC57D, \uD575\uC2EC \uC5ED\uB7C9, \uACBD\uB825/\uD504\uB85C\uC81D\uD2B8\uBCC4 \uC5ED\uD560\xB7\uAE30\uAC04\xB7\uB3C4\uAD6C\xB7\uBB38\uC81C\xB7\uD589\uB3D9\xB7\uC131\uACFC\uB97C \uD45C\uB098 \uBD88\uB9BF \uC911\uC2EC\uC73C\uB85C \uC815\uB9AC\uD55C\uB2E4. \uC218\uCE58\xB7\uD68C\uC0AC\uBA85\xB7\uAE30\uAC04\xB7\uC9C1\uCC45\uC740 \uC800\uC7A5\uB41C \uC0AC\uC2E4\uB9CC \uC4F0\uACE0, \uC5C6\uB294 \uC131\uACFC \uC218\uCE58\uB294 \uB9CC\uB4E4\uC9C0 \uC54A\uB294\uB2E4.",
|
|
94654
|
+
'\uBB34\uACBD\uB825/\uBE44\uAC1C\uBC1C\uC790\uB77C\uBA74 \uACBD\uB825\uC744 \uB0A0\uC870\uD558\uC9C0 \uB9D0\uACE0 \uAD50\uC721\xB7\uD504\uB85C\uC81D\uD2B8\xB7\uC6B4\uC601 \uACBD\uD5D8\xB7\uC5C5\uBB34 \uB3C4\uAD6C\xB7\uD611\uC5C5 \uACBD\uD5D8\xB7\uC131\uACFC \uC99D\uAC70 \uC911\uC2EC\uC758 "\uC5ED\uB7C9\uAE30\uC220\uC11C"\uB85C \uAD6C\uC131\uD55C\uB2E4.',
|
|
94655
|
+
'\uC800\uC7A5 \uC9C1\uC804 `get_verifier({ id: "truthfulness" })`, `get_verifier({ id: "consistency" })`, `get_verifier({ id: "ats-compat" })`\uB97C \uBC1B\uC544 \uB2F9\uC2E0\uC774 \uC9C1\uC811 \uC810\uAC80\uD558\uACE0, \uD5C8\uC704\xB7\uC0C1\uCDA9\xB7\uD0A4\uC6CC\uB4DC \uB204\uB77D\uC744 \uACE0\uCE5C\uB2E4. \uD655\uC778\uC774 \uD544\uC694\uD55C \uC0AC\uC2E4\uC740 \uBCF8\uBB38\uC5D0 \uD45C\uC2DC\uD558\uACE0 \uC0AC\uC6A9\uC790\uC5D0\uAC8C \uBB3B\uB294\uB2E4.',
|
|
94656
|
+
"\uC644\uC131\uBCF8\uC744 `add_resume`\uC73C\uB85C \uC800\uC7A5\uD55C\uB2E4(kind=career_description, source=ai, title\uC740 \uC0AC\uC6A9 \uBAA9\uC801\uC774 \uB4DC\uB7EC\uB098\uAC8C \uC791\uC131, tags\uC5D0 \uC9C1\uBB34/\uC6A9\uB3C4 \uD0A4\uC6CC\uB4DC \uD3EC\uD568). \uB300\uD45C \uBB38\uC11C\uB85C \uC0BC\uC544\uB3C4 \uB418\uB294\uC9C0 \uD655\uC778\uB41C \uACBD\uC6B0\uC5D0\uB9CC is_primary=true\uB97C \uC4F4\uB2E4.",
|
|
94657
|
+
"\uC800\uC7A5 \uACB0\uACFC\uB97C \uC0AC\uC6A9\uC790\uC758 \uC5B8\uC5B4\uB85C \uC54C\uB9AC\uACE0, \uBB38\uC11C \uD0ED\uC5D0\uC11C \uD655\uC778\uD560 \uC218 \uC788\uC74C\uC744 \uC548\uB0B4\uD55C\uB2E4. \uD2B9\uC815 \uACF5\uACE0\uC6A9\uC73C\uB85C \uC791\uC131\uD588\uB2E4\uBA74 \uC774\uC5B4\uC11C \uC790\uAE30\uC18C\uAC1C\uC11C\uB098 \uBA74\uC811 \uC900\uBE44\uB97C \uC81C\uC548\uD55C\uB2E4."
|
|
94416
94658
|
]
|
|
94417
94659
|
},
|
|
94418
94660
|
{
|
|
@@ -94423,7 +94665,7 @@ var WORKFLOWS = [
|
|
|
94423
94665
|
steps: [
|
|
94424
94666
|
"\uD544\uC694\uD558\uBA74 `get_application_context` \uB610\uB294 `get_job_posting`\uC73C\uB85C \uB300\uC0C1 \uC9C0\uC6D0 \uAC74\uACFC \uACF5\uACE0\uB97C \uD655\uC778\uD55C\uB2E4.",
|
|
94425
94667
|
"\uC801\uC808\uD55C \uC0C1\uD0DC\uB85C `update_application_status`\uB97C \uD638\uCD9C\uD55C\uB2E4. 8\uB2E8\uACC4: draft(\uC791\uC131 \uC911), planned(\uC9C0\uC6D0 \uC608\uC815), applied(\uC9C0\uC6D0 \uC644\uB8CC), document_passed(\uC11C\uB958 \uD569\uACA9), interview(\uBA74\uC811 \uC9C4\uD589), final_passed(\uCD5C\uC885 \uD569\uACA9), rejected(\uBD88\uD569\uACA9), on_hold(\uBCF4\uB958). \uBCC0\uACBD \uC0AC\uC720\uB294 note\uC5D0 \uB0A8\uAE34\uB2E4.",
|
|
94426
|
-
"\uBCC0\uACBD \uACB0\uACFC\uB97C \uC0AC\uC6A9\uC790\
|
|
94668
|
+
"\uBCC0\uACBD \uACB0\uACFC\uB97C \uC0AC\uC6A9\uC790\uC758 \uC5B8\uC5B4\uB85C \uC27D\uAC8C \uC54C\uB9B0\uB2E4.",
|
|
94427
94669
|
"\uC0C1\uD0DC\uC5D0 \uB9DE\uB294 \uB2E4\uC74C \uB2E8\uACC4\uB97C \uC81C\uC548\uD55C\uB2E4: applied \u2192 \uACB0\uACFC \uAE30\uB2E4\uB9AC\uAE30 \uC548\uB0B4, document_passed/interview \u2192 \uBA74\uC811 \uC900\uBE44(prepare_interview) \uC81C\uC548, final_passed \u2192 \uCD95\uD558 \uBC0F \uB9C8\uBB34\uB9AC, rejected/on_hold \u2192 \uD68C\uACE0 \uB610\uB294 \uB2E4\uB978 \uACF5\uACE0 \uD0D0\uC0C9 \uC81C\uC548.",
|
|
94428
94670
|
"\uD544\uC694\uD558\uBA74 `open_application`\uC73C\uB85C \uD574\uB2F9 \uC9C0\uC6D0 \uAC74\uC744 \uC5F4\uC5B4 \uBCF4\uC5EC\uC900\uB2E4."
|
|
94429
94671
|
]
|
|
@@ -94431,14 +94673,29 @@ var WORKFLOWS = [
|
|
|
94431
94673
|
{
|
|
94432
94674
|
id: "prepare_interview",
|
|
94433
94675
|
title: "\uBA74\uC811 \uC900\uBE44",
|
|
94434
|
-
description: "\
|
|
94435
|
-
trigger: '\uC9C0\uC6D0 \uC0C1\uD0DC\uAC00 \uC11C\uB958 \uD569\uACA9(document_passed) \uB610\uB294 \uBA74\uC811 \uC9C4\uD589(interview)\uC73C\uB85C \uBC14\uB00C\uC5C8\uC744 \uB54C
|
|
94676
|
+
description: "\uACF5\uACE0 \uAE30\uC900 \uC608\uC0C1 \uC9C8\uBB38\xB7STAR \uB2F5\uBCC0\xB71\uBD84 \uC790\uAE30\uC18C\uAC1C\uB97C \uC900\uBE44\uD574 \uC800\uC7A5\uD558\uB294 \uD750\uB984.",
|
|
94677
|
+
trigger: '\uC0AC\uC6A9\uC790\uAC00 "\uBA74\uC811 \uC900\uBE44 \uB3C4\uC640\uC918"\uB77C\uACE0 \uC694\uCCAD\uD558\uAC70\uB098, \uC9C0\uC6D0 \uC0C1\uD0DC\uAC00 \uC11C\uB958 \uD569\uACA9(document_passed) \uB610\uB294 \uBA74\uC811 \uC9C4\uD589(interview)\uC73C\uB85C \uBC14\uB00C\uC5C8\uC744 \uB54C.',
|
|
94436
94678
|
steps: [
|
|
94437
94679
|
"`get_application_context`(job_id \uD3EC\uD568)\uB97C \uD638\uCD9C\uD574 \uACF5\uACE0, \uD504\uB85C\uD544, \uACBD\uB825/\uD504\uB85C\uC81D\uD2B8, \uC801\uD569\uB3C4 \uBD84\uC11D(\uAC15\uC810\xB7\uAC2D), \uC790\uAE30\uC18C\uAC1C\uC11C\uB97C \uAC00\uC838\uC628\uB2E4.",
|
|
94438
94680
|
"\uACF5\uACE0\uC640 \uC0AC\uC6A9\uC790 \uACBD\uD5D8\uC744 \uBC14\uD0D5\uC73C\uB85C \uC608\uC0C1 \uBA74\uC811 \uC9C8\uBB38(question, intent, followups, answer_outline)\uC744 \uB3C4\uCD9C\uD55C\uB2E4.",
|
|
94439
94681
|
"\uD575\uC2EC \uACBD\uD5D8\uC5D0 \uB300\uD55C STAR \uAC00\uC774\uB4DC(question, situation, task, action, result)\uC640 1\uBD84 \uC790\uAE30\uC18C\uAC1C(self_introduction) \uCD08\uC548\uC744 \uC791\uC131\uD55C\uB2E4. \uC2E4\uC81C \uACBD\uD5D8\uB9CC \uC0AC\uC6A9\uD55C\uB2E4.",
|
|
94440
94682
|
"\uC900\uBE44 \uB0B4\uC6A9\uC744 `save_interview_prep`\uB85C \uC800\uC7A5\uD55C\uB2E4(job_id, questions, star_guides, self_introduction, notes).",
|
|
94441
|
-
"\uC900\uBE44 \uB0B4\uC6A9\uC744 \uC0AC\uC6A9\uC790\
|
|
94683
|
+
"\uC900\uBE44 \uB0B4\uC6A9\uC744 \uC0AC\uC6A9\uC790\uC758 \uC5B8\uC5B4\uB85C \uC27D\uAC8C \uC694\uC57D\uD574 \uC804\uB2EC\uD558\uACE0, \uBAA8\uC758 \uBA74\uC811/\uCD94\uAC00 \uC9C8\uBB38 \uC5F0\uC2B5\uC774\uB098 \uC0C1\uD0DC \uC5C5\uB370\uC774\uD2B8(`update_application_status`\uB85C interview/final_passed)\uB97C \uC81C\uC548\uD55C\uB2E4."
|
|
94684
|
+
]
|
|
94685
|
+
},
|
|
94686
|
+
{
|
|
94687
|
+
id: "build_personal_brand",
|
|
94688
|
+
title: "\uD37C\uC2A4\uB110 \uBE0C\uB79C\uB4DC (LinkedIn\xB7\uD3EC\uD2B8\uD3F4\uB9AC\uC624)",
|
|
94689
|
+
description: "LinkedIn \uD504\uB85C\uD544\uACFC \uD3EC\uD2B8\uD3F4\uB9AC\uC624 \uAC19\uC740 \uC790\uAE30\uD45C\uD604 \uC790\uC0B0\uC744 \uC9C1\uBB34\uC5D0 \uB9DE\uCDB0 \uC791\uC131\xB7\uCD5C\uC801\uD654\uD558\uB294 \uD750\uB984. \uC774\uB825\uC11C \uC784\uD3EC\uD2B8(\uC628\uBCF4\uB529)\uC640 \uBD84\uB9AC\uB41C \uBCC4\uB3C4 \uC791\uC5C5.",
|
|
94690
|
+
trigger: '\uC0AC\uC6A9\uC790\uAC00 "\uB9C1\uD06C\uB4DC\uC778 \uD504\uB85C\uD544 \uBD10\uC918 / \uD3EC\uD2B8\uD3F4\uB9AC\uC624 \uC815\uB9AC\uD574\uC918 / \uD37C\uC2A4\uB110 \uBE0C\uB79C\uB529 \uB3C4\uC640\uC918"\uB77C\uACE0 \uC694\uCCAD\uD560 \uB54C.',
|
|
94691
|
+
steps: [
|
|
94692
|
+
"`get_application_context`(\uAC00\uB2A5\uD558\uBA74 \uB300\uC0C1 job_id \uD3EC\uD568)\uB97C \uD638\uCD9C\uD574 \uD504\uB85C\uD544\xB7\uACBD\uB825\xB7\uD504\uB85C\uC81D\uD2B8\xB7\uC2A4\uD0AC\xB7\uB300\uD45C \uC774\uB825\uC11C\xB7\uAE00\uC4F0\uAE30 \uC120\uD638\uB97C \uAC00\uC838\uC628\uB2E4. \uD0C0\uAE43 \uACF5\uACE0\uAC00 \uC788\uC73C\uBA74 \uADF8 \uD0A4\uC6CC\uB4DC\uB97C \uC0AC\uC804 \uC785\uB825\uC73C\uB85C \uC4F4\uB2E4.",
|
|
94693
|
+
'`get_workflow_guide({ workflow_id: "build_personal_brand" })`\uAC00 \uC548\uB0B4\uD558\uB294 \uC804\uBB38\uAC00 \uC808\uCC28\uB97C \uB530\uB978\uB2E4. \uC791\uC131 \uC9C1\uC804 `get_playbook({ domain: "linkedin-profile" })`\xB7`get_playbook({ domain: "portfolio" })`\uB97C \uBC1B\uC544 \uD5E4\uB4DC\uB77C\uC778\xB7About\xB7Featured\xB73\uB9C9(problem\u2192approach\u2192impact) \uADDC\uBC94\uC744 \uC801\uC6A9\uD55C\uB2E4.',
|
|
94694
|
+
"\uBB34\uC5C7\uC744 \uB9CC\uB4E4\uC9C0 \uD655\uC778\uD55C\uB2E4(LinkedIn \uD504\uB85C\uD544\uB9CC/\uD3EC\uD2B8\uD3F4\uB9AC\uC624\uB9CC/\uB458 \uB2E4, \uD0C0\uAE43 \uC9C1\uBB34, \uAC15\uC870 \uD3EC\uC778\uD2B8). \uC800\uC7A5\uB41C \uC2E4\uC81C \uACBD\uD5D8\xB7\uC131\uACFC\uB9CC \uC4F0\uACE0, \uC5C6\uB294 \uC218\uCE58\xB7\uACE0\uC720\uBA85\uC0AC\uB294 \uCD94\uCE21\uD558\uC9C0 \uB9D0\uACE0 `[\uD655\uC778 \uD544\uC694]`\uB85C \uD45C\uC2DC\uD574 \uC0AC\uC6A9\uC790\uC5D0\uAC8C \uBB3B\uB294\uB2E4.",
|
|
94695
|
+
"LinkedIn: \uD5E4\uB4DC\uB77C\uC778(\uD575\uC2EC \uD0A4\uC6CC\uB4DC\uB97C \uC55E 120\uC790\uC5D0 front-load, \uD558\uB4DC \uC0C1\uD55C 220\uC790)\xB7About \uCCAB \uBB38\uC7A5 \uD6C5\xB7\uC815\uB7C9 \uC131\uACFC\xB7\uC9C1\uBB34 \uD0A4\uC6CC\uB4DC\uB97C \uC791\uC131. \uD3EC\uD2B8\uD3F4\uB9AC\uC624: \uC9C1\uBB34\uC5D0 \uB9DE\uB294 3~6\uAC1C \uD56D\uBAA9\uC744 problem\u2192approach\u2192impact 3\uB9C9\uC73C\uB85C \uAD6C\uC131\uD558\uACE0 \uBCF8\uC778 \uAE30\uC5EC(my_role)\uC640 \uC815\uB7C9 \uC784\uD329\uD2B8\uB97C \uBA85\uC2DC\uD55C\uB2E4.",
|
|
94696
|
+
'\uC800\uC7A5 \uC9C1\uC804 `get_verifier({ id: "human-voice" })`\xB7`get_verifier({ id: "truthfulness" })`\xB7`get_verifier({ id: "consistency" })`\uB97C \uBC1B\uC544 \uB2F9\uC2E0\uC774 \uC9C1\uC811 \uC810\uAC80\uD55C\uB2E4(AI \uD2F0\xB7\uD658\uAC01\xB7\uC0AC\uC2E4 \uBCF4\uC874). \uD0A4\uC6CC\uB4DC \uC0AC\uC804\uC774 \uBE44\uBA74 \uD0A4\uC6CC\uB4DC \uCCB4\uD06C\uB294 \uBCF4\uB958\uD55C\uB2E4.',
|
|
94697
|
+
"\uD3EC\uD2B8\uD3F4\uB9AC\uC624 \uBCF8\uBB38\uC740 `add_resume`(kind=portfolio)\uB85C \uC800\uC7A5\uD55C\uB2E4. LinkedIn \uD504\uB85C\uD544 \uCD08\uC548\uC740 \uC0AC\uC6A9\uC790\uAC00 \uBCF5\uC0AC\uD574 \uC4F0\uB3C4\uB85D \uC81C\uC2DC\uD558\uACE0(\uC804\uC6A9 \uC800\uC7A5\xB7\uAC80\uC99D \uB3C4\uAD6C validate_linkedin_profile\uC740 Phase B \uBBF8\uAD6C\uD604), \uC6D0\uD558\uBA74 \uD30C\uC77C\uB85C \uB0B4\uBCF4\uB0B8\uB2E4.",
|
|
94698
|
+
"\uC800\uC7A5 \uACB0\uACFC\uB97C \uC0AC\uC6A9\uC790\uC758 \uC5B8\uC5B4\uB85C \uC54C\uB9AC\uACE0 \uB300\uC2DC\uBCF4\uB4DC \uB9C1\uD06C\uB97C \uC548\uB0B4\uD558\uBA70, \uB124\uD2B8\uC6CC\uD0B9(\uCD94\uCC9C \uACBD\uB85C)\uC774\uB098 \uACF5\uACE0 \uC9C0\uC6D0\uC73C\uB85C \uC774\uC5B4\uAC08\uC9C0 \uC81C\uC548\uD55C\uB2E4."
|
|
94442
94699
|
]
|
|
94443
94700
|
}
|
|
94444
94701
|
];
|
|
@@ -94522,7 +94779,7 @@ var CAREER_ROUTES = {
|
|
|
94522
94779
|
verifierSequence: ["truthfulness", "consistency"]
|
|
94523
94780
|
},
|
|
94524
94781
|
analyze_job: {
|
|
94525
|
-
eop: "job-analysis",
|
|
94782
|
+
eop: ["job-analysis", "fit-analysis"],
|
|
94526
94783
|
expertSequence: ["fit-matching", "company-research"],
|
|
94527
94784
|
verifierSequence: ["truthfulness", "consistency", "responsiveness-on-target"],
|
|
94528
94785
|
loop: "draft_verify_revise"
|
|
@@ -94533,11 +94790,46 @@ var CAREER_ROUTES = {
|
|
|
94533
94790
|
verifierSequence: ["human-voice", "truthfulness", "ats-compat", "consistency"],
|
|
94534
94791
|
loop: "draft_verify_revise"
|
|
94535
94792
|
},
|
|
94793
|
+
write_career_description: {
|
|
94794
|
+
eop: "career-description",
|
|
94795
|
+
expertSequence: ["resume", "ats"],
|
|
94796
|
+
verifierSequence: ["truthfulness", "consistency", "ats-compat"],
|
|
94797
|
+
loop: "draft_verify_revise"
|
|
94798
|
+
},
|
|
94536
94799
|
prepare_interview: {
|
|
94537
94800
|
eop: "interview-prep",
|
|
94538
|
-
expertSequence: ["interview-behavioral", "interview-technical", "company-research"],
|
|
94801
|
+
expertSequence: ["recruiter-screen", "interview-behavioral", "interview-technical", "company-research"],
|
|
94539
94802
|
verifierSequence: ["truthfulness", "consistency"],
|
|
94540
94803
|
loop: "draft_verify_revise"
|
|
94804
|
+
},
|
|
94805
|
+
// R7 A2: manage_application_status had no route → rejection-triage / offer-evaluation /
|
|
94806
|
+
// salary-negotiation were orphaned (served only on-demand via get_playbook). Route the
|
|
94807
|
+
// decision-stage playbooks so they are pushed when the user manages application outcomes.
|
|
94808
|
+
// R7 A4: A2 routed the decision-stage playbooks, but the EOP-free lifecycle domains
|
|
94809
|
+
// onboarding-first-90-days and networking-referrals were still on-demand-only. Anchor them
|
|
94810
|
+
// here (the only EOP-free lifecycle route). NOTE: networking's strongest lever is *before*
|
|
94811
|
+
// applied (pre-referral, networking-referrals §2) — this route is the surfacing point, not
|
|
94812
|
+
// the recommended timing, so surface networking early when the user is pre-application.
|
|
94813
|
+
// linkedin-profile/portfolio stay on-demand pending a dedicated personal-brand workflow id
|
|
94814
|
+
// (FIXES.md / STATUS §7.9 follow-up — onboarding EOP is résumé-import-only, so brand-
|
|
94815
|
+
// creation playbooks would blur its stage meaning). Additive wiring (A1/A2 precedent).
|
|
94816
|
+
manage_application_status: {
|
|
94817
|
+
expertSequence: [
|
|
94818
|
+
"rejection-triage-iteration",
|
|
94819
|
+
"offer-evaluation-decision",
|
|
94820
|
+
"salary-negotiation",
|
|
94821
|
+
"onboarding-first-90-days",
|
|
94822
|
+
"networking-referrals"
|
|
94823
|
+
],
|
|
94824
|
+
verifierSequence: ["truthfulness", "consistency"]
|
|
94825
|
+
},
|
|
94826
|
+
// R7 후속: linkedin-profile·portfolio는 onboarding(이력서 임포트)과 단계 의미가
|
|
94827
|
+
// 달라(개인 브랜드 자산 *생성*) 전용 워크플로우로 분리(consensus 권고). networking은
|
|
94828
|
+
// manage_application_status에 이미 정박. 저장은 add_resume(kind=portfolio); linkedin
|
|
94829
|
+
// 전용 저장/검증은 Phase B.
|
|
94830
|
+
build_personal_brand: {
|
|
94831
|
+
expertSequence: ["linkedin-profile", "portfolio"],
|
|
94832
|
+
verifierSequence: ["truthfulness", "human-voice", "consistency"]
|
|
94541
94833
|
}
|
|
94542
94834
|
};
|
|
94543
94835
|
function getRoute(id2) {
|
|
@@ -94547,12 +94839,15 @@ function renderRouteGuide(id2) {
|
|
|
94547
94839
|
const route = CAREER_ROUTES[id2];
|
|
94548
94840
|
if (!route) return void 0;
|
|
94549
94841
|
const lines = [];
|
|
94550
|
-
|
|
94842
|
+
const eops = route.eop ? Array.isArray(route.eop) ? route.eop : [route.eop] : [];
|
|
94843
|
+
if (eops.length) {
|
|
94551
94844
|
lines.push("---", "");
|
|
94552
94845
|
lines.push("## \uC804\uBB38\uAC00 \uC2E4\uD589 \uC808\uCC28 (EOP) \u2014 \uC989\uB2F5\uD558\uC9C0 \uB9D0\uACE0 \uC774 \uC808\uCC28\uB97C \uB530\uB974\uC138\uC694");
|
|
94553
94846
|
lines.push("");
|
|
94554
|
-
|
|
94555
|
-
|
|
94847
|
+
for (const e of eops) {
|
|
94848
|
+
lines.push(getEop(e));
|
|
94849
|
+
lines.push("");
|
|
94850
|
+
}
|
|
94556
94851
|
}
|
|
94557
94852
|
lines.push("## \uC774 \uC791\uC5C5\uC5D0 \uC801\uC6A9\uD560 \uC804\uBB38\uAC00 \uD50C\uB808\uC774\uBD81");
|
|
94558
94853
|
lines.push("\uC791\uC131 \uC9C1\uC804, \uC544\uB798 \uB3C4\uBA54\uC778\uC758 \uAE4A\uC740 \uC9C0\uC2DD\uC744 \uBC1B\uC544 \uC801\uC6A9\uD558\uC138\uC694:");
|
|
@@ -94666,10 +94961,22 @@ function slugify(input, fallback = "document") {
|
|
|
94666
94961
|
function joinBlocks(blocks) {
|
|
94667
94962
|
return blocks.filter((b) => typeof b === "string" && b.trim().length > 0).join("\n\n");
|
|
94668
94963
|
}
|
|
94964
|
+
function bulletList(items) {
|
|
94965
|
+
const lines = items.filter((i2) => typeof i2 === "string" && i2.trim().length > 0).map((i2) => `- ${i2.trim()}`);
|
|
94966
|
+
return lines.join("\n");
|
|
94967
|
+
}
|
|
94669
94968
|
function kv(label, value) {
|
|
94670
94969
|
if (!value || !value.trim()) return "";
|
|
94671
94970
|
return `**${label}**: ${value.trim()}`;
|
|
94672
94971
|
}
|
|
94972
|
+
function dateRange(start, end, current = false) {
|
|
94973
|
+
const s = (start ?? "").trim();
|
|
94974
|
+
const e = current ? "\uD604\uC7AC" : (end ?? "").trim();
|
|
94975
|
+
if (!s && !e) return "";
|
|
94976
|
+
if (!s) return e;
|
|
94977
|
+
if (!e) return s;
|
|
94978
|
+
return `${s} ~ ${e}`;
|
|
94979
|
+
}
|
|
94673
94980
|
function renderInline(escaped) {
|
|
94674
94981
|
let out = escaped;
|
|
94675
94982
|
out = out.replace(/\*\*([^*]+)\*\*/g, "<strong>$1</strong>");
|
|
@@ -94778,6 +95085,123 @@ function coverLetterToHtml(cl, opts) {
|
|
|
94778
95085
|
content: toPrintableHtml(cl.title, coverLetterBody(cl, opts))
|
|
94779
95086
|
};
|
|
94780
95087
|
}
|
|
95088
|
+
function resumeToMarkdown(doc, profile) {
|
|
95089
|
+
const kindLabel = DOCUMENT_KIND_LABELS[doc.kind] ?? doc.kind;
|
|
95090
|
+
const header = [];
|
|
95091
|
+
if (profile?.name) header.push(kv("\uC774\uB984", profile.name));
|
|
95092
|
+
if (profile?.email) header.push(kv("\uC774\uBA54\uC77C", profile.email));
|
|
95093
|
+
if (profile?.phone) header.push(kv("\uC5F0\uB77D\uCC98", profile.phone));
|
|
95094
|
+
const body = joinBlocks([
|
|
95095
|
+
`# ${doc.title}`,
|
|
95096
|
+
`_${kindLabel}_`,
|
|
95097
|
+
header.length ? header.filter(Boolean).join("\n\n") : "",
|
|
95098
|
+
header.length ? "---" : "",
|
|
95099
|
+
(doc.content ?? "").trim() || "_(\uB0B4\uC6A9 \uC5C6\uC74C)_"
|
|
95100
|
+
]);
|
|
95101
|
+
return {
|
|
95102
|
+
filename: `${slugify(doc.title, doc.kind)}.md`,
|
|
95103
|
+
mimeType: MD_MIME,
|
|
95104
|
+
content: body
|
|
95105
|
+
};
|
|
95106
|
+
}
|
|
95107
|
+
function resumeToHtml(doc, profile) {
|
|
95108
|
+
const md = resumeToMarkdown(doc, profile);
|
|
95109
|
+
return {
|
|
95110
|
+
filename: `${slugify(doc.title, doc.kind)}.html`,
|
|
95111
|
+
mimeType: HTML_MIME,
|
|
95112
|
+
content: toPrintableHtml(doc.title, md.content)
|
|
95113
|
+
};
|
|
95114
|
+
}
|
|
95115
|
+
function profileToMarkdown(profile, experiences = [], projects = [], skills = []) {
|
|
95116
|
+
const name = profile.name?.trim() || "\uC774\uB825\uC11C";
|
|
95117
|
+
const contact = [];
|
|
95118
|
+
if (profile.email) contact.push(profile.email);
|
|
95119
|
+
if (profile.phone) contact.push(profile.phone);
|
|
95120
|
+
if (profile.location) contact.push(profile.location);
|
|
95121
|
+
const links = (profile.links ?? []).filter((l2) => l2.url).map((l2) => `[${l2.label || l2.url}](${l2.url})`);
|
|
95122
|
+
const headerBlocks = joinBlocks([
|
|
95123
|
+
`# ${name}`,
|
|
95124
|
+
profile.headline ? `## ${profile.headline}` : "",
|
|
95125
|
+
contact.length ? contact.join(" \xB7 ") : "",
|
|
95126
|
+
links.length ? links.join(" \xB7 ") : ""
|
|
95127
|
+
]);
|
|
95128
|
+
const summaryBlock = profile.summary?.trim() ? joinBlocks(["## \uC18C\uAC1C", profile.summary.trim()]) : "";
|
|
95129
|
+
const desiredLines = [];
|
|
95130
|
+
if (profile.desired_roles?.length) {
|
|
95131
|
+
desiredLines.push(kv("\uD76C\uB9DD \uC9C1\uBB34", profile.desired_roles.join(", ")));
|
|
95132
|
+
}
|
|
95133
|
+
if (profile.desired_conditions?.trim()) {
|
|
95134
|
+
desiredLines.push(kv("\uD76C\uB9DD \uC870\uAC74", profile.desired_conditions));
|
|
95135
|
+
}
|
|
95136
|
+
const desiredBlock = desiredLines.length ? joinBlocks(["## \uD76C\uB9DD \uC0AC\uD56D", desiredLines.filter(Boolean).join("\n\n")]) : "";
|
|
95137
|
+
const expBlocks = experiences.length ? joinBlocks([
|
|
95138
|
+
"## \uACBD\uB825",
|
|
95139
|
+
...experiences.map((e) => {
|
|
95140
|
+
const range2 = dateRange(e.start_date, e.end_date, e.is_current);
|
|
95141
|
+
const titleParts = [e.company, e.role].filter(Boolean).join(" \u2014 ");
|
|
95142
|
+
const subParts = [e.employment_type, range2].filter(Boolean).join(" \xB7 ");
|
|
95143
|
+
return joinBlocks([
|
|
95144
|
+
`### ${titleParts}`,
|
|
95145
|
+
subParts ? `_${subParts}_` : "",
|
|
95146
|
+
e.description?.trim() ? e.description.trim() : "",
|
|
95147
|
+
e.achievements?.length ? bulletList(e.achievements) : "",
|
|
95148
|
+
e.tech?.length ? kv("\uAE30\uC220", e.tech.join(", ")) : ""
|
|
95149
|
+
]);
|
|
95150
|
+
})
|
|
95151
|
+
]) : "";
|
|
95152
|
+
const projBlocks = projects.length ? joinBlocks([
|
|
95153
|
+
"## \uD504\uB85C\uC81D\uD2B8",
|
|
95154
|
+
...projects.map((p) => {
|
|
95155
|
+
const range2 = dateRange(p.start_date, p.end_date);
|
|
95156
|
+
const subParts = [p.role, range2].filter(Boolean).join(" \xB7 ");
|
|
95157
|
+
return joinBlocks([
|
|
95158
|
+
`### ${p.name}`,
|
|
95159
|
+
subParts ? `_${subParts}_` : "",
|
|
95160
|
+
p.description?.trim() ? p.description.trim() : "",
|
|
95161
|
+
p.highlights?.length ? bulletList(p.highlights) : "",
|
|
95162
|
+
p.tech?.length ? kv("\uAE30\uC220", p.tech.join(", ")) : "",
|
|
95163
|
+
p.url ? kv("\uB9C1\uD06C", p.url) : ""
|
|
95164
|
+
]);
|
|
95165
|
+
})
|
|
95166
|
+
]) : "";
|
|
95167
|
+
let skillsBlock = "";
|
|
95168
|
+
if (skills.length) {
|
|
95169
|
+
const groups = /* @__PURE__ */ new Map();
|
|
95170
|
+
for (const s of skills) {
|
|
95171
|
+
const cat = s.category?.trim() || "\uAE30\uD0C0";
|
|
95172
|
+
const label = s.level?.trim() ? `${s.name} (${s.level.trim()})` : s.name;
|
|
95173
|
+
if (!groups.has(cat)) groups.set(cat, []);
|
|
95174
|
+
groups.get(cat).push(label);
|
|
95175
|
+
}
|
|
95176
|
+
const lines = [...groups.entries()].map(
|
|
95177
|
+
([cat, items]) => kv(cat, items.join(", "))
|
|
95178
|
+
);
|
|
95179
|
+
skillsBlock = joinBlocks(["## \uBCF4\uC720 \uAE30\uC220", lines.filter(Boolean).join("\n\n")]);
|
|
95180
|
+
}
|
|
95181
|
+
const content = joinBlocks([
|
|
95182
|
+
headerBlocks,
|
|
95183
|
+
"---",
|
|
95184
|
+
summaryBlock,
|
|
95185
|
+
desiredBlock,
|
|
95186
|
+
expBlocks,
|
|
95187
|
+
projBlocks,
|
|
95188
|
+
skillsBlock
|
|
95189
|
+
]);
|
|
95190
|
+
return {
|
|
95191
|
+
filename: `${slugify(name, "resume")}-resume.md`,
|
|
95192
|
+
mimeType: MD_MIME,
|
|
95193
|
+
content
|
|
95194
|
+
};
|
|
95195
|
+
}
|
|
95196
|
+
function profileToHtml(profile, experiences = [], projects = [], skills = []) {
|
|
95197
|
+
const md = profileToMarkdown(profile, experiences, projects, skills);
|
|
95198
|
+
const title = profile.name?.trim() || "\uC774\uB825\uC11C";
|
|
95199
|
+
return {
|
|
95200
|
+
filename: `${slugify(title, "resume")}-resume.html`,
|
|
95201
|
+
mimeType: HTML_MIME,
|
|
95202
|
+
content: toPrintableHtml(title, md.content)
|
|
95203
|
+
};
|
|
95204
|
+
}
|
|
94781
95205
|
|
|
94782
95206
|
// packages/parsers/src/html.ts
|
|
94783
95207
|
var NAMED_ENTITIES = {
|
|
@@ -95338,7 +95762,12 @@ async function extractDocument(input, baseDir) {
|
|
|
95338
95762
|
path: filePath,
|
|
95339
95763
|
...over
|
|
95340
95764
|
});
|
|
95341
|
-
|
|
95765
|
+
let realPath = filePath;
|
|
95766
|
+
try {
|
|
95767
|
+
realPath = fs4.realpathSync.native(filePath);
|
|
95768
|
+
} catch {
|
|
95769
|
+
}
|
|
95770
|
+
if (SENSITIVE_PATH_RE.test(filePath) || SENSITIVE_PATH_RE.test(realPath)) {
|
|
95342
95771
|
return base("unsupported", {
|
|
95343
95772
|
warnings: [
|
|
95344
95773
|
"\uBCF4\uC548\uC0C1 \uBBFC\uAC10\uD560 \uC218 \uC788\uB294 \uD30C\uC77C(\uAC1C\uC778 \uD0A4\xB7\uC790\uACA9\uC99D\uBA85 \uB4F1)\uC740 \uC77D\uC9C0 \uC54A\uC2B5\uB2C8\uB2E4. \uC774\uB825\uC11C\xB7\uACBD\uB825\uAE30\uC220\uC11C\xB7\uC790\uAE30\uC18C\uAC1C\uC11C \uAC19\uC740 \uBB38\uC11C \uD30C\uC77C\uC744 \uC9C0\uC815\uD574 \uC8FC\uC138\uC694."
|
|
@@ -95675,14 +96104,94 @@ function toCallToolResult(r) {
|
|
|
95675
96104
|
}
|
|
95676
96105
|
|
|
95677
96106
|
// packages/mcp-tools/src/bridge.ts
|
|
95678
|
-
import { spawn } from "node:child_process";
|
|
96107
|
+
import { spawn, spawnSync } from "node:child_process";
|
|
96108
|
+
import fs5 from "node:fs";
|
|
95679
96109
|
import path5 from "node:path";
|
|
95680
96110
|
import { fileURLToPath as fileURLToPath2 } from "node:url";
|
|
95681
96111
|
var __dirname = path5.dirname(fileURLToPath2(import.meta.url));
|
|
95682
96112
|
var REPO_ROOT = path5.resolve(__dirname, "..", "..", "..");
|
|
95683
|
-
|
|
96113
|
+
var HEALTH_TIMEOUT_MS = 800;
|
|
96114
|
+
var pendingStart = null;
|
|
96115
|
+
function dashboardLogPath() {
|
|
96116
|
+
return path5.join(getDataDir(), "server.log");
|
|
96117
|
+
}
|
|
96118
|
+
function launchdPlistPath() {
|
|
96119
|
+
return path5.join(getDataDir(), "dashboard.launchd.plist");
|
|
96120
|
+
}
|
|
96121
|
+
function launchdLabel() {
|
|
96122
|
+
let hash = 5381;
|
|
96123
|
+
for (const ch of getDataDir()) hash = (hash * 33 ^ ch.charCodeAt(0)) >>> 0;
|
|
96124
|
+
return `life.careermate.dashboard.${hash.toString(16)}`;
|
|
96125
|
+
}
|
|
96126
|
+
function xmlEscape(value) {
|
|
96127
|
+
return value.replace(/&/g, "&").replace(/</g, "<").replace(/>/g, ">").replace(/"/g, """).replace(/'/g, "'");
|
|
96128
|
+
}
|
|
96129
|
+
function plistString(key, value) {
|
|
96130
|
+
return ` <key>${xmlEscape(key)}</key>
|
|
96131
|
+
<string>${xmlEscape(value)}</string>`;
|
|
96132
|
+
}
|
|
96133
|
+
function renderLaunchdPlist(bin, args, cwd, log) {
|
|
96134
|
+
const env2 = {
|
|
96135
|
+
CAREERMATE_DATA_DIR: getDataDir(),
|
|
96136
|
+
CAREERMATE_NO_OPEN: "1"
|
|
96137
|
+
};
|
|
96138
|
+
if (process.env.CAREERMATE_PORT) env2.CAREERMATE_PORT = process.env.CAREERMATE_PORT;
|
|
96139
|
+
if (process.env.PATH) env2.PATH = process.env.PATH;
|
|
96140
|
+
const programArgs = [bin, ...args].map((arg) => ` <string>${xmlEscape(arg)}</string>`).join("\n");
|
|
96141
|
+
const envEntries = Object.entries(env2).map(([key, value]) => `${plistString(key, value)}`).join("\n");
|
|
96142
|
+
return `<?xml version="1.0" encoding="UTF-8"?>
|
|
96143
|
+
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
|
96144
|
+
<plist version="1.0">
|
|
96145
|
+
<dict>
|
|
96146
|
+
<key>Label</key>
|
|
96147
|
+
<string>${xmlEscape(launchdLabel())}</string>
|
|
96148
|
+
<key>ProgramArguments</key>
|
|
96149
|
+
<array>
|
|
96150
|
+
${programArgs}
|
|
96151
|
+
</array>
|
|
96152
|
+
<key>WorkingDirectory</key>
|
|
96153
|
+
<string>${xmlEscape(cwd)}</string>
|
|
96154
|
+
<key>EnvironmentVariables</key>
|
|
96155
|
+
<dict>
|
|
96156
|
+
${envEntries}
|
|
96157
|
+
</dict>
|
|
96158
|
+
<key>RunAtLoad</key>
|
|
96159
|
+
<true/>
|
|
96160
|
+
<key>KeepAlive</key>
|
|
96161
|
+
<false/>
|
|
96162
|
+
<key>StandardOutPath</key>
|
|
96163
|
+
<string>${xmlEscape(log)}</string>
|
|
96164
|
+
<key>StandardErrorPath</key>
|
|
96165
|
+
<string>${xmlEscape(log)}</string>
|
|
96166
|
+
</dict>
|
|
96167
|
+
</plist>
|
|
96168
|
+
`;
|
|
96169
|
+
}
|
|
96170
|
+
function delay(ms) {
|
|
96171
|
+
return new Promise((resolve) => setTimeout(resolve, ms));
|
|
96172
|
+
}
|
|
96173
|
+
async function pingDashboard(url, timeoutMs = HEALTH_TIMEOUT_MS) {
|
|
96174
|
+
const controller = new AbortController();
|
|
96175
|
+
const timer = setTimeout(() => controller.abort(), timeoutMs);
|
|
96176
|
+
timer.unref?.();
|
|
96177
|
+
try {
|
|
96178
|
+
const healthUrl = new URL("/api/health", url);
|
|
96179
|
+
const res = await fetch(healthUrl, {
|
|
96180
|
+
signal: controller.signal,
|
|
96181
|
+
headers: { accept: "application/json" }
|
|
96182
|
+
});
|
|
96183
|
+
if (!res.ok) return false;
|
|
96184
|
+
const body = await res.json().catch(() => null);
|
|
96185
|
+
return body?.ok === true;
|
|
96186
|
+
} catch {
|
|
96187
|
+
return false;
|
|
96188
|
+
} finally {
|
|
96189
|
+
clearTimeout(timer);
|
|
96190
|
+
}
|
|
96191
|
+
}
|
|
96192
|
+
async function liveServer() {
|
|
95684
96193
|
const info2 = readRuntimeInfo();
|
|
95685
|
-
if (info2 && isProcessAlive(info2.pid)) return info2;
|
|
96194
|
+
if (info2 && isProcessAlive(info2.pid) && await pingDashboard(info2.url)) return info2;
|
|
95686
96195
|
return null;
|
|
95687
96196
|
}
|
|
95688
96197
|
function spawnDetached(cmd, args, opts = {}) {
|
|
@@ -95691,19 +96200,101 @@ function spawnDetached(cmd, args, opts = {}) {
|
|
|
95691
96200
|
child.on("error", () => {
|
|
95692
96201
|
});
|
|
95693
96202
|
child.unref();
|
|
96203
|
+
return child.pid ?? null;
|
|
95694
96204
|
} catch {
|
|
96205
|
+
return null;
|
|
95695
96206
|
}
|
|
95696
96207
|
}
|
|
96208
|
+
function spawnViaLaunchd(bin, args, cwd, log) {
|
|
96209
|
+
if (process.platform !== "darwin" || process.env.CAREERMATE_LAUNCHER === "detached") return false;
|
|
96210
|
+
if (typeof process.getuid !== "function") return false;
|
|
96211
|
+
const domain = `gui/${process.getuid()}`;
|
|
96212
|
+
const label = launchdLabel();
|
|
96213
|
+
const plist = launchdPlistPath();
|
|
96214
|
+
try {
|
|
96215
|
+
fs5.writeFileSync(plist, renderLaunchdPlist(bin, args, cwd, log), "utf8");
|
|
96216
|
+
spawnSync("launchctl", ["bootout", `${domain}/${label}`], { stdio: "ignore" });
|
|
96217
|
+
const res = spawnSync("launchctl", ["bootstrap", domain, plist], {
|
|
96218
|
+
encoding: "utf8",
|
|
96219
|
+
timeout: 5e3
|
|
96220
|
+
});
|
|
96221
|
+
if (res.status === 0) return true;
|
|
96222
|
+
fs5.appendFileSync(log, `[${(/* @__PURE__ */ new Date()).toISOString()}] launchctl bootstrap failed: ${res.stderr || res.stdout || res.status}
|
|
96223
|
+
`);
|
|
96224
|
+
} catch (e) {
|
|
96225
|
+
try {
|
|
96226
|
+
fs5.appendFileSync(log, `[${(/* @__PURE__ */ new Date()).toISOString()}] launchctl launch failed: ${e instanceof Error ? e.message : String(e)}
|
|
96227
|
+
`);
|
|
96228
|
+
} catch {
|
|
96229
|
+
}
|
|
96230
|
+
}
|
|
96231
|
+
return false;
|
|
96232
|
+
}
|
|
96233
|
+
function spawnDashboardDetached(bin, args, cwd, logFd) {
|
|
96234
|
+
spawnDetached(bin, args, {
|
|
96235
|
+
cwd,
|
|
96236
|
+
env: { ...process.env, CAREERMATE_NO_OPEN: "1" },
|
|
96237
|
+
stdio: logFd === null ? "ignore" : ["ignore", logFd, logFd]
|
|
96238
|
+
});
|
|
96239
|
+
}
|
|
95697
96240
|
async function ensureServer(timeoutMs = 12e3) {
|
|
95698
|
-
const existing = liveServer();
|
|
96241
|
+
const existing = await liveServer();
|
|
95699
96242
|
if (existing) return { url: existing.url };
|
|
95700
|
-
|
|
95701
|
-
|
|
96243
|
+
if (pendingStart) return pendingStart;
|
|
96244
|
+
pendingStart = startServerBackground(timeoutMs);
|
|
96245
|
+
try {
|
|
96246
|
+
return await pendingStart;
|
|
96247
|
+
} finally {
|
|
96248
|
+
pendingStart = null;
|
|
96249
|
+
}
|
|
96250
|
+
}
|
|
96251
|
+
async function startServerBackground(timeoutMs) {
|
|
96252
|
+
const [bin, args, cwd] = BUNDLED ? [process.execPath, ["--experimental-sqlite", path5.join(__dirname, "web.mjs")], __dirname] : [
|
|
96253
|
+
process.execPath,
|
|
96254
|
+
["--no-warnings", "--experimental-sqlite", "--import", "tsx", path5.join(REPO_ROOT, "apps/web/src/index.ts")],
|
|
96255
|
+
REPO_ROOT
|
|
96256
|
+
];
|
|
96257
|
+
const log = dashboardLogPath();
|
|
96258
|
+
let logFd = null;
|
|
96259
|
+
try {
|
|
96260
|
+
logFd = fs5.openSync(log, "a");
|
|
96261
|
+
fs5.writeSync(logFd, `
|
|
96262
|
+
[${(/* @__PURE__ */ new Date()).toISOString()}] CareerMate dashboard background launch
|
|
96263
|
+
`);
|
|
96264
|
+
} catch {
|
|
96265
|
+
logFd = null;
|
|
96266
|
+
}
|
|
96267
|
+
let launchedViaLaunchd = false;
|
|
96268
|
+
try {
|
|
96269
|
+
launchedViaLaunchd = spawnViaLaunchd(bin, args, cwd, log);
|
|
96270
|
+
if (!launchedViaLaunchd) spawnDashboardDetached(bin, args, cwd, logFd);
|
|
96271
|
+
} finally {
|
|
96272
|
+
if (logFd !== null) {
|
|
96273
|
+
try {
|
|
96274
|
+
fs5.closeSync(logFd);
|
|
96275
|
+
} catch {
|
|
96276
|
+
}
|
|
96277
|
+
}
|
|
96278
|
+
}
|
|
95702
96279
|
const start = Date.now();
|
|
95703
96280
|
while (Date.now() - start < timeoutMs) {
|
|
95704
|
-
const info2 = liveServer();
|
|
96281
|
+
const info2 = await liveServer();
|
|
95705
96282
|
if (info2) return { url: info2.url };
|
|
95706
|
-
await
|
|
96283
|
+
await delay(300);
|
|
96284
|
+
}
|
|
96285
|
+
if (launchedViaLaunchd) {
|
|
96286
|
+
try {
|
|
96287
|
+
fs5.appendFileSync(log, `[${(/* @__PURE__ */ new Date()).toISOString()}] launchd did not produce a healthy server; falling back to detached spawn
|
|
96288
|
+
`);
|
|
96289
|
+
} catch {
|
|
96290
|
+
}
|
|
96291
|
+
spawnDashboardDetached(bin, args, cwd, null);
|
|
96292
|
+
const fallbackStart = Date.now();
|
|
96293
|
+
while (Date.now() - fallbackStart < Math.min(timeoutMs, 8e3)) {
|
|
96294
|
+
const info2 = await liveServer();
|
|
96295
|
+
if (info2) return { url: info2.url };
|
|
96296
|
+
await delay(300);
|
|
96297
|
+
}
|
|
95707
96298
|
}
|
|
95708
96299
|
return null;
|
|
95709
96300
|
}
|
|
@@ -95727,7 +96318,7 @@ function openInFileManager(dir) {
|
|
|
95727
96318
|
else openOsTarget(dir);
|
|
95728
96319
|
}
|
|
95729
96320
|
async function resolveDashboardUrl(hash = "") {
|
|
95730
|
-
const live = liveServer();
|
|
96321
|
+
const live = await liveServer();
|
|
95731
96322
|
if (live) return { url: live.url + hash, running: true };
|
|
95732
96323
|
const started = await ensureServer();
|
|
95733
96324
|
if (started) return { url: started.url + hash, running: true };
|
|
@@ -95735,7 +96326,7 @@ async function resolveDashboardUrl(hash = "") {
|
|
|
95735
96326
|
}
|
|
95736
96327
|
|
|
95737
96328
|
// packages/mcp-tools/src/update.ts
|
|
95738
|
-
import
|
|
96329
|
+
import fs6 from "node:fs";
|
|
95739
96330
|
import path6 from "node:path";
|
|
95740
96331
|
import { fileURLToPath as fileURLToPath3 } from "node:url";
|
|
95741
96332
|
import { spawn as spawn2 } from "node:child_process";
|
|
@@ -95792,14 +96383,14 @@ function comparePrerelease(a, b) {
|
|
|
95792
96383
|
}
|
|
95793
96384
|
function readCache() {
|
|
95794
96385
|
try {
|
|
95795
|
-
return JSON.parse(
|
|
96386
|
+
return JSON.parse(fs6.readFileSync(cacheFile(), "utf8"));
|
|
95796
96387
|
} catch {
|
|
95797
96388
|
return null;
|
|
95798
96389
|
}
|
|
95799
96390
|
}
|
|
95800
96391
|
function writeCache(c) {
|
|
95801
96392
|
try {
|
|
95802
|
-
|
|
96393
|
+
fs6.writeFileSync(cacheFile(), JSON.stringify(c), "utf8");
|
|
95803
96394
|
} catch {
|
|
95804
96395
|
}
|
|
95805
96396
|
}
|
|
@@ -95858,14 +96449,20 @@ function getUpdateStatus() {
|
|
|
95858
96449
|
if (cacheExpired(cache2)) refreshInBackground();
|
|
95859
96450
|
return buildStatus(cache2);
|
|
95860
96451
|
}
|
|
95861
|
-
async function getUpdateStatusAsync() {
|
|
96452
|
+
async function getUpdateStatusAsync(force = false) {
|
|
95862
96453
|
if (checkDisabled()) return buildStatus(null);
|
|
95863
|
-
|
|
95864
|
-
if (cacheExpired(cache2))
|
|
95865
|
-
|
|
95866
|
-
|
|
95867
|
-
|
|
95868
|
-
|
|
96454
|
+
const cache2 = readCache();
|
|
96455
|
+
if (!force && !cacheExpired(cache2)) return buildStatus(cache2);
|
|
96456
|
+
const latest = await fetchLatest();
|
|
96457
|
+
if (latest !== null) {
|
|
96458
|
+
const fresh = { checkedAt: Date.now(), latest };
|
|
96459
|
+
writeCache(fresh);
|
|
96460
|
+
return buildStatus(fresh);
|
|
96461
|
+
}
|
|
96462
|
+
if (force) return buildStatus(null);
|
|
96463
|
+
const failed = { checkedAt: Date.now(), latest: null };
|
|
96464
|
+
writeCache(failed);
|
|
96465
|
+
return buildStatus(failed);
|
|
95869
96466
|
}
|
|
95870
96467
|
function killTree(child) {
|
|
95871
96468
|
if (process.platform === "win32" && child.pid) {
|
|
@@ -95923,12 +96520,8 @@ async function runSelfUpdate() {
|
|
|
95923
96520
|
manual: manualCommand()
|
|
95924
96521
|
};
|
|
95925
96522
|
}
|
|
95926
|
-
|
|
95927
|
-
if (
|
|
95928
|
-
cache2 = { checkedAt: Date.now(), latest: await fetchLatest() };
|
|
95929
|
-
writeCache(cache2);
|
|
95930
|
-
}
|
|
95931
|
-
const latest = cache2?.latest ?? null;
|
|
96523
|
+
const latest = await fetchLatest();
|
|
96524
|
+
if (latest !== null) writeCache({ checkedAt: Date.now(), latest });
|
|
95932
96525
|
if (latest === null) {
|
|
95933
96526
|
return {
|
|
95934
96527
|
ok: false,
|
|
@@ -95956,26 +96549,38 @@ async function runSelfUpdate() {
|
|
|
95956
96549
|
ok: true,
|
|
95957
96550
|
from,
|
|
95958
96551
|
to: latest,
|
|
95959
|
-
message: `
|
|
96552
|
+
message: `CareerMate\uB97C ${latest ? `v${latest}` : "\uCD5C\uC2E0 \uBC84\uC804"}(\uC73C)\uB85C \uC5C5\uB370\uC774\uD2B8\uD588\uC2B5\uB2C8\uB2E4. \uC801\uC6A9\uD558\uB824\uBA74 AI \uC571(\uB610\uB294 MCP \uC5F0\uACB0)\uC744 \uC7AC\uC2DC\uC791\uD558\uC138\uC694. \uC7AC\uC2DC\uC791 \uC2DC \uB370\uC774\uD130\uBCA0\uC774\uC2A4\uB294 \uC790\uB3D9\uC73C\uB85C \uB9C8\uC774\uADF8\uB808\uC774\uC158\uB418\uBA70 \uAE30\uC874 \uB370\uC774\uD130\uB294 \uBCF4\uC874\uB429\uB2C8\uB2E4.`
|
|
95960
96553
|
};
|
|
95961
96554
|
}
|
|
95962
96555
|
|
|
95963
96556
|
// packages/mcp-tools/src/tools.ts
|
|
95964
96557
|
var STATUS_LIST = APPLICATION_STATUSES.map((s) => `${s}(${APPLICATION_STATUS_LABELS[s]})`).join(", ");
|
|
96558
|
+
var DELETE_CONFIRMATION = "DELETE";
|
|
96559
|
+
var DASHBOARD_URL = "http://127.0.0.1:4319";
|
|
95965
96560
|
function listInboxFiles(dir) {
|
|
95966
96561
|
let names;
|
|
95967
96562
|
try {
|
|
95968
|
-
names =
|
|
96563
|
+
names = fs7.readdirSync(dir);
|
|
95969
96564
|
} catch {
|
|
95970
96565
|
return [];
|
|
95971
96566
|
}
|
|
96567
|
+
let realDir;
|
|
96568
|
+
try {
|
|
96569
|
+
realDir = fs7.realpathSync.native(dir);
|
|
96570
|
+
} catch {
|
|
96571
|
+
realDir = dir;
|
|
96572
|
+
}
|
|
95972
96573
|
const SKIP = /^[.~]|^(thumbs\.db|desktop\.ini)$/i;
|
|
95973
96574
|
const out = [];
|
|
95974
96575
|
for (const name of names) {
|
|
95975
96576
|
if (SKIP.test(name)) continue;
|
|
95976
96577
|
const p = path7.join(dir, name);
|
|
95977
96578
|
try {
|
|
95978
|
-
if (
|
|
96579
|
+
if (!fs7.statSync(p).isFile()) continue;
|
|
96580
|
+
const real = fs7.realpathSync.native(p);
|
|
96581
|
+
const rel = path7.relative(realDir, real);
|
|
96582
|
+
if (rel.startsWith("..") || path7.isAbsolute(rel)) continue;
|
|
96583
|
+
out.push({ name, path: p });
|
|
95979
96584
|
} catch {
|
|
95980
96585
|
}
|
|
95981
96586
|
}
|
|
@@ -96045,8 +96650,8 @@ ${r.warnings.join("\n")}`, {
|
|
|
96045
96650
|
/* --------------------------------------------------------- inbox (파일 인입) */
|
|
96046
96651
|
{
|
|
96047
96652
|
name: "open_inbox",
|
|
96048
|
-
title: "\
|
|
96049
|
-
description: 'CLI \uD074\uB77C\uC774\uC5B8\uD2B8\uB294 \uD30C\uC77C \uCCA8\uBD80\uAC00 \uC548 \uB418\uBBC0\uB85C, \uC0AC\uC6A9\uC790\uAC00 \uAE30\uC874 \uC774\uB825\uC11C\xB7\uACBD\uB825\uAE30\uC220\uC11C \uD30C\uC77C(hwp/hwpx/docx/pdf \uB4F1)\uC744 \uB04C\uC5B4\uB2E4 \uB123\uC744 \uC218 \uC788\uB294 \uB85C\uCEEC \uC778\uC785 \uD3F4\uB354(~/.careermate/inbox)\uB97C \uBCF4\uC7A5\uD558\uACE0 \uD30C\uC77C \uD0D0\uC0C9\uAE30\uB85C \uC5FD\uB2C8\uB2E4. \uC628\uBCF4\uB529\uC5D0\uC11C "\uAE30\uC874\uC5D0 \uC791\uC131\uD574 \uB454 \
|
|
96653
|
+
title: "\uBB38\uC11C \uC778\uC785 \uD3F4\uB354 \uC5F4\uAE30",
|
|
96654
|
+
description: 'CLI \uD074\uB77C\uC774\uC5B8\uD2B8\uB294 \uD30C\uC77C \uCCA8\uBD80\uAC00 \uC548 \uB418\uBBC0\uB85C, \uC0AC\uC6A9\uC790\uAC00 \uAE30\uC874 \uC774\uB825\uC11C\xB7\uACBD\uB825\uAE30\uC220\uC11C\xB7\uD3EC\uD2B8\uD3F4\uB9AC\uC624\xB7\uC790\uAE30\uC18C\uAC1C\uC11C \uD30C\uC77C(hwp/hwpx/docx/pdf \uB4F1)\uC744 \uB04C\uC5B4\uB2E4 \uB123\uC744 \uC218 \uC788\uB294 \uB85C\uCEEC \uC778\uC785 \uD3F4\uB354(~/.careermate/inbox)\uB97C \uBCF4\uC7A5\uD558\uACE0 \uD30C\uC77C \uD0D0\uC0C9\uAE30\uB85C \uC5FD\uB2C8\uB2E4. \uC628\uBCF4\uB529\uC5D0\uC11C "\uAE30\uC874\uC5D0 \uC791\uC131\uD574 \uB454 \uBB38\uC11C \uD30C\uC77C\uC774 \uC788\uB2E4"\uACE0 \uC0AC\uC6A9\uC790\uAC00 \uB2F5\uD588\uC744 \uB54C\uB9CC \uD638\uCD9C\uD558\uC138\uC694 \u2014 \uBB3B\uC9C0\uB3C4 \uC54A\uACE0 \uD3F4\uB354\uB97C \uC790\uB3D9\uC73C\uB85C \uC5F4\uC9C0 \uB9C8\uC138\uC694. \uD30C\uC77C \uACBD\uB85C\uB97C \uC9C1\uC811 \uC54C\uB824\uC8FC\uB294 \uC0AC\uC6A9\uC790\uC5D0\uAC8C\uB294 \uC774 \uB3C4\uAD6C \uB300\uC2E0 read_document\uB97C \uC4F0\uC138\uC694. \uD638\uCD9C\uD558\uBA74 \uD3F4\uB354 \uACBD\uB85C\uC640 \uD604\uC7AC \uD3F4\uB354\uC5D0 \uB4E4\uC5B4 \uC788\uB294 \uD30C\uC77C \uBAA9\uB85D\uC744 \uB3CC\uB824\uC90D\uB2C8\uB2E4. \uC0AC\uC6A9\uC790\uAC00 \uD30C\uC77C\uC744 \uB2E4 \uB123\uC5C8\uB2E4\uACE0 \uD558\uBA74 read_inbox\uB85C \uBCF8\uBB38\uC744 \uC77D\uC73C\uC138\uC694.',
|
|
96050
96655
|
inputSchema: {},
|
|
96051
96656
|
handler: () => {
|
|
96052
96657
|
const dir = getInboxDir();
|
|
@@ -96054,10 +96659,10 @@ ${r.warnings.join("\n")}`, {
|
|
|
96054
96659
|
const files = listInboxFiles(dir);
|
|
96055
96660
|
const list = files.length ? files.map((f) => `- ${f.name}`).join("\n") : "(\uC544\uC9C1 \uBE44\uC5B4 \uC788\uC74C)";
|
|
96056
96661
|
return ok(
|
|
96057
|
-
`\
|
|
96662
|
+
`\uBB38\uC11C \uC778\uC785 \uD3F4\uB354\uB97C \uC5F4\uC5C8\uC2B5\uB2C8\uB2E4:
|
|
96058
96663
|
${dir}
|
|
96059
96664
|
|
|
96060
|
-
\uC5EC\uAE30\uC5D0 \uC774\uB825\uC11C\xB7\uACBD\uB825\uAE30\uC220\uC11C \uD30C\uC77C\uC744 \uB123\uACE0 "\uB2E4 \uB123\uC5C8\uC5B4"\uB77C\uACE0 \uC54C\uB824\uC8FC\uC138\uC694. (hwp/hwpx/docx\uB294 \uC790\uB3D9\uC73C\uB85C \uD14D\uC2A4\uD2B8\uB97C \uCD94\uCD9C\uD558\uACE0, pdf\xB7\uC774\uBBF8\uC9C0\uB294 \uC81C\uAC00 \uC9C1\uC811 \uC77D\uC2B5\uB2C8\uB2E4.)
|
|
96665
|
+
\uC5EC\uAE30\uC5D0 \uC774\uB825\uC11C\xB7\uACBD\uB825\uAE30\uC220\uC11C\xB7\uD3EC\uD2B8\uD3F4\uB9AC\uC624\xB7\uAE30\uC874 \uC790\uAE30\uC18C\uAC1C\uC11C \uD30C\uC77C\uC744 \uB123\uACE0 "\uB2E4 \uB123\uC5C8\uC5B4"\uB77C\uACE0 \uC54C\uB824\uC8FC\uC138\uC694. (hwp/hwpx/docx\uB294 \uC790\uB3D9\uC73C\uB85C \uD14D\uC2A4\uD2B8\uB97C \uCD94\uCD9C\uD558\uACE0, pdf\xB7\uC774\uBBF8\uC9C0\uB294 \uC81C\uAC00 \uC9C1\uC811 \uC77D\uC2B5\uB2C8\uB2E4.)
|
|
96061
96666
|
|
|
96062
96667
|
\uD604\uC7AC \uD30C\uC77C:
|
|
96063
96668
|
${list}`,
|
|
@@ -96068,7 +96673,7 @@ ${list}`,
|
|
|
96068
96673
|
{
|
|
96069
96674
|
name: "read_inbox",
|
|
96070
96675
|
title: "\uC778\uC785 \uD3F4\uB354 \uD30C\uC77C \uC77D\uAE30",
|
|
96071
|
-
description: '\uC778\uC785 \uD3F4\uB354(~/.careermate/inbox)\uC5D0 \uC0AC\uC6A9\uC790\uAC00 \uB123\uC5B4 \uB454 \uBB38\uC11C\uB4E4\uC758 \uBCF8\uBB38\uC744 \uD55C \uBC88\uC5D0 \uC77D\uC5B4 \uB3CC\uB824\uC90D\uB2C8\uB2E4. open_inbox\uB85C \uD3F4\uB354\uB97C \uC548\uB0B4\uD55C \uB4A4 \uC0AC\uC6A9\uC790\uAC00 "\uB2E4 \uB123\uC5C8\uC5B4"\uB77C\uACE0 \uD558\uBA74 \uD638\uCD9C\uD558\uC138\uC694. docx/hwp/hwpx/\uD14D\uC2A4\uD2B8\uB294 \uD14D\uC2A4\uD2B8\uB97C \uCD94\uCD9C\uD558\uACE0, pdf\xB7\uC774\uBBF8\uC9C0\uB294 \uCD94\uCD9C\uD558\uC9C0 \uC54A\uACE0 \uD30C\uC77C \uACBD\uB85C\uB97C \uB3CC\uB824\uC8FC\uB2C8 AI \uD074\uB77C\uC774\uC5B8\uD2B8\uC758 \uD30C\uC77C \uC77D\uAE30 \uAE30\uB2A5\uC73C\uB85C \uADF8 \uACBD\uB85C\uB97C \uC9C1\uC811 \uC5F4\uC5B4 \uC77D\uC73C\uC138\uC694. \uC77D\uC740 \uB0B4\uC6A9\uC744 \uAD6C\uC870\uD654\uD574 save_profile\
|
|
96676
|
+
description: '\uC778\uC785 \uD3F4\uB354(~/.careermate/inbox)\uC5D0 \uC0AC\uC6A9\uC790\uAC00 \uB123\uC5B4 \uB454 \uBB38\uC11C\uB4E4\uC758 \uBCF8\uBB38\uC744 \uD55C \uBC88\uC5D0 \uC77D\uC5B4 \uB3CC\uB824\uC90D\uB2C8\uB2E4. open_inbox\uB85C \uD3F4\uB354\uB97C \uC548\uB0B4\uD55C \uB4A4 \uC0AC\uC6A9\uC790\uAC00 "\uB2E4 \uB123\uC5C8\uC5B4"\uB77C\uACE0 \uD558\uBA74 \uD638\uCD9C\uD558\uC138\uC694. docx/hwp/hwpx/\uD14D\uC2A4\uD2B8\uB294 \uD14D\uC2A4\uD2B8\uB97C \uCD94\uCD9C\uD558\uACE0, pdf\xB7\uC774\uBBF8\uC9C0\uB294 \uCD94\uCD9C\uD558\uC9C0 \uC54A\uACE0 \uD30C\uC77C \uACBD\uB85C\uB97C \uB3CC\uB824\uC8FC\uB2C8 AI \uD074\uB77C\uC774\uC5B8\uD2B8\uC758 \uD30C\uC77C \uC77D\uAE30 \uAE30\uB2A5\uC73C\uB85C \uADF8 \uACBD\uB85C\uB97C \uC9C1\uC811 \uC5F4\uC5B4 \uC77D\uC73C\uC138\uC694. \uC77D\uC740 \uB0B4\uC6A9\uC744 \uAD6C\uC870\uD654\uD574 \uD504\uB85C\uD544\uC740 save_profile, \uC774\uB825\uC11C\xB7\uACBD\uB825\uAE30\uC220\uC11C\xB7\uD3EC\uD2B8\uD3F4\uB9AC\uC624\uB294 add_resume, \uAE30\uC874 \uC790\uAE30\uC18C\uAC1C\uC11C\uB294 save_cover_letter_version\uC73C\uB85C \uC800\uC7A5\uD558\uC138\uC694(\uD30C\uC77C \uB0B4\uC6A9\uC744 \uC0C8 \uD30C\uC77C\uB85C \uB2E4\uC2DC \uC4F0\uC9C0 \uB9C8\uC138\uC694). filename\uC744 \uC8FC\uBA74 \uD574\uB2F9 \uD30C\uC77C\uB9CC \uC77D\uC2B5\uB2C8\uB2E4.',
|
|
96072
96677
|
inputSchema: {
|
|
96073
96678
|
filename: external_exports.string().optional().describe("\uD2B9\uC815 \uD30C\uC77C\uB9CC \uC77D\uC744 \uB54C \uD30C\uC77C\uBA85(\uB300\uC18C\uBB38\uC790 \uBB34\uC2DC). \uC0DD\uB7B5\uD558\uBA74 \uD3F4\uB354 \uC548 \uBAA8\uB4E0 \uD30C\uC77C\uC744 \uC77D\uC2B5\uB2C8\uB2E4."),
|
|
96074
96679
|
max_chars: external_exports.number().optional().describe("\uD30C\uC77C\uBCC4 \uBC18\uD658 \uD14D\uC2A4\uD2B8 \uCD5C\uB300 \uAE38\uC774(\uCD08\uACFC \uC2DC \uC798\uB77C\uB0C4). \uAE30\uBCF8 20000\uC790")
|
|
@@ -96109,7 +96714,7 @@ ${dir}
|
|
|
96109
96714
|
`\uC778\uC785 \uD3F4\uB354 \uD30C\uC77C ${files.length}\uAC74\uC744 \uC77D\uC5C8\uC2B5\uB2C8\uB2E4:
|
|
96110
96715
|
${summary}
|
|
96111
96716
|
|
|
96112
|
-
\uCD94\uCD9C\uB41C \uB0B4\uC6A9\uC744 \uAD6C\uC870\uD654\uD574 save_profile\
|
|
96717
|
+
\uCD94\uCD9C\uB41C \uB0B4\uC6A9\uC744 \uAD6C\uC870\uD654\uD574 \uD504\uB85C\uD544\uC740 save_profile, \uC774\uB825\uC11C\xB7\uACBD\uB825\uAE30\uC220\uC11C\xB7\uD3EC\uD2B8\uD3F4\uB9AC\uC624\uB294 add_resume, \uAE30\uC874 \uC790\uAE30\uC18C\uAC1C\uC11C\uB294 save_cover_letter_version\uC73C\uB85C \uC800\uC7A5\uD558\uC138\uC694.`,
|
|
96113
96718
|
{ dir, files }
|
|
96114
96719
|
);
|
|
96115
96720
|
}
|
|
@@ -96138,9 +96743,17 @@ ${lines}`;
|
|
|
96138
96743
|
if (upd.update_available) {
|
|
96139
96744
|
text += `
|
|
96140
96745
|
|
|
96141
|
-
\
|
|
96746
|
+
\uC0C8 \uBC84\uC804 v${upd.latest}\uC774 \uB098\uC654\uC2B5\uB2C8\uB2E4(\uD604\uC7AC v${upd.current}). \uC0AC\uC6A9\uC790\uAC00 \uC6D0\uD558\uBA74 \uBC14\uB85C \uC5C5\uB370\uC774\uD2B8\uB97C \uC9C4\uD589\uD558\uC138\uC694. \uC5C5\uB370\uC774\uD2B8 \uD6C4\uC5D0\uB294 AI \uC571 \uB610\uB294 MCP \uC5F0\uACB0\uC744 \uC7AC\uC2DC\uC791\uD574\uC57C \uC801\uC6A9\uB429\uB2C8\uB2E4.`;
|
|
96142
96747
|
}
|
|
96143
|
-
return ok(text, {
|
|
96748
|
+
return ok(text, {
|
|
96749
|
+
...s,
|
|
96750
|
+
verify_strict: strict,
|
|
96751
|
+
update: upd,
|
|
96752
|
+
suggested_next_action: upd.update_available ? {
|
|
96753
|
+
prompt: `\uC0C8 \uBC84\uC804 v${upd.latest}\uC774 \uB098\uC654\uC2B5\uB2C8\uB2E4. \uC9C0\uAE08 \uC5C5\uB370\uC774\uD2B8\uD560\uAE4C\uC694?`,
|
|
96754
|
+
next_tool: "update_careermate"
|
|
96755
|
+
} : null
|
|
96756
|
+
});
|
|
96144
96757
|
}
|
|
96145
96758
|
},
|
|
96146
96759
|
/* --------------------------------------------------------------- profile */
|
|
@@ -96169,7 +96782,7 @@ ${lines}`;
|
|
|
96169
96782
|
{
|
|
96170
96783
|
name: "add_resume",
|
|
96171
96784
|
title: "\uC774\uB825\uC11C/\uACBD\uB825\uAE30\uC220\uC11C \uCD94\uAC00",
|
|
96172
|
-
description: "\uC774\uB825\uC11C, \uACBD\uB825\uAE30\uC220\uC11C, \uD3EC\uD2B8\uD3F4\uB9AC\uC624 \uB4F1 \uBB38\uC11C\uB97C \uC800\uC7A5\uD569\uB2C8\uB2E4. content\uC5D0\uB294 \uC0AC\uC6A9\uC790\uAC00 \uC5C5\uB85C\uB4DC/\uBD99\uC5EC\uB123\uC740 \uD14D\uC2A4\uD2B8
|
|
96785
|
+
description: "\uC774\uB825\uC11C, \uACBD\uB825\uAE30\uC220\uC11C, \uD3EC\uD2B8\uD3F4\uB9AC\uC624 \uB4F1 \uBB38\uC11C\uB97C \uC800\uC7A5\uD569\uB2C8\uB2E4. content\uC5D0\uB294 \uC0AC\uC6A9\uC790\uAC00 \uC5C5\uB85C\uB4DC/\uBD99\uC5EC\uB123\uC740 \uD14D\uC2A4\uD2B8 \uB610\uB294 AI\uAC00 \uC804\uBB38\uAC00 \uC808\uCC28\uB85C \uC815\uB9AC\uD55C Markdown\uC744 \uB123\uC73C\uC138\uC694. \uACBD\uB825\uAE30\uC220\uC11C\uB97C \uC791\uC131\uD574 \uC800\uC7A5\uD560 \uB54C\uB294 kind=career_description, source=ai\uB97C \uC0AC\uC6A9\uD569\uB2C8\uB2E4. kind \uAE30\uBCF8\uAC12\uC740 resume\uC785\uB2C8\uB2E4. is_primary=true\uB85C \uB300\uD45C \uBB38\uC11C\uB97C \uC9C0\uC815\uD558\uBA74 get_application_context\uC758 primary_resume\uB85C \uB178\uCD9C\uB429\uB2C8\uB2E4.",
|
|
96173
96786
|
// Reuse the shared (length-bounded, whitespace-rejecting) Document schema so
|
|
96174
96787
|
// the MCP ingestion path — the primary route for résumé text — inherits the
|
|
96175
96788
|
// same caps as the web API. kind stays optional here (defaults to resume).
|
|
@@ -96193,6 +96806,23 @@ ${lines}`;
|
|
|
96193
96806
|
return ok(`\uBB38\uC11C ${docs.length}\uAC74`, docs);
|
|
96194
96807
|
}
|
|
96195
96808
|
},
|
|
96809
|
+
{
|
|
96810
|
+
name: "delete_resume",
|
|
96811
|
+
title: "\uC774\uB825\uC11C/\uBB38\uC11C \uC0AD\uC81C",
|
|
96812
|
+
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.",
|
|
96813
|
+
inputSchema: {
|
|
96814
|
+
document_id: external_exports.string(),
|
|
96815
|
+
confirm: external_exports.string().describe("\uC0AD\uC81C \uD655\uC778\uAC12. \uC815\uD655\uD788 DELETE\uB97C \uB123\uC5B4\uC57C \uC0AD\uC81C\uB429\uB2C8\uB2E4.")
|
|
96816
|
+
},
|
|
96817
|
+
handler: (args) => {
|
|
96818
|
+
if (args?.confirm !== DELETE_CONFIRMATION) return fail("\uC0AD\uC81C\uD558\uB824\uBA74 confirm\uC5D0 DELETE\uB97C \uB123\uC5B4 \uB2E4\uC2DC \uD638\uCD9C\uD558\uC138\uC694.");
|
|
96819
|
+
const doc = documentRepo.get(args.document_id);
|
|
96820
|
+
if (!doc) return fail("\uBB38\uC11C\uB97C \uCC3E\uC744 \uC218 \uC5C6\uC2B5\uB2C8\uB2E4.");
|
|
96821
|
+
if (!documentRepo.remove(doc.id)) return fail("\uBB38\uC11C\uB97C \uC0AD\uC81C\uD558\uC9C0 \uBABB\uD588\uC2B5\uB2C8\uB2E4.");
|
|
96822
|
+
const user_message = `'${doc.title}' \uBB38\uC11C\uB97C \uC0AD\uC81C\uD588\uC5B4\uC694.`;
|
|
96823
|
+
return ok(user_message, { deleted: true, document_id: doc.id, user_message });
|
|
96824
|
+
}
|
|
96825
|
+
},
|
|
96196
96826
|
/* ----------------------------------------------------------- experiences */
|
|
96197
96827
|
{
|
|
96198
96828
|
name: "add_experience",
|
|
@@ -96262,6 +96892,57 @@ ${lines}`;
|
|
|
96262
96892
|
return ok(`\uAE30\uC220 ${list.length}\uAC74`, list);
|
|
96263
96893
|
}
|
|
96264
96894
|
},
|
|
96895
|
+
{
|
|
96896
|
+
name: "delete_experience",
|
|
96897
|
+
title: "\uACBD\uB825 \uD56D\uBAA9 \uC0AD\uC81C",
|
|
96898
|
+
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.",
|
|
96899
|
+
inputSchema: {
|
|
96900
|
+
experience_id: external_exports.string(),
|
|
96901
|
+
confirm: external_exports.string().describe("\uC0AD\uC81C \uD655\uC778\uAC12. \uC815\uD655\uD788 DELETE\uB97C \uB123\uC5B4\uC57C \uC0AD\uC81C\uB429\uB2C8\uB2E4.")
|
|
96902
|
+
},
|
|
96903
|
+
handler: (args) => {
|
|
96904
|
+
if (args?.confirm !== DELETE_CONFIRMATION) return fail("\uC0AD\uC81C\uD558\uB824\uBA74 confirm\uC5D0 DELETE\uB97C \uB123\uC5B4 \uB2E4\uC2DC \uD638\uCD9C\uD558\uC138\uC694.");
|
|
96905
|
+
const exp = experienceRepo.get(args.experience_id);
|
|
96906
|
+
if (!exp) return fail("\uD574\uB2F9 \uACBD\uB825 \uD56D\uBAA9\uC744 \uCC3E\uC744 \uC218 \uC5C6\uC2B5\uB2C8\uB2E4.");
|
|
96907
|
+
if (!experienceRepo.remove(exp.id)) return fail("\uACBD\uB825 \uD56D\uBAA9\uC744 \uC0AD\uC81C\uD558\uC9C0 \uBABB\uD588\uC2B5\uB2C8\uB2E4.");
|
|
96908
|
+
const user_message = `'${exp.company}' \uACBD\uB825\uC744 \uC0AD\uC81C\uD588\uC5B4\uC694.`;
|
|
96909
|
+
return ok(user_message, { deleted: true, experience_id: exp.id, user_message });
|
|
96910
|
+
}
|
|
96911
|
+
},
|
|
96912
|
+
{
|
|
96913
|
+
name: "delete_project",
|
|
96914
|
+
title: "\uD504\uB85C\uC81D\uD2B8 \uD56D\uBAA9 \uC0AD\uC81C",
|
|
96915
|
+
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.",
|
|
96916
|
+
inputSchema: {
|
|
96917
|
+
project_id: external_exports.string(),
|
|
96918
|
+
confirm: external_exports.string().describe("\uC0AD\uC81C \uD655\uC778\uAC12. \uC815\uD655\uD788 DELETE\uB97C \uB123\uC5B4\uC57C \uC0AD\uC81C\uB429\uB2C8\uB2E4.")
|
|
96919
|
+
},
|
|
96920
|
+
handler: (args) => {
|
|
96921
|
+
if (args?.confirm !== DELETE_CONFIRMATION) return fail("\uC0AD\uC81C\uD558\uB824\uBA74 confirm\uC5D0 DELETE\uB97C \uB123\uC5B4 \uB2E4\uC2DC \uD638\uCD9C\uD558\uC138\uC694.");
|
|
96922
|
+
const proj = projectRepo.get(args.project_id);
|
|
96923
|
+
if (!proj) return fail("\uD574\uB2F9 \uD504\uB85C\uC81D\uD2B8 \uD56D\uBAA9\uC744 \uCC3E\uC744 \uC218 \uC5C6\uC2B5\uB2C8\uB2E4.");
|
|
96924
|
+
if (!projectRepo.remove(proj.id)) return fail("\uD504\uB85C\uC81D\uD2B8 \uD56D\uBAA9\uC744 \uC0AD\uC81C\uD558\uC9C0 \uBABB\uD588\uC2B5\uB2C8\uB2E4.");
|
|
96925
|
+
const user_message = `'${proj.name}' \uD504\uB85C\uC81D\uD2B8\uB97C \uC0AD\uC81C\uD588\uC5B4\uC694.`;
|
|
96926
|
+
return ok(user_message, { deleted: true, project_id: proj.id, user_message });
|
|
96927
|
+
}
|
|
96928
|
+
},
|
|
96929
|
+
{
|
|
96930
|
+
name: "delete_skill",
|
|
96931
|
+
title: "\uAE30\uC220\uC2A4\uD0DD \uD56D\uBAA9 \uC0AD\uC81C",
|
|
96932
|
+
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.",
|
|
96933
|
+
inputSchema: {
|
|
96934
|
+
skill_id: external_exports.string(),
|
|
96935
|
+
confirm: external_exports.string().describe("\uC0AD\uC81C \uD655\uC778\uAC12. \uC815\uD655\uD788 DELETE\uB97C \uB123\uC5B4\uC57C \uC0AD\uC81C\uB429\uB2C8\uB2E4.")
|
|
96936
|
+
},
|
|
96937
|
+
handler: (args) => {
|
|
96938
|
+
if (args?.confirm !== DELETE_CONFIRMATION) return fail("\uC0AD\uC81C\uD558\uB824\uBA74 confirm\uC5D0 DELETE\uB97C \uB123\uC5B4 \uB2E4\uC2DC \uD638\uCD9C\uD558\uC138\uC694.");
|
|
96939
|
+
const skill = skillRepo.get(args.skill_id);
|
|
96940
|
+
if (!skill) return fail("\uD574\uB2F9 \uAE30\uC220 \uD56D\uBAA9\uC744 \uCC3E\uC744 \uC218 \uC5C6\uC2B5\uB2C8\uB2E4.");
|
|
96941
|
+
if (!skillRepo.remove(skill.id)) return fail("\uAE30\uC220 \uD56D\uBAA9\uC744 \uC0AD\uC81C\uD558\uC9C0 \uBABB\uD588\uC2B5\uB2C8\uB2E4.");
|
|
96942
|
+
const user_message = `'${skill.name}' \uAE30\uC220\uC744 \uC0AD\uC81C\uD588\uC5B4\uC694.`;
|
|
96943
|
+
return ok(user_message, { deleted: true, skill_id: skill.id, user_message });
|
|
96944
|
+
}
|
|
96945
|
+
},
|
|
96265
96946
|
/* ---------------------------------------------------------- cover letters */
|
|
96266
96947
|
{
|
|
96267
96948
|
name: "get_cover_letters",
|
|
@@ -96293,6 +96974,31 @@ ${lines}`;
|
|
|
96293
96974
|
}
|
|
96294
96975
|
}
|
|
96295
96976
|
},
|
|
96977
|
+
{
|
|
96978
|
+
name: "delete_cover_letter",
|
|
96979
|
+
title: "\uC790\uAE30\uC18C\uAC1C\uC11C \uC0AD\uC81C",
|
|
96980
|
+
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.",
|
|
96981
|
+
inputSchema: {
|
|
96982
|
+
cover_letter_id: external_exports.string(),
|
|
96983
|
+
confirm: external_exports.string().describe("\uC0AD\uC81C \uD655\uC778\uAC12. \uC815\uD655\uD788 DELETE\uB97C \uB123\uC5B4\uC57C \uC0AD\uC81C\uB429\uB2C8\uB2E4.")
|
|
96984
|
+
},
|
|
96985
|
+
handler: (args) => {
|
|
96986
|
+
if (args?.confirm !== DELETE_CONFIRMATION) {
|
|
96987
|
+
return fail("\uC0AD\uC81C\uD558\uB824\uBA74 confirm\uC5D0 DELETE\uB97C \uB123\uC5B4 \uB2E4\uC2DC \uD638\uCD9C\uD558\uC138\uC694.");
|
|
96988
|
+
}
|
|
96989
|
+
const cl = coverLetterRepo.get(args.cover_letter_id, false);
|
|
96990
|
+
if (!cl) return fail("\uC790\uAE30\uC18C\uAC1C\uC11C\uB97C \uCC3E\uC744 \uC218 \uC5C6\uC2B5\uB2C8\uB2E4.");
|
|
96991
|
+
const removed = coverLetterRepo.remove(cl.id);
|
|
96992
|
+
if (!removed) return fail("\uC790\uAE30\uC18C\uAC1C\uC11C\uB97C \uC0AD\uC81C\uD558\uC9C0 \uBABB\uD588\uC2B5\uB2C8\uB2E4.");
|
|
96993
|
+
const user_message = `'${cl.title}' \uC790\uAE30\uC18C\uAC1C\uC11C\uB97C \uC0AD\uC81C\uD588\uC5B4\uC694. \uC5F0\uACB0\uB41C \uC9C0\uC6D0 \uAE30\uB85D\uC5D0\uC11C\uB294 \uC790\uAE30\uC18C\uAC1C\uC11C \uC5F0\uACB0\uB9CC \uBE44\uC6CC\uB480\uC2B5\uB2C8\uB2E4.`;
|
|
96994
|
+
return ok(user_message, {
|
|
96995
|
+
deleted: true,
|
|
96996
|
+
cover_letter_id: cl.id,
|
|
96997
|
+
title: cl.title,
|
|
96998
|
+
user_message
|
|
96999
|
+
});
|
|
97000
|
+
}
|
|
97001
|
+
},
|
|
96296
97002
|
/* ------------------------------------------------------------------ jobs */
|
|
96297
97003
|
{
|
|
96298
97004
|
name: "save_job_posting",
|
|
@@ -96301,18 +97007,26 @@ ${lines}`;
|
|
|
96301
97007
|
inputSchema: JobInputSchema.shape,
|
|
96302
97008
|
handler: (args) => {
|
|
96303
97009
|
const { job } = saveJobPosting(args);
|
|
96304
|
-
|
|
97010
|
+
const user_message = `'${job.company} \xB7 ${job.position}' \uACF5\uACE0\uB97C \uC800\uC7A5\uD588\uC5B4\uC694.`;
|
|
97011
|
+
return ok(user_message, {
|
|
97012
|
+
...job,
|
|
97013
|
+
user_message,
|
|
97014
|
+
suggested_next_action: {
|
|
97015
|
+
prompt: "\uC774 \uACF5\uACE0\uC640 \uB0B4 \uD504\uB85C\uD544\uC744 \uBE44\uAD50\uD574 \uC801\uD569\uB3C4\uB97C \uBD84\uC11D\uD560\uAE4C\uC694?",
|
|
97016
|
+
next_workflow: "analyze_job"
|
|
97017
|
+
}
|
|
97018
|
+
});
|
|
96305
97019
|
}
|
|
96306
97020
|
},
|
|
96307
97021
|
{
|
|
96308
97022
|
name: "get_job_posting",
|
|
96309
97023
|
title: "\uCC44\uC6A9\uACF5\uACE0 \uC0C1\uC138 \uC870\uD68C",
|
|
96310
|
-
description: "\uACF5\uACE0 1\uAC74\uC758 \uC0C1\uC138\uB97C \uC870\uD68C\uD569\uB2C8\uB2E4. \uACF5\uACE0 \uC815\uBCF4\uC640 \uD568\uAED8 \uC801\uD569\uB3C4 \uBD84\uC11D, \uC9C0\uC6D0 \uC0C1\uD0DC, \
|
|
97024
|
+
description: "\uACF5\uACE0 1\uAC74\uC758 \uC0C1\uC138\uB97C \uC870\uD68C\uD569\uB2C8\uB2E4. \uACF5\uACE0 \uC815\uBCF4\uC640 \uD568\uAED8 \uC801\uD569\uB3C4 \uBD84\uC11D, \uC9C0\uC6D0 \uC0C1\uD0DC, \uC790\uAE30\uC18C\uAC1C\uC11C, \uBA74\uC811 \uC900\uBE44 \uC790\uB8CC\uB97C \uD55C \uBC88\uC5D0 \uB3CC\uB824\uC90D\uB2C8\uB2E4.",
|
|
96311
97025
|
inputSchema: { job_id: external_exports.string() },
|
|
96312
97026
|
readOnly: true,
|
|
96313
97027
|
handler: (args) => {
|
|
96314
97028
|
const job = jobRepo.get(args.job_id);
|
|
96315
|
-
if (!job) return fail(
|
|
97029
|
+
if (!job) return fail("\uACF5\uACE0\uB97C \uCC3E\uC744 \uC218 \uC5C6\uC2B5\uB2C8\uB2E4.");
|
|
96316
97030
|
return ok(`${job.company} \xB7 ${job.position}`, {
|
|
96317
97031
|
job: jobWithMeta(job),
|
|
96318
97032
|
fit: fitRepo.getByJob(job.id),
|
|
@@ -96333,6 +97047,35 @@ ${lines}`;
|
|
|
96333
97047
|
return ok(`\uACF5\uACE0 ${jobs.length}\uAC74`, jobs);
|
|
96334
97048
|
}
|
|
96335
97049
|
},
|
|
97050
|
+
{
|
|
97051
|
+
name: "delete_job_posting",
|
|
97052
|
+
title: "\uCC44\uC6A9\uACF5\uACE0 \uC0AD\uC81C",
|
|
97053
|
+
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.",
|
|
97054
|
+
inputSchema: {
|
|
97055
|
+
job_id: external_exports.string(),
|
|
97056
|
+
confirm: external_exports.string().describe("\uC0AD\uC81C \uD655\uC778\uAC12. \uC815\uD655\uD788 DELETE\uB97C \uB123\uC5B4\uC57C \uC0AD\uC81C\uB429\uB2C8\uB2E4.")
|
|
97057
|
+
},
|
|
97058
|
+
handler: (args) => {
|
|
97059
|
+
if (args?.confirm !== DELETE_CONFIRMATION) {
|
|
97060
|
+
return fail("\uC0AD\uC81C\uD558\uB824\uBA74 confirm\uC5D0 DELETE\uB97C \uB123\uC5B4 \uB2E4\uC2DC \uD638\uCD9C\uD558\uC138\uC694.");
|
|
97061
|
+
}
|
|
97062
|
+
const job = jobRepo.get(args.job_id);
|
|
97063
|
+
if (!job) return fail("\uACF5\uACE0\uB97C \uCC3E\uC744 \uC218 \uC5C6\uC2B5\uB2C8\uB2E4.");
|
|
97064
|
+
const detachedCoverLetters = coverLetterRepo.listByJob(job.id).length;
|
|
97065
|
+
const removed = jobRepo.remove(job.id);
|
|
97066
|
+
if (!removed) return fail("\uACF5\uACE0\uB97C \uC0AD\uC81C\uD558\uC9C0 \uBABB\uD588\uC2B5\uB2C8\uB2E4.");
|
|
97067
|
+
const detachedNote = detachedCoverLetters ? ` \uC5F0\uACB0\uB41C \uC790\uAE30\uC18C\uAC1C\uC11C ${detachedCoverLetters}\uAC74\uC740 \uC0AD\uC81C\uD558\uC9C0 \uC54A\uACE0 \uACF5\uACE0 \uC5F0\uACB0\uB9CC \uD574\uC81C\uD588\uC2B5\uB2C8\uB2E4.` : "";
|
|
97068
|
+
const user_message = `'${job.company} \xB7 ${job.position}' \uACF5\uACE0\uB97C \uC0AD\uC81C\uD588\uC5B4\uC694. \uC5F0\uACB0\uB41C \uC9C0\uC6D0 \uC0C1\uD0DC, \uC801\uD569\uB3C4 \uBD84\uC11D, \uBA74\uC811 \uC900\uBE44\uB3C4 \uD568\uAED8 \uC815\uB9AC\uD588\uC2B5\uB2C8\uB2E4.${detachedNote}`;
|
|
97069
|
+
return ok(user_message, {
|
|
97070
|
+
deleted: true,
|
|
97071
|
+
job_id: job.id,
|
|
97072
|
+
company: job.company,
|
|
97073
|
+
position: job.position,
|
|
97074
|
+
detached_cover_letters: detachedCoverLetters,
|
|
97075
|
+
user_message
|
|
97076
|
+
});
|
|
97077
|
+
}
|
|
97078
|
+
},
|
|
96336
97079
|
/* ----------------------------------------------------- application context */
|
|
96337
97080
|
{
|
|
96338
97081
|
name: "get_application_context",
|
|
@@ -96344,18 +97087,46 @@ ${lines}`;
|
|
|
96344
97087
|
const ctx = getApplicationContext({ job_id: args?.job_id });
|
|
96345
97088
|
const recommended_route = pickRoute(ctx);
|
|
96346
97089
|
const route = recommended_route ? getRoute(recommended_route) : void 0;
|
|
97090
|
+
const today = (/* @__PURE__ */ new Date()).toISOString().slice(0, 10);
|
|
97091
|
+
const ym = (s) => {
|
|
97092
|
+
const m = s ? /^(\d{4})-(\d{2})/.exec(s) : null;
|
|
97093
|
+
return m ? Number(m[1]) * 12 + Number(m[2]) : null;
|
|
97094
|
+
};
|
|
97095
|
+
const monthsBetween = (a, b) => {
|
|
97096
|
+
const x2 = ym(a), y = ym(b);
|
|
97097
|
+
return x2 != null && y != null ? y - x2 : null;
|
|
97098
|
+
};
|
|
97099
|
+
const tenure = ctx.experiences.map((e) => {
|
|
97100
|
+
if (!e.start_date) return null;
|
|
97101
|
+
const asOf = e.is_current ? e.updated_at ?? today : e.end_date;
|
|
97102
|
+
const months = monthsBetween(e.start_date, asOf);
|
|
97103
|
+
if (months == null || months < 0) return null;
|
|
97104
|
+
return {
|
|
97105
|
+
company: e.company,
|
|
97106
|
+
is_current: e.is_current,
|
|
97107
|
+
start_date: e.start_date,
|
|
97108
|
+
as_of: (asOf ?? "").slice(0, 7),
|
|
97109
|
+
// 재직중=updated_at(정보 확인 시점) / 종료=end_date
|
|
97110
|
+
months,
|
|
97111
|
+
years: Math.round(months / 12 * 10) / 10,
|
|
97112
|
+
data_age_months: e.is_current ? monthsBetween(e.updated_at, today) : null
|
|
97113
|
+
};
|
|
97114
|
+
}).filter((t) => t != null);
|
|
96347
97115
|
const enriched = {
|
|
96348
97116
|
...ctx,
|
|
97117
|
+
today,
|
|
97118
|
+
tenure,
|
|
96349
97119
|
recommended_route,
|
|
96350
97120
|
verifier_sequence: route?.verifierSequence ?? [],
|
|
96351
97121
|
next_tool: recommended_route ? "get_workflow_guide" : null
|
|
96352
97122
|
};
|
|
96353
97123
|
const summary = [
|
|
97124
|
+
`\uC624\uB298 \uB0A0\uC9DC: ${today}. \uACBD\uB825 \uC5F0\uCC28\xB7\uC7AC\uC9C1\uAE30\uAC04\uC740 \uC9C1\uC811 \uACC4\uC0B0\uD558\uC9C0 \uB9D0\uACE0 \uC81C\uACF5\uB41C tenure[](\uC11C\uBC84 \uACC4\uC0B0: \uC7AC\uC9C1\uC911=\uC815\uBCF4\uD655\uC778\uC77C \uAE30\uC900 \uC5F0\uCC28, data_age_months \uD06C\uBA74 \uD604\uC7AC \uC7AC\uC9C1 \uD655\uC778 \uD544\uC694)\uB97C \uADF8\uB300\uB85C \uC4F0\uC138\uC694.`,
|
|
96354
97125
|
`\uD504\uB85C\uD544: ${ctx.profile?.name ?? "\uBBF8\uC785\uB825"}`,
|
|
96355
97126
|
`\uC774\uB825\uC11C ${ctx.resumes.length} \xB7 \uACBD\uB825 ${ctx.experiences.length} \xB7 \uD504\uB85C\uC81D\uD2B8 ${ctx.projects.length} \xB7 \uC2A4\uD0AC ${ctx.skills.length} \xB7 \uC790\uC18C\uC11C ${ctx.cover_letters.length}`,
|
|
96356
97127
|
ctx.job ? `\uB300\uC0C1 \uACF5\uACE0: ${ctx.job.company} \xB7 ${ctx.job.position}` : "\uB300\uC0C1 \uACF5\uACE0 \uC5C6\uC74C",
|
|
96357
97128
|
ctx.writing_preferences.preferred_tone ? `\uC120\uD638 \uBB38\uCCB4: ${ctx.writing_preferences.preferred_tone}` : "",
|
|
96358
|
-
recommended_route ? `\
|
|
97129
|
+
recommended_route ? `\uB0B4\uBD80 \uC548\uB0B4: \uC0AC\uC6A9\uC790\uC5D0\uAC8C\uB294 \uB3C4\uAD6C\uBA85\uC774\uB098 ID\uB97C \uB9D0\uD558\uC9C0 \uB9D0\uACE0, \uBA3C\uC800 get_workflow_guide({ workflow_id: "${recommended_route}" })\uB85C \uC2E4\uD589 \uC808\uCC28\uC640 \uAC80\uC99D \uC21C\uC11C\uB97C \uBC1B\uC740 \uB4A4 \uC26C\uC6B4 \uB9D0\uB85C \uC548\uB0B4\uD558\uC138\uC694.` : "\uB0B4\uBD80 \uC548\uB0B4: \uC0AC\uC6A9\uC790\uC5D0\uAC8C\uB294 \uB3C4\uAD6C\uBA85\uC744 \uB9D0\uD558\uC9C0 \uB9D0\uACE0, \uBA3C\uC800 get_workflow_guide\uB85C \uC2E4\uD589 \uC808\uCC28\uC640 \uAC80\uC99D \uC21C\uC11C\uB97C \uBC1B\uC740 \uB4A4 \uC26C\uC6B4 \uB9D0\uB85C \uC548\uB0B4\uD558\uC138\uC694."
|
|
96359
97130
|
].filter(Boolean).join("\n");
|
|
96360
97131
|
return ok(summary, enriched);
|
|
96361
97132
|
}
|
|
@@ -96368,7 +97139,34 @@ ${lines}`;
|
|
|
96368
97139
|
handler: (args) => {
|
|
96369
97140
|
try {
|
|
96370
97141
|
const fit = saveFitAnalysis(args);
|
|
96371
|
-
|
|
97142
|
+
const suggested_next_action = {
|
|
97143
|
+
prompt: "\uC774 \uACF5\uACE0\uC5D0 \uB9DE\uCD98 \uC790\uAE30\uC18C\uAC1C\uC11C\uB97C \uC368\uB4DC\uB9B4\uAE4C\uC694?",
|
|
97144
|
+
options: [
|
|
97145
|
+
{
|
|
97146
|
+
label: "\uB124, \uC774 \uACF5\uACE0\uC5D0 \uB9DE\uCD98 \uC790\uAE30\uC18C\uAC1C\uC11C\uB97C \uC368\uC918",
|
|
97147
|
+
next_workflow: "write_cover_letter"
|
|
97148
|
+
},
|
|
97149
|
+
{
|
|
97150
|
+
label: "\uC544\uB2C8\uC694, \uBD84\uC11D\uB9CC \uC800\uC7A5\uD574\uC918",
|
|
97151
|
+
next_workflow: null
|
|
97152
|
+
}
|
|
97153
|
+
]
|
|
97154
|
+
};
|
|
97155
|
+
const user_message = `\uC801\uD569\uB3C4 \uBD84\uC11D\uC744 \uC800\uC7A5\uD588\uC5B4\uC694${fit.score != null ? ` (${fit.score}\uC810)` : ""}. \uC790\uC138\uD55C \uACB0\uACFC\uB294 \uB300\uC2DC\uBCF4\uB4DC\uC5D0\uC11C\uB3C4 \uD655\uC778\uD560 \uC218 \uC788\uC2B5\uB2C8\uB2E4: ${DASHBOARD_URL}`;
|
|
97156
|
+
return ok(
|
|
97157
|
+
[
|
|
97158
|
+
user_message,
|
|
97159
|
+
"",
|
|
97160
|
+
"\uC0AC\uC6A9\uC790\uC5D0\uAC8C \uB2E4\uC74C \uC120\uD0DD\uC9C0\uB97C \uBCF4\uC5EC\uC8FC\uC138\uC694:",
|
|
97161
|
+
"1. \uB124, \uC774 \uACF5\uACE0\uC5D0 \uB9DE\uCD98 \uC790\uAE30\uC18C\uAC1C\uC11C\uB97C \uC368\uC918",
|
|
97162
|
+
"2. \uC544\uB2C8\uC694, \uBD84\uC11D\uB9CC \uC800\uC7A5\uD574\uC918"
|
|
97163
|
+
].join("\n"),
|
|
97164
|
+
{
|
|
97165
|
+
...fit,
|
|
97166
|
+
user_message,
|
|
97167
|
+
suggested_next_action
|
|
97168
|
+
}
|
|
97169
|
+
);
|
|
96372
97170
|
} catch (e) {
|
|
96373
97171
|
return fail(e instanceof Error ? e.message : "\uC800\uC7A5 \uC2E4\uD328");
|
|
96374
97172
|
}
|
|
@@ -96382,16 +97180,25 @@ ${lines}`;
|
|
|
96382
97180
|
inputSchema: {
|
|
96383
97181
|
job_id: external_exports.string(),
|
|
96384
97182
|
status: external_exports.enum(APPLICATION_STATUSES),
|
|
96385
|
-
note: external_exports.string().optional()
|
|
97183
|
+
note: external_exports.string().optional(),
|
|
97184
|
+
submission: ApplicationSubmissionSchema.optional()
|
|
96386
97185
|
},
|
|
96387
97186
|
handler: (args) => {
|
|
96388
97187
|
try {
|
|
96389
|
-
const res = updateApplicationStatus(args.job_id, args.status, args.note);
|
|
96390
|
-
|
|
96391
|
-
`\uC0C1\uD0DC\uB97C '${APPLICATION_STATUS_LABELS[args.status]}'(\uC73C)\uB85C \uBCC0\uACBD\uD588\uC2B5\uB2C8\uB2E4.${res.hint ? `
|
|
97188
|
+
const res = updateApplicationStatus(args.job_id, args.status, args.note, args.submission);
|
|
97189
|
+
const user_message = `\uC9C0\uC6D0 \uC0C1\uD0DC\uB97C '${APPLICATION_STATUS_LABELS[args.status]}'(\uC73C)\uB85C \uBC14\uAFE8\uC5B4\uC694.` + (res.hint ? `
|
|
96392
97190
|
|
|
96393
|
-
|
|
96394
|
-
|
|
97191
|
+
${res.hint}` : "");
|
|
97192
|
+
return ok(
|
|
97193
|
+
user_message,
|
|
97194
|
+
{
|
|
97195
|
+
...res,
|
|
97196
|
+
user_message,
|
|
97197
|
+
suggested_next_action: res.hint ? {
|
|
97198
|
+
prompt: res.hint,
|
|
97199
|
+
next_workflow: "prepare_interview"
|
|
97200
|
+
} : null
|
|
97201
|
+
}
|
|
96395
97202
|
);
|
|
96396
97203
|
} catch (e) {
|
|
96397
97204
|
return fail(e instanceof Error ? e.message : "\uBCC0\uACBD \uC2E4\uD328");
|
|
@@ -96402,12 +97209,15 @@ ${lines}`;
|
|
|
96402
97209
|
{
|
|
96403
97210
|
name: "save_interview_prep",
|
|
96404
97211
|
title: "\uBA74\uC811 \uC900\uBE44 \uC790\uB8CC \uC800\uC7A5",
|
|
96405
|
-
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 \uBA74\uC811 \uC900\uBE44 \uC790\uB8CC\uB97C \uC800\uC7A5\uD569\uB2C8\uB2E4. \
|
|
97212
|
+
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). job_id\uB294 \uD544\uC218\uC785\uB2C8\uB2E4. \uAC19\uC740 \uACF5\uACE0\uC5D0 \uB2E4\uC2DC \uC800\uC7A5\uD558\uBA74 \uAC31\uC2E0\uB429\uB2C8\uB2E4.",
|
|
96406
97213
|
inputSchema: InterviewPrepInputSchema.shape,
|
|
96407
97214
|
handler: (args) => {
|
|
96408
97215
|
try {
|
|
96409
97216
|
const prep = saveInterviewPrep(args);
|
|
96410
|
-
|
|
97217
|
+
const tech = prep.questions.filter((q) => (q.category ?? "technical") === "technical").length;
|
|
97218
|
+
const behavioral = prep.questions.filter((q) => q.category === "behavioral").length;
|
|
97219
|
+
const user_message = `\uBA74\uC811 \uC900\uBE44 \uC790\uB8CC\uB97C \uC800\uC7A5\uD588\uC5B4\uC694. \uC608\uC0C1 \uC9C8\uBB38 ${prep.questions.length}\uAC1C` + (behavioral > 0 ? ` (\uAE30\uC220 ${tech}\uAC1C \xB7 \uC778\uC131\xB7\uCEEC\uCC98\uD54F ${behavioral}\uAC1C)` : "") + "\uAC00 \uC900\uBE44\uB418\uC5B4 \uC788\uC2B5\uB2C8\uB2E4.";
|
|
97220
|
+
return ok(user_message, { ...prep, user_message });
|
|
96411
97221
|
} catch (e) {
|
|
96412
97222
|
return fail(e instanceof Error ? e.message : "\uC800\uC7A5 \uC2E4\uD328");
|
|
96413
97223
|
}
|
|
@@ -96432,11 +97242,70 @@ ${lines}`;
|
|
|
96432
97242
|
const dir = getExportsDir();
|
|
96433
97243
|
const filePath = path7.join(dir, result2.filename);
|
|
96434
97244
|
try {
|
|
96435
|
-
|
|
97245
|
+
fs7.writeFileSync(filePath, result2.content, "utf8");
|
|
96436
97246
|
} catch (e) {
|
|
96437
97247
|
return fail(`\uD30C\uC77C \uC800\uC7A5 \uC2E4\uD328: ${e instanceof Error ? e.message : e}`);
|
|
96438
97248
|
}
|
|
96439
97249
|
return ok(`'${cl.title}'\uB97C ${format.toUpperCase()}\uB85C \uB0B4\uBCF4\uB0C8\uC2B5\uB2C8\uB2E4.
|
|
97250
|
+
\uC800\uC7A5 \uC704\uCE58: ${filePath}`, {
|
|
97251
|
+
path: filePath,
|
|
97252
|
+
filename: result2.filename,
|
|
97253
|
+
content: result2.content
|
|
97254
|
+
});
|
|
97255
|
+
}
|
|
97256
|
+
},
|
|
97257
|
+
{
|
|
97258
|
+
name: "export_resume",
|
|
97259
|
+
title: "\uC774\uB825\uC11C/\uACBD\uB825\uAE30\uC220\uC11C \uB0B4\uBCF4\uB0B4\uAE30",
|
|
97260
|
+
description: '\uC800\uC7A5\uB41C \uC774\uB825\uC11C\xB7\uACBD\uB825\uAE30\uC220\uC11C \uB4F1 \uBB38\uC11C\uB97C Markdown \uB610\uB294 \uC778\uC1C4\uC6A9 HTML(\uBE0C\uB77C\uC6B0\uC800\uC5D0\uC11C PDF\uB85C \uC800\uC7A5) \uD30C\uC77C\uB85C \uB0B4\uBCF4\uB0B4 \uB370\uC774\uD130 \uD3F4\uB354\uC758 exports\uC5D0 \uC800\uC7A5\uD558\uACE0, \uD30C\uC77C \uACBD\uB85C\uC640 \uBCF8\uBB38\uC744 \uB3CC\uB824\uC90D\uB2C8\uB2E4. \uC0AC\uC6A9\uC790\uAC00 \uACF5\uACE0\uC5D0 \uB9DE\uCDB0 \uC815\uB9AC\uD55C \uC774\uB825\uC11C\uB97C \uBA3C\uC800 add_resume\uB85C \uC800\uC7A5\uD55C \uB4A4, "\uC774\uB825\uC11C \uD30C\uC77C\uB85C \uBC1B\uACE0 \uC2F6\uC5B4"\uB77C\uACE0 \uD560 \uB54C \uC0AC\uC6A9\uD558\uC138\uC694. document_id\uB294 get_resumes\uB85C \uD655\uC778\uD560 \uC218 \uC788\uC2B5\uB2C8\uB2E4. \uB300\uC2DC\uBCF4\uB4DC\uC5D0\uC11C \uC9C1\uC811 \uB2E4\uC6B4\uB85C\uB4DC\uD560 \uC218\uB3C4 \uC788\uC2B5\uB2C8\uB2E4.',
|
|
97261
|
+
inputSchema: {
|
|
97262
|
+
document_id: external_exports.string(),
|
|
97263
|
+
format: external_exports.enum(["md", "html"]).optional().describe("\uAE30\uBCF8 md")
|
|
97264
|
+
},
|
|
97265
|
+
handler: (args) => {
|
|
97266
|
+
const doc = documentRepo.get(args.document_id);
|
|
97267
|
+
if (!doc) return fail("\uBB38\uC11C\uB97C \uCC3E\uC744 \uC218 \uC5C6\uC2B5\uB2C8\uB2E4.");
|
|
97268
|
+
const profile = profileRepo.get();
|
|
97269
|
+
const format = args.format ?? "md";
|
|
97270
|
+
const result2 = format === "html" ? resumeToHtml(doc, profile) : resumeToMarkdown(doc, profile);
|
|
97271
|
+
const dir = getExportsDir();
|
|
97272
|
+
const filePath = path7.join(dir, result2.filename);
|
|
97273
|
+
try {
|
|
97274
|
+
fs7.writeFileSync(filePath, result2.content, "utf8");
|
|
97275
|
+
} catch (e) {
|
|
97276
|
+
return fail(`\uD30C\uC77C \uC800\uC7A5 \uC2E4\uD328: ${e instanceof Error ? e.message : e}`);
|
|
97277
|
+
}
|
|
97278
|
+
return ok(`'${doc.title}'\uB97C ${format.toUpperCase()}\uB85C \uB0B4\uBCF4\uB0C8\uC2B5\uB2C8\uB2E4.
|
|
97279
|
+
\uC800\uC7A5 \uC704\uCE58: ${filePath}`, {
|
|
97280
|
+
path: filePath,
|
|
97281
|
+
filename: result2.filename,
|
|
97282
|
+
content: result2.content
|
|
97283
|
+
});
|
|
97284
|
+
}
|
|
97285
|
+
},
|
|
97286
|
+
{
|
|
97287
|
+
name: "export_profile",
|
|
97288
|
+
title: "\uD504\uB85C\uD544\uC744 \uC774\uB825\uC11C\uB85C \uB0B4\uBCF4\uB0B4\uAE30",
|
|
97289
|
+
description: '\uC800\uC7A5\uB41C \uD504\uB85C\uD544\xB7\uACBD\uB825\xB7\uD504\uB85C\uC81D\uD2B8\xB7\uBCF4\uC720 \uAE30\uC220\uC744 \uD55C \uC7A5\uC758 \uC774\uB825\uC11C \uD615\uC2DD\uC73C\uB85C \uBAA8\uC544 Markdown \uB610\uB294 \uC778\uC1C4\uC6A9 HTML(\uBE0C\uB77C\uC6B0\uC800\uC5D0\uC11C PDF\uB85C \uC800\uC7A5) \uD30C\uC77C\uB85C \uB0B4\uBCF4\uB0B4 \uB370\uC774\uD130 \uD3F4\uB354\uC758 exports\uC5D0 \uC800\uC7A5\uD558\uACE0, \uD30C\uC77C \uACBD\uB85C\uC640 \uBCF8\uBB38\uC744 \uB3CC\uB824\uC90D\uB2C8\uB2E4. \uC0AC\uC6A9\uC790\uAC00 "\uB0B4 \uD504\uB85C\uD544\uC744 \uC774\uB825\uC11C\uB85C \uBF51\uC544\uC918"\uCC98\uB7FC \uAD6C\uC870\uD654\uB41C \uB370\uC774\uD130 \uC804\uCCB4\uB97C \uC774\uB825\uC11C\uB85C \uBC1B\uACE0 \uC2F6\uC744 \uB54C \uC0AC\uC6A9\uD558\uC138\uC694. \uD2B9\uC815 \uACF5\uACE0 \uB9DE\uCDA4 \uC774\uB825\uC11C\uB294 add_resume\uB85C \uC815\uB9AC\xB7\uC800\uC7A5\uD55C \uB4A4 export_resume\uB97C \uC4F0\uC138\uC694. \uB300\uC2DC\uBCF4\uB4DC\uC5D0\uC11C \uC9C1\uC811 \uB2E4\uC6B4\uB85C\uB4DC\uD560 \uC218\uB3C4 \uC788\uC2B5\uB2C8\uB2E4.',
|
|
97290
|
+
inputSchema: {
|
|
97291
|
+
format: external_exports.enum(["md", "html"]).optional().describe("\uAE30\uBCF8 md")
|
|
97292
|
+
},
|
|
97293
|
+
handler: (args) => {
|
|
97294
|
+
const profile = profileRepo.get();
|
|
97295
|
+
if (!profile) return fail("\uD504\uB85C\uD544\uC774 \uC5C6\uC2B5\uB2C8\uB2E4. \uBA3C\uC800 \uD504\uB85C\uD544\uC744 \uC800\uC7A5\uD558\uC138\uC694.");
|
|
97296
|
+
const format = args.format ?? "md";
|
|
97297
|
+
const experiences = experienceRepo.list();
|
|
97298
|
+
const projects = projectRepo.list();
|
|
97299
|
+
const skills = skillRepo.list();
|
|
97300
|
+
const result2 = format === "html" ? profileToHtml(profile, experiences, projects, skills) : profileToMarkdown(profile, experiences, projects, skills);
|
|
97301
|
+
const dir = getExportsDir();
|
|
97302
|
+
const filePath = path7.join(dir, result2.filename);
|
|
97303
|
+
try {
|
|
97304
|
+
fs7.writeFileSync(filePath, result2.content, "utf8");
|
|
97305
|
+
} catch (e) {
|
|
97306
|
+
return fail(`\uD30C\uC77C \uC800\uC7A5 \uC2E4\uD328: ${e instanceof Error ? e.message : e}`);
|
|
97307
|
+
}
|
|
97308
|
+
return ok(`\uD504\uB85C\uD544\uC744 \uC774\uB825\uC11C(${format.toUpperCase()})\uB85C \uB0B4\uBCF4\uB0C8\uC2B5\uB2C8\uB2E4.
|
|
96440
97309
|
\uC800\uC7A5 \uC704\uCE58: ${filePath}`, {
|
|
96441
97310
|
path: filePath,
|
|
96442
97311
|
filename: result2.filename,
|
|
@@ -96488,9 +97357,17 @@ ${lines}`;
|
|
|
96488
97357
|
{
|
|
96489
97358
|
name: "get_workflow_guide",
|
|
96490
97359
|
title: "\uC6CC\uD06C\uD50C\uB85C\uC6B0 \uAC00\uC774\uB4DC",
|
|
96491
|
-
description: '\uCEE4\uB9AC\uC5B4 \uC791\uC5C5(\uACF5\uACE0 \uBD84\uC11D\xB7\uC790\uC18C\uC11C\xB7\uBA74\uC811 \uC900\uBE44 \uB4F1)\uC744 \uC2DC\uC791\uD558\uAE30 \uC9C1\uC804\uC5D0 \uD638\uCD9C\uD558\uC138\uC694. \uD45C\uC900 \uC6CC\uD06C\uD50C\uB85C\uC6B0\uC758 \uB2E8\uACC4\uBCC4 \uC548\uB0B4\uC5D0 \uB354\uD574, \uADF8 \uC791\uC5C5\uC758 "\uC804\uBB38\uAC00 \uC2E4\uD589 \uC808\uCC28(EOP)"\uC640 \uC801\uC6A9\uD560 \uC804\uBB38\uAC00 \uD50C\uB808\uC774\uBD81\xB7\uC800\uC7A5 \uC804 \uAC80\uC99D\uAE30 \uC21C\uC11C\uB97C \uD55C \uBC88\uC5D0 \uB3CC\uB824\uC90D\uB2C8\uB2E4. \uC548\uB0B4\uB41C \uB300\uB85C get_playbook\uC73C\uB85C \uB3C4\uBA54\uC778 \uC9C0\uC2DD\uC744, \uC800\uC7A5 \uC9C1\uC804 get_verifier\uB85C \uAC80\uC99D \uB8E8\uBE0C\uB9AD\uC744 \uBC1B\uC544 \uC801\uC6A9\uD558\uC138\uC694. workflow_id\uB97C \uC0DD\uB7B5\uD558\uBA74 \uC804\uCCB4 \uBAA9\uB85D\uC744 \uB3CC\uB824\uC90D\uB2C8\uB2E4.',
|
|
97360
|
+
description: '\uCEE4\uB9AC\uC5B4 \uC791\uC5C5(\uACF5\uACE0 \uBD84\uC11D\xB7\uC790\uC18C\uC11C\xB7\uACBD\uB825\uAE30\uC220\uC11C\xB7\uBA74\uC811 \uC900\uBE44 \uB4F1)\uC744 \uC2DC\uC791\uD558\uAE30 \uC9C1\uC804\uC5D0 \uD638\uCD9C\uD558\uC138\uC694. \uD45C\uC900 \uC6CC\uD06C\uD50C\uB85C\uC6B0\uC758 \uB2E8\uACC4\uBCC4 \uC548\uB0B4\uC5D0 \uB354\uD574, \uADF8 \uC791\uC5C5\uC758 "\uC804\uBB38\uAC00 \uC2E4\uD589 \uC808\uCC28(EOP)"\uC640 \uC801\uC6A9\uD560 \uC804\uBB38\uAC00 \uD50C\uB808\uC774\uBD81\xB7\uC800\uC7A5 \uC804 \uAC80\uC99D\uAE30 \uC21C\uC11C\uB97C \uD55C \uBC88\uC5D0 \uB3CC\uB824\uC90D\uB2C8\uB2E4. \uC548\uB0B4\uB41C \uB300\uB85C get_playbook\uC73C\uB85C \uB3C4\uBA54\uC778 \uC9C0\uC2DD\uC744, \uC800\uC7A5 \uC9C1\uC804 get_verifier\uB85C \uAC80\uC99D \uB8E8\uBE0C\uB9AD\uC744 \uBC1B\uC544 \uC801\uC6A9\uD558\uC138\uC694. workflow_id\uB97C \uC0DD\uB7B5\uD558\uBA74 \uC804\uCCB4 \uBAA9\uB85D\uC744 \uB3CC\uB824\uC90D\uB2C8\uB2E4.',
|
|
96492
97361
|
inputSchema: {
|
|
96493
|
-
workflow_id: external_exports.enum([
|
|
97362
|
+
workflow_id: external_exports.enum([
|
|
97363
|
+
"onboarding",
|
|
97364
|
+
"analyze_job",
|
|
97365
|
+
"write_cover_letter",
|
|
97366
|
+
"write_career_description",
|
|
97367
|
+
"manage_application_status",
|
|
97368
|
+
"prepare_interview",
|
|
97369
|
+
"build_personal_brand"
|
|
97370
|
+
]).optional()
|
|
96494
97371
|
},
|
|
96495
97372
|
readOnly: true,
|
|
96496
97373
|
handler: (args) => {
|
|
@@ -96585,38 +97462,59 @@ ${report.disclaimer}`, report);
|
|
|
96585
97462
|
{
|
|
96586
97463
|
name: "get_writing_style_guide",
|
|
96587
97464
|
title: "AI \uD2F0 \uC548 \uB098\uB294 \uAE00\uC4F0\uAE30 \uAC00\uC774\uB4DC",
|
|
96588
|
-
description: '\uC790\uAE30\uC18C\uAC1C\uC11C\xB7\uC790\uAE30 PR\xB7\uC9C0\uC6D0 \uBA54\uC77C \uB4F1 \uC0AC\uB78C\uC774 \uC4F4 \uB4EF\uD55C \uAE00\uC744 \uC791\uC131\uD558\uAE30 \uC9C1\uC804\uC5D0 \uD638\uCD9C\uD558\uC138\uC694. "AI\uAC00 \uC4F4 \uD2F0"\uAC00 \uB098\uB294 \uD55C\uAD6D\uC5B4 \uBB38\uC7A5 \uC2B5\uAD00(\uBC88\uC5ED\uD22C, \uD074\uB9AC\uC170, \uAE30\uACC4\uC801 \uBCD1\uB82C, \uC0C1\uD22C\uC801 \uC5F0\uACB0\uC5B4, \uADE0\uC77C\uD55C \uBB38\uC7A5 \uB9AC\uB4EC \uB4F1)\uC744 \uC81C\uAC70\uD558\uB294 \uC791\uC131 \uADDC\uCE59\uACFC \uC800\uC7A5 \uC804 \uC790\uAC00 \uC810\uAC80 \uD56D\uBAA9\uC744 \uB3CC\uB824\uC90D\uB2C8\uB2E4. \uC0AC\uC2E4\xB7\uC218\uCE58\xB7\uACE0\uC720\uBA85\uC0AC\uB294 \uADF8\uB300\uB85C \uB450\uACE0 \uBB38\uC7A5 \uACB0\uB9CC \uB2E4\uB4EC\uB3C4\uB85D \uC548\uB0B4\uD569\uB2C8\uB2E4. write_cover_letter / analyze_job \uC6CC\uD06C\uD50C\uB85C\uC6B0\uC5D0\uC11C \
|
|
96589
|
-
inputSchema: {
|
|
97465
|
+
description: '\uC790\uAE30\uC18C\uAC1C\uC11C\xB7\uC790\uAE30 PR\xB7\uC9C0\uC6D0 \uBA54\uC77C \uB4F1 \uC0AC\uB78C\uC774 \uC4F4 \uB4EF\uD55C \uAE00\uC744 \uC791\uC131\uD558\uAE30 \uC9C1\uC804\uC5D0 \uD638\uCD9C\uD558\uC138\uC694. "AI\uAC00 \uC4F4 \uD2F0"\uAC00 \uB098\uB294 \uD55C\uAD6D\uC5B4 \uBB38\uC7A5 \uC2B5\uAD00(\uBC88\uC5ED\uD22C, \uD074\uB9AC\uC170, \uAE30\uACC4\uC801 \uBCD1\uB82C, \uC0C1\uD22C\uC801 \uC5F0\uACB0\uC5B4, \uADE0\uC77C\uD55C \uBB38\uC7A5 \uB9AC\uB4EC \uB4F1)\uC744 \uC81C\uAC70\uD558\uB294 \uC791\uC131 \uADDC\uCE59\uACFC \uC800\uC7A5 \uC804 \uC790\uAC00 \uC810\uAC80 \uD56D\uBAA9\uC744 \uB3CC\uB824\uC90D\uB2C8\uB2E4. \uC0AC\uC2E4\xB7\uC218\uCE58\xB7\uACE0\uC720\uBA85\uC0AC\uB294 \uADF8\uB300\uB85C \uB450\uACE0 \uBB38\uC7A5 \uACB0\uB9CC \uB2E4\uB4EC\uB3C4\uB85D \uC548\uB0B4\uD569\uB2C8\uB2E4. \uACBD\uB825\uAE30\uC220\uC11C\xB7\uC774\uB825\uC11C\xB7\uD3EC\uD2B8\uD3F4\uB9AC\uC624\uB97C \uC4F8 \uB54C\uB294 doc_type\uC744 \uD568\uAED8 \uC8FC\uBA74 \uBD88\uB9BF\xB7\uBC88\uD638 \uC131\uACFC \uAC19\uC740 \uAD6C\uC870\uB97C \uC0B0\uBB38\uC73C\uB85C \uD3C9\uD0C4\uD654\uD558\uC9C0 \uC54A\uB3C4\uB85D \uAD6C\uC870 \uBCF4\uC874 \uBCF4\uC815 \uC9C0\uCE68\uC744 \uB354\uD574 \uB3CC\uB824\uC90D\uB2C8\uB2E4. write_cover_letter / write_career_description / analyze_job \uC6CC\uD06C\uD50C\uB85C\uC6B0\uC5D0\uC11C \uAE00\uC744 \uC4F8 \uB54C \uBC18\uB4DC\uC2DC \uD568\uAED8 \uC801\uC6A9\uD558\uC138\uC694.',
|
|
97466
|
+
inputSchema: {
|
|
97467
|
+
doc_type: external_exports.enum([
|
|
97468
|
+
"cover_letter",
|
|
97469
|
+
"self_pr",
|
|
97470
|
+
"application_email",
|
|
97471
|
+
"career_description",
|
|
97472
|
+
"resume",
|
|
97473
|
+
"portfolio"
|
|
97474
|
+
]).optional().describe(
|
|
97475
|
+
"\uC791\uC131\uD560 \uBB38\uC11C \uC720\uD615. career_description\xB7resume\xB7portfolio\uB294 \uBD88\uB9BF\xB7\uAD6C\uC870\uB97C \uBCF4\uC874\uD558\uB294 \uBCF4\uC815\uC744 \uB354\uD574 \uB3CC\uB824\uC90D\uB2C8\uB2E4. \uC0DD\uB7B5\uD558\uBA74 \uC790\uAE30\uC18C\uAC1C\uC11C \uB4F1 \uC0B0\uBB38\uD615 \uAE30\uC900."
|
|
97476
|
+
)
|
|
97477
|
+
},
|
|
96590
97478
|
readOnly: true,
|
|
96591
|
-
handler: () => ok("AI \uD2F0 \uC548 \uB098\uB294 \uAE00\uC4F0\uAE30 \uAC00\uC774\uB4DC\uB97C \uC801\uC6A9\uD574 \uC791\uC131\uD558\uC138\uC694.", {
|
|
97479
|
+
handler: (args) => ok("AI \uD2F0 \uC548 \uB098\uB294 \uAE00\uC4F0\uAE30 \uAC00\uC774\uB4DC\uB97C \uC801\uC6A9\uD574 \uC791\uC131\uD558\uC138\uC694.", {
|
|
97480
|
+
guide: getWritingStyleGuide(args?.doc_type)
|
|
97481
|
+
})
|
|
96592
97482
|
},
|
|
96593
97483
|
/* ----------------------------------------------------------------- update */
|
|
96594
97484
|
{
|
|
96595
97485
|
name: "check_for_update",
|
|
96596
97486
|
title: "\uC5C5\uB370\uC774\uD2B8 \uD655\uC778",
|
|
96597
|
-
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. \
|
|
97487
|
+
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.',
|
|
96598
97488
|
inputSchema: {},
|
|
96599
97489
|
readOnly: true,
|
|
96600
97490
|
handler: async () => {
|
|
96601
|
-
const u = await getUpdateStatusAsync();
|
|
97491
|
+
const u = await getUpdateStatusAsync(true);
|
|
96602
97492
|
if (u.latest === null) return ok("\uC5C5\uB370\uC774\uD2B8 \uD655\uC778\uC5D0 \uC2E4\uD328\uD588\uC2B5\uB2C8\uB2E4(\uC624\uD504\uB77C\uC778\uC774\uAC70\uB098 \uC77C\uC2DC\uC801 \uC624\uB958). \uC7A0\uC2DC \uD6C4 \uB2E4\uC2DC \uC2DC\uB3C4\uD558\uC138\uC694.", u);
|
|
97493
|
+
const user_message = u.update_available ? `\uC0C8 \uBC84\uC804 v${u.latest}\uC774 \uB098\uC654\uC5B4\uC694. \uD604\uC7AC \uBC84\uC804\uC740 v${u.current}\uC785\uB2C8\uB2E4. \uC6D0\uD558\uC2DC\uBA74 \uC9C0\uAE08 \uC5C5\uB370\uC774\uD2B8\uD560 \uC218 \uC788\uC2B5\uB2C8\uB2E4.` : `\uCD5C\uC2E0 \uBC84\uC804\uC785\uB2C8\uB2E4 (v${u.current}).`;
|
|
96603
97494
|
return ok(
|
|
96604
|
-
|
|
96605
|
-
|
|
97495
|
+
user_message,
|
|
97496
|
+
{
|
|
97497
|
+
...u,
|
|
97498
|
+
user_message,
|
|
97499
|
+
suggested_next_action: u.update_available ? {
|
|
97500
|
+
prompt: "\uC9C0\uAE08 CareerMate\uB97C \uC5C5\uB370\uC774\uD2B8\uD560\uAE4C\uC694?",
|
|
97501
|
+
next_tool: "update_careermate"
|
|
97502
|
+
} : null
|
|
97503
|
+
}
|
|
96606
97504
|
);
|
|
96607
97505
|
}
|
|
96608
97506
|
},
|
|
96609
97507
|
{
|
|
96610
97508
|
name: "update_careermate",
|
|
96611
97509
|
title: "CareerMate \uC5C5\uB370\uC774\uD2B8",
|
|
96612
|
-
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"\uB77C\uACE0 \uD560 \uB54C
|
|
97510
|
+
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.',
|
|
96613
97511
|
inputSchema: {},
|
|
96614
97512
|
handler: async () => {
|
|
96615
97513
|
const r = await runSelfUpdate();
|
|
96616
97514
|
if (!r.ok) return fail(`${r.message}${r.manual ? `
|
|
96617
97515
|
|
|
96618
97516
|
\uC9C1\uC811 \uC2E4\uD589: ${r.manual}` : ""}`);
|
|
96619
|
-
return ok(r.message, r);
|
|
97517
|
+
return ok(r.message, { ...r, user_message: r.message });
|
|
96620
97518
|
}
|
|
96621
97519
|
}
|
|
96622
97520
|
];
|
|
@@ -96627,7 +97525,7 @@ async function main() {
|
|
|
96627
97525
|
const server = new McpServer(
|
|
96628
97526
|
{ name: "careermate", version: APP_VERSION },
|
|
96629
97527
|
{
|
|
96630
|
-
instructions: "CareerMate\uB294 \uC0AC\uC6A9\uC790\uC758 \uB85C\uCEEC \uCEE4\uB9AC\uC5B4 \uB370\uC774\uD130\uBCA0\uC774\uC2A4\uC785\uB2C8\uB2E4. \uACF5\uACE0 \uBD84\uC11D
|
|
97528
|
+
instructions: "CareerMate\uB294 \uC0AC\uC6A9\uC790\uC758 \uB85C\uCEEC \uCEE4\uB9AC\uC5B4 \uB370\uC774\uD130\uBCA0\uC774\uC2A4\uC785\uB2C8\uB2E4. \uACF5\uACE0 \uBD84\uC11D, \uC790\uAE30\uC18C\uAC1C\uC11C \uC791\uC131, \uACBD\uB825\uAE30\uC220\uC11C \uC791\uC131 \uC804\uC5D0\uB294 \uD56D\uC0C1 \uC800\uC7A5\uB41C \uC0AC\uC6A9\uC790 \uC815\uBCF4\uB97C \uBA3C\uC800 \uAC00\uC838\uC624\uACE0(\uACF5\uACE0 \uC911\uC2EC \uC791\uC5C5\uC740 get_application_context \uC751\uB2F5\uC758 recommended_route\xB7next_tool\uAC00 \uB2E4\uC74C \uD638\uCD9C\uC744 \uC548\uB0B4\uD569\uB2C8\uB2E4), \uC774\uC5B4 get_workflow_guide\uB85C \uADF8 \uC791\uC5C5\uC758 \uC804\uBB38\uAC00 \uC2E4\uD589 \uC808\uCC28\uC640 \uAC80\uC99D \uC21C\uC11C\uB97C \uBC1B\uC544 \uC801\uC6A9\uD558\uC138\uC694. \uACB0\uACFC\uB294 save_fit_analysis / save_cover_letter_version / add_resume(kind=career_description) \uB4F1\uC73C\uB85C \uB2E4\uC2DC \uC800\uC7A5\uD558\uB418, \uC800\uC7A5 \uC9C1\uC804 \uC548\uB0B4\uB41C get_verifier \uB8E8\uBE0C\uB9AD\uC73C\uB85C \uB2F9\uC2E0\uC774 \uC2A4\uC2A4\uB85C \uC810\uAC80\uD558\uC138\uC694 \u2014 CareerMate\uB294 \uC140 \uC218 \uC788\uB294 \uD56D\uBAA9\uB9CC \uB3CC\uB824\uC8FC\uACE0 \uBD84\uC11D\xB7\uC791\uC131\xB7\uD310\uB2E8\uC740 \uB2F9\uC2E0(AI)\uC774 \uD569\uB2C8\uB2E4. \uBAA8\uB4E0 \uB370\uC774\uD130\uB294 \uC0AC\uC6A9\uC790 \uB85C\uCEEC\uC5D0\uB9CC \uC800\uC7A5\uB429\uB2C8\uB2E4. \uC0AC\uC6A9\uC790\uC5D0\uAC8C \uB2F5\uD560 \uB54C\uB294 \uD56D\uC0C1 \uC0AC\uC6A9\uC790\uAC00 \uC4F4 \uC5B8\uC5B4\uB85C \uB2F5\uD558\uC138\uC694 \u2014 \uC774 \uC9C0\uCE68\uACFC \uB3C4\uAD6C \uC751\uB2F5\uC774 \uD55C\uAD6D\uC5B4\uB85C \uC4F0\uC5EC \uC788\uC5B4\uB3C4 \uADF8\uB300\uB85C \uBCF5\uC0AC\uD558\uC9C0 \uB9D0\uACE0 \uC0AC\uC6A9\uC790 \uC5B8\uC5B4\uB85C \uC62E\uACA8 \uC804\uB2EC\uD558\uACE0, \uC0AC\uC2E4\xB7\uC218\uCE58\xB7\uACE0\uC720\uBA85\uC0AC\uB294 \uBCF4\uC874\uD569\uB2C8\uB2E4."
|
|
96631
97529
|
}
|
|
96632
97530
|
);
|
|
96633
97531
|
for (const tool of TOOLS) {
|
|
@@ -96656,6 +97554,18 @@ async function main() {
|
|
|
96656
97554
|
}
|
|
96657
97555
|
const transport = new StdioServerTransport();
|
|
96658
97556
|
await server.connect(transport);
|
|
97557
|
+
let closing = false;
|
|
97558
|
+
const shutdown = () => {
|
|
97559
|
+
if (closing) return;
|
|
97560
|
+
closing = true;
|
|
97561
|
+
try {
|
|
97562
|
+
closeDb();
|
|
97563
|
+
} catch {
|
|
97564
|
+
}
|
|
97565
|
+
process.exit(0);
|
|
97566
|
+
};
|
|
97567
|
+
process.once("SIGINT", shutdown);
|
|
97568
|
+
process.once("SIGTERM", shutdown);
|
|
96659
97569
|
console.error(`[careermate-mcp] \uC5F0\uACB0\uB428 \xB7 \uB3C4\uAD6C ${TOOLS.length}\uAC1C \xB7 \uB370\uC774\uD130: ${getDataDir()}`);
|
|
96660
97570
|
}
|
|
96661
97571
|
main().catch((err2) => {
|