docuking-mcp 2.13.0 → 3.0.0

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 CHANGED
@@ -77,18 +77,18 @@ claude mcp add docuking -s user -- docuking-mcp
77
77
 
78
78
  | 도구 | 설명 |
79
79
  |------|------|
80
- | docuking_init | 프로젝트 연결, yy_All_Docu/ 및 zz_ai_* 폴더 생성 |
81
- | docuking_push | yy_All_Docu/ → 서버 업로드 |
82
- | docuking_pull | 서버 → yy_All_Docu/ 다운로드 |
80
+ | docuking_init | 프로젝트 연결, 필수 폴더 생성 |
81
+ | docuking_push | 로컬 → 서버 업로드 |
82
+ | docuking_pull | 서버 → 로컬 다운로드 |
83
83
  | docuking_status | 동기화 상태 확인 |
84
84
  | docuking_list | 서버 파일 목록 조회 |
85
85
  | docuking_log | 커밋 히스토리 조회 |
86
86
  | docuking_diff | 버전 간 차이 비교 |
87
87
  | docuking_rollback | 특정 커밋으로 롤백 |
88
- | docuking_talk | AI 대화록 저장 (zz_ai_1_Talk/) |
89
- | docuking_plan | 작업 계획 관리 (zz_ai_3_Plan/) |
88
+ | docuking_talk | AI 대화록 저장 (xy_TalkTodoPlan/) |
89
+ | docuking_plan | 작업 계획 관리 (xy_TalkTodoPlan/) |
90
90
  | docuking_done | 작업 완료 처리 |
91
- | docuking_todo | 킹투두 관리 (zz_ai_2_Todo/) |
91
+ | docuking_todo | 킹투두 관리 (xy_TalkTodoPlan/z_King_Todo.md) |
92
92
  | docuking_urgent | 긴급 보고 (xx_Urgent/) |
93
93
  | docuking_delete | 서버 파일 삭제 |
94
94
  | docuking_validate | 정책 준수 검증 |
@@ -100,20 +100,17 @@ claude mcp add docuking -s user -- docuking-mcp
100
100
  ├── xx_Infra_Config/ ← 시스템 설정 (동기화 대상)
101
101
  ├── xx_Policy/ ← 정책 문서 (동기화 대상, 킹캐스트)
102
102
  ├── xx_Urgent/ ← 긴급 보고 (동기화 대상)
103
+ ├── xy_TalkTodoPlan/ ← 오너 AI 기록 (Talk+Todo+Plan 통합)
103
104
  ├── yy_All_Docu/ ← 문서 허브 (동기화 대상)
104
- ├── yy_Coworker_{이름}/ ← 협업자 작업 폴더 (동기화 대상)
105
- │ ├── zz_ai_1_Talk/ ← 협업자의 AI 대화록
106
- │ ├── zz_ai_2_Todo/ ← 협업자의 AI 투두
107
- │ └── zz_ai_3_Plan/ ← 협업자의 AI 플랜
108
- ├── zz_ai_1_Talk/ ← 오너의 AI 대화록 (동기화 대상)
109
- ├── zz_ai_2_Todo/ ← 오너의 AI 투두 (동기화 대상)
110
- └── zz_ai_3_Plan/ ← 오너의 AI 플랜 (동기화 대상)
105
+ └── yy_Coworker_{이름}/ ← 협업자 작업 폴더 (동기화 대상)
106
+ └── zz_TalkTodoPlan/ ← 협업자의 AI 기록
111
107
  ```
112
108
 
113
109
  **접두사 규칙:**
114
110
  - `xx_*`: 시스템/인프라 폴더
111
+ - `xy_*`: 오너 AI 기록 폴더
115
112
  - `yy_*`: 사람용 폴더
116
- - `zz_ai_*`: AI 폴더
113
+ - `zz_*`: 협업자 AI 기록 폴더 (협업자 폴더 안에서만)
117
114
 
118
115
  ## 웹사이트
119
116
 
package/handlers/docs.js CHANGED
@@ -17,11 +17,12 @@ export async function handleTodo(args) {
17
17
  const localPath = args.localPath || process.cwd();
18
18
  const { action, todo, todoId } = args;
19
19
 
20
- // 협업자 여부에 따라 zz_ai 경로 결정
21
- // - 오너: localPath/zz_ai_2_Todo/
22
- // - 협업자: localPath/yy_Coworker_{폴더명}/zz_ai_2_Todo/
23
- const { basePath } = getAiBasePath(localPath);
24
- const todoBasePath = path.join(basePath, 'zz_ai_2_Todo');
20
+ // 협업자 여부에 따라 AI 폴더 경로 결정
21
+ // - 오너: localPath/xy_TalkTodoPlan/
22
+ // - 협업자: localPath/yy_Coworker_{폴더명}/zz_TalkTodoPlan/
23
+ const { basePath, isCoworker } = getAiBasePath(localPath);
24
+ const aiFolder = isCoworker ? 'zz_TalkTodoPlan' : 'xy_TalkTodoPlan';
25
+ const todoBasePath = path.join(basePath, aiFolder);
25
26
  const todoFilePath = path.join(todoBasePath, 'z_King_Todo.md');
26
27
 
27
28
  // 폴더 생성
@@ -182,7 +183,7 @@ export async function handleTodo(args) {
182
183
  text: `📋 킹투두 미결: 없음
