careermate 0.1.0 → 0.1.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +22 -17
- package/THIRD_PARTY_NOTICES.md +15 -0
- package/apps/mcp/src/index.ts +4 -3
- package/apps/web/DESIGN_GUIDE.md +2 -2
- package/apps/web/demo/demo-shim.js +536 -0
- package/apps/web/demo/demo.css +75 -0
- package/apps/web/demo/seed.js +269 -0
- package/apps/web/public/app.js +34 -2
- package/apps/web/public/icon-180.png +0 -0
- package/apps/web/public/index.html +14 -3
- package/apps/web/public/lib.js +135 -23
- package/apps/web/public/pages/applications.js +18 -9
- package/apps/web/public/pages/documents.js +66 -50
- package/apps/web/public/pages/home.js +12 -11
- package/apps/web/public/pages/interview.js +9 -12
- package/apps/web/public/pages/jobs.js +39 -36
- package/apps/web/public/pages/profile.js +66 -86
- package/apps/web/public/pages/settings.js +21 -14
- package/apps/web/public/styles.css +105 -38
- package/apps/web/src/http.ts +31 -4
- package/apps/web/src/info.ts +9 -22
- package/apps/web/src/routes.ts +19 -14
- package/apps/web/src/server.ts +34 -29
- package/apps/web/src/settings.ts +35 -17
- package/bin/careermate.mjs +8 -5
- package/dist/doctor.mjs +78908 -0
- package/dist/install-page/.omc/state/agent-replay-55a58c0d-bb6e-43ea-8a05-4b6c93b80b34.jsonl +12 -0
- package/dist/install-page/.omc/state/idle-notif-cooldown.json +3 -0
- package/dist/install-page/.omc/state/sessions/55a58c0d-bb6e-43ea-8a05-4b6c93b80b34/mission-state.json +147 -0
- package/dist/install-page/.omc/state/sessions/55a58c0d-bb6e-43ea-8a05-4b6c93b80b34/pre-tool-advisory-throttle.json +22 -0
- package/dist/install-page/.omc/state/sessions/55a58c0d-bb6e-43ea-8a05-4b6c93b80b34/subagent-tracking-state.json +44 -0
- package/dist/install-page/favicon.svg +1 -0
- package/dist/install-page/icon-180.png +0 -0
- package/dist/install-page/icon-512.png +0 -0
- package/dist/install-page/index.html +328 -225
- package/dist/install-page/landing.js +54 -0
- package/dist/install-page/llms-install.txt +202 -0
- package/dist/install-page/og.png +0 -0
- package/dist/install-page/shots/applications-dark.png +0 -0
- package/dist/install-page/shots/applications-light.png +0 -0
- package/dist/install-page/shots/documents-dark.png +0 -0
- package/dist/install-page/shots/documents-light.png +0 -0
- package/dist/install-page/shots/home-dark.png +0 -0
- package/dist/install-page/shots/home-light.png +0 -0
- package/dist/install-page/shots/interview-dark.png +0 -0
- package/dist/install-page/shots/interview-light.png +0 -0
- package/dist/install-page/shots/jobs-dark.png +0 -0
- package/dist/install-page/shots/jobs-light.png +0 -0
- package/dist/install-page/shots/settings-dark.png +0 -0
- package/dist/install-page/shots/settings-light.png +0 -0
- package/dist/install-page/start.html +323 -0
- package/dist/install-page/style.css +128 -4
- package/dist/mcp.mjs +74225 -2007
- package/dist/{mcpb-stage/dist/web.mjs → migrate.mjs} +142 -2660
- package/dist/pdf.worker.min.mjs +28 -0
- package/dist/public/app.js +34 -2
- package/dist/public/icon-180.png +0 -0
- package/dist/public/index.html +14 -3
- package/dist/public/lib.js +135 -23
- package/dist/public/pages/applications.js +18 -9
- package/dist/public/pages/documents.js +66 -50
- package/dist/public/pages/home.js +12 -11
- package/dist/public/pages/interview.js +9 -12
- package/dist/public/pages/jobs.js +39 -36
- package/dist/public/pages/profile.js +66 -86
- package/dist/public/pages/settings.js +21 -14
- package/dist/public/styles.css +105 -38
- package/dist/web.mjs +39950 -369
- package/docs/ARCHITECTURE.md +5 -5
- package/docs/DECISIONS.md +1 -1
- package/docs/DEMO.md +6 -6
- package/docs/MCP_TOOLS.md +68 -9
- package/docs/ROADMAP.md +11 -10
- package/docs/RUNTIME_DISTRIBUTION_RESEARCH.md +135 -0
- package/docs/START_WORKFLOW.md +19 -7
- package/docs/SUPPORTED_AI_APPS.md +85 -33
- package/docs/TODO.md +1 -1
- package/docs/WORKFLOWS.md +8 -6
- package/docs/superpowers/specs/2026-06-16-demo-dashboard-deploy-design.md +64 -0
- package/package.json +8 -3
- package/packages/core/src/services.ts +42 -1
- package/packages/db/src/connection.ts +30 -0
- package/packages/db/src/index.ts +1 -0
- package/packages/db/src/paths.ts +11 -0
- package/packages/db/src/repositories.ts +109 -63
- package/packages/db/src/schema.ts +118 -0
- package/packages/exporters/src/html.ts +9 -12
- package/packages/mcp-tools/src/bridge.ts +55 -32
- package/packages/mcp-tools/src/index.ts +9 -0
- package/packages/mcp-tools/src/tools.ts +269 -65
- package/packages/mcp-tools/src/update.ts +330 -0
- package/packages/parsers/src/documents.ts +521 -0
- package/packages/parsers/src/index.ts +8 -5
- package/packages/prompts/src/onboarding.ts +2 -2
- package/packages/shared/src/build-info.ts +22 -0
- package/packages/shared/src/enums.ts +39 -0
- package/packages/shared/src/index.ts +1 -0
- package/packages/shared/src/schemas.ts +24 -3
- package/packages/workflows/src/definitions.ts +4 -2
- package/scripts/build-demo.mjs +130 -0
- package/scripts/build-dist.mjs +46 -8
- package/scripts/build-mcpb.mjs +60 -4
- package/scripts/doctor.ts +16 -3
- package/scripts/gen-og.mjs +86 -0
- package/scripts/init.ts +32 -3
- package/scripts/seed.ts +5 -5
- package/scripts/shots-seed.ts +192 -0
- package/scripts/shots.ts +89 -0
- package/tsconfig.json +3 -1
- package/dist/careermate.mcpb +0 -0
- package/dist/mcp-smoke.err +0 -3
- package/dist/mcpb-stage/README.md +0 -219
- package/dist/mcpb-stage/dist/install-page/index.html +0 -434
- package/dist/mcpb-stage/dist/install-page/style.css +0 -407
- package/dist/mcpb-stage/dist/install-page/vercel.json +0 -20
- package/dist/mcpb-stage/dist/mcp.mjs +0 -23704
- package/dist/mcpb-stage/dist/public/app.js +0 -118
- package/dist/mcpb-stage/dist/public/index.html +0 -41
- package/dist/mcpb-stage/dist/public/lib.js +0 -282
- package/dist/mcpb-stage/dist/public/pages/applications.js +0 -98
- package/dist/mcpb-stage/dist/public/pages/documents.js +0 -446
- package/dist/mcpb-stage/dist/public/pages/home.js +0 -263
- package/dist/mcpb-stage/dist/public/pages/interview.js +0 -230
- package/dist/mcpb-stage/dist/public/pages/jobs.js +0 -494
- package/dist/mcpb-stage/dist/public/pages/profile.js +0 -576
- package/dist/mcpb-stage/dist/public/pages/settings.js +0 -233
- package/dist/mcpb-stage/dist/public/styles.css +0 -420
- package/dist/mcpb-stage/manifest.json +0 -40
- package/docs/INSTALL.md +0 -148
- package/docs/INSTALL_AND_USAGE.md +0 -99
- package/install-page/index.html +0 -474
- package/install-page/style.css +0 -391
- package/install-page/vercel.json +0 -20
- /package/dist/{mcpb-stage/dist/public → install-page}/fonts/PretendardVariable.woff2 +0 -0
package/docs/ARCHITECTURE.md
CHANGED
|
@@ -11,7 +11,7 @@
|
|
|
11
11
|
CareerMate는 독립적으로 동작하는 **두 개의 로컬 프로세스**로 구성된다.
|
|
12
12
|
|
|
13
13
|
- **대시보드 웹서버** (`apps/web`) — `npm start`로 사용자가 직접 기동. `http://127.0.0.1:4319`(사용 중이면 다음 포트로 폴백)에 바인딩하고 브라우저를 자동으로 연다. 사람이 보는 UI와 REST API를 제공한다.
|
|
14
|
-
- **MCP stdio 서버** (`apps/mcp`) — AI 클라이언트(Claude Desktop, ChatGPT, Cursor 등)가 `npm run mcp` 형태로 기동. stdio 위에서 MCP 프로토콜로 통신하며,
|
|
14
|
+
- **MCP stdio 서버** (`apps/mcp`) — AI 클라이언트(Claude Desktop, ChatGPT, Cursor 등)가 `npm run mcp` 형태로 기동. stdio 위에서 MCP 프로토콜로 통신하며, 31개의 CareerMate 도구를 노출한다.
|
|
15
15
|
|
|
16
16
|
두 프로세스는 서로를 직접 호출하지 않는다. 대신 **같은 로컬 SQLite 파일**(`~/.careermate/careermate.sqlite`)을 공유한다. AI가 도구로 쓴 내용은 대시보드에 즉시 보이고, 사용자가 대시보드에서 편집한 내용은 AI가 다음 도구 호출에서 그대로 읽는다. SQLite는 WAL(Write-Ahead Logging) 모드로 열려 두 프로세스의 동시 읽기/쓰기를 안전하게 처리한다.
|
|
17
17
|
|
|
@@ -28,7 +28,7 @@ CareerMate는 독립적으로 동작하는 **두 개의 로컬 프로세스**로
|
|
|
28
28
|
│ │ 대시보드 웹서버 │ │ MCP stdio 서버 │ │
|
|
29
29
|
│ │ (npm start) │ │ (npm run mcp, │ │
|
|
30
30
|
│ │ │ │ AI 클라이언트가 기동) │ │
|
|
31
|
-
│ │ 보안 게이트 → API 라우터 │ │
|
|
31
|
+
│ │ 보안 게이트 → API 라우터 │ │ 31개 도구 등록 │ │
|
|
32
32
|
│ │ → 정적 대시보드/설치페이지│ │ toCallToolResult │ │
|
|
33
33
|
│ └───────────┬──────────────┘ └───────────┬──────────────┘ │
|
|
34
34
|
│ │ │ │
|
|
@@ -72,7 +72,7 @@ CareerMate는 독립적으로 동작하는 **두 개의 로컬 프로세스**로
|
|
|
72
72
|
┌───────────────────────────┬───────────────────────────┐
|
|
73
73
|
│ │ │
|
|
74
74
|
apps/web (REST API) packages/mcp-tools │
|
|
75
|
-
· routes.ts ·
|
|
75
|
+
· routes.ts · 31개 도구 정의 │
|
|
76
76
|
· security/http/exports · 핸들러 → core 호출 │
|
|
77
77
|
└──────────┬────────────────┘
|
|
78
78
|
▼
|
|
@@ -190,7 +190,7 @@ CareerMate의 두 표면(MCP 도구, REST API)은 각각 다른 클라이언트
|
|
|
190
190
|
| `packages/shared` | `@careermate/shared` | 타입, zod 입력 스키마, 상태/문서 라벨·순서 등 상수. 모든 계층이 공유. | (없음) |
|
|
191
191
|
| `packages/db` | `@careermate/db` | 단일 `DatabaseSync` 연결(WAL), 12개 테이블 스키마/마이그레이션, 리포지토리, 데이터 경로(`paths.ts`), 런타임 핸드셰이크(`runtime.ts`). | shared |
|
|
192
192
|
| `packages/core` | `@careermate/core` | 비즈니스 유스케이스. `getApplicationContext`(핵심), `saveProfile`, `saveJobPosting`, `saveFitAnalysis`, `saveCoverLetterVersion`, `updateApplicationStatus`, `saveInterviewPrep`, 온보딩/요약/활동 조회 등. 두 진입점이 공유. | db, shared |
|
|
193
|
-
| `packages/mcp-tools` | `@careermate/mcp-tools` |
|
|
193
|
+
| `packages/mcp-tools` | `@careermate/mcp-tools` | 31개 MCP 도구 정의(`TOOLS`)와 핸들러, `toCallToolResult`. 도구 핸들러는 core를 호출. | core, shared, parsers/prompts/workflows |
|
|
194
194
|
| `packages/parsers` | `@careermate/parsers` | 공고 텍스트 정제(`cleanJobPosting`), 업로드 파일 텍스트 추출(`extractText`). | shared |
|
|
195
195
|
| `packages/exporters` | `@careermate/exporters` | md/html/txt 내보내기 포맷팅(`ExportResult`). | shared |
|
|
196
196
|
| `packages/prompts` | `@careermate/prompts` | 사용자 AI에 전달할 프롬프트 텍스트(`PROMPTS`). | shared |
|
|
@@ -204,5 +204,5 @@ CareerMate의 두 표면(MCP 도구, REST API)은 각각 다른 클라이언트
|
|
|
204
204
|
|
|
205
205
|
- 기술 의사결정 근거 및 보안 모델: [DECISIONS.md](./DECISIONS.md)
|
|
206
206
|
- 데이터 모델(테이블 12개): [DATA_MODEL.md](./DATA_MODEL.md)
|
|
207
|
-
- MCP 도구 목록(
|
|
207
|
+
- MCP 도구 목록(31개): [MCP_TOOLS.md](./MCP_TOOLS.md)
|
|
208
208
|
- 워크플로우: [WORKFLOWS.md](./WORKFLOWS.md)
|
package/docs/DECISIONS.md
CHANGED
|
@@ -140,7 +140,7 @@ CareerMate 내부에는 LLM을 두지 않는다. 대신 MCP(Model Context Protoc
|
|
|
140
140
|
- 데이터 흐름의 통제권이 사용자에게 있다(어떤 AI를 쓸지 사용자가 선택).
|
|
141
141
|
- "인터페이스 = 대화, 저장소 = 로컬 DB"라는 역할 분리가 명확하다.
|
|
142
142
|
- 트레이드오프: CareerMate 단독으로는 분석을 못 한다. MCP를 지원하는 AI 클라이언트가
|
|
143
|
-
전제된다. 도구 표면(
|
|
143
|
+
전제된다. 도구 표면(31개 MCP 도구)과 워크플로 가이드 설계가 제품 품질의 핵심이 된다.
|
|
144
144
|
|
|
145
145
|
---
|
|
146
146
|
|
package/docs/DEMO.md
CHANGED
|
@@ -7,7 +7,7 @@
|
|
|
7
7
|
|
|
8
8
|
> 핵심 모델: **CareerMate 안에는 LLM이 없습니다.** 분석·작성은 당신의 AI(ChatGPT/Claude/Gemini)가 수행하고, CareerMate는 로컬 DB에 데이터를 읽고/쓰는 **MCP 도구**를 제공합니다. 모든 데이터는 로컬(`~/.careermate`)에만 저장됩니다.
|
|
9
9
|
>
|
|
10
|
-
> 관련 문서: [`INSTALL.md`](
|
|
10
|
+
> 관련 문서: [`INSTALL.md`](../INSTALL.md) · [`START_WORKFLOW.md`](./START_WORKFLOW.md)
|
|
11
11
|
|
|
12
12
|
---
|
|
13
13
|
|
|
@@ -95,18 +95,18 @@ npm start
|
|
|
95
95
|
- **글쓰기 선호도**를 꼭 채우세요: 선호 문체(`preferred_tone`)와 강조 포인트(`emphasis_points`). 이 두 값이 이후 자기소개서 품질에 직접 영향을 줍니다.
|
|
96
96
|
- 경력·프로젝트·기술도 이 화면에서 추가할 수 있습니다.
|
|
97
97
|
|
|
98
|
-
> 참고: 같은 작업을 AI에게 맡길 수도 있습니다. 그 경우 AI가 `save_profile
|
|
98
|
+
> 참고: 같은 작업을 AI에게 맡길 수도 있습니다. 그 경우 AI가 `save_profile`을 호출합니다. 전달한 필드만 갱신되고 나머지는 유지됩니다(부분 저장 안전).
|
|
99
99
|
|
|
100
100
|
### 4단계 — 자기소개서/이력서 추가 🧑
|
|
101
101
|
|
|
102
102
|
- 가진 이력서가 있으면 Documents 페이지에서 추가하고, 대표 문서로 지정합니다(대표 이력서는 이후 분석의 근거로 쓰입니다).
|
|
103
103
|
- 기존 자기소개서가 있으면 함께 등록해 두면 좋습니다(AI가 톤·표현을 참고).
|
|
104
104
|
|
|
105
|
-
> AI에게 맡기면 `add_resume`(이력서/경력기술서/포트폴리오), `
|
|
105
|
+
> AI에게 맡기면 `add_resume`(이력서/경력기술서/포트폴리오), `save_cover_letter_version`(기존 자소서는 title+content로 v1 저장)을 호출하고, 구조화된 경력·프로젝트·스킬은 `add_experience`·`add_project`·`add_skill`로 저장합니다.
|
|
106
106
|
|
|
107
107
|
### 5단계 — AI 클라이언트에서 MCP 연결 확인 🧑
|
|
108
108
|
|
|
109
|
-
- CareerMate는 **로컬 stdio MCP 서버**라, 내 컴퓨터에서 실행되며 로컬 프로그램을 띄울 수 있는 클라이언트에서만 동작합니다 — Claude Desktop · Cursor · Cline · Windsurf · Claude Code. (ChatGPT·Gemini의 웹/앱은 클라우드에서 돌아 로컬 MCP 서버에 직접 연결할 수 없습니다.) 설치는
|
|
109
|
+
- CareerMate는 **로컬 stdio MCP 서버**라, 내 컴퓨터에서 실행되며 로컬 프로그램을 띄울 수 있는 클라이언트에서만 동작합니다 — Claude Desktop · Cursor · Cline · Windsurf · Claude Code. (ChatGPT·Gemini의 웹/앱은 클라우드에서 돌아 로컬 MCP 서버에 직접 연결할 수 없습니다.) 설치는 크게 세 갈래입니다: 에이전트가 한 문장으로 대신 설치 / 터미널 `npx -y careermate init` / Claude Desktop `.mcpb` — 자세한 절차는 [`SUPPORTED_AI_APPS.md`](./SUPPORTED_AI_APPS.md)(또는 사람용 안내 https://careermate.life)를 참고하세요. MCP 서버 자체는 보통 다음 형태로 기동됩니다(클라이언트가 자동 실행).
|
|
110
110
|
|
|
111
111
|
```bash
|
|
112
112
|
npm run mcp
|
|
@@ -143,7 +143,7 @@ npm run mcp
|
|
|
143
143
|
|
|
144
144
|
### 9단계 — AI가 공고를 구조화해 저장 🤖
|
|
145
145
|
|
|
146
|
-
- 🤖
|
|
146
|
+
- 🤖 붙여넣은 원문에서 회사명/직무/마감일/키워드를 AI가 직접 구조화합니다.
|
|
147
147
|
- 🤖 `save_job_posting`으로 저장합니다. `company`·`position`은 필수, 원문은 `description`, 자격/우대는 `requirements`, 키워드는 `keywords`에 넣습니다. 저장하면 **지원(application) 항목이 자동 생성**됩니다. 같은 `url`이면 중복 없이 갱신됩니다.
|
|
148
148
|
|
|
149
149
|
### 10단계 — AI가 지원 맥락을 가져옴 (★핵심) 🤖
|
|
@@ -239,4 +239,4 @@ npm run mcp
|
|
|
239
239
|
7. `save_interview_prep` — 면접 준비 저장
|
|
240
240
|
8. `open_application` / `open_dashboard` — 사용자에게 결과 보여주기
|
|
241
241
|
|
|
242
|
-
> 더 자세한 단계별 런북은 [`START_WORKFLOW.md`](./START_WORKFLOW.md), 설치·연결은 [`INSTALL.md`](
|
|
242
|
+
> 더 자세한 단계별 런북은 [`START_WORKFLOW.md`](./START_WORKFLOW.md), 설치·연결은 [`INSTALL.md`](../INSTALL.md)를 참고하세요.
|
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`에 정의된 **
|
|
5
|
+
이 문서는 `packages/mcp-tools/src/tools.ts`에 정의된 커리어 워크플로 **31개 도구**의 레퍼런스입니다. 도구의 입력 파라미터는 `packages/shared/src/schemas.ts`의 zod 스키마와 일치합니다.
|
|
6
6
|
|
|
7
7
|
> 설계 원칙: 이 도구들은 단순 CRUD 래퍼가 아닙니다. 각 도구는 AI가 사용자를 대신해 수행하는 실제 작업에 대응하며, 설명에 *언제* 그리고 *어떻게* 호출해야 하는지가 담겨 있습니다. 가장 중요한 도구는 [`get_application_context`](#get_application_context-) 입니다.
|
|
8
8
|
|
|
@@ -16,7 +16,36 @@ CareerMate는 **MCP-우선** 로컬 커리어 관리 도구입니다. 사용자
|
|
|
16
16
|
|
|
17
17
|
| 읽기전용(✅) 도구 | 쓰기/부수효과(✏️) 도구 |
|
|
18
18
|
| --- | --- |
|
|
19
|
-
| `
|
|
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_writing_style_guide`, `check_for_update` | `open_inbox`, `save_profile`, `add_resume`, `add_experience`, `add_project`, `add_skill`, `save_cover_letter_version`, `save_job_posting`, `save_fit_analysis`, `update_application_status`, `save_interview_prep`, `export_cover_letter`, `open_dashboard`, `open_application`, `update_careermate` |
|
|
20
|
+
|
|
21
|
+
---
|
|
22
|
+
|
|
23
|
+
## 0. 문서 읽기 (Read Document)
|
|
24
|
+
|
|
25
|
+
| 도구 | 목적 | 주요 입력 | 반환 | 언제 호출 | 읽기전용 |
|
|
26
|
+
| --- | --- | --- | --- | --- | --- |
|
|
27
|
+
| `read_document` | 컴퓨터의 문서 파일에서 본문 텍스트 추출(PDF·Word·한컴·텍스트) | `path`(절대 경로 권장), `max_chars?` | `{ path, format, characters, truncated, warnings[], text }` | 사용자가 파일 경로를 주며 "이 파일 읽어줘/참고해줘"라고 할 때 | ✅ |
|
|
28
|
+
|
|
29
|
+
- 지원 형식: `.pdf`, `.docx`, `.hwp`(HWP 5.x), `.hwpx`, `.txt`/`.md` 등 텍스트. 전부 **순수 JS로 추출**하며 외부 변환기(poppler 등) 설치가 필요 없습니다.
|
|
30
|
+
- 추출한 텍스트는 그대로 새 파일로 다시 쓰지 말고, 분석/작성에 활용한 뒤 결과를 `add_resume`·`save_job_posting`·`save_cover_letter_version` 등으로 CareerMate에 저장하세요.
|
|
31
|
+
- **이미지·스캔 PDF**는 텍스트 레이어가 없어 추출되지 않습니다(`unsupported`로 반환되며 `warnings`에 안내). 이때는 이미지를 직접 볼 수 있는 클라이언트(예: Claude)로 읽거나, 사용자에게 내용을 텍스트로 붙여넣어 달라고 안내하세요. 구형 `.doc`/`.ppt`/`.xls`·`.odt`·iWork는 미지원이니 PDF/`.docx`로 다시 저장하도록 안내합니다.
|
|
32
|
+
- 파일은 **로컬에서만** 처리되며 외부로 전송되지 않습니다. 25MB를 넘는 파일은 거부합니다.
|
|
33
|
+
|
|
34
|
+
---
|
|
35
|
+
|
|
36
|
+
## 0-1. 인입 폴더 (Inbox)
|
|
37
|
+
|
|
38
|
+
CLI 클라이언트(Claude Code·Codex 등)는 파일 첨부가 안 되므로, 사용자가 기존 이력서·경력기술서 파일을 끌어다 넣을 수 있는 로컬 인입 폴더(`~/.careermate/inbox`)를 두고 그 안의 파일을 읽습니다. 사용자가 파일 **경로**를 직접 알려주는 경우에는 인입 폴더 대신 `read_document`를 쓰세요.
|
|
39
|
+
|
|
40
|
+
| 도구 | 목적 | 주요 입력 | 반환 | 언제 호출 | 읽기전용 |
|
|
41
|
+
| --- | --- | --- | --- | --- | --- |
|
|
42
|
+
| `open_inbox` | 인입 폴더(`~/.careermate/inbox`)를 보장하고 파일 탐색기로 열기 + 현재 들어 있는 파일 목록 반환 | 없음 | `{ dir, files[] }` | 온보딩에서 사용자가 "기존에 작성해 둔 이력서 파일이 있다"고 답했을 때만(묻지 않고 자동으로 열지 마세요) | ✏️ |
|
|
43
|
+
| `read_inbox` | 인입 폴더에 넣어 둔 문서들의 본문을 한 번에 추출해 반환 | `filename?`(대소문자 무시, 생략 시 전체), `max_chars?`(파일별 기본 20000자) | `{ dir, files[] }`(각 `{ filename, path, format, unsupported, truncated, warnings[], text }`) | `open_inbox`로 안내한 뒤 사용자가 "다 넣었어"라고 할 때 | ✅ |
|
|
44
|
+
|
|
45
|
+
- `open_inbox`는 폴더를 열기만 합니다. 사용자가 파일을 다 넣었다고 하면 `read_inbox`로 본문을 읽으세요.
|
|
46
|
+
- `docx`/`hwp`/`hwpx`/텍스트는 텍스트를 추출하고, **`pdf`·이미지는 추출하지 않고 파일 경로만** 돌려주니(`unsupported`) AI 클라이언트의 파일 읽기 기능으로 그 경로를 직접 열어 읽으세요.
|
|
47
|
+
- 읽은 내용은 그대로 새 파일로 다시 쓰지 말고, 구조화해 `save_profile`·`add_resume` 등 알맞은 도구로 CareerMate에 저장하세요.
|
|
48
|
+
- 응답 폭발을 막기 위해 파일별 본문은 `max_chars`(기본 20000자)로 잘라서 돌려주며, 잘린 경우 `truncated: true`로 표시합니다.
|
|
20
49
|
|
|
21
50
|
---
|
|
22
51
|
|
|
@@ -25,9 +54,8 @@ CareerMate는 **MCP-우선** 로컬 커리어 관리 도구입니다. 사용자
|
|
|
25
54
|
| 도구 | 목적 | 주요 입력 | 반환 | 언제 호출 | 읽기전용 |
|
|
26
55
|
| --- | --- | --- | --- | --- | --- |
|
|
27
56
|
| `get_onboarding_status` | CareerMate에 어떤 정보(프로필·이력서·경력·스킬·자소서·공고)가 준비되어 있는지 확인하고 다음 단계를 제시 | 없음 | `completed`, `has_profile`/`has_resume`/`has_cover_letter`/`has_experience`/`has_skills`/`has_job`, `profile_completeness`(0~100), `next_steps[]` | AI 클라이언트 연결 직후 가장 먼저 | ✅ |
|
|
28
|
-
| `start_onboarding` | 가이드형 온보딩 시작. 현재 상태 + AI가 사용자를 안내하는 단계별 지침 반환 | 없음 | `status`(온보딩 상태), `guide`(온보딩 프롬프트 텍스트) | 사용자가 "시작하자 / 설정 도와줘"라고 할 때 | ✅ |
|
|
29
57
|
|
|
30
|
-
|
|
58
|
+
AI 클라이언트가 연결되면 이 도구를 가장 먼저 호출해 상태를 파악한 뒤, 단계별 가이드가 필요하면 `get_workflow_guide('onboarding')`로 받으세요. 안내 흐름: 프로필 입력 → 이력서/경력·스킬 추가 → 대시보드 열기.
|
|
31
59
|
|
|
32
60
|
---
|
|
33
61
|
|
|
@@ -37,7 +65,6 @@ CareerMate는 **MCP-우선** 로컬 커리어 관리 도구입니다. 사용자
|
|
|
37
65
|
| --- | --- | --- | --- | --- | --- |
|
|
38
66
|
| `get_profile` | 기본 프로필 조회(이름, 한 줄 소개, 요약, 희망 직무/조건, 선호 문체, 강조 포인트, 링크) | 없음 | `ProfileRecord` 또는 `null` | 프로필 확인이 필요할 때 | ✅ |
|
|
39
67
|
| `save_profile` | 프로필 저장(부분 저장 안전 — 전달한 필드만 갱신, 나머지는 유지) | 아래 프로필 필드 | 저장된 `ProfileRecord` | 이력서 구조화 후 이름/소개/희망 직무/선호 문체/강조 포인트를 채워 저장할 때 | ✏️ |
|
|
40
|
-
| `update_profile` | 기존 프로필을 유지하며 일부 필드만 수정(`save_profile`과 동일 동작, 의미 명확화용) | 프로필 필드(모두 선택) | 저장된 `ProfileRecord` | 한두 개 항목만 바꿀 때 | ✏️ |
|
|
41
68
|
|
|
42
69
|
프로필 입력 필드(`ProfileInputSchema`):
|
|
43
70
|
|
|
@@ -64,11 +91,29 @@ CareerMate는 **MCP-우선** 로컬 커리어 관리 도구입니다. 사용자
|
|
|
64
91
|
|
|
65
92
|
---
|
|
66
93
|
|
|
94
|
+
## 3-1. 경력·프로젝트·기술스택 (Experiences / Projects / Skills)
|
|
95
|
+
|
|
96
|
+
이력서 본문(`add_resume`)과 별개로, **구조화된** 경력·프로젝트·기술을 각각의 테이블에 항목 단위로 저장합니다. `get_application_context`의 `experiences`/`projects`/`skills`로 노출되며, `get_onboarding_status`의 `has_experience`/`has_skills`와 프로필 완성도(0~100) 계산에 직접 반영됩니다. (대시보드의 Profile 페이지에서도 같은 데이터를 편집합니다.)
|
|
97
|
+
|
|
98
|
+
| 도구 | 목적 | 주요 입력 | 반환 | 언제 호출 | 읽기전용 |
|
|
99
|
+
| --- | --- | --- | --- | --- | --- |
|
|
100
|
+
| `add_experience` | 경력(직장 단위) 항목 저장 | `company`(필수), `role?`, `employment_type?`, `start_date?`, `end_date?`, `is_current?`, `description?`, `achievements?`, `tech?`, `order_index?` | 저장된 `ExperienceRecord` | 이력서에서 경력을 구조화해 보관할 때 | ✏️ |
|
|
101
|
+
| `get_experiences` | 저장된 경력을 시간 역순으로 조회 | 없음 | `ExperienceRecord[]` | 경력 목록만 빠르게 확인할 때 | ✅ |
|
|
102
|
+
| `add_project` | 대표 프로젝트 항목 저장 | `name`(필수), `role?`, `description?`, `highlights?`, `tech?`, `url?`, `start_date?`, `end_date?`, `order_index?` | 저장된 `ProjectRecord` | 프로젝트 이력을 구조화해 보관할 때 | ✏️ |
|
|
103
|
+
| `get_projects` | 저장된 프로젝트 조회 | 없음 | `ProjectRecord[]` | 프로젝트 목록만 확인할 때 | ✅ |
|
|
104
|
+
| `add_skill` | 기술스택 항목 저장(개당 1건) | `name`(필수), `category?`, `level?`, `years?`, `order_index?` | 저장된 `SkillRecord` | 보유 기술을 정리해 둘 때 | ✏️ |
|
|
105
|
+
| `get_skills` | 저장된 기술스택 조회 | 없음 | `SkillRecord[]` | 기술 목록만 확인할 때 | ✅ |
|
|
106
|
+
|
|
107
|
+
- `achievements`/`highlights`에는 정량 지표가 담긴 성과를, `tech`에는 사용 기술을 배열로 넣으면 적합도 분석·자소서·면접 준비에서 근거로 활용됩니다.
|
|
108
|
+
- 기술은 항목당 1건이므로 여러 개면 `add_skill`을 반복 호출하세요.
|
|
109
|
+
- 입력 스키마: `ExperienceInputSchema` / `ProjectInputSchema` / `SkillInputSchema`(`packages/shared/src/schemas.ts`).
|
|
110
|
+
|
|
111
|
+
---
|
|
112
|
+
|
|
67
113
|
## 4. 자기소개서 (Cover Letters)
|
|
68
114
|
|
|
69
115
|
| 도구 | 목적 | 주요 입력 | 반환 | 언제 호출 | 읽기전용 |
|
|
70
116
|
| --- | --- | --- | --- | --- | --- |
|
|
71
|
-
| `add_cover_letter` | 기존 자기소개서를 등록(`content`를 주면 첫 버전 v1로 저장) | `title`, `content?`, `job_id?`, `is_primary?`, `note?`, `source?` | 생성/저장된 `CoverLetterRecord` | 사용자가 이미 쓴 자소서를 학습용으로 보관할 때 | ✏️ |
|
|
72
117
|
| `get_cover_letters` | 저장된 자기소개서 조회(공고별 필터 가능). 각 항목은 현재 버전 내용·버전 수 포함 | `job_id?` | `CoverLetterRecord[]` | 자소서 목록/내용을 확인할 때 | ✅ |
|
|
73
118
|
| `save_cover_letter_version` | 자기소개서의 새 버전 저장 — 자소서 작성 워크플로우의 핵심 저장 단계 | `content`(필수), `cover_letter_id?`, `title?`, `job_id?`, `note?`, `source?`, `set_current?` | `{ coverLetter, version }` | 새 공고용 자소서를 생성·갱신해 버전으로 남길 때 | ✏️ |
|
|
74
119
|
|
|
@@ -79,7 +124,7 @@ CareerMate는 **MCP-우선** 로컬 커리어 관리 도구입니다. 사용자
|
|
|
79
124
|
- `job_id`로 공고에 연결하면 지원(application) 항목과 자동 연결됩니다.
|
|
80
125
|
- `set_current`(기본 `true`): 이 버전을 현재 버전으로 지정.
|
|
81
126
|
|
|
82
|
-
> 새 공고용 자소서를
|
|
127
|
+
> 기존 자소서를 학습용으로 보관하든 새 공고용 자소서를 새로 쓰든, 저장은 모두 `save_cover_letter_version`으로 합니다. `title`+`content`만 주면 새 자소서의 v1로 저장됩니다.
|
|
83
128
|
|
|
84
129
|
---
|
|
85
130
|
|
|
@@ -90,11 +135,10 @@ CareerMate는 **MCP-우선** 로컬 커리어 관리 도구입니다. 사용자
|
|
|
90
135
|
| `save_job_posting` | 채용공고 저장(있으면 갱신). 저장 시 지원(application) 항목 자동 생성 | `company`, `position`(필수), `url?`, `location?`, `employment_type?`, `description?`, `requirements?`, `keywords?`, `deadline?`, `source?` | 저장된 `JobRecord`(`job_id` 포함) | 공고를 DB에 등록/갱신할 때 | ✏️ |
|
|
91
136
|
| `get_job_posting` | 공고 1건 상세 조회 | `job_id` | `{ job, fit, application, cover_letters, interview }` | 한 공고의 분석·상태·자소서·면접 자료를 한 번에 볼 때 | ✅ |
|
|
92
137
|
| `list_jobs` | 저장된 모든 공고를 지원 상태·적합도 점수와 함께 목록화 | 없음 | 공고 메타 포함 배열 | 전체 공고를 훑어볼 때 | ✅ |
|
|
93
|
-
| `parse_job_posting` | 붙여넣은 공고 원문을 정리해 회사명/직무/마감일 추정 + 기술 키워드 추출 | `raw`(공고 원문 텍스트) | 정리된 공고 구조 | `save_job_posting` 전에 빠르게 구조화할 때(보조) | ✅ |
|
|
94
138
|
|
|
95
139
|
- `url`이 같으면 중복 생성 없이 갱신됩니다.
|
|
96
140
|
- `requirements`에는 자격요건/우대사항 핵심, `keywords`에는 핵심 키워드를 정리해 넣으면 이후 적합도 분석·자소서 작성에 활용됩니다.
|
|
97
|
-
-
|
|
141
|
+
- 붙여넣은 공고 원문의 구조화(회사명/직무/마감일/키워드 추출)는 AI가 직접 수행한 뒤 `save_job_posting`으로 저장합니다.
|
|
98
142
|
|
|
99
143
|
---
|
|
100
144
|
|
|
@@ -198,6 +242,21 @@ CareerMate는 **MCP-우선** 로컬 커리어 관리 도구입니다. 사용자
|
|
|
198
242
|
|
|
199
243
|
---
|
|
200
244
|
|
|
245
|
+
## 14. 업데이트 (Update)
|
|
246
|
+
|
|
247
|
+
CareerMate를 최신 버전으로 유지하기 위한 유지보수 도구입니다. 확인은 `check_for_update`로, 실제 적용은 `update_careermate`로 합니다.
|
|
248
|
+
|
|
249
|
+
| 도구 | 목적 | 주요 입력 | 반환 | 언제 호출 | 읽기전용 |
|
|
250
|
+
| --- | --- | --- | --- | --- | --- |
|
|
251
|
+
| `check_for_update` | npm 레지스트리에서 새 버전이 있는지 지금 확인(공개 버전 정보만 GET, 사용자 데이터 미전송) | 없음 | `{ current, latest, update_available }` | 사용자가 "최신이야?/업데이트 있어?"라고 묻거나 `get_onboarding_status`가 새 버전을 알릴 때 | ✅ |
|
|
252
|
+
| `update_careermate` | 설치 폴더에 `careermate@latest`를 npm으로 설치해 최신 버전으로 업데이트 | 없음 | 업데이트 결과(`{ ok, message, manual? }`) | 사용자가 명시적으로 "업데이트해줘"라고 할 때만 | ✏️ |
|
|
253
|
+
|
|
254
|
+
- `check_for_update`는 확인만 하며 데이터를 변경하지 않습니다. 새 버전이 있으면 `update_careermate`로 적용하세요.
|
|
255
|
+
- `update_careermate` 성공 후에는 적용을 위해 AI 앱(또는 MCP 연결) **재시작**이 필요합니다. 재시작 시 데이터베이스는 자동 마이그레이션되어 기존 데이터가 보존됩니다.
|
|
256
|
+
- 자동 설치가 막히면(개발 모드·비표준 설치) 직접 칠 명령(`manual`)을 안내합니다.
|
|
257
|
+
|
|
258
|
+
---
|
|
259
|
+
|
|
201
260
|
## ⭐ get_application_context — 분석/작성 전 필수 호출
|
|
202
261
|
|
|
203
262
|
> `get_application_context`는 **가장 중요한 도구**입니다. 공고를 분석하거나 자기소개서를 작성하기 **전에 반드시 먼저** 호출하세요. 한 번의 호출로 사용자에 대한 모든 맥락을 돌려줍니다. 읽기전용(✅)입니다.
|
package/docs/ROADMAP.md
CHANGED
|
@@ -2,15 +2,15 @@
|
|
|
2
2
|
|
|
3
3
|
CareerMate는 MCP-우선 로컬 커리어 관리 도구다. 사용자는 자신의 ChatGPT/Claude/Gemini와 대화하고, 그 AI가 CareerMate의 로컬 MCP 도구를 호출해 로컬 커리어 DB를 읽고 쓴다. CareerMate 내부에는 LLM이 없으며(분석·작성은 사용자의 AI가 수행), 모든 데이터는 로컬에만 저장된다.
|
|
4
4
|
|
|
5
|
-
이 문서는 현재 버전(`0.1.
|
|
5
|
+
이 문서는 현재 버전(`0.1.1`)의 MVP 완료 범위와, 지금은 제외하되 구조는 열어둔 향후 과제를 정리한다.
|
|
6
6
|
|
|
7
|
-
관련 문서: [README](../README.md), [설치
|
|
7
|
+
관련 문서: [README](../README.md), [설치 런북](../INSTALL.md), [지원 앱·설치 레퍼런스](./SUPPORTED_AI_APPS.md), [워크플로우](./WORKFLOWS.md), [시작하기 워크플로우](./START_WORKFLOW.md)
|
|
8
8
|
|
|
9
9
|
---
|
|
10
10
|
|
|
11
11
|
## 현재 버전
|
|
12
12
|
|
|
13
|
-
- 버전: `0.1.
|
|
13
|
+
- 버전: `0.1.1` (`package.json`)
|
|
14
14
|
- 런타임 요구: Node `>=22.5.0` (`node:sqlite` 내장 사용, 네이티브 컴파일 없음)
|
|
15
15
|
- 실행 방식: 무빌드(tsx) — `node --no-warnings --import tsx ...`
|
|
16
16
|
|
|
@@ -42,10 +42,11 @@ CareerMate는 MCP-우선 로컬 커리어 관리 도구다. 사용자는 자신
|
|
|
42
42
|
|
|
43
43
|
### MCP 서버 (`apps/mcp`) + 도구 (`packages/mcp-tools`)
|
|
44
44
|
- [x] **MCP stdio 서버**: `@modelcontextprotocol/sdk` 기반, AI 클라이언트가 `npm run mcp`로 기동, 대시보드와 동일 DB 공유
|
|
45
|
-
- [x]
|
|
46
|
-
- 온보딩/프로필: `get_onboarding_status`, `
|
|
47
|
-
- 문서: `add_resume`, `get_resumes`, `
|
|
48
|
-
-
|
|
45
|
+
- [x] **커리어 워크플로 MCP 도구 (26개)**:
|
|
46
|
+
- 온보딩/프로필: `get_onboarding_status`, `save_profile`, `get_profile`
|
|
47
|
+
- 문서: `add_resume`, `get_resumes`, `get_cover_letters`
|
|
48
|
+
- 경력·프로젝트·스킬: `add_experience`, `get_experiences`, `add_project`, `get_projects`, `add_skill`, `get_skills`
|
|
49
|
+
- 공고: `save_job_posting`, `get_job_posting`, `list_jobs`
|
|
49
50
|
- 컨텍스트(핵심): `get_application_context`
|
|
50
51
|
- 분석/작성: `save_fit_analysis`, `save_cover_letter_version`
|
|
51
52
|
- 지원/면접: `update_application_status`, `save_interview_prep`
|
|
@@ -57,7 +58,7 @@ CareerMate는 MCP-우선 로컬 커리어 관리 도구다. 사용자는 자신
|
|
|
57
58
|
|
|
58
59
|
### 기능 흐름 (저장/관리)
|
|
59
60
|
- [x] **온보딩**: 프로필·경력·프로젝트·스킬 입력 흐름
|
|
60
|
-
- [x] **공고
|
|
61
|
+
- [x] **공고 저장**: 공고 본문 저장(회사명/직무/키워드 구조화는 AI가 수행)
|
|
61
62
|
- [x] **적합도(fit) 분석 저장**: `save_fit_analysis`
|
|
62
63
|
- [x] **자소서 버전 관리**: `cover_letter_versions` 테이블 + 타임라인 (Documents 페이지)
|
|
63
64
|
- [x] **지원 상태 관리**: 8단계 칸반 (Applications 페이지) + `update_application_status`
|
|
@@ -92,8 +93,8 @@ CareerMate는 MCP-우선 로컬 커리어 관리 도구다. 사용자는 자신
|
|
|
92
93
|
아래 항목은 **지금은 제외하되, 구조는 열어둔다**. 즉 현재 MVP 범위에서 구현하지 않지만, 패키지 경계·데이터 모델·도구 인터페이스가 이후 추가를 수용할 수 있도록 설계되어 있다.
|
|
93
94
|
|
|
94
95
|
### 공고 크롤링 (사람인 / 잡코리아 / 원티드)
|
|
95
|
-
- 현재는 사용자가 공고 본문을 붙여넣으면 `
|
|
96
|
-
- 구조 개방:
|
|
96
|
+
- 현재는 사용자가 공고 본문을 붙여넣으면 AI가 직접 구조화해 `save_job_posting`으로 저장한다. URL 입력 시 자동 크롤링은 미구현.
|
|
97
|
+
- 구조 개방: 텍스트 정제 로직이 `packages/parsers`로 분리되어 있어(대시보드 `/api/parse/job`에서 사용), 사이트별 크롤러/어댑터를 추가하는 형태로 확장 가능.
|
|
97
98
|
- **지금은 제외, 구조는 열어둠.**
|
|
98
99
|
|
|
99
100
|
### 클라우드 동기화
|
|
@@ -0,0 +1,135 @@
|
|
|
1
|
+
# 런타임·배포 조사: 완전 원클릭(Codex .exe / Claude `.mcpb`) 실현 가능성
|
|
2
|
+
|
|
3
|
+
- **작성일**: 2026-06-15
|
|
4
|
+
- **상태**: 조사 완료 / 큰 작업은 **보류(문서만)**
|
|
5
|
+
- **관련**: [ADR #1 `node:sqlite` 채택](./DECISIONS.md), [ADR #6 대시보드·MCP의 SQLite(WAL) 공유 + `server.json` 핸드셰이크](./DECISIONS.md), [ROADMAP](./ROADMAP.md)
|
|
6
|
+
|
|
7
|
+
> 이 문서는 "사용자가 Node/npx/git을 미리 깔지 않고도 한 번에 설치되는 경험"을 두 경로
|
|
8
|
+
> (① OpenAI **Codex Windows 앱** + 단일 `.exe`, ② Claude Desktop **`.mcpb`**)에서 만들 수
|
|
9
|
+
> 있는지 조사한 기록이다. 결론과 근거, 그리고 다음에 누가 이어받든 헛수고하지 않도록
|
|
10
|
+
> "무엇이 작은 수정이고 무엇이 큰 작업인지"를 남긴다.
|
|
11
|
+
|
|
12
|
+
---
|
|
13
|
+
|
|
14
|
+
## TL;DR
|
|
15
|
+
|
|
16
|
+
- **공통 근본 제약**: CareerMate는 **`node:sqlite`(Node ≥22.5의 최신 내장 기능)**에 의존한다.
|
|
17
|
+
"무설치 번들 런타임" 전략의 성패는 전부 **"충분히 새로운 Node를 어떻게 확보하느냐"**로 수렴한다.
|
|
18
|
+
- **Codex Windows 앱 + 단일 `.exe`**: 패키징(Node SEA)은 **기술적으로 성립**하나, **자가등록 지속성**과
|
|
19
|
+
**샌드박스** 두 개의 (2026-05~06 기준) 외부 버그/제약 때문에 **진정한 무인 원클릭은 현재 불가**. → **보류.**
|
|
20
|
+
- **Claude `.mcpb`**: 산출물(`dist/mcp.mjs`)은 **Node ≥22.5에서 정상 동작**함을 실증함. 사용자가 겪은
|
|
21
|
+
"설치는 됐는데 도구가 안 뜸/빨간 에러"는 **Claude Desktop 내장 Node가 22.5 미만**일 때의 증상으로 추정되며,
|
|
22
|
+
그 경우의 해결은 **저장 계층 rewrite(= 큰 작업)**다. → **로그로 근본 원인 확정 후 결정.**
|
|
23
|
+
|
|
24
|
+
---
|
|
25
|
+
|
|
26
|
+
## 1. 배경 / 질문
|
|
27
|
+
|
|
28
|
+
- CareerMate는 로컬 MCP stdio 서버 + 로컬 웹 대시보드. 저장은 `node:sqlite`.
|
|
29
|
+
- 목표: 비개발자가 **아무것도 미리 설치하지 않고** 한 번에 쓰기 시작하는 경험.
|
|
30
|
+
- 두 경로를 검토:
|
|
31
|
+
1. **Codex Windows 데스크톱 앱**(2026-03 출시, MS Store, 로컬 샌드박스+PowerShell)에 **Node 런타임을
|
|
32
|
+
동봉한 단일 `.exe`**(Node SEA)를 더블클릭 → 자가등록 → 동작.
|
|
33
|
+
2. **Claude Desktop `.mcpb`**(런타임 동봉형 원클릭) — 이미 빌드 파이프라인 존재(`scripts/build-mcpb.mjs`).
|
|
34
|
+
|
|
35
|
+
---
|
|
36
|
+
|
|
37
|
+
## 2. Codex Windows 앱 + 단일 `.exe` (Node SEA)
|
|
38
|
+
|
|
39
|
+
### 2.1 패키징 자체 — 성립 (조건부 가능)
|
|
40
|
+
|
|
41
|
+
| 항목 | 판정 | 근거 |
|
|
42
|
+
|---|---|---|
|
|
43
|
+
| Windows에서 SEA `.exe` 생성 | 가능 | Node SEA의 **첫 번째 CI 테스트 플랫폼이 Windows**. `.exe` 출력 지원. 안정성 지수는 1.1(Active development). |
|
|
44
|
+
| 빌드 워크플로 | 간소화됨 | Node **25.5.0**의 `--build-sea` 단일 플래그로 통합(종전 postject 3단계 불필요). |
|
|
45
|
+
| 정적 자산(대시보드 HTML/CSS/JS) 임베드 | 가능 | `sea.getAsset()`/`getRawAsset()` 계열로 번들·런타임 서빙(v20.12.0~). 단 현재 `apps/web`는 디스크에서 자산을 읽으므로 **임베드용 코드 수정 필요**. |
|
|
46
|
+
| `node:sqlite` 플래그 | 사실상 비이슈 | **Node ≥22.13 / ≥23.4부터 `--experimental-sqlite` 없이 동작**. 최신 Node를 임베드하면 해결. 필요시 SEA `execArgv`로 플래그 주입도 가능. |
|
|
47
|
+
|
|
48
|
+
근거 출처(주요): nodejs.org `single-executable-applications`, `sqlite` 문서; Node v25.5.0 릴리스 블로그;
|
|
49
|
+
Joyee Cheung 블로그(Windows PE 주입 실테스트); commit `55239a48b6`("unflag sqlite module").
|
|
50
|
+
|
|
51
|
+
### 2.2 자가등록·동작을 막는 두 개의 블로커 — 현재 불가
|
|
52
|
+
|
|
53
|
+
1. **🚨 Codex 데스크톱이 시작 시 `~/.codex/config.toml`을 재작성하며 사용자 커스텀 `[mcp_servers]` 블록을 삭제**
|
|
54
|
+
- openai/codex **issue #24718** (2026-05-27 OPEN, v26.519.11010.0, Win11 26200): "Codex Desktop overwrites
|
|
55
|
+
`%USERPROFILE%\.codex\config.toml` during startup ... removes a manually configured custom MCP server",
|
|
56
|
+
"blocking data-loss issue." (보강: #26530, #24387, JetBrains LLM-24906)
|
|
57
|
+
- 의미: `.exe`가 `init`으로 스스로 등록해도 **앱이 지워버릴 수 있음** → 자가등록 전략의 핵심 전제가 깨짐.
|
|
58
|
+
2. **샌드박스가 MCP stdio 서브프로세스에도 상속됨**
|
|
59
|
+
- 공식 문서: "The sandbox applies to spawned commands ... inherit the same sandbox boundaries", "Every file
|
|
60
|
+
write, terminal command, network request, and process spawn goes through the sandbox."
|
|
61
|
+
- 기본 `workspace-write`의 쓰기 가능 루트는 `cwd + $TMPDIR + /tmp`뿐 → **워크스페이스 바깥인
|
|
62
|
+
`~/.careermate` 쓰기와 127.0.0.1 포트 바인딩이 기본 거부**. `danger-full-access` 또는
|
|
63
|
+
`sandbox_workspace_write.writable_roots` 명시 필요. (실증: issue #18243, #24727 "windows sandbox failed: spawn setup")
|
|
64
|
+
|
|
65
|
+
> 두 블로커 모두 **CareerMate 코드 문제가 아니라 Codex 앱 측 미해결 버그/설계 제약**이라 우리가 코드로 못 고친다.
|
|
66
|
+
> #24718이 패치되고 샌드박스 정책이 정리되면 결론이 뒤집힐 수 있으므로 **추적 대상**.
|
|
67
|
+
|
|
68
|
+
### 2.3 결론(Codex)
|
|
69
|
+
|
|
70
|
+
- 패키징은 가능, **무인 원클릭은 현재 불가** → **보류.** 당분간 Codex는 CLI/IDE 확장 경로 또는
|
|
71
|
+
"Node 1회 설치 → `npx -y careermate init`" 안내가 현실적.
|
|
72
|
+
|
|
73
|
+
---
|
|
74
|
+
|
|
75
|
+
## 3. Claude Desktop `.mcpb`
|
|
76
|
+
|
|
77
|
+
### 3.1 실증 결과 (이 저장소, 2026-06-15, Node v25)
|
|
78
|
+
|
|
79
|
+
- `manifest.json`은 정상: `server.type:"node"`, `args:["--experimental-sqlite","${__dirname}/dist/mcp.mjs"]`.
|
|
80
|
+
- **`dist/mcp.mjs` 단독 부팅 성공** — `initialize` 응답 정상, **도구 24개** 로드, 데이터 `~/.careermate` 연결.
|
|
81
|
+
- 이 PC의 **Node v25**에서: `--experimental-sqlite`는 **거부되지 않고 경고만**, 플래그 없이도 `node:sqlite` 동작.
|
|
82
|
+
→ "최신 Node가 플래그를 거부해 죽는다" 시나리오는 (최소 v25까지) **없음**.
|
|
83
|
+
|
|
84
|
+
### 3.2 그렇다면 사용자가 본 "도구 안 뜸/빨간 에러"의 원인
|
|
85
|
+
|
|
86
|
+
- 산출물·플래그가 Node ≥22.5에서 멀쩡하므로, **sqlite 경로의 유일한 실패 원인 = Claude Desktop 내장 Node < 22.5**.
|
|
87
|
+
그 경우 `node:sqlite` 모듈이 **아예 없고** `--experimental-sqlite`도 **모르는 옵션**이라 서버가 즉시 죽는다.
|
|
88
|
+
- (대안 가설) sqlite 무관 환경 문제 — 단 Claude Desktop 미설치 환경에서는 재현 불가.
|
|
89
|
+
- **확정 방법(저비용, 먼저 할 것)**: `.mcpb`를 깐 PC에서 로그 확인
|
|
90
|
+
- Windows: `%APPDATA%\Claude\logs\mcp-server-careermate.log` (또는 `mcp.log`)
|
|
91
|
+
- `bad option: --experimental-sqlite` / `No such built-in module: node:sqlite` → **내장 Node < 22.5 확정**
|
|
92
|
+
- 그 외(경로/ESM/`__dirname`) → 패키징 문제(별개 갈래)
|
|
93
|
+
|
|
94
|
+
### 3.3 내장 Node < 22.5가 확정될 경우 — 저장 계층 대안
|
|
95
|
+
|
|
96
|
+
코드 결합도는 낮다. `node:sqlite`를 만지는 곳은 **3개 파일**뿐:
|
|
97
|
+
`packages/db/src/{connection.ts, schema.ts, repositories.ts}`. 사용 API도 작은 부분집합
|
|
98
|
+
(`DatabaseSync`, `exec`, `prepare().get()/.all()/.run()`, `?`/`@name` 인자, `.changes`, `close`), **JOIN 없음**.
|
|
99
|
+
→ `getDb()` 뒤 어댑터 교체 자체는 소규모.
|
|
100
|
+
|
|
101
|
+
**그러나 두 개의 지뢰:**
|
|
102
|
+
|
|
103
|
+
1. **2-프로세스 동시성(ADR #6)** — 웹 대시보드와 MCP 서버가 **별도 프로세스로 같은 DB를 WAL 동시 접근**.
|
|
104
|
+
- `sql.js`(WASM): 낡은 Node까지 호환되지만 **인메모리+수동 저장**이라 두 프로세스 공유 시 last-writer-wins로 **깨짐**.
|
|
105
|
+
- JSON 스토어(lowdb 등): 동일하게 동시성 재설계 필요.
|
|
106
|
+
2. **네이티브 ABI** — `better-sqlite3`는 API가 거의 동일하지만 **네이티브 모듈**이라 내장 Node ABI와
|
|
107
|
+
prebuilt 불일치(NODE_MODULE_VERSION) 위험. 버전 문제를 다른 형태로 되살림.
|
|
108
|
+
|
|
109
|
+
| 대안 | 낡은 내장 Node 호환 | 2-프로세스 동시성 | 비용 |
|
|
110
|
+
|---|---|---|---|
|
|
111
|
+
| sql.js (WASM) | ✅ | ❌ 재설계 필요 | 中~大 |
|
|
112
|
+
| better-sqlite3 | ❌ ABI 위험 | ✅ | 中(근본 미해결) |
|
|
113
|
+
| JSON 스토어 | ✅ | ❌ 재설계 필요 | 中~大 |
|
|
114
|
+
|
|
115
|
+
가장 깔끔한 방향: **MCP 서버가 DB를 직접 열지 않고 웹 서버의 127.0.0.1 HTTP로 데이터를 요청 → 웹 서버가
|
|
116
|
+
단일 DB 소유자**. 이러면 sql.js가 성립하지만 "대시보드가 안 떠 있어도 MCP 동작" UX를 잃는다(진짜 아키텍처 변경).
|
|
117
|
+
|
|
118
|
+
→ 어느 쪽이든 **"작은 수정"이 아니라 아키텍처 변경**이므로, 근본 원인(로그) 확정 전에는 착수하지 않는다.
|
|
119
|
+
|
|
120
|
+
---
|
|
121
|
+
|
|
122
|
+
## 4. 권고 / 다음 단계
|
|
123
|
+
|
|
124
|
+
1. **(먼저, 저비용)** `.mcpb` 깐 PC에서 로그 한 줄 확인 → 내장 Node < 22.5 여부 확정.
|
|
125
|
+
- 플래그류 에러면: (가설과 달리) 단순 수정 가능성 → 재검토.
|
|
126
|
+
- `node:sqlite` 부재면: 아래 3.3 rewrite를 정식 과제로.
|
|
127
|
+
2. **단기 우회**(무설치 포기 허용 시): "Node ≥22.5 1회 설치 → `npx -y careermate init`" — Claude/Codex 공통으로 가장 견고.
|
|
128
|
+
3. **추적**: Codex issue #24718(config 재작성) 상태. 닫히면 Codex SEA 원클릭을 재평가.
|
|
129
|
+
|
|
130
|
+
## 5. 검증 메모 / 한계
|
|
131
|
+
|
|
132
|
+
- Codex 데스크톱 관련 결론은 **2026-05~06 기준 OPEN 버그**에 의존(시간 민감).
|
|
133
|
+
- #24718의 구체 재현은 HTTP MCP였다는 점에서 stdio 삭제는 광범위 재작성 정황으로의 소폭 일반화.
|
|
134
|
+
- 미서명 `.exe`의 SmartScreen/Defender 경고가 원클릭 UX를 얼마나 저해하는지는 **이번 라운드에서 확정 근거 미확보**(미검증).
|
|
135
|
+
- `.mcpb` 실패의 "내장 Node < 22.5" 결론은 **로그로 직접 확정 전까지 강한 추정**이다.
|
package/docs/START_WORKFLOW.md
CHANGED
|
@@ -4,6 +4,8 @@
|
|
|
4
4
|
|
|
5
5
|
> 핵심 원칙: **분석과 글쓰기는 당신(AI)이 수행하고, CareerMate는 데이터를 제공·보관**합니다. 공고 분석이나 자기소개서 작성 전에는 항상 `get_application_context`를 먼저 호출해 근거 데이터를 가져오세요.
|
|
6
6
|
|
|
7
|
+
> **대시보드 안내 정책**: 브라우저를 직접 여는 건 **첫 온보딩에서 한 번만**(`open_dashboard`)입니다. 이후 무언가를 저장·완료할 때는 **자동으로 새로 열지 말고** 주소(`http://127.0.0.1:4319`)만 안내하고, 사용자가 "열어줘"라고 할 때만 `open_application`(단건)·`open_dashboard`(전체)로 엽니다.
|
|
8
|
+
|
|
7
9
|
---
|
|
8
10
|
|
|
9
11
|
## A. 온보딩 (첫 연결 시 한 번)
|
|
@@ -13,26 +15,36 @@
|
|
|
13
15
|
- 연결 직후 가장 먼저 호출합니다.
|
|
14
16
|
- 결과의 `has_profile` / `has_resume` / `has_cover_letter` / `has_experience` / `has_skills` / `has_job`, `profile_completeness`(0~100), `next_steps`를 확인합니다.
|
|
15
17
|
- 사용자에게 "지금까지 등록된 정보"와 "앞으로 채우면 좋은 정보"를 짧게 안내합니다. **이미 채워진 항목은 다시 묻지 마세요.**
|
|
16
|
-
- (선택)
|
|
18
|
+
- (선택) 단계별 가이드가 필요하면 `get_workflow_guide('onboarding')`로 받을 수 있습니다.
|
|
17
19
|
|
|
18
20
|
### 2. 프로필 수집 및 저장 — `save_profile`
|
|
19
21
|
|
|
20
22
|
- 사용자가 올린 이력서/자기소개서 파일 또는 직접 알려준 내용을 바탕으로 프로필을 구조화합니다.
|
|
21
23
|
- 정리 항목: 이름, 연락처, 한 줄 소개(`headline`), 요약(`summary`), 희망 직무(`desired_roles`), 희망 근무 조건(`desired_conditions`).
|
|
22
24
|
- **글쓰기 선호도**를 함께 물어보세요: 선호 문체(`preferred_tone`, 예: "담백하고 구체적")와 강조 포인트(`emphasis_points`). 이 두 값은 이후 자기소개서 품질에 직접 영향을 줍니다.
|
|
23
|
-
- `save_profile`로 저장합니다. 전달한 필드만 갱신되고 나머지는 유지됩니다(부분 저장 안전). 한두 개만 바꿀
|
|
25
|
+
- `save_profile`로 저장합니다. 전달한 필드만 갱신되고 나머지는 유지됩니다(부분 저장 안전). 한두 개만 바꿀 때도 그대로 `save_profile`을 다시 호출하면 됩니다.
|
|
24
26
|
- 파일에서 읽은 정보는 `source`를 `upload`, 사용자가 말로 준 정보는 `manual`로 표시합니다.
|
|
25
27
|
|
|
26
28
|
### 3. 이력서 등록 — `add_resume`
|
|
27
29
|
|
|
30
|
+
- **사용자가 이력서를 주는 방법은 앱마다 다릅니다.** 상황에 맞게 안내하세요:
|
|
31
|
+
- 가장 쉬운 공통 방법은 **내용을 대화창에 그대로 붙여넣기**(파일 위치 무관).
|
|
32
|
+
- Claude 채팅 앱(.mcpb)이면 **파일 직접 첨부**, 폴더 기반(Claude Code 탭/Codex/Antigravity)이면 작업 폴더에 두고 **파일명·경로로 지시**.
|
|
33
|
+
- 스캔본(이미지) PDF·보안 걸린 파일은 못 읽을 수 있으니, 그때는 **텍스트로 붙여넣어** 달라고 요청합니다.
|
|
28
34
|
- 업로드한 이력서/경력기술서/포트폴리오 본문을 `add_resume`로 저장합니다.
|
|
29
35
|
- `kind`(resume / career_description / portfolio / other)와 `title`을 적절히 지정하고, 대표 문서는 `is_primary=true`로 설정합니다. 대표 문서는 이후 `get_application_context`의 `primary_resume`로 노출됩니다.
|
|
30
36
|
- `source`는 `upload`를 사용합니다.
|
|
31
37
|
|
|
32
|
-
###
|
|
38
|
+
### 3-1. 경력·프로젝트·스킬 등록 (있는 경우) — `add_experience` · `add_project` · `add_skill`
|
|
39
|
+
|
|
40
|
+
- 이력서에서 파악되는 경력·프로젝트·보유 기술은 본문 저장과 별개로 `add_experience` / `add_project` / `add_skill`로 항목 단위 저장하면 적합도 분석·자소서·면접 준비에서 정밀하게 활용됩니다.
|
|
41
|
+
- 경력 `achievements`에는 가능하면 정량 지표를 넣고, 기술은 항목당 1건이라 여러 개면 `add_skill`을 반복 호출합니다.
|
|
42
|
+
- 이 항목들은 `get_onboarding_status`의 `has_experience` / `has_skills`와 프로필 완성도(0~100)에 반영됩니다.
|
|
43
|
+
|
|
44
|
+
### 4. 자기소개서 등록 (있는 경우) — `save_cover_letter_version`
|
|
33
45
|
|
|
34
|
-
- 기존 자기소개서가 있으면 `
|
|
35
|
-
- `content
|
|
46
|
+
- 기존 자기소개서가 있으면 `save_cover_letter_version`으로 저장합니다(`title` + `content`). 특정 공고용이면 `job_id`를 연결합니다.
|
|
47
|
+
- `cover_letter_id` 없이 `title`+`content`만 주면 새 자소서의 첫 버전(v1)으로 저장됩니다. 학습/참고용 보관에 적합합니다.
|
|
36
48
|
- 없으면 "나중에 공고를 분석한 뒤 맞춤 자기소개서를 써드릴 수 있어요"라고 안내만 합니다.
|
|
37
49
|
|
|
38
50
|
### 5. 대시보드 열기 & 다음 단계 — `open_dashboard`
|
|
@@ -50,7 +62,7 @@
|
|
|
50
62
|
### 1. 공고 저장 — `save_job_posting`
|
|
51
63
|
|
|
52
64
|
- `company`, `position`은 필수입니다. 공고 원문은 `description`에, 핵심 자격/우대는 `requirements` 배열에, 키워드는 `keywords`에 정리해 넣습니다.
|
|
53
|
-
-
|
|
65
|
+
- 붙여넣은 원문의 회사명/직무/마감일/기술 키워드 구조화는 AI가 직접 수행한 뒤 위 필드에 채워 저장하세요.
|
|
54
66
|
- 저장하면 지원(application) 항목이 자동 생성되고 `job_id`가 반환됩니다. 같은 `url`이면 중복 없이 갱신됩니다.
|
|
55
67
|
|
|
56
68
|
### 2. 지원 맥락 가져오기 — `get_application_context` ⭐ (반드시 먼저)
|
|
@@ -90,7 +102,7 @@
|
|
|
90
102
|
|
|
91
103
|
### `update_application_status`
|
|
92
104
|
|
|
93
|
-
- 지원 상태를 변경합니다. 가능한
|
|
105
|
+
- 지원 상태를 변경합니다. 가능한 상태는 8단계뿐입니다(AGENTS.md 기준): draft(작성 중), planned(지원 예정), applied(지원 완료), document_passed(서류 합격), interview(면접 진행), final_passed(최종 합격), rejected(불합격), on_hold(보류). 이 외의 값(saved·offer·closed 등)은 대시보드가 모르므로 쓰지 마세요.
|
|
94
106
|
- `note`에 변경 사유를 남길 수 있습니다.
|
|
95
107
|
- 상태가 **서류 합격(document_passed) 이상**으로 바뀌면 면접 준비를 제안하는 힌트를 함께 돌려줍니다 → 다음 단계(E)로 이어집니다.
|
|
96
108
|
|