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/docs/FAQ.md CHANGED
@@ -6,6 +6,20 @@
6
6
 
7
7
  ---
8
8
 
9
+ ## 시작하기 전에
10
+
11
+ ### 돈이 드나요? API 키가 필요한가요?
12
+ CareerMate 자체는 **무료·오픈소스**이고, 내부에 LLM이 없어 **별도 API 키가 필요 없습니다.**
13
+ 분석·작성은 이미 쓰고 있는 AI 구독(Claude 등)이 그대로 수행하고, CareerMate는 커리어
14
+ 데이터를 로컬에 저장·제공하는 "서랍장" 역할만 합니다.
15
+
16
+ ### 어떻게 업데이트하나요?
17
+ AI에게 **"CareerMate 업데이트해줘"**(`update_careermate`)라고 하면 최신 버전으로 올립니다.
18
+ 확인만 하려면 "최신이야?"(`check_for_update`). 업데이트 후에는 AI 앱 또는 MCP 연결을
19
+ **재시작**해 주세요.
20
+
21
+ ---
22
+
9
23
  ## 설치 / 연결
10
24
 
11
25
  ### "MCP 도구가 안 보여요" / AI가 CareerMate를 모릅니다
@@ -78,9 +92,15 @@ AI에게 "이 공고 저장하고 분석해줘"라고 하면서 URL이나 본문
78
92
  - AI에게 "분석 전에 application context부터 불러와줘"라고 하면 프로필·이력서·공고를 한 번에
79
93
  모아 분석 맥락을 갖춥니다.
80
94
 
81
- ### 면접 준비가 잠겨 있어요
82
- 면접 준비는 지원 상태가 **'서류 합격(document_passed)' 이상**일 때만 열립니다. 먼저 해당
83
- 공고의 상태를 서류 합격으로 바꿔 주세요(`draft → planned → applied → document_passed → …`).
95
+ ### 면접 준비는 언제 만들 수 있나요
96
+ 공고가 저장되어 있으면 AI에게 면접 준비를 요청해 저장할 수 있습니다. 다만 지원 상태가
97
+ **'서류 합격(document_passed)' 이상**이 되면 대시보드가 면접 준비를 다음 행동으로 더 적극적으로 제안합니다.
98
+
99
+ ### 이력서·자소서를 파일로 받을 수 있나요?
100
+ 네. AI에게 **"이력서 파일로 내보내줘"**(또는 자소서/프로필)라고 하면
101
+ `~/.careermate/exports`에 **Markdown** 또는 **인쇄용 HTML**(브라우저에서 "인쇄 → PDF로 저장")로
102
+ 저장됩니다(`export_resume`/`export_profile`/`export_cover_letter`). 대시보드 **문서·프로필
103
+ 페이지**에서 버튼으로 직접 다운로드할 수도 있습니다.
84
104
 
85
105
  ---
86
106
 
package/docs/MCP_TOOLS.md CHANGED
@@ -2,7 +2,7 @@
2
2
 
3
3
  CareerMate는 **MCP-우선** 로컬 커리어 관리 도구입니다. 사용자는 자신의 ChatGPT/Claude/Gemini와 대화하고, 그 AI가 여기 정의된 MCP 도구를 호출해 로컬 커리어 DB(`~/.careermate/careermate.sqlite`)를 읽고 씁니다. **CareerMate 내부에는 LLM이 없습니다.** 적합도 분석·자기소개서 작성 같은 추론은 모두 사용자의 AI가 수행하고, CareerMate는 데이터를 저장하고 다시 돌려주는 역할만 합니다.
4
4
 
5
- 이 문서는 `packages/mcp-tools/src/tools.ts`에 정의된 커리어 워크플로 **37개 도구**의 레퍼런스입니다. 도구의 입력 파라미터는 `packages/shared/src/schemas.ts`의 zod 스키마와 일치합니다.
5
+ 이 문서는 `packages/mcp-tools/src/tools.ts`에 정의된 커리어 워크플로 **도구**의 레퍼런스입니다. 도구의 입력 파라미터는 `packages/shared/src/schemas.ts`의 zod 스키마와 일치합니다.
6
6
 
