@haema/cli 0.8.1
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 +258 -0
- package/dist/auth.js +30 -0
- package/dist/auth.js.map +1 -0
- package/dist/discoverClaudeFiles.js +132 -0
- package/dist/discoverClaudeFiles.js.map +1 -0
- package/dist/index.js +29 -0
- package/dist/index.js.map +1 -0
- package/dist/mcp/install.js +353 -0
- package/dist/mcp/install.js.map +1 -0
- package/dist/mcp/mcpClient.js +55 -0
- package/dist/mcp/mcpClient.js.map +1 -0
- package/dist/mcp/resolveProjectId.js +27 -0
- package/dist/mcp/resolveProjectId.js.map +1 -0
- package/dist/mcp/server.js +344 -0
- package/dist/mcp/server.js.map +1 -0
- package/dist/mcp/tools/addTask.js +15 -0
- package/dist/mcp/tools/addTask.js.map +1 -0
- package/dist/mcp/tools/applyHooks.js +110 -0
- package/dist/mcp/tools/applyHooks.js.map +1 -0
- package/dist/mcp/tools/brief.js +166 -0
- package/dist/mcp/tools/brief.js.map +1 -0
- package/dist/mcp/tools/createFolder.js +11 -0
- package/dist/mcp/tools/createFolder.js.map +1 -0
- package/dist/mcp/tools/finishTask.js +16 -0
- package/dist/mcp/tools/finishTask.js.map +1 -0
- package/dist/mcp/tools/getTask.js +31 -0
- package/dist/mcp/tools/getTask.js.map +1 -0
- package/dist/mcp/tools/listTasks.js +27 -0
- package/dist/mcp/tools/listTasks.js.map +1 -0
- package/dist/mcp/tools/loadSkill.js +8 -0
- package/dist/mcp/tools/loadSkill.js.map +1 -0
- package/dist/mcp/tools/logSession.js +13 -0
- package/dist/mcp/tools/logSession.js.map +1 -0
- package/dist/mcp/tools/recall.js +23 -0
- package/dist/mcp/tools/recall.js.map +1 -0
- package/dist/mcp/tools/signin.js +111 -0
- package/dist/mcp/tools/signin.js.map +1 -0
- package/dist/mcp/tools/signout.js +11 -0
- package/dist/mcp/tools/signout.js.map +1 -0
- package/dist/mcp/tools/startTask.js +21 -0
- package/dist/mcp/tools/startTask.js.map +1 -0
- package/dist/mcp/tools/updateTask.js +9 -0
- package/dist/mcp/tools/updateTask.js.map +1 -0
- package/dist/mcp/tools/uploadPrompt.js +32 -0
- package/dist/mcp/tools/uploadPrompt.js.map +1 -0
- package/dist/mcp/tools/whoami.js +13 -0
- package/dist/mcp/tools/whoami.js.map +1 -0
- package/dist/openBrowser.js +15 -0
- package/dist/openBrowser.js.map +1 -0
- package/dist/readClaudeFile.js +16 -0
- package/dist/readClaudeFile.js.map +1 -0
- package/dist/scanLimits.js +15 -0
- package/dist/scanLimits.js.map +1 -0
- package/package.json +36 -0
|
@@ -0,0 +1,166 @@
|
|
|
1
|
+
import { execSync } from "node:child_process";
|
|
2
|
+
import { mcpGet } from "../mcpClient.js";
|
|
3
|
+
export async function handleBrief(projectId, config) {
|
|
4
|
+
const data = await mcpGet(config, "/api/memory/brief", { projectId });
|
|
5
|
+
if (!data.ok)
|
|
6
|
+
throw new Error(data.error);
|
|
7
|
+
const b = data.brief;
|
|
8
|
+
const commits = b.cwd ? getRecentCommits(b.cwd) : [];
|
|
9
|
+
const lines = [];
|
|
10
|
+
// 폴더 id → name 맵 (add_task 시 참조용)
|
|
11
|
+
const folderMap = new Map((b.folders ?? []).map((f) => [f.id, f.name]));
|
|
12
|
+
// 최근 작업 흐름: AI 요약 + 완료 태스크 + 커밋 → Claude가 bullet 3개로 합성
|
|
13
|
+
const flowContext = [];
|
|
14
|
+
if (b.aiSummary?.summary) {
|
|
15
|
+
flowContext.push(`프로젝트 AI 요약: ${b.aiSummary.summary}`);
|
|
16
|
+
}
|
|
17
|
+
const recentDoneForFlow = b.recentlyDone.slice(0, 3);
|
|
18
|
+
if (recentDoneForFlow.length > 0) {
|
|
19
|
+
flowContext.push("최근 완료 태스크: " + recentDoneForFlow.map((t) => t.title).join(", "));
|
|
20
|
+
}
|
|
21
|
+
if (commits.length > 0) {
|
|
22
|
+
flowContext.push("최근 커밋: " + commits.map((c) => c.replace(/^[a-f0-9]+ /, "")).join(" / "));
|
|
23
|
+
}
|
|
24
|
+
if (flowContext.length > 0) {
|
|
25
|
+
lines.push(`[다음 정보를 바탕으로 "최근 작업 흐름:" bullet 3개를 작성하세요]`);
|
|
26
|
+
lines.push(...flowContext);
|
|
27
|
+
lines.push("");
|
|
28
|
+
}
|
|
29
|
+
// 프로젝트 상태 요약
|
|
30
|
+
const statusCtx = [];
|
|
31
|
+
const recentDone = b.recentlyDone.slice(0, 3);
|
|
32
|
+
if (recentDone.length > 0) {
|
|
33
|
+
statusCtx.push(`최근 완료: ${recentDone.map((t) => t.title).join(", ")}`);
|
|
34
|
+
const withDecisions = recentDone.filter((t) => t.keyDecisions.length > 0);
|
|
35
|
+
for (const t of withDecisions) {
|
|
36
|
+
statusCtx.push(` #${t.seq} 핵심 결정: ${t.keyDecisions.join(" / ")}`);
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
if (b.aiSummary?.warnings?.length) {
|
|
40
|
+
statusCtx.push(`주의: ${b.aiSummary.warnings.join(", ")}`);
|
|
41
|
+
}
|
|
42
|
+
const activeFolders = (b.folders ?? []).filter((f) => f.taskCount > 0);
|
|
43
|
+
if (activeFolders.length > 0) {
|
|
44
|
+
statusCtx.push(`폴더: ${activeFolders.map((f) => `${f.name}(${f.taskCount}개)`).join(", ")}`);
|
|
45
|
+
}
|
|
46
|
+
lines.push(`[아래 태스크 정보를 바탕으로 현재 프로젝트 상태를 2~3줄 bullet으로 요약하세요 (각 줄 "- " 로 시작)]`);
|
|
47
|
+
lines.push(...statusCtx);
|
|
48
|
+
lines.push("");
|
|
49
|
+
// 진행 중·대기 태스크 목록 (에이전트가 현재 상태 파악용)
|
|
50
|
+
if (b.inProgressTasks.length > 0) {
|
|
51
|
+
lines.push(`진행 중인 태스크:`);
|
|
52
|
+
for (const t of b.inProgressTasks) {
|
|
53
|
+
const folder = t.folderId ? folderMap.get(t.folderId) : null;
|
|
54
|
+
lines.push(`- #${t.seq} ${t.title}${t.module ? ` [${t.module}]` : ""}${folder ? ` (${folder})` : ""}`);
|
|
55
|
+
}
|
|
56
|
+
lines.push("");
|
|
57
|
+
}
|
|
58
|
+
if (b.pendingTasks.length > 0) {
|
|
59
|
+
lines.push(`대기 중인 태스크:`);
|
|
60
|
+
for (const t of b.pendingTasks) {
|
|
61
|
+
const folder = t.folderId ? folderMap.get(t.folderId) : null;
|
|
62
|
+
lines.push(`- #${t.seq} ${t.title}${t.module ? ` [${t.module}]` : ""}${folder ? ` (${folder})` : ""}`);
|
|
63
|
+
}
|
|
64
|
+
lines.push("");
|
|
65
|
+
}
|
|
66
|
+
// 폴더 목록 (add_task 시 folderId 참조용)
|
|
67
|
+
if (activeFolders.length > 0) {
|
|
68
|
+
lines.push(`폴더 목록 (add_task 시 folderId 사용):`);
|
|
69
|
+
for (const f of activeFolders) {
|
|
70
|
+
lines.push(`- ${f.name} (id: ${f.id}, 태스크 ${f.taskCount}개)`);
|
|
71
|
+
}
|
|
72
|
+
lines.push("");
|
|
73
|
+
}
|
|
74
|
+
lines.push(`추천 태스크:`);
|
|
75
|
+
// DB AI 추천 최대 3개 먼저 출력
|
|
76
|
+
const aiRecs = b.recommendedNextTasks ?? [];
|
|
77
|
+
let recNum = 1;
|
|
78
|
+
for (const rec of aiRecs.slice(0, 3)) {
|
|
79
|
+
lines.push(`${recNum}) ${rec.title}${rec.reason ? ` — ${rec.reason}` : ""}`);
|
|
80
|
+
recNum++;
|
|
81
|
+
}
|
|
82
|
+
// DB 추천이 3개 미만이면 대기 태스크·커밋 컨텍스트로 나머지 채우도록 지시
|
|
83
|
+
if (recNum <= 3) {
|
|
84
|
+
const recContext = [];
|
|
85
|
+
if (b.pendingTasks.length > 0) {
|
|
86
|
+
recContext.push("대기 중인 태스크: " + b.pendingTasks.slice(0, 5).map((t) => `#${t.seq} ${t.title}`).join(", "));
|
|
87
|
+
}
|
|
88
|
+
if (recentDone.length > 0) {
|
|
89
|
+
recContext.push("최근 완료 태스크: " + recentDone.map((t) => t.title).join(", "));
|
|
90
|
+
}
|
|
91
|
+
if (commits.length > 0) {
|
|
92
|
+
recContext.push("최근 커밋: " + commits.map((c) => c.replace(/^[a-f0-9]+ /, "")).join(" / "));
|
|
93
|
+
}
|
|
94
|
+
if (recContext.length > 0) {
|
|
95
|
+
lines.push(`[위 정보를 바탕으로 ${recNum})~3) 추천 태스크를 "N) 태스크명" 형식으로 각 한 줄씩 추가하세요]`);
|
|
96
|
+
lines.push(...recContext);
|
|
97
|
+
}
|
|
98
|
+
else if (recNum === 1) {
|
|
99
|
+
lines.push("등록된 태스크나 이전 작업이 없어요. 하려는 작업을 말씀해주세요.");
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
// AI 프로젝트 맥락 (성장형 plain text 기억)
|
|
103
|
+
if (b.memoryContext) {
|
|
104
|
+
lines.push(`\nAI 프로젝트 맥락 (자기학습 기억):\n${b.memoryContext}`);
|
|
105
|
+
}
|
|
106
|
+
// 장기 기억 (LONG_TERM) 태스크
|
|
107
|
+
if (b.longTermTasks && b.longTermTasks.length > 0) {
|
|
108
|
+
lines.push(`\n장기 기억 (영구 보존):`);
|
|
109
|
+
for (const t of b.longTermTasks) {
|
|
110
|
+
const ago = t.lastAccessedAt ? daysAgo(t.lastAccessedAt) : null;
|
|
111
|
+
lines.push(`- #${t.seq} ${t.title}${ago !== null ? ` [${ago}일 전 접근]` : ""}`);
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
// 최근 AI 메모리 인사이트
|
|
115
|
+
if (b.latestReflection) {
|
|
116
|
+
const r = b.latestReflection;
|
|
117
|
+
if (r.contextSummary || (r.insights && r.insights.length > 0)) {
|
|
118
|
+
lines.push(`\nAI 메모리 분석:`);
|
|
119
|
+
if (r.contextSummary)
|
|
120
|
+
lines.push(`프로젝트 맥락: ${r.contextSummary}`);
|
|
121
|
+
for (const ins of (r.insights ?? []).slice(0, 3)) {
|
|
122
|
+
const label = ins.type === "pattern" ? "패턴" : ins.type === "risk" ? "위험" : "인사이트";
|
|
123
|
+
lines.push(`- [${label}] ${ins.text}`);
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
// 프로젝트 스킬 (folder별 그룹핑)
|
|
128
|
+
if (b.customSkills && b.customSkills.length > 0) {
|
|
129
|
+
const byFolder = new Map();
|
|
130
|
+
for (const s of b.customSkills) {
|
|
131
|
+
const arr = byFolder.get(s.folder) ?? [];
|
|
132
|
+
arr.push(s);
|
|
133
|
+
byFolder.set(s.folder, arr);
|
|
134
|
+
}
|
|
135
|
+
lines.push(`\n프로젝트 커스텀 스킬 (load_skill로 로드):`);
|
|
136
|
+
for (const [folder, skills] of byFolder) {
|
|
137
|
+
lines.push(`[${folder}]`);
|
|
138
|
+
for (const s of skills) {
|
|
139
|
+
lines.push(`- ${s.slug}: ${s.name} — ${s.contextHint}`);
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
// 스킬 제안 (패턴 감지됨)
|
|
144
|
+
if (b.skillSuggestions && b.skillSuggestions.length > 0) {
|
|
145
|
+
lines.push(`\n💡 스킬 제안 (반복 패턴 감지됨):`);
|
|
146
|
+
for (const s of b.skillSuggestions) {
|
|
147
|
+
lines.push(`- "${s.name}": ${s.description} [폴더: ${s.folder}]`);
|
|
148
|
+
lines.push(` 근거: ${s.patternSummary}`);
|
|
149
|
+
lines.push(` → propose_skill(name="${s.name}", folder="${s.folder}", ...)로 등록하세요.`);
|
|
150
|
+
}
|
|
151
|
+
}
|
|
152
|
+
return lines.join("\n");
|
|
153
|
+
}
|
|
154
|
+
function daysAgo(isoDate) {
|
|
155
|
+
return Math.floor((Date.now() - new Date(isoDate).getTime()) / (1000 * 60 * 60 * 24));
|
|
156
|
+
}
|
|
157
|
+
function getRecentCommits(cwd) {
|
|
158
|
+
try {
|
|
159
|
+
const out = execSync("git log --oneline --no-merges -10", { cwd, encoding: "utf8", timeout: 3000 });
|
|
160
|
+
return out.trim().split("\n").filter(Boolean);
|
|
161
|
+
}
|
|
162
|
+
catch {
|
|
163
|
+
return [];
|
|
164
|
+
}
|
|
165
|
+
}
|
|
166
|
+
//# sourceMappingURL=brief.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"brief.js","sourceRoot":"","sources":["../../../src/mcp/tools/brief.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,oBAAoB,CAAC;AAG9C,OAAO,EAAE,MAAM,EAAE,MAAM,iBAAiB,CAAC;AAkCzC,MAAM,CAAC,KAAK,UAAU,WAAW,CAAC,SAAiB,EAAE,MAAiB;IACpE,MAAM,IAAI,GAAG,MAAM,MAAM,CAAgB,MAAM,EAAE,mBAAmB,EAAE,EAAE,SAAS,EAAE,CAAC,CAAC;IACrF,IAAI,CAAC,IAAI,CAAC,EAAE;QAAE,MAAM,IAAI,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;IAE1C,MAAM,CAAC,GAAG,IAAI,CAAC,KAAK,CAAC;IACrB,MAAM,OAAO,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,gBAAgB,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;IACrD,MAAM,KAAK,GAAa,EAAE,CAAC;IAE3B,kCAAkC;IAClC,MAAM,SAAS,GAAG,IAAI,GAAG,CAAC,CAAC,CAAC,CAAC,OAAO,IAAI,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAExE,wDAAwD;IACxD,MAAM,WAAW,GAAa,EAAE,CAAC;IACjC,IAAI,CAAC,CAAC,SAAS,EAAE,OAAO,EAAE,CAAC;QACzB,WAAW,CAAC,IAAI,CAAC,eAAe,CAAC,CAAC,SAAS,CAAC,OAAO,EAAE,CAAC,CAAC;IACzD,CAAC;IACD,MAAM,iBAAiB,GAAG,CAAC,CAAC,YAAY,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;IACrD,IAAI,iBAAiB,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QACjC,WAAW,CAAC,IAAI,CAAC,aAAa,GAAG,iBAAiB,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC;IACrF,CAAC;IACD,IAAI,OAAO,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QACvB,WAAW,CAAC,IAAI,CAAC,SAAS,GAAG,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,OAAO,CAAC,aAAa,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC;IAC7F,CAAC;IACD,IAAI,WAAW,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QAC3B,KAAK,CAAC,IAAI,CAAC,4CAA4C,CAAC,CAAC;QACzD,KAAK,CAAC,IAAI,CAAC,GAAG,WAAW,CAAC,CAAC;QAC3B,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;IACjB,CAAC;IAED,aAAa;IACb,MAAM,SAAS,GAAa,EAAE,CAAC;IAC/B,MAAM,UAAU,GAAG,CAAC,CAAC,YAAY,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;IAC9C,IAAI,UAAU,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QAC1B,SAAS,CAAC,IAAI,CAAC,UAAU,UAAU,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;QACtE,MAAM,aAAa,GAAG,UAAU,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,YAAY,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC;QAC1E,KAAK,MAAM,CAAC,IAAI,aAAa,EAAE,CAAC;YAC9B,SAAS,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,GAAG,WAAW,CAAC,CAAC,YAAY,CAAC,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC;QACrE,CAAC;IACH,CAAC;IACD,IAAI,CAAC,CAAC,SAAS,EAAE,QAAQ,EAAE,MAAM,EAAE,CAAC;QAClC,SAAS,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,SAAS,CAAC,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;IAC3D,CAAC;IACD,MAAM,aAAa,GAAG,CAAC,CAAC,CAAC,OAAO,IAAI,EAAE,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,SAAS,GAAG,CAAC,CAAC,CAAC;IACvE,IAAI,aAAa,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QAC7B,SAAS,CAAC,IAAI,CAAC,OAAO,aAAa,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,GAAG,CAAC,CAAC,IAAI,IAAI,CAAC,CAAC,SAAS,IAAI,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;IAC7F,CAAC;IACD,KAAK,CAAC,IAAI,CAAC,mEAAmE,CAAC,CAAC;IAChF,KAAK,CAAC,IAAI,CAAC,GAAG,SAAS,CAAC,CAAC;IACzB,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;IAEf,mCAAmC;IACnC,IAAI,CAAC,CAAC,eAAe,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QACjC,KAAK,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC;QACzB,KAAK,MAAM,CAAC,IAAI,CAAC,CAAC,eAAe,EAAE,CAAC;YAClC,MAAM,MAAM,GAAG,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,SAAS,CAAC,GAAG,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC;YAC7D,KAAK,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,GAAG,IAAI,CAAC,CAAC,KAAK,GAAG,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,EAAE,GAAG,MAAM,CAAC,CAAC,CAAC,KAAK,MAAM,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;QACzG,CAAC;QACD,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;IACjB,CAAC;IACD,IAAI,CAAC,CAAC,YAAY,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QAC9B,KAAK,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC;QACzB,KAAK,MAAM,CAAC,IAAI,CAAC,CAAC,YAAY,EAAE,CAAC;YAC/B,MAAM,MAAM,GAAG,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,SAAS,CAAC,GAAG,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC;YAC7D,KAAK,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,GAAG,IAAI,CAAC,CAAC,KAAK,GAAG,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,EAAE,GAAG,MAAM,CAAC,CAAC,CAAC,KAAK,MAAM,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;QACzG,CAAC;QACD,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;IACjB,CAAC;IAED,kCAAkC;IAClC,IAAI,aAAa,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QAC7B,KAAK,CAAC,IAAI,CAAC,iCAAiC,CAAC,CAAC;QAC9C,KAAK,MAAM,CAAC,IAAI,aAAa,EAAE,CAAC;YAC9B,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,IAAI,SAAS,CAAC,CAAC,EAAE,SAAS,CAAC,CAAC,SAAS,IAAI,CAAC,CAAC;QAC/D,CAAC;QACD,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;IACjB,CAAC;IAED,KAAK,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;IAEtB,uBAAuB;IACvB,MAAM,MAAM,GAAG,CAAC,CAAC,oBAAoB,IAAI,EAAE,CAAC;IAC5C,IAAI,MAAM,GAAG,CAAC,CAAC;IACf,KAAK,MAAM,GAAG,IAAI,MAAM,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC;QACrC,KAAK,CAAC,IAAI,CAAC,GAAG,MAAM,KAAK,GAAG,CAAC,KAAK,GAAG,GAAG,CAAC,MAAM,CAAC,CAAC,CAAC,MAAM,GAAG,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;QAC7E,MAAM,EAAE,CAAC;IACX,CAAC;IAED,6CAA6C;IAC7C,IAAI,MAAM,IAAI,CAAC,EAAE,CAAC;QAChB,MAAM,UAAU,GAAa,EAAE,CAAC;QAChC,IAAI,CAAC,CAAC,YAAY,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YAC9B,UAAU,CAAC,IAAI,CAAC,aAAa,GAAG,CAAC,CAAC,YAAY,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,IAAI,CAAC,CAAC,GAAG,IAAI,CAAC,CAAC,KAAK,EAAE,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC;QAC5G,CAAC;QACD,IAAI,UAAU,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YAC1B,UAAU,CAAC,IAAI,CAAC,aAAa,GAAG,UAAU,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC;QAC7E,CAAC;QACD,IAAI,OAAO,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YACvB,UAAU,CAAC,IAAI,CAAC,SAAS,GAAG,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,OAAO,CAAC,aAAa,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC;QAC5F,CAAC;QACD,IAAI,UAAU,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YAC1B,KAAK,CAAC,IAAI,CAAC,eAAe,MAAM,2CAA2C,CAAC,CAAC;YAC7E,KAAK,CAAC,IAAI,CAAC,GAAG,UAAU,CAAC,CAAC;QAC5B,CAAC;aAAM,IAAI,MAAM,KAAK,CAAC,EAAE,CAAC;YACxB,KAAK,CAAC,IAAI,CAAC,sCAAsC,CAAC,CAAC;QACrD,CAAC;IACH,CAAC;IAED,iCAAiC;IACjC,IAAI,CAAC,CAAC,aAAa,EAAE,CAAC;QACpB,KAAK,CAAC,IAAI,CAAC,4BAA4B,CAAC,CAAC,aAAa,EAAE,CAAC,CAAC;IAC5D,CAAC;IAED,wBAAwB;IACxB,IAAI,CAAC,CAAC,aAAa,IAAI,CAAC,CAAC,aAAa,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QAClD,KAAK,CAAC,IAAI,CAAC,kBAAkB,CAAC,CAAC;QAC/B,KAAK,MAAM,CAAC,IAAI,CAAC,CAAC,aAAa,EAAE,CAAC;YAChC,MAAM,GAAG,GAAG,CAAC,CAAC,cAAc,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,cAAc,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC;YAChE,KAAK,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,GAAG,IAAI,CAAC,CAAC,KAAK,GAAG,GAAG,KAAK,IAAI,CAAC,CAAC,CAAC,KAAK,GAAG,SAAS,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;QAC/E,CAAC;IACH,CAAC;IAED,iBAAiB;IACjB,IAAI,CAAC,CAAC,gBAAgB,EAAE,CAAC;QACvB,MAAM,CAAC,GAAG,CAAC,CAAC,gBAAgB,CAAC;QAC7B,IAAI,CAAC,CAAC,cAAc,IAAI,CAAC,CAAC,CAAC,QAAQ,IAAI,CAAC,CAAC,QAAQ,CAAC,MAAM,GAAG,CAAC,CAAC,EAAE,CAAC;YAC9D,KAAK,CAAC,IAAI,CAAC,cAAc,CAAC,CAAC;YAC3B,IAAI,CAAC,CAAC,cAAc;gBAAE,KAAK,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC,cAAc,EAAE,CAAC,CAAC;YACjE,KAAK,MAAM,GAAG,IAAI,CAAC,CAAC,CAAC,QAAQ,IAAI,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC;gBACjD,MAAM,KAAK,GAAG,GAAG,CAAC,IAAI,KAAK,SAAS,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,GAAG,CAAC,IAAI,KAAK,MAAM,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,MAAM,CAAC;gBAClF,KAAK,CAAC,IAAI,CAAC,MAAM,KAAK,KAAK,GAAG,CAAC,IAAI,EAAE,CAAC,CAAC;YACzC,CAAC;QACH,CAAC;IACH,CAAC;IAED,wBAAwB;IACxB,IAAI,CAAC,CAAC,YAAY,IAAI,CAAC,CAAC,YAAY,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QAChD,MAAM,QAAQ,GAAG,IAAI,GAAG,EAAyB,CAAC;QAClD,KAAK,MAAM,CAAC,IAAI,CAAC,CAAC,YAAY,EAAE,CAAC;YAC/B,MAAM,GAAG,GAAG,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC,MAAM,CAAC,IAAI,EAAE,CAAC;YACzC,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;YACZ,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;QAC9B,CAAC;QACD,KAAK,CAAC,IAAI,CAAC,iCAAiC,CAAC,CAAC;QAC9C,KAAK,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,IAAI,QAAQ,EAAE,CAAC;YACxC,KAAK,CAAC,IAAI,CAAC,IAAI,MAAM,GAAG,CAAC,CAAC;YAC1B,KAAK,MAAM,CAAC,IAAI,MAAM,EAAE,CAAC;gBACvB,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,IAAI,KAAK,CAAC,CAAC,IAAI,MAAM,CAAC,CAAC,WAAW,EAAE,CAAC,CAAC;YAC1D,CAAC;QACH,CAAC;IACH,CAAC;IAED,iBAAiB;IACjB,IAAI,CAAC,CAAC,gBAAgB,IAAI,CAAC,CAAC,gBAAgB,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QACxD,KAAK,CAAC,IAAI,CAAC,yBAAyB,CAAC,CAAC;QACtC,KAAK,MAAM,CAAC,IAAI,CAAC,CAAC,gBAAgB,EAAE,CAAC;YACnC,KAAK,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,IAAI,MAAM,CAAC,CAAC,WAAW,SAAS,CAAC,CAAC,MAAM,GAAG,CAAC,CAAC;YAChE,KAAK,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC,cAAc,EAAE,CAAC,CAAC;YACxC,KAAK,CAAC,IAAI,CAAC,2BAA2B,CAAC,CAAC,IAAI,cAAc,CAAC,CAAC,MAAM,iBAAiB,CAAC,CAAC;QACvF,CAAC;IACH,CAAC;IAED,OAAO,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;AAC1B,CAAC;AAED,SAAS,OAAO,CAAC,OAAe;IAC9B,OAAO,IAAI,CAAC,KAAK,CAAC,CAAC,IAAI,CAAC,GAAG,EAAE,GAAG,IAAI,IAAI,CAAC,OAAO,CAAC,CAAC,OAAO,EAAE,CAAC,GAAG,CAAC,IAAI,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,CAAC,CAAC,CAAC;AACxF,CAAC;AAED,SAAS,gBAAgB,CAAC,GAAW;IACnC,IAAI,CAAC;QACH,MAAM,GAAG,GAAG,QAAQ,CAAC,mCAAmC,EAAE,EAAE,GAAG,EAAE,QAAQ,EAAE,MAAM,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC,CAAC;QACpG,OAAO,GAAG,CAAC,IAAI,EAAE,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC;IAChD,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,EAAE,CAAC;IACZ,CAAC;AACH,CAAC"}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { mcpPost } from "../mcpClient.js";
|
|
2
|
+
export async function handleCreateFolder(args, projectId, config) {
|
|
3
|
+
const data = await mcpPost(config, "/api/memory/folders", {
|
|
4
|
+
projectId,
|
|
5
|
+
name: args.name,
|
|
6
|
+
});
|
|
7
|
+
if (!data.ok)
|
|
8
|
+
throw new Error(data.error);
|
|
9
|
+
return `폴더 생성됨: "${data.folder.name}" (id: ${data.folder.id})`;
|
|
10
|
+
}
|
|
11
|
+
//# sourceMappingURL=createFolder.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"createFolder.js","sourceRoot":"","sources":["../../../src/mcp/tools/createFolder.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,OAAO,EAAE,MAAM,iBAAiB,CAAC;AAM1C,MAAM,CAAC,KAAK,UAAU,kBAAkB,CACtC,IAAsB,EACtB,SAAiB,EACjB,MAAiB;IAEjB,MAAM,IAAI,GAAG,MAAM,OAAO,CAAuB,MAAM,EAAE,qBAAqB,EAAE;QAC9E,SAAS;QACT,IAAI,EAAE,IAAI,CAAC,IAAI;KAChB,CAAC,CAAC;IACH,IAAI,CAAC,IAAI,CAAC,EAAE;QAAE,MAAM,IAAI,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;IAC1C,OAAO,YAAY,IAAI,CAAC,MAAM,CAAC,IAAI,UAAU,IAAI,CAAC,MAAM,CAAC,EAAE,GAAG,CAAC;AACjE,CAAC"}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { mcpPost } from "../mcpClient.js";
|
|
2
|
+
export async function handleFinishTask(args, projectId, config) {
|
|
3
|
+
const data = await mcpPost(config, `/api/memory/tasks/${args.taskSeq}/finish`, {
|
|
4
|
+
projectId,
|
|
5
|
+
summary: args.summary,
|
|
6
|
+
aiTool: args.aiTool,
|
|
7
|
+
keyDecisions: args.keyDecisions,
|
|
8
|
+
outcome: args.outcome,
|
|
9
|
+
});
|
|
10
|
+
if (!data.ok)
|
|
11
|
+
throw new Error(data.error);
|
|
12
|
+
const decisionsNote = args.keyDecisions?.length ? ` 핵심 결정 ${args.keyDecisions.length}개 저장됨.` : "";
|
|
13
|
+
const outcomeNote = args.outcome ? " outcome 저장됨." : "";
|
|
14
|
+
return `태스크 완료: #${data.task.seq} "${data.task.title}" → DONE${decisionsNote}${outcomeNote}`;
|
|
15
|
+
}
|
|
16
|
+
//# sourceMappingURL=finishTask.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"finishTask.js","sourceRoot":"","sources":["../../../src/mcp/tools/finishTask.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,OAAO,EAAE,MAAM,iBAAiB,CAAC;AAM1C,MAAM,CAAC,KAAK,UAAU,gBAAgB,CACpC,IAAsG,EACtG,SAAiB,EACjB,MAAiB;IAEjB,MAAM,IAAI,GAAG,MAAM,OAAO,CAAqB,MAAM,EAAE,qBAAqB,IAAI,CAAC,OAAO,SAAS,EAAE;QACjG,SAAS;QACT,OAAO,EAAE,IAAI,CAAC,OAAO;QACrB,MAAM,EAAE,IAAI,CAAC,MAAM;QACnB,YAAY,EAAE,IAAI,CAAC,YAAY;QAC/B,OAAO,EAAE,IAAI,CAAC,OAAO;KACtB,CAAC,CAAC;IACH,IAAI,CAAC,IAAI,CAAC,EAAE;QAAE,MAAM,IAAI,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;IAC1C,MAAM,aAAa,GAAG,IAAI,CAAC,YAAY,EAAE,MAAM,CAAC,CAAC,CAAC,UAAU,IAAI,CAAC,YAAY,CAAC,MAAM,QAAQ,CAAC,CAAC,CAAC,EAAE,CAAC;IAClG,MAAM,WAAW,GAAG,IAAI,CAAC,OAAO,CAAC,CAAC,CAAC,eAAe,CAAC,CAAC,CAAC,EAAE,CAAC;IACxD,OAAO,YAAY,IAAI,CAAC,IAAI,CAAC,GAAG,KAAK,IAAI,CAAC,IAAI,CAAC,KAAK,WAAW,aAAa,GAAG,WAAW,EAAE,CAAC;AAC/F,CAAC"}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import { mcpGet } from "../mcpClient.js";
|
|
2
|
+
const STATUS_LABEL = {
|
|
3
|
+
PENDING: "대기",
|
|
4
|
+
IN_PROGRESS: "진행 중",
|
|
5
|
+
DONE: "완료",
|
|
6
|
+
CANCELLED: "취소됨",
|
|
7
|
+
};
|
|
8
|
+
export async function handleGetTask(args, projectId, config) {
|
|
9
|
+
const data = await mcpGet(config, `/api/memory/tasks/${args.taskSeq}`, { projectId });
|
|
10
|
+
if (!data.ok)
|
|
11
|
+
throw new Error(data.error);
|
|
12
|
+
const t = data.task;
|
|
13
|
+
const lines = [
|
|
14
|
+
`#${t.seq} ${t.title}`,
|
|
15
|
+
`상태: ${STATUS_LABEL[t.status] ?? t.status}`,
|
|
16
|
+
];
|
|
17
|
+
if (t.module)
|
|
18
|
+
lines.push(`모듈: ${t.module}`);
|
|
19
|
+
if (t.priority)
|
|
20
|
+
lines.push(`우선순위: ${t.priority}`);
|
|
21
|
+
if (t.folderId)
|
|
22
|
+
lines.push(`폴더: ${t.folderId}`);
|
|
23
|
+
if (t.description)
|
|
24
|
+
lines.push(`\n설명:\n${t.description}`);
|
|
25
|
+
if (t.outcome)
|
|
26
|
+
lines.push(`\n결과:\n${t.outcome}`);
|
|
27
|
+
if (t.keyDecisions.length > 0)
|
|
28
|
+
lines.push(`\n핵심 결정:\n${t.keyDecisions.map((d) => `- ${d}`).join("\n")}`);
|
|
29
|
+
return lines.join("\n");
|
|
30
|
+
}
|
|
31
|
+
//# sourceMappingURL=getTask.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"getTask.js","sourceRoot":"","sources":["../../../src/mcp/tools/getTask.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,MAAM,EAAE,MAAM,iBAAiB,CAAC;AAkBzC,MAAM,YAAY,GAA2B;IAC3C,OAAO,EAAE,IAAI;IACb,WAAW,EAAE,MAAM;IACnB,IAAI,EAAE,IAAI;IACV,SAAS,EAAE,KAAK;CACjB,CAAC;AAEF,MAAM,CAAC,KAAK,UAAU,aAAa,CACjC,IAAyB,EACzB,SAAiB,EACjB,MAAiB;IAEjB,MAAM,IAAI,GAAG,MAAM,MAAM,CAAc,MAAM,EAAE,qBAAqB,IAAI,CAAC,OAAO,EAAE,EAAE,EAAE,SAAS,EAAE,CAAC,CAAC;IACnG,IAAI,CAAC,IAAI,CAAC,EAAE;QAAE,MAAM,IAAI,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;IAE1C,MAAM,CAAC,GAAG,IAAI,CAAC,IAAI,CAAC;IACpB,MAAM,KAAK,GAAa;QACtB,IAAI,CAAC,CAAC,GAAG,IAAI,CAAC,CAAC,KAAK,EAAE;QACtB,OAAO,YAAY,CAAC,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,MAAM,EAAE;KAC5C,CAAC;IACF,IAAI,CAAC,CAAC,MAAM;QAAE,KAAK,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,MAAM,EAAE,CAAC,CAAC;IAC5C,IAAI,CAAC,CAAC,QAAQ;QAAE,KAAK,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC,QAAQ,EAAE,CAAC,CAAC;IAClD,IAAI,CAAC,CAAC,QAAQ;QAAE,KAAK,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,QAAQ,EAAE,CAAC,CAAC;IAChD,IAAI,CAAC,CAAC,WAAW;QAAE,KAAK,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC,WAAW,EAAE,CAAC,CAAC;IACzD,IAAI,CAAC,CAAC,OAAO;QAAE,KAAK,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC,OAAO,EAAE,CAAC,CAAC;IACjD,IAAI,CAAC,CAAC,YAAY,CAAC,MAAM,GAAG,CAAC;QAAE,KAAK,CAAC,IAAI,CAAC,aAAa,CAAC,CAAC,YAAY,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;IAEzG,OAAO,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;AAC1B,CAAC"}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import { mcpGet } from "../mcpClient.js";
|
|
2
|
+
const STATUS_EMOJI = {
|
|
3
|
+
PENDING: "📋",
|
|
4
|
+
IN_PROGRESS: "🔄",
|
|
5
|
+
DONE: "✅",
|
|
6
|
+
CANCELLED: "❌",
|
|
7
|
+
};
|
|
8
|
+
export async function handleListTasks(args, projectId, config) {
|
|
9
|
+
const params = { projectId };
|
|
10
|
+
if (args.status)
|
|
11
|
+
params.status = args.status;
|
|
12
|
+
if (args.module)
|
|
13
|
+
params.module = args.module;
|
|
14
|
+
const data = await mcpGet(config, "/api/memory/tasks", params);
|
|
15
|
+
if (!data.ok)
|
|
16
|
+
throw new Error(data.error);
|
|
17
|
+
if (data.tasks.length === 0)
|
|
18
|
+
return "태스크가 없어요.";
|
|
19
|
+
const lines = data.tasks.map((t) => {
|
|
20
|
+
const emoji = STATUS_EMOJI[t.status] ?? "•";
|
|
21
|
+
const mod = t.module ? ` [${t.module}]` : "";
|
|
22
|
+
const desc = t.description ? `\n ${t.description}` : "";
|
|
23
|
+
return `${emoji} #${t.seq} ${t.title}${mod} (priority: ${t.priority})${desc}`;
|
|
24
|
+
});
|
|
25
|
+
return `태스크 목록 (${data.tasks.length}개):\n\n${lines.join("\n")}`;
|
|
26
|
+
}
|
|
27
|
+
//# sourceMappingURL=listTasks.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"listTasks.js","sourceRoot":"","sources":["../../../src/mcp/tools/listTasks.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,MAAM,EAAE,MAAM,iBAAiB,CAAC;AAazC,MAAM,YAAY,GAA2B;IAC3C,OAAO,EAAE,IAAI;IACb,WAAW,EAAE,IAAI;IACjB,IAAI,EAAE,GAAG;IACT,SAAS,EAAE,GAAG;CACf,CAAC;AAEF,MAAM,CAAC,KAAK,UAAU,eAAe,CACnC,IAA0C,EAC1C,SAAiB,EACjB,MAAiB;IAEjB,MAAM,MAAM,GAA2B,EAAE,SAAS,EAAE,CAAC;IACrD,IAAI,IAAI,CAAC,MAAM;QAAE,MAAM,CAAC,MAAM,GAAG,IAAI,CAAC,MAAM,CAAC;IAC7C,IAAI,IAAI,CAAC,MAAM;QAAE,MAAM,CAAC,MAAM,GAAG,IAAI,CAAC,MAAM,CAAC;IAE7C,MAAM,IAAI,GAAG,MAAM,MAAM,CAAe,MAAM,EAAE,mBAAmB,EAAE,MAAM,CAAC,CAAC;IAC7E,IAAI,CAAC,IAAI,CAAC,EAAE;QAAE,MAAM,IAAI,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;IAE1C,IAAI,IAAI,CAAC,KAAK,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,WAAW,CAAC;IAEhD,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE;QACjC,MAAM,KAAK,GAAG,YAAY,CAAC,CAAC,CAAC,MAAM,CAAC,IAAI,GAAG,CAAC;QAC5C,MAAM,GAAG,GAAG,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC;QAC7C,MAAM,IAAI,GAAG,CAAC,CAAC,WAAW,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,WAAW,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;QAC1D,OAAO,GAAG,KAAK,KAAK,CAAC,CAAC,GAAG,IAAI,CAAC,CAAC,KAAK,GAAG,GAAG,eAAe,CAAC,CAAC,QAAQ,IAAI,IAAI,EAAE,CAAC;IAChF,CAAC,CAAC,CAAC;IAEH,OAAO,WAAW,IAAI,CAAC,KAAK,CAAC,MAAM,UAAU,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC;AAClE,CAAC"}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import { mcpGet } from "../mcpClient.js";
|
|
2
|
+
export async function handleLoadSkill(args, projectId, config) {
|
|
3
|
+
const data = await mcpGet(config, `/api/skills/${args.slug}`, { projectId });
|
|
4
|
+
if (!data.ok)
|
|
5
|
+
throw new Error(data.error);
|
|
6
|
+
return `# Skill: ${data.name}\n> ${data.contextHint}\n\n${data.content}`;
|
|
7
|
+
}
|
|
8
|
+
//# sourceMappingURL=loadSkill.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"loadSkill.js","sourceRoot":"","sources":["../../../src/mcp/tools/loadSkill.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,MAAM,EAAE,MAAM,iBAAiB,CAAC;AAMzC,MAAM,CAAC,KAAK,UAAU,eAAe,CACnC,IAAsB,EACtB,SAAiB,EACjB,MAAiB;IAEjB,MAAM,IAAI,GAAG,MAAM,MAAM,CAAgB,MAAM,EAAE,eAAe,IAAI,CAAC,IAAI,EAAE,EAAE,EAAE,SAAS,EAAE,CAAC,CAAC;IAC5F,IAAI,CAAC,IAAI,CAAC,EAAE;QAAE,MAAM,IAAI,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;IAC1C,OAAO,YAAY,IAAI,CAAC,IAAI,OAAO,IAAI,CAAC,WAAW,OAAO,IAAI,CAAC,OAAO,EAAE,CAAC;AAC3E,CAAC"}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { mcpPost } from "../mcpClient.js";
|
|
2
|
+
export async function handleLogSession(args, projectId, config, sessionId) {
|
|
3
|
+
const data = await mcpPost(config, "/api/memory/sessions", {
|
|
4
|
+
projectId,
|
|
5
|
+
summary: args.summary,
|
|
6
|
+
aiTool: args.aiTool ?? "unknown",
|
|
7
|
+
sessionId,
|
|
8
|
+
});
|
|
9
|
+
if (!data.ok)
|
|
10
|
+
throw new Error(data.error);
|
|
11
|
+
return `세션 로그 저장됐어요 (id: ${data.sessionLog.id})`;
|
|
12
|
+
}
|
|
13
|
+
//# sourceMappingURL=logSession.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"logSession.js","sourceRoot":"","sources":["../../../src/mcp/tools/logSession.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,OAAO,EAAE,MAAM,iBAAiB,CAAC;AAI1C,MAAM,CAAC,KAAK,UAAU,gBAAgB,CACpC,IAA0C,EAC1C,SAAiB,EACjB,MAAiB,EACjB,SAAkB;IAElB,MAAM,IAAI,GAAG,MAAM,OAAO,CAAqB,MAAM,EAAE,sBAAsB,EAAE;QAC7E,SAAS;QACT,OAAO,EAAE,IAAI,CAAC,OAAO;QACrB,MAAM,EAAE,IAAI,CAAC,MAAM,IAAI,SAAS;QAChC,SAAS;KACV,CAAC,CAAC;IACH,IAAI,CAAC,IAAI,CAAC,EAAE;QAAE,MAAM,IAAI,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;IAC1C,OAAO,oBAAoB,IAAI,CAAC,UAAU,CAAC,EAAE,GAAG,CAAC;AACnD,CAAC"}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import { mcpPost } from "../mcpClient.js";
|
|
2
|
+
export async function handleRecall(args, projectId, config) {
|
|
3
|
+
const data = await mcpPost(config, "/api/memory/thoughts/search", {
|
|
4
|
+
projectId,
|
|
5
|
+
query: args.query,
|
|
6
|
+
limit: args.limit ?? 10,
|
|
7
|
+
});
|
|
8
|
+
if (!data.ok)
|
|
9
|
+
throw new Error(data.error);
|
|
10
|
+
if (data.results.length === 0)
|
|
11
|
+
return "관련된 기억을 찾지 못했어요.";
|
|
12
|
+
const lines = data.results.map((r) => {
|
|
13
|
+
const date = new Date(r.doneAt ?? r.createdAt).toLocaleDateString("ko-KR");
|
|
14
|
+
const moduleTag = r.module ? ` [${r.module}]` : "";
|
|
15
|
+
const header = `#${r.seq} ${r.title}${moduleTag} (${date})`;
|
|
16
|
+
if (r.keyDecisions.length === 0)
|
|
17
|
+
return header;
|
|
18
|
+
const decisions = r.keyDecisions.map((d) => ` • ${d}`).join("\n");
|
|
19
|
+
return `${header}\n${decisions}`;
|
|
20
|
+
});
|
|
21
|
+
return `검색 결과 (${data.results.length}개):\n\n${lines.join("\n\n")}`;
|
|
22
|
+
}
|
|
23
|
+
//# sourceMappingURL=recall.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"recall.js","sourceRoot":"","sources":["../../../src/mcp/tools/recall.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,OAAO,EAAE,MAAM,iBAAiB,CAAC;AAa1C,MAAM,CAAC,KAAK,UAAU,YAAY,CAChC,IAAuC,EACvC,SAAiB,EACjB,MAAiB;IAEjB,MAAM,IAAI,GAAG,MAAM,OAAO,CAAiB,MAAM,EAAE,6BAA6B,EAAE;QAChF,SAAS;QACT,KAAK,EAAE,IAAI,CAAC,KAAK;QACjB,KAAK,EAAE,IAAI,CAAC,KAAK,IAAI,EAAE;KACxB,CAAC,CAAC;IACH,IAAI,CAAC,IAAI,CAAC,EAAE;QAAE,MAAM,IAAI,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;IAC1C,IAAI,IAAI,CAAC,OAAO,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,kBAAkB,CAAC;IAEzD,MAAM,KAAK,GAAG,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE;QACnC,MAAM,IAAI,GAAG,IAAI,IAAI,CAAC,CAAC,CAAC,MAAM,IAAI,CAAC,CAAC,SAAS,CAAC,CAAC,kBAAkB,CAAC,OAAO,CAAC,CAAC;QAC3E,MAAM,SAAS,GAAG,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC;QACnD,MAAM,MAAM,GAAG,IAAI,CAAC,CAAC,GAAG,IAAI,CAAC,CAAC,KAAK,GAAG,SAAS,KAAK,IAAI,GAAG,CAAC;QAC5D,IAAI,CAAC,CAAC,YAAY,CAAC,MAAM,KAAK,CAAC;YAAE,OAAO,MAAM,CAAC;QAC/C,MAAM,SAAS,GAAG,CAAC,CAAC,YAAY,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QACnE,OAAO,GAAG,MAAM,KAAK,SAAS,EAAE,CAAC;IACnC,CAAC,CAAC,CAAC;IAEH,OAAO,UAAU,IAAI,CAAC,OAAO,CAAC,MAAM,UAAU,KAAK,CAAC,IAAI,CAAC,MAAM,CAAC,EAAE,CAAC;AACrE,CAAC"}
|
|
@@ -0,0 +1,111 @@
|
|
|
1
|
+
import { randomBytes } from "node:crypto";
|
|
2
|
+
import { createServer } from "node:http";
|
|
3
|
+
import { authFilePath, writeAuth } from "../../auth.js";
|
|
4
|
+
import { openBrowser } from "../../openBrowser.js";
|
|
5
|
+
const DEFAULT_APP_URL = "https://haema.jocodingax.ai";
|
|
6
|
+
const PORT_RANGE_START = 5180;
|
|
7
|
+
const PORT_RANGE_END = 5189;
|
|
8
|
+
const TIMEOUT_MS = 120_000;
|
|
9
|
+
export async function handleSignin(args) {
|
|
10
|
+
const appUrl = stripTrailingSlash(args.appUrl ?? process.env.HAEMA_APP_URL ?? DEFAULT_APP_URL);
|
|
11
|
+
if (process.env.MOCK_AUTH === "true") {
|
|
12
|
+
await writeAuth({
|
|
13
|
+
appUrl,
|
|
14
|
+
apiKey: `haema_mock_${randomBytes(16).toString("hex")}`,
|
|
15
|
+
email: "dev@mock.local",
|
|
16
|
+
signedInAt: new Date().toISOString(),
|
|
17
|
+
});
|
|
18
|
+
return `🛠 Mock 로그인 완료 (MOCK_AUTH=true)\n자격증명 저장: ${authFilePath()}`;
|
|
19
|
+
}
|
|
20
|
+
const state = randomBytes(16).toString("hex");
|
|
21
|
+
const { port, server, resultPromise } = await startCallbackServer(state);
|
|
22
|
+
const callback = `http://127.0.0.1:${port}/callback`;
|
|
23
|
+
const signinUrl = `${appUrl}/cli/signin?callback=${encodeURIComponent(callback)}&state=${state}`;
|
|
24
|
+
openBrowser(signinUrl);
|
|
25
|
+
const timeoutPromise = new Promise((_, reject) => setTimeout(() => reject(new Error("TIMEOUT")), TIMEOUT_MS));
|
|
26
|
+
let result;
|
|
27
|
+
try {
|
|
28
|
+
result = await Promise.race([resultPromise, timeoutPromise]);
|
|
29
|
+
}
|
|
30
|
+
catch (e) {
|
|
31
|
+
server.close();
|
|
32
|
+
const msg = e instanceof Error ? e.message : String(e);
|
|
33
|
+
if (msg === "TIMEOUT") {
|
|
34
|
+
return `로그인 대기 시간이 초과됐어요. 아래 URL을 직접 브라우저에서 열고 다시 시도해주세요:\n${signinUrl}`;
|
|
35
|
+
}
|
|
36
|
+
throw e;
|
|
37
|
+
}
|
|
38
|
+
finally {
|
|
39
|
+
server.close();
|
|
40
|
+
}
|
|
41
|
+
await writeAuth({
|
|
42
|
+
appUrl,
|
|
43
|
+
apiKey: result.token,
|
|
44
|
+
email: result.email,
|
|
45
|
+
signedInAt: new Date().toISOString(),
|
|
46
|
+
});
|
|
47
|
+
const who = result.email ? ` (${result.email})` : "";
|
|
48
|
+
return `로그인 성공${who}\n자격증명 저장: ${authFilePath()}`;
|
|
49
|
+
}
|
|
50
|
+
function stripTrailingSlash(s) {
|
|
51
|
+
return s.endsWith("/") ? s.slice(0, -1) : s;
|
|
52
|
+
}
|
|
53
|
+
async function startCallbackServer(expectedState) {
|
|
54
|
+
let resolveResult;
|
|
55
|
+
let rejectResult;
|
|
56
|
+
const resultPromise = new Promise((res, rej) => {
|
|
57
|
+
resolveResult = res;
|
|
58
|
+
rejectResult = rej;
|
|
59
|
+
});
|
|
60
|
+
const server = createServer((req, res) => {
|
|
61
|
+
if (!req.url) {
|
|
62
|
+
res.statusCode = 400;
|
|
63
|
+
res.end();
|
|
64
|
+
return;
|
|
65
|
+
}
|
|
66
|
+
const u = new URL(req.url, "http://127.0.0.1");
|
|
67
|
+
if (u.pathname !== "/callback") {
|
|
68
|
+
res.statusCode = 404;
|
|
69
|
+
res.end();
|
|
70
|
+
return;
|
|
71
|
+
}
|
|
72
|
+
const token = u.searchParams.get("token");
|
|
73
|
+
const state = u.searchParams.get("state");
|
|
74
|
+
const email = u.searchParams.get("email") ?? undefined;
|
|
75
|
+
if (!token || state !== expectedState) {
|
|
76
|
+
res.statusCode = 400;
|
|
77
|
+
res.setHeader("content-type", "text/html; charset=utf-8");
|
|
78
|
+
res.end(htmlPage("로그인 실패", "유효하지 않은 응답이에요. 다시 시도해주세요."));
|
|
79
|
+
rejectResult(new Error("invalid callback"));
|
|
80
|
+
return;
|
|
81
|
+
}
|
|
82
|
+
res.setHeader("content-type", "text/html; charset=utf-8");
|
|
83
|
+
res.end(htmlPage("로그인 완료", "이 창은 닫아도 돼요."));
|
|
84
|
+
resolveResult({ token, email });
|
|
85
|
+
});
|
|
86
|
+
const port = await listenFirstAvailable(server);
|
|
87
|
+
return { port, server, resultPromise };
|
|
88
|
+
}
|
|
89
|
+
async function listenFirstAvailable(server) {
|
|
90
|
+
let lastErr;
|
|
91
|
+
for (let p = PORT_RANGE_START; p <= PORT_RANGE_END; p++) {
|
|
92
|
+
try {
|
|
93
|
+
await new Promise((resolve, reject) => {
|
|
94
|
+
server.once("error", (e) => { server.removeAllListeners("listening"); reject(e); });
|
|
95
|
+
server.once("listening", () => { server.removeAllListeners("error"); resolve(); });
|
|
96
|
+
server.listen(p, "127.0.0.1");
|
|
97
|
+
});
|
|
98
|
+
return p;
|
|
99
|
+
}
|
|
100
|
+
catch (e) {
|
|
101
|
+
lastErr = e instanceof Error ? e : new Error(String(e));
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
throw new Error(`사용 가능한 포트가 없어요 (${PORT_RANGE_START}-${PORT_RANGE_END}): ${lastErr?.message ?? ""}`);
|
|
105
|
+
}
|
|
106
|
+
function htmlPage(title, body) {
|
|
107
|
+
return `<!doctype html><html lang="ko"><head><meta charset="utf-8"><title>${title}</title>
|
|
108
|
+
<style>body{font-family:-apple-system,system-ui,sans-serif;display:grid;place-items:center;height:100vh;margin:0;background:#0a0a0a;color:#e5e5e5}div{text-align:center;max-width:420px;padding:24px}h1{margin:0 0 12px;font-weight:500;font-size:22px}p{color:#888;line-height:1.5;margin:0}</style>
|
|
109
|
+
</head><body><div><h1>${title}</h1><p>${body}</p></div></body></html>`;
|
|
110
|
+
}
|
|
111
|
+
//# sourceMappingURL=signin.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"signin.js","sourceRoot":"","sources":["../../../src/mcp/tools/signin.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAC1C,OAAO,EAAE,YAAY,EAAe,MAAM,WAAW,CAAC;AAEtD,OAAO,EAAE,YAAY,EAAE,SAAS,EAAE,MAAM,eAAe,CAAC;AACxD,OAAO,EAAE,WAAW,EAAE,MAAM,sBAAsB,CAAC;AAEnD,MAAM,eAAe,GAAG,6BAA6B,CAAC;AACtD,MAAM,gBAAgB,GAAG,IAAI,CAAC;AAC9B,MAAM,cAAc,GAAG,IAAI,CAAC;AAC5B,MAAM,UAAU,GAAG,OAAO,CAAC;AAI3B,MAAM,CAAC,KAAK,UAAU,YAAY,CAAC,IAAyB;IAC1D,MAAM,MAAM,GAAG,kBAAkB,CAAC,IAAI,CAAC,MAAM,IAAI,OAAO,CAAC,GAAG,CAAC,aAAa,IAAI,eAAe,CAAC,CAAC;IAE/F,IAAI,OAAO,CAAC,GAAG,CAAC,SAAS,KAAK,MAAM,EAAE,CAAC;QACrC,MAAM,SAAS,CAAC;YACd,MAAM;YACN,MAAM,EAAE,cAAc,WAAW,CAAC,EAAE,CAAC,CAAC,QAAQ,CAAC,KAAK,CAAC,EAAE;YACvD,KAAK,EAAE,gBAAgB;YACvB,UAAU,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE;SACrC,CAAC,CAAC;QACH,OAAO,6CAA6C,YAAY,EAAE,EAAE,CAAC;IACvE,CAAC;IAED,MAAM,KAAK,GAAG,WAAW,CAAC,EAAE,CAAC,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC;IAE9C,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,aAAa,EAAE,GAAG,MAAM,mBAAmB,CAAC,KAAK,CAAC,CAAC;IACzE,MAAM,QAAQ,GAAG,oBAAoB,IAAI,WAAW,CAAC;IACrD,MAAM,SAAS,GAAG,GAAG,MAAM,wBAAwB,kBAAkB,CAAC,QAAQ,CAAC,UAAU,KAAK,EAAE,CAAC;IAEjG,WAAW,CAAC,SAAS,CAAC,CAAC;IAEvB,MAAM,cAAc,GAAG,IAAI,OAAO,CAAQ,CAAC,CAAC,EAAE,MAAM,EAAE,EAAE,CACtD,UAAU,CAAC,GAAG,EAAE,CAAC,MAAM,CAAC,IAAI,KAAK,CAAC,SAAS,CAAC,CAAC,EAAE,UAAU,CAAC,CAC3D,CAAC;IAEF,IAAI,MAAsB,CAAC;IAC3B,IAAI,CAAC;QACH,MAAM,GAAG,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC,aAAa,EAAE,cAAc,CAAC,CAAC,CAAC;IAC/D,CAAC;IAAC,OAAO,CAAC,EAAE,CAAC;QACX,MAAM,CAAC,KAAK,EAAE,CAAC;QACf,MAAM,GAAG,GAAG,CAAC,YAAY,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC;QACvD,IAAI,GAAG,KAAK,SAAS,EAAE,CAAC;YACtB,OAAO,sDAAsD,SAAS,EAAE,CAAC;QAC3E,CAAC;QACD,MAAM,CAAC,CAAC;IACV,CAAC;YAAS,CAAC;QACT,MAAM,CAAC,KAAK,EAAE,CAAC;IACjB,CAAC;IAED,MAAM,SAAS,CAAC;QACd,MAAM;QACN,MAAM,EAAE,MAAM,CAAC,KAAK;QACpB,KAAK,EAAE,MAAM,CAAC,KAAK;QACnB,UAAU,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE;KACrC,CAAC,CAAC;IAEH,MAAM,GAAG,GAAG,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,KAAK,MAAM,CAAC,KAAK,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC;IACrD,OAAO,SAAS,GAAG,cAAc,YAAY,EAAE,EAAE,CAAC;AACpD,CAAC;AAED,SAAS,kBAAkB,CAAC,CAAS;IACnC,OAAO,CAAC,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;AAC9C,CAAC;AAED,KAAK,UAAU,mBAAmB,CAChC,aAAqB;IAErB,IAAI,aAA2C,CAAC;IAChD,IAAI,YAAiC,CAAC;IACtC,MAAM,aAAa,GAAG,IAAI,OAAO,CAAiB,CAAC,GAAG,EAAE,GAAG,EAAE,EAAE;QAC7D,aAAa,GAAG,GAAG,CAAC;QACpB,YAAY,GAAG,GAAG,CAAC;IACrB,CAAC,CAAC,CAAC;IAEH,MAAM,MAAM,GAAG,YAAY,CAAC,CAAC,GAAG,EAAE,GAAG,EAAE,EAAE;QACvC,IAAI,CAAC,GAAG,CAAC,GAAG,EAAE,CAAC;YAAC,GAAG,CAAC,UAAU,GAAG,GAAG,CAAC;YAAC,GAAG,CAAC,GAAG,EAAE,CAAC;YAAC,OAAO;QAAC,CAAC;QAC1D,MAAM,CAAC,GAAG,IAAI,GAAG,CAAC,GAAG,CAAC,GAAG,EAAE,kBAAkB,CAAC,CAAC;QAC/C,IAAI,CAAC,CAAC,QAAQ,KAAK,WAAW,EAAE,CAAC;YAAC,GAAG,CAAC,UAAU,GAAG,GAAG,CAAC;YAAC,GAAG,CAAC,GAAG,EAAE,CAAC;YAAC,OAAO;QAAC,CAAC;QAE5E,MAAM,KAAK,GAAG,CAAC,CAAC,YAAY,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC;QAC1C,MAAM,KAAK,GAAG,CAAC,CAAC,YAAY,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC;QAC1C,MAAM,KAAK,GAAG,CAAC,CAAC,YAAY,CAAC,GAAG,CAAC,OAAO,CAAC,IAAI,SAAS,CAAC;QAEvD,IAAI,CAAC,KAAK,IAAI,KAAK,KAAK,aAAa,EAAE,CAAC;YACtC,GAAG,CAAC,UAAU,GAAG,GAAG,CAAC;YACrB,GAAG,CAAC,SAAS,CAAC,cAAc,EAAE,0BAA0B,CAAC,CAAC;YAC1D,GAAG,CAAC,GAAG,CAAC,QAAQ,CAAC,QAAQ,EAAE,2BAA2B,CAAC,CAAC,CAAC;YACzD,YAAY,CAAC,IAAI,KAAK,CAAC,kBAAkB,CAAC,CAAC,CAAC;YAC5C,OAAO;QACT,CAAC;QACD,GAAG,CAAC,SAAS,CAAC,cAAc,EAAE,0BAA0B,CAAC,CAAC;QAC1D,GAAG,CAAC,GAAG,CAAC,QAAQ,CAAC,QAAQ,EAAE,cAAc,CAAC,CAAC,CAAC;QAC5C,aAAa,CAAC,EAAE,KAAK,EAAE,KAAK,EAAE,CAAC,CAAC;IAClC,CAAC,CAAC,CAAC;IAEH,MAAM,IAAI,GAAG,MAAM,oBAAoB,CAAC,MAAM,CAAC,CAAC;IAChD,OAAO,EAAE,IAAI,EAAE,MAAM,EAAE,aAAa,EAAE,CAAC;AACzC,CAAC;AAED,KAAK,UAAU,oBAAoB,CAAC,MAAc;IAChD,IAAI,OAA0B,CAAC;IAC/B,KAAK,IAAI,CAAC,GAAG,gBAAgB,EAAE,CAAC,IAAI,cAAc,EAAE,CAAC,EAAE,EAAE,CAAC;QACxD,IAAI,CAAC;YACH,MAAM,IAAI,OAAO,CAAO,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE;gBAC1C,MAAM,CAAC,IAAI,CAAC,OAAO,EAAE,CAAC,CAAC,EAAE,EAAE,GAAG,MAAM,CAAC,kBAAkB,CAAC,WAAW,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;gBACpF,MAAM,CAAC,IAAI,CAAC,WAAW,EAAE,GAAG,EAAE,GAAG,MAAM,CAAC,kBAAkB,CAAC,OAAO,CAAC,CAAC,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC;gBACnF,MAAM,CAAC,MAAM,CAAC,CAAC,EAAE,WAAW,CAAC,CAAC;YAChC,CAAC,CAAC,CAAC;YACH,OAAO,CAAC,CAAC;QACX,CAAC;QAAC,OAAO,CAAC,EAAE,CAAC;YACX,OAAO,GAAG,CAAC,YAAY,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC;QAC1D,CAAC;IACH,CAAC;IACD,MAAM,IAAI,KAAK,CAAC,mBAAmB,gBAAgB,IAAI,cAAc,MAAM,OAAO,EAAE,OAAO,IAAI,EAAE,EAAE,CAAC,CAAC;AACvG,CAAC;AAED,SAAS,QAAQ,CAAC,KAAa,EAAE,IAAY;IAC3C,OAAO,qEAAqE,KAAK;;wBAE3D,KAAK,WAAW,IAAI,0BAA0B,CAAC;AACvE,CAAC"}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { promises as fs } from "node:fs";
|
|
2
|
+
import { authFilePath, readAuth } from "../../auth.js";
|
|
3
|
+
export async function handleSignout() {
|
|
4
|
+
const auth = await readAuth();
|
|
5
|
+
if (!auth)
|
|
6
|
+
return "이미 로그아웃 상태예요.";
|
|
7
|
+
await fs.rm(authFilePath());
|
|
8
|
+
const who = auth.email ? ` (${auth.email})` : "";
|
|
9
|
+
return `로그아웃 완료${who}`;
|
|
10
|
+
}
|
|
11
|
+
//# sourceMappingURL=signout.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"signout.js","sourceRoot":"","sources":["../../../src/mcp/tools/signout.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,IAAI,EAAE,EAAE,MAAM,SAAS,CAAC;AAEzC,OAAO,EAAE,YAAY,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAC;AAEvD,MAAM,CAAC,KAAK,UAAU,aAAa;IACjC,MAAM,IAAI,GAAG,MAAM,QAAQ,EAAE,CAAC;IAC9B,IAAI,CAAC,IAAI;QAAE,OAAO,eAAe,CAAC;IAClC,MAAM,EAAE,CAAC,EAAE,CAAC,YAAY,EAAE,CAAC,CAAC;IAC5B,MAAM,GAAG,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,KAAK,IAAI,CAAC,KAAK,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC;IACjD,OAAO,UAAU,GAAG,EAAE,CAAC;AACzB,CAAC"}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import { mcpPost } from "../mcpClient.js";
|
|
2
|
+
export async function handleStartTask(args, projectId, config) {
|
|
3
|
+
const data = await mcpPost(config, "/api/memory/tasks/start", {
|
|
4
|
+
projectId,
|
|
5
|
+
title: args.title,
|
|
6
|
+
description: args.description,
|
|
7
|
+
module: args.module,
|
|
8
|
+
priority: args.priority,
|
|
9
|
+
folderId: args.folderId,
|
|
10
|
+
});
|
|
11
|
+
if (!data.ok)
|
|
12
|
+
throw new Error(data.error);
|
|
13
|
+
let output = `태스크 시작됨: #${data.task.seq} "${data.task.title}" → IN_PROGRESS`;
|
|
14
|
+
if (data.matchedSkills && data.matchedSkills.length > 0) {
|
|
15
|
+
const skillLines = data.matchedSkills.map((s) => `- ${s.slug}: ${s.name} — ${s.contextHint}`).join("\n");
|
|
16
|
+
output += `\n\n[필수] 매칭된 스킬이 있어요. 구현 전 반드시 load_skill(slug)를 호출하세요:\n${skillLines}`;
|
|
17
|
+
}
|
|
18
|
+
output += `\n\n다음 단계: recall("${data.task.title}")로 관련 과거 결정을 검색하세요.`;
|
|
19
|
+
return output;
|
|
20
|
+
}
|
|
21
|
+
//# sourceMappingURL=startTask.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"startTask.js","sourceRoot":"","sources":["../../../src/mcp/tools/startTask.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,OAAO,EAAE,MAAM,iBAAiB,CAAC;AAQ1C,MAAM,CAAC,KAAK,UAAU,eAAe,CACnC,IAAoG,EACpG,SAAiB,EACjB,MAAiB;IAEjB,MAAM,IAAI,GAAG,MAAM,OAAO,CAAoB,MAAM,EAAE,yBAAyB,EAAE;QAC/E,SAAS;QACT,KAAK,EAAE,IAAI,CAAC,KAAK;QACjB,WAAW,EAAE,IAAI,CAAC,WAAW;QAC7B,MAAM,EAAE,IAAI,CAAC,MAAM;QACnB,QAAQ,EAAE,IAAI,CAAC,QAAQ;QACvB,QAAQ,EAAE,IAAI,CAAC,QAAQ;KACxB,CAAC,CAAC;IACH,IAAI,CAAC,IAAI,CAAC,EAAE;QAAE,MAAM,IAAI,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;IAE1C,IAAI,MAAM,GAAG,aAAa,IAAI,CAAC,IAAI,CAAC,GAAG,KAAK,IAAI,CAAC,IAAI,CAAC,KAAK,iBAAiB,CAAC;IAC7E,IAAI,IAAI,CAAC,aAAa,IAAI,IAAI,CAAC,aAAa,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QACxD,MAAM,UAAU,GAAG,IAAI,CAAC,aAAa,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,KAAK,CAAC,CAAC,IAAI,KAAK,CAAC,CAAC,IAAI,MAAM,CAAC,CAAC,WAAW,EAAE,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QACzG,MAAM,IAAI,4DAA4D,UAAU,EAAE,CAAC;IACrF,CAAC;IACD,MAAM,IAAI,sBAAsB,IAAI,CAAC,IAAI,CAAC,KAAK,sBAAsB,CAAC;IACtE,OAAO,MAAM,CAAC;AAChB,CAAC"}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { mcpPatch } from "../mcpClient.js";
|
|
2
|
+
export async function handleUpdateTask(args, config) {
|
|
3
|
+
const { taskSeq, projectId, ...updates } = args;
|
|
4
|
+
const data = await mcpPatch(config, `/api/memory/tasks/${taskSeq}`, { projectId, ...updates });
|
|
5
|
+
if (!data.ok)
|
|
6
|
+
throw new Error(data.error);
|
|
7
|
+
return `태스크 업데이트됨: #${data.task.seq} "${data.task.title}" → ${data.task.status}`;
|
|
8
|
+
}
|
|
9
|
+
//# sourceMappingURL=updateTask.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"updateTask.js","sourceRoot":"","sources":["../../../src/mcp/tools/updateTask.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,QAAQ,EAAE,MAAM,iBAAiB,CAAC;AAK3C,MAAM,CAAC,KAAK,UAAU,gBAAgB,CACpC,IAQC,EACD,MAAiB;IAEjB,MAAM,EAAE,OAAO,EAAE,SAAS,EAAE,GAAG,OAAO,EAAE,GAAG,IAAI,CAAC;IAChD,MAAM,IAAI,GAAG,MAAM,QAAQ,CAAiB,MAAM,EAAE,qBAAqB,OAAO,EAAE,EAAE,EAAE,SAAS,EAAE,GAAG,OAAO,EAAE,CAAC,CAAC;IAC/G,IAAI,CAAC,IAAI,CAAC,EAAE;QAAE,MAAM,IAAI,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;IAC1C,OAAO,eAAe,IAAI,CAAC,IAAI,CAAC,GAAG,KAAK,IAAI,CAAC,IAAI,CAAC,KAAK,OAAO,IAAI,CAAC,IAAI,CAAC,MAAM,EAAE,CAAC;AACnF,CAAC"}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import { discoverClaudeFiles } from "../../discoverClaudeFiles.js";
|
|
2
|
+
import { readClaudeFile } from "../../readClaudeFile.js";
|
|
3
|
+
export async function handleUploadPrompt(args, config) {
|
|
4
|
+
const discovered = await discoverClaudeFiles(args.cwd);
|
|
5
|
+
if (discovered.length === 0) {
|
|
6
|
+
return "업로드할 파일이 없어요. CLAUDE.md, AGENTS.md, SKILL.md 파일을 확인해주세요.";
|
|
7
|
+
}
|
|
8
|
+
const files = [];
|
|
9
|
+
for (const f of discovered) {
|
|
10
|
+
const result = await readClaudeFile(f.absPath);
|
|
11
|
+
if (!result)
|
|
12
|
+
continue;
|
|
13
|
+
files.push({ ...f, content: result.content, mtime: result.mtime });
|
|
14
|
+
}
|
|
15
|
+
if (files.length === 0)
|
|
16
|
+
return "파일을 읽을 수 없었어요.";
|
|
17
|
+
const res = await fetch(`${config.appUrl}/api/claude-files/ingest`, {
|
|
18
|
+
method: "POST",
|
|
19
|
+
headers: {
|
|
20
|
+
"content-type": "application/json",
|
|
21
|
+
authorization: `Bearer ${config.apiKey}`,
|
|
22
|
+
},
|
|
23
|
+
body: JSON.stringify({ source: args.cwd, files }),
|
|
24
|
+
});
|
|
25
|
+
if (!res.ok) {
|
|
26
|
+
const text = await res.text().catch(() => "");
|
|
27
|
+
throw new Error(`업로드 실패 HTTP ${res.status}: ${text.slice(0, 200)}`);
|
|
28
|
+
}
|
|
29
|
+
const lines = files.map((f) => ` • ${f.displayPath} [${f.kind}]`).join("\n");
|
|
30
|
+
return `${files.length}개 파일 업로드 완료:\n${lines}`;
|
|
31
|
+
}
|
|
32
|
+
//# sourceMappingURL=uploadPrompt.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"uploadPrompt.js","sourceRoot":"","sources":["../../../src/mcp/tools/uploadPrompt.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,mBAAmB,EAAE,MAAM,8BAA8B,CAAC;AACnE,OAAO,EAAE,cAAc,EAAE,MAAM,yBAAyB,CAAC;AAGzD,MAAM,CAAC,KAAK,UAAU,kBAAkB,CACtC,IAAqB,EACrB,MAAiB;IAEjB,MAAM,UAAU,GAAG,MAAM,mBAAmB,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;IACvD,IAAI,UAAU,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QAC5B,OAAO,0DAA0D,CAAC;IACpE,CAAC;IAED,MAAM,KAAK,GAOL,EAAE,CAAC;IAET,KAAK,MAAM,CAAC,IAAI,UAAU,EAAE,CAAC;QAC3B,MAAM,MAAM,GAAG,MAAM,cAAc,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC;QAC/C,IAAI,CAAC,MAAM;YAAE,SAAS;QACtB,KAAK,CAAC,IAAI,CAAC,EAAE,GAAG,CAAC,EAAE,OAAO,EAAE,MAAM,CAAC,OAAO,EAAE,KAAK,EAAE,MAAM,CAAC,KAAK,EAAE,CAAC,CAAC;IACrE,CAAC;IAED,IAAI,KAAK,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,gBAAgB,CAAC;IAEhD,MAAM,GAAG,GAAG,MAAM,KAAK,CAAC,GAAG,MAAM,CAAC,MAAM,0BAA0B,EAAE;QAClE,MAAM,EAAE,MAAM;QACd,OAAO,EAAE;YACP,cAAc,EAAE,kBAAkB;YAClC,aAAa,EAAE,UAAU,MAAM,CAAC,MAAM,EAAE;SACzC;QACD,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,EAAE,MAAM,EAAE,IAAI,CAAC,GAAG,EAAE,KAAK,EAAE,CAAC;KAClD,CAAC,CAAC;IAEH,IAAI,CAAC,GAAG,CAAC,EAAE,EAAE,CAAC;QACZ,MAAM,IAAI,GAAG,MAAM,GAAG,CAAC,IAAI,EAAE,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC,EAAE,CAAC,CAAC;QAC9C,MAAM,IAAI,KAAK,CAAC,eAAe,GAAG,CAAC,MAAM,KAAK,IAAI,CAAC,KAAK,CAAC,CAAC,EAAE,GAAG,CAAC,EAAE,CAAC,CAAC;IACtE,CAAC;IAED,MAAM,KAAK,GAAG,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,OAAO,CAAC,CAAC,WAAW,KAAK,CAAC,CAAC,IAAI,GAAG,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IAC9E,OAAO,GAAG,KAAK,CAAC,MAAM,iBAAiB,KAAK,EAAE,CAAC;AACjD,CAAC"}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { authFilePath, readAuth } from "../../auth.js";
|
|
2
|
+
export async function handleWhoami() {
|
|
3
|
+
const auth = await readAuth();
|
|
4
|
+
if (!auth)
|
|
5
|
+
return "로그인되지 않았어요. `signin` 툴로 로그인해 주세요.";
|
|
6
|
+
return [
|
|
7
|
+
`계정: ${auth.email ?? "(이메일 정보 없음)"}`,
|
|
8
|
+
`서버: ${auth.appUrl}`,
|
|
9
|
+
`로그인: ${auth.signedInAt}`,
|
|
10
|
+
`저장: ${authFilePath()}`,
|
|
11
|
+
].join("\n");
|
|
12
|
+
}
|
|
13
|
+
//# sourceMappingURL=whoami.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"whoami.js","sourceRoot":"","sources":["../../../src/mcp/tools/whoami.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAC;AAEvD,MAAM,CAAC,KAAK,UAAU,YAAY;IAChC,MAAM,IAAI,GAAG,MAAM,QAAQ,EAAE,CAAC;IAC9B,IAAI,CAAC,IAAI;QAAE,OAAO,mCAAmC,CAAC;IACtD,OAAO;QACL,SAAS,IAAI,CAAC,KAAK,IAAI,aAAa,EAAE;QACtC,SAAS,IAAI,CAAC,MAAM,EAAE;QACtB,QAAQ,IAAI,CAAC,UAAU,EAAE;QACzB,SAAS,YAAY,EAAE,EAAE;KAC1B,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;AACf,CAAC"}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { spawn } from "node:child_process";
|
|
2
|
+
export function openBrowser(url) {
|
|
3
|
+
const cmd = process.platform === "darwin"
|
|
4
|
+
? "open"
|
|
5
|
+
: process.platform === "win32"
|
|
6
|
+
? "cmd"
|
|
7
|
+
: "xdg-open";
|
|
8
|
+
const args = process.platform === "win32" ? ["/c", "start", "", url] : [url];
|
|
9
|
+
const child = spawn(cmd, args, { stdio: "ignore", detached: true });
|
|
10
|
+
child.on("error", () => {
|
|
11
|
+
// 브라우저 자동 열기 실패해도 무시 — 사용자가 URL 직접 열면 됨
|
|
12
|
+
});
|
|
13
|
+
child.unref();
|
|
14
|
+
}
|
|
15
|
+
//# sourceMappingURL=openBrowser.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"openBrowser.js","sourceRoot":"","sources":["../src/openBrowser.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,MAAM,oBAAoB,CAAC;AAE3C,MAAM,UAAU,WAAW,CAAC,GAAW;IACrC,MAAM,GAAG,GACP,OAAO,CAAC,QAAQ,KAAK,QAAQ;QAC3B,CAAC,CAAC,MAAM;QACR,CAAC,CAAC,OAAO,CAAC,QAAQ,KAAK,OAAO;YAC5B,CAAC,CAAC,KAAK;YACP,CAAC,CAAC,UAAU,CAAC;IACnB,MAAM,IAAI,GAAG,OAAO,CAAC,QAAQ,KAAK,OAAO,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,OAAO,EAAE,EAAE,EAAE,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC;IAC7E,MAAM,KAAK,GAAG,KAAK,CAAC,GAAG,EAAE,IAAI,EAAE,EAAE,KAAK,EAAE,QAAQ,EAAE,QAAQ,EAAE,IAAI,EAAE,CAAC,CAAC;IACpE,KAAK,CAAC,EAAE,CAAC,OAAO,EAAE,GAAG,EAAE;QACrB,wCAAwC;IAC1C,CAAC,CAAC,CAAC;IACH,KAAK,CAAC,KAAK,EAAE,CAAC;AAChB,CAAC"}
|