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/doctor.mjs
CHANGED
|
@@ -6477,9 +6477,9 @@ var require_timers = __commonJS({
|
|
|
6477
6477
|
clearTimeout(this.handle);
|
|
6478
6478
|
};
|
|
6479
6479
|
var afterValue = function(value) {
|
|
6480
|
-
return
|
|
6480
|
+
return delay2(+this).thenReturn(value);
|
|
6481
6481
|
};
|
|
6482
|
-
var
|
|
6482
|
+
var delay2 = Promise2.delay = function(ms, value) {
|
|
6483
6483
|
var ret2;
|
|
6484
6484
|
var handle;
|
|
6485
6485
|
if (value !== void 0) {
|
|
@@ -6501,7 +6501,7 @@ var require_timers = __commonJS({
|
|
|
6501
6501
|
return ret2;
|
|
6502
6502
|
};
|
|
6503
6503
|
Promise2.prototype.delay = function(ms) {
|
|
6504
|
-
return
|
|
6504
|
+
return delay2(ms, this);
|
|
6505
6505
|
};
|
|
6506
6506
|
var afterTimeout = function(promise, message, parent) {
|
|
6507
6507
|
var err2;
|
|
@@ -28297,7 +28297,7 @@ var require_path_is_absolute = __commonJS({
|
|
|
28297
28297
|
var require_files = __commonJS({
|
|
28298
28298
|
"node_modules/mammoth/lib/docx/files.js"(exports2) {
|
|
28299
28299
|
"use strict";
|
|
28300
|
-
var
|
|
28300
|
+
var fs9 = __require("fs");
|
|
28301
28301
|
var url = __require("url");
|
|
28302
28302
|
var os3 = __require("os");
|
|
28303
28303
|
var dirname = __require("path").dirname;
|
|
@@ -28338,7 +28338,7 @@ var require_files = __commonJS({
|
|
|
28338
28338
|
read
|
|
28339
28339
|
};
|
|
28340
28340
|
}
|
|
28341
|
-
var readFile = promises.promisify(
|
|
28341
|
+
var readFile = promises.promisify(fs9.readFile.bind(fs9));
|
|
28342
28342
|
function uriToPath(uriString, platform) {
|
|
28343
28343
|
if (!platform) {
|
|
28344
28344
|
platform = os3.platform();
|
|
@@ -31080,11 +31080,11 @@ var require_options_reader = __commonJS({
|
|
|
31080
31080
|
var require_unzip = __commonJS({
|
|
31081
31081
|
"node_modules/mammoth/lib/unzip.js"(exports2) {
|
|
31082
31082
|
"use strict";
|
|
31083
|
-
var
|
|
31083
|
+
var fs9 = __require("fs");
|
|
31084
31084
|
var promises = require_promises();
|
|
31085
31085
|
var zipfile = require_zipfile();
|
|
31086
31086
|
exports2.openZip = openZip;
|
|
31087
|
-
var readFile = promises.promisify(
|
|
31087
|
+
var readFile = promises.promisify(fs9.readFile);
|
|
31088
31088
|
function openZip(options) {
|
|
31089
31089
|
if (options.path) {
|
|
31090
31090
|
return readFile(options.path).then(zipfile.openArrayBuffer);
|
|
@@ -31809,9 +31809,9 @@ var require_cjs = __commonJS({
|
|
|
31809
31809
|
}
|
|
31810
31810
|
return o;
|
|
31811
31811
|
}
|
|
31812
|
-
var
|
|
31812
|
+
var fs9;
|
|
31813
31813
|
function get_fs() {
|
|
31814
|
-
return
|
|
31814
|
+
return fs9 || (fs9 = require$$0__default["default"]);
|
|
31815
31815
|
}
|
|
31816
31816
|
function parse2(file, options) {
|
|
31817
31817
|
if (file[0] == 80 && file[1] == 75) return parse_zip(file, options);
|
|
@@ -32096,7 +32096,7 @@ var require_cjs = __commonJS({
|
|
|
32096
32096
|
}
|
|
32097
32097
|
function read_file(filename2, options) {
|
|
32098
32098
|
get_fs();
|
|
32099
|
-
return parse2(
|
|
32099
|
+
return parse2(fs9.readFileSync(filename2), options);
|
|
32100
32100
|
}
|
|
32101
32101
|
function read(blob, options) {
|
|
32102
32102
|
switch (options && options.type || "base64") {
|
|
@@ -32411,7 +32411,7 @@ var require_cjs = __commonJS({
|
|
|
32411
32411
|
function write_file(cfb2, filename2, options) {
|
|
32412
32412
|
get_fs();
|
|
32413
32413
|
var o = _write(cfb2, options);
|
|
32414
|
-
|
|
32414
|
+
fs9.writeFileSync(filename2, o);
|
|
32415
32415
|
}
|
|
32416
32416
|
function a2s(o) {
|
|
32417
32417
|
var out = new Array(o.length);
|
|
@@ -32423,7 +32423,7 @@ var require_cjs = __commonJS({
|
|
|
32423
32423
|
switch (options && options.type || "buffer") {
|
|
32424
32424
|
case "file":
|
|
32425
32425
|
get_fs();
|
|
32426
|
-
|
|
32426
|
+
fs9.writeFileSync(options.filename, o);
|
|
32427
32427
|
return o;
|
|
32428
32428
|
case "binary":
|
|
32429
32429
|
return typeof o == "string" ? o : a2s(o);
|
|
@@ -40116,8 +40116,8 @@ function blend(fg, bg, alpha) {
|
|
|
40116
40116
|
return Math.round(alpha * fg + (1 - alpha) * bg);
|
|
40117
40117
|
}
|
|
40118
40118
|
async function node_utils_fetchData(url) {
|
|
40119
|
-
const
|
|
40120
|
-
const data = await
|
|
40119
|
+
const fs9 = process.getBuiltinModule("fs/promises");
|
|
40120
|
+
const data = await fs9.readFile(url);
|
|
40121
40121
|
return new Uint8Array(data);
|
|
40122
40122
|
}
|
|
40123
40123
|
function initGPU() {
|
|
@@ -40746,11 +40746,11 @@ function network_getArrayBuffer(val) {
|
|
|
40746
40746
|
return typeof val !== "string" ? val : stringToBytes(val).buffer;
|
|
40747
40747
|
}
|
|
40748
40748
|
function getReadableStream(url, opts = null) {
|
|
40749
|
-
const
|
|
40749
|
+
const fs9 = process.getBuiltinModule("fs");
|
|
40750
40750
|
const {
|
|
40751
40751
|
Readable
|
|
40752
40752
|
} = process.getBuiltinModule("stream");
|
|
40753
|
-
const readStream =
|
|
40753
|
+
const readStream = fs9.createReadStream(url, opts);
|
|
40754
40754
|
return Readable.toWeb(readStream);
|
|
40755
40755
|
}
|
|
40756
40756
|
function getNetworkStream(url) {
|
|
@@ -57747,8 +57747,8 @@ fn fs_main(in : VertexOutput) -> @location(0) vec4<f32> {
|
|
|
57747
57747
|
url
|
|
57748
57748
|
} = stream._source;
|
|
57749
57749
|
this._isStreamingSupported = !disableStream;
|
|
57750
|
-
const
|
|
57751
|
-
|
|
57750
|
+
const fs9 = process.getBuiltinModule("fs/promises");
|
|
57751
|
+
fs9.lstat(url).then((stat) => {
|
|
57752
57752
|
const readableStream = getReadableStream(url);
|
|
57753
57753
|
this._reader = readableStream.getReader();
|
|
57754
57754
|
const {
|
|
@@ -59394,9 +59394,9 @@ fn fs_main(in : VertexOutput) -> @location(0) vec4<f32> {
|
|
|
59394
59394
|
return;
|
|
59395
59395
|
}
|
|
59396
59396
|
if (reason instanceof RenderingCancelledException) {
|
|
59397
|
-
let
|
|
59397
|
+
let delay2 = RENDERING_CANCELLED_TIMEOUT;
|
|
59398
59398
|
if (reason.extraDelay > 0 && reason.extraDelay < 1e3) {
|
|
59399
|
-
|
|
59399
|
+
delay2 += reason.extraDelay;
|
|
59400
59400
|
}
|
|
59401
59401
|
intentState.streamReaderCancelTimeout = setTimeout(() => {
|
|
59402
59402
|
intentState.streamReaderCancelTimeout = null;
|
|
@@ -59405,7 +59405,7 @@ fn fs_main(in : VertexOutput) -> @location(0) vec4<f32> {
|
|
|
59405
59405
|
reason,
|
|
59406
59406
|
force: true
|
|
59407
59407
|
});
|
|
59408
|
-
},
|
|
59408
|
+
}, delay2);
|
|
59409
59409
|
return;
|
|
59410
59410
|
}
|
|
59411
59411
|
}
|
|
@@ -71040,7 +71040,7 @@ fn fs_main(in : VertexOutput) -> @location(0) vec4<f32> {
|
|
|
71040
71040
|
});
|
|
71041
71041
|
|
|
71042
71042
|
// scripts/doctor.ts
|
|
71043
|
-
import
|
|
71043
|
+
import fs8 from "node:fs";
|
|
71044
71044
|
|
|
71045
71045
|
// packages/db/src/paths.ts
|
|
71046
71046
|
import os from "node:os";
|
|
@@ -71366,6 +71366,22 @@ var MIGRATIONS = [
|
|
|
71366
71366
|
|
|
71367
71367
|
COMMIT;
|
|
71368
71368
|
PRAGMA foreign_keys=ON;
|
|
71369
|
+
`,
|
|
71370
|
+
// v3 — per-job timeline entries. Document/cover-letter refs live in payload
|
|
71371
|
+
// snapshots instead of FKs so deleting a document does not erase the history.
|
|
71372
|
+
`
|
|
71373
|
+
CREATE TABLE IF NOT EXISTS application_timeline_events (
|
|
71374
|
+
id TEXT PRIMARY KEY,
|
|
71375
|
+
job_id TEXT NOT NULL REFERENCES jobs(id) ON DELETE CASCADE,
|
|
71376
|
+
type TEXT NOT NULL,
|
|
71377
|
+
title TEXT NOT NULL,
|
|
71378
|
+
summary TEXT,
|
|
71379
|
+
payload TEXT NOT NULL DEFAULT '{}',
|
|
71380
|
+
occurred_at TEXT NOT NULL,
|
|
71381
|
+
created_at TEXT NOT NULL
|
|
71382
|
+
);
|
|
71383
|
+
|
|
71384
|
+
CREATE INDEX IF NOT EXISTS idx_timeline_job ON application_timeline_events(job_id, occurred_at ASC);
|
|
71369
71385
|
`
|
|
71370
71386
|
];
|
|
71371
71387
|
function migrate(db) {
|
|
@@ -71526,6 +71542,12 @@ function assertStatusTransition(from, to) {
|
|
|
71526
71542
|
}
|
|
71527
71543
|
}
|
|
71528
71544
|
var DOCUMENT_KINDS = ["resume", "career_description", "portfolio", "other"];
|
|
71545
|
+
var DOCUMENT_KIND_LABELS = {
|
|
71546
|
+
resume: "\uC774\uB825\uC11C",
|
|
71547
|
+
career_description: "\uACBD\uB825\uAE30\uC220\uC11C",
|
|
71548
|
+
portfolio: "\uD3EC\uD2B8\uD3F4\uB9AC\uC624",
|
|
71549
|
+
other: "\uAE30\uD0C0 \uBB38\uC11C"
|
|
71550
|
+
};
|
|
71529
71551
|
var CONTENT_SOURCES = ["manual", "upload", "ai", "edit"];
|
|
71530
71552
|
var ACTIVITY_TYPES = [
|
|
71531
71553
|
"profile_updated",
|
|
@@ -71538,6 +71560,13 @@ var ACTIVITY_TYPES = [
|
|
|
71538
71560
|
"interview_prep_saved",
|
|
71539
71561
|
"document_exported"
|
|
71540
71562
|
];
|
|
71563
|
+
var APPLICATION_TIMELINE_TYPES = [
|
|
71564
|
+
"job_saved",
|
|
71565
|
+
"fit_analysis_saved",
|
|
71566
|
+
"cover_letter_version_saved",
|
|
71567
|
+
"application_status_changed",
|
|
71568
|
+
"interview_prep_saved"
|
|
71569
|
+
];
|
|
71541
71570
|
var ENTITY_TYPES = [
|
|
71542
71571
|
"profile",
|
|
71543
71572
|
"experience",
|
|
@@ -75845,11 +75874,19 @@ var ApplicationInputSchema = external_exports.object({
|
|
|
75845
75874
|
applied_at: optLine,
|
|
75846
75875
|
notes: optNote
|
|
75847
75876
|
});
|
|
75877
|
+
var ApplicationSubmissionSchema = external_exports.object({
|
|
75878
|
+
submitted_at: optLine.describe("\uC2E4\uC81C \uC81C\uCD9C\uC77C YYYY-MM-DD"),
|
|
75879
|
+
channel: optLine.describe("\uC81C\uCD9C \uCC44\uB110(\uC6D0\uD2F0\uB4DC/\uC0AC\uB78C\uC778/\uD68C\uC0AC \uCC44\uC6A9\uD398\uC774\uC9C0 \uB4F1)"),
|
|
75880
|
+
cover_letter_id: optLine,
|
|
75881
|
+
cover_letter_version_id: optLine,
|
|
75882
|
+
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")
|
|
75883
|
+
});
|
|
75848
75884
|
var ApplicationStatusUpdateSchema = external_exports.object({
|
|
75849
75885
|
job_id: optLine,
|
|
75850
75886
|
application_id: optLine,
|
|
75851
75887
|
status: external_exports.enum(APPLICATION_STATUSES),
|
|
75852
|
-
note: optNote.describe("\uC0C1\uD0DC \uBCC0\uACBD \uC0AC\uC720/\uBA54\uBAA8")
|
|
75888
|
+
note: optNote.describe("\uC0C1\uD0DC \uBCC0\uACBD \uC0AC\uC720/\uBA54\uBAA8"),
|
|
75889
|
+
submission: ApplicationSubmissionSchema.optional().describe("\uC9C0\uC6D0 \uC644\uB8CC \uAE30\uB85D\uC5D0 \uB0A8\uAE38 \uC81C\uCD9C \uC790\uB8CC \uC2A4\uB0C5\uC0F7")
|
|
75853
75890
|
});
|
|
75854
75891
|
var ApplicationRecordSchema = external_exports.object({
|
|
75855
75892
|
...baseRecord,
|
|
@@ -75867,8 +75904,10 @@ var StarGuideSchema = external_exports.object({
|
|
|
75867
75904
|
action: optNote,
|
|
75868
75905
|
result: optNote
|
|
75869
75906
|
});
|
|
75907
|
+
var INTERVIEW_CATEGORIES = ["technical", "behavioral"];
|
|
75870
75908
|
var InterviewQuestionSchema = external_exports.object({
|
|
75871
75909
|
question: external_exports.string().max(MAX_NOTE),
|
|
75910
|
+
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."),
|
|
75872
75911
|
intent: external_exports.string().max(MAX_NOTE).optional().describe("\uC9C8\uBB38 \uC758\uB3C4"),
|
|
75873
75912
|
followups: strList.optional().describe("\uC608\uC0C1 \uAF2C\uB9AC \uC9C8\uBB38"),
|
|
75874
75913
|
answer_outline: optBody.describe("\uB2F5\uBCC0 \uAC00\uC774\uB4DC/\uD575\uC2EC \uD3EC\uC778\uD2B8")
|
|
@@ -75896,6 +75935,24 @@ var ActivityRecordSchema = external_exports.object({
|
|
|
75896
75935
|
summary: external_exports.string(),
|
|
75897
75936
|
created_at: isoDateTime
|
|
75898
75937
|
});
|
|
75938
|
+
var ApplicationTimelineInputSchema = external_exports.object({
|
|
75939
|
+
job_id: reqLine,
|
|
75940
|
+
type: external_exports.enum(APPLICATION_TIMELINE_TYPES),
|
|
75941
|
+
title: reqLine,
|
|
75942
|
+
summary: optNote,
|
|
75943
|
+
payload: external_exports.record(external_exports.string(), external_exports.unknown()).optional(),
|
|
75944
|
+
occurred_at: optLine
|
|
75945
|
+
});
|
|
75946
|
+
var ApplicationTimelineRecordSchema = external_exports.object({
|
|
75947
|
+
id,
|
|
75948
|
+
job_id: external_exports.string(),
|
|
75949
|
+
type: external_exports.enum(APPLICATION_TIMELINE_TYPES),
|
|
75950
|
+
title: external_exports.string(),
|
|
75951
|
+
summary: external_exports.string().nullable(),
|
|
75952
|
+
payload: external_exports.record(external_exports.string(), external_exports.unknown()),
|
|
75953
|
+
occurred_at: isoDateTime,
|
|
75954
|
+
created_at: isoDateTime
|
|
75955
|
+
});
|
|
75899
75956
|
var OnboardingStatusSchema = external_exports.object({
|
|
75900
75957
|
completed: external_exports.boolean(),
|
|
75901
75958
|
has_profile: external_exports.boolean(),
|
|
@@ -75932,7 +75989,7 @@ var ApplicationContextSchema = external_exports.object({
|
|
|
75932
75989
|
});
|
|
75933
75990
|
|
|
75934
75991
|
// packages/shared/src/build-info.ts
|
|
75935
|
-
var APP_VERSION = true ? "0.0.
|
|
75992
|
+
var APP_VERSION = true ? "0.0.6" : "0.0.0-dev";
|
|
75936
75993
|
var BUNDLED = true;
|
|
75937
75994
|
|
|
75938
75995
|
// packages/shared/src/index.ts
|
|
@@ -76026,7 +76083,7 @@ function mapExperience(r) {
|
|
|
76026
76083
|
};
|
|
76027
76084
|
}
|
|
76028
76085
|
function expKey(company, role, start) {
|
|
76029
|
-
return [norm(company), norm(role), norm(start)].join("
|
|
76086
|
+
return [norm(company), norm(role), norm(start)].join("");
|
|
76030
76087
|
}
|
|
76031
76088
|
var experienceRepo = {
|
|
76032
76089
|
list() {
|
|
@@ -76444,6 +76501,7 @@ var coverLetterRepo = {
|
|
|
76444
76501
|
remove(id2) {
|
|
76445
76502
|
const db = getDb();
|
|
76446
76503
|
return tx(() => {
|
|
76504
|
+
db.prepare(`UPDATE applications SET cover_letter_id=NULL, updated_at=? WHERE cover_letter_id=?`).run(now(), id2);
|
|
76447
76505
|
db.prepare(`DELETE FROM cover_letter_versions WHERE cover_letter_id=?`).run(id2);
|
|
76448
76506
|
return db.prepare(`DELETE FROM cover_letters WHERE id=?`).run(id2).changes > 0;
|
|
76449
76507
|
});
|
|
@@ -76532,9 +76590,11 @@ var jobRepo = {
|
|
|
76532
76590
|
remove(id2) {
|
|
76533
76591
|
const db = getDb();
|
|
76534
76592
|
return tx(() => {
|
|
76593
|
+
db.prepare(`UPDATE cover_letters SET job_id=NULL, updated_at=? WHERE job_id=?`).run(now(), id2);
|
|
76535
76594
|
db.prepare(`DELETE FROM fit_analyses WHERE job_id=?`).run(id2);
|
|
76536
76595
|
db.prepare(`DELETE FROM applications WHERE job_id=?`).run(id2);
|
|
76537
76596
|
db.prepare(`DELETE FROM interview_preps WHERE job_id=?`).run(id2);
|
|
76597
|
+
db.prepare(`DELETE FROM application_timeline_events WHERE job_id=?`).run(id2);
|
|
76538
76598
|
return db.prepare(`DELETE FROM jobs WHERE id=?`).run(id2).changes > 0;
|
|
76539
76599
|
});
|
|
76540
76600
|
}
|
|
@@ -76647,7 +76707,7 @@ var applicationRepo = {
|
|
|
76647
76707
|
const m = { ...app, ...input };
|
|
76648
76708
|
getDb().prepare(
|
|
76649
76709
|
`UPDATE applications SET status=?,resume_id=?,cover_letter_id=?,applied_at=?,notes=?,updated_at=? WHERE id=?`
|
|
76650
|
-
).run(m.status, m.resume_id, m.cover_letter_id, m.applied_at, m.notes, now(), app.id);
|
|
76710
|
+
).run(m.status, m.resume_id ?? null, m.cover_letter_id ?? null, m.applied_at ?? null, m.notes ?? null, now(), app.id);
|
|
76651
76711
|
return this.get(app.id);
|
|
76652
76712
|
},
|
|
76653
76713
|
setStatus(jobId, status, note) {
|
|
@@ -76728,9 +76788,51 @@ var activityRepo = {
|
|
|
76728
76788
|
return getDb().prepare(`SELECT * FROM activities ORDER BY created_at DESC LIMIT ?`).all(limit);
|
|
76729
76789
|
}
|
|
76730
76790
|
};
|
|
76791
|
+
function mapTimelineEvent(r) {
|
|
76792
|
+
return {
|
|
76793
|
+
id: r.id,
|
|
76794
|
+
job_id: r.job_id,
|
|
76795
|
+
type: r.type,
|
|
76796
|
+
title: r.title,
|
|
76797
|
+
summary: r.summary,
|
|
76798
|
+
payload: fromJson(r.payload, {}),
|
|
76799
|
+
occurred_at: r.occurred_at,
|
|
76800
|
+
created_at: r.created_at
|
|
76801
|
+
};
|
|
76802
|
+
}
|
|
76803
|
+
var timelineRepo = {
|
|
76804
|
+
add(input) {
|
|
76805
|
+
const ts = now();
|
|
76806
|
+
const id2 = newId("tl_");
|
|
76807
|
+
getDb().prepare(
|
|
76808
|
+
`INSERT INTO application_timeline_events (id,job_id,type,title,summary,payload,occurred_at,created_at)
|
|
76809
|
+
VALUES (?,?,?,?,?,?,?,?)`
|
|
76810
|
+
).run(
|
|
76811
|
+
id2,
|
|
76812
|
+
input.job_id,
|
|
76813
|
+
input.type,
|
|
76814
|
+
input.title,
|
|
76815
|
+
input.summary ?? null,
|
|
76816
|
+
toJson(input.payload ?? {}),
|
|
76817
|
+
input.occurred_at ?? ts,
|
|
76818
|
+
ts
|
|
76819
|
+
);
|
|
76820
|
+
return this.get(id2);
|
|
76821
|
+
},
|
|
76822
|
+
get(id2) {
|
|
76823
|
+
const r = getDb().prepare(`SELECT * FROM application_timeline_events WHERE id=?`).get(id2);
|
|
76824
|
+
return r ? mapTimelineEvent(r) : null;
|
|
76825
|
+
},
|
|
76826
|
+
listByJob(jobId) {
|
|
76827
|
+
return getDb().prepare(`SELECT * FROM application_timeline_events WHERE job_id=? ORDER BY occurred_at ASC, created_at ASC`).all(jobId).map(mapTimelineEvent);
|
|
76828
|
+
},
|
|
76829
|
+
remove(id2) {
|
|
76830
|
+
return getDb().prepare(`DELETE FROM application_timeline_events WHERE id=?`).run(id2).changes > 0;
|
|
76831
|
+
}
|
|
76832
|
+
};
|
|
76731
76833
|
|
|
76732
76834
|
// packages/mcp-tools/src/tools.ts
|
|
76733
|
-
import
|
|
76835
|
+
import fs7 from "node:fs";
|
|
76734
76836
|
import path7 from "node:path";
|
|
76735
76837
|
|
|
76736
76838
|
// packages/core/src/onboarding.ts
|
|
@@ -76754,12 +76856,13 @@ function profileCompleteness(p) {
|
|
|
76754
76856
|
function getOnboardingStatus() {
|
|
76755
76857
|
const profile = profileRepo.get();
|
|
76756
76858
|
const resumes = documentRepo.list("resume");
|
|
76859
|
+
const careerDescriptions = documentRepo.list("career_description");
|
|
76757
76860
|
const coverLetters = coverLetterRepo.list();
|
|
76758
76861
|
const experiences = experienceRepo.list();
|
|
76759
76862
|
const skills = skillRepo.list();
|
|
76760
76863
|
const jobs = jobRepo.list();
|
|
76761
76864
|
const has_profile = !!(profile && profile.name);
|
|
76762
|
-
const has_resume = resumes.length > 0;
|
|
76865
|
+
const has_resume = resumes.length > 0 || careerDescriptions.length > 0;
|
|
76763
76866
|
const has_cover_letter = coverLetters.length > 0;
|
|
76764
76867
|
const has_experience = experiences.length > 0;
|
|
76765
76868
|
const has_skills = skills.length > 0;
|
|
@@ -77172,6 +77275,29 @@ function batchNames(names) {
|
|
|
77172
77275
|
if (!shown) return "";
|
|
77173
77276
|
return `: ${shown}${names.length > 8 ? " \uC678" : ""}`;
|
|
77174
77277
|
}
|
|
77278
|
+
function coverLetterTimelineRef(coverLetter, version2, requestedVersionId) {
|
|
77279
|
+
const resolvedVersion = version2 ?? coverLetter.versions?.find((v) => v.id === requestedVersionId || v.id === coverLetter.current_version_id) ?? null;
|
|
77280
|
+
return {
|
|
77281
|
+
kind: "cover_letter",
|
|
77282
|
+
id: coverLetter.id,
|
|
77283
|
+
title: coverLetter.title,
|
|
77284
|
+
version_id: resolvedVersion?.id ?? requestedVersionId ?? coverLetter.current_version_id,
|
|
77285
|
+
version_no: resolvedVersion?.version_no ?? coverLetter.version_count
|
|
77286
|
+
};
|
|
77287
|
+
}
|
|
77288
|
+
function documentTimelineRef(doc) {
|
|
77289
|
+
return {
|
|
77290
|
+
kind: "document",
|
|
77291
|
+
id: doc.id,
|
|
77292
|
+
title: doc.title,
|
|
77293
|
+
document_kind: doc.kind
|
|
77294
|
+
};
|
|
77295
|
+
}
|
|
77296
|
+
function submittedAtToOccurrence(value) {
|
|
77297
|
+
if (!value) return void 0;
|
|
77298
|
+
if (/^\d{4}-\d{2}-\d{2}$/.test(value)) return `${value}T00:00:00.000Z`;
|
|
77299
|
+
return void 0;
|
|
77300
|
+
}
|
|
77175
77301
|
function addExperiences(inputs) {
|
|
77176
77302
|
const res = experienceRepo.addMany(inputs);
|
|
77177
77303
|
activityRepo.log(
|
|
@@ -77210,11 +77336,22 @@ function saveJobPosting(input, id2) {
|
|
|
77210
77336
|
}
|
|
77211
77337
|
function saveFitAnalysis(input) {
|
|
77212
77338
|
const job = jobRepo.get(input.job_id);
|
|
77213
|
-
if (!job) throw notFound(
|
|
77339
|
+
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.");
|
|
77214
77340
|
applicationRepo.ensure(job.id, "draft");
|
|
77215
77341
|
const fit = fitRepo.save(input);
|
|
77216
77342
|
const scoreText = fit.score != null ? ` (\uC801\uD569\uB3C4 ${fit.score}\uC810)` : "";
|
|
77217
77343
|
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);
|
|
77344
|
+
timelineRepo.add({
|
|
77345
|
+
job_id: job.id,
|
|
77346
|
+
type: "fit_analysis_saved",
|
|
77347
|
+
title: "\uC801\uD569\uB3C4 \uBD84\uC11D",
|
|
77348
|
+
summary: fit.score != null ? `\uC885\uD569 ${fit.score}\uC810` : fit.summary ?? void 0,
|
|
77349
|
+
payload: {
|
|
77350
|
+
fit_id: fit.id,
|
|
77351
|
+
score: fit.score
|
|
77352
|
+
},
|
|
77353
|
+
occurred_at: fit.updated_at
|
|
77354
|
+
});
|
|
77218
77355
|
return fit;
|
|
77219
77356
|
}
|
|
77220
77357
|
function saveCoverLetterVersion(input) {
|
|
@@ -77248,35 +77385,88 @@ function saveCoverLetterVersion(input) {
|
|
|
77248
77385
|
"cover_letter",
|
|
77249
77386
|
coverLetter.id
|
|
77250
77387
|
);
|
|
77388
|
+
if (coverLetter.job_id) {
|
|
77389
|
+
timelineRepo.add({
|
|
77390
|
+
job_id: coverLetter.job_id,
|
|
77391
|
+
type: "cover_letter_version_saved",
|
|
77392
|
+
title: "\uC790\uAE30\uC18C\uAC1C\uC11C \uC791\uC131",
|
|
77393
|
+
summary: `${coverLetter.title} v${version2.version_no}`,
|
|
77394
|
+
payload: {
|
|
77395
|
+
cover_letter: coverLetterTimelineRef(coverLetter, version2)
|
|
77396
|
+
},
|
|
77397
|
+
occurred_at: version2.created_at
|
|
77398
|
+
});
|
|
77399
|
+
}
|
|
77251
77400
|
return { coverLetter, version: version2, verification, forced };
|
|
77252
77401
|
}
|
|
77253
|
-
function updateApplicationStatus(jobId, status, note) {
|
|
77402
|
+
function updateApplicationStatus(jobId, status, note, submission) {
|
|
77254
77403
|
const job = jobRepo.get(jobId);
|
|
77255
|
-
if (!job) throw notFound(
|
|
77256
|
-
const
|
|
77257
|
-
|
|
77258
|
-
|
|
77259
|
-
|
|
77260
|
-
|
|
77261
|
-
|
|
77262
|
-
|
|
77404
|
+
if (!job) throw notFound("\uACF5\uACE0\uB97C \uCC3E\uC744 \uC218 \uC5C6\uC2B5\uB2C8\uB2E4.");
|
|
77405
|
+
const before2 = applicationRepo.getByJob(jobId);
|
|
77406
|
+
const application = tx(() => {
|
|
77407
|
+
let application2 = applicationRepo.setStatus(jobId, status, note);
|
|
77408
|
+
const submittedDocs = (submission?.document_ids ?? []).map((docId) => documentRepo.get(docId)).filter((doc) => !!doc);
|
|
77409
|
+
const submittedCoverLetter = submission?.cover_letter_id ? coverLetterRepo.get(submission.cover_letter_id, true) : null;
|
|
77410
|
+
if (status === "applied" && submission) {
|
|
77411
|
+
const resumeLike = submittedDocs.find((doc) => doc.kind === "resume" || doc.kind === "career_description") ?? submittedDocs[0] ?? null;
|
|
77412
|
+
application2 = applicationRepo.upsert({
|
|
77413
|
+
job_id: jobId,
|
|
77414
|
+
resume_id: resumeLike?.id ?? application2.resume_id ?? void 0,
|
|
77415
|
+
cover_letter_id: submittedCoverLetter?.id ?? application2.cover_letter_id ?? void 0,
|
|
77416
|
+
applied_at: submission.submitted_at ?? application2.applied_at ?? void 0
|
|
77417
|
+
});
|
|
77418
|
+
}
|
|
77419
|
+
activityRepo.log(
|
|
77420
|
+
"application_status_changed",
|
|
77421
|
+
`${job.company} \xB7 ${job.position} \uC0C1\uD0DC\uB97C '${APPLICATION_STATUS_LABELS[status]}'(\uC73C)\uB85C \uBCC0\uACBD\uD588\uC2B5\uB2C8\uB2E4.`,
|
|
77422
|
+
"application",
|
|
77423
|
+
application2.id
|
|
77424
|
+
);
|
|
77425
|
+
const submittedAt = submission?.submitted_at?.trim();
|
|
77426
|
+
const channel = submission?.channel?.trim();
|
|
77427
|
+
const submissionPayload = submission && (submittedAt || channel || submittedCoverLetter || submittedDocs.length > 0) ? {
|
|
77428
|
+
submitted_at: submittedAt || null,
|
|
77429
|
+
channel: channel || null,
|
|
77430
|
+
cover_letter: submittedCoverLetter ? coverLetterTimelineRef(submittedCoverLetter, null, submission.cover_letter_version_id) : null,
|
|
77431
|
+
documents: submittedDocs.map(documentTimelineRef)
|
|
77432
|
+
} : null;
|
|
77433
|
+
timelineRepo.add({
|
|
77434
|
+
job_id: job.id,
|
|
77435
|
+
type: "application_status_changed",
|
|
77436
|
+
title: APPLICATION_STATUS_LABELS[status],
|
|
77437
|
+
summary: channel && status === "applied" ? `${channel}\uB85C \uC81C\uCD9C` : note ?? void 0,
|
|
77438
|
+
payload: {
|
|
77439
|
+
from_status: before2?.status ?? null,
|
|
77440
|
+
status,
|
|
77441
|
+
status_label: APPLICATION_STATUS_LABELS[status],
|
|
77442
|
+
note: note ?? null,
|
|
77443
|
+
submission: submissionPayload
|
|
77444
|
+
},
|
|
77445
|
+
occurred_at: submittedAtToOccurrence(submittedAt)
|
|
77446
|
+
});
|
|
77447
|
+
return application2;
|
|
77448
|
+
});
|
|
77263
77449
|
const interview_unlocked = INTERVIEW_UNLOCK_STATUSES.includes(status);
|
|
77264
77450
|
const hasPrep = !!interviewRepo.getByJob(jobId);
|
|
77265
|
-
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?
|
|
77451
|
+
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;
|
|
77266
77452
|
return { application, job, interview_unlocked, hint };
|
|
77267
77453
|
}
|
|
77268
77454
|
function saveInterviewPrep(input) {
|
|
77269
77455
|
const job = jobRepo.get(input.job_id);
|
|
77270
|
-
if (!job) throw notFound(
|
|
77271
|
-
const app = applicationRepo.getByJob(job.id);
|
|
77272
|
-
if (!app || !INTERVIEW_UNLOCK_STATUSES.includes(app.status)) {
|
|
77273
|
-
const current = app ? APPLICATION_STATUS_LABELS[app.status] : "\uBBF8\uC9C0\uC6D0";
|
|
77274
|
-
throw conflict(
|
|
77275
|
-
`\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.`
|
|
77276
|
-
);
|
|
77277
|
-
}
|
|
77456
|
+
if (!job) throw notFound("\uACF5\uACE0\uB97C \uCC3E\uC744 \uC218 \uC5C6\uC2B5\uB2C8\uB2E4.");
|
|
77278
77457
|
const prep = interviewRepo.save(input);
|
|
77279
77458
|
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);
|
|
77459
|
+
timelineRepo.add({
|
|
77460
|
+
job_id: job.id,
|
|
77461
|
+
type: "interview_prep_saved",
|
|
77462
|
+
title: "\uBA74\uC811 \uC900\uBE44",
|
|
77463
|
+
summary: prep.questions.length > 0 ? `\uC608\uC0C1 \uC9C8\uBB38 ${prep.questions.length}\uAC1C` : prep.notes ?? void 0,
|
|
77464
|
+
payload: {
|
|
77465
|
+
interview_prep_id: prep.id,
|
|
77466
|
+
question_count: prep.questions.length
|
|
77467
|
+
},
|
|
77468
|
+
occurred_at: prep.updated_at
|
|
77469
|
+
});
|
|
77280
77470
|
return prep;
|
|
77281
77471
|
}
|
|
77282
77472
|
|
|
@@ -77297,6 +77487,8 @@ var HUMANIZE_WRITING_GUIDE = `# \uC0AC\uB78C\uC774 \uC4F4 \uAC83\uCC98\uB7FC: \u
|
|
|
77297
77487
|
\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.
|
|
77298
77488
|
\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.
|
|
77299
77489
|
|
|
77490
|
+
> **\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.
|
|
77491
|
+
|
|
77300
77492
|
## \uC808\uB300 \uC6D0\uCE59
|
|
77301
77493
|
- \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.
|
|
77302
77494
|
- \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.
|
|
@@ -77338,6 +77530,33 @@ var HUMANIZE_WRITING_GUIDE = `# \uC0AC\uB78C\uC774 \uC4F4 \uAC83\uCC98\uB7FC: \u
|
|
|
77338
77530
|
- \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.
|
|
77339
77531
|
- \uC0AC\uC2E4\xB7\uC218\uCE58\xB7\uACE0\uC720\uBA85\uC0AC\uAC00 \uC6D0\uBCF8\uACFC 100% \uC77C\uCE58\uD558\uB294\uAC00?
|
|
77340
77532
|
- \uC0AC\uC6A9\uC790\uC758 \uD1A4\uACFC \uAC15\uC870 \uD3EC\uC778\uD2B8\uAC00 \uC0B4\uC544 \uC788\uB294\uAC00?`;
|
|
77533
|
+
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
|
|
77534
|
+
|
|
77535
|
+
\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.
|
|
77536
|
+
|
|
77537
|
+
## \uC704 8\uAC1C AI-tell \uC911 \uAD6C\uC870\uD615\uC5D0\uC11C \uB2E4\uB974\uAC8C \uC801\uC6A9\uD558\uB294 \uAC83
|
|
77538
|
+
- 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.
|
|
77539
|
+
- \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.
|
|
77540
|
+
|
|
77541
|
+
## \uAD6C\uC870\uB294 \uC0B4\uB9AC\uACE0, \uBD88\uB9BF '\uC548\uC758 \uC5B8\uC5B4'\uB9CC \uC0AC\uB78C\uB2F5\uAC8C
|
|
77542
|
+
- \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.
|
|
77543
|
+
- \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)
|
|
77544
|
+
- 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.
|
|
77545
|
+
|
|
77546
|
+
## Do / Don't
|
|
77547
|
+
- 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.
|
|
77548
|
+
- 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.
|
|
77549
|
+
|
|
77550
|
+
\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.`;
|
|
77551
|
+
var STRUCTURED_DOC_TYPES = /* @__PURE__ */ new Set(["career_description", "resume", "portfolio"]);
|
|
77552
|
+
function getWritingStyleGuide(docType) {
|
|
77553
|
+
if (docType && STRUCTURED_DOC_TYPES.has(docType)) {
|
|
77554
|
+
return `${HUMANIZE_WRITING_GUIDE}
|
|
77555
|
+
|
|
77556
|
+
${STRUCTURED_DOC_WRITING_GUIDE}`;
|
|
77557
|
+
}
|
|
77558
|
+
return HUMANIZE_WRITING_GUIDE;
|
|
77559
|
+
}
|
|
77341
77560
|
|
|
77342
77561
|
// packages/workflows/src/definitions.ts
|
|
77343
77562
|
var WORKFLOWS = [
|
|
@@ -77348,7 +77567,7 @@ var WORKFLOWS = [
|
|
|
77348
77567
|
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.',
|
|
77349
77568
|
steps: [
|
|
77350
77569
|
"`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.",
|
|
77351
|
-
'\uBE44\uC5B4 \uC788\uB294 \uD56D\uBAA9\uC744 \uC0AC\uC6A9\uC790\
|
|
77570
|
+
'\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).',
|
|
77352
77571
|
'\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.)',
|
|
77353
77572
|
"\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.",
|
|
77354
77573
|
"\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).",
|
|
@@ -77369,9 +77588,9 @@ var WORKFLOWS = [
|
|
|
77369
77588
|
"\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.",
|
|
77370
77589
|
"\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.",
|
|
77371
77590
|
"\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).",
|
|
77372
|
-
"\uBD84\uC11D \uACB0\uACFC\uB97C \uC0AC\uC6A9\uC790\
|
|
77373
|
-
'"\uC774 \uACF5\uACE0\uC5D0 \uB9DE\uCD98 \uC790\uAE30\uC18C\uAC1C\uC11C\uB97C \uC368\uB4DC\uB9B4\uAE4C\uC694?"\uB77C\uACE0 \uC790\uAE30\uC18C\uAC1C\uC11C \
|
|
77374
|
-
'\uC0AC\uC6A9\uC790\uAC00 \
|
|
77591
|
+
"\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.",
|
|
77592
|
+
'\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".',
|
|
77593
|
+
'\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.',
|
|
77375
77594
|
"\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).",
|
|
77376
77595
|
"`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."
|
|
77377
77596
|
]
|
|
@@ -77388,7 +77607,24 @@ var WORKFLOWS = [
|
|
|
77388
77607
|
"\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.",
|
|
77389
77608
|
"\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).",
|
|
77390
77609
|
"\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.",
|
|
77391
|
-
"\uC800\uC7A5 \uACB0\uACFC\uB97C \
|
|
77610
|
+
"\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."
|
|
77611
|
+
]
|
|
77612
|
+
},
|
|
77613
|
+
{
|
|
77614
|
+
id: "write_career_description",
|
|
77615
|
+
title: "\uACBD\uB825\uAE30\uC220\uC11C \uC791\uC131",
|
|
77616
|
+
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.",
|
|
77617
|
+
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.',
|
|
77618
|
+
steps: [
|
|
77619
|
+
"`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.",
|
|
77620
|
+
"\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.",
|
|
77621
|
+
'`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.',
|
|
77622
|
+
"\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.",
|
|
77623
|
+
"\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.",
|
|
77624
|
+
'\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.',
|
|
77625
|
+
'\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.',
|
|
77626
|
+
"\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.",
|
|
77627
|
+
"\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."
|
|
77392
77628
|
]
|
|
77393
77629
|
},
|
|
77394
77630
|
{
|
|
@@ -77399,7 +77635,7 @@ var WORKFLOWS = [
|
|
|
77399
77635
|
steps: [
|
|
77400
77636
|
"\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.",
|
|
77401
77637
|
"\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.",
|
|
77402
|
-
"\uBCC0\uACBD \uACB0\uACFC\uB97C \uC0AC\uC6A9\uC790\
|
|
77638
|
+
"\uBCC0\uACBD \uACB0\uACFC\uB97C \uC0AC\uC6A9\uC790\uC758 \uC5B8\uC5B4\uB85C \uC27D\uAC8C \uC54C\uB9B0\uB2E4.",
|
|
77403
77639
|
"\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.",
|
|
77404
77640
|
"\uD544\uC694\uD558\uBA74 `open_application`\uC73C\uB85C \uD574\uB2F9 \uC9C0\uC6D0 \uAC74\uC744 \uC5F4\uC5B4 \uBCF4\uC5EC\uC900\uB2E4."
|
|
77405
77641
|
]
|
|
@@ -77407,14 +77643,29 @@ var WORKFLOWS = [
|
|
|
77407
77643
|
{
|
|
77408
77644
|
id: "prepare_interview",
|
|
77409
77645
|
title: "\uBA74\uC811 \uC900\uBE44",
|
|
77410
|
-
description: "\
|
|
77411
|
-
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
|
|
77646
|
+
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.",
|
|
77647
|
+
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.',
|
|
77412
77648
|
steps: [
|
|
77413
77649
|
"`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.",
|
|
77414
77650
|
"\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.",
|
|
77415
77651
|
"\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.",
|
|
77416
77652
|
"\uC900\uBE44 \uB0B4\uC6A9\uC744 `save_interview_prep`\uB85C \uC800\uC7A5\uD55C\uB2E4(job_id, questions, star_guides, self_introduction, notes).",
|
|
77417
|
-
"\uC900\uBE44 \uB0B4\uC6A9\uC744 \uC0AC\uC6A9\uC790\
|
|
77653
|
+
"\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."
|
|
77654
|
+
]
|
|
77655
|
+
},
|
|
77656
|
+
{
|
|
77657
|
+
id: "build_personal_brand",
|
|
77658
|
+
title: "\uD37C\uC2A4\uB110 \uBE0C\uB79C\uB4DC (LinkedIn\xB7\uD3EC\uD2B8\uD3F4\uB9AC\uC624)",
|
|
77659
|
+
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.",
|
|
77660
|
+
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.',
|
|
77661
|
+
steps: [
|
|
77662
|
+
"`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.",
|
|
77663
|
+
'`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.',
|
|
77664
|
+
"\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.",
|
|
77665
|
+
"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.",
|
|
77666
|
+
'\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.',
|
|
77667
|
+
"\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.",
|
|
77668
|
+
"\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."
|
|
77418
77669
|
]
|
|
77419
77670
|
}
|
|
77420
77671
|
];
|
|
@@ -77498,7 +77749,7 @@ var CAREER_ROUTES = {
|
|
|
77498
77749
|
verifierSequence: ["truthfulness", "consistency"]
|
|
77499
77750
|
},
|
|
77500
77751
|
analyze_job: {
|
|
77501
|
-
eop: "job-analysis",
|
|
77752
|
+
eop: ["job-analysis", "fit-analysis"],
|
|
77502
77753
|
expertSequence: ["fit-matching", "company-research"],
|
|
77503
77754
|
verifierSequence: ["truthfulness", "consistency", "responsiveness-on-target"],
|
|
77504
77755
|
loop: "draft_verify_revise"
|
|
@@ -77509,11 +77760,46 @@ var CAREER_ROUTES = {
|
|
|
77509
77760
|
verifierSequence: ["human-voice", "truthfulness", "ats-compat", "consistency"],
|
|
77510
77761
|
loop: "draft_verify_revise"
|
|
77511
77762
|
},
|
|
77763
|
+
write_career_description: {
|
|
77764
|
+
eop: "career-description",
|
|
77765
|
+
expertSequence: ["resume", "ats"],
|
|
77766
|
+
verifierSequence: ["truthfulness", "consistency", "ats-compat"],
|
|
77767
|
+
loop: "draft_verify_revise"
|
|
77768
|
+
},
|
|
77512
77769
|
prepare_interview: {
|
|
77513
77770
|
eop: "interview-prep",
|
|
77514
|
-
expertSequence: ["interview-behavioral", "interview-technical", "company-research"],
|
|
77771
|
+
expertSequence: ["recruiter-screen", "interview-behavioral", "interview-technical", "company-research"],
|
|
77515
77772
|
verifierSequence: ["truthfulness", "consistency"],
|
|
77516
77773
|
loop: "draft_verify_revise"
|
|
77774
|
+
},
|
|
77775
|
+
// R7 A2: manage_application_status had no route → rejection-triage / offer-evaluation /
|
|
77776
|
+
// salary-negotiation were orphaned (served only on-demand via get_playbook). Route the
|
|
77777
|
+
// decision-stage playbooks so they are pushed when the user manages application outcomes.
|
|
77778
|
+
// R7 A4: A2 routed the decision-stage playbooks, but the EOP-free lifecycle domains
|
|
77779
|
+
// onboarding-first-90-days and networking-referrals were still on-demand-only. Anchor them
|
|
77780
|
+
// here (the only EOP-free lifecycle route). NOTE: networking's strongest lever is *before*
|
|
77781
|
+
// applied (pre-referral, networking-referrals §2) — this route is the surfacing point, not
|
|
77782
|
+
// the recommended timing, so surface networking early when the user is pre-application.
|
|
77783
|
+
// linkedin-profile/portfolio stay on-demand pending a dedicated personal-brand workflow id
|
|
77784
|
+
// (FIXES.md / STATUS §7.9 follow-up — onboarding EOP is résumé-import-only, so brand-
|
|
77785
|
+
// creation playbooks would blur its stage meaning). Additive wiring (A1/A2 precedent).
|
|
77786
|
+
manage_application_status: {
|
|
77787
|
+
expertSequence: [
|
|
77788
|
+
"rejection-triage-iteration",
|
|
77789
|
+
"offer-evaluation-decision",
|
|
77790
|
+
"salary-negotiation",
|
|
77791
|
+
"onboarding-first-90-days",
|
|
77792
|
+
"networking-referrals"
|
|
77793
|
+
],
|
|
77794
|
+
verifierSequence: ["truthfulness", "consistency"]
|
|
77795
|
+
},
|
|
77796
|
+
// R7 후속: linkedin-profile·portfolio는 onboarding(이력서 임포트)과 단계 의미가
|
|
77797
|
+
// 달라(개인 브랜드 자산 *생성*) 전용 워크플로우로 분리(consensus 권고). networking은
|
|
77798
|
+
// manage_application_status에 이미 정박. 저장은 add_resume(kind=portfolio); linkedin
|
|
77799
|
+
// 전용 저장/검증은 Phase B.
|
|
77800
|
+
build_personal_brand: {
|
|
77801
|
+
expertSequence: ["linkedin-profile", "portfolio"],
|
|
77802
|
+
verifierSequence: ["truthfulness", "human-voice", "consistency"]
|
|
77517
77803
|
}
|
|
77518
77804
|
};
|
|
77519
77805
|
function getRoute(id2) {
|
|
@@ -77523,12 +77809,15 @@ function renderRouteGuide(id2) {
|
|
|
77523
77809
|
const route = CAREER_ROUTES[id2];
|
|
77524
77810
|
if (!route) return void 0;
|
|
77525
77811
|
const lines = [];
|
|
77526
|
-
|
|
77812
|
+
const eops = route.eop ? Array.isArray(route.eop) ? route.eop : [route.eop] : [];
|
|
77813
|
+
if (eops.length) {
|
|
77527
77814
|
lines.push("---", "");
|
|
77528
77815
|
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");
|
|
77529
77816
|
lines.push("");
|
|
77530
|
-
|
|
77531
|
-
|
|
77817
|
+
for (const e of eops) {
|
|
77818
|
+
lines.push(getEop(e));
|
|
77819
|
+
lines.push("");
|
|
77820
|
+
}
|
|
77532
77821
|
}
|
|
77533
77822
|
lines.push("## \uC774 \uC791\uC5C5\uC5D0 \uC801\uC6A9\uD560 \uC804\uBB38\uAC00 \uD50C\uB808\uC774\uBD81");
|
|
77534
77823
|
lines.push("\uC791\uC131 \uC9C1\uC804, \uC544\uB798 \uB3C4\uBA54\uC778\uC758 \uAE4A\uC740 \uC9C0\uC2DD\uC744 \uBC1B\uC544 \uC801\uC6A9\uD558\uC138\uC694:");
|
|
@@ -77642,10 +77931,22 @@ function slugify(input, fallback = "document") {
|
|
|
77642
77931
|
function joinBlocks(blocks) {
|
|
77643
77932
|
return blocks.filter((b) => typeof b === "string" && b.trim().length > 0).join("\n\n");
|
|
77644
77933
|
}
|
|
77934
|
+
function bulletList(items) {
|
|
77935
|
+
const lines = items.filter((i2) => typeof i2 === "string" && i2.trim().length > 0).map((i2) => `- ${i2.trim()}`);
|
|
77936
|
+
return lines.join("\n");
|
|
77937
|
+
}
|
|
77645
77938
|
function kv(label, value) {
|
|
77646
77939
|
if (!value || !value.trim()) return "";
|
|
77647
77940
|
return `**${label}**: ${value.trim()}`;
|
|
77648
77941
|
}
|
|
77942
|
+
function dateRange(start, end, current = false) {
|
|
77943
|
+
const s = (start ?? "").trim();
|
|
77944
|
+
const e = current ? "\uD604\uC7AC" : (end ?? "").trim();
|
|
77945
|
+
if (!s && !e) return "";
|
|
77946
|
+
if (!s) return e;
|
|
77947
|
+
if (!e) return s;
|
|
77948
|
+
return `${s} ~ ${e}`;
|
|
77949
|
+
}
|
|
77649
77950
|
function renderInline(escaped) {
|
|
77650
77951
|
let out = escaped;
|
|
77651
77952
|
out = out.replace(/\*\*([^*]+)\*\*/g, "<strong>$1</strong>");
|
|
@@ -77754,6 +78055,123 @@ function coverLetterToHtml(cl, opts) {
|
|
|
77754
78055
|
content: toPrintableHtml(cl.title, coverLetterBody(cl, opts))
|
|
77755
78056
|
};
|
|
77756
78057
|
}
|
|
78058
|
+
function resumeToMarkdown(doc, profile) {
|
|
78059
|
+
const kindLabel = DOCUMENT_KIND_LABELS[doc.kind] ?? doc.kind;
|
|
78060
|
+
const header = [];
|
|
78061
|
+
if (profile?.name) header.push(kv("\uC774\uB984", profile.name));
|
|
78062
|
+
if (profile?.email) header.push(kv("\uC774\uBA54\uC77C", profile.email));
|
|
78063
|
+
if (profile?.phone) header.push(kv("\uC5F0\uB77D\uCC98", profile.phone));
|
|
78064
|
+
const body = joinBlocks([
|
|
78065
|
+
`# ${doc.title}`,
|
|
78066
|
+
`_${kindLabel}_`,
|
|
78067
|
+
header.length ? header.filter(Boolean).join("\n\n") : "",
|
|
78068
|
+
header.length ? "---" : "",
|
|
78069
|
+
(doc.content ?? "").trim() || "_(\uB0B4\uC6A9 \uC5C6\uC74C)_"
|
|
78070
|
+
]);
|
|
78071
|
+
return {
|
|
78072
|
+
filename: `${slugify(doc.title, doc.kind)}.md`,
|
|
78073
|
+
mimeType: MD_MIME,
|
|
78074
|
+
content: body
|
|
78075
|
+
};
|
|
78076
|
+
}
|
|
78077
|
+
function resumeToHtml(doc, profile) {
|
|
78078
|
+
const md = resumeToMarkdown(doc, profile);
|
|
78079
|
+
return {
|
|
78080
|
+
filename: `${slugify(doc.title, doc.kind)}.html`,
|
|
78081
|
+
mimeType: HTML_MIME,
|
|
78082
|
+
content: toPrintableHtml(doc.title, md.content)
|
|
78083
|
+
};
|
|
78084
|
+
}
|
|
78085
|
+
function profileToMarkdown(profile, experiences = [], projects = [], skills = []) {
|
|
78086
|
+
const name = profile.name?.trim() || "\uC774\uB825\uC11C";
|
|
78087
|
+
const contact = [];
|
|
78088
|
+
if (profile.email) contact.push(profile.email);
|
|
78089
|
+
if (profile.phone) contact.push(profile.phone);
|
|
78090
|
+
if (profile.location) contact.push(profile.location);
|
|
78091
|
+
const links = (profile.links ?? []).filter((l2) => l2.url).map((l2) => `[${l2.label || l2.url}](${l2.url})`);
|
|
78092
|
+
const headerBlocks = joinBlocks([
|
|
78093
|
+
`# ${name}`,
|
|
78094
|
+
profile.headline ? `## ${profile.headline}` : "",
|
|
78095
|
+
contact.length ? contact.join(" \xB7 ") : "",
|
|
78096
|
+
links.length ? links.join(" \xB7 ") : ""
|
|
78097
|
+
]);
|
|
78098
|
+
const summaryBlock = profile.summary?.trim() ? joinBlocks(["## \uC18C\uAC1C", profile.summary.trim()]) : "";
|
|
78099
|
+
const desiredLines = [];
|
|
78100
|
+
if (profile.desired_roles?.length) {
|
|
78101
|
+
desiredLines.push(kv("\uD76C\uB9DD \uC9C1\uBB34", profile.desired_roles.join(", ")));
|
|
78102
|
+
}
|
|
78103
|
+
if (profile.desired_conditions?.trim()) {
|
|
78104
|
+
desiredLines.push(kv("\uD76C\uB9DD \uC870\uAC74", profile.desired_conditions));
|
|
78105
|
+
}
|
|
78106
|
+
const desiredBlock = desiredLines.length ? joinBlocks(["## \uD76C\uB9DD \uC0AC\uD56D", desiredLines.filter(Boolean).join("\n\n")]) : "";
|
|
78107
|
+
const expBlocks = experiences.length ? joinBlocks([
|
|
78108
|
+
"## \uACBD\uB825",
|
|
78109
|
+
...experiences.map((e) => {
|
|
78110
|
+
const range2 = dateRange(e.start_date, e.end_date, e.is_current);
|
|
78111
|
+
const titleParts = [e.company, e.role].filter(Boolean).join(" \u2014 ");
|
|
78112
|
+
const subParts = [e.employment_type, range2].filter(Boolean).join(" \xB7 ");
|
|
78113
|
+
return joinBlocks([
|
|
78114
|
+
`### ${titleParts}`,
|
|
78115
|
+
subParts ? `_${subParts}_` : "",
|
|
78116
|
+
e.description?.trim() ? e.description.trim() : "",
|
|
78117
|
+
e.achievements?.length ? bulletList(e.achievements) : "",
|
|
78118
|
+
e.tech?.length ? kv("\uAE30\uC220", e.tech.join(", ")) : ""
|
|
78119
|
+
]);
|
|
78120
|
+
})
|
|
78121
|
+
]) : "";
|
|
78122
|
+
const projBlocks = projects.length ? joinBlocks([
|
|
78123
|
+
"## \uD504\uB85C\uC81D\uD2B8",
|
|
78124
|
+
...projects.map((p) => {
|
|
78125
|
+
const range2 = dateRange(p.start_date, p.end_date);
|
|
78126
|
+
const subParts = [p.role, range2].filter(Boolean).join(" \xB7 ");
|
|
78127
|
+
return joinBlocks([
|
|
78128
|
+
`### ${p.name}`,
|
|
78129
|
+
subParts ? `_${subParts}_` : "",
|
|
78130
|
+
p.description?.trim() ? p.description.trim() : "",
|
|
78131
|
+
p.highlights?.length ? bulletList(p.highlights) : "",
|
|
78132
|
+
p.tech?.length ? kv("\uAE30\uC220", p.tech.join(", ")) : "",
|
|
78133
|
+
p.url ? kv("\uB9C1\uD06C", p.url) : ""
|
|
78134
|
+
]);
|
|
78135
|
+
})
|
|
78136
|
+
]) : "";
|
|
78137
|
+
let skillsBlock = "";
|
|
78138
|
+
if (skills.length) {
|
|
78139
|
+
const groups = /* @__PURE__ */ new Map();
|
|
78140
|
+
for (const s of skills) {
|
|
78141
|
+
const cat = s.category?.trim() || "\uAE30\uD0C0";
|
|
78142
|
+
const label = s.level?.trim() ? `${s.name} (${s.level.trim()})` : s.name;
|
|
78143
|
+
if (!groups.has(cat)) groups.set(cat, []);
|
|
78144
|
+
groups.get(cat).push(label);
|
|
78145
|
+
}
|
|
78146
|
+
const lines = [...groups.entries()].map(
|
|
78147
|
+
([cat, items]) => kv(cat, items.join(", "))
|
|
78148
|
+
);
|
|
78149
|
+
skillsBlock = joinBlocks(["## \uBCF4\uC720 \uAE30\uC220", lines.filter(Boolean).join("\n\n")]);
|
|
78150
|
+
}
|
|
78151
|
+
const content = joinBlocks([
|
|
78152
|
+
headerBlocks,
|
|
78153
|
+
"---",
|
|
78154
|
+
summaryBlock,
|
|
78155
|
+
desiredBlock,
|
|
78156
|
+
expBlocks,
|
|
78157
|
+
projBlocks,
|
|
78158
|
+
skillsBlock
|
|
78159
|
+
]);
|
|
78160
|
+
return {
|
|
78161
|
+
filename: `${slugify(name, "resume")}-resume.md`,
|
|
78162
|
+
mimeType: MD_MIME,
|
|
78163
|
+
content
|
|
78164
|
+
};
|
|
78165
|
+
}
|
|
78166
|
+
function profileToHtml(profile, experiences = [], projects = [], skills = []) {
|
|
78167
|
+
const md = profileToMarkdown(profile, experiences, projects, skills);
|
|
78168
|
+
const title = profile.name?.trim() || "\uC774\uB825\uC11C";
|
|
78169
|
+
return {
|
|
78170
|
+
filename: `${slugify(title, "resume")}-resume.html`,
|
|
78171
|
+
mimeType: HTML_MIME,
|
|
78172
|
+
content: toPrintableHtml(title, md.content)
|
|
78173
|
+
};
|
|
78174
|
+
}
|
|
77757
78175
|
|
|
77758
78176
|
// packages/parsers/src/html.ts
|
|
77759
78177
|
var NAMED_ENTITIES = {
|
|
@@ -78314,7 +78732,12 @@ async function extractDocument(input, baseDir) {
|
|
|
78314
78732
|
path: filePath,
|
|
78315
78733
|
...over
|
|
78316
78734
|
});
|
|
78317
|
-
|
|
78735
|
+
let realPath = filePath;
|
|
78736
|
+
try {
|
|
78737
|
+
realPath = fs4.realpathSync.native(filePath);
|
|
78738
|
+
} catch {
|
|
78739
|
+
}
|
|
78740
|
+
if (SENSITIVE_PATH_RE.test(filePath) || SENSITIVE_PATH_RE.test(realPath)) {
|
|
78318
78741
|
return base("unsupported", {
|
|
78319
78742
|
warnings: [
|
|
78320
78743
|
"\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."
|
|
@@ -78639,14 +79062,94 @@ function fail(text) {
|
|
|
78639
79062
|
}
|
|
78640
79063
|
|
|
78641
79064
|
// packages/mcp-tools/src/bridge.ts
|
|
78642
|
-
import { spawn } from "node:child_process";
|
|
79065
|
+
import { spawn, spawnSync } from "node:child_process";
|
|
79066
|
+
import fs5 from "node:fs";
|
|
78643
79067
|
import path5 from "node:path";
|
|
78644
79068
|
import { fileURLToPath as fileURLToPath2 } from "node:url";
|
|
78645
79069
|
var __dirname = path5.dirname(fileURLToPath2(import.meta.url));
|
|
78646
79070
|
var REPO_ROOT = path5.resolve(__dirname, "..", "..", "..");
|
|
78647
|
-
|
|
79071
|
+
var HEALTH_TIMEOUT_MS = 800;
|
|
79072
|
+
var pendingStart = null;
|
|
79073
|
+
function dashboardLogPath() {
|
|
79074
|
+
return path5.join(getDataDir(), "server.log");
|
|
79075
|
+
}
|
|
79076
|
+
function launchdPlistPath() {
|
|
79077
|
+
return path5.join(getDataDir(), "dashboard.launchd.plist");
|
|
79078
|
+
}
|
|
79079
|
+
function launchdLabel() {
|
|
79080
|
+
let hash = 5381;
|
|
79081
|
+
for (const ch of getDataDir()) hash = (hash * 33 ^ ch.charCodeAt(0)) >>> 0;
|
|
79082
|
+
return `life.careermate.dashboard.${hash.toString(16)}`;
|
|
79083
|
+
}
|
|
79084
|
+
function xmlEscape(value) {
|
|
79085
|
+
return value.replace(/&/g, "&").replace(/</g, "<").replace(/>/g, ">").replace(/"/g, """).replace(/'/g, "'");
|
|
79086
|
+
}
|
|
79087
|
+
function plistString(key, value) {
|
|
79088
|
+
return ` <key>${xmlEscape(key)}</key>
|
|
79089
|
+
<string>${xmlEscape(value)}</string>`;
|
|
79090
|
+
}
|
|
79091
|
+
function renderLaunchdPlist(bin, args, cwd, log) {
|
|
79092
|
+
const env2 = {
|
|
79093
|
+
CAREERMATE_DATA_DIR: getDataDir(),
|
|
79094
|
+
CAREERMATE_NO_OPEN: "1"
|
|
79095
|
+
};
|
|
79096
|
+
if (process.env.CAREERMATE_PORT) env2.CAREERMATE_PORT = process.env.CAREERMATE_PORT;
|
|
79097
|
+
if (process.env.PATH) env2.PATH = process.env.PATH;
|
|
79098
|
+
const programArgs = [bin, ...args].map((arg) => ` <string>${xmlEscape(arg)}</string>`).join("\n");
|
|
79099
|
+
const envEntries = Object.entries(env2).map(([key, value]) => `${plistString(key, value)}`).join("\n");
|
|
79100
|
+
return `<?xml version="1.0" encoding="UTF-8"?>
|
|
79101
|
+
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
|
79102
|
+
<plist version="1.0">
|
|
79103
|
+
<dict>
|
|
79104
|
+
<key>Label</key>
|
|
79105
|
+
<string>${xmlEscape(launchdLabel())}</string>
|
|
79106
|
+
<key>ProgramArguments</key>
|
|
79107
|
+
<array>
|
|
79108
|
+
${programArgs}
|
|
79109
|
+
</array>
|
|
79110
|
+
<key>WorkingDirectory</key>
|
|
79111
|
+
<string>${xmlEscape(cwd)}</string>
|
|
79112
|
+
<key>EnvironmentVariables</key>
|
|
79113
|
+
<dict>
|
|
79114
|
+
${envEntries}
|
|
79115
|
+
</dict>
|
|
79116
|
+
<key>RunAtLoad</key>
|
|
79117
|
+
<true/>
|
|
79118
|
+
<key>KeepAlive</key>
|
|
79119
|
+
<false/>
|
|
79120
|
+
<key>StandardOutPath</key>
|
|
79121
|
+
<string>${xmlEscape(log)}</string>
|
|
79122
|
+
<key>StandardErrorPath</key>
|
|
79123
|
+
<string>${xmlEscape(log)}</string>
|
|
79124
|
+
</dict>
|
|
79125
|
+
</plist>
|
|
79126
|
+
`;
|
|
79127
|
+
}
|
|
79128
|
+
function delay(ms) {
|
|
79129
|
+
return new Promise((resolve) => setTimeout(resolve, ms));
|
|
79130
|
+
}
|
|
79131
|
+
async function pingDashboard(url, timeoutMs = HEALTH_TIMEOUT_MS) {
|
|
79132
|
+
const controller = new AbortController();
|
|
79133
|
+
const timer = setTimeout(() => controller.abort(), timeoutMs);
|
|
79134
|
+
timer.unref?.();
|
|
79135
|
+
try {
|
|
79136
|
+
const healthUrl = new URL("/api/health", url);
|
|
79137
|
+
const res = await fetch(healthUrl, {
|
|
79138
|
+
signal: controller.signal,
|
|
79139
|
+
headers: { accept: "application/json" }
|
|
79140
|
+
});
|
|
79141
|
+
if (!res.ok) return false;
|
|
79142
|
+
const body = await res.json().catch(() => null);
|
|
79143
|
+
return body?.ok === true;
|
|
79144
|
+
} catch {
|
|
79145
|
+
return false;
|
|
79146
|
+
} finally {
|
|
79147
|
+
clearTimeout(timer);
|
|
79148
|
+
}
|
|
79149
|
+
}
|
|
79150
|
+
async function liveServer() {
|
|
78648
79151
|
const info3 = readRuntimeInfo();
|
|
78649
|
-
if (info3 && isProcessAlive(info3.pid)) return info3;
|
|
79152
|
+
if (info3 && isProcessAlive(info3.pid) && await pingDashboard(info3.url)) return info3;
|
|
78650
79153
|
return null;
|
|
78651
79154
|
}
|
|
78652
79155
|
function spawnDetached(cmd, args, opts = {}) {
|
|
@@ -78655,19 +79158,101 @@ function spawnDetached(cmd, args, opts = {}) {
|
|
|
78655
79158
|
child.on("error", () => {
|
|
78656
79159
|
});
|
|
78657
79160
|
child.unref();
|
|
79161
|
+
return child.pid ?? null;
|
|
78658
79162
|
} catch {
|
|
79163
|
+
return null;
|
|
79164
|
+
}
|
|
79165
|
+
}
|
|
79166
|
+
function spawnViaLaunchd(bin, args, cwd, log) {
|
|
79167
|
+
if (process.platform !== "darwin" || process.env.CAREERMATE_LAUNCHER === "detached") return false;
|
|
79168
|
+
if (typeof process.getuid !== "function") return false;
|
|
79169
|
+
const domain = `gui/${process.getuid()}`;
|
|
79170
|
+
const label = launchdLabel();
|
|
79171
|
+
const plist = launchdPlistPath();
|
|
79172
|
+
try {
|
|
79173
|
+
fs5.writeFileSync(plist, renderLaunchdPlist(bin, args, cwd, log), "utf8");
|
|
79174
|
+
spawnSync("launchctl", ["bootout", `${domain}/${label}`], { stdio: "ignore" });
|
|
79175
|
+
const res = spawnSync("launchctl", ["bootstrap", domain, plist], {
|
|
79176
|
+
encoding: "utf8",
|
|
79177
|
+
timeout: 5e3
|
|
79178
|
+
});
|
|
79179
|
+
if (res.status === 0) return true;
|
|
79180
|
+
fs5.appendFileSync(log, `[${(/* @__PURE__ */ new Date()).toISOString()}] launchctl bootstrap failed: ${res.stderr || res.stdout || res.status}
|
|
79181
|
+
`);
|
|
79182
|
+
} catch (e) {
|
|
79183
|
+
try {
|
|
79184
|
+
fs5.appendFileSync(log, `[${(/* @__PURE__ */ new Date()).toISOString()}] launchctl launch failed: ${e instanceof Error ? e.message : String(e)}
|
|
79185
|
+
`);
|
|
79186
|
+
} catch {
|
|
79187
|
+
}
|
|
78659
79188
|
}
|
|
79189
|
+
return false;
|
|
79190
|
+
}
|
|
79191
|
+
function spawnDashboardDetached(bin, args, cwd, logFd) {
|
|
79192
|
+
spawnDetached(bin, args, {
|
|
79193
|
+
cwd,
|
|
79194
|
+
env: { ...process.env, CAREERMATE_NO_OPEN: "1" },
|
|
79195
|
+
stdio: logFd === null ? "ignore" : ["ignore", logFd, logFd]
|
|
79196
|
+
});
|
|
78660
79197
|
}
|
|
78661
79198
|
async function ensureServer(timeoutMs = 12e3) {
|
|
78662
|
-
const existing = liveServer();
|
|
79199
|
+
const existing = await liveServer();
|
|
78663
79200
|
if (existing) return { url: existing.url };
|
|
78664
|
-
|
|
78665
|
-
|
|
79201
|
+
if (pendingStart) return pendingStart;
|
|
79202
|
+
pendingStart = startServerBackground(timeoutMs);
|
|
79203
|
+
try {
|
|
79204
|
+
return await pendingStart;
|
|
79205
|
+
} finally {
|
|
79206
|
+
pendingStart = null;
|
|
79207
|
+
}
|
|
79208
|
+
}
|
|
79209
|
+
async function startServerBackground(timeoutMs) {
|
|
79210
|
+
const [bin, args, cwd] = BUNDLED ? [process.execPath, ["--experimental-sqlite", path5.join(__dirname, "web.mjs")], __dirname] : [
|
|
79211
|
+
process.execPath,
|
|
79212
|
+
["--no-warnings", "--experimental-sqlite", "--import", "tsx", path5.join(REPO_ROOT, "apps/web/src/index.ts")],
|
|
79213
|
+
REPO_ROOT
|
|
79214
|
+
];
|
|
79215
|
+
const log = dashboardLogPath();
|
|
79216
|
+
let logFd = null;
|
|
79217
|
+
try {
|
|
79218
|
+
logFd = fs5.openSync(log, "a");
|
|
79219
|
+
fs5.writeSync(logFd, `
|
|
79220
|
+
[${(/* @__PURE__ */ new Date()).toISOString()}] CareerMate dashboard background launch
|
|
79221
|
+
`);
|
|
79222
|
+
} catch {
|
|
79223
|
+
logFd = null;
|
|
79224
|
+
}
|
|
79225
|
+
let launchedViaLaunchd = false;
|
|
79226
|
+
try {
|
|
79227
|
+
launchedViaLaunchd = spawnViaLaunchd(bin, args, cwd, log);
|
|
79228
|
+
if (!launchedViaLaunchd) spawnDashboardDetached(bin, args, cwd, logFd);
|
|
79229
|
+
} finally {
|
|
79230
|
+
if (logFd !== null) {
|
|
79231
|
+
try {
|
|
79232
|
+
fs5.closeSync(logFd);
|
|
79233
|
+
} catch {
|
|
79234
|
+
}
|
|
79235
|
+
}
|
|
79236
|
+
}
|
|
78666
79237
|
const start = Date.now();
|
|
78667
79238
|
while (Date.now() - start < timeoutMs) {
|
|
78668
|
-
const info3 = liveServer();
|
|
79239
|
+
const info3 = await liveServer();
|
|
78669
79240
|
if (info3) return { url: info3.url };
|
|
78670
|
-
await
|
|
79241
|
+
await delay(300);
|
|
79242
|
+
}
|
|
79243
|
+
if (launchedViaLaunchd) {
|
|
79244
|
+
try {
|
|
79245
|
+
fs5.appendFileSync(log, `[${(/* @__PURE__ */ new Date()).toISOString()}] launchd did not produce a healthy server; falling back to detached spawn
|
|
79246
|
+
`);
|
|
79247
|
+
} catch {
|
|
79248
|
+
}
|
|
79249
|
+
spawnDashboardDetached(bin, args, cwd, null);
|
|
79250
|
+
const fallbackStart = Date.now();
|
|
79251
|
+
while (Date.now() - fallbackStart < Math.min(timeoutMs, 8e3)) {
|
|
79252
|
+
const info3 = await liveServer();
|
|
79253
|
+
if (info3) return { url: info3.url };
|
|
79254
|
+
await delay(300);
|
|
79255
|
+
}
|
|
78671
79256
|
}
|
|
78672
79257
|
return null;
|
|
78673
79258
|
}
|
|
@@ -78691,7 +79276,7 @@ function openInFileManager(dir) {
|
|
|
78691
79276
|
else openOsTarget(dir);
|
|
78692
79277
|
}
|
|
78693
79278
|
async function resolveDashboardUrl(hash = "") {
|
|
78694
|
-
const live = liveServer();
|
|
79279
|
+
const live = await liveServer();
|
|
78695
79280
|
if (live) return { url: live.url + hash, running: true };
|
|
78696
79281
|
const started = await ensureServer();
|
|
78697
79282
|
if (started) return { url: started.url + hash, running: true };
|
|
@@ -78699,7 +79284,7 @@ async function resolveDashboardUrl(hash = "") {
|
|
|
78699
79284
|
}
|
|
78700
79285
|
|
|
78701
79286
|
// packages/mcp-tools/src/update.ts
|
|
78702
|
-
import
|
|
79287
|
+
import fs6 from "node:fs";
|
|
78703
79288
|
import path6 from "node:path";
|
|
78704
79289
|
import { fileURLToPath as fileURLToPath3 } from "node:url";
|
|
78705
79290
|
import { spawn as spawn2 } from "node:child_process";
|
|
@@ -78756,14 +79341,14 @@ function comparePrerelease(a, b) {
|
|
|
78756
79341
|
}
|
|
78757
79342
|
function readCache() {
|
|
78758
79343
|
try {
|
|
78759
|
-
return JSON.parse(
|
|
79344
|
+
return JSON.parse(fs6.readFileSync(cacheFile(), "utf8"));
|
|
78760
79345
|
} catch {
|
|
78761
79346
|
return null;
|
|
78762
79347
|
}
|
|
78763
79348
|
}
|
|
78764
79349
|
function writeCache(c) {
|
|
78765
79350
|
try {
|
|
78766
|
-
|
|
79351
|
+
fs6.writeFileSync(cacheFile(), JSON.stringify(c), "utf8");
|
|
78767
79352
|
} catch {
|
|
78768
79353
|
}
|
|
78769
79354
|
}
|
|
@@ -78822,14 +79407,20 @@ function getUpdateStatus() {
|
|
|
78822
79407
|
if (cacheExpired(cache2)) refreshInBackground();
|
|
78823
79408
|
return buildStatus(cache2);
|
|
78824
79409
|
}
|
|
78825
|
-
async function getUpdateStatusAsync() {
|
|
79410
|
+
async function getUpdateStatusAsync(force = false) {
|
|
78826
79411
|
if (checkDisabled()) return buildStatus(null);
|
|
78827
|
-
|
|
78828
|
-
if (cacheExpired(cache2))
|
|
78829
|
-
|
|
78830
|
-
|
|
78831
|
-
|
|
78832
|
-
|
|
79412
|
+
const cache2 = readCache();
|
|
79413
|
+
if (!force && !cacheExpired(cache2)) return buildStatus(cache2);
|
|
79414
|
+
const latest = await fetchLatest();
|
|
79415
|
+
if (latest !== null) {
|
|
79416
|
+
const fresh = { checkedAt: Date.now(), latest };
|
|
79417
|
+
writeCache(fresh);
|
|
79418
|
+
return buildStatus(fresh);
|
|
79419
|
+
}
|
|
79420
|
+
if (force) return buildStatus(null);
|
|
79421
|
+
const failed = { checkedAt: Date.now(), latest: null };
|
|
79422
|
+
writeCache(failed);
|
|
79423
|
+
return buildStatus(failed);
|
|
78833
79424
|
}
|
|
78834
79425
|
function killTree(child) {
|
|
78835
79426
|
if (process.platform === "win32" && child.pid) {
|
|
@@ -78887,12 +79478,8 @@ async function runSelfUpdate() {
|
|
|
78887
79478
|
manual: manualCommand()
|
|
78888
79479
|
};
|
|
78889
79480
|
}
|
|
78890
|
-
|
|
78891
|
-
if (
|
|
78892
|
-
cache2 = { checkedAt: Date.now(), latest: await fetchLatest() };
|
|
78893
|
-
writeCache(cache2);
|
|
78894
|
-
}
|
|
78895
|
-
const latest = cache2?.latest ?? null;
|
|
79481
|
+
const latest = await fetchLatest();
|
|
79482
|
+
if (latest !== null) writeCache({ checkedAt: Date.now(), latest });
|
|
78896
79483
|
if (latest === null) {
|
|
78897
79484
|
return {
|
|
78898
79485
|
ok: false,
|
|
@@ -78920,26 +79507,38 @@ async function runSelfUpdate() {
|
|
|
78920
79507
|
ok: true,
|
|
78921
79508
|
from,
|
|
78922
79509
|
to: latest,
|
|
78923
|
-
message: `
|
|
79510
|
+
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.`
|
|
78924
79511
|
};
|
|
78925
79512
|
}
|
|
78926
79513
|
|
|
78927
79514
|
// packages/mcp-tools/src/tools.ts
|
|
78928
79515
|
var STATUS_LIST = APPLICATION_STATUSES.map((s) => `${s}(${APPLICATION_STATUS_LABELS[s]})`).join(", ");
|
|
79516
|
+
var DELETE_CONFIRMATION = "DELETE";
|
|
79517
|
+
var DASHBOARD_URL = "http://127.0.0.1:4319";
|
|
78929
79518
|
function listInboxFiles(dir) {
|
|
78930
79519
|
let names;
|
|
78931
79520
|
try {
|
|
78932
|
-
names =
|
|
79521
|
+
names = fs7.readdirSync(dir);
|
|
78933
79522
|
} catch {
|
|
78934
79523
|
return [];
|
|
78935
79524
|
}
|
|
79525
|
+
let realDir;
|
|
79526
|
+
try {
|
|
79527
|
+
realDir = fs7.realpathSync.native(dir);
|
|
79528
|
+
} catch {
|
|
79529
|
+
realDir = dir;
|
|
79530
|
+
}
|
|
78936
79531
|
const SKIP = /^[.~]|^(thumbs\.db|desktop\.ini)$/i;
|
|
78937
79532
|
const out = [];
|
|
78938
79533
|
for (const name of names) {
|
|
78939
79534
|
if (SKIP.test(name)) continue;
|
|
78940
79535
|
const p = path7.join(dir, name);
|
|
78941
79536
|
try {
|
|
78942
|
-
if (
|
|
79537
|
+
if (!fs7.statSync(p).isFile()) continue;
|
|
79538
|
+
const real = fs7.realpathSync.native(p);
|
|
79539
|
+
const rel = path7.relative(realDir, real);
|
|
79540
|
+
if (rel.startsWith("..") || path7.isAbsolute(rel)) continue;
|
|
79541
|
+
out.push({ name, path: p });
|
|
78943
79542
|
} catch {
|
|
78944
79543
|
}
|
|
78945
79544
|
}
|
|
@@ -79009,8 +79608,8 @@ ${r.warnings.join("\n")}`, {
|
|
|
79009
79608
|
/* --------------------------------------------------------- inbox (파일 인입) */
|
|
79010
79609
|
{
|
|
79011
79610
|
name: "open_inbox",
|
|
79012
|
-
title: "\
|
|
79013
|
-
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 \
|
|
79611
|
+
title: "\uBB38\uC11C \uC778\uC785 \uD3F4\uB354 \uC5F4\uAE30",
|
|
79612
|
+
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.',
|
|
79014
79613
|
inputSchema: {},
|
|
79015
79614
|
handler: () => {
|
|
79016
79615
|
const dir = getInboxDir();
|
|
@@ -79018,10 +79617,10 @@ ${r.warnings.join("\n")}`, {
|
|
|
79018
79617
|
const files = listInboxFiles(dir);
|
|
79019
79618
|
const list = files.length ? files.map((f) => `- ${f.name}`).join("\n") : "(\uC544\uC9C1 \uBE44\uC5B4 \uC788\uC74C)";
|
|
79020
79619
|
return ok(
|
|
79021
|
-
`\
|
|
79620
|
+
`\uBB38\uC11C \uC778\uC785 \uD3F4\uB354\uB97C \uC5F4\uC5C8\uC2B5\uB2C8\uB2E4:
|
|
79022
79621
|
${dir}
|
|
79023
79622
|
|
|
79024
|
-
\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.)
|
|
79623
|
+
\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.)
|
|
79025
79624
|
|
|
79026
79625
|
\uD604\uC7AC \uD30C\uC77C:
|
|
79027
79626
|
${list}`,
|
|
@@ -79032,7 +79631,7 @@ ${list}`,
|
|
|
79032
79631
|
{
|
|
79033
79632
|
name: "read_inbox",
|
|
79034
79633
|
title: "\uC778\uC785 \uD3F4\uB354 \uD30C\uC77C \uC77D\uAE30",
|
|
79035
|
-
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\
|
|
79634
|
+
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.',
|
|
79036
79635
|
inputSchema: {
|
|
79037
79636
|
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."),
|
|
79038
79637
|
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")
|
|
@@ -79073,7 +79672,7 @@ ${dir}
|
|
|
79073
79672
|
`\uC778\uC785 \uD3F4\uB354 \uD30C\uC77C ${files.length}\uAC74\uC744 \uC77D\uC5C8\uC2B5\uB2C8\uB2E4:
|
|
79074
79673
|
${summary}
|
|
79075
79674
|
|
|
79076
|
-
\uCD94\uCD9C\uB41C \uB0B4\uC6A9\uC744 \uAD6C\uC870\uD654\uD574 save_profile\
|
|
79675
|
+
\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.`,
|
|
79077
79676
|
{ dir, files }
|
|
79078
79677
|
);
|
|
79079
79678
|
}
|
|
@@ -79102,9 +79701,17 @@ ${lines}`;
|
|
|
79102
79701
|
if (upd.update_available) {
|
|
79103
79702
|
text += `
|
|
79104
79703
|
|
|
79105
|
-
\
|
|
79106
|
-
}
|
|
79107
|
-
return ok(text, {
|
|
79704
|
+
\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.`;
|
|
79705
|
+
}
|
|
79706
|
+
return ok(text, {
|
|
79707
|
+
...s,
|
|
79708
|
+
verify_strict: strict,
|
|
79709
|
+
update: upd,
|
|
79710
|
+
suggested_next_action: upd.update_available ? {
|
|
79711
|
+
prompt: `\uC0C8 \uBC84\uC804 v${upd.latest}\uC774 \uB098\uC654\uC2B5\uB2C8\uB2E4. \uC9C0\uAE08 \uC5C5\uB370\uC774\uD2B8\uD560\uAE4C\uC694?`,
|
|
79712
|
+
next_tool: "update_careermate"
|
|
79713
|
+
} : null
|
|
79714
|
+
});
|
|
79108
79715
|
}
|
|
79109
79716
|
},
|
|
79110
79717
|
/* --------------------------------------------------------------- profile */
|
|
@@ -79133,7 +79740,7 @@ ${lines}`;
|
|
|
79133
79740
|
{
|
|
79134
79741
|
name: "add_resume",
|
|
79135
79742
|
title: "\uC774\uB825\uC11C/\uACBD\uB825\uAE30\uC220\uC11C \uCD94\uAC00",
|
|
79136
|
-
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
|
|
79743
|
+
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.",
|
|
79137
79744
|
// Reuse the shared (length-bounded, whitespace-rejecting) Document schema so
|
|
79138
79745
|
// the MCP ingestion path — the primary route for résumé text — inherits the
|
|
79139
79746
|
// same caps as the web API. kind stays optional here (defaults to resume).
|
|
@@ -79157,6 +79764,23 @@ ${lines}`;
|
|
|
79157
79764
|
return ok(`\uBB38\uC11C ${docs.length}\uAC74`, docs);
|
|
79158
79765
|
}
|
|
79159
79766
|
},
|
|
79767
|
+
{
|
|
79768
|
+
name: "delete_resume",
|
|
79769
|
+
title: "\uC774\uB825\uC11C/\uBB38\uC11C \uC0AD\uC81C",
|
|
79770
|
+
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.",
|
|
79771
|
+
inputSchema: {
|
|
79772
|
+
document_id: external_exports.string(),
|
|
79773
|
+
confirm: external_exports.string().describe("\uC0AD\uC81C \uD655\uC778\uAC12. \uC815\uD655\uD788 DELETE\uB97C \uB123\uC5B4\uC57C \uC0AD\uC81C\uB429\uB2C8\uB2E4.")
|
|
79774
|
+
},
|
|
79775
|
+
handler: (args) => {
|
|
79776
|
+
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.");
|
|
79777
|
+
const doc = documentRepo.get(args.document_id);
|
|
79778
|
+
if (!doc) return fail("\uBB38\uC11C\uB97C \uCC3E\uC744 \uC218 \uC5C6\uC2B5\uB2C8\uB2E4.");
|
|
79779
|
+
if (!documentRepo.remove(doc.id)) return fail("\uBB38\uC11C\uB97C \uC0AD\uC81C\uD558\uC9C0 \uBABB\uD588\uC2B5\uB2C8\uB2E4.");
|
|
79780
|
+
const user_message = `'${doc.title}' \uBB38\uC11C\uB97C \uC0AD\uC81C\uD588\uC5B4\uC694.`;
|
|
79781
|
+
return ok(user_message, { deleted: true, document_id: doc.id, user_message });
|
|
79782
|
+
}
|
|
79783
|
+
},
|
|
79160
79784
|
/* ----------------------------------------------------------- experiences */
|
|
79161
79785
|
{
|
|
79162
79786
|
name: "add_experience",
|
|
@@ -79226,6 +79850,57 @@ ${lines}`;
|
|
|
79226
79850
|
return ok(`\uAE30\uC220 ${list.length}\uAC74`, list);
|
|
79227
79851
|
}
|
|
79228
79852
|
},
|
|
79853
|
+
{
|
|
79854
|
+
name: "delete_experience",
|
|
79855
|
+
title: "\uACBD\uB825 \uD56D\uBAA9 \uC0AD\uC81C",
|
|
79856
|
+
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.",
|
|
79857
|
+
inputSchema: {
|
|
79858
|
+
experience_id: external_exports.string(),
|
|
79859
|
+
confirm: external_exports.string().describe("\uC0AD\uC81C \uD655\uC778\uAC12. \uC815\uD655\uD788 DELETE\uB97C \uB123\uC5B4\uC57C \uC0AD\uC81C\uB429\uB2C8\uB2E4.")
|
|
79860
|
+
},
|
|
79861
|
+
handler: (args) => {
|
|
79862
|
+
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.");
|
|
79863
|
+
const exp = experienceRepo.get(args.experience_id);
|
|
79864
|
+
if (!exp) return fail("\uD574\uB2F9 \uACBD\uB825 \uD56D\uBAA9\uC744 \uCC3E\uC744 \uC218 \uC5C6\uC2B5\uB2C8\uB2E4.");
|
|
79865
|
+
if (!experienceRepo.remove(exp.id)) return fail("\uACBD\uB825 \uD56D\uBAA9\uC744 \uC0AD\uC81C\uD558\uC9C0 \uBABB\uD588\uC2B5\uB2C8\uB2E4.");
|
|
79866
|
+
const user_message = `'${exp.company}' \uACBD\uB825\uC744 \uC0AD\uC81C\uD588\uC5B4\uC694.`;
|
|
79867
|
+
return ok(user_message, { deleted: true, experience_id: exp.id, user_message });
|
|
79868
|
+
}
|
|
79869
|
+
},
|
|
79870
|
+
{
|
|
79871
|
+
name: "delete_project",
|
|
79872
|
+
title: "\uD504\uB85C\uC81D\uD2B8 \uD56D\uBAA9 \uC0AD\uC81C",
|
|
79873
|
+
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.",
|
|
79874
|
+
inputSchema: {
|
|
79875
|
+
project_id: external_exports.string(),
|
|
79876
|
+
confirm: external_exports.string().describe("\uC0AD\uC81C \uD655\uC778\uAC12. \uC815\uD655\uD788 DELETE\uB97C \uB123\uC5B4\uC57C \uC0AD\uC81C\uB429\uB2C8\uB2E4.")
|
|
79877
|
+
},
|
|
79878
|
+
handler: (args) => {
|
|
79879
|
+
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.");
|
|
79880
|
+
const proj = projectRepo.get(args.project_id);
|
|
79881
|
+
if (!proj) return fail("\uD574\uB2F9 \uD504\uB85C\uC81D\uD2B8 \uD56D\uBAA9\uC744 \uCC3E\uC744 \uC218 \uC5C6\uC2B5\uB2C8\uB2E4.");
|
|
79882
|
+
if (!projectRepo.remove(proj.id)) return fail("\uD504\uB85C\uC81D\uD2B8 \uD56D\uBAA9\uC744 \uC0AD\uC81C\uD558\uC9C0 \uBABB\uD588\uC2B5\uB2C8\uB2E4.");
|
|
79883
|
+
const user_message = `'${proj.name}' \uD504\uB85C\uC81D\uD2B8\uB97C \uC0AD\uC81C\uD588\uC5B4\uC694.`;
|
|
79884
|
+
return ok(user_message, { deleted: true, project_id: proj.id, user_message });
|
|
79885
|
+
}
|
|
79886
|
+
},
|
|
79887
|
+
{
|
|
79888
|
+
name: "delete_skill",
|
|
79889
|
+
title: "\uAE30\uC220\uC2A4\uD0DD \uD56D\uBAA9 \uC0AD\uC81C",
|
|
79890
|
+
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.",
|
|
79891
|
+
inputSchema: {
|
|
79892
|
+
skill_id: external_exports.string(),
|
|
79893
|
+
confirm: external_exports.string().describe("\uC0AD\uC81C \uD655\uC778\uAC12. \uC815\uD655\uD788 DELETE\uB97C \uB123\uC5B4\uC57C \uC0AD\uC81C\uB429\uB2C8\uB2E4.")
|
|
79894
|
+
},
|
|
79895
|
+
handler: (args) => {
|
|
79896
|
+
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.");
|
|
79897
|
+
const skill = skillRepo.get(args.skill_id);
|
|
79898
|
+
if (!skill) return fail("\uD574\uB2F9 \uAE30\uC220 \uD56D\uBAA9\uC744 \uCC3E\uC744 \uC218 \uC5C6\uC2B5\uB2C8\uB2E4.");
|
|
79899
|
+
if (!skillRepo.remove(skill.id)) return fail("\uAE30\uC220 \uD56D\uBAA9\uC744 \uC0AD\uC81C\uD558\uC9C0 \uBABB\uD588\uC2B5\uB2C8\uB2E4.");
|
|
79900
|
+
const user_message = `'${skill.name}' \uAE30\uC220\uC744 \uC0AD\uC81C\uD588\uC5B4\uC694.`;
|
|
79901
|
+
return ok(user_message, { deleted: true, skill_id: skill.id, user_message });
|
|
79902
|
+
}
|
|
79903
|
+
},
|
|
79229
79904
|
/* ---------------------------------------------------------- cover letters */
|
|
79230
79905
|
{
|
|
79231
79906
|
name: "get_cover_letters",
|
|
@@ -79257,6 +79932,31 @@ ${lines}`;
|
|
|
79257
79932
|
}
|
|
79258
79933
|
}
|
|
79259
79934
|
},
|
|
79935
|
+
{
|
|
79936
|
+
name: "delete_cover_letter",
|
|
79937
|
+
title: "\uC790\uAE30\uC18C\uAC1C\uC11C \uC0AD\uC81C",
|
|
79938
|
+
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.",
|
|
79939
|
+
inputSchema: {
|
|
79940
|
+
cover_letter_id: external_exports.string(),
|
|
79941
|
+
confirm: external_exports.string().describe("\uC0AD\uC81C \uD655\uC778\uAC12. \uC815\uD655\uD788 DELETE\uB97C \uB123\uC5B4\uC57C \uC0AD\uC81C\uB429\uB2C8\uB2E4.")
|
|
79942
|
+
},
|
|
79943
|
+
handler: (args) => {
|
|
79944
|
+
if (args?.confirm !== DELETE_CONFIRMATION) {
|
|
79945
|
+
return fail("\uC0AD\uC81C\uD558\uB824\uBA74 confirm\uC5D0 DELETE\uB97C \uB123\uC5B4 \uB2E4\uC2DC \uD638\uCD9C\uD558\uC138\uC694.");
|
|
79946
|
+
}
|
|
79947
|
+
const cl = coverLetterRepo.get(args.cover_letter_id, false);
|
|
79948
|
+
if (!cl) return fail("\uC790\uAE30\uC18C\uAC1C\uC11C\uB97C \uCC3E\uC744 \uC218 \uC5C6\uC2B5\uB2C8\uB2E4.");
|
|
79949
|
+
const removed = coverLetterRepo.remove(cl.id);
|
|
79950
|
+
if (!removed) return fail("\uC790\uAE30\uC18C\uAC1C\uC11C\uB97C \uC0AD\uC81C\uD558\uC9C0 \uBABB\uD588\uC2B5\uB2C8\uB2E4.");
|
|
79951
|
+
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.`;
|
|
79952
|
+
return ok(user_message, {
|
|
79953
|
+
deleted: true,
|
|
79954
|
+
cover_letter_id: cl.id,
|
|
79955
|
+
title: cl.title,
|
|
79956
|
+
user_message
|
|
79957
|
+
});
|
|
79958
|
+
}
|
|
79959
|
+
},
|
|
79260
79960
|
/* ------------------------------------------------------------------ jobs */
|
|
79261
79961
|
{
|
|
79262
79962
|
name: "save_job_posting",
|
|
@@ -79265,18 +79965,26 @@ ${lines}`;
|
|
|
79265
79965
|
inputSchema: JobInputSchema.shape,
|
|
79266
79966
|
handler: (args) => {
|
|
79267
79967
|
const { job } = saveJobPosting(args);
|
|
79268
|
-
|
|
79968
|
+
const user_message = `'${job.company} \xB7 ${job.position}' \uACF5\uACE0\uB97C \uC800\uC7A5\uD588\uC5B4\uC694.`;
|
|
79969
|
+
return ok(user_message, {
|
|
79970
|
+
...job,
|
|
79971
|
+
user_message,
|
|
79972
|
+
suggested_next_action: {
|
|
79973
|
+
prompt: "\uC774 \uACF5\uACE0\uC640 \uB0B4 \uD504\uB85C\uD544\uC744 \uBE44\uAD50\uD574 \uC801\uD569\uB3C4\uB97C \uBD84\uC11D\uD560\uAE4C\uC694?",
|
|
79974
|
+
next_workflow: "analyze_job"
|
|
79975
|
+
}
|
|
79976
|
+
});
|
|
79269
79977
|
}
|
|
79270
79978
|
},
|
|
79271
79979
|
{
|
|
79272
79980
|
name: "get_job_posting",
|
|
79273
79981
|
title: "\uCC44\uC6A9\uACF5\uACE0 \uC0C1\uC138 \uC870\uD68C",
|
|
79274
|
-
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, \
|
|
79982
|
+
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.",
|
|
79275
79983
|
inputSchema: { job_id: external_exports.string() },
|
|
79276
79984
|
readOnly: true,
|
|
79277
79985
|
handler: (args) => {
|
|
79278
79986
|
const job = jobRepo.get(args.job_id);
|
|
79279
|
-
if (!job) return fail(
|
|
79987
|
+
if (!job) return fail("\uACF5\uACE0\uB97C \uCC3E\uC744 \uC218 \uC5C6\uC2B5\uB2C8\uB2E4.");
|
|
79280
79988
|
return ok(`${job.company} \xB7 ${job.position}`, {
|
|
79281
79989
|
job: jobWithMeta(job),
|
|
79282
79990
|
fit: fitRepo.getByJob(job.id),
|
|
@@ -79297,6 +80005,35 @@ ${lines}`;
|
|
|
79297
80005
|
return ok(`\uACF5\uACE0 ${jobs.length}\uAC74`, jobs);
|
|
79298
80006
|
}
|
|
79299
80007
|
},
|
|
80008
|
+
{
|
|
80009
|
+
name: "delete_job_posting",
|
|
80010
|
+
title: "\uCC44\uC6A9\uACF5\uACE0 \uC0AD\uC81C",
|
|
80011
|
+
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.",
|
|
80012
|
+
inputSchema: {
|
|
80013
|
+
job_id: external_exports.string(),
|
|
80014
|
+
confirm: external_exports.string().describe("\uC0AD\uC81C \uD655\uC778\uAC12. \uC815\uD655\uD788 DELETE\uB97C \uB123\uC5B4\uC57C \uC0AD\uC81C\uB429\uB2C8\uB2E4.")
|
|
80015
|
+
},
|
|
80016
|
+
handler: (args) => {
|
|
80017
|
+
if (args?.confirm !== DELETE_CONFIRMATION) {
|
|
80018
|
+
return fail("\uC0AD\uC81C\uD558\uB824\uBA74 confirm\uC5D0 DELETE\uB97C \uB123\uC5B4 \uB2E4\uC2DC \uD638\uCD9C\uD558\uC138\uC694.");
|
|
80019
|
+
}
|
|
80020
|
+
const job = jobRepo.get(args.job_id);
|
|
80021
|
+
if (!job) return fail("\uACF5\uACE0\uB97C \uCC3E\uC744 \uC218 \uC5C6\uC2B5\uB2C8\uB2E4.");
|
|
80022
|
+
const detachedCoverLetters = coverLetterRepo.listByJob(job.id).length;
|
|
80023
|
+
const removed = jobRepo.remove(job.id);
|
|
80024
|
+
if (!removed) return fail("\uACF5\uACE0\uB97C \uC0AD\uC81C\uD558\uC9C0 \uBABB\uD588\uC2B5\uB2C8\uB2E4.");
|
|
80025
|
+
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.` : "";
|
|
80026
|
+
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}`;
|
|
80027
|
+
return ok(user_message, {
|
|
80028
|
+
deleted: true,
|
|
80029
|
+
job_id: job.id,
|
|
80030
|
+
company: job.company,
|
|
80031
|
+
position: job.position,
|
|
80032
|
+
detached_cover_letters: detachedCoverLetters,
|
|
80033
|
+
user_message
|
|
80034
|
+
});
|
|
80035
|
+
}
|
|
80036
|
+
},
|
|
79300
80037
|
/* ----------------------------------------------------- application context */
|
|
79301
80038
|
{
|
|
79302
80039
|
name: "get_application_context",
|
|
@@ -79308,18 +80045,46 @@ ${lines}`;
|
|
|
79308
80045
|
const ctx = getApplicationContext({ job_id: args?.job_id });
|
|
79309
80046
|
const recommended_route = pickRoute(ctx);
|
|
79310
80047
|
const route = recommended_route ? getRoute(recommended_route) : void 0;
|
|
80048
|
+
const today = (/* @__PURE__ */ new Date()).toISOString().slice(0, 10);
|
|
80049
|
+
const ym = (s) => {
|
|
80050
|
+
const m = s ? /^(\d{4})-(\d{2})/.exec(s) : null;
|
|
80051
|
+
return m ? Number(m[1]) * 12 + Number(m[2]) : null;
|
|
80052
|
+
};
|
|
80053
|
+
const monthsBetween = (a, b) => {
|
|
80054
|
+
const x2 = ym(a), y = ym(b);
|
|
80055
|
+
return x2 != null && y != null ? y - x2 : null;
|
|
80056
|
+
};
|
|
80057
|
+
const tenure = ctx.experiences.map((e) => {
|
|
80058
|
+
if (!e.start_date) return null;
|
|
80059
|
+
const asOf = e.is_current ? e.updated_at ?? today : e.end_date;
|
|
80060
|
+
const months = monthsBetween(e.start_date, asOf);
|
|
80061
|
+
if (months == null || months < 0) return null;
|
|
80062
|
+
return {
|
|
80063
|
+
company: e.company,
|
|
80064
|
+
is_current: e.is_current,
|
|
80065
|
+
start_date: e.start_date,
|
|
80066
|
+
as_of: (asOf ?? "").slice(0, 7),
|
|
80067
|
+
// 재직중=updated_at(정보 확인 시점) / 종료=end_date
|
|
80068
|
+
months,
|
|
80069
|
+
years: Math.round(months / 12 * 10) / 10,
|
|
80070
|
+
data_age_months: e.is_current ? monthsBetween(e.updated_at, today) : null
|
|
80071
|
+
};
|
|
80072
|
+
}).filter((t) => t != null);
|
|
79311
80073
|
const enriched = {
|
|
79312
80074
|
...ctx,
|
|
80075
|
+
today,
|
|
80076
|
+
tenure,
|
|
79313
80077
|
recommended_route,
|
|
79314
80078
|
verifier_sequence: route?.verifierSequence ?? [],
|
|
79315
80079
|
next_tool: recommended_route ? "get_workflow_guide" : null
|
|
79316
80080
|
};
|
|
79317
80081
|
const summary = [
|
|
80082
|
+
`\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.`,
|
|
79318
80083
|
`\uD504\uB85C\uD544: ${ctx.profile?.name ?? "\uBBF8\uC785\uB825"}`,
|
|
79319
80084
|
`\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}`,
|
|
79320
80085
|
ctx.job ? `\uB300\uC0C1 \uACF5\uACE0: ${ctx.job.company} \xB7 ${ctx.job.position}` : "\uB300\uC0C1 \uACF5\uACE0 \uC5C6\uC74C",
|
|
79321
80086
|
ctx.writing_preferences.preferred_tone ? `\uC120\uD638 \uBB38\uCCB4: ${ctx.writing_preferences.preferred_tone}` : "",
|
|
79322
|
-
recommended_route ? `\
|
|
80087
|
+
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."
|
|
79323
80088
|
].filter(Boolean).join("\n");
|
|
79324
80089
|
return ok(summary, enriched);
|
|
79325
80090
|
}
|
|
@@ -79332,7 +80097,34 @@ ${lines}`;
|
|
|
79332
80097
|
handler: (args) => {
|
|
79333
80098
|
try {
|
|
79334
80099
|
const fit = saveFitAnalysis(args);
|
|
79335
|
-
|
|
80100
|
+
const suggested_next_action = {
|
|
80101
|
+
prompt: "\uC774 \uACF5\uACE0\uC5D0 \uB9DE\uCD98 \uC790\uAE30\uC18C\uAC1C\uC11C\uB97C \uC368\uB4DC\uB9B4\uAE4C\uC694?",
|
|
80102
|
+
options: [
|
|
80103
|
+
{
|
|
80104
|
+
label: "\uB124, \uC774 \uACF5\uACE0\uC5D0 \uB9DE\uCD98 \uC790\uAE30\uC18C\uAC1C\uC11C\uB97C \uC368\uC918",
|
|
80105
|
+
next_workflow: "write_cover_letter"
|
|
80106
|
+
},
|
|
80107
|
+
{
|
|
80108
|
+
label: "\uC544\uB2C8\uC694, \uBD84\uC11D\uB9CC \uC800\uC7A5\uD574\uC918",
|
|
80109
|
+
next_workflow: null
|
|
80110
|
+
}
|
|
80111
|
+
]
|
|
80112
|
+
};
|
|
80113
|
+
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}`;
|
|
80114
|
+
return ok(
|
|
80115
|
+
[
|
|
80116
|
+
user_message,
|
|
80117
|
+
"",
|
|
80118
|
+
"\uC0AC\uC6A9\uC790\uC5D0\uAC8C \uB2E4\uC74C \uC120\uD0DD\uC9C0\uB97C \uBCF4\uC5EC\uC8FC\uC138\uC694:",
|
|
80119
|
+
"1. \uB124, \uC774 \uACF5\uACE0\uC5D0 \uB9DE\uCD98 \uC790\uAE30\uC18C\uAC1C\uC11C\uB97C \uC368\uC918",
|
|
80120
|
+
"2. \uC544\uB2C8\uC694, \uBD84\uC11D\uB9CC \uC800\uC7A5\uD574\uC918"
|
|
80121
|
+
].join("\n"),
|
|
80122
|
+
{
|
|
80123
|
+
...fit,
|
|
80124
|
+
user_message,
|
|
80125
|
+
suggested_next_action
|
|
80126
|
+
}
|
|
80127
|
+
);
|
|
79336
80128
|
} catch (e) {
|
|
79337
80129
|
return fail(e instanceof Error ? e.message : "\uC800\uC7A5 \uC2E4\uD328");
|
|
79338
80130
|
}
|
|
@@ -79346,16 +80138,25 @@ ${lines}`;
|
|
|
79346
80138
|
inputSchema: {
|
|
79347
80139
|
job_id: external_exports.string(),
|
|
79348
80140
|
status: external_exports.enum(APPLICATION_STATUSES),
|
|
79349
|
-
note: external_exports.string().optional()
|
|
80141
|
+
note: external_exports.string().optional(),
|
|
80142
|
+
submission: ApplicationSubmissionSchema.optional()
|
|
79350
80143
|
},
|
|
79351
80144
|
handler: (args) => {
|
|
79352
80145
|
try {
|
|
79353
|
-
const res = updateApplicationStatus(args.job_id, args.status, args.note);
|
|
79354
|
-
|
|
79355
|
-
`\uC0C1\uD0DC\uB97C '${APPLICATION_STATUS_LABELS[args.status]}'(\uC73C)\uB85C \uBCC0\uACBD\uD588\uC2B5\uB2C8\uB2E4.${res.hint ? `
|
|
80146
|
+
const res = updateApplicationStatus(args.job_id, args.status, args.note, args.submission);
|
|
80147
|
+
const user_message = `\uC9C0\uC6D0 \uC0C1\uD0DC\uB97C '${APPLICATION_STATUS_LABELS[args.status]}'(\uC73C)\uB85C \uBC14\uAFE8\uC5B4\uC694.` + (res.hint ? `
|
|
79356
80148
|
|
|
79357
|
-
|
|
79358
|
-
|
|
80149
|
+
${res.hint}` : "");
|
|
80150
|
+
return ok(
|
|
80151
|
+
user_message,
|
|
80152
|
+
{
|
|
80153
|
+
...res,
|
|
80154
|
+
user_message,
|
|
80155
|
+
suggested_next_action: res.hint ? {
|
|
80156
|
+
prompt: res.hint,
|
|
80157
|
+
next_workflow: "prepare_interview"
|
|
80158
|
+
} : null
|
|
80159
|
+
}
|
|
79359
80160
|
);
|
|
79360
80161
|
} catch (e) {
|
|
79361
80162
|
return fail(e instanceof Error ? e.message : "\uBCC0\uACBD \uC2E4\uD328");
|
|
@@ -79366,12 +80167,15 @@ ${lines}`;
|
|
|
79366
80167
|
{
|
|
79367
80168
|
name: "save_interview_prep",
|
|
79368
80169
|
title: "\uBA74\uC811 \uC900\uBE44 \uC790\uB8CC \uC800\uC7A5",
|
|
79369
|
-
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. \
|
|
80170
|
+
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.",
|
|
79370
80171
|
inputSchema: InterviewPrepInputSchema.shape,
|
|
79371
80172
|
handler: (args) => {
|
|
79372
80173
|
try {
|
|
79373
80174
|
const prep = saveInterviewPrep(args);
|
|
79374
|
-
|
|
80175
|
+
const tech = prep.questions.filter((q) => (q.category ?? "technical") === "technical").length;
|
|
80176
|
+
const behavioral = prep.questions.filter((q) => q.category === "behavioral").length;
|
|
80177
|
+
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.";
|
|
80178
|
+
return ok(user_message, { ...prep, user_message });
|
|
79375
80179
|
} catch (e) {
|
|
79376
80180
|
return fail(e instanceof Error ? e.message : "\uC800\uC7A5 \uC2E4\uD328");
|
|
79377
80181
|
}
|
|
@@ -79396,11 +80200,70 @@ ${lines}`;
|
|
|
79396
80200
|
const dir = getExportsDir();
|
|
79397
80201
|
const filePath = path7.join(dir, result2.filename);
|
|
79398
80202
|
try {
|
|
79399
|
-
|
|
80203
|
+
fs7.writeFileSync(filePath, result2.content, "utf8");
|
|
79400
80204
|
} catch (e) {
|
|
79401
80205
|
return fail(`\uD30C\uC77C \uC800\uC7A5 \uC2E4\uD328: ${e instanceof Error ? e.message : e}`);
|
|
79402
80206
|
}
|
|
79403
80207
|
return ok(`'${cl.title}'\uB97C ${format.toUpperCase()}\uB85C \uB0B4\uBCF4\uB0C8\uC2B5\uB2C8\uB2E4.
|
|
80208
|
+
\uC800\uC7A5 \uC704\uCE58: ${filePath}`, {
|
|
80209
|
+
path: filePath,
|
|
80210
|
+
filename: result2.filename,
|
|
80211
|
+
content: result2.content
|
|
80212
|
+
});
|
|
80213
|
+
}
|
|
80214
|
+
},
|
|
80215
|
+
{
|
|
80216
|
+
name: "export_resume",
|
|
80217
|
+
title: "\uC774\uB825\uC11C/\uACBD\uB825\uAE30\uC220\uC11C \uB0B4\uBCF4\uB0B4\uAE30",
|
|
80218
|
+
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.',
|
|
80219
|
+
inputSchema: {
|
|
80220
|
+
document_id: external_exports.string(),
|
|
80221
|
+
format: external_exports.enum(["md", "html"]).optional().describe("\uAE30\uBCF8 md")
|
|
80222
|
+
},
|
|
80223
|
+
handler: (args) => {
|
|
80224
|
+
const doc = documentRepo.get(args.document_id);
|
|
80225
|
+
if (!doc) return fail("\uBB38\uC11C\uB97C \uCC3E\uC744 \uC218 \uC5C6\uC2B5\uB2C8\uB2E4.");
|
|
80226
|
+
const profile = profileRepo.get();
|
|
80227
|
+
const format = args.format ?? "md";
|
|
80228
|
+
const result2 = format === "html" ? resumeToHtml(doc, profile) : resumeToMarkdown(doc, profile);
|
|
80229
|
+
const dir = getExportsDir();
|
|
80230
|
+
const filePath = path7.join(dir, result2.filename);
|
|
80231
|
+
try {
|
|
80232
|
+
fs7.writeFileSync(filePath, result2.content, "utf8");
|
|
80233
|
+
} catch (e) {
|
|
80234
|
+
return fail(`\uD30C\uC77C \uC800\uC7A5 \uC2E4\uD328: ${e instanceof Error ? e.message : e}`);
|
|
80235
|
+
}
|
|
80236
|
+
return ok(`'${doc.title}'\uB97C ${format.toUpperCase()}\uB85C \uB0B4\uBCF4\uB0C8\uC2B5\uB2C8\uB2E4.
|
|
80237
|
+
\uC800\uC7A5 \uC704\uCE58: ${filePath}`, {
|
|
80238
|
+
path: filePath,
|
|
80239
|
+
filename: result2.filename,
|
|
80240
|
+
content: result2.content
|
|
80241
|
+
});
|
|
80242
|
+
}
|
|
80243
|
+
},
|
|
80244
|
+
{
|
|
80245
|
+
name: "export_profile",
|
|
80246
|
+
title: "\uD504\uB85C\uD544\uC744 \uC774\uB825\uC11C\uB85C \uB0B4\uBCF4\uB0B4\uAE30",
|
|
80247
|
+
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.',
|
|
80248
|
+
inputSchema: {
|
|
80249
|
+
format: external_exports.enum(["md", "html"]).optional().describe("\uAE30\uBCF8 md")
|
|
80250
|
+
},
|
|
80251
|
+
handler: (args) => {
|
|
80252
|
+
const profile = profileRepo.get();
|
|
80253
|
+
if (!profile) return fail("\uD504\uB85C\uD544\uC774 \uC5C6\uC2B5\uB2C8\uB2E4. \uBA3C\uC800 \uD504\uB85C\uD544\uC744 \uC800\uC7A5\uD558\uC138\uC694.");
|
|
80254
|
+
const format = args.format ?? "md";
|
|
80255
|
+
const experiences = experienceRepo.list();
|
|
80256
|
+
const projects = projectRepo.list();
|
|
80257
|
+
const skills = skillRepo.list();
|
|
80258
|
+
const result2 = format === "html" ? profileToHtml(profile, experiences, projects, skills) : profileToMarkdown(profile, experiences, projects, skills);
|
|
80259
|
+
const dir = getExportsDir();
|
|
80260
|
+
const filePath = path7.join(dir, result2.filename);
|
|
80261
|
+
try {
|
|
80262
|
+
fs7.writeFileSync(filePath, result2.content, "utf8");
|
|
80263
|
+
} catch (e) {
|
|
80264
|
+
return fail(`\uD30C\uC77C \uC800\uC7A5 \uC2E4\uD328: ${e instanceof Error ? e.message : e}`);
|
|
80265
|
+
}
|
|
80266
|
+
return ok(`\uD504\uB85C\uD544\uC744 \uC774\uB825\uC11C(${format.toUpperCase()})\uB85C \uB0B4\uBCF4\uB0C8\uC2B5\uB2C8\uB2E4.
|
|
79404
80267
|
\uC800\uC7A5 \uC704\uCE58: ${filePath}`, {
|
|
79405
80268
|
path: filePath,
|
|
79406
80269
|
filename: result2.filename,
|
|
@@ -79452,9 +80315,17 @@ ${lines}`;
|
|
|
79452
80315
|
{
|
|
79453
80316
|
name: "get_workflow_guide",
|
|
79454
80317
|
title: "\uC6CC\uD06C\uD50C\uB85C\uC6B0 \uAC00\uC774\uB4DC",
|
|
79455
|
-
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.',
|
|
80318
|
+
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.',
|
|
79456
80319
|
inputSchema: {
|
|
79457
|
-
workflow_id: external_exports.enum([
|
|
80320
|
+
workflow_id: external_exports.enum([
|
|
80321
|
+
"onboarding",
|
|
80322
|
+
"analyze_job",
|
|
80323
|
+
"write_cover_letter",
|
|
80324
|
+
"write_career_description",
|
|
80325
|
+
"manage_application_status",
|
|
80326
|
+
"prepare_interview",
|
|
80327
|
+
"build_personal_brand"
|
|
80328
|
+
]).optional()
|
|
79458
80329
|
},
|
|
79459
80330
|
readOnly: true,
|
|
79460
80331
|
handler: (args) => {
|
|
@@ -79549,38 +80420,59 @@ ${report.disclaimer}`, report);
|
|
|
79549
80420
|
{
|
|
79550
80421
|
name: "get_writing_style_guide",
|
|
79551
80422
|
title: "AI \uD2F0 \uC548 \uB098\uB294 \uAE00\uC4F0\uAE30 \uAC00\uC774\uB4DC",
|
|
79552
|
-
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 \
|
|
79553
|
-
inputSchema: {
|
|
80423
|
+
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.',
|
|
80424
|
+
inputSchema: {
|
|
80425
|
+
doc_type: external_exports.enum([
|
|
80426
|
+
"cover_letter",
|
|
80427
|
+
"self_pr",
|
|
80428
|
+
"application_email",
|
|
80429
|
+
"career_description",
|
|
80430
|
+
"resume",
|
|
80431
|
+
"portfolio"
|
|
80432
|
+
]).optional().describe(
|
|
80433
|
+
"\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."
|
|
80434
|
+
)
|
|
80435
|
+
},
|
|
79554
80436
|
readOnly: true,
|
|
79555
|
-
handler: () => ok("AI \uD2F0 \uC548 \uB098\uB294 \uAE00\uC4F0\uAE30 \uAC00\uC774\uB4DC\uB97C \uC801\uC6A9\uD574 \uC791\uC131\uD558\uC138\uC694.", {
|
|
80437
|
+
handler: (args) => ok("AI \uD2F0 \uC548 \uB098\uB294 \uAE00\uC4F0\uAE30 \uAC00\uC774\uB4DC\uB97C \uC801\uC6A9\uD574 \uC791\uC131\uD558\uC138\uC694.", {
|
|
80438
|
+
guide: getWritingStyleGuide(args?.doc_type)
|
|
80439
|
+
})
|
|
79556
80440
|
},
|
|
79557
80441
|
/* ----------------------------------------------------------------- update */
|
|
79558
80442
|
{
|
|
79559
80443
|
name: "check_for_update",
|
|
79560
80444
|
title: "\uC5C5\uB370\uC774\uD2B8 \uD655\uC778",
|
|
79561
|
-
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. \
|
|
80445
|
+
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.',
|
|
79562
80446
|
inputSchema: {},
|
|
79563
80447
|
readOnly: true,
|
|
79564
80448
|
handler: async () => {
|
|
79565
|
-
const u = await getUpdateStatusAsync();
|
|
80449
|
+
const u = await getUpdateStatusAsync(true);
|
|
79566
80450
|
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);
|
|
80451
|
+
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}).`;
|
|
79567
80452
|
return ok(
|
|
79568
|
-
|
|
79569
|
-
|
|
80453
|
+
user_message,
|
|
80454
|
+
{
|
|
80455
|
+
...u,
|
|
80456
|
+
user_message,
|
|
80457
|
+
suggested_next_action: u.update_available ? {
|
|
80458
|
+
prompt: "\uC9C0\uAE08 CareerMate\uB97C \uC5C5\uB370\uC774\uD2B8\uD560\uAE4C\uC694?",
|
|
80459
|
+
next_tool: "update_careermate"
|
|
80460
|
+
} : null
|
|
80461
|
+
}
|
|
79570
80462
|
);
|
|
79571
80463
|
}
|
|
79572
80464
|
},
|
|
79573
80465
|
{
|
|
79574
80466
|
name: "update_careermate",
|
|
79575
80467
|
title: "CareerMate \uC5C5\uB370\uC774\uD2B8",
|
|
79576
|
-
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
|
|
80468
|
+
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.',
|
|
79577
80469
|
inputSchema: {},
|
|
79578
80470
|
handler: async () => {
|
|
79579
80471
|
const r = await runSelfUpdate();
|
|
79580
80472
|
if (!r.ok) return fail(`${r.message}${r.manual ? `
|
|
79581
80473
|
|
|
79582
80474
|
\uC9C1\uC811 \uC2E4\uD589: ${r.manual}` : ""}`);
|
|
79583
|
-
return ok(r.message, r);
|
|
80475
|
+
return ok(r.message, { ...r, user_message: r.message });
|
|
79584
80476
|
}
|
|
79585
80477
|
}
|
|
79586
80478
|
];
|
|
@@ -79601,7 +80493,7 @@ async function main() {
|
|
|
79601
80493
|
const nodeOk = checkNode();
|
|
79602
80494
|
const dir = getDataDir();
|
|
79603
80495
|
try {
|
|
79604
|
-
|
|
80496
|
+
fs8.accessSync(dir, fs8.constants.W_OK);
|
|
79605
80497
|
ok2(`\uB370\uC774\uD130 \uD3F4\uB354 \uC4F0\uAE30 \uAC00\uB2A5: ${dir}`);
|
|
79606
80498
|
} catch {
|
|
79607
80499
|
warn2(`\uB370\uC774\uD130 \uD3F4\uB354\uC5D0 \uC4F8 \uC218 \uC5C6\uC2B5\uB2C8\uB2E4: ${dir}`);
|
|
@@ -79631,7 +80523,7 @@ async function main() {
|
|
|
79631
80523
|
}
|
|
79632
80524
|
ok2(`MCP \uB3C4\uAD6C ${TOOLS.length}\uAC1C \uB4F1\uB85D\uB428`);
|
|
79633
80525
|
try {
|
|
79634
|
-
const u = await getUpdateStatusAsync();
|
|
80526
|
+
const u = await getUpdateStatusAsync(true);
|
|
79635
80527
|
if (u.latest === null) info2(`\uBC84\uC804 v${u.current} (\uC5C5\uB370\uC774\uD2B8 \uD655\uC778 \uC0DD\uB7B5 \u2014 \uC624\uD504\uB77C\uC778\uC774\uAC70\uB098 \uC77C\uC2DC\uC801 \uC624\uB958)`);
|
|
79636
80528
|
else if (u.update_available) warn2(`\uC0C8 \uBC84\uC804 v${u.latest} \uC788\uC74C (\uD604\uC7AC v${u.current}). \uC5C5\uB370\uC774\uD2B8: ${u.update_command}`);
|
|
79637
80529
|
else ok2(`\uCD5C\uC2E0 \uBC84\uC804 v${u.current}`);
|