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.
Files changed (125) hide show
  1. package/AGENTS.md +13 -10
  2. package/INSTALL.md +16 -15
  3. package/README.md +24 -24
  4. package/THIRD_PARTY_NOTICES.md +2 -3
  5. package/bin/careermate.mjs +8 -1
  6. package/dist/career-os/README.md +12 -6
  7. package/dist/career-os/eop/career-description.md +139 -0
  8. package/dist/career-os/eop/cover-letter.md +10 -5
  9. package/dist/career-os/eop/fit-analysis.md +16 -6
  10. package/dist/career-os/eop/interview-prep.md +209 -21
  11. package/dist/career-os/eop/job-analysis.md +6 -4
  12. package/dist/career-os/eop/profile-extraction.md +5 -4
  13. package/dist/career-os/knowledge/cover-letter.md +5 -4
  14. package/dist/career-os/knowledge/fit-matching.md +8 -8
  15. package/dist/career-os/knowledge/human-writing.md +2 -0
  16. package/dist/career-os/knowledge/interview-behavioral.md +76 -8
  17. package/dist/career-os/knowledge/interview-technical.md +106 -4
  18. package/dist/career-os/knowledge/linkedin-profile.md +1 -1
  19. package/dist/career-os/knowledge/networking-referrals.md +1 -1
  20. package/dist/career-os/knowledge/offer-evaluation-decision.md +10 -10
  21. package/dist/career-os/knowledge/portfolio.md +3 -3
  22. package/dist/career-os/knowledge/verifiers/ats-compat.md +8 -4
  23. package/dist/career-os/knowledge/verifiers/human-voice.md +4 -2
  24. package/dist/career-os/knowledge/verifiers/recency-staleness.md +1 -1
  25. package/dist/career-os/knowledge/verifiers/responsiveness-on-target.md +2 -2
  26. package/dist/career-os/knowledge/verifiers/truthfulness.md +1 -1
  27. package/dist/doctor.mjs +692 -71
  28. package/dist/mcp.mjs +710 -71
  29. package/dist/migrate.mjs +52 -1
  30. package/dist/public/app.js +42 -16
  31. package/dist/public/i18n/en/applications.js +23 -0
  32. package/dist/public/i18n/en/common.js +22 -0
  33. package/dist/public/i18n/en/documents.js +133 -0
  34. package/dist/public/i18n/en/home.js +75 -0
  35. package/dist/public/i18n/en/interview.js +69 -0
  36. package/dist/public/i18n/en/jobs.js +152 -0
  37. package/dist/public/i18n/en/nav.js +18 -0
  38. package/dist/public/i18n/en/profile.js +201 -0
  39. package/dist/public/i18n/en/settings.js +127 -0
  40. package/dist/public/i18n/en/status.js +22 -0
  41. package/dist/public/i18n/en.js +17 -0
  42. package/dist/public/i18n/ko/applications.js +23 -0
  43. package/dist/public/i18n/ko/common.js +22 -0
  44. package/dist/public/i18n/ko/documents.js +133 -0
  45. package/dist/public/i18n/ko/home.js +63 -0
  46. package/dist/public/i18n/ko/interview.js +69 -0
  47. package/dist/public/i18n/ko/jobs.js +152 -0
  48. package/dist/public/i18n/ko/nav.js +18 -0
  49. package/dist/public/i18n/ko/profile.js +201 -0
  50. package/dist/public/i18n/ko/settings.js +127 -0
  51. package/dist/public/i18n/ko/status.js +23 -0
  52. package/dist/public/i18n/ko.js +18 -0
  53. package/dist/public/i18n.js +55 -0
  54. package/dist/public/index.html +1 -0
  55. package/dist/public/lib.js +24 -17
  56. package/dist/public/pages/applications.js +17 -21
  57. package/dist/public/pages/documents.js +153 -107
  58. package/dist/public/pages/home.js +88 -53
  59. package/dist/public/pages/interview.js +105 -51
  60. package/dist/public/pages/jobs.js +330 -106
  61. package/dist/public/pages/profile.js +157 -152
  62. package/dist/public/pages/settings.js +154 -102
  63. package/dist/public/styles.css +28 -1
  64. package/dist/web.mjs +495 -75
  65. package/docs/FAQ.md +23 -3
  66. package/docs/MCP_TOOLS.md +22 -13
  67. package/docs/START_WORKFLOW.md +3 -3
  68. package/docs/SUPPORTED_AI_APPS.md +13 -0
  69. package/docs/WORKFLOWS.md +77 -20
  70. package/docs/career-os/README.md +12 -6
  71. package/docs/career-os/eop/career-description.md +139 -0
  72. package/docs/career-os/eop/cover-letter.md +10 -5
  73. package/docs/career-os/eop/fit-analysis.md +16 -6
  74. package/docs/career-os/eop/interview-prep.md +209 -21
  75. package/docs/career-os/eop/job-analysis.md +6 -4
  76. package/docs/career-os/eop/profile-extraction.md +5 -4
  77. package/docs/career-os/knowledge/cover-letter.md +5 -4
  78. package/docs/career-os/knowledge/fit-matching.md +8 -8
  79. package/docs/career-os/knowledge/human-writing.md +2 -0
  80. package/docs/career-os/knowledge/interview-behavioral.md +76 -8
  81. package/docs/career-os/knowledge/interview-technical.md +106 -4
  82. package/docs/career-os/knowledge/linkedin-profile.md +1 -1
  83. package/docs/career-os/knowledge/networking-referrals.md +1 -1
  84. package/docs/career-os/knowledge/offer-evaluation-decision.md +10 -10
  85. package/docs/career-os/knowledge/portfolio.md +3 -3
  86. package/docs/career-os/knowledge/verifiers/ats-compat.md +8 -4
  87. package/docs/career-os/knowledge/verifiers/human-voice.md +4 -2
  88. package/docs/career-os/knowledge/verifiers/recency-staleness.md +1 -1
  89. package/docs/career-os/knowledge/verifiers/responsiveness-on-target.md +2 -2
  90. package/docs/career-os/knowledge/verifiers/truthfulness.md +1 -1
  91. package/package.json +2 -2
  92. package/packages/core/src/onboarding.ts +2 -1
  93. package/packages/core/src/services.ts +134 -17
  94. package/packages/core/src/summary.ts +59 -1
  95. package/packages/core/src/verify/lint.ts +4 -0
  96. package/packages/db/src/index.ts +1 -0
  97. package/packages/db/src/repositories.ts +0 -0
  98. package/packages/db/src/schema.ts +17 -0
  99. package/packages/exporters/src/index.ts +28 -17
  100. package/packages/knowledge/src/index.ts +55 -9
  101. package/packages/mcp-tools/src/tools.ts +250 -24
  102. package/packages/mcp-tools/src/update.ts +30 -15
  103. package/packages/parsers/src/documents.ts +12 -1
  104. package/packages/prompts/src/humanize.ts +46 -0
  105. package/packages/prompts/src/index.ts +5 -1
  106. package/packages/prompts/src/install.ts +4 -4
  107. package/packages/prompts/src/onboarding.ts +4 -4
  108. package/packages/prompts/src/system.ts +9 -7
  109. package/packages/shared/src/enums.ts +14 -4
  110. package/packages/shared/src/schemas.ts +41 -0
  111. package/packages/workflows/src/definitions.ts +45 -8
  112. package/scripts/init.ts +284 -13
  113. package/dist/site/analytics.js +0 -97
  114. package/dist/site/favicon.svg +0 -1
  115. package/dist/site/fonts/PretendardVariable.woff2 +0 -0
  116. package/dist/site/icon-180.png +0 -0
  117. package/dist/site/icon-512.png +0 -0
  118. package/dist/site/index.html +0 -465
  119. package/dist/site/landing.js +0 -163
  120. package/dist/site/llms-install.txt +0 -218
  121. package/dist/site/robots.txt +0 -4
  122. package/dist/site/sitemap.xml +0 -21
  123. package/dist/site/start.html +0 -356
  124. package/dist/site/style.css +0 -665
  125. package/dist/site/vercel.json +0 -20
