careermate 0.0.5 → 0.0.7
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 +13 -10
- package/INSTALL.md +16 -15
- package/README.md +24 -24
- package/THIRD_PARTY_NOTICES.md +2 -3
- package/bin/careermate.mjs +8 -1
- package/dist/career-os/README.md +12 -6
- package/dist/career-os/eop/career-description.md +139 -0
- package/dist/career-os/eop/cover-letter.md +10 -5
- package/dist/career-os/eop/fit-analysis.md +16 -6
- package/dist/career-os/eop/interview-prep.md +209 -21
- package/dist/career-os/eop/job-analysis.md +6 -4
- package/dist/career-os/eop/profile-extraction.md +5 -4
- package/dist/career-os/knowledge/cover-letter.md +5 -4
- package/dist/career-os/knowledge/fit-matching.md +8 -8
- package/dist/career-os/knowledge/human-writing.md +2 -0
- 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 +4 -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 +692 -71
- package/dist/mcp.mjs +710 -71
- 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 +24 -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 +154 -102
- package/dist/public/styles.css +28 -1
- package/dist/web.mjs +495 -75
- package/docs/FAQ.md +23 -3
- package/docs/MCP_TOOLS.md +22 -13
- package/docs/START_WORKFLOW.md +3 -3
- package/docs/SUPPORTED_AI_APPS.md +13 -0
- package/docs/WORKFLOWS.md +77 -20
- package/docs/career-os/README.md +12 -6
- package/docs/career-os/eop/career-description.md +139 -0
- package/docs/career-os/eop/cover-letter.md +10 -5
- package/docs/career-os/eop/fit-analysis.md +16 -6
- package/docs/career-os/eop/interview-prep.md +209 -21
- package/docs/career-os/eop/job-analysis.md +6 -4
- package/docs/career-os/eop/profile-extraction.md +5 -4
- package/docs/career-os/knowledge/cover-letter.md +5 -4
- package/docs/career-os/knowledge/fit-matching.md +8 -8
- package/docs/career-os/knowledge/human-writing.md +2 -0
- 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 +4 -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 +134 -17
- 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 +55 -9
- package/packages/mcp-tools/src/tools.ts +250 -24
- package/packages/mcp-tools/src/update.ts +30 -15
- 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 +9 -7
- package/packages/shared/src/enums.ts +14 -4
- package/packages/shared/src/schemas.ts +41 -0
- package/packages/workflows/src/definitions.ts +45 -8
- 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 -465
- package/dist/site/landing.js +0 -163
- 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 -356
- package/dist/site/style.css +0 -665
- package/dist/site/vercel.json +0 -20
package/dist/mcp.mjs
CHANGED
|
@@ -92431,6 +92431,22 @@ var MIGRATIONS = [
|
|
|
92431
92431
|
|
|
92432
92432
|
COMMIT;
|
|
92433
92433
|
PRAGMA foreign_keys=ON;
|
|
92434
|
+
`,
|
|
92435
|
+
// v3 — per-job timeline entries. Document/cover-letter refs live in payload
|
|
92436
|
+
// snapshots instead of FKs so deleting a document does not erase the history.
|
|
92437
|
+
`
|
|
92438
|
+
CREATE TABLE IF NOT EXISTS application_timeline_events (
|
|
92439
|
+
id TEXT PRIMARY KEY,
|
|
92440
|
+
job_id TEXT NOT NULL REFERENCES jobs(id) ON DELETE CASCADE,
|
|
92441
|
+
type TEXT NOT NULL,
|
|
92442
|
+
title TEXT NOT NULL,
|
|
92443
|
+
summary TEXT,
|
|
92444
|
+
payload TEXT NOT NULL DEFAULT '{}',
|
|
92445
|
+
occurred_at TEXT NOT NULL,
|
|
92446
|
+
created_at TEXT NOT NULL
|
|
92447
|
+
);
|
|
92448
|
+
|
|
92449
|
+
CREATE INDEX IF NOT EXISTS idx_timeline_job ON application_timeline_events(job_id, occurred_at ASC);
|
|
92434
92450
|
`
|
|
92435
92451
|
];
|
|
92436
92452
|
function migrate(db) {
|
|
@@ -92462,6 +92478,12 @@ function getDb() {
|
|
|
92462
92478
|
_db = db;
|
|
92463
92479
|
return db;
|
|
92464
92480
|
}
|
|
92481
|
+
function closeDb() {
|
|
92482
|
+
if (_db) {
|
|
92483
|
+
_db.close();
|
|
92484
|
+
_db = null;
|
|
92485
|
+
}
|
|
92486
|
+
}
|
|
92465
92487
|
var _inTx = false;
|
|
92466
92488
|
function tx(fn) {
|
|
92467
92489
|
if (_inTx) return fn();
|
|
@@ -92591,6 +92613,12 @@ function assertStatusTransition(from, to) {
|
|
|
92591
92613
|
}
|
|
92592
92614
|
}
|
|
92593
92615
|
var DOCUMENT_KINDS = ["resume", "career_description", "portfolio", "other"];
|
|
92616
|
+
var DOCUMENT_KIND_LABELS = {
|
|
92617
|
+
resume: "\uC774\uB825\uC11C",
|
|
92618
|
+
career_description: "\uACBD\uB825\uAE30\uC220\uC11C",
|
|
92619
|
+
portfolio: "\uD3EC\uD2B8\uD3F4\uB9AC\uC624",
|
|
92620
|
+
other: "\uAE30\uD0C0 \uBB38\uC11C"
|
|
92621
|
+
};
|
|
92594
92622
|
var CONTENT_SOURCES = ["manual", "upload", "ai", "edit"];
|
|
92595
92623
|
var ACTIVITY_TYPES = [
|
|
92596
92624
|
"profile_updated",
|
|
@@ -92603,6 +92631,13 @@ var ACTIVITY_TYPES = [
|
|
|
92603
92631
|
"interview_prep_saved",
|
|
92604
92632
|
"document_exported"
|
|
92605
92633
|
];
|
|
92634
|
+
var APPLICATION_TIMELINE_TYPES = [
|
|
92635
|
+
"job_saved",
|
|
92636
|
+
"fit_analysis_saved",
|
|
92637
|
+
"cover_letter_version_saved",
|
|
92638
|
+
"application_status_changed",
|
|
92639
|
+
"interview_prep_saved"
|
|
92640
|
+
];
|
|
92606
92641
|
var ENTITY_TYPES = [
|
|
92607
92642
|
"profile",
|
|
92608
92643
|
"experience",
|
|
@@ -92869,11 +92904,19 @@ var ApplicationInputSchema = external_exports.object({
|
|
|
92869
92904
|
applied_at: optLine,
|
|
92870
92905
|
notes: optNote
|
|
92871
92906
|
});
|
|
92907
|
+
var ApplicationSubmissionSchema = external_exports.object({
|
|
92908
|
+
submitted_at: optLine.describe("\uC2E4\uC81C \uC81C\uCD9C\uC77C YYYY-MM-DD"),
|
|
92909
|
+
channel: optLine.describe("\uC81C\uCD9C \uCC44\uB110(\uC6D0\uD2F0\uB4DC/\uC0AC\uB78C\uC778/\uD68C\uC0AC \uCC44\uC6A9\uD398\uC774\uC9C0 \uB4F1)"),
|
|
92910
|
+
cover_letter_id: optLine,
|
|
92911
|
+
cover_letter_version_id: optLine,
|
|
92912
|
+
document_ids: strList.optional().describe("\uC81C\uCD9C\uD55C \uC774\uB825\uC11C\xB7\uACBD\uB825\uAE30\uC220\uC11C\xB7\uD3EC\uD2B8\uD3F4\uB9AC\uC624 \uBB38\uC11C ID \uBAA9\uB85D")
|
|
92913
|
+
});
|
|
92872
92914
|
var ApplicationStatusUpdateSchema = external_exports.object({
|
|
92873
92915
|
job_id: optLine,
|
|
92874
92916
|
application_id: optLine,
|
|
92875
92917
|
status: external_exports.enum(APPLICATION_STATUSES),
|
|
92876
|
-
note: optNote.describe("\uC0C1\uD0DC \uBCC0\uACBD \uC0AC\uC720/\uBA54\uBAA8")
|
|
92918
|
+
note: optNote.describe("\uC0C1\uD0DC \uBCC0\uACBD \uC0AC\uC720/\uBA54\uBAA8"),
|
|
92919
|
+
submission: ApplicationSubmissionSchema.optional().describe("\uC9C0\uC6D0 \uC644\uB8CC \uAE30\uB85D\uC5D0 \uB0A8\uAE38 \uC81C\uCD9C \uC790\uB8CC \uC2A4\uB0C5\uC0F7")
|
|
92877
92920
|
});
|
|
92878
92921
|
var ApplicationRecordSchema = external_exports.object({
|
|
92879
92922
|
...baseRecord,
|
|
@@ -92891,8 +92934,10 @@ var StarGuideSchema = external_exports.object({
|
|
|
92891
92934
|
action: optNote,
|
|
92892
92935
|
result: optNote
|
|
92893
92936
|
});
|
|
92937
|
+
var INTERVIEW_CATEGORIES = ["technical", "behavioral"];
|
|
92894
92938
|
var InterviewQuestionSchema = external_exports.object({
|
|
92895
92939
|
question: external_exports.string().max(MAX_NOTE),
|
|
92940
|
+
category: external_exports.enum(INTERVIEW_CATEGORIES).optional().describe("\uC9C8\uBB38 \uAC08\uB798: 'technical'(\uAE30\uC220\xB7\uC9C1\uBB34 1\uCC28) | 'behavioral'(\uC778\uC131\xB7\uCEEC\uCC98\uD54F\xB7\uC784\uC6D0 2\uCC28, \uC790\uAE30\uC18C\uAC1C\uC11C \uAE30\uBC18). \uC0DD\uB7B5 \uC2DC \uAE30\uC220\uB85C \uAC04\uC8FC."),
|
|
92896
92941
|
intent: external_exports.string().max(MAX_NOTE).optional().describe("\uC9C8\uBB38 \uC758\uB3C4"),
|
|
92897
92942
|
followups: strList.optional().describe("\uC608\uC0C1 \uAF2C\uB9AC \uC9C8\uBB38"),
|
|
92898
92943
|
answer_outline: optBody.describe("\uB2F5\uBCC0 \uAC00\uC774\uB4DC/\uD575\uC2EC \uD3EC\uC778\uD2B8")
|
|
@@ -92920,6 +92965,24 @@ var ActivityRecordSchema = external_exports.object({
|
|
|
92920
92965
|
summary: external_exports.string(),
|
|
92921
92966
|
created_at: isoDateTime
|
|
92922
92967
|
});
|
|
92968
|
+
var ApplicationTimelineInputSchema = external_exports.object({
|
|
92969
|
+
job_id: reqLine,
|
|
92970
|
+
type: external_exports.enum(APPLICATION_TIMELINE_TYPES),
|
|
92971
|
+
title: reqLine,
|
|
92972
|
+
summary: optNote,
|
|
92973
|
+
payload: external_exports.record(external_exports.string(), external_exports.unknown()).optional(),
|
|
92974
|
+
occurred_at: optLine
|
|
92975
|
+
});
|
|
92976
|
+
var ApplicationTimelineRecordSchema = external_exports.object({
|
|
92977
|
+
id,
|
|
92978
|
+
job_id: external_exports.string(),
|
|
92979
|
+
type: external_exports.enum(APPLICATION_TIMELINE_TYPES),
|
|
92980
|
+
title: external_exports.string(),
|
|
92981
|
+
summary: external_exports.string().nullable(),
|
|
92982
|
+
payload: external_exports.record(external_exports.string(), external_exports.unknown()),
|
|
92983
|
+
occurred_at: isoDateTime,
|
|
92984
|
+
created_at: isoDateTime
|
|
92985
|
+
});
|
|
92923
92986
|
var OnboardingStatusSchema = external_exports.object({
|
|
92924
92987
|
completed: external_exports.boolean(),
|
|
92925
92988
|
has_profile: external_exports.boolean(),
|
|
@@ -92956,7 +93019,7 @@ var ApplicationContextSchema = external_exports.object({
|
|
|
92956
93019
|
});
|
|
92957
93020
|
|
|
92958
93021
|
// packages/shared/src/build-info.ts
|
|
92959
|
-
var APP_VERSION = true ? "0.0.
|
|
93022
|
+
var APP_VERSION = true ? "0.0.7" : "0.0.0-dev";
|
|
92960
93023
|
var BUNDLED = true;
|
|
92961
93024
|
|
|
92962
93025
|
// packages/shared/src/index.ts
|
|
@@ -93050,7 +93113,7 @@ function mapExperience(r) {
|
|
|
93050
93113
|
};
|
|
93051
93114
|
}
|
|
93052
93115
|
function expKey(company, role, start) {
|
|
93053
|
-
return [norm(company), norm(role), norm(start)].join("
|
|
93116
|
+
return [norm(company), norm(role), norm(start)].join("");
|
|
93054
93117
|
}
|
|
93055
93118
|
var experienceRepo = {
|
|
93056
93119
|
list() {
|
|
@@ -93561,6 +93624,7 @@ var jobRepo = {
|
|
|
93561
93624
|
db.prepare(`DELETE FROM fit_analyses WHERE job_id=?`).run(id2);
|
|
93562
93625
|
db.prepare(`DELETE FROM applications WHERE job_id=?`).run(id2);
|
|
93563
93626
|
db.prepare(`DELETE FROM interview_preps WHERE job_id=?`).run(id2);
|
|
93627
|
+
db.prepare(`DELETE FROM application_timeline_events WHERE job_id=?`).run(id2);
|
|
93564
93628
|
return db.prepare(`DELETE FROM jobs WHERE id=?`).run(id2).changes > 0;
|
|
93565
93629
|
});
|
|
93566
93630
|
}
|
|
@@ -93673,7 +93737,7 @@ var applicationRepo = {
|
|
|
93673
93737
|
const m = { ...app, ...input };
|
|
93674
93738
|
getDb().prepare(
|
|
93675
93739
|
`UPDATE applications SET status=?,resume_id=?,cover_letter_id=?,applied_at=?,notes=?,updated_at=? WHERE id=?`
|
|
93676
|
-
).run(m.status, m.resume_id, m.cover_letter_id, m.applied_at, m.notes, now(), app.id);
|
|
93740
|
+
).run(m.status, m.resume_id ?? null, m.cover_letter_id ?? null, m.applied_at ?? null, m.notes ?? null, now(), app.id);
|
|
93677
93741
|
return this.get(app.id);
|
|
93678
93742
|
},
|
|
93679
93743
|
setStatus(jobId, status, note) {
|
|
@@ -93754,6 +93818,48 @@ var activityRepo = {
|
|
|
93754
93818
|
return getDb().prepare(`SELECT * FROM activities ORDER BY created_at DESC LIMIT ?`).all(limit);
|
|
93755
93819
|
}
|
|
93756
93820
|
};
|
|
93821
|
+
function mapTimelineEvent(r) {
|
|
93822
|
+
return {
|
|
93823
|
+
id: r.id,
|
|
93824
|
+
job_id: r.job_id,
|
|
93825
|
+
type: r.type,
|
|
93826
|
+
title: r.title,
|
|
93827
|
+
summary: r.summary,
|
|
93828
|
+
payload: fromJson(r.payload, {}),
|
|
93829
|
+
occurred_at: r.occurred_at,
|
|
93830
|
+
created_at: r.created_at
|
|
93831
|
+
};
|
|
93832
|
+
}
|
|
93833
|
+
var timelineRepo = {
|
|
93834
|
+
add(input) {
|
|
93835
|
+
const ts = now();
|
|
93836
|
+
const id2 = newId("tl_");
|
|
93837
|
+
getDb().prepare(
|
|
93838
|
+
`INSERT INTO application_timeline_events (id,job_id,type,title,summary,payload,occurred_at,created_at)
|
|
93839
|
+
VALUES (?,?,?,?,?,?,?,?)`
|
|
93840
|
+
).run(
|
|
93841
|
+
id2,
|
|
93842
|
+
input.job_id,
|
|
93843
|
+
input.type,
|
|
93844
|
+
input.title,
|
|
93845
|
+
input.summary ?? null,
|
|
93846
|
+
toJson(input.payload ?? {}),
|
|
93847
|
+
input.occurred_at ?? ts,
|
|
93848
|
+
ts
|
|
93849
|
+
);
|
|
93850
|
+
return this.get(id2);
|
|
93851
|
+
},
|
|
93852
|
+
get(id2) {
|
|
93853
|
+
const r = getDb().prepare(`SELECT * FROM application_timeline_events WHERE id=?`).get(id2);
|
|
93854
|
+
return r ? mapTimelineEvent(r) : null;
|
|
93855
|
+
},
|
|
93856
|
+
listByJob(jobId) {
|
|
93857
|
+
return getDb().prepare(`SELECT * FROM application_timeline_events WHERE job_id=? ORDER BY occurred_at ASC, created_at ASC`).all(jobId).map(mapTimelineEvent);
|
|
93858
|
+
},
|
|
93859
|
+
remove(id2) {
|
|
93860
|
+
return getDb().prepare(`DELETE FROM application_timeline_events WHERE id=?`).run(id2).changes > 0;
|
|
93861
|
+
}
|
|
93862
|
+
};
|
|
93757
93863
|
|
|
93758
93864
|
// packages/mcp-tools/src/tools.ts
|
|
93759
93865
|
import fs7 from "node:fs";
|
|
@@ -93780,12 +93886,13 @@ function profileCompleteness(p) {
|
|
|
93780
93886
|
function getOnboardingStatus() {
|
|
93781
93887
|
const profile = profileRepo.get();
|
|
93782
93888
|
const resumes = documentRepo.list("resume");
|
|
93889
|
+
const careerDescriptions = documentRepo.list("career_description");
|
|
93783
93890
|
const coverLetters = coverLetterRepo.list();
|
|
93784
93891
|
const experiences = experienceRepo.list();
|
|
93785
93892
|
const skills = skillRepo.list();
|
|
93786
93893
|
const jobs = jobRepo.list();
|
|
93787
93894
|
const has_profile = !!(profile && profile.name);
|
|
93788
|
-
const has_resume = resumes.length > 0;
|
|
93895
|
+
const has_resume = resumes.length > 0 || careerDescriptions.length > 0;
|
|
93789
93896
|
const has_cover_letter = coverLetters.length > 0;
|
|
93790
93897
|
const has_experience = experiences.length > 0;
|
|
93791
93898
|
const has_skills = skills.length > 0;
|
|
@@ -94198,6 +94305,29 @@ function batchNames(names) {
|
|
|
94198
94305
|
if (!shown) return "";
|
|
94199
94306
|
return `: ${shown}${names.length > 8 ? " \uC678" : ""}`;
|
|
94200
94307
|
}
|
|
94308
|
+
function coverLetterTimelineRef(coverLetter, version3, requestedVersionId) {
|
|
94309
|
+
const resolvedVersion = version3 ?? coverLetter.versions?.find((v) => v.id === requestedVersionId || v.id === coverLetter.current_version_id) ?? null;
|
|
94310
|
+
return {
|
|
94311
|
+
kind: "cover_letter",
|
|
94312
|
+
id: coverLetter.id,
|
|
94313
|
+
title: coverLetter.title,
|
|
94314
|
+
version_id: resolvedVersion?.id ?? requestedVersionId ?? coverLetter.current_version_id,
|
|
94315
|
+
version_no: resolvedVersion?.version_no ?? coverLetter.version_count
|
|
94316
|
+
};
|
|
94317
|
+
}
|
|
94318
|
+
function documentTimelineRef(doc) {
|
|
94319
|
+
return {
|
|
94320
|
+
kind: "document",
|
|
94321
|
+
id: doc.id,
|
|
94322
|
+
title: doc.title,
|
|
94323
|
+
document_kind: doc.kind
|
|
94324
|
+
};
|
|
94325
|
+
}
|
|
94326
|
+
function submittedAtToOccurrence(value) {
|
|
94327
|
+
if (!value) return void 0;
|
|
94328
|
+
if (/^\d{4}-\d{2}-\d{2}$/.test(value)) return `${value}T00:00:00.000Z`;
|
|
94329
|
+
return void 0;
|
|
94330
|
+
}
|
|
94201
94331
|
function addExperiences(inputs) {
|
|
94202
94332
|
const res = experienceRepo.addMany(inputs);
|
|
94203
94333
|
activityRepo.log(
|
|
@@ -94241,6 +94371,17 @@ function saveFitAnalysis(input) {
|
|
|
94241
94371
|
const fit = fitRepo.save(input);
|
|
94242
94372
|
const scoreText = fit.score != null ? ` (\uC801\uD569\uB3C4 ${fit.score}\uC810)` : "";
|
|
94243
94373
|
activityRepo.log("fit_analysis_saved", `${job.company} \xB7 ${job.position} \uC801\uD569\uB3C4 \uBD84\uC11D\uC744 \uC800\uC7A5\uD588\uC2B5\uB2C8\uB2E4${scoreText}.`, "fit_analysis", fit.id);
|
|
94374
|
+
timelineRepo.add({
|
|
94375
|
+
job_id: job.id,
|
|
94376
|
+
type: "fit_analysis_saved",
|
|
94377
|
+
title: "\uC801\uD569\uB3C4 \uBD84\uC11D",
|
|
94378
|
+
summary: fit.score != null ? `\uC885\uD569 ${fit.score}\uC810` : fit.summary ?? void 0,
|
|
94379
|
+
payload: {
|
|
94380
|
+
fit_id: fit.id,
|
|
94381
|
+
score: fit.score
|
|
94382
|
+
},
|
|
94383
|
+
occurred_at: fit.updated_at
|
|
94384
|
+
});
|
|
94244
94385
|
return fit;
|
|
94245
94386
|
}
|
|
94246
94387
|
function saveCoverLetterVersion(input) {
|
|
@@ -94274,18 +94415,67 @@ function saveCoverLetterVersion(input) {
|
|
|
94274
94415
|
"cover_letter",
|
|
94275
94416
|
coverLetter.id
|
|
94276
94417
|
);
|
|
94418
|
+
if (coverLetter.job_id) {
|
|
94419
|
+
timelineRepo.add({
|
|
94420
|
+
job_id: coverLetter.job_id,
|
|
94421
|
+
type: "cover_letter_version_saved",
|
|
94422
|
+
title: "\uC790\uAE30\uC18C\uAC1C\uC11C \uC791\uC131",
|
|
94423
|
+
summary: `${coverLetter.title} v${version3.version_no}`,
|
|
94424
|
+
payload: {
|
|
94425
|
+
cover_letter: coverLetterTimelineRef(coverLetter, version3)
|
|
94426
|
+
},
|
|
94427
|
+
occurred_at: version3.created_at
|
|
94428
|
+
});
|
|
94429
|
+
}
|
|
94277
94430
|
return { coverLetter, version: version3, verification, forced };
|
|
94278
94431
|
}
|
|
94279
|
-
function updateApplicationStatus(jobId, status, note) {
|
|
94432
|
+
function updateApplicationStatus(jobId, status, note, submission) {
|
|
94280
94433
|
const job = jobRepo.get(jobId);
|
|
94281
94434
|
if (!job) throw notFound("\uACF5\uACE0\uB97C \uCC3E\uC744 \uC218 \uC5C6\uC2B5\uB2C8\uB2E4.");
|
|
94282
|
-
const
|
|
94283
|
-
|
|
94284
|
-
|
|
94285
|
-
|
|
94286
|
-
|
|
94287
|
-
|
|
94288
|
-
|
|
94435
|
+
const before2 = applicationRepo.getByJob(jobId);
|
|
94436
|
+
const application = tx(() => {
|
|
94437
|
+
let application2 = applicationRepo.setStatus(jobId, status, note);
|
|
94438
|
+
const submittedDocs = (submission?.document_ids ?? []).map((docId) => documentRepo.get(docId)).filter((doc) => !!doc);
|
|
94439
|
+
const submittedCoverLetter = submission?.cover_letter_id ? coverLetterRepo.get(submission.cover_letter_id, true) : null;
|
|
94440
|
+
if (status === "applied" && submission) {
|
|
94441
|
+
const resumeLike = submittedDocs.find((doc) => doc.kind === "resume" || doc.kind === "career_description") ?? submittedDocs[0] ?? null;
|
|
94442
|
+
application2 = applicationRepo.upsert({
|
|
94443
|
+
job_id: jobId,
|
|
94444
|
+
resume_id: resumeLike?.id ?? application2.resume_id ?? void 0,
|
|
94445
|
+
cover_letter_id: submittedCoverLetter?.id ?? application2.cover_letter_id ?? void 0,
|
|
94446
|
+
applied_at: submission.submitted_at ?? application2.applied_at ?? void 0
|
|
94447
|
+
});
|
|
94448
|
+
}
|
|
94449
|
+
activityRepo.log(
|
|
94450
|
+
"application_status_changed",
|
|
94451
|
+
`${job.company} \xB7 ${job.position} \uC0C1\uD0DC\uB97C '${APPLICATION_STATUS_LABELS[status]}'(\uC73C)\uB85C \uBCC0\uACBD\uD588\uC2B5\uB2C8\uB2E4.`,
|
|
94452
|
+
"application",
|
|
94453
|
+
application2.id
|
|
94454
|
+
);
|
|
94455
|
+
const submittedAt = submission?.submitted_at?.trim();
|
|
94456
|
+
const channel = submission?.channel?.trim();
|
|
94457
|
+
const submissionPayload = submission && (submittedAt || channel || submittedCoverLetter || submittedDocs.length > 0) ? {
|
|
94458
|
+
submitted_at: submittedAt || null,
|
|
94459
|
+
channel: channel || null,
|
|
94460
|
+
cover_letter: submittedCoverLetter ? coverLetterTimelineRef(submittedCoverLetter, null, submission.cover_letter_version_id) : null,
|
|
94461
|
+
documents: submittedDocs.map(documentTimelineRef)
|
|
94462
|
+
} : null;
|
|
94463
|
+
timelineRepo.add({
|
|
94464
|
+
job_id: job.id,
|
|
94465
|
+
type: "application_status_changed",
|
|
94466
|
+
title: APPLICATION_STATUS_LABELS[status],
|
|
94467
|
+
summary: channel && status === "applied" ? `${channel}\uB85C \uC81C\uCD9C` : note ?? void 0,
|
|
94468
|
+
payload: {
|
|
94469
|
+
from_status: before2?.status ?? null,
|
|
94470
|
+
status,
|
|
94471
|
+
status_label: APPLICATION_STATUS_LABELS[status],
|
|
94472
|
+
note: note ?? null,
|
|
94473
|
+
submission: submissionPayload
|
|
94474
|
+
},
|
|
94475
|
+
occurred_at: submittedAtToOccurrence(submittedAt)
|
|
94476
|
+
});
|
|
94477
|
+
return application2;
|
|
94478
|
+
});
|
|
94289
94479
|
const interview_unlocked = INTERVIEW_UNLOCK_STATUSES.includes(status);
|
|
94290
94480
|
const hasPrep = !!interviewRepo.getByJob(jobId);
|
|
94291
94481
|
const hint = interview_unlocked && !hasPrep ? "\uC11C\uB958 \uB2E8\uACC4\uB97C \uD1B5\uACFC\uD588\uC5B4\uC694. \uC774 \uACF5\uACE0 \uAE30\uC900\uC73C\uB85C \uC608\uC0C1 \uBA74\uC811 \uC9C8\uBB38\uACFC 1\uBD84 \uC790\uAE30\uC18C\uAC1C\uB97C \uC900\uBE44\uD560\uAE4C\uC694?" : null;
|
|
@@ -94294,15 +94484,19 @@ function updateApplicationStatus(jobId, status, note) {
|
|
|
94294
94484
|
function saveInterviewPrep(input) {
|
|
94295
94485
|
const job = jobRepo.get(input.job_id);
|
|
94296
94486
|
if (!job) throw notFound("\uACF5\uACE0\uB97C \uCC3E\uC744 \uC218 \uC5C6\uC2B5\uB2C8\uB2E4.");
|
|
94297
|
-
const app = applicationRepo.getByJob(job.id);
|
|
94298
|
-
if (!app || !INTERVIEW_UNLOCK_STATUSES.includes(app.status)) {
|
|
94299
|
-
const current = app ? APPLICATION_STATUS_LABELS[app.status] : "\uBBF8\uC9C0\uC6D0";
|
|
94300
|
-
throw conflict(
|
|
94301
|
-
`\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 \uC9C0\uC6D0 \uC0C1\uD0DC\uB97C '\uC11C\uB958 \uD569\uACA9' \uC774\uC0C1\uC73C\uB85C \uBC14\uAFBC \uB4A4 \uB2E4\uC2DC \uC2DC\uB3C4\uD558\uC138\uC694.`
|
|
94302
|
-
);
|
|
94303
|
-
}
|
|
94304
94487
|
const prep = interviewRepo.save(input);
|
|
94305
94488
|
activityRepo.log("interview_prep_saved", `${job.company} \xB7 ${job.position} \uBA74\uC811 \uC900\uBE44 \uC790\uB8CC\uB97C \uC800\uC7A5\uD588\uC2B5\uB2C8\uB2E4.`, "interview_prep", prep.id);
|
|
94489
|
+
timelineRepo.add({
|
|
94490
|
+
job_id: job.id,
|
|
94491
|
+
type: "interview_prep_saved",
|
|
94492
|
+
title: "\uBA74\uC811 \uC900\uBE44",
|
|
94493
|
+
summary: prep.questions.length > 0 ? `\uC608\uC0C1 \uC9C8\uBB38 ${prep.questions.length}\uAC1C` : prep.notes ?? void 0,
|
|
94494
|
+
payload: {
|
|
94495
|
+
interview_prep_id: prep.id,
|
|
94496
|
+
question_count: prep.questions.length
|
|
94497
|
+
},
|
|
94498
|
+
occurred_at: prep.updated_at
|
|
94499
|
+
});
|
|
94306
94500
|
return prep;
|
|
94307
94501
|
}
|
|
94308
94502
|
|
|
@@ -94323,6 +94517,8 @@ var HUMANIZE_WRITING_GUIDE = `# \uC0AC\uB78C\uC774 \uC4F4 \uAC83\uCC98\uB7FC: \u
|
|
|
94323
94517
|
\uBAA9\uD45C: \uC0AC\uC2E4\uACFC \uACBD\uD5D8\uC740 100% \uADF8\uB300\uB85C \uB450\uBA74\uC11C, "AI\uAC00 \uC4F4 \uD2F0"\uAC00 \uB098\uB294 \uBB38\uC7A5 \uC2B5\uAD00\uB9CC \uC81C\uAC70\uD55C\uB2E4.
|
|
94324
94518
|
\uAC80\uC5F4\uAE30\uB97C \uC18D\uC774\uB294 \uAC8C \uC544\uB2C8\uB77C, \uCC44\uC6A9 \uB2F4\uB2F9\uC790\uAC00 \uC77D\uAE30\uC5D0 \uC790\uC5F0\uC2A4\uB7FD\uACE0 \uC0AC\uB78C \uB0C4\uC0C8 \uB098\uB294 \uAE00\uC744 \uC4F0\uB294 \uAC83\uC774 \uBAA9\uC801\uC774\uB2E4.
|
|
94325
94519
|
|
|
94520
|
+
> **\uC5B8\uC5B4 \uBC94\uC704:** \uC544\uB798 AI-tell \uBAA9\uB85D\uC740 \uD55C\uAD6D\uC5B4 \uAE00 \uAE30\uC900\uC774\uB2E4. \uC601\uC5B4 \uB4F1 \uB2E4\uB978 \uC5B8\uC5B4\uB85C \uC4F8 \uB54C\uB294 \uC774 \uBAA9\uB85D\uC744 \uADF8\uB300\uB85C \uC801\uC6A9\uD558\uC9C0 \uB9D0\uACE0, **\uAC19\uC740 \uC6D0\uB9AC**(\uD074\uB9AC\uC170\xB7\uAE30\uACC4\uC801 \uBCD1\uB82C\xB7\uACFC\uC7A5 \uC218\uC2DD\xB7\uACF5\uD5C8\uD55C \uC77C\uBC18\uB860 \uC81C\uAC70, \uAD6C\uCCB4\uC131, \uC0AC\uC2E4\xB7\uC218\uCE58 \uBCF4\uC874)\uB97C \uADF8 \uC5B8\uC5B4\uC758 \uC790\uC5F0\uC2A4\uB7EC\uC6B4 \uAD00\uC2B5\uC73C\uB85C \uC801\uC6A9\uD55C\uB2E4. \uACB0\uACFC\uBB3C\uC758 \uC5B8\uC5B4\uB294 \uB300\uC0C1 \uACF5\uACE0\xB7\uC2DC\uC7A5\uC744 \uB530\uB978\uB2E4.
|
|
94521
|
+
|
|
94326
94522
|
## \uC808\uB300 \uC6D0\uCE59
|
|
94327
94523
|
- \uC800\uC7A5\uB41C \uC2E4\uC81C \uACBD\uD5D8\xB7\uC218\uCE58\xB7\uD68C\uC0AC\uBA85\xB7\uACE0\uC720\uBA85\uC0AC\xB7\uC9C1\uC811 \uC778\uC6A9\uC740 \uC808\uB300 \uBC14\uAFB8\uAC70\uB098 \uC9C0\uC5B4\uB0B4\uC9C0 \uC54A\uB294\uB2E4. \uBB38\uC7A5 \uACB0\uB9CC \uB2E4\uB4EC\uB294\uB2E4.
|
|
94328
94524
|
- \uBE48\uCE78\uC774\uB098 \uD655\uC778\uC774 \uD544\uC694\uD55C \uBD80\uBD84\uC740 \uB9E4\uB044\uB7FD\uAC8C \uCC44\uC6CC \uB123\uC9C0 \uB9D0\uACE0 \uADF8\uB300\uB85C \uD45C\uC2DC\uD574 \uC0AC\uC6A9\uC790\uC5D0\uAC8C \uBB3B\uB294\uB2E4.
|
|
@@ -94364,6 +94560,33 @@ var HUMANIZE_WRITING_GUIDE = `# \uC0AC\uB78C\uC774 \uC4F4 \uAC83\uCC98\uB7FC: \u
|
|
|
94364
94560
|
- \uC18C\uB9AC \uB0B4\uC5B4 \uC77D\uC5C8\uC744 \uB54C \uC5B4\uC0C9\uD558\uAC70\uB098 "\uC0AC\uB78C\uC774 \uC774\uB807\uAC8C \uB9D0 \uC548 \uD558\uB294\uB370" \uC2F6\uC740 \uACF3\uC744 \uB2E4\uB4EC\uB294\uB2E4.
|
|
94365
94561
|
- \uC0AC\uC2E4\xB7\uC218\uCE58\xB7\uACE0\uC720\uBA85\uC0AC\uAC00 \uC6D0\uBCF8\uACFC 100% \uC77C\uCE58\uD558\uB294\uAC00?
|
|
94366
94562
|
- \uC0AC\uC6A9\uC790\uC758 \uD1A4\uACFC \uAC15\uC870 \uD3EC\uC778\uD2B8\uAC00 \uC0B4\uC544 \uC788\uB294\uAC00?`;
|
|
94563
|
+
var STRUCTURED_DOC_WRITING_GUIDE = `# \uAD6C\uC870\uD615 \uBB38\uC11C(\uACBD\uB825\uAE30\uC220\uC11C\xB7\uC774\uB825\uC11C\xB7\uD3EC\uD2B8\uD3F4\uB9AC\uC624) \uBCF4\uC815
|
|
94564
|
+
|
|
94565
|
+
\uACBD\uB825\uAE30\uC220\uC11C\xB7\uC774\uB825\uC11C\xB7\uD3EC\uD2B8\uD3F4\uB9AC\uC624\uB294 \uCC44\uC6A9 \uB2F4\uB2F9\uC790\uAC00 \uCC98\uC74C\uBD80\uD130 \uB05D\uAE4C\uC9C0 \uC77D\uB294 \uAE00\uC774 \uC544\uB2C8\uB77C \uBA87 \uCD08 \uC548\uC5D0 "\uC2A4\uCE94"\uD558\uB294 \uBB38\uC11C\uB2E4. \uBD88\uB9BF, \uBC88\uD638 \uB9E4\uAE34 \uC131\uACFC, \uC9C1\uBB34\xB7\uAE30\uAC04\xB7\uC5ED\uD560\uC744 \uAD6C\uBD84\uD55C \uC139\uC158 \uAD6C\uC870\uB294 AI\uAC00 \uC4F4 \uD2F0\uAC00 \uC544\uB2C8\uB77C \uC774 \uBB38\uC11C\uC758 \uC815\uC11D\uC774\uB2E4. \uC790\uAE30\uC18C\uAC1C\uC11C\uCC98\uB7FC \uC904\uAE00(\uC0B0\uBB38)\uB85C \uD480\uC9C0 \uB9D0\uACE0 \uAD6C\uC870\uB97C \uBCF4\uC874\uD55C\uB2E4.
|
|
94566
|
+
|
|
94567
|
+
## \uC704 8\uAC1C AI-tell \uC911 \uAD6C\uC870\uD615\uC5D0\uC11C \uB2E4\uB974\uAC8C \uC801\uC6A9\uD558\uB294 \uAC83
|
|
94568
|
+
- 3\uBC88(\uAE30\uACC4\uC801 \uBCD1\uB82C)\xB78\uBC88(\uD615\uC2DD \uACFC\uC6A9)\uC740 \uC0B0\uBB38 \uBB38\uC7A5\uC5D0\uB9CC \uC801\uC6A9\uD55C\uB2E4. \uC131\uACFC\uB97C \uB098\uC5F4\uD558\uB294 \uBD88\uB9BF\xB7\uBC88\uD638 \uBAA9\uB85D \uAD6C\uC870 \uC790\uCCB4\uC5D0\uB294 \uC801\uC6A9\uD558\uC9C0 \uC54A\uB294\uB2E4 \u2014 \uBD88\uB9BF\uB85C \uB04A\uC5B4 \uC4F0\uB294 \uAC83\uC740 \uAC00\uB3C5\uC131\uC744 \uC704\uD55C \uC815\uC0C1 \uAD6C\uC870\uB2E4.
|
|
94569
|
+
- \uB2E8 \uC758\uBBF8 \uC5C6\uB294 "\uCCAB\uC9F8\xB7\uB458\uC9F8\xB7\uC14B\uC9F8" \uC11C\uC218 \uB098\uC5F4, \uBAA8\uB4E0 \uBD88\uB9BF\uC744 \uB611\uAC19\uC740 \uACE8\uACA9("~\uC744 \uD1B5\uD574 ~\uC744 \uD568")\uC73C\uB85C \uCC0D\uC5B4\uB0B4\uB294 \uAC83, \uACFC\uD55C \uAD75\uAC8C\xB7\uC774\uBAA8\uC9C0\xB7\uAC00\uC6B4\uB383\uC810 \uB5A1\uCE60\uC740 \uAD6C\uC870\uD615\uC5D0\uC11C\uB3C4 \uC81C\uAC70\uD55C\uB2E4.
|
|
94570
|
+
|
|
94571
|
+
## \uAD6C\uC870\uB294 \uC0B4\uB9AC\uACE0, \uBD88\uB9BF '\uC548\uC758 \uC5B8\uC5B4'\uB9CC \uC0AC\uB78C\uB2F5\uAC8C
|
|
94572
|
+
- \uAC01 \uBD88\uB9BF\uC740 \uB3D9\uC0AC\uB098 \uC218\uCE58\uB85C \uC2DC\uC791\uD558\uACE0, \uAC80\uC99D \uAC00\uB2A5\uD55C \uC0AC\uC2E4(\uC22B\uC790\xB7\uAE30\uAC04\xB7\uB3C4\uAD6C\xB7\uC5ED\uD560\xB7\uACB0\uACFC)\uC744 \uD55C \uC904\uC5D0 \uB2F4\uB294\uB2E4.
|
|
94573
|
+
- \uBD88\uB9BF \uC548\uC758 \uBC88\uC5ED\uD22C\xB7\uD074\uB9AC\uC170\xB7\uACF5\uD5C8\uD55C \uC77C\uBC18\uB860\xB7\uC218\uB3D9\uD0DC\uB294 \uC790\uAE30\uC18C\uAC1C\uC11C\uC640 \uB611\uAC19\uC774 \uC81C\uAC70\uD55C\uB2E4. (\uC608: "\uBD84\uC11D\uC744 \uC9C4\uD589\uD558\uC600\uC2B5\uB2C8\uB2E4" \u2192 "\uBD84\uC11D\uD588\uB2E4", "\uB9CE\uC740 \uC131\uACFC\uB97C \uB0C8\uC2B5\uB2C8\uB2E4" \u2192 \uC2E4\uC81C \uC218\uCE58)
|
|
94574
|
+
- STAR\uC744 \uD55C\uB450 \uC904\uB85C \uC555\uCD95\uD55C\uB2E4: \uBB34\uC5C7\uC744 \uC65C \uD588\uACE0 \uACB0\uACFC \uC218\uCE58\uAC00 \uC5B4\uB5BB\uAC8C \uB410\uB294\uC9C0.
|
|
94575
|
+
|
|
94576
|
+
## Do / Don't
|
|
94577
|
+
- Do: \uB450\uAD04\uC2DD \uBD88\uB9BF(\uACB0\uACFC\xB7\uC218\uCE58\uB97C \uC55E\uC138\uC6C0), \uC9C1\uBB34\xB7\uAE30\uAC04\xB7\uC5ED\uD560 \uAD6C\uBD84, \uC131\uACFC\uB97C \uC22B\uC790\uB85C.
|
|
94578
|
+
- Don't: \uACBD\uB825\uAE30\uC220\uC11C\uB97C \uC790\uAE30\uC18C\uAC1C\uC11C\uCC98\uB7FC \uC904\uAE00\uB85C \uD3C9\uD0C4\uD654\uD558\uC9C0 \uC54A\uB294\uB2E4. \uBD88\uB9BF\uC744 \uC5C6\uC560 \uC2A4\uCE94\uD558\uAE30 \uC5B4\uB835\uAC8C \uB9CC\uB4E4\uC9C0 \uC54A\uB294\uB2E4. \uB77C\uBCA8\xB7\uAD6C\uC870\uB97C \uB2E4 \uAC77\uC5B4\uB0B4 \uAC00\uB3C5\uC131\uC744 \uB5A8\uC5B4\uB728\uB9AC\uC9C0 \uC54A\uB294\uB2E4.
|
|
94579
|
+
|
|
94580
|
+
\uD575\uC2EC: \uC790\uAE30\uC18C\uAC1C\uC11C\uB294 \uC0AC\uB78C\uC758 \uBAA9\uC18C\uB9AC(\uC0B0\uBB38)\uB85C, \uACBD\uB825\uAE30\uC220\uC11C\xB7\uC774\uB825\uC11C\uB294 \uC0AC\uB78C\uC758 \uC5B8\uC5B4\uB85C \uC4F4 \uAE54\uB054\uD55C \uAD6C\uC870\uB85C. \uB458 \uB2E4 \uC0AC\uC2E4\xB7\uC218\uCE58\xB7\uACE0\uC720\uBA85\uC0AC\uB294 100% \uBCF4\uC874\uD55C\uB2E4.`;
|
|
94581
|
+
var STRUCTURED_DOC_TYPES = /* @__PURE__ */ new Set(["career_description", "resume", "portfolio"]);
|
|
94582
|
+
function getWritingStyleGuide(docType) {
|
|
94583
|
+
if (docType && STRUCTURED_DOC_TYPES.has(docType)) {
|
|
94584
|
+
return `${HUMANIZE_WRITING_GUIDE}
|
|
94585
|
+
|
|
94586
|
+
${STRUCTURED_DOC_WRITING_GUIDE}`;
|
|
94587
|
+
}
|
|
94588
|
+
return HUMANIZE_WRITING_GUIDE;
|
|
94589
|
+
}
|
|
94367
94590
|
|
|
94368
94591
|
// packages/workflows/src/definitions.ts
|
|
94369
94592
|
var WORKFLOWS = [
|
|
@@ -94374,7 +94597,7 @@ var WORKFLOWS = [
|
|
|
94374
94597
|
trigger: '\uC0AC\uC6A9\uC790\uAC00 \uCC98\uC74C CareerMate\uC5D0 \uC5F0\uACB0\uD588\uAC70\uB098, "\uC2DC\uC791\uD558\uC790 / \uC14B\uC5C5\uD574\uC918 / \uD504\uB85C\uD544 \uB4F1\uB85D"\uC774\uB77C\uACE0 \uC694\uCCAD\uD560 \uB54C.',
|
|
94375
94598
|
steps: [
|
|
94376
94599
|
"`get_onboarding_status`\uB97C \uD638\uCD9C\uD574 \uD604\uC7AC \uB4F1\uB85D \uC0C1\uD0DC(has_profile, has_resume, has_cover_letter, has_experience, has_skills, profile_completeness, next_steps)\uB97C \uD655\uC778\uD55C\uB2E4.",
|
|
94377
|
-
'\uBE44\uC5B4 \uC788\uB294 \uD56D\uBAA9\uC744 \uC0AC\uC6A9\uC790\
|
|
94600
|
+
'\uBE44\uC5B4 \uC788\uB294 \uD56D\uBAA9\uC744 \uC0AC\uC6A9\uC790\uC758 \uC5B8\uC5B4\uB85C \uC27D\uAC8C \uC548\uB0B4\uD558\uACE0, \uBA3C\uC800 "\uAE30\uC874\uC5D0 \uC791\uC131\uD574 \uB454 \uC774\uB825\uC11C\xB7\uACBD\uB825\uAE30\uC220\uC11C\xB7\uC790\uAE30\uC18C\uAC1C\uC11C \uD30C\uC77C\uC774 \uC788\uB294\uC9C0" \uBB3B\uB294\uB2E4(hwp/docx/pdf \uBAA8\uB450 \uAC00\uB2A5).',
|
|
94378
94601
|
'\uD30C\uC77C \uC785\uB825 \uBD84\uAE30: \u2460 \uC0AC\uC6A9\uC790\uAC00 "\uD30C\uC77C\uC774 \uC788\uB2E4"\uACE0 \uD558\uBA74 `open_inbox`\uB85C \uC778\uC785 \uD3F4\uB354\uB97C \uC5F4\uC5B4 \uD30C\uC77C\uC744 \uB123\uAC8C \uD558\uACE0, "\uB2E4 \uB123\uC5C8\uB2E4"\uACE0 \uD558\uBA74 `read_inbox`\uB85C \uBCF8\uBB38\uC744 \uC77D\uB294\uB2E4(pdf\xB7\uC774\uBBF8\uC9C0\uB294 read_inbox\uAC00 \uACBD\uB85C\uB9CC \uC8FC\uBBC0\uB85C \uD074\uB77C\uC774\uC5B8\uD2B8\uC758 \uD30C\uC77C \uC77D\uAE30\uB85C \uC9C1\uC811 \uC77D\uB294\uB2E4). \u2461 \uC0AC\uC6A9\uC790\uAC00 \uD30C\uC77C \uACBD\uB85C\uB97C \uC9C1\uC811 \uC54C\uB824\uC8FC\uBA74 `read_document`\uB85C \uC77D\uB294\uB2E4. \u2462 "\uC5C6\uB2E4/\uC9C1\uC811 \uC785\uB825/\uD14D\uC2A4\uD2B8\uB85C \uBD99\uC5EC\uB123\uAE30"\uBA74 \uD3F4\uB354\uB97C \uC5F4\uC9C0 \uB9D0\uACE0 \uBC1B\uC740 \uD14D\uC2A4\uD2B8\uB97C \uADF8\uB300\uB85C \uC4F4\uB2E4. (\uBB3B\uC9C0\uB3C4 \uC54A\uACE0 open_inbox\uB85C \uD3F4\uB354\uB97C \uC790\uB3D9\uC73C\uB85C \uC5F4\uC9C0 \uC54A\uB294\uB2E4.)',
|
|
94379
94602
|
"\uC218\uC9D1\uD55C \uC815\uBCF4\uB97C \uAD6C\uC870\uD654\uD574 `save_profile`\uB85C \uC800\uC7A5\uD55C\uB2E4(\uC774\uB984\xB7\uC5F0\uB77D\uCC98\xB7headline\xB7summary\xB7desired_roles\xB7desired_conditions, \uADF8\uB9AC\uACE0 \uAE00\uC4F0\uAE30 \uC120\uD638\uC778 preferred_tone\uACFC emphasis_points \uD3EC\uD568). \uD30C\uC77C \uCD9C\uCC98\uB294 source=upload, \uC9C1\uC811 \uC785\uB825\uC740 manual.",
|
|
94380
94603
|
"\uC5C5\uB85C\uB4DC\uD55C \uC774\uB825\uC11C/\uACBD\uB825\uAE30\uC220\uC11C/\uD3EC\uD2B8\uD3F4\uB9AC\uC624 \uBCF8\uBB38\uC744 `add_resume`\uB85C \uC800\uC7A5\uD55C\uB2E4(kind\xB7title \uC9C0\uC815, \uB300\uD45C \uBB38\uC11C\uB294 is_primary=true).",
|
|
@@ -94395,7 +94618,7 @@ var WORKFLOWS = [
|
|
|
94395
94618
|
"\uACF5\uACE0 \uC694\uAD6C\uC0AC\uD56D\uACFC \uC0AC\uC6A9\uC790 \uACBD\uB825/\uC2A4\uD0AC/\uD504\uB85C\uC81D\uD2B8\uB97C \uBE44\uAD50\uD55C\uB2E4: \uC77C\uCE58\uD558\uB294 \uAC15\uC810(strengths)\uACFC \uBD80\uC871\uD55C \uBD80\uBD84(gaps), \uB9E4\uCE6D \uD0A4\uC6CC\uB4DC(matched_keywords)\uC640 \uB204\uB77D \uD0A4\uC6CC\uB4DC(missing_keywords)\uB97C \uB3C4\uCD9C\uD558\uACE0, \uC885\uD569 \uC801\uD569\uB3C4 \uC810\uC218(score 0~100)\uC640 \uC694\uC57D(summary), \uC9C0\uC6D0 \uC804\uB7B5 \uC81C\uC548(recommendations)\uC744 \uC815\uB9AC\uD55C\uB2E4. \uC5C6\uB294 \uACBD\uD5D8\uC744 \uC9C0\uC5B4\uB0B4\uC9C0 \uC54A\uB294\uB2E4.",
|
|
94396
94619
|
"\uC544\uC9C1 \uC800\uC7A5\uB418\uC9C0 \uC54A\uC740 \uACF5\uACE0\uB77C\uBA74 `save_job_posting`\uC73C\uB85C \uACF5\uACE0\uB97C \uC800\uC7A5\uD558\uACE0 job_id\uB97C \uD655\uBCF4\uD55C\uB2E4.",
|
|
94397
94620
|
"\uB3C4\uCD9C\uD55C \uBD84\uC11D \uACB0\uACFC\uB97C `save_fit_analysis`\uB85C \uC800\uC7A5\uD55C\uB2E4(job_id, score, summary, strengths, gaps, matched_keywords, missing_keywords, recommendations).",
|
|
94398
|
-
"\uBD84\uC11D \uACB0\uACFC\uB97C \uC0AC\uC6A9\uC790\
|
|
94621
|
+
"\uBD84\uC11D \uACB0\uACFC\uB97C \uC0AC\uC6A9\uC790\uC758 \uC5B8\uC5B4\uB85C \uC27D\uAC8C \uC124\uBA85\uD55C\uB2E4(\uC798 \uB9DE\uB294 \uC810, \uBCF4\uC644\uD560 \uC810, \uCD94\uCC9C \uC804\uB7B5). \uAE30\uC220 \uC6A9\uC5B4\uB294 \uBE7C\uACE0 \uC804\uB2EC\uD55C\uB2E4.",
|
|
94399
94622
|
'\uBD84\uC11D \uB4A4 \uACE7\uC7A5 \uC790\uAE30\uC18C\uAC1C\uC11C\uB97C \uC4F0\uC9C0 \uB9D0\uACE0, "\uC774 \uACF5\uACE0\uC5D0 \uB9DE\uCD98 \uC790\uAE30\uC18C\uAC1C\uC11C\uB97C \uC368\uB4DC\uB9B4\uAE4C\uC694?"\uB77C\uACE0 \uBB3B\uACE0 \uC120\uD0DD\uC9C0\uB97C \uC81C\uC2DC\uD55C\uB2E4: \u2460 "\uB124, \uC774 \uACF5\uACE0\uC5D0 \uB9DE\uCD98 \uC790\uAE30\uC18C\uAC1C\uC11C\uB97C \uC368\uC918" \u2461 "\uC544\uB2C8\uC694, \uBD84\uC11D\uB9CC \uC800\uC7A5\uD574\uC918".',
|
|
94400
94623
|
'\uC0AC\uC6A9\uC790\uAC00 \u2460\uC744 \uC120\uD0DD\uD558\uBA74 \uC790\uAE30\uC18C\uAC1C\uC11C\uB97C \uC791\uC131\uD558\uAE30 \uC9C1\uC804\uC5D0 `get_writing_style_guide`\uB97C \uD638\uCD9C\uD574 "AI \uD2F0 \uC548 \uB098\uB294 \uAE00\uC4F0\uAE30 \uADDC\uCE59"\uC744 \uAC00\uC838\uC628\uB2E4. \u2461\uB97C \uC120\uD0DD\uD558\uBA74 \uC790\uC18C\uC11C \uC791\uC131 \uC5C6\uC774 \uBA48\uCD94\uACE0 \uC800\uC7A5 \uACB0\uACFC\uC640 \uB300\uC2DC\uBCF4\uB4DC \uD655\uC778\uB9CC \uC548\uB0B4\uD55C\uB2E4.',
|
|
94401
94624
|
"\uC801\uD569\uB3C4 \uBD84\uC11D\xB7\uAE00\uC4F0\uAE30 \uC120\uD638\uC640 \uAE00\uC4F0\uAE30 \uADDC\uCE59\uC744 \uD568\uAED8 \uBC18\uC601\uD574 \uC790\uAE30\uC18C\uAC1C\uC11C\uB97C \uC791\uC131\uD558\uACE0(\uBC88\uC5ED\uD22C\xB7\uD074\uB9AC\uC170\xB7\uAE30\uACC4\uC801 \uBCD1\uB82C \uC81C\uAC70, \uC0AC\uC2E4\xB7\uC218\uCE58\uB294 \uADF8\uB300\uB85C), `save_cover_letter_version`\uC73C\uB85C \uC800\uC7A5\uD55C\uB2E4(job_id \uC5F0\uACB0, note\uC5D0 \uC791\uC131 \uC758\uB3C4 \uC694\uC57D).",
|
|
@@ -94414,7 +94637,24 @@ var WORKFLOWS = [
|
|
|
94414
94637
|
"\uC800\uC7A5\uB41C \uC2E4\uC81C \uACBD\uD5D8\xB7\uC131\uACFC\uB9CC\uC73C\uB85C \uC790\uAE30\uC18C\uAC1C\uC11C\uB97C \uC791\uC131\uD558\uB418, \uC704 \uAE00\uC4F0\uAE30 \uADDC\uCE59\uC744 \uC801\uC6A9\uD574 \uC0AC\uB78C\uC774 \uC4F4 \uB4EF \uC790\uC5F0\uC2A4\uB7FD\uAC8C \uC4F4\uB2E4(\uC0AC\uC2E4\xB7\uC218\uCE58\xB7\uACE0\uC720\uBA85\uC0AC\uB294 \uADF8\uB300\uB85C). \uBE48\uCE78\uC774\uB098 \uD655\uC778\uC774 \uD544\uC694\uD55C \uBD80\uBD84\uC740 \uCD94\uCE21\uD558\uC9C0 \uB9D0\uACE0 \uD45C\uC2DC\uD574 \uC0AC\uC6A9\uC790\uC5D0\uAC8C \uBB3B\uB294\uB2E4.",
|
|
94415
94638
|
"\uC644\uC131\uBCF8\uC744 `save_cover_letter_version`\uC73C\uB85C \uC800\uC7A5\uD55C\uB2E4(\uAE30\uC874 \uC790\uAE30\uC18C\uAC1C\uC11C\uBA74 cover_letter_id, \uC0C8\uB85C \uB9CC\uB4E4\uBA74 title, \uACF5\uACE0\uC6A9\uC774\uBA74 job_id, \uBCC0\uACBD \uC694\uC57D\uC740 note, source=ai).",
|
|
94416
94639
|
"\uC0AC\uC6A9\uC790\uAC00 \uC6D0\uD558\uBA74 `export_cover_letter`\uB85C \uD30C\uC77C\uB85C \uB0B4\uBCF4\uB0B4\uACE0, \uCD94\uAC00 \uC218\uC815 \uC694\uCCAD\uC774 \uC788\uC73C\uBA74 \uC0C8 \uBC84\uC804\uC73C\uB85C \uB2E4\uC2DC \uC800\uC7A5\uD55C\uB2E4.",
|
|
94417
|
-
"\uC800\uC7A5 \uACB0\uACFC\uB97C \
|
|
94640
|
+
"\uC800\uC7A5 \uACB0\uACFC\uB97C \uC0AC\uC6A9\uC790\uC758 \uC5B8\uC5B4\uB85C \uC54C\uB9AC\uACE0, \uC9C0\uC6D0 \uC0C1\uD0DC \uC5C5\uB370\uC774\uD2B8(`update_application_status`)\uB098 \uBA74\uC811 \uC900\uBE44 \uB4F1 \uB2E4\uC74C \uB2E8\uACC4\uB97C \uC81C\uC548\uD55C\uB2E4."
|
|
94641
|
+
]
|
|
94642
|
+
},
|
|
94643
|
+
{
|
|
94644
|
+
id: "write_career_description",
|
|
94645
|
+
title: "\uACBD\uB825\uAE30\uC220\uC11C \uC791\uC131",
|
|
94646
|
+
description: "\uD504\uB85C\uD544\xB7\uC774\uB825\uC11C\xB7\uACBD\uB825\xB7\uD504\uB85C\uC81D\uD2B8\xB7\uC2A4\uD0AC\uC744 \uADFC\uAC70\uB85C \uC2E4\uC81C \uC81C\uCD9C \uAC00\uB2A5\uD55C \uACBD\uB825\uAE30\uC220\uC11C\uB97C \uC791\uC131\uD558\uACE0 \uBB38\uC11C\uD568\uC5D0 \uC800\uC7A5\uD558\uB294 \uD750\uB984.",
|
|
94647
|
+
trigger: '\uC0AC\uC6A9\uC790\uAC00 "\uACBD\uB825\uAE30\uC220\uC11C \uC368\uC918 / \uACBD\uB825\uAE30\uC220\uC11C \uB9CC\uB4E4\uC5B4\uC918 / \uB0B4 \uACBD\uB825 \uC815\uB9AC\uD574\uC918"\uB77C\uACE0 \uC694\uCCAD\uD560 \uB54C.',
|
|
94648
|
+
steps: [
|
|
94649
|
+
"`get_onboarding_status`\uB85C \uC900\uBE44 \uC0C1\uD0DC\uB97C \uD655\uC778\uD558\uACE0, `get_profile`\xB7`get_resumes`\xB7`get_experiences`\xB7`get_projects`\xB7`get_skills`\uB97C \uD638\uCD9C\uD574 \uAE30\uC874 \uD504\uB85C\uD544, \uC774\uB825\uC11C, \uACBD\uB825\uAE30\uC220\uC11C(kind=career_description), \uACBD\uB825, \uD504\uB85C\uC81D\uD2B8, \uAE30\uC220\uC2A4\uD0DD\uC744 \uBAA8\uB450 \uD655\uC778\uD55C\uB2E4.",
|
|
94650
|
+
"\uC0AC\uC6A9\uC790\uAC00 \uD30C\uC77C \uACBD\uB85C\uB97C \uC8FC\uBA74 `read_document`\uB85C \uC77D\uACE0, \uC778\uC785 \uD3F4\uB354\uB97C \uC0AC\uC6A9\uD588\uB2E4\uBA74 `read_inbox`\uB85C \uBCF8\uBB38\uC744 \uC77D\uB294\uB2E4. \uC774\uBBF8 \uC800\uC7A5\uB41C \uC790\uB8CC\uC640 \uC0C8 \uD30C\uC77C\uC744 \uBE44\uAD50\uD574 \uC911\uBCF5\xB7\uC0C1\uCDA9\uB418\uB294 \uC0AC\uC2E4\uC740 \uD45C\uC2DC\uD558\uACE0 \uCD94\uCE21\uD558\uC9C0 \uC54A\uB294\uB2E4.",
|
|
94651
|
+
'`get_workflow_guide({ workflow_id: "write_career_description" })`\uAC00 \uC548\uB0B4\uD558\uB294 \uC804\uBB38\uAC00 \uC808\uCC28\uB97C \uB530\uB978\uB2E4. \uC791\uC131 \uC9C1\uC804 `get_playbook({ domain: "resume" })`\uC640 `get_playbook({ domain: "ats" })`\uB97C \uBC1B\uC544 \uC2E4\uC81C \uACBD\uB825\uAE30\uC220\uC11C \uD615\uC2DD\uACFC ATS \uCE5C\uD654\uC131\uC744 \uC801\uC6A9\uD55C\uB2E4.',
|
|
94652
|
+
"\uC791\uC131 \uC804\uC5D0 \uBAA9\uC801\uC744 \uD655\uC778\uD55C\uB2E4: \uBC94\uC6A9 \uB9C8\uC2A4\uD130\uBCF8\uC778\uC9C0, \uD2B9\uC815 \uC9C1\uBB34/\uACF5\uACE0\uC6A9\uC778\uC9C0, \uC2E0\uC785/\uBB34\uACBD\uB825\uC774\uB77C \uD504\uB85C\uC81D\uD2B8\xB7\uAD50\uC721\xB7\uD65C\uB3D9 \uC911\uC2EC \uC5ED\uB7C9\uAE30\uC220\uC11C\uB85C \uC4F8\uC9C0, \uBD84\uB7C9\uACFC \uD1A4\uC740 \uC5B4\uB5BB\uAC8C \uD560\uC9C0 \uBB3B\uB294\uB2E4.",
|
|
94653
|
+
"\uACBD\uB825\uAE30\uC220\uC11C\uB294 \uC790\uAE30\uC18C\uAC1C\uC11C\uCC98\uB7FC \uC11C\uC0AC\uB85C \uC4F0\uC9C0 \uC54A\uB294\uB2E4. \uC81C\uBAA9, \uD575\uC2EC \uC694\uC57D, \uD575\uC2EC \uC5ED\uB7C9, \uACBD\uB825/\uD504\uB85C\uC81D\uD2B8\uBCC4 \uC5ED\uD560\xB7\uAE30\uAC04\xB7\uB3C4\uAD6C\xB7\uBB38\uC81C\xB7\uD589\uB3D9\xB7\uC131\uACFC\uB97C \uD45C\uB098 \uBD88\uB9BF \uC911\uC2EC\uC73C\uB85C \uC815\uB9AC\uD55C\uB2E4. \uC218\uCE58\xB7\uD68C\uC0AC\uBA85\xB7\uAE30\uAC04\xB7\uC9C1\uCC45\uC740 \uC800\uC7A5\uB41C \uC0AC\uC2E4\uB9CC \uC4F0\uACE0, \uC5C6\uB294 \uC131\uACFC \uC218\uCE58\uB294 \uB9CC\uB4E4\uC9C0 \uC54A\uB294\uB2E4.",
|
|
94654
|
+
'\uBB34\uACBD\uB825/\uBE44\uAC1C\uBC1C\uC790\uB77C\uBA74 \uACBD\uB825\uC744 \uB0A0\uC870\uD558\uC9C0 \uB9D0\uACE0 \uAD50\uC721\xB7\uD504\uB85C\uC81D\uD2B8\xB7\uC6B4\uC601 \uACBD\uD5D8\xB7\uC5C5\uBB34 \uB3C4\uAD6C\xB7\uD611\uC5C5 \uACBD\uD5D8\xB7\uC131\uACFC \uC99D\uAC70 \uC911\uC2EC\uC758 "\uC5ED\uB7C9\uAE30\uC220\uC11C"\uB85C \uAD6C\uC131\uD55C\uB2E4.',
|
|
94655
|
+
'\uC800\uC7A5 \uC9C1\uC804 `get_verifier({ id: "truthfulness" })`, `get_verifier({ id: "consistency" })`, `get_verifier({ id: "ats-compat" })`\uB97C \uBC1B\uC544 \uB2F9\uC2E0\uC774 \uC9C1\uC811 \uC810\uAC80\uD558\uACE0, \uD5C8\uC704\xB7\uC0C1\uCDA9\xB7\uD0A4\uC6CC\uB4DC \uB204\uB77D\uC744 \uACE0\uCE5C\uB2E4. \uD655\uC778\uC774 \uD544\uC694\uD55C \uC0AC\uC2E4\uC740 \uBCF8\uBB38\uC5D0 \uD45C\uC2DC\uD558\uACE0 \uC0AC\uC6A9\uC790\uC5D0\uAC8C \uBB3B\uB294\uB2E4.',
|
|
94656
|
+
"\uC644\uC131\uBCF8\uC744 `add_resume`\uC73C\uB85C \uC800\uC7A5\uD55C\uB2E4(kind=career_description, source=ai, title\uC740 \uC0AC\uC6A9 \uBAA9\uC801\uC774 \uB4DC\uB7EC\uB098\uAC8C \uC791\uC131, tags\uC5D0 \uC9C1\uBB34/\uC6A9\uB3C4 \uD0A4\uC6CC\uB4DC \uD3EC\uD568). \uB300\uD45C \uBB38\uC11C\uB85C \uC0BC\uC544\uB3C4 \uB418\uB294\uC9C0 \uD655\uC778\uB41C \uACBD\uC6B0\uC5D0\uB9CC is_primary=true\uB97C \uC4F4\uB2E4.",
|
|
94657
|
+
"\uC800\uC7A5 \uACB0\uACFC\uB97C \uC0AC\uC6A9\uC790\uC758 \uC5B8\uC5B4\uB85C \uC54C\uB9AC\uACE0, \uBB38\uC11C \uD0ED\uC5D0\uC11C \uD655\uC778\uD560 \uC218 \uC788\uC74C\uC744 \uC548\uB0B4\uD55C\uB2E4. \uD2B9\uC815 \uACF5\uACE0\uC6A9\uC73C\uB85C \uC791\uC131\uD588\uB2E4\uBA74 \uC774\uC5B4\uC11C \uC790\uAE30\uC18C\uAC1C\uC11C\uB098 \uBA74\uC811 \uC900\uBE44\uB97C \uC81C\uC548\uD55C\uB2E4."
|
|
94418
94658
|
]
|
|
94419
94659
|
},
|
|
94420
94660
|
{
|
|
@@ -94425,7 +94665,7 @@ var WORKFLOWS = [
|
|
|
94425
94665
|
steps: [
|
|
94426
94666
|
"\uD544\uC694\uD558\uBA74 `get_application_context` \uB610\uB294 `get_job_posting`\uC73C\uB85C \uB300\uC0C1 \uC9C0\uC6D0 \uAC74\uACFC \uACF5\uACE0\uB97C \uD655\uC778\uD55C\uB2E4.",
|
|
94427
94667
|
"\uC801\uC808\uD55C \uC0C1\uD0DC\uB85C `update_application_status`\uB97C \uD638\uCD9C\uD55C\uB2E4. 8\uB2E8\uACC4: draft(\uC791\uC131 \uC911), planned(\uC9C0\uC6D0 \uC608\uC815), applied(\uC9C0\uC6D0 \uC644\uB8CC), document_passed(\uC11C\uB958 \uD569\uACA9), interview(\uBA74\uC811 \uC9C4\uD589), final_passed(\uCD5C\uC885 \uD569\uACA9), rejected(\uBD88\uD569\uACA9), on_hold(\uBCF4\uB958). \uBCC0\uACBD \uC0AC\uC720\uB294 note\uC5D0 \uB0A8\uAE34\uB2E4.",
|
|
94428
|
-
"\uBCC0\uACBD \uACB0\uACFC\uB97C \uC0AC\uC6A9\uC790\
|
|
94668
|
+
"\uBCC0\uACBD \uACB0\uACFC\uB97C \uC0AC\uC6A9\uC790\uC758 \uC5B8\uC5B4\uB85C \uC27D\uAC8C \uC54C\uB9B0\uB2E4.",
|
|
94429
94669
|
"\uC0C1\uD0DC\uC5D0 \uB9DE\uB294 \uB2E4\uC74C \uB2E8\uACC4\uB97C \uC81C\uC548\uD55C\uB2E4: applied \u2192 \uACB0\uACFC \uAE30\uB2E4\uB9AC\uAE30 \uC548\uB0B4, document_passed/interview \u2192 \uBA74\uC811 \uC900\uBE44(prepare_interview) \uC81C\uC548, final_passed \u2192 \uCD95\uD558 \uBC0F \uB9C8\uBB34\uB9AC, rejected/on_hold \u2192 \uD68C\uACE0 \uB610\uB294 \uB2E4\uB978 \uACF5\uACE0 \uD0D0\uC0C9 \uC81C\uC548.",
|
|
94430
94670
|
"\uD544\uC694\uD558\uBA74 `open_application`\uC73C\uB85C \uD574\uB2F9 \uC9C0\uC6D0 \uAC74\uC744 \uC5F4\uC5B4 \uBCF4\uC5EC\uC900\uB2E4."
|
|
94431
94671
|
]
|
|
@@ -94433,14 +94673,29 @@ var WORKFLOWS = [
|
|
|
94433
94673
|
{
|
|
94434
94674
|
id: "prepare_interview",
|
|
94435
94675
|
title: "\uBA74\uC811 \uC900\uBE44",
|
|
94436
|
-
description: "\
|
|
94437
|
-
trigger: '\uC9C0\uC6D0 \uC0C1\uD0DC\uAC00 \uC11C\uB958 \uD569\uACA9(document_passed) \uB610\uB294 \uBA74\uC811 \uC9C4\uD589(interview)\uC73C\uB85C \uBC14\uB00C\uC5C8\uC744 \uB54C
|
|
94676
|
+
description: "\uACF5\uACE0 \uAE30\uC900 \uC608\uC0C1 \uC9C8\uBB38\xB7STAR \uB2F5\uBCC0\xB71\uBD84 \uC790\uAE30\uC18C\uAC1C\uB97C \uC900\uBE44\uD574 \uC800\uC7A5\uD558\uB294 \uD750\uB984.",
|
|
94677
|
+
trigger: '\uC0AC\uC6A9\uC790\uAC00 "\uBA74\uC811 \uC900\uBE44 \uB3C4\uC640\uC918"\uB77C\uACE0 \uC694\uCCAD\uD558\uAC70\uB098, \uC9C0\uC6D0 \uC0C1\uD0DC\uAC00 \uC11C\uB958 \uD569\uACA9(document_passed) \uB610\uB294 \uBA74\uC811 \uC9C4\uD589(interview)\uC73C\uB85C \uBC14\uB00C\uC5C8\uC744 \uB54C.',
|
|
94438
94678
|
steps: [
|
|
94439
94679
|
"`get_application_context`(job_id \uD3EC\uD568)\uB97C \uD638\uCD9C\uD574 \uACF5\uACE0, \uD504\uB85C\uD544, \uACBD\uB825/\uD504\uB85C\uC81D\uD2B8, \uC801\uD569\uB3C4 \uBD84\uC11D(\uAC15\uC810\xB7\uAC2D), \uC790\uAE30\uC18C\uAC1C\uC11C\uB97C \uAC00\uC838\uC628\uB2E4.",
|
|
94440
94680
|
"\uACF5\uACE0\uC640 \uC0AC\uC6A9\uC790 \uACBD\uD5D8\uC744 \uBC14\uD0D5\uC73C\uB85C \uC608\uC0C1 \uBA74\uC811 \uC9C8\uBB38(question, intent, followups, answer_outline)\uC744 \uB3C4\uCD9C\uD55C\uB2E4.",
|
|
94441
94681
|
"\uD575\uC2EC \uACBD\uD5D8\uC5D0 \uB300\uD55C STAR \uAC00\uC774\uB4DC(question, situation, task, action, result)\uC640 1\uBD84 \uC790\uAE30\uC18C\uAC1C(self_introduction) \uCD08\uC548\uC744 \uC791\uC131\uD55C\uB2E4. \uC2E4\uC81C \uACBD\uD5D8\uB9CC \uC0AC\uC6A9\uD55C\uB2E4.",
|
|
94442
94682
|
"\uC900\uBE44 \uB0B4\uC6A9\uC744 `save_interview_prep`\uB85C \uC800\uC7A5\uD55C\uB2E4(job_id, questions, star_guides, self_introduction, notes).",
|
|
94443
|
-
"\uC900\uBE44 \uB0B4\uC6A9\uC744 \uC0AC\uC6A9\uC790\
|
|
94683
|
+
"\uC900\uBE44 \uB0B4\uC6A9\uC744 \uC0AC\uC6A9\uC790\uC758 \uC5B8\uC5B4\uB85C \uC27D\uAC8C \uC694\uC57D\uD574 \uC804\uB2EC\uD558\uACE0, \uBAA8\uC758 \uBA74\uC811/\uCD94\uAC00 \uC9C8\uBB38 \uC5F0\uC2B5\uC774\uB098 \uC0C1\uD0DC \uC5C5\uB370\uC774\uD2B8(`update_application_status`\uB85C interview/final_passed)\uB97C \uC81C\uC548\uD55C\uB2E4."
|
|
94684
|
+
]
|
|
94685
|
+
},
|
|
94686
|
+
{
|
|
94687
|
+
id: "build_personal_brand",
|
|
94688
|
+
title: "\uD37C\uC2A4\uB110 \uBE0C\uB79C\uB4DC (LinkedIn\xB7\uD3EC\uD2B8\uD3F4\uB9AC\uC624)",
|
|
94689
|
+
description: "LinkedIn \uD504\uB85C\uD544\uACFC \uD3EC\uD2B8\uD3F4\uB9AC\uC624 \uAC19\uC740 \uC790\uAE30\uD45C\uD604 \uC790\uC0B0\uC744 \uC9C1\uBB34\uC5D0 \uB9DE\uCDB0 \uC791\uC131\xB7\uCD5C\uC801\uD654\uD558\uB294 \uD750\uB984. \uC774\uB825\uC11C \uC784\uD3EC\uD2B8(\uC628\uBCF4\uB529)\uC640 \uBD84\uB9AC\uB41C \uBCC4\uB3C4 \uC791\uC5C5.",
|
|
94690
|
+
trigger: '\uC0AC\uC6A9\uC790\uAC00 "\uB9C1\uD06C\uB4DC\uC778 \uD504\uB85C\uD544 \uBD10\uC918 / \uD3EC\uD2B8\uD3F4\uB9AC\uC624 \uC815\uB9AC\uD574\uC918 / \uD37C\uC2A4\uB110 \uBE0C\uB79C\uB529 \uB3C4\uC640\uC918"\uB77C\uACE0 \uC694\uCCAD\uD560 \uB54C.',
|
|
94691
|
+
steps: [
|
|
94692
|
+
"`get_application_context`(\uAC00\uB2A5\uD558\uBA74 \uB300\uC0C1 job_id \uD3EC\uD568)\uB97C \uD638\uCD9C\uD574 \uD504\uB85C\uD544\xB7\uACBD\uB825\xB7\uD504\uB85C\uC81D\uD2B8\xB7\uC2A4\uD0AC\xB7\uB300\uD45C \uC774\uB825\uC11C\xB7\uAE00\uC4F0\uAE30 \uC120\uD638\uB97C \uAC00\uC838\uC628\uB2E4. \uD0C0\uAE43 \uACF5\uACE0\uAC00 \uC788\uC73C\uBA74 \uADF8 \uD0A4\uC6CC\uB4DC\uB97C \uC0AC\uC804 \uC785\uB825\uC73C\uB85C \uC4F4\uB2E4.",
|
|
94693
|
+
'`get_workflow_guide({ workflow_id: "build_personal_brand" })`\uAC00 \uC548\uB0B4\uD558\uB294 \uC804\uBB38\uAC00 \uC808\uCC28\uB97C \uB530\uB978\uB2E4. \uC791\uC131 \uC9C1\uC804 `get_playbook({ domain: "linkedin-profile" })`\xB7`get_playbook({ domain: "portfolio" })`\uB97C \uBC1B\uC544 \uD5E4\uB4DC\uB77C\uC778\xB7About\xB7Featured\xB73\uB9C9(problem\u2192approach\u2192impact) \uADDC\uBC94\uC744 \uC801\uC6A9\uD55C\uB2E4.',
|
|
94694
|
+
"\uBB34\uC5C7\uC744 \uB9CC\uB4E4\uC9C0 \uD655\uC778\uD55C\uB2E4(LinkedIn \uD504\uB85C\uD544\uB9CC/\uD3EC\uD2B8\uD3F4\uB9AC\uC624\uB9CC/\uB458 \uB2E4, \uD0C0\uAE43 \uC9C1\uBB34, \uAC15\uC870 \uD3EC\uC778\uD2B8). \uC800\uC7A5\uB41C \uC2E4\uC81C \uACBD\uD5D8\xB7\uC131\uACFC\uB9CC \uC4F0\uACE0, \uC5C6\uB294 \uC218\uCE58\xB7\uACE0\uC720\uBA85\uC0AC\uB294 \uCD94\uCE21\uD558\uC9C0 \uB9D0\uACE0 `[\uD655\uC778 \uD544\uC694]`\uB85C \uD45C\uC2DC\uD574 \uC0AC\uC6A9\uC790\uC5D0\uAC8C \uBB3B\uB294\uB2E4.",
|
|
94695
|
+
"LinkedIn: \uD5E4\uB4DC\uB77C\uC778(\uD575\uC2EC \uD0A4\uC6CC\uB4DC\uB97C \uC55E 120\uC790\uC5D0 front-load, \uD558\uB4DC \uC0C1\uD55C 220\uC790)\xB7About \uCCAB \uBB38\uC7A5 \uD6C5\xB7\uC815\uB7C9 \uC131\uACFC\xB7\uC9C1\uBB34 \uD0A4\uC6CC\uB4DC\uB97C \uC791\uC131. \uD3EC\uD2B8\uD3F4\uB9AC\uC624: \uC9C1\uBB34\uC5D0 \uB9DE\uB294 3~6\uAC1C \uD56D\uBAA9\uC744 problem\u2192approach\u2192impact 3\uB9C9\uC73C\uB85C \uAD6C\uC131\uD558\uACE0 \uBCF8\uC778 \uAE30\uC5EC(my_role)\uC640 \uC815\uB7C9 \uC784\uD329\uD2B8\uB97C \uBA85\uC2DC\uD55C\uB2E4.",
|
|
94696
|
+
'\uC800\uC7A5 \uC9C1\uC804 `get_verifier({ id: "human-voice" })`\xB7`get_verifier({ id: "truthfulness" })`\xB7`get_verifier({ id: "consistency" })`\uB97C \uBC1B\uC544 \uB2F9\uC2E0\uC774 \uC9C1\uC811 \uC810\uAC80\uD55C\uB2E4(AI \uD2F0\xB7\uD658\uAC01\xB7\uC0AC\uC2E4 \uBCF4\uC874). \uD0A4\uC6CC\uB4DC \uC0AC\uC804\uC774 \uBE44\uBA74 \uD0A4\uC6CC\uB4DC \uCCB4\uD06C\uB294 \uBCF4\uB958\uD55C\uB2E4.',
|
|
94697
|
+
"\uD3EC\uD2B8\uD3F4\uB9AC\uC624 \uBCF8\uBB38\uC740 `add_resume`(kind=portfolio)\uB85C \uC800\uC7A5\uD55C\uB2E4. LinkedIn \uD504\uB85C\uD544 \uCD08\uC548\uC740 \uC0AC\uC6A9\uC790\uAC00 \uBCF5\uC0AC\uD574 \uC4F0\uB3C4\uB85D \uC81C\uC2DC\uD558\uACE0(\uC804\uC6A9 \uC800\uC7A5\xB7\uAC80\uC99D \uB3C4\uAD6C validate_linkedin_profile\uC740 Phase B \uBBF8\uAD6C\uD604), \uC6D0\uD558\uBA74 \uD30C\uC77C\uB85C \uB0B4\uBCF4\uB0B8\uB2E4.",
|
|
94698
|
+
"\uC800\uC7A5 \uACB0\uACFC\uB97C \uC0AC\uC6A9\uC790\uC758 \uC5B8\uC5B4\uB85C \uC54C\uB9AC\uACE0 \uB300\uC2DC\uBCF4\uB4DC \uB9C1\uD06C\uB97C \uC548\uB0B4\uD558\uBA70, \uB124\uD2B8\uC6CC\uD0B9(\uCD94\uCC9C \uACBD\uB85C)\uC774\uB098 \uACF5\uACE0 \uC9C0\uC6D0\uC73C\uB85C \uC774\uC5B4\uAC08\uC9C0 \uC81C\uC548\uD55C\uB2E4."
|
|
94444
94699
|
]
|
|
94445
94700
|
}
|
|
94446
94701
|
];
|
|
@@ -94524,22 +94779,64 @@ var CAREER_ROUTES = {
|
|
|
94524
94779
|
verifierSequence: ["truthfulness", "consistency"]
|
|
94525
94780
|
},
|
|
94526
94781
|
analyze_job: {
|
|
94527
|
-
eop: "job-analysis",
|
|
94782
|
+
eop: ["job-analysis", "fit-analysis"],
|
|
94528
94783
|
expertSequence: ["fit-matching", "company-research"],
|
|
94529
94784
|
verifierSequence: ["truthfulness", "consistency", "responsiveness-on-target"],
|
|
94530
94785
|
loop: "draft_verify_revise"
|
|
94531
94786
|
},
|
|
94787
|
+
// R22(audit): responsiveness-on-target는 한국 문항형 자소서 전용 검증기(문항별 1:1 응답·
|
|
94788
|
+
// 글자수 상·하한 = "핵심 탈락 사유")인데 analyze_job에만 라우팅돼 있어 정작 자소서 자가검증
|
|
94789
|
+
// 루프에서 빠져 있었다. 동문서답·미응답 문항·글자수 초과를 잡도록 write_cover_letter에 추가.
|
|
94532
94790
|
write_cover_letter: {
|
|
94533
94791
|
eop: "cover-letter",
|
|
94534
94792
|
expertSequence: ["cover-letter", "human-writing", "company-research"],
|
|
94535
|
-
verifierSequence: ["human-voice", "truthfulness", "ats-compat", "consistency"],
|
|
94793
|
+
verifierSequence: ["human-voice", "truthfulness", "responsiveness-on-target", "ats-compat", "consistency"],
|
|
94794
|
+
loop: "draft_verify_revise"
|
|
94795
|
+
},
|
|
94796
|
+
write_career_description: {
|
|
94797
|
+
eop: "career-description",
|
|
94798
|
+
expertSequence: ["resume", "ats"],
|
|
94799
|
+
verifierSequence: ["truthfulness", "consistency", "ats-compat"],
|
|
94536
94800
|
loop: "draft_verify_revise"
|
|
94537
94801
|
},
|
|
94538
94802
|
prepare_interview: {
|
|
94539
94803
|
eop: "interview-prep",
|
|
94540
|
-
expertSequence: ["interview-behavioral", "interview-technical", "company-research"],
|
|
94541
|
-
|
|
94804
|
+
expertSequence: ["recruiter-screen", "interview-behavioral", "interview-technical", "company-research"],
|
|
94805
|
+
// R22(audit): recency-staleness 추가 — 면접의 "최근 소식"·회사 근황이 낡으면 거짓 신선도가
|
|
94806
|
+
// 되므로(company-research) 저장 전 신선도 점검을 푸시한다.
|
|
94807
|
+
verifierSequence: ["truthfulness", "consistency", "recency-staleness"],
|
|
94542
94808
|
loop: "draft_verify_revise"
|
|
94809
|
+
},
|
|
94810
|
+
// R7 A2: manage_application_status had no route → rejection-triage / offer-evaluation /
|
|
94811
|
+
// salary-negotiation were orphaned (served only on-demand via get_playbook). Route the
|
|
94812
|
+
// decision-stage playbooks so they are pushed when the user manages application outcomes.
|
|
94813
|
+
// R7 A4: A2 routed the decision-stage playbooks, but the EOP-free lifecycle domains
|
|
94814
|
+
// onboarding-first-90-days and networking-referrals were still on-demand-only. Anchor them
|
|
94815
|
+
// here (the only EOP-free lifecycle route). NOTE: networking's strongest lever is *before*
|
|
94816
|
+
// applied (pre-referral, networking-referrals §2) — this route is the surfacing point, not
|
|
94817
|
+
// the recommended timing, so surface networking early when the user is pre-application.
|
|
94818
|
+
// linkedin-profile/portfolio stay on-demand pending a dedicated personal-brand workflow id
|
|
94819
|
+
// (FIXES.md / STATUS §7.9 follow-up — onboarding EOP is résumé-import-only, so brand-
|
|
94820
|
+
// creation playbooks would blur its stage meaning). Additive wiring (A1/A2 precedent).
|
|
94821
|
+
manage_application_status: {
|
|
94822
|
+
expertSequence: [
|
|
94823
|
+
"rejection-triage-iteration",
|
|
94824
|
+
"offer-evaluation-decision",
|
|
94825
|
+
"salary-negotiation",
|
|
94826
|
+
"onboarding-first-90-days",
|
|
94827
|
+
"networking-referrals"
|
|
94828
|
+
],
|
|
94829
|
+
// R22(audit): recency-staleness 추가 — 연봉 벤치마크·오퍼 비교는 시점이 지나면 낡은 기준이
|
|
94830
|
+
// 되므로(salary-negotiation/offer-evaluation) 저장 전 신선도 점검을 푸시한다.
|
|
94831
|
+
verifierSequence: ["truthfulness", "consistency", "recency-staleness"]
|
|
94832
|
+
},
|
|
94833
|
+
// R7 후속: linkedin-profile·portfolio는 onboarding(이력서 임포트)과 단계 의미가
|
|
94834
|
+
// 달라(개인 브랜드 자산 *생성*) 전용 워크플로우로 분리(consensus 권고). networking은
|
|
94835
|
+
// manage_application_status에 이미 정박. 저장은 add_resume(kind=portfolio); linkedin
|
|
94836
|
+
// 전용 저장/검증은 Phase B.
|
|
94837
|
+
build_personal_brand: {
|
|
94838
|
+
expertSequence: ["linkedin-profile", "portfolio"],
|
|
94839
|
+
verifierSequence: ["truthfulness", "human-voice", "consistency"]
|
|
94543
94840
|
}
|
|
94544
94841
|
};
|
|
94545
94842
|
function getRoute(id2) {
|
|
@@ -94549,12 +94846,15 @@ function renderRouteGuide(id2) {
|
|
|
94549
94846
|
const route = CAREER_ROUTES[id2];
|
|
94550
94847
|
if (!route) return void 0;
|
|
94551
94848
|
const lines = [];
|
|
94552
|
-
|
|
94849
|
+
const eops = route.eop ? Array.isArray(route.eop) ? route.eop : [route.eop] : [];
|
|
94850
|
+
if (eops.length) {
|
|
94553
94851
|
lines.push("---", "");
|
|
94554
94852
|
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");
|
|
94555
94853
|
lines.push("");
|
|
94556
|
-
|
|
94557
|
-
|
|
94854
|
+
for (const e of eops) {
|
|
94855
|
+
lines.push(getEop(e));
|
|
94856
|
+
lines.push("");
|
|
94857
|
+
}
|
|
94558
94858
|
}
|
|
94559
94859
|
lines.push("## \uC774 \uC791\uC5C5\uC5D0 \uC801\uC6A9\uD560 \uC804\uBB38\uAC00 \uD50C\uB808\uC774\uBD81");
|
|
94560
94860
|
lines.push("\uC791\uC131 \uC9C1\uC804, \uC544\uB798 \uB3C4\uBA54\uC778\uC758 \uAE4A\uC740 \uC9C0\uC2DD\uC744 \uBC1B\uC544 \uC801\uC6A9\uD558\uC138\uC694:");
|
|
@@ -94668,10 +94968,22 @@ function slugify(input, fallback = "document") {
|
|
|
94668
94968
|
function joinBlocks(blocks) {
|
|
94669
94969
|
return blocks.filter((b) => typeof b === "string" && b.trim().length > 0).join("\n\n");
|
|
94670
94970
|
}
|
|
94971
|
+
function bulletList(items) {
|
|
94972
|
+
const lines = items.filter((i2) => typeof i2 === "string" && i2.trim().length > 0).map((i2) => `- ${i2.trim()}`);
|
|
94973
|
+
return lines.join("\n");
|
|
94974
|
+
}
|
|
94671
94975
|
function kv(label, value) {
|
|
94672
94976
|
if (!value || !value.trim()) return "";
|
|
94673
94977
|
return `**${label}**: ${value.trim()}`;
|
|
94674
94978
|
}
|
|
94979
|
+
function dateRange(start, end, current = false) {
|
|
94980
|
+
const s = (start ?? "").trim();
|
|
94981
|
+
const e = current ? "\uD604\uC7AC" : (end ?? "").trim();
|
|
94982
|
+
if (!s && !e) return "";
|
|
94983
|
+
if (!s) return e;
|
|
94984
|
+
if (!e) return s;
|
|
94985
|
+
return `${s} ~ ${e}`;
|
|
94986
|
+
}
|
|
94675
94987
|
function renderInline(escaped) {
|
|
94676
94988
|
let out = escaped;
|
|
94677
94989
|
out = out.replace(/\*\*([^*]+)\*\*/g, "<strong>$1</strong>");
|
|
@@ -94780,6 +95092,123 @@ function coverLetterToHtml(cl, opts) {
|
|
|
94780
95092
|
content: toPrintableHtml(cl.title, coverLetterBody(cl, opts))
|
|
94781
95093
|
};
|
|
94782
95094
|
}
|
|
95095
|
+
function resumeToMarkdown(doc, profile) {
|
|
95096
|
+
const kindLabel = DOCUMENT_KIND_LABELS[doc.kind] ?? doc.kind;
|
|
95097
|
+
const header = [];
|
|
95098
|
+
if (profile?.name) header.push(kv("\uC774\uB984", profile.name));
|
|
95099
|
+
if (profile?.email) header.push(kv("\uC774\uBA54\uC77C", profile.email));
|
|
95100
|
+
if (profile?.phone) header.push(kv("\uC5F0\uB77D\uCC98", profile.phone));
|
|
95101
|
+
const body = joinBlocks([
|
|
95102
|
+
`# ${doc.title}`,
|
|
95103
|
+
`_${kindLabel}_`,
|
|
95104
|
+
header.length ? header.filter(Boolean).join("\n\n") : "",
|
|
95105
|
+
header.length ? "---" : "",
|
|
95106
|
+
(doc.content ?? "").trim() || "_(\uB0B4\uC6A9 \uC5C6\uC74C)_"
|
|
95107
|
+
]);
|
|
95108
|
+
return {
|
|
95109
|
+
filename: `${slugify(doc.title, doc.kind)}.md`,
|
|
95110
|
+
mimeType: MD_MIME,
|
|
95111
|
+
content: body
|
|
95112
|
+
};
|
|
95113
|
+
}
|
|
95114
|
+
function resumeToHtml(doc, profile) {
|
|
95115
|
+
const md = resumeToMarkdown(doc, profile);
|
|
95116
|
+
return {
|
|
95117
|
+
filename: `${slugify(doc.title, doc.kind)}.html`,
|
|
95118
|
+
mimeType: HTML_MIME,
|
|
95119
|
+
content: toPrintableHtml(doc.title, md.content)
|
|
95120
|
+
};
|
|
95121
|
+
}
|
|
95122
|
+
function profileToMarkdown(profile, experiences = [], projects = [], skills = []) {
|
|
95123
|
+
const name = profile.name?.trim() || "\uC774\uB825\uC11C";
|
|
95124
|
+
const contact = [];
|
|
95125
|
+
if (profile.email) contact.push(profile.email);
|
|
95126
|
+
if (profile.phone) contact.push(profile.phone);
|
|
95127
|
+
if (profile.location) contact.push(profile.location);
|
|
95128
|
+
const links = (profile.links ?? []).filter((l2) => l2.url).map((l2) => `[${l2.label || l2.url}](${l2.url})`);
|
|
95129
|
+
const headerBlocks = joinBlocks([
|
|
95130
|
+
`# ${name}`,
|
|
95131
|
+
profile.headline ? `## ${profile.headline}` : "",
|
|
95132
|
+
contact.length ? contact.join(" \xB7 ") : "",
|
|
95133
|
+
links.length ? links.join(" \xB7 ") : ""
|
|
95134
|
+
]);
|
|
95135
|
+
const summaryBlock = profile.summary?.trim() ? joinBlocks(["## \uC18C\uAC1C", profile.summary.trim()]) : "";
|
|
95136
|
+
const desiredLines = [];
|
|
95137
|
+
if (profile.desired_roles?.length) {
|
|
95138
|
+
desiredLines.push(kv("\uD76C\uB9DD \uC9C1\uBB34", profile.desired_roles.join(", ")));
|
|
95139
|
+
}
|
|
95140
|
+
if (profile.desired_conditions?.trim()) {
|
|
95141
|
+
desiredLines.push(kv("\uD76C\uB9DD \uC870\uAC74", profile.desired_conditions));
|
|
95142
|
+
}
|
|
95143
|
+
const desiredBlock = desiredLines.length ? joinBlocks(["## \uD76C\uB9DD \uC0AC\uD56D", desiredLines.filter(Boolean).join("\n\n")]) : "";
|
|
95144
|
+
const expBlocks = experiences.length ? joinBlocks([
|
|
95145
|
+
"## \uACBD\uB825",
|
|
95146
|
+
...experiences.map((e) => {
|
|
95147
|
+
const range2 = dateRange(e.start_date, e.end_date, e.is_current);
|
|
95148
|
+
const titleParts = [e.company, e.role].filter(Boolean).join(" \u2014 ");
|
|
95149
|
+
const subParts = [e.employment_type, range2].filter(Boolean).join(" \xB7 ");
|
|
95150
|
+
return joinBlocks([
|
|
95151
|
+
`### ${titleParts}`,
|
|
95152
|
+
subParts ? `_${subParts}_` : "",
|
|
95153
|
+
e.description?.trim() ? e.description.trim() : "",
|
|
95154
|
+
e.achievements?.length ? bulletList(e.achievements) : "",
|
|
95155
|
+
e.tech?.length ? kv("\uAE30\uC220", e.tech.join(", ")) : ""
|
|
95156
|
+
]);
|
|
95157
|
+
})
|
|
95158
|
+
]) : "";
|
|
95159
|
+
const projBlocks = projects.length ? joinBlocks([
|
|
95160
|
+
"## \uD504\uB85C\uC81D\uD2B8",
|
|
95161
|
+
...projects.map((p) => {
|
|
95162
|
+
const range2 = dateRange(p.start_date, p.end_date);
|
|
95163
|
+
const subParts = [p.role, range2].filter(Boolean).join(" \xB7 ");
|
|
95164
|
+
return joinBlocks([
|
|
95165
|
+
`### ${p.name}`,
|
|
95166
|
+
subParts ? `_${subParts}_` : "",
|
|
95167
|
+
p.description?.trim() ? p.description.trim() : "",
|
|
95168
|
+
p.highlights?.length ? bulletList(p.highlights) : "",
|
|
95169
|
+
p.tech?.length ? kv("\uAE30\uC220", p.tech.join(", ")) : "",
|
|
95170
|
+
p.url ? kv("\uB9C1\uD06C", p.url) : ""
|
|
95171
|
+
]);
|
|
95172
|
+
})
|
|
95173
|
+
]) : "";
|
|
95174
|
+
let skillsBlock = "";
|
|
95175
|
+
if (skills.length) {
|
|
95176
|
+
const groups = /* @__PURE__ */ new Map();
|
|
95177
|
+
for (const s of skills) {
|
|
95178
|
+
const cat = s.category?.trim() || "\uAE30\uD0C0";
|
|
95179
|
+
const label = s.level?.trim() ? `${s.name} (${s.level.trim()})` : s.name;
|
|
95180
|
+
if (!groups.has(cat)) groups.set(cat, []);
|
|
95181
|
+
groups.get(cat).push(label);
|
|
95182
|
+
}
|
|
95183
|
+
const lines = [...groups.entries()].map(
|
|
95184
|
+
([cat, items]) => kv(cat, items.join(", "))
|
|
95185
|
+
);
|
|
95186
|
+
skillsBlock = joinBlocks(["## \uBCF4\uC720 \uAE30\uC220", lines.filter(Boolean).join("\n\n")]);
|
|
95187
|
+
}
|
|
95188
|
+
const content = joinBlocks([
|
|
95189
|
+
headerBlocks,
|
|
95190
|
+
"---",
|
|
95191
|
+
summaryBlock,
|
|
95192
|
+
desiredBlock,
|
|
95193
|
+
expBlocks,
|
|
95194
|
+
projBlocks,
|
|
95195
|
+
skillsBlock
|
|
95196
|
+
]);
|
|
95197
|
+
return {
|
|
95198
|
+
filename: `${slugify(name, "resume")}-resume.md`,
|
|
95199
|
+
mimeType: MD_MIME,
|
|
95200
|
+
content
|
|
95201
|
+
};
|
|
95202
|
+
}
|
|
95203
|
+
function profileToHtml(profile, experiences = [], projects = [], skills = []) {
|
|
95204
|
+
const md = profileToMarkdown(profile, experiences, projects, skills);
|
|
95205
|
+
const title = profile.name?.trim() || "\uC774\uB825\uC11C";
|
|
95206
|
+
return {
|
|
95207
|
+
filename: `${slugify(title, "resume")}-resume.html`,
|
|
95208
|
+
mimeType: HTML_MIME,
|
|
95209
|
+
content: toPrintableHtml(title, md.content)
|
|
95210
|
+
};
|
|
95211
|
+
}
|
|
94783
95212
|
|
|
94784
95213
|
// packages/parsers/src/html.ts
|
|
94785
95214
|
var NAMED_ENTITIES = {
|
|
@@ -95340,7 +95769,12 @@ async function extractDocument(input, baseDir) {
|
|
|
95340
95769
|
path: filePath,
|
|
95341
95770
|
...over
|
|
95342
95771
|
});
|
|
95343
|
-
|
|
95772
|
+
let realPath = filePath;
|
|
95773
|
+
try {
|
|
95774
|
+
realPath = fs4.realpathSync.native(filePath);
|
|
95775
|
+
} catch {
|
|
95776
|
+
}
|
|
95777
|
+
if (SENSITIVE_PATH_RE.test(filePath) || SENSITIVE_PATH_RE.test(realPath)) {
|
|
95344
95778
|
return base("unsupported", {
|
|
95345
95779
|
warnings: [
|
|
95346
95780
|
"\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."
|
|
@@ -96022,14 +96456,20 @@ function getUpdateStatus() {
|
|
|
96022
96456
|
if (cacheExpired(cache2)) refreshInBackground();
|
|
96023
96457
|
return buildStatus(cache2);
|
|
96024
96458
|
}
|
|
96025
|
-
async function getUpdateStatusAsync() {
|
|
96459
|
+
async function getUpdateStatusAsync(force = false) {
|
|
96026
96460
|
if (checkDisabled()) return buildStatus(null);
|
|
96027
|
-
|
|
96028
|
-
if (cacheExpired(cache2))
|
|
96029
|
-
|
|
96030
|
-
|
|
96031
|
-
|
|
96032
|
-
|
|
96461
|
+
const cache2 = readCache();
|
|
96462
|
+
if (!force && !cacheExpired(cache2)) return buildStatus(cache2);
|
|
96463
|
+
const latest = await fetchLatest();
|
|
96464
|
+
if (latest !== null) {
|
|
96465
|
+
const fresh = { checkedAt: Date.now(), latest };
|
|
96466
|
+
writeCache(fresh);
|
|
96467
|
+
return buildStatus(fresh);
|
|
96468
|
+
}
|
|
96469
|
+
if (force) return buildStatus(null);
|
|
96470
|
+
const failed = { checkedAt: Date.now(), latest: null };
|
|
96471
|
+
writeCache(failed);
|
|
96472
|
+
return buildStatus(failed);
|
|
96033
96473
|
}
|
|
96034
96474
|
function killTree(child) {
|
|
96035
96475
|
if (process.platform === "win32" && child.pid) {
|
|
@@ -96087,12 +96527,8 @@ async function runSelfUpdate() {
|
|
|
96087
96527
|
manual: manualCommand()
|
|
96088
96528
|
};
|
|
96089
96529
|
}
|
|
96090
|
-
|
|
96091
|
-
if (
|
|
96092
|
-
cache2 = { checkedAt: Date.now(), latest: await fetchLatest() };
|
|
96093
|
-
writeCache(cache2);
|
|
96094
|
-
}
|
|
96095
|
-
const latest = cache2?.latest ?? null;
|
|
96530
|
+
const latest = await fetchLatest();
|
|
96531
|
+
if (latest !== null) writeCache({ checkedAt: Date.now(), latest });
|
|
96096
96532
|
if (latest === null) {
|
|
96097
96533
|
return {
|
|
96098
96534
|
ok: false,
|
|
@@ -96135,13 +96571,23 @@ function listInboxFiles(dir) {
|
|
|
96135
96571
|
} catch {
|
|
96136
96572
|
return [];
|
|
96137
96573
|
}
|
|
96574
|
+
let realDir;
|
|
96575
|
+
try {
|
|
96576
|
+
realDir = fs7.realpathSync.native(dir);
|
|
96577
|
+
} catch {
|
|
96578
|
+
realDir = dir;
|
|
96579
|
+
}
|
|
96138
96580
|
const SKIP = /^[.~]|^(thumbs\.db|desktop\.ini)$/i;
|
|
96139
96581
|
const out = [];
|
|
96140
96582
|
for (const name of names) {
|
|
96141
96583
|
if (SKIP.test(name)) continue;
|
|
96142
96584
|
const p = path7.join(dir, name);
|
|
96143
96585
|
try {
|
|
96144
|
-
if (fs7.statSync(p).isFile())
|
|
96586
|
+
if (!fs7.statSync(p).isFile()) continue;
|
|
96587
|
+
const real = fs7.realpathSync.native(p);
|
|
96588
|
+
const rel = path7.relative(realDir, real);
|
|
96589
|
+
if (rel.startsWith("..") || path7.isAbsolute(rel)) continue;
|
|
96590
|
+
out.push({ name, path: p });
|
|
96145
96591
|
} catch {
|
|
96146
96592
|
}
|
|
96147
96593
|
}
|
|
@@ -96211,8 +96657,8 @@ ${r.warnings.join("\n")}`, {
|
|
|
96211
96657
|
/* --------------------------------------------------------- inbox (파일 인입) */
|
|
96212
96658
|
{
|
|
96213
96659
|
name: "open_inbox",
|
|
96214
|
-
title: "\
|
|
96215
|
-
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 \
|
|
96660
|
+
title: "\uBB38\uC11C \uC778\uC785 \uD3F4\uB354 \uC5F4\uAE30",
|
|
96661
|
+
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.',
|
|
96216
96662
|
inputSchema: {},
|
|
96217
96663
|
handler: () => {
|
|
96218
96664
|
const dir = getInboxDir();
|
|
@@ -96220,10 +96666,10 @@ ${r.warnings.join("\n")}`, {
|
|
|
96220
96666
|
const files = listInboxFiles(dir);
|
|
96221
96667
|
const list = files.length ? files.map((f) => `- ${f.name}`).join("\n") : "(\uC544\uC9C1 \uBE44\uC5B4 \uC788\uC74C)";
|
|
96222
96668
|
return ok(
|
|
96223
|
-
`\
|
|
96669
|
+
`\uBB38\uC11C \uC778\uC785 \uD3F4\uB354\uB97C \uC5F4\uC5C8\uC2B5\uB2C8\uB2E4:
|
|
96224
96670
|
${dir}
|
|
96225
96671
|
|
|
96226
|
-
\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
|
|
96672
|
+
\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\xB7hwpx\xB7docx\xB7pdf\uB294 \uC790\uB3D9\uC73C\uB85C \uD14D\uC2A4\uD2B8\uB97C \uCD94\uCD9C\uD558\uACE0, \uD14D\uC2A4\uD2B8 \uB808\uC774\uC5B4\uAC00 \uC5C6\uB294 \uC774\uBBF8\uC9C0\xB7\uC2A4\uCE94 PDF\uB9CC \uC81C\uAC00 \uC9C1\uC811 \uC77D\uC2B5\uB2C8\uB2E4.)
|
|
96227
96673
|
|
|
96228
96674
|
\uD604\uC7AC \uD30C\uC77C:
|
|
96229
96675
|
${list}`,
|
|
@@ -96234,7 +96680,7 @@ ${list}`,
|
|
|
96234
96680
|
{
|
|
96235
96681
|
name: "read_inbox",
|
|
96236
96682
|
title: "\uC778\uC785 \uD3F4\uB354 \uD30C\uC77C \uC77D\uAE30",
|
|
96237
|
-
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
|
|
96683
|
+
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\xB7hwp\xB7hwpx\xB7pdf\xB7\uD14D\uC2A4\uD2B8(.txt/.md)\uC5D0\uC11C \uBCF8\uBB38 \uD14D\uC2A4\uD2B8\uB97C \uCD94\uCD9C\uD574 \uB3CC\uB824\uC90D\uB2C8\uB2E4(read_document\uC640 \uB3D9\uC77C\uD55C \uCD94\uCD9C \uC2A4\uD0DD). \uB2E8 \uD14D\uC2A4\uD2B8 \uB808\uC774\uC5B4\uAC00 \uC5C6\uB294 \uC774\uBBF8\uC9C0\xB7\uC2A4\uCE94 PDF\uB294 \uCD94\uCD9C\uB418\uC9C0 \uC54A\uC544(unsupported=true) \uD30C\uC77C \uACBD\uB85C\uB9CC \uB3CC\uB824\uC8FC\uB2C8, \uADF8 \uACBD\uB85C\uB294 AI \uD074\uB77C\uC774\uC5B8\uD2B8\uC758 \uD30C\uC77C \uC77D\uAE30 \uAE30\uB2A5\uC73C\uB85C \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.',
|
|
96238
96684
|
inputSchema: {
|
|
96239
96685
|
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."),
|
|
96240
96686
|
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")
|
|
@@ -96275,7 +96721,7 @@ ${dir}
|
|
|
96275
96721
|
`\uC778\uC785 \uD3F4\uB354 \uD30C\uC77C ${files.length}\uAC74\uC744 \uC77D\uC5C8\uC2B5\uB2C8\uB2E4:
|
|
96276
96722
|
${summary}
|
|
96277
96723
|
|
|
96278
|
-
\uCD94\uCD9C\uB41C \uB0B4\uC6A9\uC744 \uAD6C\uC870\uD654\uD574 save_profile\
|
|
96724
|
+
\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.`,
|
|
96279
96725
|
{ dir, files }
|
|
96280
96726
|
);
|
|
96281
96727
|
}
|
|
@@ -96343,7 +96789,7 @@ ${lines}`;
|
|
|
96343
96789
|
{
|
|
96344
96790
|
name: "add_resume",
|
|
96345
96791
|
title: "\uC774\uB825\uC11C/\uACBD\uB825\uAE30\uC220\uC11C \uCD94\uAC00",
|
|
96346
|
-
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
|
|
96792
|
+
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. \u26A0\uFE0F content\uC5D0\uB294 \uC774 \uBB38\uC11C \uD55C \uC885\uB958\uC758 \uBCF8\uBB38\uB9CC \uB123\uACE0, \uC790\uAE30\uC18C\uAC1C\uC11C \uB4F1 \uB2E4\uB978 \uC885\uB958 \uBB38\uC11C\uB97C \uAC19\uC740 content\uC5D0 \uC774\uC5B4\uBD99\uC774\uC9C0 \uB9C8\uC138\uC694 \u2014 \uC790\uAE30\uC18C\uAC1C\uC11C\uB294 save_cover_letter_version\uC73C\uB85C \uB530\uB85C \uC800\uC7A5\uD569\uB2C8\uB2E4(\uD55C \uBC88\uC5D0 \uB458 \uB2E4 \uC694\uCCAD\uBC1B\uC558\uC5B4\uB3C4 \uD55C \uC800\uC7A5 \uD638\uCD9C\uC5D0 \uB450 \uBB38\uC11C\uB97C \uD569\uCE58\uC9C0 \uC54A\uC2B5\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.",
|
|
96347
96793
|
// Reuse the shared (length-bounded, whitespace-rejecting) Document schema so
|
|
96348
96794
|
// the MCP ingestion path — the primary route for résumé text — inherits the
|
|
96349
96795
|
// same caps as the web API. kind stays optional here (defaults to resume).
|
|
@@ -96367,6 +96813,23 @@ ${lines}`;
|
|
|
96367
96813
|
return ok(`\uBB38\uC11C ${docs.length}\uAC74`, docs);
|
|
96368
96814
|
}
|
|
96369
96815
|
},
|
|
96816
|
+
{
|
|
96817
|
+
name: "delete_resume",
|
|
96818
|
+
title: "\uC774\uB825\uC11C/\uBB38\uC11C \uC0AD\uC81C",
|
|
96819
|
+
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.",
|
|
96820
|
+
inputSchema: {
|
|
96821
|
+
document_id: external_exports.string(),
|
|
96822
|
+
confirm: external_exports.string().describe("\uC0AD\uC81C \uD655\uC778\uAC12. \uC815\uD655\uD788 DELETE\uB97C \uB123\uC5B4\uC57C \uC0AD\uC81C\uB429\uB2C8\uB2E4.")
|
|
96823
|
+
},
|
|
96824
|
+
handler: (args) => {
|
|
96825
|
+
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.");
|
|
96826
|
+
const doc = documentRepo.get(args.document_id);
|
|
96827
|
+
if (!doc) return fail("\uBB38\uC11C\uB97C \uCC3E\uC744 \uC218 \uC5C6\uC2B5\uB2C8\uB2E4.");
|
|
96828
|
+
if (!documentRepo.remove(doc.id)) return fail("\uBB38\uC11C\uB97C \uC0AD\uC81C\uD558\uC9C0 \uBABB\uD588\uC2B5\uB2C8\uB2E4.");
|
|
96829
|
+
const user_message = `'${doc.title}' \uBB38\uC11C\uB97C \uC0AD\uC81C\uD588\uC5B4\uC694.`;
|
|
96830
|
+
return ok(user_message, { deleted: true, document_id: doc.id, user_message });
|
|
96831
|
+
}
|
|
96832
|
+
},
|
|
96370
96833
|
/* ----------------------------------------------------------- experiences */
|
|
96371
96834
|
{
|
|
96372
96835
|
name: "add_experience",
|
|
@@ -96436,6 +96899,57 @@ ${lines}`;
|
|
|
96436
96899
|
return ok(`\uAE30\uC220 ${list.length}\uAC74`, list);
|
|
96437
96900
|
}
|
|
96438
96901
|
},
|
|
96902
|
+
{
|
|
96903
|
+
name: "delete_experience",
|
|
96904
|
+
title: "\uACBD\uB825 \uD56D\uBAA9 \uC0AD\uC81C",
|
|
96905
|
+
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.",
|
|
96906
|
+
inputSchema: {
|
|
96907
|
+
experience_id: external_exports.string(),
|
|
96908
|
+
confirm: external_exports.string().describe("\uC0AD\uC81C \uD655\uC778\uAC12. \uC815\uD655\uD788 DELETE\uB97C \uB123\uC5B4\uC57C \uC0AD\uC81C\uB429\uB2C8\uB2E4.")
|
|
96909
|
+
},
|
|
96910
|
+
handler: (args) => {
|
|
96911
|
+
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.");
|
|
96912
|
+
const exp = experienceRepo.get(args.experience_id);
|
|
96913
|
+
if (!exp) return fail("\uD574\uB2F9 \uACBD\uB825 \uD56D\uBAA9\uC744 \uCC3E\uC744 \uC218 \uC5C6\uC2B5\uB2C8\uB2E4.");
|
|
96914
|
+
if (!experienceRepo.remove(exp.id)) return fail("\uACBD\uB825 \uD56D\uBAA9\uC744 \uC0AD\uC81C\uD558\uC9C0 \uBABB\uD588\uC2B5\uB2C8\uB2E4.");
|
|
96915
|
+
const user_message = `'${exp.company}' \uACBD\uB825\uC744 \uC0AD\uC81C\uD588\uC5B4\uC694.`;
|
|
96916
|
+
return ok(user_message, { deleted: true, experience_id: exp.id, user_message });
|
|
96917
|
+
}
|
|
96918
|
+
},
|
|
96919
|
+
{
|
|
96920
|
+
name: "delete_project",
|
|
96921
|
+
title: "\uD504\uB85C\uC81D\uD2B8 \uD56D\uBAA9 \uC0AD\uC81C",
|
|
96922
|
+
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.",
|
|
96923
|
+
inputSchema: {
|
|
96924
|
+
project_id: external_exports.string(),
|
|
96925
|
+
confirm: external_exports.string().describe("\uC0AD\uC81C \uD655\uC778\uAC12. \uC815\uD655\uD788 DELETE\uB97C \uB123\uC5B4\uC57C \uC0AD\uC81C\uB429\uB2C8\uB2E4.")
|
|
96926
|
+
},
|
|
96927
|
+
handler: (args) => {
|
|
96928
|
+
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.");
|
|
96929
|
+
const proj = projectRepo.get(args.project_id);
|
|
96930
|
+
if (!proj) return fail("\uD574\uB2F9 \uD504\uB85C\uC81D\uD2B8 \uD56D\uBAA9\uC744 \uCC3E\uC744 \uC218 \uC5C6\uC2B5\uB2C8\uB2E4.");
|
|
96931
|
+
if (!projectRepo.remove(proj.id)) return fail("\uD504\uB85C\uC81D\uD2B8 \uD56D\uBAA9\uC744 \uC0AD\uC81C\uD558\uC9C0 \uBABB\uD588\uC2B5\uB2C8\uB2E4.");
|
|
96932
|
+
const user_message = `'${proj.name}' \uD504\uB85C\uC81D\uD2B8\uB97C \uC0AD\uC81C\uD588\uC5B4\uC694.`;
|
|
96933
|
+
return ok(user_message, { deleted: true, project_id: proj.id, user_message });
|
|
96934
|
+
}
|
|
96935
|
+
},
|
|
96936
|
+
{
|
|
96937
|
+
name: "delete_skill",
|
|
96938
|
+
title: "\uAE30\uC220\uC2A4\uD0DD \uD56D\uBAA9 \uC0AD\uC81C",
|
|
96939
|
+
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.",
|
|
96940
|
+
inputSchema: {
|
|
96941
|
+
skill_id: external_exports.string(),
|
|
96942
|
+
confirm: external_exports.string().describe("\uC0AD\uC81C \uD655\uC778\uAC12. \uC815\uD655\uD788 DELETE\uB97C \uB123\uC5B4\uC57C \uC0AD\uC81C\uB429\uB2C8\uB2E4.")
|
|
96943
|
+
},
|
|
96944
|
+
handler: (args) => {
|
|
96945
|
+
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.");
|
|
96946
|
+
const skill = skillRepo.get(args.skill_id);
|
|
96947
|
+
if (!skill) return fail("\uD574\uB2F9 \uAE30\uC220 \uD56D\uBAA9\uC744 \uCC3E\uC744 \uC218 \uC5C6\uC2B5\uB2C8\uB2E4.");
|
|
96948
|
+
if (!skillRepo.remove(skill.id)) return fail("\uAE30\uC220 \uD56D\uBAA9\uC744 \uC0AD\uC81C\uD558\uC9C0 \uBABB\uD588\uC2B5\uB2C8\uB2E4.");
|
|
96949
|
+
const user_message = `'${skill.name}' \uAE30\uC220\uC744 \uC0AD\uC81C\uD588\uC5B4\uC694.`;
|
|
96950
|
+
return ok(user_message, { deleted: true, skill_id: skill.id, user_message });
|
|
96951
|
+
}
|
|
96952
|
+
},
|
|
96439
96953
|
/* ---------------------------------------------------------- cover letters */
|
|
96440
96954
|
{
|
|
96441
96955
|
name: "get_cover_letters",
|
|
@@ -96451,7 +96965,7 @@ ${lines}`;
|
|
|
96451
96965
|
{
|
|
96452
96966
|
name: "save_cover_letter_version",
|
|
96453
96967
|
title: "\uC790\uAE30\uC18C\uAC1C\uC11C \uBC84\uC804 \uC800\uC7A5",
|
|
96454
|
-
description: '\uC790\uAE30\uC18C\uAC1C\uC11C\uC758 \uC0C8 \uBC84\uC804\uC744 \uC800\uC7A5\uD569\uB2C8\uB2E4. CareerMate \uC790\uC18C\uC11C \uC791\uC131 \uC6CC\uD06C\uD50C\uB85C\uC6B0\uC758 \uD575\uC2EC \uC800\uC7A5 \uB2E8\uACC4\uC785\uB2C8\uB2E4. cover_letter_id\uB97C \uC8FC\uBA74 \uAE30\uC874 \uC790\uC18C\uC11C\uC5D0 \uC0C8 \uBC84\uC804\uC744 \uCD94\uAC00\uD558\uACE0, \uC5C6\uC73C\uBA74 \uC0C8 \uC790\uC18C\uC11C\uB97C \uB9CC\uB4E4\uC5B4 v1\uB85C \uC800\uC7A5\uD569\uB2C8\uB2E4(\uC774\uB54C title \uAD8C\uC7A5). note\uC5D0 \uC774 \uBC84\uC804\uC758 \uBCC0\uACBD \uC694\uC57D(\uC608: "\uC9C0\uC6D0\uB3D9\uAE30 \uBCF4\uAC15")\uC744 \uB0A8\uAE30\uBA74 \uC0AC\uC6A9\uC790\uAC00 \uB300\uC2DC\uBCF4\uB4DC\uC5D0\uC11C \uBC84\uC804 \uD788\uC2A4\uD1A0\uB9AC\uB97C \uC774\uD574\uD558\uAE30 \uC27D\uC2B5\uB2C8\uB2E4. job_id\uB85C \uACF5\uACE0\uC5D0 \uC5F0\uACB0\uD558\uBA74 \uC9C0\uC6D0 \uD56D\uBAA9\uACFC \uC790\uB3D9 \uC5F0\uACB0\uB429\uB2C8\uB2E4. \uC800\uC7A5 \uC9C1\uC804 \uC790\uB3D9\uC73C\uB85C "\uADFC\uAC70 \uC5C6\uB294 \uC218\uCE58" \uC810\uAC80\uC744 \uB3CC\uB9BD\uB2C8\uB2E4 \u2014 \uBCF8\uBB38\uC758 \uC815\uB7C9 \uC218\uCE58\uAC00 \uC800\uC7A5\uB41C \uACBD\uB825\xB7\uC774\uB825\uC11C\xB7\uD504\uB85C\uC81D\uD2B8\uC5D0 \uADFC\uAC70\uAC00 \uC5C6\uC73C\uBA74(\uD658\uAC01 \uC758\uC2EC) \uC800\uC7A5\uC774 \uB9C9\uD799\uB2C8\uB2E4. \uADF8\uB54C\uB294 \uC6D0\uBCF8\uC758 \uC2E4\uC81C \uC218\uCE58\uB85C \uACE0\uCE58\uAC70\uB098, \uC758\uB3C4\uD55C \uAC12\uC774\uBA74 force:true\uB85C \uB2E4\uC2DC \uC800\uC7A5\uD558\uC138\uC694.',
|
|
96968
|
+
description: '\uC790\uAE30\uC18C\uAC1C\uC11C\uC758 \uC0C8 \uBC84\uC804\uC744 \uC800\uC7A5\uD569\uB2C8\uB2E4. CareerMate \uC790\uC18C\uC11C \uC791\uC131 \uC6CC\uD06C\uD50C\uB85C\uC6B0\uC758 \uD575\uC2EC \uC800\uC7A5 \uB2E8\uACC4\uC785\uB2C8\uB2E4. \u26A0\uFE0F content\uC5D0\uB294 \uC790\uAE30\uC18C\uAC1C\uC11C \uBCF8\uBB38\uB9CC \uB123\uACE0, \uACBD\uB825\uAE30\uC220\uC11C \uB4F1 \uB2E4\uB978 \uC885\uB958 \uBB38\uC11C\uB97C \uC774\uC5B4\uBD99\uC774\uC9C0 \uB9C8\uC138\uC694(\uACBD\uB825\uAE30\uC220\uC11C\uB294 add_resume(kind=career_description)\uB85C \uB530\uB85C \uC800\uC7A5). cover_letter_id\uB97C \uC8FC\uBA74 \uAE30\uC874 \uC790\uC18C\uC11C\uC5D0 \uC0C8 \uBC84\uC804\uC744 \uCD94\uAC00\uD558\uACE0, \uC5C6\uC73C\uBA74 \uC0C8 \uC790\uC18C\uC11C\uB97C \uB9CC\uB4E4\uC5B4 v1\uB85C \uC800\uC7A5\uD569\uB2C8\uB2E4(\uC774\uB54C title \uAD8C\uC7A5). note\uC5D0 \uC774 \uBC84\uC804\uC758 \uBCC0\uACBD \uC694\uC57D(\uC608: "\uC9C0\uC6D0\uB3D9\uAE30 \uBCF4\uAC15")\uC744 \uB0A8\uAE30\uBA74 \uC0AC\uC6A9\uC790\uAC00 \uB300\uC2DC\uBCF4\uB4DC\uC5D0\uC11C \uBC84\uC804 \uD788\uC2A4\uD1A0\uB9AC\uB97C \uC774\uD574\uD558\uAE30 \uC27D\uC2B5\uB2C8\uB2E4. job_id\uB85C \uACF5\uACE0\uC5D0 \uC5F0\uACB0\uD558\uBA74 \uC9C0\uC6D0 \uD56D\uBAA9\uACFC \uC790\uB3D9 \uC5F0\uACB0\uB429\uB2C8\uB2E4. \uC800\uC7A5 \uC9C1\uC804 \uC790\uB3D9\uC73C\uB85C "\uADFC\uAC70 \uC5C6\uB294 \uC218\uCE58" \uC810\uAC80\uC744 \uB3CC\uB9BD\uB2C8\uB2E4 \u2014 \uBCF8\uBB38\uC758 \uC815\uB7C9 \uC218\uCE58\uAC00 \uC800\uC7A5\uB41C \uACBD\uB825\xB7\uC774\uB825\uC11C\xB7\uD504\uB85C\uC81D\uD2B8\uC5D0 \uADFC\uAC70\uAC00 \uC5C6\uC73C\uBA74(\uD658\uAC01 \uC758\uC2EC) \uC800\uC7A5\uC774 \uB9C9\uD799\uB2C8\uB2E4. \uADF8\uB54C\uB294 \uC6D0\uBCF8\uC758 \uC2E4\uC81C \uC218\uCE58\uB85C \uACE0\uCE58\uAC70\uB098, \uC758\uB3C4\uD55C \uAC12\uC774\uBA74 force:true\uB85C \uB2E4\uC2DC \uC800\uC7A5\uD558\uC138\uC694.',
|
|
96455
96969
|
inputSchema: CoverLetterVersionInputSchema.shape,
|
|
96456
96970
|
handler: (args) => {
|
|
96457
96971
|
try {
|
|
@@ -96514,7 +97028,7 @@ ${lines}`;
|
|
|
96514
97028
|
{
|
|
96515
97029
|
name: "get_job_posting",
|
|
96516
97030
|
title: "\uCC44\uC6A9\uACF5\uACE0 \uC0C1\uC138 \uC870\uD68C",
|
|
96517
|
-
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, \
|
|
97031
|
+
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.",
|
|
96518
97032
|
inputSchema: { job_id: external_exports.string() },
|
|
96519
97033
|
readOnly: true,
|
|
96520
97034
|
handler: (args) => {
|
|
@@ -96580,13 +97094,42 @@ ${lines}`;
|
|
|
96580
97094
|
const ctx = getApplicationContext({ job_id: args?.job_id });
|
|
96581
97095
|
const recommended_route = pickRoute(ctx);
|
|
96582
97096
|
const route = recommended_route ? getRoute(recommended_route) : void 0;
|
|
97097
|
+
const today = (/* @__PURE__ */ new Date()).toISOString().slice(0, 10);
|
|
97098
|
+
const ym = (s) => {
|
|
97099
|
+
const m = s ? /^(\d{4})-(\d{2})/.exec(s) : null;
|
|
97100
|
+
return m ? Number(m[1]) * 12 + Number(m[2]) : null;
|
|
97101
|
+
};
|
|
97102
|
+
const monthsBetween = (a, b) => {
|
|
97103
|
+
const x2 = ym(a), y = ym(b);
|
|
97104
|
+
return x2 != null && y != null ? y - x2 : null;
|
|
97105
|
+
};
|
|
97106
|
+
const tenure = ctx.experiences.map((e) => {
|
|
97107
|
+
if (!e.start_date) return null;
|
|
97108
|
+
const asOf = e.is_current ? e.updated_at ?? today : e.end_date;
|
|
97109
|
+
const months = monthsBetween(e.start_date, asOf);
|
|
97110
|
+
if (months == null || months < 0) return null;
|
|
97111
|
+
return {
|
|
97112
|
+
company: e.company,
|
|
97113
|
+
is_current: e.is_current,
|
|
97114
|
+
start_date: e.start_date,
|
|
97115
|
+
as_of: (asOf ?? "").slice(0, 7),
|
|
97116
|
+
// 재직중=updated_at(정보 확인 시점) / 종료=end_date
|
|
97117
|
+
months,
|
|
97118
|
+
years: Math.round(months / 12 * 10) / 10,
|
|
97119
|
+
// 음수 방지(미래 updated_at·시계 오차) — 0 미만은 0으로 클램프
|
|
97120
|
+
data_age_months: e.is_current ? Math.max(0, monthsBetween(e.updated_at, today) ?? 0) : null
|
|
97121
|
+
};
|
|
97122
|
+
}).filter((t) => t != null);
|
|
96583
97123
|
const enriched = {
|
|
96584
97124
|
...ctx,
|
|
97125
|
+
today,
|
|
97126
|
+
tenure,
|
|
96585
97127
|
recommended_route,
|
|
96586
97128
|
verifier_sequence: route?.verifierSequence ?? [],
|
|
96587
97129
|
next_tool: recommended_route ? "get_workflow_guide" : null
|
|
96588
97130
|
};
|
|
96589
97131
|
const summary = [
|
|
97132
|
+
`\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.`,
|
|
96590
97133
|
`\uD504\uB85C\uD544: ${ctx.profile?.name ?? "\uBBF8\uC785\uB825"}`,
|
|
96591
97134
|
`\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}`,
|
|
96592
97135
|
ctx.job ? `\uB300\uC0C1 \uACF5\uACE0: ${ctx.job.company} \xB7 ${ctx.job.position}` : "\uB300\uC0C1 \uACF5\uACE0 \uC5C6\uC74C",
|
|
@@ -96605,7 +97148,7 @@ ${lines}`;
|
|
|
96605
97148
|
try {
|
|
96606
97149
|
const fit = saveFitAnalysis(args);
|
|
96607
97150
|
const suggested_next_action = {
|
|
96608
|
-
prompt: "\uC774 \uACF5\uACE0\uC5D0 \uB9DE\uCD98 \uC790\uAE30\uC18C\uAC1C\uC11C\uB97C \uC368\uB4DC\uB9B4\uAE4C\uC694?",
|
|
97151
|
+
prompt: "\uC774 \uACF5\uACE0\uC5D0 \uB9DE\uCD98 \uC790\uAE30\uC18C\uAC1C\uC11C\uB97C \uC368\uB4DC\uB9B4\uAE4C\uC694? (\uD68C\uC0AC \uC9C0\uC815 \uBB38\uD56D\xB7\uC591\uC2DD\xB7\uAE00\uC790\uC218\uAC00 \uC788\uC73C\uBA74 \uD568\uAED8 \uC54C\uB824\uC8FC\uC2DC\uBA74 \uADF8\uC5D0 \uB9DE\uCDB0 \uC791\uC131\uD569\uB2C8\uB2E4)",
|
|
96609
97152
|
options: [
|
|
96610
97153
|
{
|
|
96611
97154
|
label: "\uB124, \uC774 \uACF5\uACE0\uC5D0 \uB9DE\uCD98 \uC790\uAE30\uC18C\uAC1C\uC11C\uB97C \uC368\uC918",
|
|
@@ -96624,7 +97167,8 @@ ${lines}`;
|
|
|
96624
97167
|
"",
|
|
96625
97168
|
"\uC0AC\uC6A9\uC790\uC5D0\uAC8C \uB2E4\uC74C \uC120\uD0DD\uC9C0\uB97C \uBCF4\uC5EC\uC8FC\uC138\uC694:",
|
|
96626
97169
|
"1. \uB124, \uC774 \uACF5\uACE0\uC5D0 \uB9DE\uCD98 \uC790\uAE30\uC18C\uAC1C\uC11C\uB97C \uC368\uC918",
|
|
96627
|
-
"2. \uC544\uB2C8\uC694, \uBD84\uC11D\uB9CC \uC800\uC7A5\uD574\uC918"
|
|
97170
|
+
"2. \uC544\uB2C8\uC694, \uBD84\uC11D\uB9CC \uC800\uC7A5\uD574\uC918",
|
|
97171
|
+
"(1\uBC88\uC774\uBA74, \uD68C\uC0AC \uC9C0\uC815 \uBB38\uD56D\xB7\uC591\uC2DD\xB7\uAE00\uC790\uC218\uAC00 \uC788\uC73C\uBA74 \uC54C\uB824\uB2EC\uB77C\uACE0 \uC694\uCCAD\uD558\uC138\uC694 \u2014 \uD55C\uAD6D \uC790\uC18C\uC11C\uB294 \uBB38\uD56D\uD615\uC774 \uB9CE\uC2B5\uB2C8\uB2E4. \uC5C6\uC73C\uBA74 \uC77C\uBC18 \uC591\uC2DD\uC73C\uB85C \uC9C4\uD589\uD569\uB2C8\uB2E4.)"
|
|
96628
97172
|
].join("\n"),
|
|
96629
97173
|
{
|
|
96630
97174
|
...fit,
|
|
@@ -96645,11 +97189,12 @@ ${lines}`;
|
|
|
96645
97189
|
inputSchema: {
|
|
96646
97190
|
job_id: external_exports.string(),
|
|
96647
97191
|
status: external_exports.enum(APPLICATION_STATUSES),
|
|
96648
|
-
note: external_exports.string().optional()
|
|
97192
|
+
note: external_exports.string().optional(),
|
|
97193
|
+
submission: ApplicationSubmissionSchema.optional()
|
|
96649
97194
|
},
|
|
96650
97195
|
handler: (args) => {
|
|
96651
97196
|
try {
|
|
96652
|
-
const res = updateApplicationStatus(args.job_id, args.status, args.note);
|
|
97197
|
+
const res = updateApplicationStatus(args.job_id, args.status, args.note, args.submission);
|
|
96653
97198
|
const user_message = `\uC9C0\uC6D0 \uC0C1\uD0DC\uB97C '${APPLICATION_STATUS_LABELS[args.status]}'(\uC73C)\uB85C \uBC14\uAFE8\uC5B4\uC694.` + (res.hint ? `
|
|
96654
97199
|
|
|
96655
97200
|
${res.hint}` : "");
|
|
@@ -96673,12 +97218,14 @@ ${res.hint}` : "");
|
|
|
96673
97218
|
{
|
|
96674
97219
|
name: "save_interview_prep",
|
|
96675
97220
|
title: "\uBA74\uC811 \uC900\uBE44 \uC790\uB8CC \uC800\uC7A5",
|
|
96676
|
-
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. \
|
|
97221
|
+
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.",
|
|
96677
97222
|
inputSchema: InterviewPrepInputSchema.shape,
|
|
96678
97223
|
handler: (args) => {
|
|
96679
97224
|
try {
|
|
96680
97225
|
const prep = saveInterviewPrep(args);
|
|
96681
|
-
const
|
|
97226
|
+
const tech = prep.questions.filter((q) => (q.category ?? "technical") === "technical").length;
|
|
97227
|
+
const behavioral = prep.questions.filter((q) => q.category === "behavioral").length;
|
|
97228
|
+
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.";
|
|
96682
97229
|
return ok(user_message, { ...prep, user_message });
|
|
96683
97230
|
} catch (e) {
|
|
96684
97231
|
return fail(e instanceof Error ? e.message : "\uC800\uC7A5 \uC2E4\uD328");
|
|
@@ -96709,6 +97256,65 @@ ${res.hint}` : "");
|
|
|
96709
97256
|
return fail(`\uD30C\uC77C \uC800\uC7A5 \uC2E4\uD328: ${e instanceof Error ? e.message : e}`);
|
|
96710
97257
|
}
|
|
96711
97258
|
return ok(`'${cl.title}'\uB97C ${format.toUpperCase()}\uB85C \uB0B4\uBCF4\uB0C8\uC2B5\uB2C8\uB2E4.
|
|
97259
|
+
\uC800\uC7A5 \uC704\uCE58: ${filePath}`, {
|
|
97260
|
+
path: filePath,
|
|
97261
|
+
filename: result2.filename,
|
|
97262
|
+
content: result2.content
|
|
97263
|
+
});
|
|
97264
|
+
}
|
|
97265
|
+
},
|
|
97266
|
+
{
|
|
97267
|
+
name: "export_resume",
|
|
97268
|
+
title: "\uC774\uB825\uC11C/\uACBD\uB825\uAE30\uC220\uC11C \uB0B4\uBCF4\uB0B4\uAE30",
|
|
97269
|
+
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.',
|
|
97270
|
+
inputSchema: {
|
|
97271
|
+
document_id: external_exports.string(),
|
|
97272
|
+
format: external_exports.enum(["md", "html"]).optional().describe("\uAE30\uBCF8 md")
|
|
97273
|
+
},
|
|
97274
|
+
handler: (args) => {
|
|
97275
|
+
const doc = documentRepo.get(args.document_id);
|
|
97276
|
+
if (!doc) return fail("\uBB38\uC11C\uB97C \uCC3E\uC744 \uC218 \uC5C6\uC2B5\uB2C8\uB2E4.");
|
|
97277
|
+
const profile = profileRepo.get();
|
|
97278
|
+
const format = args.format ?? "md";
|
|
97279
|
+
const result2 = format === "html" ? resumeToHtml(doc, profile) : resumeToMarkdown(doc, profile);
|
|
97280
|
+
const dir = getExportsDir();
|
|
97281
|
+
const filePath = path7.join(dir, result2.filename);
|
|
97282
|
+
try {
|
|
97283
|
+
fs7.writeFileSync(filePath, result2.content, "utf8");
|
|
97284
|
+
} catch (e) {
|
|
97285
|
+
return fail(`\uD30C\uC77C \uC800\uC7A5 \uC2E4\uD328: ${e instanceof Error ? e.message : e}`);
|
|
97286
|
+
}
|
|
97287
|
+
return ok(`'${doc.title}'\uB97C ${format.toUpperCase()}\uB85C \uB0B4\uBCF4\uB0C8\uC2B5\uB2C8\uB2E4.
|
|
97288
|
+
\uC800\uC7A5 \uC704\uCE58: ${filePath}`, {
|
|
97289
|
+
path: filePath,
|
|
97290
|
+
filename: result2.filename,
|
|
97291
|
+
content: result2.content
|
|
97292
|
+
});
|
|
97293
|
+
}
|
|
97294
|
+
},
|
|
97295
|
+
{
|
|
97296
|
+
name: "export_profile",
|
|
97297
|
+
title: "\uD504\uB85C\uD544\uC744 \uC774\uB825\uC11C\uB85C \uB0B4\uBCF4\uB0B4\uAE30",
|
|
97298
|
+
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.',
|
|
97299
|
+
inputSchema: {
|
|
97300
|
+
format: external_exports.enum(["md", "html"]).optional().describe("\uAE30\uBCF8 md")
|
|
97301
|
+
},
|
|
97302
|
+
handler: (args) => {
|
|
97303
|
+
const profile = profileRepo.get();
|
|
97304
|
+
if (!profile) return fail("\uD504\uB85C\uD544\uC774 \uC5C6\uC2B5\uB2C8\uB2E4. \uBA3C\uC800 \uD504\uB85C\uD544\uC744 \uC800\uC7A5\uD558\uC138\uC694.");
|
|
97305
|
+
const format = args.format ?? "md";
|
|
97306
|
+
const experiences = experienceRepo.list();
|
|
97307
|
+
const projects = projectRepo.list();
|
|
97308
|
+
const skills = skillRepo.list();
|
|
97309
|
+
const result2 = format === "html" ? profileToHtml(profile, experiences, projects, skills) : profileToMarkdown(profile, experiences, projects, skills);
|
|
97310
|
+
const dir = getExportsDir();
|
|
97311
|
+
const filePath = path7.join(dir, result2.filename);
|
|
97312
|
+
try {
|
|
97313
|
+
fs7.writeFileSync(filePath, result2.content, "utf8");
|
|
97314
|
+
} catch (e) {
|
|
97315
|
+
return fail(`\uD30C\uC77C \uC800\uC7A5 \uC2E4\uD328: ${e instanceof Error ? e.message : e}`);
|
|
97316
|
+
}
|
|
97317
|
+
return ok(`\uD504\uB85C\uD544\uC744 \uC774\uB825\uC11C(${format.toUpperCase()})\uB85C \uB0B4\uBCF4\uB0C8\uC2B5\uB2C8\uB2E4.
|
|
96712
97318
|
\uC800\uC7A5 \uC704\uCE58: ${filePath}`, {
|
|
96713
97319
|
path: filePath,
|
|
96714
97320
|
filename: result2.filename,
|
|
@@ -96760,9 +97366,17 @@ ${res.hint}` : "");
|
|
|
96760
97366
|
{
|
|
96761
97367
|
name: "get_workflow_guide",
|
|
96762
97368
|
title: "\uC6CC\uD06C\uD50C\uB85C\uC6B0 \uAC00\uC774\uB4DC",
|
|
96763
|
-
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.',
|
|
97369
|
+
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.',
|
|
96764
97370
|
inputSchema: {
|
|
96765
|
-
workflow_id: external_exports.enum([
|
|
97371
|
+
workflow_id: external_exports.enum([
|
|
97372
|
+
"onboarding",
|
|
97373
|
+
"analyze_job",
|
|
97374
|
+
"write_cover_letter",
|
|
97375
|
+
"write_career_description",
|
|
97376
|
+
"manage_application_status",
|
|
97377
|
+
"prepare_interview",
|
|
97378
|
+
"build_personal_brand"
|
|
97379
|
+
]).optional()
|
|
96766
97380
|
},
|
|
96767
97381
|
readOnly: true,
|
|
96768
97382
|
handler: (args) => {
|
|
@@ -96857,10 +97471,23 @@ ${report.disclaimer}`, report);
|
|
|
96857
97471
|
{
|
|
96858
97472
|
name: "get_writing_style_guide",
|
|
96859
97473
|
title: "AI \uD2F0 \uC548 \uB098\uB294 \uAE00\uC4F0\uAE30 \uAC00\uC774\uB4DC",
|
|
96860
|
-
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 \
|
|
96861
|
-
inputSchema: {
|
|
97474
|
+
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.',
|
|
97475
|
+
inputSchema: {
|
|
97476
|
+
doc_type: external_exports.enum([
|
|
97477
|
+
"cover_letter",
|
|
97478
|
+
"self_pr",
|
|
97479
|
+
"application_email",
|
|
97480
|
+
"career_description",
|
|
97481
|
+
"resume",
|
|
97482
|
+
"portfolio"
|
|
97483
|
+
]).optional().describe(
|
|
97484
|
+
"\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."
|
|
97485
|
+
)
|
|
97486
|
+
},
|
|
96862
97487
|
readOnly: true,
|
|
96863
|
-
handler: () => ok("AI \uD2F0 \uC548 \uB098\uB294 \uAE00\uC4F0\uAE30 \uAC00\uC774\uB4DC\uB97C \uC801\uC6A9\uD574 \uC791\uC131\uD558\uC138\uC694.", {
|
|
97488
|
+
handler: (args) => ok("AI \uD2F0 \uC548 \uB098\uB294 \uAE00\uC4F0\uAE30 \uAC00\uC774\uB4DC\uB97C \uC801\uC6A9\uD574 \uC791\uC131\uD558\uC138\uC694.", {
|
|
97489
|
+
guide: getWritingStyleGuide(args?.doc_type)
|
|
97490
|
+
})
|
|
96864
97491
|
},
|
|
96865
97492
|
/* ----------------------------------------------------------------- update */
|
|
96866
97493
|
{
|
|
@@ -96870,7 +97497,7 @@ ${report.disclaimer}`, report);
|
|
|
96870
97497
|
inputSchema: {},
|
|
96871
97498
|
readOnly: true,
|
|
96872
97499
|
handler: async () => {
|
|
96873
|
-
const u = await getUpdateStatusAsync();
|
|
97500
|
+
const u = await getUpdateStatusAsync(true);
|
|
96874
97501
|
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);
|
|
96875
97502
|
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}).`;
|
|
96876
97503
|
return ok(
|
|
@@ -96907,7 +97534,7 @@ async function main() {
|
|
|
96907
97534
|
const server = new McpServer(
|
|
96908
97535
|
{ name: "careermate", version: APP_VERSION },
|
|
96909
97536
|
{
|
|
96910
|
-
instructions: "CareerMate\uB294 \uC0AC\uC6A9\uC790\uC758 \uB85C\uCEEC \uCEE4\uB9AC\uC5B4 \uB370\uC774\uD130\uBCA0\uC774\uC2A4\uC785\uB2C8\uB2E4. \uACF5\uACE0 \uBD84\uC11D
|
|
97537
|
+
instructions: "CareerMate\uB294 \uC0AC\uC6A9\uC790\uC758 \uB85C\uCEEC \uCEE4\uB9AC\uC5B4 \uB370\uC774\uD130\uBCA0\uC774\uC2A4\uC785\uB2C8\uB2E4. \uACF5\uACE0 \uBD84\uC11D, \uC790\uAE30\uC18C\uAC1C\uC11C \uC791\uC131, \uACBD\uB825\uAE30\uC220\uC11C \uC791\uC131 \uC804\uC5D0\uB294 \uD56D\uC0C1 \uC800\uC7A5\uB41C \uC0AC\uC6A9\uC790 \uC815\uBCF4\uB97C \uBA3C\uC800 \uAC00\uC838\uC624\uACE0(\uACF5\uACE0 \uC911\uC2EC \uC791\uC5C5\uC740 get_application_context \uC751\uB2F5\uC758 recommended_route\xB7next_tool\uAC00 \uB2E4\uC74C \uD638\uCD9C\uC744 \uC548\uB0B4\uD569\uB2C8\uB2E4), \uC774\uC5B4 get_workflow_guide\uB85C \uADF8 \uC791\uC5C5\uC758 \uC804\uBB38\uAC00 \uC2E4\uD589 \uC808\uCC28\uC640 \uAC80\uC99D \uC21C\uC11C\uB97C \uBC1B\uC544 \uC801\uC6A9\uD558\uC138\uC694. \uACB0\uACFC\uB294 save_fit_analysis / save_cover_letter_version / add_resume(kind=career_description) \uB4F1\uC73C\uB85C \uB2E4\uC2DC \uC800\uC7A5\uD558\uB418(\uC5EC\uB7EC \uBB38\uC11C\uB97C \uD55C \uBC88\uC5D0 \uC694\uCCAD\uBC1B\uC544\uB3C4 \uAC01 \uBB38\uC11C\uB294 \uAC01\uC790\uC758 \uC800\uC7A5 \uB3C4\uAD6C\uB85C \uB530\uB85C \uC800\uC7A5\uD558\uACE0 \uD55C \uC800\uC7A5 \uBCF8\uBB38\uC5D0 \uB2E4\uB978 \uBB38\uC11C\uB97C \uC774\uC5B4\uBD99\uC774\uC9C0 \uB9C8\uC138\uC694 \u2014 \uACBD\uB825\uAE30\uC220\uC11C=add_resume, \uC790\uAE30\uC18C\uAC1C\uC11C=save_cover_letter_version), \uC800\uC7A5 \uC9C1\uC804 \uC548\uB0B4\uB41C get_verifier \uB8E8\uBE0C\uB9AD\uC73C\uB85C \uB2F9\uC2E0\uC774 \uC2A4\uC2A4\uB85C \uC810\uAC80\uD558\uC138\uC694 \u2014 CareerMate\uB294 \uC140 \uC218 \uC788\uB294 \uD56D\uBAA9\uB9CC \uB3CC\uB824\uC8FC\uACE0 \uBD84\uC11D\xB7\uC791\uC131\xB7\uD310\uB2E8\uC740 \uB2F9\uC2E0(AI)\uC774 \uD569\uB2C8\uB2E4. \uBAA8\uB4E0 \uB370\uC774\uD130\uB294 \uC0AC\uC6A9\uC790 \uB85C\uCEEC\uC5D0\uB9CC \uC800\uC7A5\uB429\uB2C8\uB2E4. \uC0AC\uC6A9\uC790\uC5D0\uAC8C \uB2F5\uD560 \uB54C\uB294 \uD56D\uC0C1 \uC0AC\uC6A9\uC790\uAC00 \uC4F4 \uC5B8\uC5B4\uB85C \uB2F5\uD558\uC138\uC694 \u2014 \uC774 \uC9C0\uCE68\uACFC \uB3C4\uAD6C \uC751\uB2F5\uC774 \uD55C\uAD6D\uC5B4\uB85C \uC4F0\uC5EC \uC788\uC5B4\uB3C4 \uADF8\uB300\uB85C \uBCF5\uC0AC\uD558\uC9C0 \uB9D0\uACE0 \uC0AC\uC6A9\uC790 \uC5B8\uC5B4\uB85C \uC62E\uACA8 \uC804\uB2EC\uD558\uACE0, \uC0AC\uC2E4\xB7\uC218\uCE58\xB7\uACE0\uC720\uBA85\uC0AC\uB294 \uBCF4\uC874\uD569\uB2C8\uB2E4."
|
|
96911
97538
|
}
|
|
96912
97539
|
);
|
|
96913
97540
|
for (const tool of TOOLS) {
|
|
@@ -96936,6 +97563,18 @@ async function main() {
|
|
|
96936
97563
|
}
|
|
96937
97564
|
const transport = new StdioServerTransport();
|
|
96938
97565
|
await server.connect(transport);
|
|
97566
|
+
let closing = false;
|
|
97567
|
+
const shutdown = () => {
|
|
97568
|
+
if (closing) return;
|
|
97569
|
+
closing = true;
|
|
97570
|
+
try {
|
|
97571
|
+
closeDb();
|
|
97572
|
+
} catch {
|
|
97573
|
+
}
|
|
97574
|
+
process.exit(0);
|
|
97575
|
+
};
|
|
97576
|
+
process.once("SIGINT", shutdown);
|
|
97577
|
+
process.once("SIGTERM", shutdown);
|
|
96939
97578
|
console.error(`[careermate-mcp] \uC5F0\uACB0\uB428 \xB7 \uB3C4\uAD6C ${TOOLS.length}\uAC1C \xB7 \uB370\uC774\uD130: ${getDataDir()}`);
|
|
96940
97579
|
}
|
|
96941
97580
|
main().catch((err2) => {
|