careermate 0.1.1 → 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 +12 -10
- package/THIRD_PARTY_NOTICES.md +15 -0
- package/apps/mcp/src/index.ts +4 -5
- 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/index.html +10 -2
- package/apps/web/public/lib.js +134 -22
- package/apps/web/public/pages/applications.js +2 -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 +15 -10
- package/apps/web/public/styles.css +56 -2
- package/apps/web/src/http.ts +31 -4
- package/apps/web/src/info.ts +3 -3
- package/apps/web/src/routes.ts +2 -1
- package/apps/web/src/server.ts +1 -4
- package/dist/doctor.mjs +72607 -611
- 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/index.html +31 -70
- package/dist/install-page/landing.js +54 -0
- package/dist/install-page/start.html +13 -36
- package/dist/install-page/style.css +34 -1
- package/dist/mcp.mjs +73936 -1976
- package/dist/migrate.mjs +17 -10
- package/dist/pdf.worker.min.mjs +28 -0
- package/dist/public/app.js +34 -2
- package/dist/public/index.html +10 -2
- package/dist/public/lib.js +134 -22
- package/dist/public/pages/applications.js +2 -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 +15 -10
- package/dist/public/styles.css +56 -2
- package/dist/web.mjs +39631 -244
- package/docs/ARCHITECTURE.md +5 -5
- package/docs/DECISIONS.md +1 -1
- package/docs/DEMO.md +3 -3
- package/docs/MCP_TOOLS.md +49 -9
- package/docs/ROADMAP.md +8 -7
- package/docs/START_WORKFLOW.md +13 -7
- package/docs/TODO.md +1 -1
- package/docs/WORKFLOWS.md +7 -5
- package/docs/superpowers/specs/2026-06-16-demo-dashboard-deploy-design.md +64 -0
- package/package.json +6 -2
- package/packages/db/src/paths.ts +11 -0
- 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 +193 -70
- 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/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 +20 -1
- package/scripts/doctor.ts +16 -3
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
{"t":0,"agent":"a10f819","agent_type":"workflow-subagent","event":"agent_start","parent_mode":"none"}
|
|
2
|
+
{"t":0,"agent":"a10f819","agent_type":"workflow-subagent","event":"agent_stop","success":true,"duration_ms":143102}
|
|
3
|
+
{"t":0,"agent":"aca9cea","agent_type":"workflow-subagent","event":"agent_start","parent_mode":"none"}
|
|
4
|
+
{"t":0,"agent":"a4768e2","agent_type":"workflow-subagent","event":"agent_start","parent_mode":"none"}
|
|
5
|
+
{"t":0,"agent":"a349ced","agent_type":"workflow-subagent","event":"agent_start","parent_mode":"none"}
|
|
6
|
+
{"t":0,"agent":"a349ced","agent_type":"workflow-subagent","event":"agent_stop","success":true,"duration_ms":60038}
|
|
7
|
+
{"t":0,"agent":"a4768e2","agent_type":"workflow-subagent","event":"agent_stop","success":true,"duration_ms":114215}
|
|
8
|
+
{"t":0,"agent":"aca9cea","agent_type":"workflow-subagent","event":"agent_stop","success":true,"duration_ms":121159}
|
|
9
|
+
{"t":0,"agent":"acc5653","agent_type":"unknown","event":"agent_stop","success":true}
|
|
10
|
+
{"t":0,"agent":"a0edd5d","agent_type":"unknown","event":"agent_stop","success":true}
|
|
11
|
+
{"t":0,"agent":"a245f43","agent_type":"unknown","event":"agent_stop","success":true}
|
|
12
|
+
{"t":0,"agent":"aefa1c0","agent_type":"unknown","event":"agent_stop","success":true}
|
|
@@ -0,0 +1,147 @@
|
|
|
1
|
+
{
|
|
2
|
+
"updatedAt": "2026-06-16T12:38:24.867Z",
|
|
3
|
+
"missions": [
|
|
4
|
+
{
|
|
5
|
+
"id": "session:55a58c0d-bb6e-43ea-8a05-4b6c93b80b34:none",
|
|
6
|
+
"source": "session",
|
|
7
|
+
"name": "none",
|
|
8
|
+
"objective": "Session mission",
|
|
9
|
+
"createdAt": "2026-06-16T12:14:33.928Z",
|
|
10
|
+
"updatedAt": "2026-06-16T12:38:24.867Z",
|
|
11
|
+
"status": "done",
|
|
12
|
+
"workerCount": 4,
|
|
13
|
+
"taskCounts": {
|
|
14
|
+
"total": 4,
|
|
15
|
+
"pending": 0,
|
|
16
|
+
"blocked": 0,
|
|
17
|
+
"inProgress": 0,
|
|
18
|
+
"completed": 4,
|
|
19
|
+
"failed": 0
|
|
20
|
+
},
|
|
21
|
+
"agents": [
|
|
22
|
+
{
|
|
23
|
+
"name": "workflow-subagent:a10f819",
|
|
24
|
+
"role": "workflow-subagent",
|
|
25
|
+
"ownership": "a10f8198a3ec53eed",
|
|
26
|
+
"status": "done",
|
|
27
|
+
"currentStep": null,
|
|
28
|
+
"latestUpdate": "completed",
|
|
29
|
+
"completedSummary": null,
|
|
30
|
+
"updatedAt": "2026-06-16T12:38:24.867Z"
|
|
31
|
+
},
|
|
32
|
+
{
|
|
33
|
+
"name": "workflow-subagent:aca9cea",
|
|
34
|
+
"role": "workflow-subagent",
|
|
35
|
+
"ownership": "aca9cea71d20c99c3",
|
|
36
|
+
"status": "done",
|
|
37
|
+
"currentStep": null,
|
|
38
|
+
"latestUpdate": "completed",
|
|
39
|
+
"completedSummary": null,
|
|
40
|
+
"updatedAt": "2026-06-16T12:18:58.856Z"
|
|
41
|
+
},
|
|
42
|
+
{
|
|
43
|
+
"name": "workflow-subagent:a4768e2",
|
|
44
|
+
"role": "workflow-subagent",
|
|
45
|
+
"ownership": "a4768e2be198162e9",
|
|
46
|
+
"status": "done",
|
|
47
|
+
"currentStep": null,
|
|
48
|
+
"latestUpdate": "completed",
|
|
49
|
+
"completedSummary": null,
|
|
50
|
+
"updatedAt": "2026-06-16T12:18:51.989Z"
|
|
51
|
+
},
|
|
52
|
+
{
|
|
53
|
+
"name": "workflow-subagent:a349ced",
|
|
54
|
+
"role": "workflow-subagent",
|
|
55
|
+
"ownership": "a349cedbc216266f2",
|
|
56
|
+
"status": "done",
|
|
57
|
+
"currentStep": null,
|
|
58
|
+
"latestUpdate": "completed",
|
|
59
|
+
"completedSummary": null,
|
|
60
|
+
"updatedAt": "2026-06-16T12:17:57.876Z"
|
|
61
|
+
}
|
|
62
|
+
],
|
|
63
|
+
"timeline": [
|
|
64
|
+
{
|
|
65
|
+
"id": "session-start:aca9cea71d20c99c3:2026-06-16T12:16:57.697Z",
|
|
66
|
+
"at": "2026-06-16T12:16:57.697Z",
|
|
67
|
+
"kind": "update",
|
|
68
|
+
"agent": "workflow-subagent:aca9cea",
|
|
69
|
+
"detail": "started workflow-subagent:aca9cea",
|
|
70
|
+
"sourceKey": "session-start:aca9cea71d20c99c3"
|
|
71
|
+
},
|
|
72
|
+
{
|
|
73
|
+
"id": "session-start:a4768e2be198162e9:2026-06-16T12:16:57.774Z",
|
|
74
|
+
"at": "2026-06-16T12:16:57.774Z",
|
|
75
|
+
"kind": "update",
|
|
76
|
+
"agent": "workflow-subagent:a4768e2",
|
|
77
|
+
"detail": "started workflow-subagent:a4768e2",
|
|
78
|
+
"sourceKey": "session-start:a4768e2be198162e9"
|
|
79
|
+
},
|
|
80
|
+
{
|
|
81
|
+
"id": "session-start:a349cedbc216266f2:2026-06-16T12:16:57.838Z",
|
|
82
|
+
"at": "2026-06-16T12:16:57.838Z",
|
|
83
|
+
"kind": "update",
|
|
84
|
+
"agent": "workflow-subagent:a349ced",
|
|
85
|
+
"detail": "started workflow-subagent:a349ced",
|
|
86
|
+
"sourceKey": "session-start:a349cedbc216266f2"
|
|
87
|
+
},
|
|
88
|
+
{
|
|
89
|
+
"id": "session-stop:a349cedbc216266f2:2026-06-16T12:17:57.876Z",
|
|
90
|
+
"at": "2026-06-16T12:17:57.876Z",
|
|
91
|
+
"kind": "completion",
|
|
92
|
+
"agent": "workflow-subagent:a349ced",
|
|
93
|
+
"detail": "completed",
|
|
94
|
+
"sourceKey": "session-stop:a349cedbc216266f2"
|
|
95
|
+
},
|
|
96
|
+
{
|
|
97
|
+
"id": "session-stop:a4768e2be198162e9:2026-06-16T12:18:51.989Z",
|
|
98
|
+
"at": "2026-06-16T12:18:51.989Z",
|
|
99
|
+
"kind": "completion",
|
|
100
|
+
"agent": "workflow-subagent:a4768e2",
|
|
101
|
+
"detail": "completed",
|
|
102
|
+
"sourceKey": "session-stop:a4768e2be198162e9"
|
|
103
|
+
},
|
|
104
|
+
{
|
|
105
|
+
"id": "session-stop:aca9cea71d20c99c3:2026-06-16T12:18:58.856Z",
|
|
106
|
+
"at": "2026-06-16T12:18:58.856Z",
|
|
107
|
+
"kind": "completion",
|
|
108
|
+
"agent": "workflow-subagent:aca9cea",
|
|
109
|
+
"detail": "completed",
|
|
110
|
+
"sourceKey": "session-stop:aca9cea71d20c99c3"
|
|
111
|
+
},
|
|
112
|
+
{
|
|
113
|
+
"id": "session-stop:acc5653c169518c6f:2026-06-16T12:27:45.167Z",
|
|
114
|
+
"at": "2026-06-16T12:27:45.167Z",
|
|
115
|
+
"kind": "completion",
|
|
116
|
+
"agent": "workflow-subagent:a10f819",
|
|
117
|
+
"detail": "completed",
|
|
118
|
+
"sourceKey": "session-stop:acc5653c169518c6f"
|
|
119
|
+
},
|
|
120
|
+
{
|
|
121
|
+
"id": "session-stop:a0edd5de5c096a00d:2026-06-16T12:30:47.256Z",
|
|
122
|
+
"at": "2026-06-16T12:30:47.256Z",
|
|
123
|
+
"kind": "completion",
|
|
124
|
+
"agent": "workflow-subagent:a10f819",
|
|
125
|
+
"detail": "completed",
|
|
126
|
+
"sourceKey": "session-stop:a0edd5de5c096a00d"
|
|
127
|
+
},
|
|
128
|
+
{
|
|
129
|
+
"id": "session-stop:a245f437d88f5966f:2026-06-16T12:35:27.111Z",
|
|
130
|
+
"at": "2026-06-16T12:35:27.111Z",
|
|
131
|
+
"kind": "completion",
|
|
132
|
+
"agent": "workflow-subagent:a10f819",
|
|
133
|
+
"detail": "completed",
|
|
134
|
+
"sourceKey": "session-stop:a245f437d88f5966f"
|
|
135
|
+
},
|
|
136
|
+
{
|
|
137
|
+
"id": "session-stop:aefa1c00c62034d9b:2026-06-16T12:38:24.867Z",
|
|
138
|
+
"at": "2026-06-16T12:38:24.867Z",
|
|
139
|
+
"kind": "completion",
|
|
140
|
+
"agent": "workflow-subagent:a10f819",
|
|
141
|
+
"detail": "completed",
|
|
142
|
+
"sourceKey": "session-stop:aefa1c00c62034d9b"
|
|
143
|
+
}
|
|
144
|
+
]
|
|
145
|
+
}
|
|
146
|
+
]
|
|
147
|
+
}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 1,
|
|
3
|
+
"entries": {
|
|
4
|
+
"79a93d4a2f8f50b95f852280616242fee1855dc99a3c75211917f55e72e95fae": {
|
|
5
|
+
"last_emitted_at_ms": 1781613182539,
|
|
6
|
+
"message": "Use parallel execution for independent tasks. Use run_in_background for long operations (npm install, builds, tests)."
|
|
7
|
+
},
|
|
8
|
+
"445ed27a3872b681d98190bae61ccb84954e1bc4e140df5370be958dee776b3a": {
|
|
9
|
+
"last_emitted_at_ms": 1781612517441,
|
|
10
|
+
"message": "Verify changes work after editing. Test functionality before marking complete."
|
|
11
|
+
},
|
|
12
|
+
"466399dafa2d20f60587180bad0a07358eb7f2bce724df0ff682f038ad33f5ad": {
|
|
13
|
+
"last_emitted_at_ms": 1781612380768,
|
|
14
|
+
"message": "Read multiple files in parallel when possible for faster analysis."
|
|
15
|
+
},
|
|
16
|
+
"459c54e5f35d6a58dcd90d2aecc21fa6d1f35d241bc5b134c506f87dc7b6d67b": {
|
|
17
|
+
"last_emitted_at_ms": 1781612184981,
|
|
18
|
+
"message": "Combine searches in parallel when investigating multiple patterns."
|
|
19
|
+
}
|
|
20
|
+
},
|
|
21
|
+
"updated_at": "2026-06-16T12:33:02.539Z"
|
|
22
|
+
}
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
{
|
|
2
|
+
"agents": [
|
|
3
|
+
{
|
|
4
|
+
"agent_id": "a10f8198a3ec53eed",
|
|
5
|
+
"agent_type": "workflow-subagent",
|
|
6
|
+
"started_at": "2026-06-16T12:14:33.928Z",
|
|
7
|
+
"parent_mode": "none",
|
|
8
|
+
"status": "completed",
|
|
9
|
+
"completed_at": "2026-06-16T12:16:57.030Z",
|
|
10
|
+
"duration_ms": 143102
|
|
11
|
+
},
|
|
12
|
+
{
|
|
13
|
+
"agent_id": "aca9cea71d20c99c3",
|
|
14
|
+
"agent_type": "workflow-subagent",
|
|
15
|
+
"started_at": "2026-06-16T12:16:57.697Z",
|
|
16
|
+
"parent_mode": "none",
|
|
17
|
+
"status": "completed",
|
|
18
|
+
"completed_at": "2026-06-16T12:18:58.856Z",
|
|
19
|
+
"duration_ms": 121159
|
|
20
|
+
},
|
|
21
|
+
{
|
|
22
|
+
"agent_id": "a4768e2be198162e9",
|
|
23
|
+
"agent_type": "workflow-subagent",
|
|
24
|
+
"started_at": "2026-06-16T12:16:57.774Z",
|
|
25
|
+
"parent_mode": "none",
|
|
26
|
+
"status": "completed",
|
|
27
|
+
"completed_at": "2026-06-16T12:18:51.989Z",
|
|
28
|
+
"duration_ms": 114215
|
|
29
|
+
},
|
|
30
|
+
{
|
|
31
|
+
"agent_id": "a349cedbc216266f2",
|
|
32
|
+
"agent_type": "workflow-subagent",
|
|
33
|
+
"started_at": "2026-06-16T12:16:57.838Z",
|
|
34
|
+
"parent_mode": "none",
|
|
35
|
+
"status": "completed",
|
|
36
|
+
"completed_at": "2026-06-16T12:17:57.876Z",
|
|
37
|
+
"duration_ms": 60038
|
|
38
|
+
}
|
|
39
|
+
],
|
|
40
|
+
"total_spawned": 3,
|
|
41
|
+
"total_completed": 4,
|
|
42
|
+
"total_failed": 0,
|
|
43
|
+
"last_updated": "2026-06-16T12:38:24.985Z"
|
|
44
|
+
}
|
|
@@ -7,7 +7,7 @@
|
|
|
7
7
|
<script>
|
|
8
8
|
(function () {
|
|
9
9
|
try {
|
|
10
|
-
var t = window.localStorage.getItem('cf-theme');
|
|
10
|
+
var t = window.localStorage.getItem('careermate-theme') || window.localStorage.getItem('cf-theme');
|
|
11
11
|
document.documentElement.setAttribute('data-theme', t === 'light' || t === 'dark' ? t : 'dark');
|
|
12
12
|
} catch (e) { document.documentElement.setAttribute('data-theme', 'dark'); }
|
|
13
13
|
})();
|
|
@@ -44,6 +44,7 @@
|
|
|
44
44
|
<link rel="stylesheet" href="style.css" />
|
|
45
45
|
</head>
|
|
46
46
|
<body>
|
|
47
|
+
<a class="skip-link" href="#top">본문으로 건너뛰기</a>
|
|
47
48
|
<!-- ============================================================ nav -->
|
|
48
49
|
<nav class="nav">
|
|
49
50
|
<a class="nav__brand" href="#top">
|
|
@@ -67,7 +68,7 @@
|
|
|
67
68
|
</div>
|
|
68
69
|
</nav>
|
|
69
70
|
|
|
70
|
-
<main id="top">
|
|
71
|
+
<main id="top" tabindex="-1">
|
|
71
72
|
|
|
72
73
|
<!-- ========================================================== hero -->
|
|
73
74
|
<header class="hero">
|
|
@@ -80,16 +81,23 @@
|
|
|
80
81
|
나만의 <span class="accent">커리어 비서</span>로
|
|
81
82
|
</h1>
|
|
82
83
|
<p class="hero__lede">
|
|
83
|
-
|
|
84
|
-
|
|
84
|
+
<strong>공고 분석 · 맞춤 자기소개서 · 지원 현황 추적</strong>을 평소 쓰던 AI에게 말로 시키면,<br />
|
|
85
|
+
결과가 이 컴퓨터 안에 쌓이고, 한 번 정리한 경력은 대화마다 다시 붙여넣지 않아도 돼요.
|
|
85
86
|
</p>
|
|
86
87
|
|
|
88
|
+
<ul class="trust-strip" aria-label="안심 포인트">
|
|
89
|
+
<li>내 컴퓨터에만 저장</li>
|
|
90
|
+
<li>외부 업로드 없음</li>
|
|
91
|
+
<li>계정·API 키 불필요</li>
|
|
92
|
+
<li>언제든 삭제</li>
|
|
93
|
+
</ul>
|
|
94
|
+
|
|
87
95
|
<div class="hero__cta">
|
|
88
|
-
<a class="btn btn--primary" href="
|
|
96
|
+
<a class="btn btn--primary" href="start.html">처음이세요? — 내게 맞는 설치법 찾기</a>
|
|
97
|
+
<a class="btn btn--ghost" href="#install">
|
|
89
98
|
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4"/><path d="M7 10l5 5 5-5"/><path d="M12 15V3"/></svg>
|
|
90
|
-
설치 방법 보기
|
|
99
|
+
바로 설치 방법 보기
|
|
91
100
|
</a>
|
|
92
|
-
<a class="btn btn--ghost" href="start.html">처음이세요? — 내게 맞는 길 찾기</a>
|
|
93
101
|
</div>
|
|
94
102
|
|
|
95
103
|
<p class="hero__note">
|
|
@@ -117,8 +125,8 @@
|
|
|
117
125
|
<div class="feature__icon">
|
|
118
126
|
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M9 12h6"/><path d="M9 12a3 3 0 0 1-3-3V7a3 3 0 0 1 3-3"/><path d="M15 12a3 3 0 0 0 3 3v2a3 3 0 0 1-3 3"/></svg>
|
|
119
127
|
</div>
|
|
120
|
-
<h3>2.
|
|
121
|
-
<p>표준
|
|
128
|
+
<h3>2. 안전하게 연결</h3>
|
|
129
|
+
<p>표준 연결 방식(MCP)이 AI와 CareerMate를 잇는 다리가 됩니다.<br />AI가 당신의 커리어 기록을 직접 읽고 정리해 저장합니다.</p>
|
|
122
130
|
</article>
|
|
123
131
|
<article class="feature">
|
|
124
132
|
<div class="feature__icon">
|
|
@@ -152,7 +160,11 @@
|
|
|
152
160
|
<div class="section__head">
|
|
153
161
|
<span class="eyebrow">대시보드</span>
|
|
154
162
|
<h2>내 데이터를 <span class="accent">눈으로</span> 확인</h2>
|
|
155
|
-
<p>모든 기록은 이 컴퓨터의 대시보드(<code>127.0.0.1:4319</code>)에
|
|
163
|
+
<p>모든 기록은 이 컴퓨터의 대시보드(<code>127.0.0.1:4319</code>)에 모입니다.<br>아래는 실제 화면 — 설치 없이 바로 둘러볼 수 있어요.</p>
|
|
164
|
+
<div class="section__cta">
|
|
165
|
+
<a class="btn btn--primary" href="demo/">데모 둘러보기 →</a>
|
|
166
|
+
<span class="section__cta-note">샘플 데이터로 클릭해 보는 미리보기 · 설치·로그인 불필요</span>
|
|
167
|
+
</div>
|
|
156
168
|
</div>
|
|
157
169
|
|
|
158
170
|
<div class="carousel" id="dash-carousel" role="group" aria-roledescription="캐러셀" aria-label="대시보드 화면 미리보기" tabindex="0">
|
|
@@ -276,19 +288,20 @@
|
|
|
276
288
|
<details class="acc" open>
|
|
277
289
|
<summary><span class="track__tag">추천 · 앱에서 한 문장</span> 내 AI 앱에서 빈 폴더 잡고 한 문장</summary>
|
|
278
290
|
<div class="acc__body">
|
|
279
|
-
<p class="track-desc"><strong>Claude 데스크톱의 “Code” 탭</strong>처럼 폴더를 잡고 작동하는 AI 앱이면 <strong>별도 터미널 없이</strong> 앱 안에서 끝납니다(Codex는 <strong>CLI</strong> 권장 — 데스크톱 앱은 등록이
|
|
291
|
+
<p class="track-desc"><strong>Claude 데스크톱의 “Code” 탭</strong>처럼 폴더를 잡고 작동하는 AI 앱이면 <strong>별도 터미널 없이</strong> 앱 안에서 끝납니다(Codex는 <strong>CLI</strong> 권장 — 데스크톱 앱은 등록이 사라질 수 있습니다). 작업 폴더 하나를 정하고 아래 문장만 주면, 에이전트가 공개 안내(<code>careermate.life/llms-install.txt</code>)를 읽고 <strong>그 폴더 안에</strong> 설치·연결합니다. 데이터까지 그 폴더에 모여(<code>.cm/data</code>) 백업·이동이 폴더 하나로 끝.</p>
|
|
280
292
|
<ol class="steps">
|
|
281
293
|
<li class="step">
|
|
282
294
|
<div class="step__no">1</div>
|
|
283
295
|
<div class="step__body">
|
|
284
296
|
<h3>앱 열고 빈 폴더 선택</h3>
|
|
285
|
-
<p><strong>Claude 데스크톱</strong> → <strong>Code</strong> 탭에서 빈 폴더를 작업 폴더로 선택(<strong>Pro 이상</strong> 구독, <strong>Windows는 Git 먼저</strong>). <strong>Codex</strong>는 빈 폴더에서 <code>codex</code>(CLI, <strong>ChatGPT Plus 이상</strong>)로 실행하세요 — <strong>데스크톱 앱은
|
|
297
|
+
<p><strong>Claude 데스크톱</strong> → <strong>Code</strong> 탭에서 빈 폴더를 작업 폴더로 선택(<strong>Pro 이상</strong> 구독, <strong>Windows는 Git 먼저</strong>). <strong>Codex</strong>는 빈 폴더에서 <code>codex</code>(CLI, <strong>ChatGPT Plus 이상</strong>)로 실행하세요 — <strong>데스크톱 앱은 등록이 사라질 수 있어</strong> 권장하지 않습니다.</p>
|
|
286
298
|
</div>
|
|
287
299
|
</li>
|
|
288
300
|
<li class="step">
|
|
289
301
|
<div class="step__no">2</div>
|
|
290
302
|
<div class="step__body">
|
|
291
303
|
<h3>이 문장 붙여넣기</h3>
|
|
304
|
+
<p class="paste-note">💬 위에서 연 <strong>AI 앱의 대화창에</strong> 붙여넣으세요 — 터미널 명령이 아니에요. 이 문장은 공개 안내 페이지만 읽어 설치하며, <strong>당신의 이력서·개인정보는 외부로 올라가지 않아요.</strong></p>
|
|
292
305
|
<div class="code">
|
|
293
306
|
<button class="copy-btn" type="button" data-copy-target="code-prompt-agent">복사</button>
|
|
294
307
|
<pre id="code-prompt-agent">https://careermate.life/llms-install.txt 를 읽고, 그 안내대로 CareerMate를 이 폴더에 설치하고 연결해줘. 데이터도 이 폴더의 .cm/data 안에 저장하고, Node 설치처럼 시스템에 바꿀 게 있으면 실행 전에 먼저 알려줘. 설치가 끝나면 앱 재시작 방법과 이력서를 주는 법, 대시보드 주소(http://127.0.0.1:4319)도 알려줘.</pre>
|
|
@@ -300,7 +313,7 @@
|
|
|
300
313
|
<div class="step__no">3</div>
|
|
301
314
|
<div class="step__body">
|
|
302
315
|
<h3>재시작 후 확인</h3>
|
|
303
|
-
<p>AI 앱을 완전히 종료했다 다시 켜고(처음 한 번 승인을 물으면 허용), <strong
|
|
316
|
+
<p>AI 앱을 완전히 종료했다 다시 켜고(처음 한 번 승인을 물으면 허용), <strong>“커리어메이트 연결됐는지 확인해줘”</strong>라고 말해 보세요. Codex는 <code>/mcp</code>로도 확인됩니다.</p>
|
|
304
317
|
</div>
|
|
305
318
|
</li>
|
|
306
319
|
</ol>
|
|
@@ -329,7 +342,7 @@
|
|
|
329
342
|
<div class="step__no">2</div>
|
|
330
343
|
<div class="step__body">
|
|
331
344
|
<h3>AI 앱 재시작 후 확인</h3>
|
|
332
|
-
<p>연결한 AI 앱을 <strong>완전히 종료했다 다시 켜고</strong>, <strong
|
|
345
|
+
<p>연결한 AI 앱을 <strong>완전히 종료했다 다시 켜고</strong>, <strong>“커리어메이트 연결됐는지 확인해줘”</strong>라고 말해 결과가 돌아오면 정상입니다.</p>
|
|
333
346
|
</div>
|
|
334
347
|
</li>
|
|
335
348
|
<li class="step">
|
|
@@ -347,7 +360,7 @@
|
|
|
347
360
|
<details class="acc">
|
|
348
361
|
<summary><span class="track__tag">Claude Desktop · <code>.mcpb</code></span> 설치 파일로 추가 (터미널 없이)</summary>
|
|
349
362
|
<div class="acc__body">
|
|
350
|
-
<p class="track-desc">터미널·Node 없이 파일 하나로 끝나지만, <strong>Claude Desktop 내장 Node 버전에 따라 불안정할 수
|
|
363
|
+
<p class="track-desc">터미널·Node 없이 파일 하나로 끝나지만, <strong>Claude Desktop 내장 Node 버전에 따라 불안정할 수 있습니다.</strong> 잘 안 되면 위 <strong>에이전트가 직접 설치</strong> 또는 <strong>터미널 한 줄</strong>을 쓰세요.</p>
|
|
351
364
|
<ol class="steps">
|
|
352
365
|
<li class="step">
|
|
353
366
|
<div class="step__no">1</div>
|
|
@@ -372,7 +385,7 @@
|
|
|
372
385
|
<div class="step__no">3</div>
|
|
373
386
|
<div class="step__body">
|
|
374
387
|
<h3>재시작하고 확인</h3>
|
|
375
|
-
<p>Claude Desktop을 완전히 종료했다 다시 켜고, <strong
|
|
388
|
+
<p>Claude Desktop을 완전히 종료했다 다시 켜고, <strong>“커리어메이트 연결됐는지 확인해줘”</strong>라고 말해 보세요.</p>
|
|
376
389
|
</div>
|
|
377
390
|
</li>
|
|
378
391
|
</ol>
|
|
@@ -436,7 +449,7 @@
|
|
|
436
449
|
</div>
|
|
437
450
|
<div class="privacy-card__text">
|
|
438
451
|
<h2>당신의 데이터는 당신 컴퓨터를 떠나지 않습니다</h2>
|
|
439
|
-
<p>대시보드 서버는 <code>127.0.0.1</code>(이 컴퓨터)에만 바인딩되어 외부에서 접근할 수
|
|
452
|
+
<p>대시보드 서버는 <code>127.0.0.1</code>(이 컴퓨터)에만 바인딩되어 외부에서 접근할 수 없습니다.<br />MCP 서버가 외부로 내보내는 것은 (끌 수 있는) <strong>최신 버전 확인</strong>뿐이며, <strong>당신의 커리어 데이터는 전송하지 않습니다.</strong> 분석·글쓰기는 당신이 직접 고른 AI가 수행합니다.</p>
|
|
440
453
|
<ul class="privacy-card__list">
|
|
441
454
|
<li><strong>저장 위치</strong> <code>~/.careermate/careermate.sqlite</code></li>
|
|
442
455
|
<li><strong>내보내기</strong> 자기소개서 등을 <code>~/.careermate/exports</code>로</li>
|
|
@@ -460,42 +473,10 @@
|
|
|
460
473
|
|
|
461
474
|
<div class="sr-only" role="status" aria-live="polite" id="copy-status"></div>
|
|
462
475
|
|
|
476
|
+
<script src="landing.js"></script>
|
|
463
477
|
<script>
|
|
464
478
|
(function () {
|
|
465
479
|
'use strict';
|
|
466
|
-
var status = document.getElementById('copy-status');
|
|
467
|
-
|
|
468
|
-
// --- generic clipboard helper ------------------------------------
|
|
469
|
-
function legacyCopy(text) {
|
|
470
|
-
var ta = document.createElement('textarea');
|
|
471
|
-
ta.value = text; ta.setAttribute('readonly', '');
|
|
472
|
-
ta.style.position = 'absolute'; ta.style.left = '-9999px';
|
|
473
|
-
document.body.appendChild(ta); ta.select();
|
|
474
|
-
var ok = false;
|
|
475
|
-
try { ok = document.execCommand('copy'); } catch (e) { ok = false; }
|
|
476
|
-
document.body.removeChild(ta);
|
|
477
|
-
return ok;
|
|
478
|
-
}
|
|
479
|
-
function copyText(text, onok) {
|
|
480
|
-
if (navigator.clipboard && navigator.clipboard.writeText) {
|
|
481
|
-
navigator.clipboard.writeText(text).then(onok, function () { if (legacyCopy(text)) onok(); });
|
|
482
|
-
} else if (legacyCopy(text)) { onok(); }
|
|
483
|
-
}
|
|
484
|
-
function announce(msg) { if (status) status.textContent = msg; }
|
|
485
|
-
|
|
486
|
-
// --- copy buttons (code blocks) ----------------------------------
|
|
487
|
-
function flashSmall(btn) {
|
|
488
|
-
var original = btn.textContent;
|
|
489
|
-
btn.textContent = '복사됨'; btn.classList.add('copied');
|
|
490
|
-
announce('클립보드에 복사되었습니다.');
|
|
491
|
-
window.setTimeout(function () { btn.textContent = original; btn.classList.remove('copied'); }, 1600);
|
|
492
|
-
}
|
|
493
|
-
document.querySelectorAll('.copy-btn').forEach(function (btn) {
|
|
494
|
-
btn.addEventListener('click', function () {
|
|
495
|
-
var src = document.getElementById(btn.getAttribute('data-copy-target'));
|
|
496
|
-
if (src) copyText(src.textContent || '', function () { flashSmall(btn); });
|
|
497
|
-
});
|
|
498
|
-
});
|
|
499
480
|
|
|
500
481
|
// --- config tabs -------------------------------------------------
|
|
501
482
|
var tablist = document.querySelector('.tabs[role="tablist"]');
|
|
@@ -540,26 +521,6 @@
|
|
|
540
521
|
revealEls.forEach(function (el) { io.observe(el); });
|
|
541
522
|
}
|
|
542
523
|
|
|
543
|
-
// --- theme toggle (persist) --------------------------------------
|
|
544
|
-
var root = document.documentElement;
|
|
545
|
-
var toggle = document.getElementById('theme-toggle');
|
|
546
|
-
var saved = null;
|
|
547
|
-
try { saved = window.localStorage.getItem('cf-theme'); } catch (e) {}
|
|
548
|
-
if (saved === 'dark' || saved === 'light') root.setAttribute('data-theme', saved);
|
|
549
|
-
function isDark() {
|
|
550
|
-
var t = root.getAttribute('data-theme');
|
|
551
|
-
if (t === 'dark') return true;
|
|
552
|
-
if (t === 'light') return false;
|
|
553
|
-
return window.matchMedia && window.matchMedia('(prefers-color-scheme: dark)').matches;
|
|
554
|
-
}
|
|
555
|
-
if (toggle) {
|
|
556
|
-
toggle.addEventListener('click', function () {
|
|
557
|
-
var next = isDark() ? 'light' : 'dark';
|
|
558
|
-
root.setAttribute('data-theme', next);
|
|
559
|
-
try { window.localStorage.setItem('cf-theme', next); } catch (e) {}
|
|
560
|
-
});
|
|
561
|
-
}
|
|
562
|
-
|
|
563
524
|
// --- dashboard carousel (prev/next + dots + keyboard + swipe) -----
|
|
564
525
|
var carousel = document.getElementById('dash-carousel');
|
|
565
526
|
var track = document.getElementById('carousel-track');
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
// Shared behavior for the CareerMate landing pages (index.html, start.html).
|
|
2
|
+
// Loaded after the DOM is parsed; wires the clipboard "copy" buttons and the theme toggle.
|
|
3
|
+
// NOTE: the pre-paint theme resolution stays INLINE in each page's <head> to avoid a flash (FOUC) --
|
|
4
|
+
// do not move that into this file.
|
|
5
|
+
(function () {
|
|
6
|
+
'use strict';
|
|
7
|
+
var status = document.getElementById('copy-status');
|
|
8
|
+
|
|
9
|
+
// --- clipboard ---------------------------------------------------
|
|
10
|
+
function legacyCopy(text) {
|
|
11
|
+
var ta = document.createElement('textarea');
|
|
12
|
+
ta.value = text; ta.setAttribute('readonly', '');
|
|
13
|
+
ta.style.position = 'absolute'; ta.style.left = '-9999px';
|
|
14
|
+
document.body.appendChild(ta); ta.select();
|
|
15
|
+
var ok = false;
|
|
16
|
+
try { ok = document.execCommand('copy'); } catch (e) { ok = false; }
|
|
17
|
+
document.body.removeChild(ta);
|
|
18
|
+
return ok;
|
|
19
|
+
}
|
|
20
|
+
function copyText(text, onok) {
|
|
21
|
+
if (navigator.clipboard && navigator.clipboard.writeText) {
|
|
22
|
+
navigator.clipboard.writeText(text).then(onok, function () { if (legacyCopy(text)) onok(); });
|
|
23
|
+
} else if (legacyCopy(text)) { onok(); }
|
|
24
|
+
}
|
|
25
|
+
document.querySelectorAll('.copy-btn').forEach(function (btn) {
|
|
26
|
+
btn.addEventListener('click', function () {
|
|
27
|
+
var src = document.getElementById(btn.getAttribute('data-copy-target'));
|
|
28
|
+
if (!src) return;
|
|
29
|
+
copyText(src.textContent || '', function () {
|
|
30
|
+
var original = btn.textContent;
|
|
31
|
+
btn.textContent = '복사됨'; btn.classList.add('copied');
|
|
32
|
+
if (status) status.textContent = '클립보드에 복사되었습니다.';
|
|
33
|
+
window.setTimeout(function () { btn.textContent = original; btn.classList.remove('copied'); }, 1600);
|
|
34
|
+
});
|
|
35
|
+
});
|
|
36
|
+
});
|
|
37
|
+
|
|
38
|
+
// --- theme toggle (persist) --------------------------------------
|
|
39
|
+
var root = document.documentElement;
|
|
40
|
+
var toggle = document.getElementById('theme-toggle');
|
|
41
|
+
function isDark() {
|
|
42
|
+
var t = root.getAttribute('data-theme');
|
|
43
|
+
if (t === 'dark') return true;
|
|
44
|
+
if (t === 'light') return false;
|
|
45
|
+
return window.matchMedia && window.matchMedia('(prefers-color-scheme: dark)').matches;
|
|
46
|
+
}
|
|
47
|
+
if (toggle) {
|
|
48
|
+
toggle.addEventListener('click', function () {
|
|
49
|
+
var next = isDark() ? 'light' : 'dark';
|
|
50
|
+
root.setAttribute('data-theme', next);
|
|
51
|
+
try { window.localStorage.setItem('careermate-theme', next); window.localStorage.removeItem('cf-theme'); } catch (e) {}
|
|
52
|
+
});
|
|
53
|
+
}
|
|
54
|
+
})();
|
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
<script>
|
|
7
7
|
(function () {
|
|
8
8
|
try {
|
|
9
|
-
var t = window.localStorage.getItem('cf-theme');
|
|
9
|
+
var t = window.localStorage.getItem('careermate-theme') || window.localStorage.getItem('cf-theme');
|
|
10
10
|
document.documentElement.setAttribute('data-theme', t === 'light' || t === 'dark' ? t : 'dark');
|
|
11
11
|
} catch (e) { document.documentElement.setAttribute('data-theme', 'dark'); }
|
|
12
12
|
})();
|
|
@@ -129,13 +129,15 @@
|
|
|
129
129
|
</div></li>
|
|
130
130
|
<li class="step"><div class="step__no">4</div><div class="step__body">
|
|
131
131
|
<h3>이 문장 한 번 붙여넣기</h3>
|
|
132
|
+
<p class="paste-note">💬 Code 탭의 <strong>대화창에</strong> 붙여넣으세요 — 터미널 명령이 아니에요. 이 문장은 공개 안내 페이지만 읽어 설치하며, <strong>당신의 이력서·개인정보는 외부로 올라가지 않아요.</strong></p>
|
|
132
133
|
<div class="code"><button class="copy-btn" type="button" data-copy-target="p-claude">복사</button>
|
|
133
134
|
<pre id="p-claude">https://careermate.life/llms-install.txt 를 읽고, 그 안내대로 CareerMate를 이 폴더에 설치하고 연결해줘. 데이터도 이 폴더의 .cm/data 안에 저장하고, Node 설치처럼 시스템에 바꿀 게 있으면 실행 전에 먼저 알려줘. 설치가 끝나면 앱 재시작 방법과 이력서를 주는 법, 대시보드 주소(http://127.0.0.1:4319)도 알려줘.</pre></div>
|
|
134
135
|
<p class="step__tip"><strong>Node가 없어도 됩니다.</strong> 필요하면 Claude가 먼저 확인하고 설치까지 도와줍니다.<br />직접 받으려면 아래 <strong>'필요한 프로그램 받기'</strong>의 Node.js를 보세요. 설치 중 뜨는 허용 창은 눌러 주세요.</p>
|
|
135
136
|
</div></li>
|
|
136
137
|
<li class="step"><div class="step__no">5</div><div class="step__body">
|
|
137
138
|
<h3>앱 재시작 → 확인</h3>
|
|
138
|
-
<p>Claude 앱을 완전히 껐다 켜고(처음 한 번 MCP
|
|
139
|
+
<p>Claude 앱을 완전히 껐다 켜고(처음 한 번 MCP 승인 허용), <strong>"커리어메이트 연결됐는지 확인해줘"</strong>라고 말하면 끝.</p>
|
|
140
|
+
<p class="recover"><strong>도구가 안 보이면?</strong> 앱을 트레이까지 <strong>완전히 종료</strong>했다 다시 켜고, 처음 뜬 승인 창을 허용했는지 확인하세요. 그래도 안 되면 <a href="index.html#install">파일로 설치(.mcpb)</a>나 설치 전체의 <a href="index.html#install">문제가 생겼을 때</a>를 보세요.</p>
|
|
139
141
|
</div></li>
|
|
140
142
|
</ol>
|
|
141
143
|
<div class="filenote">📎 <strong>이력서 넣는 법:</strong> 가장 쉬운 방법은 <strong>이력서 내용을 대화창에 붙여넣기</strong>입니다. 또는 작업 폴더에 파일을 넣고 <em>"이력서.pdf 읽어서 등록해줘"</em>라고 하거나 채팅에 직접 첨부하세요. (스캔본·보안 PDF는 안 읽힐 수 있습니다 → 그땐 텍스트로 붙여넣으세요.)</div>
|
|
@@ -163,13 +165,15 @@
|
|
|
163
165
|
</div></li>
|
|
164
166
|
<li class="step"><div class="step__no">3</div><div class="step__body">
|
|
165
167
|
<h3>빈 폴더에서 codex 실행 → 이 문장</h3>
|
|
168
|
+
<p class="paste-note">💬 실행한 <strong>codex 안에</strong> 붙여넣으세요 — AI에게 보내는 메시지예요(쉘 명령이 아님). 공개 안내만 읽어 설치하며, <strong>당신의 데이터는 외부로 올라가지 않아요.</strong></p>
|
|
166
169
|
<div class="code"><button class="copy-btn" type="button" data-copy-target="p-codex">복사</button>
|
|
167
170
|
<pre id="p-codex">https://careermate.life/llms-install.txt 를 읽고, 그 안내대로 CareerMate를 이 폴더에 설치하고 연결해줘. 데이터도 이 폴더의 .cm/data 안에 저장하고, Node 설치처럼 시스템에 바꿀 게 있으면 실행 전에 먼저 알려줘. 설치가 끝나면 앱 재시작 방법과 이력서를 주는 법, 대시보드 주소(http://127.0.0.1:4319)도 알려줘.</pre></div>
|
|
168
171
|
<p class="step__tip">설치 중 <strong>네트워크 허용</strong>을 물으면 한 번 허용하세요(npm 다운로드 때문).</p>
|
|
169
172
|
</div></li>
|
|
170
173
|
<li class="step"><div class="step__no">4</div><div class="step__body">
|
|
171
174
|
<h3>확인</h3>
|
|
172
|
-
<p>Codex 안에서 <code>/mcp</code>를 입력해 <code>careermate</code>가 보이면
|
|
175
|
+
<p>Codex 안에서 <code>/mcp</code>를 입력해 <code>careermate</code>가 보이면 연결 성공.</p>
|
|
176
|
+
<p class="recover"><strong>안 보이면?</strong> <code>node --version</code>이 v22.5 이상인지, Codex를 껐다 켰는지 확인하세요. 그래도 안 되면 설치 전체의 <a href="index.html#install">문제가 생겼을 때</a>를 참고하세요.</p>
|
|
173
177
|
</div></li>
|
|
174
178
|
</ol>
|
|
175
179
|
<div class="filenote">📎 <strong>이력서 넣는 법:</strong> 첨부 기능이 없으니, 작업 폴더에 파일을 넣고 <em>"./이력서.pdf 읽어서 등록해줘"</em>라고 하세요. PDF가 안 읽히면 내용을 <strong>텍스트로 붙여넣으세요.</strong></div>
|
|
@@ -183,7 +187,7 @@
|
|
|
183
187
|
|
|
184
188
|
<div class="subcard">
|
|
185
189
|
<strong>① 1순위 — Claude 데스크톱 + 파일 설치(터미널 없이)</strong>
|
|
186
|
-
<p class="hint" style="margin:.3rem 0 .8rem">Claude 무료 계정이면 됩니다. 터미널·Node 없이 파일 하나로
|
|
190
|
+
<p class="hint" style="margin:.3rem 0 .8rem">Claude 무료 계정이면 됩니다. 터미널·Node 없이 파일 하나로 끝.</p>
|
|
187
191
|
<ol class="steps">
|
|
188
192
|
<li class="step"><div class="step__no">1</div><div class="step__body">
|
|
189
193
|
<h3>Claude 데스크톱 설치 → 로그인(무료 OK)</h3>
|
|
@@ -199,11 +203,11 @@
|
|
|
199
203
|
</div></li>
|
|
200
204
|
<li class="step"><div class="step__no">4</div><div class="step__body">
|
|
201
205
|
<h3>재시작 → 확인</h3>
|
|
202
|
-
<p>앱을 껐다 켜고 <strong>"커리어메이트 연결됐는지 확인해줘"</strong
|
|
206
|
+
<p>앱을 껐다 켜고 <strong>"커리어메이트 연결됐는지 확인해줘"</strong>. 도구가 보이면 끝.</p>
|
|
203
207
|
</div></li>
|
|
204
208
|
</ol>
|
|
205
209
|
<div class="filenote">📎 <strong>이력서 넣는 법:</strong> Claude 채팅창에 파일을 <strong>직접 첨부</strong>하면 됩니다(가장 쉬움).</div>
|
|
206
|
-
<p class="hint" style="margin-top:.7rem">⚠️
|
|
210
|
+
<p class="hint" style="margin-top:.7rem">⚠️ <strong>도구가 안 뜨면</strong>(Claude 내장 Node 버전 문제일 수 있습니다) → 아래 ②를 쓰세요.</p>
|
|
207
211
|
</div>
|
|
208
212
|
|
|
209
213
|
<div class="subcard">
|
|
@@ -216,12 +220,14 @@
|
|
|
216
220
|
</div></li>
|
|
217
221
|
<li class="step"><div class="step__no">2</div><div class="step__body">
|
|
218
222
|
<h3>빈 폴더 열고 → 이 문장</h3>
|
|
223
|
+
<p class="paste-note">💬 Antigravity의 <strong>대화창에</strong> 붙여넣으세요 — 터미널 명령이 아니에요. 공개 안내만 읽어 설치하며, <strong>당신의 데이터는 외부로 올라가지 않아요.</strong></p>
|
|
219
224
|
<div class="code"><button class="copy-btn" type="button" data-copy-target="p-anti">복사</button>
|
|
220
225
|
<pre id="p-anti">https://careermate.life/llms-install.txt 를 읽고, 그 안내대로 CareerMate를 이 폴더에 설치하고 연결해줘. 데이터도 이 폴더의 .cm/data 안에 저장하고, Node 설치처럼 시스템에 바꿀 게 있으면 실행 전에 먼저 알려줘. 설치가 끝나면 앱 재시작 방법과 이력서를 주는 법, 대시보드 주소(http://127.0.0.1:4319)도 알려줘.</pre></div>
|
|
221
226
|
</div></li>
|
|
222
227
|
<li class="step"><div class="step__no">3</div><div class="step__body">
|
|
223
228
|
<h3>확인</h3>
|
|
224
229
|
<p>연결 상태를 확인하고(보통 <code>/mcp</code> 또는 "연결됐는지 확인해줘") 끝.</p>
|
|
230
|
+
<p class="recover"><strong>안 보이면?</strong> 앱을 완전히 껐다 켜고 다시 시도하세요. 막히면 설치 전체의 <a href="index.html#install">문제가 생겼을 때</a>를 보세요.</p>
|
|
225
231
|
</div></li>
|
|
226
232
|
</ol>
|
|
227
233
|
<div class="filenote">📎 <strong>이력서 넣는 법:</strong> 작업 폴더에 파일을 넣고 파일명으로 지시. 안 읽히면 텍스트로 붙여넣기.</div>
|
|
@@ -275,39 +281,10 @@
|
|
|
275
281
|
|
|
276
282
|
<div class="sr-only" role="status" aria-live="polite" id="copy-status"></div>
|
|
277
283
|
|
|
284
|
+
<script src="landing.js"></script>
|
|
278
285
|
<script>
|
|
279
286
|
(function () {
|
|
280
287
|
'use strict';
|
|
281
|
-
var status = document.getElementById('copy-status');
|
|
282
|
-
// --- clipboard ---
|
|
283
|
-
function legacyCopy(text) {
|
|
284
|
-
var ta = document.createElement('textarea');
|
|
285
|
-
ta.value = text; ta.setAttribute('readonly', ''); ta.style.position = 'absolute'; ta.style.left = '-9999px';
|
|
286
|
-
document.body.appendChild(ta); ta.select();
|
|
287
|
-
var ok = false; try { ok = document.execCommand('copy'); } catch (e) { ok = false; }
|
|
288
|
-
document.body.removeChild(ta); return ok;
|
|
289
|
-
}
|
|
290
|
-
function copyText(text, onok) {
|
|
291
|
-
if (navigator.clipboard && navigator.clipboard.writeText) {
|
|
292
|
-
navigator.clipboard.writeText(text).then(onok, function () { if (legacyCopy(text)) onok(); });
|
|
293
|
-
} else if (legacyCopy(text)) { onok(); }
|
|
294
|
-
}
|
|
295
|
-
document.querySelectorAll('.copy-btn').forEach(function (btn) {
|
|
296
|
-
btn.addEventListener('click', function () {
|
|
297
|
-
var src = document.getElementById(btn.getAttribute('data-copy-target'));
|
|
298
|
-
if (!src) return;
|
|
299
|
-
copyText(src.textContent || '', function () {
|
|
300
|
-
var o = btn.textContent; btn.textContent = '복사됨'; btn.classList.add('copied');
|
|
301
|
-
if (status) status.textContent = '클립보드에 복사되었습니다.';
|
|
302
|
-
window.setTimeout(function () { btn.textContent = o; btn.classList.remove('copied'); }, 1600);
|
|
303
|
-
});
|
|
304
|
-
});
|
|
305
|
-
});
|
|
306
|
-
|
|
307
|
-
// --- theme toggle ---
|
|
308
|
-
var root = document.documentElement, toggle = document.getElementById('theme-toggle');
|
|
309
|
-
function isDark() { var t = root.getAttribute('data-theme'); if (t === 'dark') return true; if (t === 'light') return false; return window.matchMedia && window.matchMedia('(prefers-color-scheme: dark)').matches; }
|
|
310
|
-
if (toggle) toggle.addEventListener('click', function () { var n = isDark() ? 'light' : 'dark'; root.setAttribute('data-theme', n); try { window.localStorage.setItem('cf-theme', n); } catch (e) {} });
|
|
311
288
|
|
|
312
289
|
// --- wizard ---
|
|
313
290
|
var result = document.getElementById('result');
|