package/dist/web.mjs CHANGED
@@ -39681,6 +39681,22 @@ var MIGRATIONS = [
39681
39681
 
39682
39682
  COMMIT;
39683
39683
  PRAGMA foreign_keys=ON;
39684
+ `,
39685
+ // v3 — per-job timeline entries. Document/cover-letter refs live in payload
39686
+ // snapshots instead of FKs so deleting a document does not erase the history.
39687
+ `
39688
+ CREATE TABLE IF NOT EXISTS application_timeline_events (
39689
+ id TEXT PRIMARY KEY,
39690
+ job_id TEXT NOT NULL REFERENCES jobs(id) ON DELETE CASCADE,
39691
+ type TEXT NOT NULL,
39692
+ title TEXT NOT NULL,
39693
+ summary TEXT,
39694
+ payload TEXT NOT NULL DEFAULT '{}',
39695
+ occurred_at TEXT NOT NULL,
39696
+ created_at TEXT NOT NULL
39697
+ );
39698
+
39699
+ CREATE INDEX IF NOT EXISTS idx_timeline_job ON application_timeline_events(job_id, occurred_at ASC);
39684
39700
  `
39685
39701
  ];
39686
39702
  function migrate(db) {
@@ -39869,6 +39885,13 @@ var ACTIVITY_TYPES = [
39869
39885
  "interview_prep_saved",
39870
39886
  "document_exported"
39871
39887
  ];
39888
+ var APPLICATION_TIMELINE_TYPES = [
39889
+ "job_saved",
39890
+ "fit_analysis_saved",
39891
+ "cover_letter_version_saved",
39892
+ "application_status_changed",
39893
+ "interview_prep_saved"
39894
+ ];
39872
39895
  var ENTITY_TYPES = [
39873
39896
  "profile",
39874
39897
  "experience",
@@ -44176,11 +44199,19 @@ var ApplicationInputSchema = external_exports.object({
44176
44199
  applied_at: optLine,
44177
44200
  notes: optNote
44178
44201
  });
44202
+ var ApplicationSubmissionSchema = external_exports.object({
44203
+ submitted_at: optLine.describe("\uC2E4\uC81C \uC81C\uCD9C\uC77C YYYY-MM-DD"),
44204
+ channel: optLine.describe("\uC81C\uCD9C \uCC44\uB110(\uC6D0\uD2F0\uB4DC/\uC0AC\uB78C\uC778/\uD68C\uC0AC \uCC44\uC6A9\uD398\uC774\uC9C0 \uB4F1)"),
44205
+ cover_letter_id: optLine,
44206
+ cover_letter_version_id: optLine,
44207
+ 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")
44208
+ });
44179
44209
  var ApplicationStatusUpdateSchema = external_exports.object({
44180
44210
  job_id: optLine,
44181
44211
  application_id: optLine,
44182
44212
  status: external_exports.enum(APPLICATION_STATUSES),
44183
- note: optNote.describe("\uC0C1\uD0DC \uBCC0\uACBD \uC0AC\uC720/\uBA54\uBAA8")
44213
+ note: optNote.describe("\uC0C1\uD0DC \uBCC0\uACBD \uC0AC\uC720/\uBA54\uBAA8"),
44214
+ submission: ApplicationSubmissionSchema.optional().describe("\uC9C0\uC6D0 \uC644\uB8CC \uAE30\uB85D\uC5D0 \uB0A8\uAE38 \uC81C\uCD9C \uC790\uB8CC \uC2A4\uB0C5\uC0F7")
44184
44215
  });
44185
44216
  var ApplicationRecordSchema = external_exports.object({
44186
44217
  ...baseRecord,
@@ -44198,8 +44229,10 @@ var StarGuideSchema = external_exports.object({
44198
44229
  action: optNote,
44199
44230
  result: optNote
44200
44231
  });
44232
+ var INTERVIEW_CATEGORIES = ["technical", "behavioral"];
44201
44233
  var InterviewQuestionSchema = external_exports.object({
44202
44234
  question: external_exports.string().max(MAX_NOTE),
44235
+ 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."),
44203
44236
  intent: external_exports.string().max(MAX_NOTE).optional().describe("\uC9C8\uBB38 \uC758\uB3C4"),
44204
44237
  followups: strList.optional().describe("\uC608\uC0C1 \uAF2C\uB9AC \uC9C8\uBB38"),
44205
44238
  answer_outline: optBody.describe("\uB2F5\uBCC0 \uAC00\uC774\uB4DC/\uD575\uC2EC \uD3EC\uC778\uD2B8")
@@ -44227,6 +44260,24 @@ var ActivityRecordSchema = external_exports.object({
44227
44260
  summary: external_exports.string(),
44228
44261
  created_at: isoDateTime
44229
44262
  });
44263
+ var ApplicationTimelineInputSchema = external_exports.object({
44264
+ job_id: reqLine,
44265
+ type: external_exports.enum(APPLICATION_TIMELINE_TYPES),
44266
+ title: reqLine,
44267
+ summary: optNote,
44268
+ payload: external_exports.record(external_exports.string(), external_exports.unknown()).optional(),
44269
+ occurred_at: optLine
44270
+ });
44271
+ var ApplicationTimelineRecordSchema = external_exports.object({
44272
+ id,
44273
+ job_id: external_exports.string(),
44274
+ type: external_exports.enum(APPLICATION_TIMELINE_TYPES),
44275
+ title: external_exports.string(),
44276
+ summary: external_exports.string().nullable(),
44277
+ payload: external_exports.record(external_exports.string(), external_exports.unknown()),
44278
+ occurred_at: isoDateTime,
44279
+ created_at: isoDateTime
44280
+ });
44230
44281
  var OnboardingStatusSchema = external_exports.object({
44231
44282
  completed: external_exports.boolean(),
44232
44283
  has_profile: external_exports.boolean(),
@@ -44263,7 +44314,7 @@ var ApplicationContextSchema = external_exports.object({
44263
44314
  });
44264
44315
 
44265
44316
  // packages/shared/src/build-info.ts
44266
- var APP_VERSION = true ? "0.0.5" : "0.0.0-dev";
44317
+ var APP_VERSION = true ? "0.0.7" : "0.0.0-dev";
44267
44318
  var BUNDLED = true;
44268
44319
 
44269
44320
  // packages/shared/src/index.ts
@@ -44357,7 +44408,7 @@ function mapExperience(r) {
44357
44408
  };
44358
44409
  }
44359
44410
  function expKey(company, role, start) {
44360
- return [norm(company), norm(role), norm(start)].join("\0");
44411
+ return [norm(company), norm(role), norm(start)].join("");
44361
44412
  }
44362
44413
  var experienceRepo = {
44363
44414
  list() {
@@ -44868,6 +44919,7 @@ var jobRepo = {
44868
44919
  db.prepare(`DELETE FROM fit_analyses WHERE job_id=?`).run(id3);
44869
44920
  db.prepare(`DELETE FROM applications WHERE job_id=?`).run(id3);
44870
44921
  db.prepare(`DELETE FROM interview_preps WHERE job_id=?`).run(id3);
44922
+ db.prepare(`DELETE FROM application_timeline_events WHERE job_id=?`).run(id3);
44871
44923
  return db.prepare(`DELETE FROM jobs WHERE id=?`).run(id3).changes > 0;
44872
44924
  });
44873
44925
  }
@@ -44980,7 +45032,7 @@ var applicationRepo = {
44980
45032
  const m = { ...app, ...input };
44981
45033
  getDb().prepare(
44982
45034
  `UPDATE applications SET status=?,resume_id=?,cover_letter_id=?,applied_at=?,notes=?,updated_at=? WHERE id=?`
44983
- ).run(m.status, m.resume_id, m.cover_letter_id, m.applied_at, m.notes, now(), app.id);
45035
+ ).run(m.status, m.resume_id ?? null, m.cover_letter_id ?? null, m.applied_at ?? null, m.notes ?? null, now(), app.id);
44984
45036
  return this.get(app.id);
44985
45037
  },
44986
45038
  setStatus(jobId, status, note) {
@@ -45061,6 +45113,48 @@ var activityRepo = {
45061
45113
  return getDb().prepare(`SELECT * FROM activities ORDER BY created_at DESC LIMIT ?`).all(limit);
45062
45114
  }
45063
45115
  };
45116
+ function mapTimelineEvent(r) {
45117
+ return {
45118
+ id: r.id,
45119
+ job_id: r.job_id,
45120
+ type: r.type,
45121
+ title: r.title,
45122
+ summary: r.summary,
45123
+ payload: fromJson(r.payload, {}),
45124
+ occurred_at: r.occurred_at,
45125
+ created_at: r.created_at
45126
+ };
45127
+ }
45128
+ var timelineRepo = {
45129
+ add(input) {
45130
+ const ts = now();
45131
+ const id3 = newId("tl_");
45132
+ getDb().prepare(
45133
+ `INSERT INTO application_timeline_events (id,job_id,type,title,summary,payload,occurred_at,created_at)
45134
+ VALUES (?,?,?,?,?,?,?,?)`
45135
+ ).run(
45136
+ id3,
45137
+ input.job_id,
45138
+ input.type,
45139
+ input.title,
45140
+ input.summary ?? null,
45141
+ toJson(input.payload ?? {}),
45142
+ input.occurred_at ?? ts,
45143
+ ts
45144
+ );
45145
+ return this.get(id3);
45146
+ },
45147
+ get(id3) {
45148
+ const r = getDb().prepare(`SELECT * FROM application_timeline_events WHERE id=?`).get(id3);
45149
+ return r ? mapTimelineEvent(r) : null;
45150
+ },
45151
+ listByJob(jobId) {
45152
+ return getDb().prepare(`SELECT * FROM application_timeline_events WHERE job_id=? ORDER BY occurred_at ASC, created_at ASC`).all(jobId).map(mapTimelineEvent);
45153
+ },
45154
+ remove(id3) {
45155
+ return getDb().prepare(`DELETE FROM application_timeline_events WHERE id=?`).run(id3).changes > 0;
45156
+ }
45157
+ };
45064
45158
  function getEntityCounts() {
45065
45159
  const db = getDb();
45066
45160
  const ALLOWED_TABLES = /* @__PURE__ */ new Set([
@@ -45072,7 +45166,8 @@ function getEntityCounts() {
45072
45166
  "cover_letters",
45073
45167
  "jobs",
45074
45168
  "applications",
45075
- "interview_preps"
45169
+ "interview_preps",
45170
+ "application_timeline_events"
45076
45171
  ]);
45077
45172
  const c = (t) => {
45078
45173
  if (!ALLOWED_TABLES.has(t)) throw new Error(`getEntityCounts: \uD5C8\uC6A9\uB418\uC9C0 \uC54A\uC740 \uD14C\uC774\uBE14 \uC774\uB984: ${t}`);
@@ -45087,7 +45182,8 @@ function getEntityCounts() {
45087
45182
  cover_letters: c("cover_letters"),
45088
45183
  jobs: c("jobs"),
45089
45184
  applications: c("applications"),
45090
- interview_preps: c("interview_preps")
45185
+ interview_preps: c("interview_preps"),
45186
+ application_timeline_events: c("application_timeline_events")
45091
45187
  };
45092
45188
  }
45093
45189
 
@@ -45332,12 +45428,13 @@ function profileCompleteness(p) {
45332
45428
  function getOnboardingStatus() {
45333
45429
  const profile = profileRepo.get();
45334
45430
  const resumes = documentRepo.list("resume");
45431
+ const careerDescriptions = documentRepo.list("career_description");
45335
45432
  const coverLetters = coverLetterRepo.list();
45336
45433
  const experiences = experienceRepo.list();
45337
45434
  const skills = skillRepo.list();
45338
45435
  const jobs = jobRepo.list();
45339
45436
  const has_profile = !!(profile && profile.name);
45340
- const has_resume = resumes.length > 0;
45437
+ const has_resume = resumes.length > 0 || careerDescriptions.length > 0;
45341
45438
  const has_cover_letter = coverLetters.length > 0;
45342
45439
  const has_experience = experiences.length > 0;
45343
45440
  const has_skills = skills.length > 0;
@@ -45740,6 +45837,29 @@ function addSkill(input) {
45740
45837
  activityRepo.log("profile_updated", `\uAE30\uC220(${skill.name})\uC744 \uCD94\uAC00\uD588\uC2B5\uB2C8\uB2E4.`, "skill", skill.id);
45741
45838
  return skill;
45742
45839
  }
45840
+ function coverLetterTimelineRef(coverLetter, version, requestedVersionId) {
45841
+ const resolvedVersion = version ?? coverLetter.versions?.find((v) => v.id === requestedVersionId || v.id === coverLetter.current_version_id) ?? null;
45842
+ return {
45843
+ kind: "cover_letter",
45844
+ id: coverLetter.id,
45845
+ title: coverLetter.title,
45846
+ version_id: resolvedVersion?.id ?? requestedVersionId ?? coverLetter.current_version_id,
45847
+ version_no: resolvedVersion?.version_no ?? coverLetter.version_count
45848
+ };
45849
+ }
45850
+ function documentTimelineRef(doc) {
45851
+ return {
45852
+ kind: "document",
45853
+ id: doc.id,
45854
+ title: doc.title,
45855
+ document_kind: doc.kind
45856
+ };
45857
+ }
45858
+ function submittedAtToOccurrence(value) {
45859
+ if (!value) return void 0;
45860
+ if (/^\d{4}-\d{2}-\d{2}$/.test(value)) return `${value}T00:00:00.000Z`;
45861
+ return void 0;
45862
+ }
45743
45863
  function saveJobPosting(input, id3) {
45744
45864
  const job = jobRepo.upsert(input, id3);
45745
45865
  const application = applicationRepo.ensure(job.id, "draft");
@@ -45753,6 +45873,17 @@ function saveFitAnalysis(input) {
45753
45873
  const fit = fitRepo.save(input);
45754
45874
  const scoreText = fit.score != null ? ` (\uC801\uD569\uB3C4 ${fit.score}\uC810)` : "";
45755
45875
  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);
45876
+ timelineRepo.add({
45877
+ job_id: job.id,
45878
+ type: "fit_analysis_saved",
45879
+ title: "\uC801\uD569\uB3C4 \uBD84\uC11D",
45880
+ summary: fit.score != null ? `\uC885\uD569 ${fit.score}\uC810` : fit.summary ?? void 0,
45881
+ payload: {
45882
+ fit_id: fit.id,
45883
+ score: fit.score
45884
+ },
45885
+ occurred_at: fit.updated_at
45886
+ });
45756
45887
  return fit;
45757
45888
  }
45758
45889
  function saveCoverLetterVersion(input) {
@@ -45786,18 +45917,67 @@ function saveCoverLetterVersion(input) {
45786
45917
  "cover_letter",
45787
45918
  coverLetter.id
45788
45919
  );
45920
+ if (coverLetter.job_id) {
45921
+ timelineRepo.add({
45922
+ job_id: coverLetter.job_id,
45923
+ type: "cover_letter_version_saved",
45924
+ title: "\uC790\uAE30\uC18C\uAC1C\uC11C \uC791\uC131",
45925
+ summary: `${coverLetter.title} v${version.version_no}`,
45926
+ payload: {
45927
+ cover_letter: coverLetterTimelineRef(coverLetter, version)
45928
+ },
45929
+ occurred_at: version.created_at
45930
+ });
45931
+ }
45789
45932
  return { coverLetter, version, verification, forced };
45790
45933
  }
45791
- function updateApplicationStatus(jobId, status, note) {
45934
+ function updateApplicationStatus(jobId, status, note, submission) {
45792
45935
  const job = jobRepo.get(jobId);
45793
45936
  if (!job) throw notFound("\uACF5\uACE0\uB97C \uCC3E\uC744 \uC218 \uC5C6\uC2B5\uB2C8\uB2E4.");
45794
- const application = applicationRepo.setStatus(jobId, status, note);
45795
- activityRepo.log(
45796
- "application_status_changed",
45797
- `${job.company} \xB7 ${job.position} \uC0C1\uD0DC\uB97C '${APPLICATION_STATUS_LABELS[status]}'(\uC73C)\uB85C \uBCC0\uACBD\uD588\uC2B5\uB2C8\uB2E4.`,
45798
- "application",
45799
- application.id
45800
- );
45937
+ const before2 = applicationRepo.getByJob(jobId);
45938
+ const application = tx(() => {
45939
+ let application2 = applicationRepo.setStatus(jobId, status, note);
45940
+ const submittedDocs = (submission?.document_ids ?? []).map((docId) => documentRepo.get(docId)).filter((doc) => !!doc);
45941
+ const submittedCoverLetter = submission?.cover_letter_id ? coverLetterRepo.get(submission.cover_letter_id, true) : null;
45942
+ if (status === "applied" && submission) {
45943
+ const resumeLike = submittedDocs.find((doc) => doc.kind === "resume" || doc.kind === "career_description") ?? submittedDocs[0] ?? null;
45944
+ application2 = applicationRepo.upsert({
45945
+ job_id: jobId,
45946
+ resume_id: resumeLike?.id ?? application2.resume_id ?? void 0,
45947
+ cover_letter_id: submittedCoverLetter?.id ?? application2.cover_letter_id ?? void 0,
45948
+ applied_at: submission.submitted_at ?? application2.applied_at ?? void 0
45949
+ });
45950
+ }
45951
+ activityRepo.log(
45952
+ "application_status_changed",
45953
+ `${job.company} \xB7 ${job.position} \uC0C1\uD0DC\uB97C '${APPLICATION_STATUS_LABELS[status]}'(\uC73C)\uB85C \uBCC0\uACBD\uD588\uC2B5\uB2C8\uB2E4.`,
45954
+ "application",
45955
+ application2.id
45956
+ );
45957
+ const submittedAt = submission?.submitted_at?.trim();
45958
+ const channel = submission?.channel?.trim();
45959
+ const submissionPayload = submission && (submittedAt || channel || submittedCoverLetter || submittedDocs.length > 0) ? {
45960
+ submitted_at: submittedAt || null,
45961
+ channel: channel || null,
45962
+ cover_letter: submittedCoverLetter ? coverLetterTimelineRef(submittedCoverLetter, null, submission.cover_letter_version_id) : null,
45963
+ documents: submittedDocs.map(documentTimelineRef)
45964
+ } : null;
45965
+ timelineRepo.add({
45966
+ job_id: job.id,
45967
+ type: "application_status_changed",
45968
+ title: APPLICATION_STATUS_LABELS[status],
45969
+ summary: channel && status === "applied" ? `${channel}\uB85C \uC81C\uCD9C` : note ?? void 0,
45970
+ payload: {
45971
+ from_status: before2?.status ?? null,
45972
+ status,
45973
+ status_label: APPLICATION_STATUS_LABELS[status],
45974
+ note: note ?? null,
45975
+ submission: submissionPayload
45976
+ },
45977
+ occurred_at: submittedAtToOccurrence(submittedAt)
45978
+ });
45979
+ return application2;
45980
+ });
45801
45981
  const interview_unlocked = INTERVIEW_UNLOCK_STATUSES.includes(status);
45802
45982
  const hasPrep = !!interviewRepo.getByJob(jobId);
45803
45983
  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;
@@ -45806,31 +45986,54 @@ function updateApplicationStatus(jobId, status, note) {
45806
45986
  function saveInterviewPrep(input) {
45807
45987
  const job = jobRepo.get(input.job_id);
45808
45988
  if (!job) throw notFound("\uACF5\uACE0\uB97C \uCC3E\uC744 \uC218 \uC5C6\uC2B5\uB2C8\uB2E4.");
45809
- const app = applicationRepo.getByJob(job.id);
45810
- if (!app || !INTERVIEW_UNLOCK_STATUSES.includes(app.status)) {
45811
- const current = app ? APPLICATION_STATUS_LABELS[app.status] : "\uBBF8\uC9C0\uC6D0";
45812
- throw conflict(
45813
- `\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.`
45814
- );
45815
- }
45816
45989
  const prep = interviewRepo.save(input);
45817
45990
  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);
45991
+ timelineRepo.add({
45992
+ job_id: job.id,
45993
+ type: "interview_prep_saved",
45994
+ title: "\uBA74\uC811 \uC900\uBE44",
45995
+ summary: prep.questions.length > 0 ? `\uC608\uC0C1 \uC9C8\uBB38 ${prep.questions.length}\uAC1C` : prep.notes ?? void 0,
45996
+ payload: {
45997
+ interview_prep_id: prep.id,
45998
+ question_count: prep.questions.length
45999
+ },
46000
+ occurred_at: prep.updated_at
46001
+ });
45818
46002
  return prep;
45819
46003
  }
45820
46004
 
45821
46005
  // packages/core/src/summary.ts
45822
46006
  var ACTIVE = ["draft", "planned", "applied", "document_passed", "interview"];
46007
+ var DEADLINE_ACTIONABLE = ["draft", "planned"];
46008
+ var DEADLINE_SOON_DAYS = 14;
46009
+ var FOLLOWUP_STALE_DAYS = 10;
46010
+ var DAY_MS = 864e5;
46011
+ function daysUntilDate(dateStr, now2) {
46012
+ if (!dateStr) return null;
46013
+ const d = /* @__PURE__ */ new Date(`${dateStr}T00:00:00`);
46014
+ if (isNaN(d.getTime())) return null;
46015
+ const today = new Date(now2);
46016
+ today.setHours(0, 0, 0, 0);
46017
+ return Math.round((d.getTime() - today.getTime()) / DAY_MS);
46018
+ }
46019
+ function daysSinceTimestamp(iso, now2) {
46020
+ if (!iso) return null;
46021
+ const d = new Date(iso);
46022
+ if (isNaN(d.getTime())) return null;
46023
+ return Math.floor((now2.getTime() - d.getTime()) / DAY_MS);
46024
+ }
45823
46025
  function jobWithMeta(job) {
45824
46026
  const app = applicationRepo.getByJob(job.id);
45825
46027
  const fit = fitRepo.getByJob(job.id);
45826
46028
  const status = app?.status ?? "draft";
45827
46029
  return { ...job, status, status_label: APPLICATION_STATUS_LABELS[status], fit_score: fit?.score ?? null };
45828
46030
  }
45829
- function getHomeSummary() {
46031
+ function getHomeSummary(now2 = /* @__PURE__ */ new Date()) {
45830
46032
  const onboarding = getOnboardingStatus();
45831
46033
  const jobs = jobRepo.list();
45832
46034
  const applications = applicationRepo.list();
45833
46035
  const coverLetters = coverLetterRepo.list();
46036
+ const statusByJob = new Map(applications.map((a) => [a.job_id, a]));
45834
46037
  const status_breakdown = Object.keys(APPLICATION_STATUS_LABELS).map((status) => ({
45835
46038
  status,
45836
46039
  label: APPLICATION_STATUS_LABELS[status],
@@ -45841,6 +46044,19 @@ function getHomeSummary() {
45841
46044
  const job = jobRepo.get(a.job_id);
45842
46045
  return job ? { job, status_label: APPLICATION_STATUS_LABELS[a.status] } : null;
45843
46046
  }).filter((x) => x !== null);
46047
+ const deadlines = jobs.map((job) => {
46048
+ const status = statusByJob.get(job.id)?.status ?? "draft";
46049
+ if (!DEADLINE_ACTIONABLE.includes(status)) return null;
46050
+ const days_left = daysUntilDate(job.deadline, now2);
46051
+ if (days_left == null || days_left > DEADLINE_SOON_DAYS) return null;
46052
+ return { job, status, status_label: APPLICATION_STATUS_LABELS[status], days_left };
46053
+ }).filter((x) => x !== null).sort((a, b) => a.days_left - b.days_left).slice(0, 5);
46054
+ const followups = applications.filter((a) => a.status === "applied").map((a) => {
46055
+ const days_since = daysSinceTimestamp(a.applied_at, now2);
46056
+ if (days_since == null || days_since < FOLLOWUP_STALE_DAYS) return null;
46057
+ const job = jobRepo.get(a.job_id);
46058
+ return job ? { job, days_since } : null;
46059
+ }).filter((x) => x !== null).sort((a, b) => b.days_since - a.days_since).slice(0, 5);
45844
46060
  return {
45845
46061
  onboarding,
45846
46062
  counts: {
@@ -45861,6 +46077,8 @@ function getHomeSummary() {
45861
46077
  }),
45862
46078
  recent_cover_letters: coverLetters.slice(0, 5),
45863
46079
  interview_todo,
46080
+ deadlines,
46081
+ followups,
45864
46082
  recent_activity: activityRepo.recent(10)
45865
46083
  };
45866
46084
  }
@@ -45881,7 +46099,8 @@ CareerMate\uB294 \uC0AC\uC6A9\uC790\uC758 \uCEF4\uD4E8\uD130\uC5D0\uC11C \uB3D9\
45881
46099
  - \uAE30\uC5B5\uC5D0 \uC758\uC874\uD558\uC9C0 \uB9D0\uACE0, \uB9E4 \uC791\uC5C5 \uC2DC\uC791 \uC2DC \uC2E4\uC81C \uB370\uC774\uD130\uB97C \uB2E4\uC2DC \uBD88\uB7EC\uC624\uC138\uC694.
45882
46100
 
45883
46101
  2. \uACB0\uACFC\uB294 \uBC18\uB4DC\uC2DC \uB2E4\uC2DC \uC800\uC7A5\uD569\uB2C8\uB2E4.
45884
- - \uBD84\uC11D\xB7\uC791\uC131\uD55C \uB0B4\uC6A9\uC740 \uBA38\uB9BF\uC18D\uC774\uB098 \uB300\uD654\uCC3D\uC5D0\uB9CC \uB0A8\uAE30\uC9C0 \uB9D0\uACE0 \uD574\uB2F9 \uC800\uC7A5 \uD234\uB85C CareerMate\uC5D0 \uAE30\uB85D\uD558\uC138\uC694: \uACF5\uACE0\uB294 \`save_job_posting\`, \uC801\uD569\uB3C4 \uBD84\uC11D\uC740 \`save_fit_analysis\`, \uC790\uAE30\uC18C\uAC1C\uC11C \uBC84\uC804\uC740 \`save_cover_letter_version\`, \uBA74\uC811 \uC900\uBE44\uB294 \`save_interview_prep\`, \uC0C1\uD0DC \uBCC0\uACBD\uC740 \`update_application_status\`.
46102
+ - \uBD84\uC11D\xB7\uC791\uC131\uD55C \uB0B4\uC6A9\uC740 \uBA38\uB9BF\uC18D\uC774\uB098 \uB300\uD654\uCC3D\uC5D0\uB9CC \uB0A8\uAE30\uC9C0 \uB9D0\uACE0 \uD574\uB2F9 \uC800\uC7A5 \uD234\uB85C CareerMate\uC5D0 \uAE30\uB85D\uD558\uC138\uC694: \uACF5\uACE0\uB294 \`save_job_posting\`, \uC801\uD569\uB3C4 \uBD84\uC11D\uC740 \`save_fit_analysis\`, \uC790\uAE30\uC18C\uAC1C\uC11C \uBC84\uC804\uC740 \`save_cover_letter_version\`, \uACBD\uB825\uAE30\uC220\uC11C\uB294 \`add_resume\`(kind=career_description), \uBA74\uC811 \uC900\uBE44\uB294 \`save_interview_prep\`, \uC0C1\uD0DC \uBCC0\uACBD\uC740 \`update_application_status\`.
46103
+ - \uC5EC\uB7EC \uBB38\uC11C\uB97C \uD55C \uBC88\uC5D0 \uC694\uCCAD\uBC1B\uC544\uB3C4 \uAC01 \uBB38\uC11C\uB294 \uAC01\uC790\uC758 \uC800\uC7A5 \uD234\uB85C \uB530\uB85C \uC800\uC7A5\uD558\uC138\uC694. \uACBD\uB825\uAE30\uC220\uC11C\uC640 \uC790\uAE30\uC18C\uAC1C\uC11C\uB97C \uD55C \uD134\uC5D0 \uD568\uAED8 \uB9CC\uB4E4\uC5C8\uB354\uB77C\uB3C4 \uD55C \uC800\uC7A5 \uD638\uCD9C\uC758 \uBCF8\uBB38\uC5D0 \uB2E4\uB978 \uBB38\uC11C\uB97C \uC774\uC5B4\uBD99\uC774\uC9C0 \uB9C8\uC138\uC694(\uACBD\uB825\uAE30\uC220\uC11C=\`add_resume\` kind=career_description, \uC790\uAE30\uC18C\uAC1C\uC11C=\`save_cover_letter_version\`\uB85C \uAC01\uAC01 \uBD84\uB9AC \uC800\uC7A5).
45885
46104
  - \uC800\uC7A5 \uD6C4\uC5D0\uB294 \uBB34\uC5C7\uC774 \uC800\uC7A5\uB418\uC5C8\uB294\uC9C0 \uC0AC\uC6A9\uC790\uC5D0\uAC8C \uAC04\uB2E8\uD788 \uC54C\uB824\uC8FC\uC138\uC694.
45886
46105
 
45887
46106
  3. \uB370\uC774\uD130\uB97C \uC9C0\uC5B4\uB0B4\uC9C0 \uC54A\uC2B5\uB2C8\uB2E4.
@@ -45893,17 +46112,18 @@ CareerMate\uB294 \uC0AC\uC6A9\uC790\uC758 \uCEF4\uD4E8\uD130\uC5D0\uC11C \uB3D9\
45893
46112
  - \uBBFC\uAC10 \uC815\uBCF4(\uC5F0\uB77D\uCC98, \uC8FC\uC18C \uB4F1)\uB294 \uAF2D \uD544\uC694\uD55C \uC791\uC5C5\uC5D0\uB9CC \uC0AC\uC6A9\uD558\uACE0 \uBD88\uD544\uC694\uD558\uAC8C \uB178\uCD9C\uD558\uC9C0 \uB9C8\uC138\uC694.
45894
46113
 
45895
46114
  5. \uC790\uAE30\uC18C\uAC1C\uC11C\uB294 \uC791\uC131 \uC804 \uD655\uC778\uC744 \uBC1B\uC2B5\uB2C8\uB2E4.
45896
- - \uC790\uAE30\uC18C\uAC1C\uC11C\uB97C \uC0C8\uB85C \uC4F0\uAC70\uB098 \uD06C\uAC8C \uACE0\uCE58\uAE30 \uC804\uC5D0, \uC5B4\uB5A4 \uACF5\uACE0\uB97C \uB300\uC0C1\uC73C\uB85C \uC5B4\uB5A4 \uD1A4\uACFC \uAC15\uC870\uC810\uC73C\uB85C \uC4F8\uC9C0 \uC0AC\uC6A9\uC790\uC5D0\uAC8C \uBA3C\uC800 \uD655\uC778\uD558\uC138\uC694.
46115
+ - \uC790\uAE30\uC18C\uAC1C\uC11C\uB098 \uACBD\uB825\uAE30\uC220\uC11C\uB97C \uC0C8\uB85C \uC4F0\uAC70\uB098 \uD06C\uAC8C \uACE0\uCE58\uAE30 \uC804\uC5D0, \uC5B4\uB5A4 \uACF5\uACE0/\uC9C1\uBB34\uB97C \uB300\uC0C1\uC73C\uB85C \uC5B4\uB5A4 \uD1A4\uACFC \uAC15\uC870\uC810\uC73C\uB85C \uC4F8\uC9C0 \uC0AC\uC6A9\uC790\uC5D0\uAC8C \uBA3C\uC800 \uD655\uC778\uD558\uC138\uC694.
45897
46116
  - \uC791\uC131 \uD6C4\uC5D0\uB294 \`save_cover_letter_version\`\uC73C\uB85C \uBC84\uC804\uC744 \uC800\uC7A5\uD558\uACE0, \uBCC0\uACBD \uC694\uC57D\uC744 \`note\`\uC5D0 \uB0A8\uAE30\uC138\uC694. \uC0AC\uC6A9\uC790\uAC00 \uC6D0\uD558\uBA74 \`export_cover_letter\`\uB85C \uB0B4\uBCF4\uB0B4\uC138\uC694.
45898
46117
 
45899
- 6. \uC0AC\uC6A9\uC790\uC5D0\uAC8C\uB294 \uC26C\uC6B4 \uD55C\uAD6D\uC5B4\uB85C \uC54C\uB9BD\uB2C8\uB2E4.
46118
+ 6. \uC0AC\uC6A9\uC790\uC5D0\uAC8C\uB294 \uC0AC\uC6A9\uC790\uC758 \uC5B8\uC5B4\uB85C \uC27D\uAC8C \uC54C\uB9BD\uB2C8\uB2E4.
46119
+ - **\uC751\uB2F5 \uC5B8\uC5B4 = \uC0AC\uC6A9\uC790\uC758 \uC5B8\uC5B4.** \uC0AC\uC6A9\uC790\uAC00 \uD55C\uAD6D\uC5B4\uB85C \uB9D0\uD558\uBA74 \uD55C\uAD6D\uC5B4\uB85C, \uC601\uC5B4 \uB4F1 \uB2E4\uB978 \uC5B8\uC5B4\uB85C \uB9D0\uD558\uBA74 \uADF8 \uC5B8\uC5B4\uB85C \uB2F5\uD569\uB2C8\uB2E4. \uC774 \uC9C0\uCE68\xB7\uB3C4\uAD6C \uC751\uB2F5\xB7\uD50C\uB808\uC774\uBD81\uC774 \uD55C\uAD6D\uC5B4\uB85C \uC801\uD600 \uC788\uC5B4\uB3C4 \uADF8\uB300\uB85C \uBCF5\uC0AC\uD558\uC9C0 \uB9D0\uACE0 \uC0AC\uC6A9\uC790 \uC5B8\uC5B4\uB85C \uC62E\uACA8 \uC804\uB2EC\uD558\uC138\uC694(\uC0AC\uC2E4\xB7\uC218\uCE58\xB7\uACE0\uC720\uBA85\uC0AC\uB294 \uBCF4\uC874).
45900
46120
  - "MCP", "\uD234 \uD638\uCD9C", "job_id" \uAC19\uC740 \uAE30\uC220 \uC6A9\uC5B4\uB294 \uC0AC\uC6A9\uC790\uC5D0\uAC8C \uC9C1\uC811 \uB178\uCD9C\uD558\uC9C0 \uB9C8\uC138\uC694. "\uACF5\uACE0\uB97C \uC800\uC7A5\uD588\uC5B4\uC694", "\uC801\uD569\uB3C4\uB97C \uBD84\uC11D\uD588\uC5B4\uC694"\uCC98\uB7FC \uC77C\uC0C1\uC801\uC778 \uD45C\uD604\uC73C\uB85C \uC9C4\uD589 \uC0C1\uD669\uC744 \uC54C\uB9AC\uC138\uC694.
45901
- - \uB3C4\uAD6C \uC751\uB2F5\uC5D0 \`user_message\`\uAC00 \uC788\uC73C\uBA74 \uC0AC\uC6A9\uC790\uC5D0\uAC8C \uBCF4\uACE0\uD560 \uB54C \uADF8 \uBB38\uC7A5\uC744 \uC6B0\uC120 \uD65C\uC6A9\uD558\uC138\uC694. \`id\`, \`job_id\`, \`cover_letter_id\`, \`workflow_id\`, JSON \uC6D0\uBB38, \uB3C4\uAD6C \uC774\uB984\uC740 \uB0B4\uBD80 \uC791\uC5C5\uC6A9\uC73C\uB85C\uB9CC \uC4F0\uACE0 \uC0AC\uC6A9\uC790\uC5D0\uAC8C \uADF8\uB300\uB85C \uBCF5\uC0AC\uD558\uC9C0 \uB9C8\uC138\uC694.
46121
+ - \uB3C4\uAD6C \uC751\uB2F5\uC5D0 \`user_message\`\uAC00 \uC788\uC73C\uBA74 \uC0AC\uC6A9\uC790\uC5D0\uAC8C \uBCF4\uACE0\uD560 \uB54C \uADF8 \uB0B4\uC6A9\uC744 \uC6B0\uC120 \uD65C\uC6A9\uD558\uB418, \uC0AC\uC6A9\uC790\uAC00 \uD55C\uAD6D\uC5B4\uAC00 \uC544\uB2CC \uC5B8\uC5B4\uB85C \uB300\uD654\uD558\uBA74 \uD55C\uAD6D\uC5B4 \uC6D0\uBB38\uC744 \uADF8\uB300\uB85C \uBCF5\uC0AC\uD558\uC9C0 \uB9D0\uACE0 \uC0AC\uC6A9\uC790 \uC5B8\uC5B4\uB85C \uC62E\uACA8 \uC804\uB2EC\uD558\uC138\uC694. \`id\`, \`job_id\`, \`cover_letter_id\`, \`workflow_id\`, JSON \uC6D0\uBB38, \uB3C4\uAD6C \uC774\uB984\uC740 \uB0B4\uBD80 \uC791\uC5C5\uC6A9\uC73C\uB85C\uB9CC \uC4F0\uACE0 \uC0AC\uC6A9\uC790\uC5D0\uAC8C \uADF8\uB300\uB85C \uBCF5\uC0AC\uD558\uC9C0 \uB9C8\uC138\uC694.
45902
46122
  - \uB3C4\uAD6C \uC751\uB2F5\uC5D0 \`suggested_next_action\`\uC774 \uC788\uC73C\uBA74 \uB2E4\uC74C \uD589\uB3D9\uC744 \uAC15\uC694\uD558\uC9C0 \uB9D0\uACE0 \uC120\uD0DD\uC9C0\uB85C \uC81C\uC548\uD558\uC138\uC694.
45903
46123
  - \uBB34\uC5C7\uC744 \uD588\uACE0, \uBB34\uC5C7\uC744 \uC54C\uAC8C \uB418\uC5C8\uACE0, \uB2E4\uC74C\uC5D0 \uBB34\uC5C7\uC744 \uD560 \uC218 \uC788\uB294\uC9C0 \uC9E7\uACE0 \uBA85\uD655\uD558\uAC8C \uC804\uB2EC\uD558\uC138\uC694.
45904
46124
 
45905
46125
  7. \uB2E4\uC74C \uB2E8\uACC4\uB97C \uBA3C\uC800 \uC81C\uC548\uD569\uB2C8\uB2E4.
45906
- - \uC791\uC5C5\uC774 \uB05D\uB098\uBA74 \uC790\uC5F0\uC2A4\uB7EC\uC6B4 \uB2E4\uC74C \uD589\uB3D9\uC744 \uC81C\uC548\uD558\uC138\uC694. \uC608: \uACF5\uACE0 \uBD84\uC11D \uD6C4 \u2192 "\uC774 \uACF5\uACE0\uC5D0 \uB9DE\uCD98 \uC790\uAE30\uC18C\uAC1C\uC11C\uB97C \uC368\uB4DC\uB9B4\uAE4C\uC694?", \uC790\uAE30\uC18C\uAC1C\uC11C \uC800\uC7A5 \uD6C4 \u2192 "\uC9C0\uC6D0 \uC0C1\uD0DC\uB97C '\uC9C0\uC6D0 \uC644\uB8CC'\uB85C \uBC14\uAFC0\uAE4C\uC694?", \uC0C1\uD0DC\uAC00 '\uC11C\uB958 \uD569\uACA9'\uC774 \uB418\uBA74 \u2192 "\uBA74\uC811 \uC900\uBE44\uB97C \uB3C4\uC640\uB4DC\uB9B4\uAE4C\uC694?".
46126
+ - \uC791\uC5C5\uC774 \uB05D\uB098\uBA74 \uC790\uC5F0\uC2A4\uB7EC\uC6B4 \uB2E4\uC74C \uD589\uB3D9\uC744 \uC81C\uC548\uD558\uC138\uC694. \uC608: \uACF5\uACE0 \uBD84\uC11D \uD6C4 \u2192 "\uC774 \uACF5\uACE0\uC5D0 \uB9DE\uCD98 \uC790\uAE30\uC18C\uAC1C\uC11C\uB97C \uC368\uB4DC\uB9B4\uAE4C\uC694?", \uACBD\uB825\uAE30\uC220\uC11C \uC800\uC7A5 \uD6C4 \u2192 "\uC774 \uACF5\uACE0\uC5D0 \uB9DE\uCDB0 \uC790\uAE30\uC18C\uAC1C\uC11C\uB3C4 \uC815\uB9AC\uD560\uAE4C\uC694?", \uC790\uAE30\uC18C\uAC1C\uC11C \uC800\uC7A5 \uD6C4 \u2192 "\uC9C0\uC6D0 \uC0C1\uD0DC\uB97C '\uC9C0\uC6D0 \uC644\uB8CC'\uB85C \uBC14\uAFC0\uAE4C\uC694?", \uC0C1\uD0DC\uAC00 '\uC11C\uB958 \uD569\uACA9'\uC774 \uB418\uBA74 \u2192 "\uBA74\uC811 \uC900\uBE44\uB97C \uB3C4\uC640\uB4DC\uB9B4\uAE4C\uC694?".
45907
46127
  - \uACF5\uACE0 \uBD84\uC11D \uD6C4\uC5D0\uB294 \uACE7\uC7A5 \uC790\uAE30\uC18C\uAC1C\uC11C\uB97C \uC4F0\uC9C0 \uB9D0\uACE0, \uBC18\uB4DC\uC2DC \uC120\uD0DD\uC9C0\uB97C \uBCF4\uC5EC\uC8FC\uC138\uC694: "1. \uB124, \uC774 \uACF5\uACE0\uC5D0 \uB9DE\uCD98 \uC790\uAE30\uC18C\uAC1C\uC11C\uB97C \uC368\uC918" / "2. \uC544\uB2C8\uC694, \uBD84\uC11D\uB9CC \uC800\uC7A5\uD574\uC918". \uC0AC\uC6A9\uC790\uAC00 1\uBC88\uC744 \uACE0\uB978 \uACBD\uC6B0\uC5D0\uB9CC \uC790\uAE30\uC18C\uAC1C\uC11C \uC791\uC131 \uD750\uB984\uC73C\uB85C \uC774\uC5B4\uAC11\uB2C8\uB2E4.
45908
46128
  - \`get_onboarding_status\`\uC758 next_steps\uB098 \`open_dashboard\`/\`open_application\`\uC744 \uD65C\uC6A9\uD574 \uC0AC\uC6A9\uC790\uB97C \uB2E4\uC74C \uD589\uB3D9\uC73C\uB85C \uC548\uB0B4\uD558\uC138\uC694.
45909
46129
 
@@ -45914,10 +46134,10 @@ CareerMate\uB294 \uC0AC\uC6A9\uC790\uC758 \uCEF4\uD4E8\uD130\uC5D0\uC11C \uB3D9\
45914
46134
 
45915
46135
  9. \uAE00\uC740 AI \uD2F0 \uC548 \uB098\uAC8C \uC501\uB2C8\uB2E4.
45916
46136
  - \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\uB294 \`get_writing_style_guide\`\uB97C \uD638\uCD9C\uD574 \uAE00\uC4F0\uAE30 \uADDC\uCE59\uC744 \uAC00\uC838\uC624\uACE0 \uADF8\uB300\uB85C \uC801\uC6A9\uD558\uC138\uC694.
45917
- - \uBC88\uC5ED\uD22C, "\uC5F4\uC815\uC744 \uAC00\uC9C0\uACE0/\uADC0\uC0AC\uC758 \uBC1C\uC804\uC5D0 \uAE30\uC5EC" \uAC19\uC740 \uD074\uB9AC\uC170, \uAE30\uACC4\uC801 \uBCD1\uB82C(\uCCAB\uC9F8\xB7\uB458\uC9F8\xB7\uC14B\uC9F8), \uC0C1\uD22C\uC801 \uC5F0\uACB0\uC5B4, \uADE0\uC77C\uD55C \uBB38\uC7A5 \uB9AC\uB4EC\uC744 \uD53C\uD558\uACE0 \uB2F4\uBC31\uD558\uACE0 \uAD6C\uCCB4\uC801\uC73C\uB85C \uC501\uB2C8\uB2E4. \uB2E8, \uC0AC\uC2E4\xB7\uC218\uCE58\xB7\uACE0\uC720\uBA85\uC0AC\uB294 \uC808\uB300 \uBC14\uAFB8\uAC70\uB098 \uC9C0\uC5B4\uB0B4\uC9C0 \uC54A\uC2B5\uB2C8\uB2E4.
46137
+ - \uBC88\uC5ED\uD22C, "\uC5F4\uC815\uC744 \uAC00\uC9C0\uACE0/\uADC0\uC0AC\uC758 \uBC1C\uC804\uC5D0 \uAE30\uC5EC" \uAC19\uC740 \uD074\uB9AC\uC170, \uAE30\uACC4\uC801 \uBCD1\uB82C(\uCCAB\uC9F8\xB7\uB458\uC9F8\xB7\uC14B\uC9F8), \uC0C1\uD22C\uC801 \uC5F0\uACB0\uC5B4, \uADE0\uC77C\uD55C \uBB38\uC7A5 \uB9AC\uB4EC\uC744 \uD53C\uD558\uACE0 \uB2F4\uBC31\uD558\uACE0 \uAD6C\uCCB4\uC801\uC73C\uB85C \uC501\uB2C8\uB2E4. \uB2E8, \uC0AC\uC2E4\xB7\uC218\uCE58\xB7\uACE0\uC720\uBA85\uC0AC\uB294 \uC808\uB300 \uBC14\uAFB8\uAC70\uB098 \uC9C0\uC5B4\uB0B4\uC9C0 \uC54A\uC2B5\uB2C8\uB2E4. \uC774 AI-tell \uBAA9\uB85D\uC740 \uD55C\uAD6D\uC5B4 \uAE00 \uAE30\uC900\uC774\uBA70, \uB2E4\uB978 \uC5B8\uC5B4\uB85C \uC4F8 \uB54C\uB294 \uAC19\uC740 \uC6D0\uB9AC\uB97C \uADF8 \uC5B8\uC5B4\uC758 \uC790\uC5F0\uC2A4\uB7EC\uC6B4 \uAD00\uC2B5\uC73C\uB85C \uC801\uC6A9\uD569\uB2C8\uB2E4(\uC0B0\uCD9C\uBB3C \uC5B8\uC5B4\xB7\uAD00\uD589\uC740 \uB300\uC0C1 \uACF5\uACE0\xB7\uC2DC\uC7A5\uC744 \uB530\uB984).
45918
46138
 
45919
46139
  10. \uC804\uBB38\uAC00 \uC808\uCC28\uB85C \uB9CC\uB4E4\uACE0, \uC800\uC7A5 \uC804 \uB2F9\uC2E0\uC774 \uC790\uAC00\uAC80\uC99D\uD569\uB2C8\uB2E4.
45920
- - \uACF5\uACE0 \uBD84\uC11D\xB7\uC790\uC18C\uC11C\xB7\uBA74\uC811 \uC790\uB8CC\uCC98\uB7FC \uC0AC\uC6A9\uC790 \uB300\uBA74 \uACB0\uACFC\uB97C \uB9CC\uB4E4\uAE30 \uC804\uC5D0\uB294, \uC989\uB2F5\uD558\uC9C0 \uB9D0\uACE0 \`get_workflow_guide\`(workflow_id \uC9C0\uC815)\uB97C \uBA3C\uC800 \uD638\uCD9C\uD574 \uADF8 \uC791\uC5C5\uC758 \uC804\uBB38\uAC00 \uC2E4\uD589 \uC808\uCC28(EOP)\uC640 \uC801\uC6A9\uD560 \uD50C\uB808\uC774\uBD81\xB7\uAC80\uC99D\uAE30 \uC21C\uC11C\uB97C \uBC1B\uC73C\uC138\uC694. \uC774\uC5B4 \`get_playbook\`\uC73C\uB85C \uB3C4\uBA54\uC778 \uC9C0\uC2DD\uC744 \uBC1B\uC544 \uC791\uC131\uD558\uACE0, save\uB85C \uC800\uC7A5\uD558\uAE30 \uC9C1\uC804 \`get_verifier\`\uB85C \uAC80\uC99D \uB8E8\uBE0C\uB9AD\uC744 \uBC1B\uC544 **\uB2F9\uC2E0\uC774 \uC9C1\uC811** \uC810\uAC80\xB7\uC218\uC815\uD55C \uB4A4 \uC800\uC7A5\uD569\uB2C8\uB2E4.
46140
+ - \uACF5\uACE0 \uBD84\uC11D\xB7\uC790\uC18C\uC11C\xB7\uACBD\uB825\uAE30\uC220\uC11C\xB7\uBA74\uC811 \uC790\uB8CC\uCC98\uB7FC \uC0AC\uC6A9\uC790 \uB300\uBA74 \uACB0\uACFC\uB97C \uB9CC\uB4E4\uAE30 \uC804\uC5D0\uB294, \uC989\uB2F5\uD558\uC9C0 \uB9D0\uACE0 \`get_workflow_guide\`(workflow_id \uC9C0\uC815)\uB97C \uBA3C\uC800 \uD638\uCD9C\uD574 \uADF8 \uC791\uC5C5\uC758 \uC804\uBB38\uAC00 \uC2E4\uD589 \uC808\uCC28(EOP)\uC640 \uC801\uC6A9\uD560 \uD50C\uB808\uC774\uBD81\xB7\uAC80\uC99D\uAE30 \uC21C\uC11C\uB97C \uBC1B\uC73C\uC138\uC694. \uC774\uC5B4 \`get_playbook\`\uC73C\uB85C \uB3C4\uBA54\uC778 \uC9C0\uC2DD\uC744 \uBC1B\uC544 \uC791\uC131\uD558\uACE0, save\uB85C \uC800\uC7A5\uD558\uAE30 \uC9C1\uC804 \`get_verifier\`\uB85C \uAC80\uC99D \uB8E8\uBE0C\uB9AD\uC744 \uBC1B\uC544 **\uB2F9\uC2E0\uC774 \uC9C1\uC811** \uC810\uAC80\xB7\uC218\uC815\uD55C \uB4A4 \uC800\uC7A5\uD569\uB2C8\uB2E4.
45921
46141
  - CareerMate\uB294 \uC2AC\uB86D \uBC00\uB3C4\xB7\uD0A4\uC6CC\uB4DC \uB9E4\uCE6D\uCC98\uB7FC \uC140 \uC218 \uC788\uB294 \uD56D\uBAA9\uB9CC \uBCF4\uC870\uB85C \uB3D5\uACE0, \uC758\uBBF8 \uD310\uB2E8(\uC774 \uAE00\uC774 \uC9C8\uBB38\uC5D0 \uB2F5\uD558\uB294\uAC00\xB7\uD1A4\uC774 \uB9DE\uB294\uAC00)\uC740 \uB2F9\uC2E0\uC774 \uD569\uB2C8\uB2E4. \uC0AC\uC2E4\xB7\uC218\uCE58\xB7\uACE0\uC720\uBA85\uC0AC\uB294 \uADF8\uB300\uB85C \uBCF4\uC874\uD569\uB2C8\uB2E4.
45922
46142
 
45923
46143
  # \uC791\uC5C5 \uBC29\uC2DD \uC694\uC57D
@@ -45935,7 +46155,7 @@ var INSTALL_PROMPT_CLAUDE = `Claude\uC57C, \uC544\uB798 CareerMate \uC124\uCE58
45935
46155
  4. \uADF8\uB2E4\uC74C \uB098\uC5D0\uAC8C \uC774\uB825\uC11C\uB098 \uC790\uAE30\uC18C\uAC1C\uC11C \uD30C\uC77C\uC744 \uC5C5\uB85C\uB4DC\uD558\uB77C\uACE0 \uC548\uB0B4\uD574\uC918.
45936
46156
  5. \uB0B4\uAC00 \uC62C\uB9B0 \uD30C\uC77C\uC744 \uBC14\uD0D5\uC73C\uB85C \uB0B4 \uD504\uB85C\uD544\uC744 \uAD6C\uC870\uD654\uD574\uC11C \`save_profile\`\uB85C CareerMate\uC5D0 \uC800\uC7A5\uD558\uACE0, \uC628\uBCF4\uB529\uC744 \uC2DC\uC791\uD574\uC918.
45937
46157
 
45938
- \uAE30\uC220 \uC6A9\uC5B4\uB294 \uCD5C\uB300\uD55C \uBE7C\uACE0, \uB9E4 \uB2E8\uACC4\uB9C8\uB2E4 \uC9C0\uAE08 \uBB58 \uD558\uACE0 \uC788\uB294\uC9C0 \uC26C\uC6B4 \uD55C\uAD6D\uC5B4\uB85C \uC54C\uB824\uC918. \uB9C9\uD788\uB294 \uBD80\uBD84\uC774 \uC788\uC73C\uBA74 \uCD94\uCE21\uD558\uC9C0 \uB9D0\uACE0 \uB098\uC5D0\uAC8C \uBB3C\uC5B4\uBD10\uC918.`;
46158
+ \uAE30\uC220 \uC6A9\uC5B4\uB294 \uCD5C\uB300\uD55C \uBE7C\uACE0, \uB9E4 \uB2E8\uACC4\uB9C8\uB2E4 \uC9C0\uAE08 \uBB58 \uD558\uACE0 \uC788\uB294\uC9C0 \uB0B4\uAC00 \uC4F0\uB294 \uC5B8\uC5B4\uB85C \uC27D\uAC8C \uC54C\uB824\uC918. \uB9C9\uD788\uB294 \uBD80\uBD84\uC774 \uC788\uC73C\uBA74 \uCD94\uCE21\uD558\uC9C0 \uB9D0\uACE0 \uB098\uC5D0\uAC8C \uBB3C\uC5B4\uBD10\uC918.`;
45939
46159
  var INSTALL_PROMPT_CHATGPT = `ChatGPT\uC57C, \uC544\uB798 \uD398\uC774\uC9C0\uB97C \uC77D\uACE0 \uB0B4 \uCEF4\uD4E8\uD130\uC5D0 CareerMate\uB97C \uC124\uCE58\uD558\uACE0 \uC124\uC815\uD574\uC918. \uC124\uCE58\uAC00 \uB05D\uB098\uBA74 \uC5F0\uACB0 \uC0C1\uD0DC\uB97C \uD655\uC778\uD558\uACE0, \uB098\uC5D0\uAC8C \uC774\uB825\uC11C\uB098 \uC790\uAE30\uC18C\uAC1C\uC11C \uD30C\uC77C\uC744 \uC5C5\uB85C\uB4DC\uD558\uB77C\uACE0 \uC548\uB0B4\uD574\uC918. \uADF8\uB2E4\uC74C \uB0B4 \uD504\uB85C\uD544\uC744 \uAD6C\uC870\uD654\uD574\uC11C CareerMate\uC5D0 \uC800\uC7A5\uD574\uC918.
45940
46160
 
45941
46161
  \uAD6C\uCCB4\uC801\uC73C\uB85C\uB294 \uC774\uB807\uAC8C \uD574\uC918.
@@ -45945,7 +46165,7 @@ var INSTALL_PROMPT_CHATGPT = `ChatGPT\uC57C, \uC544\uB798 \uD398\uC774\uC9C0\uB9
45945
46165
  4. \uC774\uB825\uC11C\xB7\uC790\uAE30\uC18C\uAC1C\uC11C \uD30C\uC77C\uC744 \uC5C5\uB85C\uB4DC\uD558\uB77C\uACE0 \uB098\uC5D0\uAC8C \uC548\uB0B4\uD574\uC918.
45946
46166
  5. \uC62C\uB9B0 \uD30C\uC77C\uB85C \uB0B4 \uD504\uB85C\uD544\uC744 \uC815\uB9AC\uD574\uC11C \`save_profile\`\uB85C \uC800\uC7A5\uD558\uACE0 \uC628\uBCF4\uB529\uC744 \uC2DC\uC791\uD574\uC918.
45947
46167
 
45948
- \uC9C4\uD589 \uC0C1\uD669\uC740 \uD56D\uC0C1 \uC26C\uC6B4 \uD55C\uAD6D\uC5B4\uB85C \uC124\uBA85\uD558\uACE0, \uD655\uC2E4\uD558\uC9C0 \uC54A\uC740 \uC815\uBCF4\uB294 \uC9C0\uC5B4\uB0B4\uC9C0 \uB9D0\uACE0 \uB098\uC5D0\uAC8C \uBB3C\uC5B4\uBD10\uC918.`;
46168
+ \uC9C4\uD589 \uC0C1\uD669\uC740 \uD56D\uC0C1 \uB0B4\uAC00 \uC4F0\uB294 \uC5B8\uC5B4\uB85C \uC27D\uAC8C \uC124\uBA85\uD558\uACE0, \uD655\uC2E4\uD558\uC9C0 \uC54A\uC740 \uC815\uBCF4\uB294 \uC9C0\uC5B4\uB0B4\uC9C0 \uB9D0\uACE0 \uB098\uC5D0\uAC8C \uBB3C\uC5B4\uBD10\uC918.`;
45949
46169
  var INSTALL_PROMPT_GENERIC = `\uC548\uB155, \uC544\uB798 CareerMate \uC124\uCE58 \uC548\uB0B4(\uC124\uCE58 \uD398\uC774\uC9C0 \uB610\uB294 INSTALL.md)\uB97C \uC77D\uACE0 \uB0B4 \uCEF4\uD4E8\uD130\uC5D0 CareerMate\uB97C \uC124\uCE58\uD558\uACE0 \uC124\uC815\uD574\uC918.
45950
46170
 
45951
46171
  CareerMate\uB294 \uB0B4 \uCEE4\uB9AC\uC5B4 \uB370\uC774\uD130(\uD504\uB85C\uD544\xB7\uC774\uB825\uC11C\xB7\uC790\uAE30\uC18C\uAC1C\uC11C\xB7\uC9C0\uC6D0 \uD604\uD669)\uB97C \uB0B4 \uCEF4\uD4E8\uD130\uC5D0 \uC800\uC7A5\uD558\uACE0, MCP\uB97C \uD1B5\uD574 \uB108(\uB0B4 AI)\uAC00 \uADF8 \uB370\uC774\uD130\uB97C \uC77D\uACE0 \uC4F8 \uC218 \uC788\uAC8C \uD574\uC8FC\uB294 \uB3C4\uAD6C\uC57C. \uBD84\uC11D\uACFC \uC791\uC131\uC740 \uC804\uBD80 \uB124\uAC00 \uD574.
@@ -45953,21 +46173,21 @@ CareerMate\uB294 \uB0B4 \uCEE4\uB9AC\uC5B4 \uB370\uC774\uD130(\uD504\uB85C\uD544
45953
46173
  \uC774\uB807\uAC8C \uC9C4\uD589\uD574\uC918.
45954
46174
  1. \uC124\uCE58 \uC548\uB0B4 \uBB38\uC11C\uB97C \uB05D\uAE4C\uC9C0 \uC77D\uACE0 \uADF8\uB300\uB85C \uB530\uB77C \uC124\uCE58\uD574.
45955
46175
  2. \uB124\uAC00 \uC4F0\uB294 AI \uB3C4\uAD6C\uC5D0 CareerMate MCP \uC11C\uBC84\uB97C \uC5F0\uACB0(\uC124\uC815)\uD574\uC918.
45956
- 3. \uC5F0\uACB0 \uD6C4 \`get_onboarding_status\`\uB97C \uD638\uCD9C\uD574 \uC5F0\uACB0 \uC0C1\uD0DC\uB97C \uD655\uC778\uD558\uACE0, \uACB0\uACFC\uB97C \uC26C\uC6B4 \uD55C\uAD6D\uC5B4\uB85C \uC54C\uB824\uC918.
46176
+ 3. \uC5F0\uACB0 \uD6C4 \`get_onboarding_status\`\uB97C \uD638\uCD9C\uD574 \uC5F0\uACB0 \uC0C1\uD0DC\uB97C \uD655\uC778\uD558\uACE0, \uACB0\uACFC\uB97C \uB0B4\uAC00 \uC4F0\uB294 \uC5B8\uC5B4\uB85C \uC27D\uAC8C \uC54C\uB824\uC918.
45957
46177
  4. \uB098\uC5D0\uAC8C \uC774\uB825\uC11C\uB098 \uC790\uAE30\uC18C\uAC1C\uC11C \uD30C\uC77C\uC744 \uC5C5\uB85C\uB4DC\uD558\uB77C\uACE0 \uC548\uB0B4\uD574\uC918.
45958
46178
  5. \uC62C\uB9B0 \uD30C\uC77C\uB85C \uB0B4 \uD504\uB85C\uD544\uC744 \uAD6C\uC870\uD654\uD574\uC11C \`save_profile\`\uB85C \uC800\uC7A5\uD558\uACE0 \uC628\uBCF4\uB529\uC744 \uC2DC\uC791\uD574\uC918.
45959
46179
 
45960
- \uB9E4 \uB2E8\uACC4\uB9C8\uB2E4 \uC26C\uC6B4 \uD55C\uAD6D\uC5B4\uB85C \uC124\uBA85\uD558\uACE0, \uBD88\uD655\uC2E4\uD55C \uB0B4\uC6A9\uC740 \uC9C0\uC5B4\uB0B4\uC9C0 \uB9D0\uACE0 \uB098\uC5D0\uAC8C \uD655\uC778\uD574\uC918.`;
46180
+ \uB9E4 \uB2E8\uACC4\uB9C8\uB2E4 \uB0B4\uAC00 \uC4F0\uB294 \uC5B8\uC5B4\uB85C \uC27D\uAC8C \uC124\uBA85\uD558\uACE0, \uBD88\uD655\uC2E4\uD55C \uB0B4\uC6A9\uC740 \uC9C0\uC5B4\uB0B4\uC9C0 \uB9D0\uACE0 \uB098\uC5D0\uAC8C \uD655\uC778\uD574\uC918.`;
45961
46181
 
45962
46182
  // packages/prompts/src/onboarding.ts
45963
- var ONBOARDING_PROMPT = `\uC774\uC81C CareerMate\uC5D0 \uC5F0\uACB0\uB418\uC5C8\uC2B5\uB2C8\uB2E4. \uC0AC\uC6A9\uC790\uC758 \uCEE4\uB9AC\uC5B4 \uB370\uC774\uD130 \uCCAB \uC14B\uC5C5(\uC628\uBCF4\uB529)\uC744 \uB3C4\uC640\uC8FC\uC138\uC694.
46183
+ var ONBOARDING_PROMPT = `\uC774\uC81C CareerMate\uC5D0 \uC5F0\uACB0\uB418\uC5C8\uC2B5\uB2C8\uB2E4. \uC0AC\uC6A9\uC790\uC758 \uCEE4\uB9AC\uC5B4 \uB370\uC774\uD130 \uCCAB \uC14B\uC5C5(\uC628\uBCF4\uB529)\uC744 \uB3C4\uC640\uC8FC\uC138\uC694. \uC0AC\uC6A9\uC790\uAC00 \uC4F0\uB294 \uC5B8\uC5B4\uB85C \uC548\uB0B4\uD558\uC138\uC694 \u2014 \uC774 \uC548\uB0B4\uBB38\uC774 \uD55C\uAD6D\uC5B4\uB77C\uB3C4 \uC0AC\uC6A9\uC790\uAC00 \uB2E4\uB978 \uC5B8\uC5B4\uB85C \uB9D0\uD558\uBA74 \uADF8 \uC5B8\uC5B4\uB85C \uB2F5\uD569\uB2C8\uB2E4.
45964
46184
 
45965
46185
  # 1\uB2E8\uACC4 \u2014 \uD604\uC7AC \uC0C1\uD0DC \uD655\uC778
45966
46186
  - \uBA3C\uC800 \`get_onboarding_status\`\uB97C \uD638\uCD9C\uD558\uC138\uC694. \uACB0\uACFC\uC758 has_profile / has_resume / has_cover_letter / has_experience / has_skills / has_job, profile_completeness(\uC644\uC131\uB3C4), next_steps(\uB2E4\uC74C \uB2E8\uACC4)\uB97C \uD655\uC778\uD569\uB2C8\uB2E4.
45967
- - \uC0AC\uC6A9\uC790\uC5D0\uAC8C "\uC9C0\uAE08\uAE4C\uC9C0 \uB4F1\uB85D\uB41C \uC815\uBCF4"\uC640 "\uC55E\uC73C\uB85C \uCC44\uC6B0\uBA74 \uC88B\uC740 \uC815\uBCF4"\uB97C \uC26C\uC6B4 \uD55C\uAD6D\uC5B4\uB85C \uC9E7\uAC8C \uC548\uB0B4\uD558\uC138\uC694. (\uC774\uBBF8 \uCC44\uC6CC\uC9C4 \uD56D\uBAA9\uC740 \uB2E4\uC2DC \uBB3B\uC9C0 \uB9C8\uC138\uC694.)
46187
+ - \uC0AC\uC6A9\uC790\uC5D0\uAC8C "\uC9C0\uAE08\uAE4C\uC9C0 \uB4F1\uB85D\uB41C \uC815\uBCF4"\uC640 "\uC55E\uC73C\uB85C \uCC44\uC6B0\uBA74 \uC88B\uC740 \uC815\uBCF4"\uB97C \uC0AC\uC6A9\uC790\uC758 \uC5B8\uC5B4\uB85C \uC27D\uACE0 \uC9E7\uAC8C \uC548\uB0B4\uD558\uC138\uC694. (\uC774\uBBF8 \uCC44\uC6CC\uC9C4 \uD56D\uBAA9\uC740 \uB2E4\uC2DC \uBB3B\uC9C0 \uB9C8\uC138\uC694.)
45968
46188
 
45969
46189
  # 2\uB2E8\uACC4 \u2014 \uD504\uB85C\uD544 \uC218\uC9D1 \uBC0F \uC800\uC7A5
45970
- - \uC0AC\uC6A9\uC790\uAC00 \uC62C\uB9B0 \uC774\uB825\uC11C/\uC790\uAE30\uC18C\uAC1C\uC11C \uD30C\uC77C\uC774\uB098 \uC0AC\uC6A9\uC790\uAC00 \uC9C1\uC811 \uC54C\uB824\uC900 \uB0B4\uC6A9\uC744 \uBC14\uD0D5\uC73C\uB85C \uD504\uB85C\uD544\uC744 \uAD6C\uC870\uD654\uD558\uC138\uC694.
46190
+ - \uC0AC\uC6A9\uC790\uAC00 \uC62C\uB9B0 \uC774\uB825\uC11C/\uACBD\uB825\uAE30\uC220\uC11C/\uD3EC\uD2B8\uD3F4\uB9AC\uC624/\uC790\uAE30\uC18C\uAC1C\uC11C \uD30C\uC77C\uC774\uB098 \uC0AC\uC6A9\uC790\uAC00 \uC9C1\uC811 \uC54C\uB824\uC900 \uB0B4\uC6A9\uC744 \uBC14\uD0D5\uC73C\uB85C \uD504\uB85C\uD544\uC744 \uAD6C\uC870\uD654\uD558\uC138\uC694.
45971
46191
  - \uC774\uB984, \uC5F0\uB77D\uCC98, \uD55C \uC904 \uC18C\uAC1C(headline), \uC790\uAE30\uC18C\uAC1C \uC694\uC57D(summary), \uD76C\uB9DD \uC9C1\uBB34(desired_roles), \uD76C\uB9DD \uADFC\uBB34 \uC870\uAC74(desired_conditions)\uC744 \uC815\uB9AC\uD569\uB2C8\uB2E4.
45972
46192
  - \uAE00\uC4F0\uAE30 \uC120\uD638\uB3C4 \uD568\uAED8 \uBB3C\uC5B4\uBCF4\uC138\uC694: \uC120\uD638 \uBB38\uCCB4(preferred_tone, \uC608: "\uB2F4\uBC31\uD558\uACE0 \uAD6C\uCCB4\uC801")\uC640 \uAC15\uC870\uD558\uACE0 \uC2F6\uC740 \uD575\uC2EC \uD3EC\uC778\uD2B8(emphasis_points). \uC774 \uC815\uBCF4\uB294 \uC774\uD6C4 \uC790\uAE30\uC18C\uAC1C\uC11C \uC791\uC131\uC5D0 \uADF8\uB300\uB85C \uD65C\uC6A9\uB429\uB2C8\uB2E4.
45973
46193
  - \uC815\uB9AC\uD55C \uB0B4\uC6A9\uC744 \`save_profile\`\uB85C \uC800\uC7A5\uD558\uC138\uC694. \uD30C\uC77C\uC5D0\uC11C \uC77D\uC5B4\uC628 \uC815\uBCF4\uB294 source\uB97C 'upload', \uC0AC\uC6A9\uC790\uAC00 \uB9D0\uB85C \uC54C\uB824\uC900 \uC815\uBCF4\uB294 'manual'\uB85C \uD45C\uC2DC\uD558\uC138\uC694.
@@ -45986,7 +46206,7 @@ var ONBOARDING_PROMPT = `\uC774\uC81C CareerMate\uC5D0 \uC5F0\uACB0\uB418\uC5C8\
45986
46206
  - \uB2E4\uC2DC \`get_onboarding_status\`\uB85C \uC644\uC131\uB3C4\uB97C \uD655\uC778\uD558\uACE0, \uBE44\uC5B4 \uC788\uB294 \uBD80\uBD84\uC774 \uC788\uC73C\uBA74 \uCC44\uC6B0\uC790\uACE0 \uC81C\uC548\uD558\uC138\uC694.
45987
46207
  - \uB9C8\uBB34\uB9AC\uB85C \uB2E4\uC74C \uD589\uB3D9\uC744 \uC81C\uC548\uD558\uC138\uC694. \uC608: "\uC9C0\uC6D0\uD558\uACE0 \uC2F6\uC740 \uACF5\uACE0\uAC00 \uC788\uC73C\uBA74 \uB9C1\uD06C\uB098 \uB0B4\uC6A9\uC744 \uBD99\uC5EC\uC8FC\uC138\uC694. \uC801\uD569\uB3C4\uB97C \uBD84\uC11D\uD574\uB4DC\uB9B4\uAC8C\uC694."
45988
46208
 
45989
- \uC9C4\uD589 \uB0B4\uB0B4 \uAE30\uC220 \uC6A9\uC5B4(MCP, job_id \uB4F1)\uB294 \uBE7C\uACE0, \uC9C0\uAE08 \uBB34\uC5C7\uC744 \uD558\uACE0 \uC788\uB294\uC9C0 \uC26C\uC6B4 \uD55C\uAD6D\uC5B4\uB85C \uC54C\uB824\uC8FC\uC138\uC694.`;
46209
+ \uC9C4\uD589 \uB0B4\uB0B4 \uAE30\uC220 \uC6A9\uC5B4(MCP, job_id \uB4F1)\uB294 \uBE7C\uACE0, \uC9C0\uAE08 \uBB34\uC5C7\uC744 \uD558\uACE0 \uC788\uB294\uC9C0 \uC0AC\uC6A9\uC790\uC758 \uC5B8\uC5B4\uB85C \uC27D\uAC8C \uC54C\uB824\uC8FC\uC138\uC694.`;
45990
46210
 
45991
46211
  // packages/prompts/src/humanize.ts
45992
46212
  var HUMANIZE_WRITING_GUIDE = `# \uC0AC\uB78C\uC774 \uC4F4 \uAC83\uCC98\uB7FC: \uC790\uAE30\uC18C\uAC1C\uC11C\xB7\uCEE4\uB9AC\uC5B4 \uAE00\uC4F0\uAE30 \uADDC\uCE59
@@ -45994,6 +46214,8 @@ var HUMANIZE_WRITING_GUIDE = `# \uC0AC\uB78C\uC774 \uC4F4 \uAC83\uCC98\uB7FC: \u
45994
46214
  \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.
45995
46215
  \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.
45996
46216
 
46217
+ > **\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.
46218
+
45997
46219
  ## \uC808\uB300 \uC6D0\uCE59
45998
46220
  - \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.
45999
46221
  - \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.
@@ -46085,7 +46307,7 @@ var WORKFLOWS = [
46085
46307
  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.',
46086
46308
  steps: [
46087
46309
  "`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.",
46088
- '\uBE44\uC5B4 \uC788\uB294 \uD56D\uBAA9\uC744 \uC0AC\uC6A9\uC790\uC5D0\uAC8C \uC26C\uC6B4 \uD55C\uAD6D\uC5B4\uB85C \uC548\uB0B4\uD558\uACE0, \uBA3C\uC800 "\uAE30\uC874\uC5D0 \uC791\uC131\uD574 \uB454 \uC774\uB825\uC11C\xB7\uACBD\uB825\uAE30\uC220\uC11C \uD30C\uC77C\uC774 \uC788\uB294\uC9C0" \uBB3B\uB294\uB2E4(hwp/docx/pdf \uBAA8\uB450 \uAC00\uB2A5).',
46310
+ '\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).',
46089
46311
  '\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.)',
46090
46312
  "\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.",
46091
46313
  "\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).",
@@ -46106,7 +46328,7 @@ var WORKFLOWS = [
46106
46328
  "\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.",
46107
46329
  "\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.",
46108
46330
  "\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).",
46109
- "\uBD84\uC11D \uACB0\uACFC\uB97C \uC0AC\uC6A9\uC790\uC5D0\uAC8C \uC26C\uC6B4 \uD55C\uAD6D\uC5B4\uB85C \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.",
46331
+ "\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.",
46110
46332
  '\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".',
46111
46333
  '\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.',
46112
46334
  "\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).",
@@ -46125,7 +46347,24 @@ var WORKFLOWS = [
46125
46347
  "\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.",
46126
46348
  "\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).",
46127
46349
  "\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.",
46128
- "\uC800\uC7A5 \uACB0\uACFC\uB97C \uC26C\uC6B4 \uD55C\uAD6D\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."
46350
+ "\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."
46351
+ ]
46352
+ },
46353
+ {
46354
+ id: "write_career_description",
46355
+ title: "\uACBD\uB825\uAE30\uC220\uC11C \uC791\uC131",
46356
+ 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.",
46357
+ 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.',
46358
+ steps: [
46359
+ "`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.",
46360
+ "\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.",
46361
+ '`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.',
46362
+ "\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.",
46363
+ "\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.",
46364
+ '\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.',
46365
+ '\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.',
46366
+ "\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.",
46367
+ "\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."
46129
46368
  ]
46130
46369
  },
46131
46370
  {
@@ -46136,7 +46375,7 @@ var WORKFLOWS = [
46136
46375
  steps: [
46137
46376
  "\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.",
46138
46377
  "\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.",
46139
- "\uBCC0\uACBD \uACB0\uACFC\uB97C \uC0AC\uC6A9\uC790\uC5D0\uAC8C \uC26C\uC6B4 \uD55C\uAD6D\uC5B4\uB85C \uC54C\uB9B0\uB2E4.",
46378
+ "\uBCC0\uACBD \uACB0\uACFC\uB97C \uC0AC\uC6A9\uC790\uC758 \uC5B8\uC5B4\uB85C \uC27D\uAC8C \uC54C\uB9B0\uB2E4.",
46140
46379
  "\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.",
46141
46380
  "\uD544\uC694\uD558\uBA74 `open_application`\uC73C\uB85C \uD574\uB2F9 \uC9C0\uC6D0 \uAC74\uC744 \uC5F4\uC5B4 \uBCF4\uC5EC\uC900\uB2E4."
46142
46381
  ]
@@ -46144,14 +46383,29 @@ var WORKFLOWS = [
46144
46383
  {
46145
46384
  id: "prepare_interview",
46146
46385
  title: "\uBA74\uC811 \uC900\uBE44",
46147
- description: "\uC11C\uB958 \uD569\uACA9 \uC774\uD6C4 \uC608\uC0C1 \uC9C8\uBB38\xB7STAR \uB2F5\uBCC0\xB71\uBD84 \uC790\uAE30\uC18C\uAC1C\uB97C \uC900\uBE44\uD574 \uC800\uC7A5\uD558\uB294 \uD750\uB984.",
46148
- 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, \uB610\uB294 \uC0AC\uC6A9\uC790\uAC00 "\uBA74\uC811 \uC900\uBE44 \uB3C4\uC640\uC918"\uB77C\uACE0 \uC694\uCCAD\uD560 \uB54C.',
46386
+ 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.",
46387
+ 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.',
46149
46388
  steps: [
46150
46389
  "`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.",
46151
46390
  "\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.",
46152
46391
  "\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.",
46153
46392
  "\uC900\uBE44 \uB0B4\uC6A9\uC744 `save_interview_prep`\uB85C \uC800\uC7A5\uD55C\uB2E4(job_id, questions, star_guides, self_introduction, notes).",
46154
- "\uC900\uBE44 \uB0B4\uC6A9\uC744 \uC0AC\uC6A9\uC790\uC5D0\uAC8C \uC26C\uC6B4 \uD55C\uAD6D\uC5B4\uB85C \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."
46393
+ "\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."
46394
+ ]
46395
+ },
46396
+ {
46397
+ id: "build_personal_brand",
46398
+ title: "\uD37C\uC2A4\uB110 \uBE0C\uB79C\uB4DC (LinkedIn\xB7\uD3EC\uD2B8\uD3F4\uB9AC\uC624)",
46399
+ 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.",
46400
+ 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.',
46401
+ steps: [
46402
+ "`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.",
46403
+ '`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.',
46404
+ "\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.",
46405
+ "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.",
46406
+ '\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.',
46407
+ "\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.",
46408
+ "\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."
46155
46409
  ]
46156
46410
  }
46157
46411
  ];
@@ -46693,6 +46947,14 @@ function resumeToMarkdown(doc, profile) {
46693
46947
  content: body
46694
46948
  };
46695
46949
  }
46950
+ function resumeToHtml(doc, profile) {
46951
+ const md = resumeToMarkdown(doc, profile);
46952
+ return {
46953
+ filename: `${slugify(doc.title, doc.kind)}.html`,
46954
+ mimeType: HTML_MIME,
46955
+ content: toPrintableHtml(doc.title, md.content)
46956
+ };
46957
+ }
46696
46958
  function profileToMarkdown(profile, experiences = [], projects = [], skills = []) {
46697
46959
  const name = profile.name?.trim() || "\uC774\uB825\uC11C";
46698
46960
  const contact = [];
@@ -46774,6 +47036,15 @@ function profileToMarkdown(profile, experiences = [], projects = [], skills = []
46774
47036
  content
46775
47037
  };
46776
47038
  }
47039
+ function profileToHtml(profile, experiences = [], projects = [], skills = []) {
47040
+ const md = profileToMarkdown(profile, experiences, projects, skills);
47041
+ const title = profile.name?.trim() || "\uC774\uB825\uC11C";
47042
+ return {
47043
+ filename: `${slugify(title, "resume")}-resume.html`,
47044
+ mimeType: HTML_MIME,
47045
+ content: toPrintableHtml(title, md.content)
47046
+ };
47047
+ }
46777
47048
  function interviewPrepToMarkdown(prep, job) {
46778
47049
  const titleBase = job ? `${job.company} ${job.position} \uBA74\uC811 \uC900\uBE44` : "\uBA74\uC811 \uC900\uBE44";
46779
47050
  const meta = [];
@@ -46782,17 +47053,22 @@ function interviewPrepToMarkdown(prep, job) {
46782
47053
  if (job.deadline) meta.push(kv("\uB9C8\uAC10", job.deadline));
46783
47054
  }
46784
47055
  const introBlock = prep.self_introduction?.trim() ? joinBlocks(["## 1\uBD84 \uC790\uAE30\uC18C\uAC1C", prep.self_introduction.trim()]) : "";
46785
- const questionsBlock = prep.questions?.length ? joinBlocks([
46786
- "## \uC608\uC0C1 \uC9C8\uBB38",
46787
- ...prep.questions.map(
46788
- (q, idx) => joinBlocks([
46789
- `### Q${idx + 1}. ${q.question}`,
46790
- q.intent?.trim() ? kv("\uC758\uB3C4", q.intent) : "",
46791
- q.answer_outline?.trim() ? joinBlocks(["**\uB2F5\uBCC0 \uAC00\uC774\uB4DC**", q.answer_outline.trim()]) : "",
46792
- q.followups?.length ? joinBlocks(["**\uC608\uC0C1 \uAF2C\uB9AC \uC9C8\uBB38**", bulletList(q.followups)]) : ""
46793
- ])
46794
- )
46795
- ]) : "";
47056
+ const renderQuestion = (q, idx, level) => joinBlocks([
47057
+ `${level} Q${idx + 1}. ${q.question}`,
47058
+ q.intent?.trim() ? kv("\uC758\uB3C4", q.intent) : "",
47059
+ q.answer_outline?.trim() ? joinBlocks(["**\uB2F5\uBCC0 \uAC00\uC774\uB4DC**", q.answer_outline.trim()]) : "",
47060
+ q.followups?.length ? joinBlocks(["**\uC608\uC0C1 \uAF2C\uB9AC \uC9C8\uBB38**", bulletList(q.followups)]) : ""
47061
+ ]);
47062
+ let questionsBlock = "";
47063
+ if (prep.questions?.length) {
47064
+ const technical = prep.questions.filter((q) => (q.category ?? "technical") === "technical");
47065
+ const behavioral = prep.questions.filter((q) => q.category === "behavioral");
47066
+ questionsBlock = behavioral.length ? joinBlocks([
47067
+ "## \uC608\uC0C1 \uC9C8\uBB38",
47068
+ technical.length ? joinBlocks(["### \uAE30\uC220 \uBA74\uC811", ...technical.map((q, i) => renderQuestion(q, i, "####"))]) : "",
47069
+ joinBlocks(["### \uC778\uC131\xB7\uCEEC\uCC98\uD54F \uBA74\uC811", ...behavioral.map((q, i) => renderQuestion(q, i, "####"))])
47070
+ ]) : joinBlocks(["## \uC608\uC0C1 \uC9C8\uBB38", ...prep.questions.map((q, i) => renderQuestion(q, i, "###"))]);
47071
+ }
46796
47072
  const starBlock = prep.star_guides?.length ? joinBlocks([
46797
47073
  "## STAR \uC815\uB9AC",
46798
47074
  ...prep.star_guides.map(
@@ -46821,6 +47097,15 @@ function interviewPrepToMarkdown(prep, job) {
46821
47097
  content
46822
47098
  };
46823
47099
  }
47100
+ function interviewPrepToHtml(prep, job) {
47101
+ const md = interviewPrepToMarkdown(prep, job);
47102
+ const title = job ? `${job.company} ${job.position} \uBA74\uC811 \uC900\uBE44` : "\uBA74\uC811 \uC900\uBE44";
47103
+ return {
47104
+ filename: `${slugify(title, "interview-prep")}.html`,
47105
+ mimeType: HTML_MIME,
47106
+ content: toPrintableHtml(title, md.content)
47107
+ };
47108
+ }
46824
47109
 
46825
47110
  // apps/web/src/exports.ts
46826
47111
  function asFormat(result2, format) {
@@ -46844,20 +47129,25 @@ function exportCoverLetter(id3, format) {
46844
47129
  function exportDocument(id3, format) {
46845
47130
  const doc = documentRepo.get(id3);
46846
47131
  if (!doc) throw new HttpError(404, "\uBB38\uC11C\uB97C \uCC3E\uC744 \uC218 \uC5C6\uC2B5\uB2C8\uB2E4.");
46847
- return asFormat(resumeToMarkdown(doc, profileRepo.get()), format);
47132
+ const profile = profileRepo.get();
47133
+ if (format === "html") return resumeToHtml(doc, profile);
47134
+ return asFormat(resumeToMarkdown(doc, profile), format);
46848
47135
  }
46849
47136
  function exportProfile(format) {
46850
47137
  const profile = profileRepo.get();
46851
47138
  if (!profile) throw new HttpError(404, "\uD504\uB85C\uD544\uC774 \uC5C6\uC2B5\uB2C8\uB2E4.");
46852
- return asFormat(
46853
- profileToMarkdown(profile, experienceRepo.list(), projectRepo.list(), skillRepo.list()),
46854
- format
46855
- );
47139
+ const experiences = experienceRepo.list();
47140
+ const projects = projectRepo.list();
47141
+ const skills = skillRepo.list();
47142
+ if (format === "html") return profileToHtml(profile, experiences, projects, skills);
47143
+ return asFormat(profileToMarkdown(profile, experiences, projects, skills), format);
46856
47144
  }
46857
47145
  function exportInterview(jobId, format) {
46858
47146
  const prep = interviewRepo.getByJob(jobId);
46859
47147
  if (!prep) throw new HttpError(404, "\uBA74\uC811 \uC900\uBE44 \uC790\uB8CC\uAC00 \uC5C6\uC2B5\uB2C8\uB2E4.");
46860
- return asFormat(interviewPrepToMarkdown(prep, jobRepo.get(jobId)), format);
47148
+ const job = jobRepo.get(jobId);
47149
+ if (format === "html") return interviewPrepToHtml(prep, job);
47150
+ return asFormat(interviewPrepToMarkdown(prep, job), format);
46861
47151
  }
46862
47152
 
46863
47153
  // apps/web/src/info.ts
@@ -46906,6 +47196,7 @@ var RESTORE_ORDER = [
46906
47196
  "fit_analyses",
46907
47197
  "applications",
46908
47198
  "interview_preps",
47199
+ "application_timeline_events",
46909
47200
  "activities"
46910
47201
  ];
46911
47202
  function quoteIdent(name) {
@@ -47255,6 +47546,138 @@ function fmt(ctx) {
47255
47546
  function backupError(e) {
47256
47547
  return new HttpError(400, e instanceof Error ? e.message : "\uBC31\uC5C5 \uD30C\uC77C\uC744 \uCC98\uB9AC\uD558\uC9C0 \uBABB\uD588\uC2B5\uB2C8\uB2E4.", "backup_import");
47257
47548
  }
47549
+ function isRecord2(v) {
47550
+ return typeof v === "object" && v !== null && !Array.isArray(v);
47551
+ }
47552
+ function documentRoute(doc) {
47553
+ return doc.kind === "career_description" ? `/documents/career/${doc.id}` : `/documents/docs/${doc.id}`;
47554
+ }
47555
+ function enrichDocumentRef(ref) {
47556
+ if (!isRecord2(ref)) return ref;
47557
+ const refId = typeof ref.id === "string" ? ref.id : null;
47558
+ const doc = refId ? documentRepo.get(refId) : null;
47559
+ const kind = doc?.kind ?? ref.document_kind ?? ref.kind ?? null;
47560
+ return {
47561
+ ...ref,
47562
+ title: doc?.title ?? ref.title ?? "\uC0AD\uC81C\uB41C \uBB38\uC11C",
47563
+ document_kind: kind,
47564
+ exists: !!doc,
47565
+ route: doc ? documentRoute(doc) : null
47566
+ };
47567
+ }
47568
+ function enrichCoverLetterRef(ref) {
47569
+ if (!isRecord2(ref)) return ref;
47570
+ const refId = typeof ref.id === "string" ? ref.id : null;
47571
+ const cl = refId ? coverLetterRepo.get(refId, false) : null;
47572
+ return {
47573
+ ...ref,
47574
+ title: cl?.title ?? ref.title ?? "\uC0AD\uC81C\uB41C \uC790\uAE30\uC18C\uAC1C\uC11C",
47575
+ exists: !!cl,
47576
+ route: cl ? `/documents/cover/${cl.id}` : null
47577
+ };
47578
+ }
47579
+ function enrichTimelinePayload(payload) {
47580
+ const out = isRecord2(payload) ? { ...payload } : {};
47581
+ if (out.cover_letter) out.cover_letter = enrichCoverLetterRef(out.cover_letter);
47582
+ if (isRecord2(out.submission)) {
47583
+ const submission = { ...out.submission };
47584
+ if (submission.cover_letter) submission.cover_letter = enrichCoverLetterRef(submission.cover_letter);
47585
+ if (Array.isArray(submission.documents)) submission.documents = submission.documents.map(enrichDocumentRef);
47586
+ out.submission = submission;
47587
+ }
47588
+ return out;
47589
+ }
47590
+ function buildTimeline(job) {
47591
+ const application = applicationRepo.getByJob(job.id);
47592
+ const fit = fitRepo.getByJob(job.id);
47593
+ const coverLetters = coverLetterRepo.listByJob(job.id);
47594
+ const interview = interviewRepo.getByJob(job.id);
47595
+ const stored = timelineRepo.listByJob(job.id);
47596
+ const events = [
47597
+ {
47598
+ id: `synthetic-job-${job.id}`,
47599
+ job_id: job.id,
47600
+ type: "job_saved",
47601
+ title: "\uACF5\uACE0 \uB4F1\uB85D",
47602
+ summary: `${job.company} \xB7 ${job.position}`,
47603
+ payload: { synthetic: true },
47604
+ occurred_at: job.created_at,
47605
+ created_at: job.created_at
47606
+ },
47607
+ ...stored
47608
+ ];
47609
+ const hasStored = (type, predicate) => stored.some((event) => event.type === type && (!predicate || predicate(enrichTimelinePayload(event.payload))));
47610
+ if (fit && !hasStored("fit_analysis_saved", (payload) => payload.fit_id === fit.id)) {
47611
+ events.push({
47612
+ id: `synthetic-fit-${fit.id}`,
47613
+ job_id: job.id,
47614
+ type: "fit_analysis_saved",
47615
+ title: "\uC801\uD569\uB3C4 \uBD84\uC11D",
47616
+ summary: fit.score != null ? `\uC885\uD569 ${fit.score}\uC810` : fit.summary,
47617
+ payload: { synthetic: true, fit_id: fit.id, score: fit.score },
47618
+ occurred_at: fit.updated_at,
47619
+ created_at: fit.created_at
47620
+ });
47621
+ }
47622
+ for (const cl of coverLetters) {
47623
+ const versionId = cl.current_version_id;
47624
+ const alreadyStored = hasStored("cover_letter_version_saved", (payload) => {
47625
+ const ref = isRecord2(payload.cover_letter) ? payload.cover_letter : null;
47626
+ return ref?.id === cl.id && (!versionId || ref.version_id === versionId);
47627
+ });
47628
+ if (!alreadyStored) {
47629
+ events.push({
47630
+ id: `synthetic-cover-${cl.id}`,
47631
+ job_id: job.id,
47632
+ type: "cover_letter_version_saved",
47633
+ title: "\uC790\uAE30\uC18C\uAC1C\uC11C \uC791\uC131",
47634
+ summary: `${cl.title}${cl.version_count ? ` v${cl.version_count}` : ""}`,
47635
+ payload: {
47636
+ synthetic: true,
47637
+ cover_letter: {
47638
+ kind: "cover_letter",
47639
+ id: cl.id,
47640
+ title: cl.title,
47641
+ version_id: versionId,
47642
+ version_no: cl.version_count
47643
+ }
47644
+ },
47645
+ occurred_at: cl.updated_at,
47646
+ created_at: cl.created_at
47647
+ });
47648
+ }
47649
+ }
47650
+ if (application?.status && application.status !== "draft" && !hasStored("application_status_changed", (payload) => payload.status === application.status)) {
47651
+ events.push({
47652
+ id: `synthetic-status-${application.id}`,
47653
+ job_id: job.id,
47654
+ type: "application_status_changed",
47655
+ title: APPLICATION_STATUS_LABELS[application.status],
47656
+ summary: application.notes,
47657
+ payload: {
47658
+ synthetic: true,
47659
+ status: application.status,
47660
+ status_label: APPLICATION_STATUS_LABELS[application.status],
47661
+ submission: null
47662
+ },
47663
+ occurred_at: application.applied_at ?? application.updated_at,
47664
+ created_at: application.created_at
47665
+ });
47666
+ }
47667
+ if (interview && !hasStored("interview_prep_saved", (payload) => payload.interview_prep_id === interview.id)) {
47668
+ events.push({
47669
+ id: `synthetic-interview-${interview.id}`,
47670
+ job_id: job.id,
47671
+ type: "interview_prep_saved",
47672
+ title: "\uBA74\uC811 \uC900\uBE44",
47673
+ summary: interview.questions.length > 0 ? `\uC608\uC0C1 \uC9C8\uBB38 ${interview.questions.length}\uAC1C` : interview.notes,
47674
+ payload: { synthetic: true, interview_prep_id: interview.id, question_count: interview.questions.length },
47675
+ occurred_at: interview.updated_at,
47676
+ created_at: interview.created_at
47677
+ });
47678
+ }
47679
+ return events.sort((a, b) => String(a.occurred_at).localeCompare(String(b.occurred_at)) || String(a.created_at).localeCompare(String(b.created_at))).map((event) => ({ ...event, payload: enrichTimelinePayload(event.payload) }));
47680
+ }
47258
47681
  function jobDetail(jobId) {
47259
47682
  const job = jobRepo.get(jobId);
47260
47683
  if (!job) throw new HttpError(404, "\uACF5\uACE0\uB97C \uCC3E\uC744 \uC218 \uC5C6\uC2B5\uB2C8\uB2E4.");
@@ -47263,13 +47686,15 @@ function jobDetail(jobId) {
47263
47686
  const cover_letters = coverLetterRepo.listByJob(jobId);
47264
47687
  const interview = interviewRepo.getByJob(jobId);
47265
47688
  const related = jobRepo.relatedTo(job.company, job.position, job.id).map(jobWithMeta);
47689
+ const timeline = buildTimeline(job);
47266
47690
  return {
47267
47691
  ...jobWithMeta(job),
47268
47692
  application,
47269
47693
  fit,
47270
47694
  cover_letters,
47271
47695
  interview,
47272
- related
47696
+ related,
47697
+ timeline
47273
47698
  };
47274
47699
  }
47275
47700
  function registerApiRoutes(router2) {
@@ -47418,12 +47843,12 @@ function registerApiRoutes(router2) {
47418
47843
  });
47419
47844
  router2.get("/api/interview", () => {
47420
47845
  const preps = interviewRepo.list().map((p) => ({ ...p, job: jobRepo.get(p.job_id) }));
47421
- const eligible = applicationRepo.list().filter((a) => INTERVIEW_UNLOCK_STATUSES.includes(a.status)).map((a) => ({
47846
+ const eligible = applicationRepo.list().map((a) => ({
47422
47847
  job: jobRepo.get(a.job_id),
47423
47848
  status: a.status,
47424
47849
  status_label: APPLICATION_STATUS_LABELS[a.status],
47425
47850
  has_prep: !!interviewRepo.getByJob(a.job_id)
47426
- })).filter((x) => x.job);
47851
+ })).filter((x) => x.job && (x.has_prep || INTERVIEW_UNLOCK_STATUSES.includes(x.status)));
47427
47852
  return { preps, eligible };
47428
47853
  });
47429
47854
  router2.get("/api/jobs/:id/interview", (ctx) => ({ interview: interviewRepo.getByJob(id2(ctx)) }));
@@ -47442,7 +47867,7 @@ function registerApiRoutes(router2) {
47442
47867
  });
47443
47868
  router2.put("/api/applications/:jobId/status", async (ctx) => {
47444
47869
  const body = await readJsonBody(ctx.req, ApplicationStatusUpdateSchema.omit({ job_id: true, application_id: true }));
47445
- return updateApplicationStatus(id2(ctx, "jobId"), body.status, body.note);
47870
+ return updateApplicationStatus(id2(ctx, "jobId"), body.status, body.note, body.submission);
47446
47871
  });
47447
47872
  router2.put("/api/applications/:jobId", async (ctx) => {
47448
47873
  const body = await readJsonBody(ctx.req, ApplicationInputSchema.omit({ job_id: true }));
@@ -47526,7 +47951,7 @@ function isDownload(v) {
47526
47951
  // apps/web/src/server.ts
47527
47952
  var __dirname2 = path5.dirname(fileURLToPath2(import.meta.url));
47528
47953
  var WEB_ROOT = BUNDLED ? path5.resolve(__dirname2, "public") : path5.resolve(__dirname2, "..", "public");
47529
- var INSTALL_ROOT = BUNDLED ? path5.resolve(__dirname2, "site") : path5.resolve(__dirname2, "..", "..", "..", "site");
47954
+ var LANDING_URL = "https://careermate.life/";
47530
47955
  var router = new Router();
47531
47956
  registerApiRoutes(router);
47532
47957
  function createServer() {
@@ -47561,16 +47986,11 @@ function createServer() {
47561
47986
  }
47562
47987
  return;
47563
47988
  }
47564
- if (pathname === "/install") {
47565
- res.writeHead(308, { Location: `/install/${url.search}` });
47989
+ if (pathname === "/install" || pathname.startsWith("/install/")) {
47990
+ res.writeHead(302, { Location: LANDING_URL });
47566
47991
  res.end();
47567
47992
  return;
47568
47993
  }
47569
- if (pathname.startsWith("/install/")) {
47570
- const rel2 = pathname === "/install/" ? "index.html" : pathname.slice("/install/".length);
47571
- if (serveStatic(res, INSTALL_ROOT, rel2)) return;
47572
- if (serveStatic(res, INSTALL_ROOT, "index.html")) return;
47573
- }
47574
47994
  const rel = pathname === "/" ? "index.html" : pathname.slice(1);
47575
47995
  if (serveStatic(res, WEB_ROOT, rel, injectToken)) return;
47576
47996
  if (serveStatic(res, WEB_ROOT, "index.html", injectToken)) return;
@@ -47645,7 +48065,7 @@ async function main() {
47645
48065
  console.log(` CareerMate v${APP_VERSION} \u2014 \uB0B4 \uCEE4\uB9AC\uC5B4 \uD750\uB984 \uAD00\uB9AC \uB3C4\uAD6C`);
47646
48066
  console.log(`${" ".repeat(2)}${"\u2504".repeat(52)}`);
47647
48067
  console.log(` \uB300\uC2DC\uBCF4\uB4DC ${url}`);
47648
- console.log(` \uC124\uCE58 \uC548\uB0B4 ${url}/install`);
48068
+ console.log(` \uC124\uCE58\xB7\uC548\uB0B4 https://careermate.life`);
47649
48069
  console.log(` \uB370\uC774\uD130 \uC704\uCE58 ${getDataDir()}`);
47650
48070
  console.log(` (\uBAA8\uB4E0 \uB370\uC774\uD130\uB294 \uC774 \uCEF4\uD4E8\uD130\uC5D0\uB9CC \uC800\uC7A5\uB429\uB2C8\uB2E4)`);
47651
48071
  console.log(`\u2514${line}\u2518