7
7
  > 설계 원칙: 이 도구들은 단순 CRUD 래퍼가 아닙니다. 각 도구는 AI가 사용자를 대신해 수행하는 실제 작업에 대응하며, 설명에 *언제* 그리고 *어떻게* 호출해야 하는지가 담겨 있습니다. 가장 중요한 도구는 [`get_application_context`](#get_application_context-) 입니다.
8
8
 
@@ -16,7 +16,7 @@ CareerMate는 **MCP-우선** 로컬 커리어 관리 도구입니다. 사용자
16
16
 
17
17
  | 읽기전용(✅) 도구 | 쓰기/부수효과(✏️) 도구 |
18
18
  | --- | --- |
19
- | `read_document`, `read_inbox`, `get_onboarding_status`, `get_profile`, `get_resumes`, `get_experiences`, `get_projects`, `get_skills`, `get_cover_letters`, `get_job_posting`, `list_jobs`, `get_application_context`, `list_recent_activity`, `get_workflow_guide`, `get_playbook`, `get_verifier`, `validate_cover_letter`, `get_writing_style_guide`, `check_for_update` | `open_inbox`, `save_profile`, `add_resume`, `add_experience`, `add_project`, `add_skill`, `save_cover_letter_version`, `delete_cover_letter`, `set_verify_mode`, `save_job_posting`, `delete_job_posting`, `save_fit_analysis`, `update_application_status`, `save_interview_prep`, `export_cover_letter`, `open_dashboard`, `open_application`, `update_careermate` |
19
+ | `read_document`, `read_inbox`, `get_onboarding_status`, `get_profile`, `get_resumes`, `get_experiences`, `get_projects`, `get_skills`, `get_cover_letters`, `get_job_posting`, `list_jobs`, `get_application_context`, `list_recent_activity`, `get_workflow_guide`, `get_playbook`, `get_verifier`, `validate_cover_letter`, `get_writing_style_guide`, `check_for_update` | `open_inbox`, `save_profile`, `add_resume`, `delete_resume`, `add_experience`, `delete_experience`, `add_project`, `delete_project`, `add_skill`, `delete_skill`, `save_cover_letter_version`, `delete_cover_letter`, `set_verify_mode`, `save_job_posting`, `delete_job_posting`, `save_fit_analysis`, `update_application_status`, `save_interview_prep`, `export_cover_letter`, `export_resume`, `export_profile`, `open_dashboard`, `open_application`, `update_careermate` |
20
20
 
21
21
  ---
22
22
 
@@ -35,16 +35,16 @@ CareerMate는 **MCP-우선** 로컬 커리어 관리 도구입니다. 사용자
35
35
 
36
36
  ## 0-1. 인입 폴더 (Inbox)
37
37
 
38
- CLI 클라이언트(Claude Code·Codex 등)는 파일 첨부가 안 되므로, 사용자가 기존 이력서·경력기술서 파일을 끌어다 넣을 수 있는 로컬 인입 폴더(`~/.careermate/inbox`)를 두고 그 안의 파일을 읽습니다. 사용자가 파일 **경로**를 직접 알려주는 경우에는 인입 폴더 대신 `read_document`를 쓰세요.
38
+ CLI 클라이언트(Claude Code·Codex 등)는 파일 첨부가 안 되므로, 사용자가 기존 이력서·경력기술서·포트폴리오·자기소개서 파일을 끌어다 넣을 수 있는 로컬 인입 폴더(`~/.careermate/inbox`)를 두고 그 안의 파일을 읽습니다. 사용자가 파일 **경로**를 직접 알려주는 경우에는 인입 폴더 대신 `read_document`를 쓰세요.
39
39
 
40
40
  | 도구 | 목적 | 주요 입력 | 반환 | 언제 호출 | 읽기전용 |
41
41
  | --- | --- | --- | --- | --- | --- |
42
- | `open_inbox` | 인입 폴더(`~/.careermate/inbox`)를 보장하고 파일 탐색기로 열기 + 현재 들어 있는 파일 목록 반환 | 없음 | `{ dir, files[] }` | 온보딩에서 사용자가 "기존에 작성해 둔 이력서 파일이 있다"고 답했을 때만(묻지 않고 자동으로 열지 마세요) | ✏️ |
42
+ | `open_inbox` | 인입 폴더(`~/.careermate/inbox`)를 보장하고 파일 탐색기로 열기 + 현재 들어 있는 파일 목록 반환 | 없음 | `{ dir, files[] }` | 온보딩에서 사용자가 "기존에 작성해 둔 문서 파일이 있다"고 답했을 때만(묻지 않고 자동으로 열지 마세요) | ✏️ |
43
43
  | `read_inbox` | 인입 폴더에 넣어 둔 문서들의 본문을 한 번에 추출해 반환 | `filename?`(대소문자 무시, 생략 시 전체), `max_chars?`(파일별 기본 20000자) | `{ dir, files[] }`(각 `{ filename, path, format, unsupported, truncated, warnings[], text }`) | `open_inbox`로 안내한 뒤 사용자가 "다 넣었어"라고 할 때 | ✅ |
44
44
 
45
45
  - `open_inbox`는 폴더를 열기만 합니다. 사용자가 파일을 다 넣었다고 하면 `read_inbox`로 본문을 읽으세요.
46
- - `docx`/`hwp`/`hwpx`/텍스트는 텍스트를 추출하고, **`pdf`·이미지는 추출하지 않고 파일 경로만** 돌려주니(`unsupported`) AI 클라이언트의 파일 읽기 기능으로 그 경로를 직접 열어 읽으세요.
47
- - 읽은 내용은 그대로 새 파일로 다시 쓰지 말고, 구조화해 `save_profile`·`add_resume` 등 알맞은 도구로 CareerMate에 저장하세요.
46
+ - `pdf`·`docx`·`hwp`/`hwpx`·텍스트는 본문 텍스트를 추출하고, **텍스트 레이어가 없는 이미지·스캔본 PDF만** 추출되지 않아 파일 경로만(`unsupported`) 돌려주니 AI 클라이언트의 파일 읽기 기능으로 그 경로를 직접 열어 읽으세요.
47
+ - 읽은 내용은 그대로 새 파일로 다시 쓰지 말고, 구조화해 프로필은 `save_profile`, 이력서·경력기술서·포트폴리오는 `add_resume`, 기존 자기소개서는 `save_cover_letter_version`으로 저장하세요.
48
48
  - 응답 폭발을 막기 위해 파일별 본문은 `max_chars`(기본 20000자)로 잘라서 돌려주며, 잘린 경우 `truncated: true`로 표시합니다.
49
49
 
50
50
  ---
@@ -85,6 +85,7 @@ AI 클라이언트가 연결되면 이 도구를 가장 먼저 호출해 상태
85
85
  | --- | --- | --- | --- | --- | --- |
86
86
  | `add_resume` | 이력서·경력기술서·포트폴리오 등 문서 저장 | `title`, `content`(필수), `kind?`, `source?`, `is_primary?`, `tags?` | 저장된 `DocumentRecord` | 사용자가 업로드/붙여넣은 텍스트(또는 정리한 Markdown)를 보관할 때 | ✏️ |
87
87
  | `get_resumes` | 저장된 문서 조회(종류 필터 가능) | `kind?` | `DocumentRecord[]` | 저장된 이력서/문서를 확인할 때 | ✅ |
88
+ | `delete_resume` | 저장된 문서(이력서·경력기술서·포트폴리오) 삭제 | `document_id`, `confirm`(=`DELETE`) | `{ deleted, id }` | 사용자가 특정 문서 삭제를 명확히 요청했을 때(먼저 get_resumes로 확인) | ✏️ |
88
89
 
89
90
  - `kind` 값: `resume`(이력서, 기본값) / `career_description`(경력기술서) / `portfolio` / `other`
90
91
  - `is_primary: true`로 대표 문서를 지정하면 `get_application_context`의 `primary_resume`로 노출됩니다.
@@ -99,11 +100,15 @@ AI 클라이언트가 연결되면 이 도구를 가장 먼저 호출해 상태
99
100
  | --- | --- | --- | --- | --- | --- |
100
101
  | `add_experience` | 경력(직장 단위) 항목 저장 | `experiences[]` — 각 항목: `company`(필수), `role?`, `employment_type?`, `start_date?`, `end_date?`, `is_current?`, `description?`, `achievements?`, `tech?`, `order_index?` | `ExperienceRecord[]` + 신규/갱신 건수 | 이력서에서 경력을 구조화해 보관할 때(여러 건 한 번에) | ✏️ |
101
102
  | `get_experiences` | 저장된 경력을 시간 역순으로 조회 | 없음 | `ExperienceRecord[]` | 경력 목록만 빠르게 확인할 때 | ✅ |
103
+ | `delete_experience` | 경력 항목 1건 삭제 | `experience_id`, `confirm`(=`DELETE`) | `{ deleted, id }` | 잘못 추출/입력된 경력을 지울 때(먼저 get_experiences로 확인) | ✏️ |
102
104
  | `add_project` | 대표 프로젝트 항목 저장 | `projects[]` — 각 항목: `name`(필수), `role?`, `description?`, `highlights?`, `tech?`, `url?`, `start_date?`, `end_date?`, `order_index?` | `ProjectRecord[]` + 신규/갱신 건수 | 프로젝트 이력을 구조화해 보관할 때(여러 건 한 번에) | ✏️ |
103
105
  | `get_projects` | 저장된 프로젝트 조회 | 없음 | `ProjectRecord[]` | 프로젝트 목록만 확인할 때 | ✅ |
106
+ | `delete_project` | 프로젝트 항목 1건 삭제 | `project_id`, `confirm`(=`DELETE`) | `{ deleted, id }` | 잘못 추출/입력된 프로젝트를 지울 때(먼저 get_projects로 확인) | ✏️ |
104
107
  | `add_skill` | 기술스택 항목 저장 | `skills[]` — 각 항목: `name`(필수), `category?`, `level?`, `years?`, `order_index?` | `SkillRecord[]` + 신규/갱신 건수 | 보유 기술을 정리해 둘 때(여러 개 한 번에) | ✏️ |
105
108
  | `get_skills` | 저장된 기술스택 조회 | 없음 | `SkillRecord[]` | 기술 목록만 확인할 때 | ✅ |
109
+ | `delete_skill` | 기술 항목 1건 삭제 | `skill_id`, `confirm`(=`DELETE`) | `{ deleted, id }` | 잘못 추출/입력된 기술을 지울 때(먼저 get_skills로 확인) | ✏️ |
106
110
 
111
+ - `delete_*`는 항목 1건만 지웁니다. **수정**은 별도 도구 없이 `add_*`로 같은 항목(같은 식별자)을 다시 저장하면 갱신됩니다(멱등).
107
112
  - 세 도구 모두 **배열을 받아 여러 건을 한 번에 저장**합니다(한 건이어도 배열로). 항목마다 도구를 반복 호출하지 마세요.
108
113
  - **멱등 저장**: 같은 항목(스킬=`name`, 경력=`company`+`role`+`start_date`, 프로젝트=`name`, 대소문자 무시)을 다시 넣어도 중복 행을 만들지 않고 갱신합니다. 누락한 필드는 기존 값을 보존합니다. 한 번의 호출은 한 트랜잭션으로 원자 처리됩니다.
109
114
  - `achievements`/`highlights`에는 정량 지표가 담긴 성과를, `tech`에는 사용 기술을 배열로 넣으면 적합도 분석·자소서·면접 준비에서 근거로 활용됩니다.
@@ -116,7 +121,7 @@ AI 클라이언트가 연결되면 이 도구를 가장 먼저 호출해 상태
116
121
  | 도구 | 목적 | 주요 입력 | 반환 | 언제 호출 | 읽기전용 |
117
122
  | --- | --- | --- | --- | --- | --- |
118
123
  | `get_cover_letters` | 저장된 자기소개서 조회(공고별 필터 가능). 각 항목은 현재 버전 내용·버전 수 포함 | `job_id?` | `CoverLetterRecord[]` | 자소서 목록/내용을 확인할 때 | ✅ |
119
- | `save_cover_letter_version` | 자기소개서의 새 버전 저장 — 자소서 작성 워크플로우의 핵심 저장 단계 | `content`(필수), `cover_letter_id?`, `title?`, `job_id?`, `note?`, `source?`, `set_current?` | `{ coverLetter, version }` | 새 공고용 자소서를 생성·갱신해 버전으로 남길 때 | ✏️ |
124
+ | `save_cover_letter_version` | 자기소개서의 새 버전 저장 — 자소서 작성 워크플로우의 핵심 저장 단계 | `content`(필수), `cover_letter_id?`, `title?`, `job_id?`, `note?`, `source?`, `set_current?`, `force?`, `strict?` | `{ coverLetter, version }` | 새 공고용 자소서를 생성·갱신해 버전으로 남길 때 | ✏️ |
120
125
  | `delete_cover_letter` | 자기소개서 삭제(모든 버전 포함) | `cover_letter_id`, `confirm:"DELETE"` | 삭제 결과 | 사용자가 목록에서 삭제 대상을 확인한 뒤 | ✏️ |
121
126
 
122
127
  `save_cover_letter_version` 동작(`CoverLetterVersionInputSchema`):
@@ -179,7 +184,7 @@ AI 클라이언트가 연결되면 이 도구를 가장 먼저 호출해 상태
179
184
  | `rejected` | 불합격 |
180
185
  | `on_hold` | 보류 |
181
186
 
182
- > `document_passed`(서류 합격) 이상에서 면접 준비가 해금되며, 상태 변경 응답에 면접 준비 제안 힌트가 함께 돌아옵니다.
187
+ > `document_passed`(서류 합격) 이상에서는 상태 변경 응답에 면접 준비 제안 힌트가 함께 돌아옵니다. 사용자가 요청하면 그 전에도 공고 기준 면접 준비 자료를 저장할 수 있습니다.
183
188
 
184
189
  ---
185
190
 
@@ -187,7 +192,7 @@ AI 클라이언트가 연결되면 이 도구를 가장 먼저 호출해 상태
187
192
 
188
193
  | 도구 | 목적 | 주요 입력 | 반환 | 언제 호출 | 읽기전용 |
189
194
  | --- | --- | --- | --- | --- | --- |
190
- | `save_interview_prep` | 예상 질문·꼬리 질문·STAR 답변 가이드·1분 자기소개 초안 등 면접 준비 자료 저장(같은 공고면 갱신) | `job_id`(필수), `questions?`, `star_guides?`, `self_introduction?`, `notes?` | 저장된 `InterviewPrepRecord`(질문 수 포함) | 보통 서류 합격 후, AI가 생성한 면접 자료를 저장할 때 | ✏️ |
195
+ | `save_interview_prep` | 예상 질문·꼬리 질문·STAR 답변 가이드·1분 자기소개 초안 등 면접 준비 자료 저장(같은 공고면 갱신) | `job_id`(필수), `questions?`, `star_guides?`, `self_introduction?`, `notes?` | 저장된 `InterviewPrepRecord`(질문 수 포함) | 사용자가 공고 기준 면접 준비를 요청했을 때 | ✏️ |
191
196
 
192
197
  입력 구조(`InterviewPrepInputSchema`):
193
198
 
@@ -203,9 +208,11 @@ AI 클라이언트가 연결되면 이 도구를 가장 먼저 호출해 상태
203
208
  | 도구 | 목적 | 주요 입력 | 반환 | 언제 호출 | 읽기전용 |
204
209
  | --- | --- | --- | --- | --- | --- |
205
210
  | `export_cover_letter` | 자기소개서를 Markdown 또는 인쇄용 HTML 파일로 데이터 폴더 `exports/`에 저장 | `cover_letter_id`, `format?`(`md`(기본)/`html`) | `{ path, filename, content }` | 사용자가 "자소서 파일로 받고 싶어"라고 할 때 | ✏️ |
211
+ | `export_resume` | 저장된 이력서·경력기술서 등 문서를 Markdown 또는 인쇄용 HTML 파일로 `exports/`에 저장 | `document_id`, `format?`(`md`(기본)/`html`) | `{ path, filename, content }` | 공고 맞춤 이력서를 `add_resume`로 저장한 뒤 "이력서 파일로 받고 싶어"라고 할 때 | ✏️ |
212
+ | `export_profile` | 프로필·경력·프로젝트·보유 기술을 한 장의 이력서 형식으로 모아 Markdown 또는 인쇄용 HTML 파일로 `exports/`에 저장 | `format?`(`md`(기본)/`html`) | `{ path, filename, content }` | 사용자가 "내 프로필을 이력서로 뽑아줘"라고 할 때 | ✏️ |
206
213
 
207
214
  - HTML은 인쇄용으로, 브라우저에서 PDF로 저장할 수 있습니다.
208
- - 대시보드의 Documents 페이지에서 직접 다운로드할 수도 있습니다.
215
+ - 대시보드의 Documents·Profile 페이지에서 직접 다운로드할 수도 있습니다.
209
216
 
210
217
  ---
211
218
 
@@ -235,7 +242,7 @@ AI 클라이언트가 연결되면 이 도구를 가장 먼저 호출해 상태
235
242
  | --- | --- | --- | --- | --- | --- |
236
243
  | `get_workflow_guide` | 표준 워크플로우의 단계별 안내 + 그 작업의 **전문가 실행 절차(EOP)**·적용할 플레이북·저장 전 검증기 순서 반환 | `workflow_id?` | 단일 워크플로우 Markdown(EOP·플레이북/검증기 순서 포함) 또는 전체 목록(`{ id, title, trigger }[]`) | 커리어 작업을 시작하기 직전 | ✅ |
237
244
 
238
- `workflow_id` 값: `onboarding`, `analyze_job`, `write_cover_letter`, `manage_application_status`, `prepare_interview`. 생략하면 전체 목록을 돌려줍니다. `analyze_job`/`write_cover_letter`/`prepare_interview`/`onboarding`은 해당 작업의 EOP 본문과 `get_playbook`·`get_verifier` 호출 순서(`career_route`)를 함께 돌려줍니다.
245
+ `workflow_id` 값: `onboarding`, `analyze_job`, `write_cover_letter`, `write_career_description`, `manage_application_status`, `prepare_interview`, `build_personal_brand`. 생략하면 전체 목록을 돌려줍니다. `analyze_job`/`write_cover_letter`/`write_career_description`/`prepare_interview`/`onboarding`은 해당 작업의 EOP 본문과 `get_playbook`·`get_verifier` 호출 순서(`career_route`)를 함께 돌려줍니다.
239
246
 
240
247
  ---
241
248
 
@@ -273,7 +280,7 @@ AI 클라이언트가 연결되면 이 도구를 가장 먼저 호출해 상태
273
280
 
274
281
  | 도구 | 목적 | 주요 입력 | 반환 | 언제 호출 | 읽기전용 |
275
282
  | --- | --- | --- | --- | --- | --- |
276
- | `get_writing_style_guide` | "AI 티 안 나는" 한국어 글쓰기 규칙 반환 | 없음 | `{ guide }` (작성 규칙 + 저장 전 자가 점검) | 자기소개서·자기 PR·지원 메일 등 사람이 쓴 듯한 글을 작성하기 직전 | ✅ |
283
+ | `get_writing_style_guide` | "AI 티 안 나는" 한국어 글쓰기 규칙 반환 | `doc_type?`(career_description·resume·portfolio면 구조 보존 보정 추가) | `{ guide }` (작성 규칙 + 저장 전 자가 점검) | 자기소개서·자기 PR·지원 메일·경력기술서 등 사람이 쓴 듯한 글을 작성하기 직전 | ✅ |
277
284
 
278
285
  번역투·클리셰·기계적 병렬·상투적 연결어·균일한 문장 리듬 같은 AI-tell을 제거하면서, 사실·수치·고유명사는 그대로 보존하도록 안내합니다. `write_cover_letter` / `analyze_job` 워크플로우의 작성 단계에서 함께 적용합니다. (규칙 출처: `epoko77-ai/im-not-ai`, MIT.)
279
286
 
@@ -319,9 +326,11 @@ CareerMate를 최신 버전으로 유지하기 위한 유지보수 도구입니
319
326
  | `fit_analysis` | (`job_id` 제공 시) 대상 공고의 이전 적합도 분석(`FitAnalysisRecord` 또는 `null`) |
320
327
  | `related_history` | 같은 회사/직무 관련 이전 기록 배열 — 각 항목 `{ job, application, fit_analysis }` |
321
328
  | `writing_preferences` | 자소서 작성 선호 — `{ preferred_tone, emphasis_points[] }` |
322
- | `recommended_route` | 맥락 기반 추천 워크플로우 id(`analyze_job`/`write_cover_letter`/`prepare_interview`/`onboarding`) 또는 `null`. `get_workflow_guide`의 `workflow_id`로 그대로 사용 |
329
+ | `recommended_route` | 맥락 기반 추천 워크플로우 id(`analyze_job`/`write_cover_letter`/`prepare_interview`/`onboarding`) 또는 `null`. 공고 중심 맥락이 아닌 `write_career_description`은 사용자 요청에 따라 직접 선택한다. `get_workflow_guide`의 `workflow_id`로 그대로 사용 |
323
330
  | `verifier_sequence` | 추천 경로에서 저장 직전 적용할 검증기 id 배열(Career-OS) |
324
331
  | `next_tool` | 다음에 부를 도구(보통 `get_workflow_guide`) 또는 `null` |
332
+ | `today` | 서버의 오늘 날짜(`YYYY-MM-DD`). LLM이 현재일을 신뢰성 있게 모르므로 주입(연차·신선도 판단 기준; MCP 응답 한정) |
333
+ | `tenure` | 재직기간을 서버가 결정적으로 계산한 배열 — 각 `{ company, is_current, start_date, as_of, months, years, data_age_months }`. **재직중=등록일 `updated_at` 기준 연차, 종료=`end_date` 기준.** 연차는 직접 산술하지 말고 이 값을 사용(`data_age_months` 크면 현재 재직 확인 필요). MCP 응답 한정 |
325
334
 
326
335
  **사용 흐름**
327
336
 
@@ -1,6 +1,6 @@
1
1
  # CareerMate 시작 런북 (연결 직후 AI용)
2
2
 
3
- 설치·연결(`INSTALL.md`)이 끝난 직후, AI(당신)가 사용자를 빠르게 생산적으로 만들기 위해 따라가는 런북입니다. 도구는 정해진 순서로 호출하고, 매 단계 무엇을 하고 있는지 쉬운 한국어로 설명하세요. MCP·job_id 같은 기술 용어는 노출하지 마세요. 확실하지 않은 정보는 지어내지 말고 사용자에게 확인하세요.
3
+ 설치·연결(`INSTALL.md`)이 끝난 직후, AI(당신)가 사용자를 빠르게 생산적으로 만들기 위해 따라가는 런북입니다. 도구는 정해진 순서로 호출하고, 매 단계 무엇을 하고 있는지 사용자의 언어로 쉽게 설명하세요. MCP·job_id 같은 기술 용어는 노출하지 마세요. 확실하지 않은 정보는 지어내지 말고 사용자에게 확인하세요.
4
4
 
5
5
  > 핵심 원칙: **분석과 글쓰기는 당신(AI)이 수행하고, CareerMate는 데이터를 제공·보관**합니다. 공고 분석이나 자기소개서 작성 전에는 항상 `get_application_context`를 먼저 호출해 근거 데이터를 가져오세요.
6
6
 
@@ -19,7 +19,7 @@
19
19
 
20
20
  ### 2. 프로필 수집 및 저장 — `save_profile`
21
21
 
22
- - 사용자가 올린 이력서/자기소개서 파일 또는 직접 알려준 내용을 바탕으로 프로필을 구조화합니다.
22
+ - 사용자가 올린 이력서/경력기술서/포트폴리오/자기소개서 파일 또는 직접 알려준 내용을 바탕으로 프로필을 구조화합니다.
23
23
  - 정리 항목: 이름, 연락처, 한 줄 소개(`headline`), 요약(`summary`), 희망 직무(`desired_roles`), 희망 근무 조건(`desired_conditions`).
24
24
  - **글쓰기 선호도**를 함께 물어보세요: 선호 문체(`preferred_tone`, 예: "담백하고 구체적")와 강조 포인트(`emphasis_points`). 이 두 값은 이후 자기소개서 품질에 직접 영향을 줍니다.
25
25
  - `save_profile`로 저장합니다. 전달한 필드만 갱신되고 나머지는 유지됩니다(부분 저장 안전). 한두 개만 바꿀 때도 그대로 `save_profile`을 다시 호출하면 됩니다.
@@ -121,7 +121,7 @@
121
121
 
122
122
  ## 보조 도구
123
123
 
124
- - `get_workflow_guide` — 표준 워크플로우(온보딩, 공고 분석, 자소서 작성, 상태 관리, 면접 준비)의 단계별 안내. 어떤 순서로 어떤 도구를 호출할지 확인할 때 사용. `workflow_id` 생략 시 전체 목록.
124
+ - `get_workflow_guide` — 표준 워크플로우(온보딩, 공고 분석, 자소서 작성, 경력기술서 작성, 상태 관리, 면접 준비, 개인 브랜드)의 단계별 안내. 어떤 순서로 어떤 도구를 호출할지 확인할 때 사용. `workflow_id` 생략 시 전체 목록.
125
125
  - `list_recent_activity` — 최근 활동(공고 저장, 적합도 분석, 자소서 버전, 상태 변경, 면접 준비 등). "최근에 뭐 했지?" 또는 작업을 이어갈 맥락이 필요할 때.
126
126
  - `list_jobs` / `get_job_posting` — 저장된 공고 목록 / 단건 상세(적합도·상태·연결 자소서·면접 준비 포함).
127
127
  - `get_profile` / `get_resumes` / `get_cover_letters` — 저장된 데이터 조회.
@@ -31,6 +31,19 @@ CareerMate는 LLM이 없는 **로컬 MCP 도구**입니다. *내 컴퓨터에서
31
31
  ### 동작하지 않는 것
32
32
  **ChatGPT · Gemini · Claude의 웹·모바일 앱은 안 됩니다.** 클라우드에서 실행되어 **원격 URL 기반 MCP만** 지원하므로, 내 컴퓨터의 로컬 stdio 서버에 직접 닿을 수 없습니다.
33
33
 
34
+ ### 첫 사용 마찰 — 도구 사전허용 (자동)
35
+ `careermate init`은 **연결한 클라이언트에만**(감지된/`--client`로 지정한 것) 커리어 데이터 도구를 미리 허용해, 첫 사용 때 도구마다 뜨는 승인 프롬프트를 없앱니다. **민감/파괴 4개(`read_document`·`update_careermate`·`delete_cover_letter`·`delete_job_posting`)는 어느 클라이언트에서도 자동승인하지 않고 그때그때 확인**을 받습니다. `--no-allow-tools`로 전체를 끌 수 있습니다.
36
+
37
+ | 앱 | 사전허용 방식 | 쓰는 파일 |
38
+ |---|---|---|
39
+ | **Claude Code** | `permissions.allow` + 서버 신뢰(`enabledMcpjsonServers`) | 작업 폴더 `.claude/settings.local.json` |
40
+ | **Codex CLI** | 서버 도구 자동승인(`default_tools_approval_mode = "auto"`) + 민감 4개만 `approval_mode = "prompt"` | `~/.codex/config.toml` |
41
+ | **Cursor (≥3.6)** | `mcpAllowlist`에 SAFE 도구만(`"careermate:<tool>"`) | `~/.cursor/permissions.json` |
42
+ | **Gemini CLI · Antigravity** | (자동 안 함) — 도구별 사전허용이 없고 서버 단위 일괄 신뢰만 있어, 민감 도구까지 자동승인되는 걸 피하려고 **첫 사용 1회 "허용"**만 받습니다 | — |
43
+ | **Claude Desktop "채팅"** | (자동 안 함) — 앱이 세션 UI에서 "항상 허용"으로 기억 | — |
44
+
45
+ > 폴더를 처음 "신뢰"하는 1회 다이얼로그(Claude Code의 폴더 신뢰, Codex의 워크스페이스 신뢰)는 클라이언트가 강제하는 보안 게이트라 사라지지 않습니다 — 한 번만 승인하면 됩니다.
46
+
34
47
  ---
35
48
 
36
49
  ## 구독·준비물 (2026)
package/docs/WORKFLOWS.md CHANGED
@@ -8,23 +8,25 @@ CareerMate는 내부에 LLM을 두지 않는다. 분석과 작성은 사용자
8
8
 
9
9
  - 연결 직후 AI가 따라가는 시작 런북은 [시작 런북](./START_WORKFLOW.md)을 참고한다.
10
10
  - 설치·연결 절차는 [설치 런북](../INSTALL.md)(또는 [지원 앱·설치 레퍼런스](./SUPPORTED_AI_APPS.md))을 참고한다.
11
- - MCP 도구 37종의 입출력 명세는 코드(`packages/mcp-tools/src/tools.ts`)에 정의되어 있으며, AI는 각 도구의 `inputSchema`로 직접 확인할 수 있다.
11
+ - MCP 도구의 입출력 명세는 코드(`packages/mcp-tools/src/tools.ts`)에 정의되어 있으며, AI는 각 도구의 `inputSchema`로 직접 확인할 수 있다.
12
12
 
13
- ## 워크플로우 5종 개요
13
+ ## 워크플로우 7종 개요 (핵심 6 + build_personal_brand)
14
14
 
15
15
  | id | 제목 | 핵심 목적 |
16
16
  | --- | --- | --- |
17
17
  | `onboarding` | 온보딩 (첫 셋업) | 프로필·이력서·자기소개서를 등록하고 대시보드를 연다. |
18
18
  | `analyze_job` | 공고 분석 (적합도 분석) | 공고를 읽어 프로필과 비교하고, 공고·적합도 분석을 저장한 뒤 자기소개서 작성을 제안한다. |
19
19
  | `write_cover_letter` | 자기소개서 작성 | 특정 공고에 맞춘 자기소개서를 사용자 확인을 거쳐 작성·버전 저장한다. |
20
+ | `write_career_description` | 경력기술서 작성 | 프로필·이력서·경력·프로젝트·스킬을 근거로 실제 제출 가능한 경력기술서를 작성·저장한다. |
20
21
  | `manage_application_status` | 지원 상태 관리 | 지원 진행 상황(8단계)을 업데이트하고 다음 행동을 제안한다. |
21
- | `prepare_interview` | 면접 준비 | 서류 합격 이후 예상 질문·STAR 답변·1분 자기소개를 준비·저장한다. |
22
+ | `prepare_interview` | 면접 준비 | 공고 기준 예상 질문·STAR 답변·1분 자기소개를 준비·저장한다. |
23
+ | `build_personal_brand` | 퍼스널 브랜드 (LinkedIn·포트폴리오) | LinkedIn 프로필·포트폴리오 같은 자기표현 자산을 직무에 맞춰 작성·최적화한다(이력서 임포트와 분리된 선택 작업). |
22
24
 
23
25
  ## 공통 원칙
24
26
 
25
27
  - **추측 금지**: 저장된 실제 경험·성과만 사용한다. 없는 경험을 지어내지 않으며, 빈칸이나 확인이 필요한 부분은 표시해 사용자에게 묻는다.
26
28
  - **사용자 확인 우선**: 큰 작업(자기소개서 작성 등)을 진행하기 전에 대상·강조점·톤·분량을 확인한다.
27
- - **쉬운 한국어 전달**: 분석·결과를 사용자에게 설명할 때는 기술 용어를 빼고 쉬운 한국어로 전달한다.
29
+ - **쉬운 전달(사용자 언어)**: 분석·결과를 사용자에게 설명할 때는 기술 용어를 빼고 사용자의 언어로 쉽게 전달한다.
28
30
  - **로컬 전용**: 모든 데이터는 로컬에만 저장된다.
29
31
 
30
32
  ---
@@ -38,7 +40,7 @@ CareerMate는 내부에 LLM을 두지 않는다. 분석과 작성은 사용자
38
40
  **단계:**
39
41
 
40
42
  1. `get_onboarding_status`를 호출해 현재 등록 상태(`has_profile`, `has_resume`, `has_cover_letter`, `has_experience`, `has_skills`, `profile_completeness`, `next_steps`)를 확인한다.
41
- 2. 비어 있는 항목을 사용자에게 쉬운 한국어로 안내하고, 이력서/자기소개서 파일 업로드 또는 정보 입력을 요청한다.
43
+ 2. 비어 있는 항목을 사용자의 언어로 쉽게 안내하고, 이력서/경력기술서/포트폴리오/자기소개서 파일 업로드 또는 정보 입력을 요청한다.
42
44
  3. 수집한 정보를 구조화해 `save_profile`로 저장한다(이름·연락처·`headline`·`summary`·`desired_roles`·`desired_conditions`, 그리고 글쓰기 선호인 `preferred_tone`과 `emphasis_points` 포함). 파일 출처는 `source=upload`, 직접 입력은 `manual`.
43
45
  4. 업로드한 이력서/경력기술서/포트폴리오 본문을 `add_resume`로 저장한다(`kind`·`title` 지정, 대표 문서는 `is_primary=true`).
44
46
  5. 경력·프로젝트·스킬이 파악되면 `add_experience`·`add_project`·`add_skill`로 저장한다 — 각 도구는 배열을 받으므로 파악한 항목을 한 번에 모아 넘긴다(항목마다 반복 호출하지 않는다). 같은 항목을 다시 넣어도 중복 없이 갱신된다(완성도의 `has_experience`/`has_skills`에 반영).
@@ -73,9 +75,9 @@ get_onboarding_status
73
75
  3. **비교/분석** — 공고 요구사항과 사용자 경력/스킬/프로젝트를 비교한다. 일치하는 강점(`strengths`)과 부족한 부분(`gaps`), 매칭 키워드(`matched_keywords`)와 누락 키워드(`missing_keywords`)를 도출하고, 종합 적합도 점수(`score` 0~100)와 요약(`summary`), 지원 전략 제안(`recommendations`)을 정리한다. **없는 경험을 지어내지 않는다.**
74
76
  4. **공고 저장** — 아직 저장되지 않은 공고라면 `save_job_posting`으로 공고를 저장하고 `job_id`를 확보한다.
75
77
  5. **분석 저장** — 도출한 분석 결과를 `save_fit_analysis`로 저장한다(`job_id`, `score`, `summary`, `strengths`, `gaps`, `matched_keywords`, `missing_keywords`, `recommendations`).
76
- 6. **사용자 설명** — 분석 결과를 사용자에게 쉬운 한국어로 설명한다(잘 맞는 점, 보완할 점, 추천 전략). 기술 용어는 빼고 전달한다.
78
+ 6. **사용자 설명** — 분석 결과를 사용자의 언어로 쉽게 설명한다(잘 맞는 점, 보완할 점, 추천 전략). 기술 용어는 빼고 전달한다.
77
79
  7. **자소서 선택 제안** — 분석 뒤 곧장 자기소개서를 쓰지 말고 "이 공고에 맞춘 자기소개서를 써드릴까요?"라고 묻고 선택지를 제시한다: ① "네, 이 공고에 맞춘 자기소개서를 써줘" ② "아니요, 분석만 저장해줘".
78
- 8. **동의 시 자소서 저장** — 사용자가 ①을 선택하면 적합도 분석과 글쓰기 선호를 반영해 자기소개서를 작성하고 `save_cover_letter_version`으로 저장한다(`job_id` 연결, `note`에 작성 의도 요약). ②를 선택하면 자소서 작성 없이 멈추고 저장 결과와 대시보드 확인만 안내한다.
80
+ 8. **동의 시 자소서 저장** — 사용자가 ①을 선택하면 자기소개서를 작성하기 직전 `get_writing_style_guide`로 "AI 티 안 나는 글쓰기 규칙"을 가져와, 적합도 분석·글쓰기 선호와 함께 반영해 자기소개서를 작성하고 `save_cover_letter_version`으로 저장한다(`job_id` 연결, `note`에 작성 의도 요약). ②를 선택하면 자소서 작성 없이 멈추고 저장 결과와 대시보드 확인만 안내한다.
79
81
  9. **지원 건 열기** — `open_application`으로 해당 지원 건을 열어 사용자가 결과를 확인하게 하고, 지원 상태 변경(예: 지원 예정/지원 완료)을 제안한다.
80
82
 
81
83
  **도구 호출 순서 요약(정식 흐름):**
@@ -86,7 +88,7 @@ get_onboarding_status
86
88
  → (비교/분석: strengths·gaps·키워드·score·summary·recommendations)
87
89
  → save_job_posting # 미저장 공고일 때만, job_id 확보
88
90
  → save_fit_analysis # job_id 연결
89
- → (사용자에게 쉬운 한국어로 설명)
91
+ → (사용자의 언어로 쉽게 설명)
90
92
  → (자기소개서 작성 여부 선택지 제안)
91
93
  → save_cover_letter_version # 사용자가 "네"를 선택한 경우에만, job_id·note
92
94
  → open_application # 결과 확인 + 상태 변경 제안
@@ -106,16 +108,18 @@ get_onboarding_status
106
108
 
107
109
  1. `get_application_context`(가능하면 `job_id` 포함)를 호출해 프로필·경력·프로젝트·스킬·기존 자기소개서·이전 적합도 분석·글쓰기 선호(`preferred_tone`, `emphasis_points`)를 가져온다.
108
110
  2. 작성 전에 대상 공고, 강조할 포인트, 톤, 분량을 사용자에게 확인한다(확인 없이 큰 작업을 진행하지 않는다).
109
- 3. 저장된 실제 경험·성과만으로 자기소개서를 작성한다. 빈칸이나 확인이 필요한 부분은 추측하지 말고 표시해 사용자에게 묻는다.
110
- 4. 완성본을 `save_cover_letter_version`으로 저장한다(기존 자기소개서면 `cover_letter_id`, 새로 만들면 `title`, 공고용이면 `job_id`, 변경 요약은 `note`, `source=ai`).
111
- 5. 사용자가 원하면 `export_cover_letter`로 파일로 내보내고, 추가 수정 요청이 있으면 새 버전으로 다시 저장한다.
112
- 6. 저장 결과를 쉬운 한국어로 알리고, 지원 상태 업데이트(`update_application_status`)나 면접 준비 등 다음 단계를 제안한다.
111
+ 3. `get_writing_style_guide`를 호출해 "AI 티 안 나는 글쓰기 규칙"(번역투·클리셰·기계적 병렬·상투적 연결어·균일한 문장 리듬 제거)을 가져온다.
112
+ 4. 저장된 실제 경험·성과만으로 자기소개서를 작성하되, 위 글쓰기 규칙을 적용해 사람이 쓴 듯 자연스럽게 쓴다(사실·수치·고유명사는 그대로). 빈칸이나 확인이 필요한 부분은 추측하지 말고 표시해 사용자에게 묻는다.
113
+ 5. 완성본을 `save_cover_letter_version`으로 저장한다(기존 자기소개서면 `cover_letter_id`, 새로 만들면 `title`, 공고용이면 `job_id`, 변경 요약은 `note`, `source=ai`).
114
+ 6. 사용자가 원하면 `export_cover_letter`로 파일로 내보내고, 추가 수정 요청이 있으면 새 버전으로 다시 저장한다.
115
+ 7. 저장 결과를 사용자의 언어로 알리고, 지원 상태 업데이트(`update_application_status`)나 면접 준비 등 다음 단계를 제안한다.
113
116
 
114
117
  **도구 호출 순서 요약:**
115
118
 
116
119
  ```
117
120
  get_application_context # job_id 있으면 함께 전달
118
121
  → (대상·강조점·톤·분량 확인)
122
+ → get_writing_style_guide # 작성 직전, AI 티 안 나는 글쓰기 규칙
119
123
  → save_cover_letter_version # cover_letter_id 또는 title, job_id, note, source=ai
120
124
  → export_cover_letter (선택)
121
125
  → (다음 단계 제안: update_application_status 등)
@@ -123,7 +127,41 @@ get_application_context # job_id 있으면 함께 전달
123
127
 
124
128
  ---
125
129
 
126
- ## 4. manage_application_status — 지원 상태 관리
130
+ ## 4. write_career_description — 경력기술서 작성
131
+
132
+ 프로필·이력서·경력·프로젝트·스킬을 근거로 실제 제출 가능한 경력기술서를 작성하고 문서함에 저장하는 흐름.
133
+
134
+ **트리거:** 사용자가 "경력기술서 써줘 / 경력기술서 만들어줘 / 내 경력 정리해줘"라고 요청할 때.
135
+
136
+ **단계:**
137
+
138
+ 1. `get_onboarding_status`로 준비 상태를 확인하고, `get_profile`·`get_resumes`·`get_experiences`·`get_projects`·`get_skills`를 호출해 기존 프로필, 이력서, 경력기술서(`kind=career_description`), 경력, 프로젝트, 기술스택을 모두 확인한다.
139
+ 2. 사용자가 파일 경로를 주면 `read_document`로 읽고, 인입 폴더를 사용했다면 `read_inbox`로 본문을 읽는다. 이미 저장된 자료와 새 파일을 비교해 중복·상충되는 사실은 표시하고 추측하지 않는다.
140
+ 3. `get_workflow_guide({ workflow_id: "write_career_description" })`가 안내하는 전문가 절차를 따른다. 작성 직전 `get_playbook({ domain: "resume" })`와 `get_playbook({ domain: "ats" })`를 받아 실제 경력기술서 형식과 ATS 친화성을 적용한다.
141
+ 4. 작성 전에 목적을 확인한다: 범용 마스터본인지, 특정 직무/공고용인지, 신입/무경력이라 프로젝트·교육·활동 중심 역량기술서로 쓸지, 분량과 톤은 어떻게 할지 묻는다.
142
+ 5. 경력기술서는 자기소개서처럼 서사로 쓰지 않는다. 제목, 핵심 요약, 핵심 역량, 경력/프로젝트별 역할·기간·도구·문제·행동·성과를 표나 불릿 중심으로 정리한다. 수치·회사명·기간·직책은 저장된 사실만 쓰고, 없는 성과 수치는 만들지 않는다.
143
+ 6. 무경력/비개발자라면 경력을 날조하지 말고 교육·프로젝트·운영 경험·업무 도구·협업 경험·성과 증거 중심의 "역량기술서"로 구성한다.
144
+ 7. 저장 직전 `get_verifier({ id: "truthfulness" })`, `get_verifier({ id: "consistency" })`, `get_verifier({ id: "ats-compat" })`를 받아 AI가 직접 점검하고, 허위·상충·키워드 누락을 고친다.
145
+ 8. 완성본을 `add_resume`으로 저장한다(`kind=career_description`, `source=ai`, title은 사용 목적이 드러나게 작성, tags에 직무/용도 키워드 포함). 대표 문서로 삼아도 되는지 확인된 경우에만 `is_primary=true`를 쓴다.
146
+ 9. 저장 결과를 사용자의 언어로 알리고, 문서 탭에서 확인할 수 있음을 안내한다. 특정 공고용으로 작성했다면 이어서 자기소개서나 면접 준비를 제안한다.
147
+
148
+ **도구 호출 순서 요약:**
149
+
150
+ ```
151
+ get_onboarding_status
152
+ → get_profile / get_resumes / get_experiences / get_projects / get_skills
153
+ → read_document | read_inbox (사용자가 파일을 준 경우)
154
+ → get_workflow_guide({ workflow_id: "write_career_description" })
155
+ → get_playbook({ domain: "resume" }) / get_playbook({ domain: "ats" })
156
+ → (목적·대상 직무·분량 확인)
157
+ → (경력기술서 작성: 요약·역량·경력/프로젝트·성과)
158
+ → get_verifier({ id: "truthfulness" }) / get_verifier({ id: "consistency" }) / get_verifier({ id: "ats-compat" })
159
+ → add_resume(kind=career_description, source=ai)
160
+ ```
161
+
162
+ ---
163
+
164
+ ## 5. manage_application_status — 지원 상태 관리
127
165
 
128
166
  지원 진행 상황(8단계)을 업데이트하고 상태에 맞는 다음 행동을 제안하는 흐름.
129
167
 
@@ -133,7 +171,7 @@ get_application_context # job_id 있으면 함께 전달
133
171
 
134
172
  1. 필요하면 `get_application_context` 또는 `get_job_posting`으로 대상 지원 건과 공고를 확인한다.
135
173
  2. 적절한 상태로 `update_application_status`를 호출한다. 8단계: `draft`(작성 중), `planned`(지원 예정), `applied`(지원 완료), `document_passed`(서류 합격), `interview`(면접 진행), `final_passed`(최종 합격), `rejected`(불합격), `on_hold`(보류). 변경 사유는 `note`에 남긴다.
136
- 3. 변경 결과를 사용자에게 쉬운 한국어로 알린다.
174
+ 3. 변경 결과를 사용자의 언어로 쉽게 알린다.
137
175
  4. 상태에 맞는 다음 단계를 제안한다:
138
176
  - `applied` → 결과 기다리기 안내
139
177
  - `document_passed` / `interview` → 면접 준비(`prepare_interview`) 제안
@@ -141,7 +179,7 @@ get_application_context # job_id 있으면 함께 전달
141
179
  - `rejected` / `on_hold` → 회고 또는 다른 공고 탐색 제안
142
180
  5. 필요하면 `open_application`으로 해당 지원 건을 열어 보여준다.
143
181
 
144
- **상태 전이 참고:** `document_passed` 이상에서 면접 준비가 해금된다. 8단계 상태값은 코드(`update_application_status`의 `inputSchema`)에 정의되어 있다.
182
+ **상태 전이 참고:** `document_passed` 이상에서는 면접 준비를 다음 행동으로 우선 제안한다. 8단계 상태값은 코드(`update_application_status`의 `inputSchema`)에 정의되어 있다.
145
183
 
146
184
  **도구 호출 순서 요약:**
147
185
 
@@ -154,11 +192,11 @@ get_application_context | get_job_posting (필요 시)
154
192
 
155
193
  ---
156
194
 
157
- ## 5. prepare_interview — 면접 준비
195
+ ## 6. prepare_interview — 면접 준비
158
196
 
159
- 서류 합격 이후 예상 질문·STAR 답변·1분 자기소개를 준비해 저장하는 흐름.
197
+ 공고 기준 예상 질문·STAR 답변·1분 자기소개를 준비해 저장하는 흐름.
160
198
 
161
- **트리거:** 지원 상태가 서류 합격(`document_passed`) 또는 면접 진행(`interview`)으로 바뀌었을 때, 또는 사용자가 "면접 준비 도와줘"라고 요청할 때.
199
+ **트리거:** 사용자가 "면접 준비 도와줘"라고 요청하거나, 지원 상태가 서류 합격(`document_passed`) 또는 면접 진행(`interview`)으로 바뀌었을 때.
162
200
 
163
201
  **단계:**
164
202
 
@@ -166,7 +204,7 @@ get_application_context | get_job_posting (필요 시)
166
204
  2. 공고와 사용자 경험을 바탕으로 예상 면접 질문(`question`, `intent`, `followups`, `answer_outline`)을 도출한다.
167
205
  3. 핵심 경험에 대한 STAR 가이드(`question`, `situation`, `task`, `action`, `result`)와 1분 자기소개(`self_introduction`) 초안을 작성한다. **실제 경험만 사용한다.**
168
206
  4. 준비 내용을 `save_interview_prep`로 저장한다(`job_id`, `questions`, `star_guides`, `self_introduction`, `notes`).
169
- 5. 준비 내용을 사용자에게 쉬운 한국어로 요약해 전달하고, 모의 면접/추가 질문 연습이나 상태 업데이트(`update_application_status`로 `interview`/`final_passed`)를 제안한다.
207
+ 5. 준비 내용을 사용자의 언어로 쉽게 요약해 전달하고, 모의 면접/추가 질문 연습이나 상태 업데이트(`update_application_status`로 `interview`/`final_passed`)를 제안한다.
170
208
 
171
209
  **도구 호출 순서 요약:**
172
210
 
@@ -180,20 +218,39 @@ get_application_context # job_id 포함
180
218
 
181
219
  ---
182
220
 
221
+ ## 7. build_personal_brand — 퍼스널 브랜드 (LinkedIn·포트폴리오)
222
+
223
+ LinkedIn 프로필과 포트폴리오 같은 자기표현 자산을 직무에 맞춰 작성·최적화하는 흐름. 이력서 임포트(`onboarding`)와 단계 의미가 달라(개인 브랜드 자산 *생성*) 별도 워크플로우로 둔다.
224
+
225
+ **트리거:** 사용자가 "링크드인 프로필 봐줘 / 포트폴리오 정리해줘 / 퍼스널 브랜딩 도와줘"라고 요청할 때.
226
+
227
+ **단계:**
228
+
229
+ 1. `get_application_context`(가능하면 대상 `job_id` 포함)로 프로필·경력·프로젝트·스킬·대표 이력서·글쓰기 선호를 가져온다. 타깃 공고가 있으면 그 키워드를 사전 입력으로 쓴다.
230
+ 2. `get_workflow_guide({ workflow_id: "build_personal_brand" })`로 전문가 절차를 받고, 작성 직전 `get_playbook({ domain: "linkedin-profile" })`·`get_playbook({ domain: "portfolio" })`로 헤드라인·About·3막(problem→approach→impact) 규범을 적용한다.
231
+ 3. 무엇을 만들지 확인한다(LinkedIn/포트폴리오/둘 다, 타깃 직무, 강조 포인트). 저장된 실제 경험·성과만 쓰고 없는 수치·고유명사는 `[확인 필요]`로 표시해 묻는다.
232
+ 4. 저장 직전 `get_verifier({ id: "human-voice" })`·`truthfulness`·`consistency`로 직접 점검한다(AI 티·환각·사실 보존).
233
+ 5. 포트폴리오 본문은 `add_resume`(`kind=portfolio`)로 저장한다. LinkedIn 초안은 사용자가 복사해 쓰도록 제시한다(전용 저장·검증 도구는 Phase B).
234
+
235
+ ---
236
+
183
237
  ## 워크플로우 간 연결
184
238
 
185
239
  워크플로우는 독립적이지 않고 자연스럽게 이어진다.
186
240
 
187
241
  ```
188
242
  onboarding
243
+ → write_career_description
189
244
  → analyze_job ──(자소서 제안 동의)──→ write_cover_letter
190
245
  │
191
- └─→ manage_application_status ──(document_passed 이상)──→ prepare_interview
246
+ └─→ manage_application_status ──(document_passed 이상이면 우선 제안)──→ prepare_interview
192
247
  ```
193
248
 
249
+ - `write_career_description`은 공고와 무관한 마스터본으로도 시작할 수 있고, 특정 공고용으로 작성한 뒤 `write_cover_letter`로 이어질 수도 있다.
194
250
  - `analyze_job`의 마지막 단계는 자기소개서 작성 제안으로 이어지며, 동의 시 `write_cover_letter`의 작업(=`save_cover_letter_version`)을 수행한다.
195
251
  - `manage_application_status`에서 상태가 `document_passed`/`interview`가 되면 `prepare_interview`를 제안한다.
196
252
  - 모든 흐름에서 데이터 조회의 중심은 `get_application_context`이며, 작성/분석에 필요한 컨텍스트를 한 번에 제공한다.
253
+ - `build_personal_brand`(LinkedIn·포트폴리오)는 핵심 6 흐름과 독립적인 선택 작업으로, 사용자가 자기표현 자산을 요청할 때 진입한다.
197
254
 
198
255
  ## 코드와의 대응
199
256
 
@@ -32,6 +32,7 @@ EOP·이 문서를 맹신하지 말 것. **저장된 사용자 데이터나 공
32
32
  | "이 공고 적합도/나랑 맞아?/지원할 만해?" | [fit-analysis](eop/fit-analysis.md) | job-analysis, profile-extraction |
33
33
  | "이 공고 분석/뜯어줘", "무슨 회사·직무·레벨이야" | [job-analysis](eop/job-analysis.md) | — |
34
34
  | "이력서/경력 정리·입력", "기본정보 채워" | [profile-extraction](eop/profile-extraction.md) | — |
35
+ | "경력기술서/경력서술서/career description 써줘·정리해줘" | [career-description](eop/career-description.md) | profile-extraction, ats |
35
36
  | "자소서/자기소개서/지원동기/커버레터 써줘·고쳐줘" | [cover-letter](eop/cover-letter.md) | company-research, human-writing, fit-analysis |
36
37
  | "면접 준비/예상질문/모의면접" | [interview-prep](eop/interview-prep.md) | company-research, fit-analysis |
37
38
  | résumé·ATS·linkedin·portfolio·salary·offer·rejection·onboarding | `knowledge/` 플레이북 | — |
@@ -46,9 +47,14 @@ EOP·이 문서를 맹신하지 말 것. **저장된 사용자 데이터나 공
46
47
  → EOP 자가검증 루브릭 적용 → 수정 → 출력 계약대로 최종 제공
47
48
  ```
48
49
  컨텍스트가 이미 있으면 다시 묻지 않는다(AGENTS.md "기존 데이터 먼저"). 결과는 다시 CareerMate에 저장(`save_*`).
49
- **루프 종료 규율:** 자가검증→수정을 반복하되, 같은 핵심 결함(허위 수치·미앵커 사실 등)이 2번 고쳐도 남으면 더 생성하지 말고 그 부분을 보류한 채 사용자에게 쉬운 한국어로 출처/사실을 확인 요청한다. 저장 데이터에 없어 해결 불가한 갭은 즉시 사용자에게 묻는다 — **무한정 고쳐쓰지 않는다.**
50
+ **루프 종료 규율:** 자가검증→수정을 반복하되, 같은 핵심 결함(허위 수치·미앵커 사실 등)이 2번 고쳐도 남으면 더 생성하지 말고 그 부분을 보류한 채 사용자의 언어로 출처/사실을 확인 요청한다. 저장 데이터에 없어 해결 불가한 갭은 즉시 사용자에게 묻는다 — **무한정 고쳐쓰지 않는다.**
50
51
 
51
52
  ## 3. 보편 출력 계약 (사용자 대면)
53
+
54
+ **출력 언어 = 사용자의 대화 언어.** 사용자가 한국어면 한국어로, 다른 언어면 그 언어로 답한다. 이 문서·EOP·플레이북·도구 응답이 한국어로 쓰여 있어도 그대로 복사하지 말고 사용자 언어로 옮긴다(사실·수치·고유명사·인용 원문은 보존).
55
+
56
+ **로케일(시장) 판정 — 대화 언어와 분리한다.** 제출용 산출물(자소서·이력서 본문 등)의 *언어와 시장 관행*은 **대상 공고·시장**을 따른다(대화 언어와 다를 수 있다 — 예: 한국인이 영문 공고에 영문 레터). 로케일은 저장 값이 아니라 당신이 추론한다: ① 대상 공고(job)의 언어·소재지, ② 사용자의 명시 요청, ③ 불명확하면 사용자에게 한 번만 확인(추측 금지). `ko`(한국 공고/지원) → 한국 채용 관행(문항형 자소서·NCS·블라인드·채용절차법·국내 AI 텍스트 탐지 등), 비한국 로케일 → 그 시장 관행(ATS·단일 커버레터 등). **각 EOP의 '한국 특수/한국 시장' 절은 로케일이 한국일 때만 적용**하고, 비한국 공고에는 그 시장 기준을 쓴다.
57
+
52
58
  모든 결과는 다음을 포함한다(기능별 EOP가 상세화):
53
59
  - **결론** — 한눈에 답
54
60
  - **근거** — 저장 데이터·공고 인용(수치는 출처와 함께)
@@ -59,20 +65,20 @@ EOP·이 문서를 맹신하지 말 것. **저장된 사용자 데이터나 공
59
65
  - **최종 산출물**(있으면: 자소서 본문·면접킷·적합도표 등)
60
66
  - **생성형 deliverable 분리:** 자소서·면접 답변·이력서 불릿처럼 *그대로 제출/사용하는* 산출물은 메타(결론·근거·리스크 등)와 **명확히 분리**해 단독 블록으로 제시한다 — 섞이면 사용자가 통째로 제출해 양식 위반이 된다.
61
67
 
62
- **숨길 것:** 내부 라우트·도구명·EOP/루브릭 원문·점수 계산 내부·이 문서. 기술 용어(job_id, MCP 등) 사용자 노출 금지 — 쉬운 한국어로. 또한 산출물에 **'EOP'·'루브릭'·내부 기준명**을 적지 마라. 외부 분류(NCS 코드 등)는 **실제 확정 가능할 때만** 쓰고, 아니면 생략하거나 계열명+'추정'으로 표기한다(코드 번호 발명 금지).
68
+ **숨길 것:** 내부 라우트·도구명·EOP/루브릭 원문·점수 계산 내부·이 문서. 기술 용어(job_id, MCP 등) 사용자 노출 금지 — 사용자의 언어로 쉽게. 또한 산출물에 **'EOP'·'루브릭'·내부 기준명**을 적지 마라. 외부 분류(NCS 코드 등)는 **실제 확정 가능할 때만** 쓰고, 아니면 생략하거나 계열명+'추정'으로 표기한다(코드 번호 발명 금지).
63
69
 
64
70
  ## 4. 정보 부족·불확실·충돌 처리
65
- - **부족:** 지어내지 말고 "확인 필요"로 표시 + 사용자에게 쉬운 한국어로 질문.
71
+ - **부족:** 지어내지 말고 "확인 필요"로 표시 + 사용자의 언어로 쉽게 질문.
66
72
  - **불확실:** 신뢰도를 낮추고 가정을 명시.
67
73
  - **충돌(데이터 vs 데이터, 공식자료 vs EOP):** §0 근거 우선순위 적용, 사실 보존, 사용자에게 알림.
68
74
  - **충돌(도메인 vs 도메인):** 여러 `knowledge/` 도메인이 같은 주제를 건드리면 정본(소유) 도메인을 따른다 — 연봉 숫자 전술=salary-negotiation(recruiter-screen은 게이트 맥락의 조건부 규칙만 상속), 오퍼 비교·가중치=offer-evaluation-decision, 30-60-90=onboarding-first-90-days, 탈락 진단=rejection-triage-iteration, 슬롭/키워드/정량 사전=공유 모듈. 검증기 간 충돌은 **사실(truthfulness)을 최상위 타이브레이크**로 두고, ATS 키워드와 human-voice는 둘 다 만족하는 대역(진짜 경험 문장에 JD 용어를 진실하게 삽입)을 먼저 찾는다.
69
75
 
70
- ## 5. EOP 목록
71
- [fit-analysis](eop/fit-analysis.md) · [job-analysis](eop/job-analysis.md) · [profile-extraction](eop/profile-extraction.md) · [cover-letter](eop/cover-letter.md) · [interview-prep](eop/interview-prep.md)
76
+ ## 5. EOP 목록 (6종)
77
+ [fit-analysis](eop/fit-analysis.md) · [job-analysis](eop/job-analysis.md) · [profile-extraction](eop/profile-extraction.md) · [cover-letter](eop/cover-letter.md) · [career-description](eop/career-description.md) · [interview-prep](eop/interview-prep.md)
72
78
 
73
79
  각 EOP 구조 = 전문가 프레임 · 입력 수집 · 분석 절차 · 한국/영문 특수 · 출력 계약 · 자가검증 루브릭 · 근거.
74
80
 
75
81
  ## 6. 디렉터리·기존 문서와의 관계 (무엇을 버리지 않는가)
76
82
  - **`knowledge/` (Phase A — 16 도메인 플레이북 + 6 verifiers)** = **정본 deep 지식**(대학 커리어센터·NCS·ATS 등 출처 충실). **버리지 않는다.** 각 EOP는 이 플레이북을 *실행 절차로 압축*하고 상단 "지식 출처"로 가리킨다 — EOP=얇은 실행층, knowledge=깊은 지식층. 함께 적용한다.
77
83
  - **`validation/`** = 새 리서치 4편(`research/`, knowledge **보강**: 검증 출처+한국 시장+리뷰어 루브릭) + 다중 LLM(cross-vendor) 교차검증 하니스(`runs/`, `PROTOCOL.md`, `MANDATE.md`). 런타임 소비 경로는 아님.
78
- - **`implementation/`** = CareerMate **개발자용** Phase B 내부 설계(`ARCHITECTURE.md`·`CONTRACT.md`·`EXPERTS.md`·`VERIFIERS.md`·`LOOP_ENGINE.md`·`EVALUATION.md`·`CONSENSUS_ENGINE.md`·`TODO.md`·`KNOWLEDGE.md`·`CONSUMPTION.md` + `phase-b2/`). MCP 도구·DB·det 엔진 등 빌드 스펙 — **외부 LLM 소비에는 불필요**(소비 진입점은 이 README + `eop/` + `knowledge/`).
84
+ - **`implementation/`** = CareerMate **개발자용** Phase B 내부 설계(`ARCHITECTURE.md`·`CONTRACT.md`·`EXPERTS.md`·`VERIFIERS.md`·`LOOP_ENGINE.md`·`EVALUATION.md`·`CONSENSUS_ENGINE.md`·`TODO.md`·`KNOWLEDGE.md`·`CONSUMPTION.md` + `phase-b2/`). MCP 도구·DB·det 엔진 등 빌드 스펙 — **외부 LLM 소비에는 불필요**(소비 진입점은 이 README + `eop/`(6 EOP) + `knowledge/`).