183
184
 
184
185
  ✅ 완료: ${completedCount}개
185
- 📁 전체 기록: zz_ai_2_Todo/z_King_Todo.md`,
186
+ 📁 전체 기록: ${aiFolder}/z_King_Todo.md`,
186
187
  }],
187
188
  };
188
189
  }
@@ -197,7 +198,7 @@ export async function handleTodo(args) {
197
198
  ${listText}
198
199
 
199
200
  ✅ 완료: ${completedCount}개
200
- 📁 전체 기록: zz_ai_2_Todo/z_King_Todo.md`,
201
+ 📁 전체 기록: ${aiFolder}/z_King_Todo.md`,
201
202
  }],
202
203
  };
203
204
  }
@@ -215,10 +216,11 @@ export async function handleTalk(args) {
215
216
  const { title, content: talkContent, tags = [] } = args;
216
217
 
217
218
  // 협업자 여부에 따라 zz_ai 경로 결정
218
- // - 오너: localPath/zz_ai_1_Talk/
219
- // - 협업자: localPath/yy_Coworker_{폴더명}/zz_ai_1_Talk/
220
- const { basePath } = getAiBasePath(localPath);
221
- const talkBasePath = path.join(basePath, 'zz_ai_1_Talk');
219
+ // - 오너: localPath/xy_TalkTodoPlan/
220
+ // - 협업자: localPath/yy_Coworker_{폴더명}/zz_TalkTodoPlan/
221
+ const { basePath, isCoworker } = getAiBasePath(localPath);
222
+ const aiFolder = isCoworker ? 'zz_TalkTodoPlan' : 'xy_TalkTodoPlan';
223
+ const talkBasePath = path.join(basePath, aiFolder);
222
224
 
223
225
  // 날짜 기반 파일명 생성 (T_ 접두사)
224
226
  const { fileName, timestamp } = generateDateFileName(title, 'T');
@@ -299,11 +301,12 @@ export async function handlePlan(args) {
299
301
  const localPath = args.localPath || process.cwd();
300
302
  const { planId, title, goal, steps = [], notes } = args;
301
303
 
302
- // 협업자 여부에 따라 zz_ai 경로 결정
303
- // - 오너: localPath/zz_ai_3_Plan/
304
- // - 협업자: localPath/yy_Coworker_{폴더명}/zz_ai_3_Plan/
305
- const { basePath } = getAiBasePath(localPath);
306
- const planBasePath = path.join(basePath, 'zz_ai_3_Plan');
304
+ // 협업자 여부에 따라 AI 폴더 경로 결정
305
+ // - 오너: localPath/xy_TalkTodoPlan/
306
+ // - 협업자: localPath/yy_Coworker_{폴더명}/zz_TalkTodoPlan/
307
+ const { basePath, isCoworker } = getAiBasePath(localPath);
308
+ const aiFolder = isCoworker ? 'zz_TalkTodoPlan' : 'xy_TalkTodoPlan';
309
+ const planBasePath = path.join(basePath, aiFolder);
307
310
 
308
311
  // 기존 계획 업데이트 또는 새 계획 생성
309
312
  let targetPlanId = planId;
@@ -453,11 +456,12 @@ export async function handleDone(args) {
453
456
  const localPath = args.localPath || process.cwd();
454
457
  const { planId, summary, artifacts = [] } = args;
455
458
 
456
- // 협업자 여부에 따라 zz_ai 경로 결정
457
- // - 오너: localPath/zz_ai_3_Plan/
458
- // - 협업자: localPath/yy_Coworker_{폴더명}/zz_ai_3_Plan/
459
- const { basePath } = getAiBasePath(localPath);
460
- const planBasePath = path.join(basePath, 'zz_ai_3_Plan');
459
+ // 협업자 여부에 따라 AI 폴더 경로 결정
460
+ // - 오너: localPath/xy_TalkTodoPlan/
461
+ // - 협업자: localPath/yy_Coworker_{폴더명}/zz_TalkTodoPlan/
462
+ const { basePath, isCoworker } = getAiBasePath(localPath);
463
+ const aiFolder = isCoworker ? 'zz_TalkTodoPlan' : 'xy_TalkTodoPlan';
464
+ const planBasePath = path.join(basePath, aiFolder);
461
465
 
462
466
  // 계획 파일 찾기
463
467
  const planFiles = findPlanFilesLocal(planBasePath, planId);
package/handlers/sync.js CHANGED
@@ -96,8 +96,9 @@ docuking_init 호출 시 apiKey 파라미터를 포함해주세요.`,
96
96
  let coworkerFolderName = null;
97
97
  let coworkerFolderPath = null;
98
98
 
99
- // zz_ai_* 폴더 목록
100
- const aiFolders = ['zz_ai_1_Talk', 'zz_ai_2_Todo', 'zz_ai_3_Plan'];
99
+ // AI 폴더 (오너: xy_TalkTodoPlan, 협업자: zz_TalkTodoPlan)
100
+ const ownerAiFolder = 'xy_TalkTodoPlan';
101
+ const coworkerAiFolder = 'zz_TalkTodoPlan';
101
102
 
102
103
  // xx_ 시스템 폴더 목록 (오너 전용)
103
104
  const systemFolders = ['xx_Infra_Config', 'xx_Policy'];
@@ -120,12 +121,10 @@ docuking_init 호출 시 apiKey 파라미터를 포함해주세요.`,
120
121
  if (!fs.existsSync(coworkerPrivatePath)) {
121
122
  fs.mkdirSync(coworkerPrivatePath, { recursive: true });
122
123
  }
123
- // 협업자 폴더 안에 zz_ai_* 폴더 생성
124
- for (const folder of aiFolders) {
125
- const folderPath = path.join(coworkerFolderPath, folder);
126
- if (!fs.existsSync(folderPath)) {
127
- fs.mkdirSync(folderPath, { recursive: true });
128
- }
124
+ // 협업자 폴더 안에 zz_TalkTodoPlan 폴더 생성
125
+ const coworkerAiFolderPath = path.join(coworkerFolderPath, coworkerAiFolder);
126
+ if (!fs.existsSync(coworkerAiFolderPath)) {
127
+ fs.mkdirSync(coworkerAiFolderPath, { recursive: true });
129
128
  }
130
129
  } else {
131
130
  // 오너: xx_ 시스템 폴더 (루트에 생성)
@@ -140,12 +139,10 @@ docuking_init 호출 시 apiKey 파라미터를 포함해주세요.`,
140
139
  if (!fs.existsSync(ownerPrivatePath)) {
141
140
  fs.mkdirSync(ownerPrivatePath, { recursive: true });
142
141
  }
143
- // 오너: 루트에 zz_ai_* 폴더 생성
144
- for (const folder of aiFolders) {
145
- const folderPath = path.join(localPath, folder);
146
- if (!fs.existsSync(folderPath)) {
147
- fs.mkdirSync(folderPath, { recursive: true });
148
- }
142
+ // 오너: 루트에 xy_TalkTodoPlan 폴더 생성
143
+ const ownerAiFolderPath = path.join(localPath, ownerAiFolder);
144
+ if (!fs.existsSync(ownerAiFolderPath)) {
145
+ fs.mkdirSync(ownerAiFolderPath, { recursive: true });
149
146
  }
150
147
  }
151
148
 
@@ -806,82 +803,23 @@ docuking_init을 먼저 실행하세요.`,
806
803
  }
807
804
 
808
805
  // ========================================
809
- // 4. 서버에만 있고 로컬에 없는 파일 soft-delete (deleted_at 기반)
806
+ // 4. 자동 삭제 비활성화 (2026-01-17 버그 수정)
807
+ // ========================================
808
+ // 이전 로직: "서버에 있고 로컬에 없으면 삭제"
809
+ // 문제: 다른 프로젝트에서 Pull하면 서버 파일이 삭제됨
810
+ // 해결: 자동 삭제 제거, docuking_delete로만 명시적 삭제
811
+ //
812
+ // 삭제는 명시적으로만:
813
+ // - 사용자가 "이 파일 삭제해줘" 요청 시
814
+ // - docuking_delete MCP 도구 사용
810
815
  // ========================================
811
- // 단, 협업자 폴더(yy_Coworker_*)는 삭제하지 않음 (오너가 협업자 파일을 삭제하면 안됨)
812
- // source: 'web' 파일은 MCP에서 삭제 시도하지 않음 (클라이언트에서 필터링)
813
- // 중요: localPathsBeforePull 사용 (Pull 전에 수집한 목록)
814
- // processedLocalPaths는 Pull로 내려받은 파일도 포함하므로 사용 금지
815
816
  let deleted = 0;
816
817
  const deletedFilePaths = [];
817
- let protectedFiles = []; // source: 'web' 파일 (보호됨)
818
- const webProtectedPaths = []; // MCP에서 미리 필터링한 웹 파일
819
-
820
- if (serverAllPaths.length > 0 && !isCoworker) {
821
- // 오너만 삭제 수행
822
- // yy_Coworker_*로 시작하는 경로는 삭제 대상에서 제외
823
- // localPathsBeforePull: Pull 전에 수집한 로컬 파일 목록 (좀비 파일 방지)
824
- //
825
- // ★ 핵심: source: 'web' 파일은 삭제 대상에서 미리 제외!
826
- // 이렇게 하면 웹에서 생성한 파일이 절대 삭제되지 않음
827
- const pathsToDelete = serverAllPaths.filter(p => {
828
- // 1. 로컬에 있으면 제외 (삭제 대상 아님)
829
- if (localPathsBeforePull.has(p)) return false;
830
-
831
- // 2. 협업자 폴더는 제외
832
- if (p.startsWith('yy_Coworker_')) return false;
833
-
834
- // 3. source: 'web' 파일은 제외 (웹에서 생성된 파일 보호)
835
- const meta = serverPathToMeta[p];
836
- if (meta && meta.source === 'web') {
837
- webProtectedPaths.push(p);
838
- return false;
839
- }
840
-
841
- return true;
842
- });
843
-
844
- // 웹 보호 파일 로그
845
- if (webProtectedPaths.length > 0) {
846
- console.error(`[DocuKing] source:web 파일 ${webProtectedPaths.length}개 삭제에서 제외:`, webProtectedPaths.slice(0, 5));
847
- }
848
-
849
- console.error(`[DocuKing] soft-delete 대상: ${pathsToDelete.length}개 (서버에만 있고 Pull 전 로컬에 없던 파일, source:local만)`);
850
-
851
- if (pathsToDelete.length > 0) {
852
- try {
853
- // soft-delete API 호출 (deleted_at 설정, 3일 후 hard delete)
854
- const deleteResponse = await fetch(`${API_ENDPOINT}/files/soft-delete`, {
855
- method: 'POST',
856
- headers: {
857
- 'Content-Type': 'application/json',
858
- 'Authorization': `Bearer ${apiKey}`,
859
- },
860
- body: JSON.stringify({
861
- projectId,
862
- paths: pathsToDelete,
863
- }),
864
- });
865
-
866
- if (deleteResponse.ok) {
867
- const deleteResult = await deleteResponse.json();
868
- deleted = deleteResult.deleted || 0;
869
- deletedFilePaths.push(...(deleteResult.deletedPaths || []));
870
- protectedFiles = deleteResult.protected || [];
818
+ let protectedFiles = [];
871
819
 
872
- // 보호된 파일이 있으면 로그 출력 (Backend에서 추가로 보호한 파일)
873
- if (protectedFiles.length > 0) {
874
- console.error(`[DocuKing] Backend에서 추가 보호된 파일 ${protectedFiles.length}개:`, protectedFiles.slice(0, 5));
875
- }
876
- }
877
- } catch (e) {
878
- console.error('[DocuKing] 파일 soft-delete 실패:', e.message);
879
- }
880
- }
881
-
882
- // MCP에서 미리 제외한 웹 파일도 보호 목록에 추가 (결과 표시용)
883
- protectedFiles = [...protectedFiles, ...webProtectedPaths];
884
- }
820
+ // 자동 삭제 로직 비활성화 - 아래 코드는 주석 처리
821
+ // "로컬에 없으면 삭제" 로직은 위험하므로 제거
822
+ console.error(`[DocuKing] 자동 삭제 비활성화됨 (명시적 삭제만 허용: docuking_delete 사용)`);
885
823
 
886
824
  // 5. 빈 폴더 생성
887
825
  let createdEmptyFolders = 0;
@@ -1072,10 +1010,10 @@ export async function handlePullInternal(args) {
1072
1010
  const commonFolders = ['xx_Urgent'];
1073
1011
 
1074
1012
  // 오너 전용 폴더
1075
- const ownerFolders = ['xx_Infra_Config', 'xx_Policy', 'zz_ai_1_Talk', 'zz_ai_2_Todo', 'zz_ai_3_Plan'];
1013
+ const ownerFolders = ['xx_Infra_Config', 'xx_Policy', 'xy_TalkTodoPlan'];
1076
1014
 
1077
1015
  // 협업자 전용 폴더 (yy_Coworker_{폴더명}/ 안에)
1078
- const coworkerSubFolders = ['zz_ai_1_Talk', 'zz_ai_2_Todo', 'zz_ai_3_Plan', '_Private'];
1016
+ const coworkerSubFolders = ['zz_TalkTodoPlan', '_Private'];
1079
1017
 
1080
1018
  // 공통 폴더 체크
1081
1019
  for (const folder of commonFolders) {
@@ -1300,11 +1238,24 @@ export async function handlePullInternal(args) {
1300
1238
  current++;
1301
1239
  continue;
1302
1240
  }
1241
+
1242
+ // ========================================
1243
+ // [버그 수정] 로컬 파일 우선 정책
1244
+ // 해시가 다르면 → 로컬 수정이 있다는 뜻
1245
+ // 서버 파일로 덮어쓰지 않고 로컬 유지
1246
+ // 다음 Push에서 로컬 → 서버로 업로드됨
1247
+ // ========================================
1248
+ console.error(`[DocuKing] 로컬 우선: ${file.path} (해시 다름 → 로컬 유지, Push 시 업로드됨)`);
1249
+ results.push({ type: 'skip', path: file.path, reason: 'local-modified' });
1250
+ skipped++;
1251
+ current++;
1252
+ continue;
1303
1253
  } catch (e) {
1304
1254
  // 해시 계산 실패 시 다운로드 대상
1305
1255
  }
1306
1256
  }
1307
1257
 
1258
+ // 로컬에 파일이 없는 경우만 다운로드
1308
1259
  filesToDownload.push({ ...file, fullPath });
1309
1260
  }
1310
1261
 
@@ -1437,29 +1388,18 @@ export async function handlePullInternal(args) {
1437
1388
  }
1438
1389
 
1439
1390
  // ========================================
1440
- // mark-as-pulled 호출 (source: 'web' → 'local' 변경)
1441
- // Pull된 웹 파일/폴더는 이제 로컬이 관리권한을 가짐
1391
+ // mark-as-pulled 비활성화 (2026-01-17 정책 변경)
1392
+ // ========================================
1393
+ // 이전 로직: source를 'web' → 'local'로 변경
1394
+ // 문제: source는 "출생신고"로, 한 번 정해지면 불변이어야 함
1395
+ // 변경하면 "출처 위조"가 됨
1396
+ //
1397
+ // 새 정책: source는 절대 변경하지 않음
1398
+ // - web에서 태어난 파일은 Pull해도 source: 'web' 유지
1399
+ // - local에서 태어난 파일은 Push해도 source: 'local' 유지
1442
1400
  // ========================================
1443
1401
  if (filesToMarkAsPulled.length > 0) {
1444
- try {
1445
- const markResponse = await fetch(`${API_ENDPOINT}/files/mark-as-pulled`, {
1446
- method: 'POST',
1447
- headers: {
1448
- 'Content-Type': 'application/json',
1449
- 'Authorization': `Bearer ${apiKey}`,
1450
- },
1451
- body: JSON.stringify({
1452
- projectId,
1453
- paths: filesToMarkAsPulled,
1454
- }),
1455
- });
1456
-
1457
- if (markResponse.ok) {
1458
- console.error(`[DocuKing] mark-as-pulled 완료: ${filesToMarkAsPulled.length}개`);
1459
- }
1460
- } catch (e) {
1461
- console.error('[DocuKing] mark-as-pulled 실패:', e.message);
1462
- }
1402
+ console.error(`[DocuKing] mark-as-pulled 비활성화됨 (source 불변 정책): ${filesToMarkAsPulled.length}개 파일의 source 유지`);
1463
1403
  }
1464
1404
 
1465
1405
  // ========================================
package/index.js CHANGED
@@ -8,17 +8,18 @@
8
8
  * 폴더 구조:
9
9
  * - xx_Infra_Config/ : 시스템 설정 (.env 백업, 배포 정보 등) - Push 대상
10
10
  * - xx_Policy/ : 정책 문서 (AI 행동 지침) - Push 대상, 킹캐스트 대상
11
+ * - xx_Urgent/ : 긴급 보고 (킹어전트) - Push 대상
12
+ * - xy_TalkTodoPlan/ : 오너 AI 기록 (Talk+Todo+Plan 통합) - Push 대상
11
13
  * - yy_All_Docu/ : 문서 동기화 폴더 (Push/Pull 대상)
12
14
  * - yy_All_Docu/_Private/ : 오너 비공개 폴더 (오너만 접근)
13
15
  * - yy_Coworker_{폴더명}/ : 협업자 폴더 (yy_All_Docu와 별도, 동기화 대상)
14
- * - zz_ai_1_Talk/ : AI 대화록 (킹톡, Push 대상)
15
- * - zz_ai_2_Todo/ : AI 투두 (킹투두, Push 대상)
16
- * - zz_ai_3_Plan/ : AI 플랜 (킹플랜, Push 대상)
16
+ * - yy_Coworker_{폴더명}/zz_TalkTodoPlan/ : 협업자 AI 기록
17
17
  *
18
18
  * 접두사 규칙:
19
- * - xx_ : 시스템용 폴더 (인프라, 정책) - Push 대상
20
- * - yy_ : 사람용 폴더 (문서, 협업자) - Push 대상
21
- * - zz_ai_ : AI용 폴더 (Talk, Todo, Plan) - Push 대상
19
+ * - xx_ : 시스템용 폴더 (인프라, 정책, 긴급)
20
+ * - xy_ : 오너 AI 기록 폴더
21
+ * - yy_ : 사람용 폴더 (문서, 협업자)
22
+ * - zz_ : 협업자 AI 기록 폴더 (협업자 폴더 안에서만 사용)
22
23
  * - _ : 비공개 폴더 (본인만 접근)
23
24
  *
24
25
  * 도구:
@@ -98,13 +99,13 @@ server.setRequestHandler(ListToolsRequestSchema, async () => {
98
99
 
99
100
  **오너 초기화 시:**
100
101
  - xx_Infra_Config/, xx_Policy/, xx_Urgent/ 폴더 생성 (시스템 설정)
102
+ - xy_TalkTodoPlan/ 폴더 생성 (AI 기록 통합)
101
103
  - yy_All_Docu/, yy_All_Docu/_Private/ 폴더 생성
102
- - zz_ai_1_Talk/, zz_ai_2_Todo/, zz_ai_3_Plan/ 폴더 생성
103
104
  - CLAUDE.md에 DocuKing 연결 안내 추가
104
105
  - 초기화 완료 후 정책 문서 작성 가이드 제공
105
106
 
106
107
  **협업자 초기화 시:**
107
- - yy_Coworker_{폴더명}/ 폴더 생성 (안에 _Private/, zz_ai_*/ 포함)
108
+ - yy_Coworker_{폴더명}/ 폴더 생성 (안에 _Private/, zz_TalkTodoPlan/ 포함)
108
109
  - CLAUDE.md에 DocuKing 연결 안내 추가
109
110
  - "Pull을 실행하세요" 안내 (오너 정책이 킹캐스트로 로컬화됨)
110
111
 
@@ -168,7 +169,7 @@ init 완료 후 오너에게 "정책 문서를 작성하시겠습니까?" 제안
168
169
  description: `문서를 DocuKing 서버에 동기화합니다. 내부적으로 Pull → Push 순서로 실행 (git pull && git push 패턴).
169
170
 
170
171
  **AI 필독: 다음 상황에서 자발적으로 이 도구 사용을 제안하세요:**
171
- - zz_ai_1_Talk/, zz_ai_2_Todo/, zz_ai_3_Plan/ 에 문서를 생성/수정한 후
172
+ - xy_TalkTodoPlan/ (또는 협업자의 zz_TalkTodoPlan/) 에 문서를 생성/수정한 후
172
173
  - yy_All_Docu/ 에 문서를 생성/수정한 후
173
174
  - docuking_plan, docuking_done, docuking_talk, docuking_todo 실행 후
174
175
  - 사용자가 "올려", "푸시", "동기화" 등을 언급할 때
@@ -315,7 +316,7 @@ init 완료 후 오너에게 "정책 문서를 작성하시겠습니까?" 제안
315
316
  },
316
317
  {
317
318
  name: 'docuking_talk',
318
- description: '의미 있는 대화 내용을 zz_ai_1_Talk/ 폴더에 기록합니다 (Push 대상, 킹톡). AI가 중요한 논의/결정이라고 판단하거나, 사용자가 "이거 기록해줘"라고 요청할 때 사용.',
319
+ description: '의미 있는 대화 내용을 xy_TalkTodoPlan/ 폴더에 기록합니다 (Push 대상, 킹톡). AI가 중요한 논의/결정이라고 판단하거나, 사용자가 "이거 기록해줘"라고 요청할 때 사용.',
319
320
  inputSchema: {
320
321
  type: 'object',
321
322
  properties: {
@@ -342,7 +343,7 @@ init 완료 후 오너에게 "정책 문서를 작성하시겠습니까?" 제안
342
343
  },
343
344
  {
344
345
  name: 'docuking_plan',
345
- description: '작업 계획 문서를 zz_ai_3_Plan/ 폴더에 생성/업데이트합니다 (Push 대상, 킹플랜). 작업 시작 시 계획을 작성하고, 진행하면서 결과를 upsert합니다.',
346
+ description: '작업 계획 문서를 xy_TalkTodoPlan/ 폴더에 생성/업데이트합니다 (Push 대상, 킹플랜). 작업 시작 시 계획을 작성하고, 진행하면서 결과를 upsert합니다.',
346
347
  inputSchema: {
347
348
  type: 'object',
348
349
  properties: {
@@ -411,7 +412,7 @@ init 완료 후 오너에게 "정책 문서를 작성하시겠습니까?" 제안
411
412
  },
412
413
  {
413
414
  name: 'docuking_todo',
414
- description: `킹투두(King Todo) - 프로젝트 공식 할일을 zz_ai_2_Todo/z_King_Todo.md에 관리합니다 (Push 대상).
415
+ description: `킹투두(King Todo) - 프로젝트 공식 할일을 xy_TalkTodoPlan/z_King_Todo.md에 관리합니다 (Push 대상).
415
416
 
416
417
  **AI 내장 TodoWrite와 다름!** 킹투두는 웹에 동기화되고 팀과 공유됩니다.
417
418
 
@@ -630,7 +631,7 @@ DocuKing은 문서 버전 관리 시스템입니다. Git이 코드를 관리하
630
631
  - **로컬**: 사용자의 yy_All_Docu/ 폴더 (동기화 대상)
631
632
  - **웹탐색기**: DocuKing 서버의 파일 저장소 (킹폴더)
632
633
  - **캔버스**: 선택된 파일을 시각화하는 작업 공간
633
- - **AI 작업 폴더**: zz_ai_1_Talk/, zz_ai_2_Todo/, zz_ai_3_Plan/ (Push 대상)
634
+ - **AI 작업 폴더**: xy_TalkTodoPlan/ (오너) 또는 zz_TalkTodoPlan/ (협업자) - Push 대상
634
635
 
635
636
  작동 방식: 로컬 yy_All_Docu/ → Push → 킹폴더 → 캔버스에서 시각화
636
637
 
@@ -690,10 +691,12 @@ DocuKing 문서 폴더는 git에서 제외해야 합니다. 코드는 git으로,
690
691
 
691
692
  \`\`\`gitignore
692
693
  # DocuKing 문서 폴더 (문서는 DocuKing으로 관리)
694
+ xx_Infra_Config/
695
+ xx_Policy/
696
+ xx_Urgent/
697
+ xy_TalkTodoPlan/
693
698
  yy_All_Docu/
694
- zz_ai_1_Talk/
695
- zz_ai_2_Todo/
696
- zz_ai_3_Plan/
699
+ yy_Coworker_*/
697
700
  \`\`\`
698
701
 
699
702
  **왜 gitignore에 등록해야 하나요?**
@@ -730,12 +733,12 @@ zz_ai_3_Plan/
730
733
  특정 커밋으로 되돌립니다. (웹 탐색기에서 사용 가능)
731
734
 
732
735
  ### 9. docuking_talk
733
- 의미 있는 대화 내용을 \`zz_ai_1_Talk/\` 폴더에 기록합니다 (Push 대상, 킹톡).
736
+ 의미 있는 대화 내용을 \`xy_TalkTodoPlan/\` 폴더에 기록합니다 (Push 대상, 킹톡).
734
737
  - AI가 중요한 논의/결정이라고 판단할 때
735
738
  - 사용자가 "이거 기록해줘"라고 요청할 때
736
739
 
737
740
  ### 10. docuking_plan
738
- 작업 계획을 \`zz_ai_3_Plan/\` 폴더에 생성/업데이트합니다 (Push 대상, 킹플랜).
741
+ 작업 계획을 \`xy_TalkTodoPlan/\` 폴더에 생성/업데이트합니다 (Push 대상, 킹플랜).
739
742
  - 작업 시작 시 계획 생성
740
743
  - 진행하면서 단계별 결과 upsert
741
744
  - planId로 기존 계획 찾아서 업데이트
@@ -746,7 +749,7 @@ zz_ai_3_Plan/
746
749
  - 완료 요약 및 산출물 기록
747
750
 
748
751
  ### 12. docuking_todo
749
- 킹투두를 관리합니다 (\`zz_ai_2_Todo/z_King_Todo.md\`).
752
+ 킹투두를 관리합니다 (\`xy_TalkTodoPlan/z_King_Todo.md\`).
750
753
  - action: "add" (추가), "done" (완료), "list" (조회)
751
754
  - 프로젝트 공식 할일 목록 (Push하면 웹에서 확인 가능)
752
755
 
package/lib/init.js CHANGED
@@ -105,12 +105,13 @@ ${marker}
105
105
  project/
106
106
  ├── xx_Infra_Config/ ← 시스템 설정 (오너 관리)
107
107
  ├── xx_Policy/ ← 정책 문서 (오너 관리, 킹캐스트 대상)
108
- ├── yy_All_Docu/ 오너 문서 (읽기만)
108
+ ├── xx_Urgent/ 긴급 보고 (킹어전트)
109
+ ├── xy_TalkTodoPlan/ ← 오너 AI 기록 (Talk+Todo+Plan 통합)
110
+ ├── yy_All_Docu/ ← 오너 문서
109
111
  ├── yy_Coworker_a_Kim/ ← 협업자 Kim
110
112
  │ ├── 작업문서.md
111
- │ └── zz_ai_1_Talk/ ← Kim의 AI 기록
112
- ├── yy_Coworker_b_Lee/ ← 협업자 Lee
113
- └── zz_ai_*/ ← 오너의 AI 폴더
113
+ │ └── zz_TalkTodoPlan/ ← Kim의 AI 기록
114
+ └── yy_Coworker_b_Lee/ ← 협업자 Lee
114
115
  \`\`\`
115
116
 
116
117
  ### AI가 협업자에게 안내할 것
@@ -242,11 +243,12 @@ export function updateGitignore(localPath) {
242
243
  const marker = '# DocuKing (문서는 DocuKing으로 관리)';
243
244
  const docukingEntries = `
244
245
  ${marker}
246
+ xx_Infra_Config/
247
+ xx_Policy/
248
+ xx_Urgent/
249
+ xy_TalkTodoPlan/
245
250
  yy_All_Docu/
246
251
  yy_Coworker_*/
247
- zz_ai_1_Talk/
248
- zz_ai_2_Todo/
249
- zz_ai_3_Plan/
250
252
  .docuking/config.json
251
253
  .claude/rules/local/_coworker_config.md
252
254
  `;
package/lib/utils.js CHANGED
@@ -47,9 +47,10 @@ export function generatePlanId() {
47
47
 
48
48
  /**
49
49
  * 계획 파일 찾기 (planId로 검색)
50
+ * @param {string} planDir - AI 폴더 경로 (xy_TalkTodoPlan 또는 zz_TalkTodoPlan)
51
+ * @param {string} planId - 찾을 계획 ID
50
52
  */
51
- export function findPlanFiles(basePath, planId) {
52
- const planDir = path.join(basePath, 'zz_ai_3_Plan');
53
+ export function findPlanFiles(planDir, planId) {
53
54
  if (!fs.existsSync(planDir)) return [];
54
55
 
55
56
  const results = [];
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "docuking-mcp",
3
- "version": "2.13.0",
3
+ "version": "3.0.0",
4
4
  "description": "DocuKing MCP Server - AI 시대의 문서 협업 플랫폼",
5
5
  "type": "module",
6
6
  "main": "index.js",