docuking-mcp 1.2.2 → 1.2.4
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/index.js +111 -21
- package/package.json +1 -1
package/index.js
CHANGED
|
@@ -272,7 +272,7 @@ server.setRequestHandler(ListToolsRequestSchema, async () => {
|
|
|
272
272
|
},
|
|
273
273
|
{
|
|
274
274
|
name: 'docuking_plan',
|
|
275
|
-
description: '작업 계획 문서를
|
|
275
|
+
description: '작업 계획 문서를 z_Plan_Result/ 폴더에 생성하거나 업데이트합니다. 작업 시작 시 계획을 작성하고, 진행하면서 결과를 upsert합니다.',
|
|
276
276
|
inputSchema: {
|
|
277
277
|
type: 'object',
|
|
278
278
|
properties: {
|
|
@@ -413,10 +413,34 @@ zz_Coworker_*/
|
|
|
413
413
|
- git 저장소 크기 최적화 (대용량 문서 제외)
|
|
414
414
|
- DocuKing이 문서 버전 관리를 전담
|
|
415
415
|
|
|
416
|
+
## AI 필수 작업 흐름 (매우 중요!)
|
|
417
|
+
|
|
418
|
+
### MCP 서버 추가 시 (claude mcp add 명령 실행 후)
|
|
419
|
+
1. \`claude mcp add docuking ...\` 명령 실행
|
|
420
|
+
2. 사용자에게 "재시작 후 아래 명령을 다시 붙여넣으세요" 안내
|
|
421
|
+
3. 재시작 후 \`docuking_init\` 실행
|
|
422
|
+
|
|
423
|
+
### docuking_init 실행 후 (⚠️ 필수!)
|
|
424
|
+
1. init 결과에서 \`DOCUKING_REPOS\` 값 확인
|
|
425
|
+
2. **AI가 직접** \`~/.claude.json\` 파일을 Edit 도구로 수정:
|
|
426
|
+
- 해당 프로젝트의 \`mcpServers.docuking.env\`에 \`DOCUKING_REPOS\` 추가
|
|
427
|
+
- 기존 env에 추가하는 것이므로 DOCUKING_API_KEY는 유지
|
|
428
|
+
3. 사용자에게 "재시작 후 push 가능" 안내
|
|
429
|
+
|
|
430
|
+
**예시 (AI가 수행할 Edit):**
|
|
431
|
+
\`\`\`json
|
|
432
|
+
// ~/.claude.json의 해당 프로젝트 mcpServers.docuking.env
|
|
433
|
+
{
|
|
434
|
+
"DOCUKING_API_KEY": "sk_xxx...",
|
|
435
|
+
"DOCUKING_REPOS": "{\\"경로\\":{\\"id\\":\\"프로젝트ID\\",\\"name\\":\\"이름\\"}}"
|
|
436
|
+
}
|
|
437
|
+
\`\`\`
|
|
438
|
+
|
|
416
439
|
## MCP 도구 목록
|
|
417
440
|
|
|
418
441
|
### 1. docuking_init
|
|
419
442
|
프로젝트를 DocuKing에 연결합니다.
|
|
443
|
+
**중요:** init 후 AI가 ~/.claude.json에 DOCUKING_REPOS를 추가해야 함!
|
|
420
444
|
|
|
421
445
|
### 2. docuking_push
|
|
422
446
|
로컬 문서를 서버에 업로드합니다. Git의 add + commit + push를 한 번에 수행.
|
|
@@ -446,7 +470,7 @@ zz_Coworker_*/
|
|
|
446
470
|
- 사용자가 "이거 기록해줘"라고 요청할 때
|
|
447
471
|
|
|
448
472
|
### 10. docuking_plan
|
|
449
|
-
작업 계획을 \`
|
|
473
|
+
작업 계획을 \`z_Plan_Result/\` 폴더에 생성/업데이트합니다.
|
|
450
474
|
- 작업 시작 시 계획 생성
|
|
451
475
|
- 진행하면서 단계별 결과 upsert
|
|
452
476
|
- planId로 기존 계획 찾아서 업데이트
|
|
@@ -654,7 +678,7 @@ AI: (결정이 내려졌으므로 docuking_talk 호출)
|
|
|
654
678
|
})
|
|
655
679
|
\`\`\`
|
|
656
680
|
|
|
657
|
-
**저장 위치:** \`z_Talk/YYYY/MM/YYYY-MM-DD_HHMM__제목.md\`
|
|
681
|
+
**저장 위치:** \`z_DocuKing/z_Talk/YYYY/MM/YYYY-MM-DD_HHMM__제목.md\`
|
|
658
682
|
|
|
659
683
|
### 작업 계획 관리 (docuking_plan, docuking_done)
|
|
660
684
|
|
|
@@ -705,7 +729,7 @@ AI: docuking_done({
|
|
|
705
729
|
})
|
|
706
730
|
\`\`\`
|
|
707
731
|
|
|
708
|
-
**저장 위치:** \`
|
|
732
|
+
**저장 위치:** \`z_DocuKing/z_Plan_Result/YYYY/MM/YYYY-MM-DD_HHMM__제목__planId.md\`
|
|
709
733
|
|
|
710
734
|
**핵심 가치:**
|
|
711
735
|
- AI 세션이 끊겨도 (컴팩션, 세션 종료) 다음 AI가 계획 문서를 보고 이어서 작업 가능
|
|
@@ -930,7 +954,7 @@ MCP 설정에 다음을 추가하세요:
|
|
|
930
954
|
💡 참여자는 ${folderName}/ 폴더에만 Push할 수 있습니다.
|
|
931
955
|
오너의 문서는 Pull로 읽을 수 있지만 수정은 제안서 형태로 작성하세요.
|
|
932
956
|
|
|
933
|
-
MCP
|
|
957
|
+
⚠️ AI 필수 작업: ~/.claude.json의 docuking MCP env에 DOCUKING_REPOS 추가 필요
|
|
934
958
|
"DOCUKING_REPOS": "${repoConfig}"`,
|
|
935
959
|
},
|
|
936
960
|
],
|
|
@@ -953,7 +977,7 @@ MCP 설정에 레포 매핑 추가 필요:
|
|
|
953
977
|
- "DocuKing에 올려줘" → 로컬 문서를 서버에 Push
|
|
954
978
|
- "DocuKing에서 가져와" → 서버 문서를 로컬로 Pull
|
|
955
979
|
|
|
956
|
-
MCP
|
|
980
|
+
⚠️ AI 필수 작업: ~/.claude.json의 docuking MCP env에 DOCUKING_REPOS 추가 필요
|
|
957
981
|
"DOCUKING_REPOS": "${repoConfig}"`,
|
|
958
982
|
},
|
|
959
983
|
],
|
|
@@ -1058,16 +1082,47 @@ docuking_init을 먼저 실행하세요.`,
|
|
|
1058
1082
|
filesToPush.push({ path: filePath, serverPath: serverFilePath, fullPath, fileType });
|
|
1059
1083
|
}
|
|
1060
1084
|
} else {
|
|
1061
|
-
// 전체 파일 - 제외된 파일 목록도 수집
|
|
1062
|
-
collectFiles(workingPath, '', filesToPush, excludedFiles);
|
|
1063
|
-
|
|
1064
|
-
// 서버 경로 추가
|
|
1065
|
-
for (const file of filesToPush) {
|
|
1066
|
-
file.serverPath = serverPathPrefix + file.path;
|
|
1067
|
-
}
|
|
1068
|
-
|
|
1069
1085
|
if (isCoworker) {
|
|
1086
|
+
// 코워커: 본인 폴더만 수집
|
|
1087
|
+
collectFiles(workingPath, '', filesToPush, excludedFiles);
|
|
1088
|
+
|
|
1089
|
+
// 서버 경로 추가
|
|
1090
|
+
for (const file of filesToPush) {
|
|
1091
|
+
file.serverPath = serverPathPrefix + file.path;
|
|
1092
|
+
}
|
|
1070
1093
|
console.log(`[DocuKing] 코워커 Push: ${filesToPush.length}개 파일 (${coworkerFolderName}/)`);
|
|
1094
|
+
} else {
|
|
1095
|
+
// 오너: z_DocuKing/ + 모든 zz_Coworker_*/ 폴더 수집
|
|
1096
|
+
const docuKingFolderName = findDocuKingFolder(localPath);
|
|
1097
|
+
|
|
1098
|
+
// 1. z_DocuKing/ 폴더 수집
|
|
1099
|
+
if (docuKingFolderName) {
|
|
1100
|
+
const docuKingPath = path.join(localPath, docuKingFolderName);
|
|
1101
|
+
const docuKingFiles = [];
|
|
1102
|
+
collectFiles(docuKingPath, '', docuKingFiles, excludedFiles);
|
|
1103
|
+
|
|
1104
|
+
for (const file of docuKingFiles) {
|
|
1105
|
+
file.serverPath = file.path; // 오너 폴더는 서버 경로 = 파일 경로
|
|
1106
|
+
filesToPush.push(file);
|
|
1107
|
+
}
|
|
1108
|
+
}
|
|
1109
|
+
|
|
1110
|
+
// 2. 모든 zz_Coworker_*/ 폴더 수집
|
|
1111
|
+
const coworkerFolders = findCoworkerFolders(localPath);
|
|
1112
|
+
for (const cwFolder of coworkerFolders) {
|
|
1113
|
+
const cwPath = path.join(localPath, cwFolder);
|
|
1114
|
+
const cwFiles = [];
|
|
1115
|
+
collectFiles(cwPath, '', cwFiles, excludedFiles);
|
|
1116
|
+
|
|
1117
|
+
for (const file of cwFiles) {
|
|
1118
|
+
file.serverPath = `${cwFolder}/${file.path}`; // 코워커 폴더명 포함
|
|
1119
|
+
file.path = `${cwFolder}/${file.path}`; // 로컬 경로도 폴더명 포함
|
|
1120
|
+
file.fullPath = path.join(cwPath, file.path.replace(`${cwFolder}/`, ''));
|
|
1121
|
+
filesToPush.push(file);
|
|
1122
|
+
}
|
|
1123
|
+
}
|
|
1124
|
+
|
|
1125
|
+
console.log(`[DocuKing] 오너 Push: ${filesToPush.length}개 파일 (z_DocuKing/ + ${coworkerFolders.length}개 코워커 폴더)`);
|
|
1071
1126
|
}
|
|
1072
1127
|
}
|
|
1073
1128
|
|
|
@@ -1588,10 +1643,29 @@ function getFileType(fileName) {
|
|
|
1588
1643
|
return 'binary';
|
|
1589
1644
|
}
|
|
1590
1645
|
|
|
1591
|
-
// 유틸: DocuKing 폴더 찾기
|
|
1646
|
+
// 유틸: DocuKing 폴더 찾기
|
|
1647
|
+
// 우선순위: z_DocuKing > Z_DocuKing > 기타 docuking 포함 폴더
|
|
1592
1648
|
function findDocuKingFolder(projectPath) {
|
|
1593
1649
|
try {
|
|
1594
1650
|
const entries = fs.readdirSync(projectPath, { withFileTypes: true });
|
|
1651
|
+
|
|
1652
|
+
// 1순위: z_DocuKing 또는 Z_DocuKing (정확한 이름)
|
|
1653
|
+
for (const entry of entries) {
|
|
1654
|
+
if (entry.isDirectory() && (entry.name === 'z_DocuKing' || entry.name === 'Z_DocuKing')) {
|
|
1655
|
+
return entry.name;
|
|
1656
|
+
}
|
|
1657
|
+
}
|
|
1658
|
+
|
|
1659
|
+
// 2순위: z_ 또는 Z_로 시작하고 docuking 포함
|
|
1660
|
+
for (const entry of entries) {
|
|
1661
|
+
if (entry.isDirectory() &&
|
|
1662
|
+
(entry.name.startsWith('z_') || entry.name.startsWith('Z_')) &&
|
|
1663
|
+
entry.name.toLowerCase().includes('docuking')) {
|
|
1664
|
+
return entry.name;
|
|
1665
|
+
}
|
|
1666
|
+
}
|
|
1667
|
+
|
|
1668
|
+
// 3순위: docuking 포함하는 아무 폴더 (하위 호환)
|
|
1595
1669
|
for (const entry of entries) {
|
|
1596
1670
|
if (entry.isDirectory() && entry.name.toLowerCase().includes('docuking')) {
|
|
1597
1671
|
return entry.name;
|
|
@@ -1603,6 +1677,22 @@ function findDocuKingFolder(projectPath) {
|
|
|
1603
1677
|
return null;
|
|
1604
1678
|
}
|
|
1605
1679
|
|
|
1680
|
+
// 유틸: 모든 zz_Coworker_* 폴더 찾기
|
|
1681
|
+
function findCoworkerFolders(projectPath) {
|
|
1682
|
+
const folders = [];
|
|
1683
|
+
try {
|
|
1684
|
+
const entries = fs.readdirSync(projectPath, { withFileTypes: true });
|
|
1685
|
+
for (const entry of entries) {
|
|
1686
|
+
if (entry.isDirectory() && entry.name.startsWith('zz_Coworker_')) {
|
|
1687
|
+
folders.push(entry.name);
|
|
1688
|
+
}
|
|
1689
|
+
}
|
|
1690
|
+
} catch (e) {
|
|
1691
|
+
// 디렉토리 읽기 실패
|
|
1692
|
+
}
|
|
1693
|
+
return folders;
|
|
1694
|
+
}
|
|
1695
|
+
|
|
1606
1696
|
// 유틸: 디렉토리 재귀 탐색
|
|
1607
1697
|
// excludedFiles: 제외된 파일 목록을 수집할 배열 (선택)
|
|
1608
1698
|
function collectFiles(basePath, relativePath, results, excludedFiles = null) {
|
|
@@ -1872,8 +1962,8 @@ function generatePlanId() {
|
|
|
1872
1962
|
async function handleTalk(args) {
|
|
1873
1963
|
const { localPath, title, content, tags = [] } = args;
|
|
1874
1964
|
|
|
1875
|
-
// z_Talk 폴더 경로
|
|
1876
|
-
const talkBasePath = path.join(localPath, 'z_Talk');
|
|
1965
|
+
// z_Talk 폴더 경로 (z_DocuKing 아래)
|
|
1966
|
+
const talkBasePath = path.join(localPath, 'z_DocuKing', 'z_Talk');
|
|
1877
1967
|
|
|
1878
1968
|
// 날짜 기반 파일명 생성
|
|
1879
1969
|
const { fileName, yearMonth, timestamp } = generateDateFileName(title);
|
|
@@ -1926,8 +2016,8 @@ ${content}
|
|
|
1926
2016
|
async function handlePlan(args) {
|
|
1927
2017
|
const { localPath, planId, title, goal, steps = [], notes } = args;
|
|
1928
2018
|
|
|
1929
|
-
//
|
|
1930
|
-
const planBasePath = path.join(localPath, '
|
|
2019
|
+
// z_Plan_Result 폴더 경로 (z_DocuKing 아래)
|
|
2020
|
+
const planBasePath = path.join(localPath, 'z_DocuKing', 'z_Plan_Result');
|
|
1931
2021
|
|
|
1932
2022
|
// 기존 계획 업데이트 또는 새 계획 생성
|
|
1933
2023
|
let targetPlanId = planId;
|
|
@@ -2077,8 +2167,8 @@ function findPlanFiles(basePath, planId) {
|
|
|
2077
2167
|
async function handleDone(args) {
|
|
2078
2168
|
const { localPath, planId, summary, artifacts = [] } = args;
|
|
2079
2169
|
|
|
2080
|
-
//
|
|
2081
|
-
const planBasePath = path.join(localPath, '
|
|
2170
|
+
// z_Plan_Result 폴더 경로 (z_DocuKing 아래)
|
|
2171
|
+
const planBasePath = path.join(localPath, 'z_DocuKing', 'z_Plan_Result');
|
|
2082
2172
|
|
|
2083
2173
|
// 계획 파일 찾기
|
|
2084
2174
|
const planFiles = findPlanFiles(planBasePath, planId);
|