@01b/team-kb 0.1.3 → 0.2.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/dist/index.js CHANGED
@@ -277,16 +277,6 @@ async function ensureGitignorePatterns(dir, patterns) {
277
277
  }
278
278
 
279
279
  // src/commands/wire-claude.ts
280
- function buildProjectSection(ctx) {
281
- let section = "\n## \uD504\uB85C\uC81D\uD2B8\n";
282
- section += `- ${ctx.techStack}
283
- `;
284
- if (ctx.domains) section += `- \uB2F4\uB2F9: ${ctx.domains}
285
- `;
286
- section += `- \uD604\uC7AC repo: ${ctx.repoName}
287
- `;
288
- return section;
289
- }
290
280
  function buildKbLocationContent(ctx) {
291
281
  return `## KB \uC808\uB300 \uACBD\uB85C
292
282
  LLM\uC740 \uD30C\uC77C \uC811\uADFC \uBC0F \uC258 \uC2A4\uD06C\uB9BD\uD2B8 \uC2E4\uD589 \uC2DC \uBC18\uB4DC\uC2DC \uC544\uB798\uC758 \uC808\uB300 \uACBD\uB85C\uB97C \uADF8\uB300\uB85C \uC0AC\uC6A9\uD560 \uAC83.
@@ -299,20 +289,6 @@ LLM\uC740 \uD30C\uC77C \uC811\uADFC \uBC0F \uC258 \uC2A4\uD06C\uB9BD\uD2B8 \uC2E
299
289
  async function wireClaude(ctx) {
300
290
  const rulesDir = path6.join(ctx.projectRoot, ".claude", "rules");
301
291
  await fs7.ensureDir(rulesDir);
302
- const claudeMdPath = path6.join(ctx.projectRoot, "CLAUDE.md");
303
- const projectSection = buildProjectSection(ctx);
304
- if (fs7.existsSync(claudeMdPath)) {
305
- const existing = await fs7.readFile(claudeMdPath, "utf-8");
306
- if (!existing.includes("## \uD504\uB85C\uC81D\uD2B8")) {
307
- await fs7.appendFile(claudeMdPath, projectSection);
308
- log.step("CLAUDE.md\uC5D0 \uD504\uB85C\uC81D\uD2B8 \uC815\uBCF4 \uCD94\uAC00");
309
- } else {
310
- log.step("CLAUDE.md\uC5D0 \uD504\uB85C\uC81D\uD2B8 \uC815\uBCF4 \uC774\uBBF8 \uC874\uC7AC \u2014 \uC2A4\uD0B5");
311
- }
312
- } else {
313
- await fs7.writeFile(claudeMdPath, projectSection.trimStart());
314
- log.step("CLAUDE.md \uC0DD\uC131");
315
- }
316
292
  const aiContextDir = path6.join(ctx.kbPath, "ai-context");
317
293
  const symlinkTargets = [
318
294
  { name: "kb-rules.md", target: path6.join(aiContextDir, "kb-rules.md") },
@@ -349,19 +325,10 @@ async function wireClaude(ctx) {
349
325
  // src/commands/wire-gemini.ts
350
326
  import fs8 from "fs-extra";
351
327
  import path7 from "path";
352
- function buildGeminiMd(ctx) {
353
- let content = "@.gemini/kb-import.md\n";
354
- content += "\n## \uD504\uB85C\uC81D\uD2B8\n";
355
- content += `- ${ctx.techStack}
356
- `;
357
- if (ctx.domains) content += `- \uB2F4\uB2F9: ${ctx.domains}
358
- `;
359
- content += `- \uD604\uC7AC repo: ${ctx.repoName}
360
- `;
361
- return content;
328
+ function buildGeminiMd() {
329
+ return "@.gemini/kb-import.md\n";
362
330
  }
363
331
  function buildKbImportMd(ctx) {
364
- const aiContext = path7.join(ctx.kbPath, "ai-context");
365
332
  let content = `## KB \uC808\uB300 \uACBD\uB85C
366
333
  LLM\uC740 \uD30C\uC77C \uC811\uADFC \uBC0F \uC258 \uC2A4\uD06C\uB9BD\uD2B8 \uC2E4\uD589 \uC2DC \uBC18\uB4DC\uC2DC \uC544\uB798\uC758 \uC808\uB300 \uACBD\uB85C\uB97C \uADF8\uB300\uB85C \uC0AC\uC6A9\uD560 \uAC83.
367
334
  - KB \uB8E8\uD2B8: ${ctx.kbPath}
@@ -370,15 +337,14 @@ LLM\uC740 \uD30C\uC77C \uC811\uADFC \uBC0F \uC258 \uC2A4\uD06C\uB9BD\uD2B8 \uC2E
370
337
  - \uB85C\uCEEC \uC778\uB371\uC2A4 \uC7AC\uC0DD\uC131 \uC2A4\uD06C\uB9BD\uD2B8: ${ctx.kbPath}/.kb/scripts/rebuild-index.sh
371
338
 
372
339
  `;
373
- content += `@${aiContext}/kb-rules.md
374
- `;
375
- content += `@${aiContext}/team-focus.md
376
- `;
340
+ content += "@kb-context/kb-rules.md\n";
341
+ content += "@kb-context/team-focus.md\n";
342
+ const aiContext = path7.join(ctx.kbPath, "ai-context");
377
343
  if (fs8.existsSync(aiContext)) {
378
344
  const files = fs8.readdirSync(aiContext);
379
345
  for (const file of files) {
380
346
  if (file.endsWith("-overview.md")) {
381
- content += `@${aiContext}/${file}
347
+ content += `@kb-context/${file}
382
348
  `;
383
349
  }
384
350
  }
@@ -389,18 +355,23 @@ async function wireGemini(ctx) {
389
355
  const geminiDir = path7.join(ctx.projectRoot, ".gemini");
390
356
  await fs8.ensureDir(geminiDir);
391
357
  const geminiMdPath = path7.join(ctx.projectRoot, "GEMINI.md");
358
+ const importLine = buildGeminiMd();
392
359
  if (fs8.existsSync(geminiMdPath)) {
393
360
  const existing = await fs8.readFile(geminiMdPath, "utf-8");
394
- if (!existing.includes("## \uD504\uB85C\uC81D\uD2B8")) {
395
- await fs8.appendFile(geminiMdPath, "\n" + buildGeminiMd(ctx));
396
- log.step("GEMINI.md\uC5D0 \uD504\uB85C\uC81D\uD2B8 \uC815\uBCF4 \uCD94\uAC00");
361
+ if (!existing.includes("@.gemini/kb-import.md")) {
362
+ const updated = importLine + "\n" + existing;
363
+ await fs8.writeFile(geminiMdPath, updated);
364
+ log.step("GEMINI.md\uC5D0 KB @import \uCD94\uAC00");
397
365
  } else {
398
- log.step("GEMINI.md\uC5D0 \uD504\uB85C\uC81D\uD2B8 \uC815\uBCF4 \uC774\uBBF8 \uC874\uC7AC \u2014 \uC2A4\uD0B5");
366
+ log.step("GEMINI.md\uC5D0 KB @import \uC774\uBBF8 \uC874\uC7AC \u2014 \uC2A4\uD0B5");
399
367
  }
400
368
  } else {
401
- await fs8.writeFile(geminiMdPath, buildGeminiMd(ctx));
369
+ await fs8.writeFile(geminiMdPath, importLine);
402
370
  log.step("GEMINI.md \uC0DD\uC131");
403
371
  }
372
+ const aiContextDir = path7.join(ctx.kbPath, "ai-context");
373
+ const kbContextLink = path7.join(geminiDir, "kb-context");
374
+ await createSymlink(aiContextDir, kbContextLink);
404
375
  const importPath = path7.join(geminiDir, "kb-import.md");
405
376
  await fs8.writeFile(importPath, buildKbImportMd(ctx));
406
377
  log.step(".gemini/kb-import.md \uC0DD\uC131 (KB \uACBD\uB85C + @import)");
@@ -410,7 +381,8 @@ async function wireGemini(ctx) {
410
381
  log.step(".gemini/settings.json \uC0DD\uC131");
411
382
  }
412
383
  await ensureGitignorePatterns(ctx.projectRoot, [
413
- ".gemini/kb-import.md"
384
+ ".gemini/kb-import.md",
385
+ ".gemini/kb-context"
414
386
  ]);
415
387
  log.success("Gemini CLI \uC5F0\uACB0 \uC644\uB8CC");
416
388
  }
@@ -418,17 +390,8 @@ async function wireGemini(ctx) {
418
390
  // src/commands/wire-codex.ts
419
391
  import fs9 from "fs-extra";
420
392
  import path8 from "path";
421
- function buildAgentsMd(ctx) {
422
- let content = "# Project\n";
423
- content += `- ${ctx.techStack}
424
- `;
425
- if (ctx.domains) content += `- \uB2F4\uB2F9: ${ctx.domains}
426
- `;
427
- content += `- \uD604\uC7AC repo: ${ctx.repoName}
428
- `;
429
- content += "\n# Knowledge Base\n";
430
- content += "- \uC138\uC158 \uC2DC\uC791 \uC2DC \uBC18\uB4DC\uC2DC .codex/kb-directive.md \uD30C\uC77C\uC744 \uBA3C\uC800 \uC77D\uACE0 \uADF8 \uC548\uC758 \uACBD\uB85C \uC9C0\uC2DC\uB97C \uB530\uB97C \uAC83\n";
431
- return content;
393
+ function buildAgentsMd() {
394
+ return "# Knowledge Base\n- \uC138\uC158 \uC2DC\uC791 \uC2DC \uBC18\uB4DC\uC2DC .codex/kb-directive.md \uD30C\uC77C\uC744 \uBA3C\uC800 \uC77D\uACE0 \uADF8 \uC548\uC758 \uACBD\uB85C \uC9C0\uC2DC\uB97C \uB530\uB97C \uAC83\n";
432
395
  }
433
396
  function buildDirectiveMd(ctx) {
434
397
  const aiContext = path8.join(ctx.kbPath, "ai-context");
@@ -447,16 +410,17 @@ async function wireCodex(ctx) {
447
410
  const codexDir = path8.join(ctx.projectRoot, ".codex");
448
411
  await fs9.ensureDir(codexDir);
449
412
  const agentsMdPath = path8.join(ctx.projectRoot, "AGENTS.md");
413
+ const kbDirective = buildAgentsMd();
450
414
  if (fs9.existsSync(agentsMdPath)) {
451
415
  const existing = await fs9.readFile(agentsMdPath, "utf-8");
452
- if (!existing.includes("# Project")) {
453
- await fs9.appendFile(agentsMdPath, "\n" + buildAgentsMd(ctx));
454
- log.step("AGENTS.md\uC5D0 \uD504\uB85C\uC81D\uD2B8 \uC815\uBCF4 \uCD94\uAC00");
416
+ if (!existing.includes("# Knowledge Base")) {
417
+ await fs9.appendFile(agentsMdPath, "\n" + kbDirective);
418
+ log.step("AGENTS.md\uC5D0 KB \uC9C0\uC2DC\uBB38 \uCD94\uAC00");
455
419
  } else {
456
- log.step("AGENTS.md\uC5D0 \uD504\uB85C\uC81D\uD2B8 \uC815\uBCF4 \uC774\uBBF8 \uC874\uC7AC \u2014 \uC2A4\uD0B5");
420
+ log.step("AGENTS.md\uC5D0 KB \uC9C0\uC2DC\uBB38 \uC774\uBBF8 \uC874\uC7AC \u2014 \uC2A4\uD0B5");
457
421
  }
458
422
  } else {
459
- await fs9.writeFile(agentsMdPath, buildAgentsMd(ctx));
423
+ await fs9.writeFile(agentsMdPath, kbDirective);
460
424
  log.step("AGENTS.md \uC0DD\uC131");
461
425
  }
462
426
  const directivePath = path8.join(codexDir, "kb-directive.md");
@@ -482,15 +446,7 @@ async function collectWireContext() {
482
446
  }
483
447
  const projectRoot = process.cwd();
484
448
  const repoName = projectRoot.split("/").pop() || "unknown";
485
- const techStack = await input3({
486
- message: "\uAE30\uC220 \uC2A4\uD0DD",
487
- default: "Spring Boot + Kotlin, Gradle"
488
- });
489
- const domains = await input3({
490
- message: "\uB2F4\uB2F9 \uB3C4\uBA54\uC778",
491
- default: ""
492
- });
493
- return { kbPath, projectRoot, techStack, domains, repoName };
449
+ return { kbPath, projectRoot, repoName };
494
450
  }
495
451
  async function wireCommand(tool) {
496
452
  const validTools = ["claude", "gemini", "codex"];
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/index.ts","../src/commands/init.ts","../src/utils/log.ts","../src/utils/template.ts","../src/utils/config.ts","../src/utils/git.ts","../src/commands/join.ts","../src/commands/wire.ts","../src/commands/wire-claude.ts","../src/utils/symlink.ts","../src/utils/gitignore.ts","../src/commands/wire-gemini.ts","../src/commands/wire-codex.ts","../src/commands/doctor.ts","../src/commands/uninstall.ts"],"sourcesContent":["import { Command } from \"commander\";\nimport { createRequire } from \"node:module\";\nimport { initCommand } from \"./commands/init.js\";\nimport { joinCommand } from \"./commands/join.js\";\nimport { wireCommand } from \"./commands/wire.js\";\nimport { doctorCommand } from \"./commands/doctor.js\";\nimport { uninstallCommand } from \"./commands/uninstall.js\";\n\nconst require = createRequire(import.meta.url);\nconst { version } = require(\"../package.json\");\n\nconst program = new Command();\n\nprogram\n .name(\"kb\")\n .description(\"Team Knowledge Base harness CLI\")\n .version(version);\n\nprogram\n .command(\"init\")\n .description(\"KB 최초 생성 (팀 리드)\")\n .action(initCommand);\n\nprogram\n .command(\"join\")\n .description(\"기존 KB에 합류 (팀원)\")\n .argument(\"<remote-url>\", \"Git remote URL\")\n .action(joinCommand);\n\nprogram\n .command(\"wire\")\n .description(\"프로젝트에 LLM 도구 연결\")\n .argument(\"<tool>\", \"claude | gemini | codex\")\n .action(wireCommand);\n\nprogram\n .command(\"doctor\")\n .description(\"KB 환경 무결성 검증\")\n .action(doctorCommand);\n\nprogram\n .command(\"uninstall\")\n .description(\"KB wiring 제거 + 설정 정리\")\n .action(uninstallCommand);\n\nprogram.parse();\n","import { input } from \"@inquirer/prompts\";\nimport fs from \"fs-extra\";\nimport path from \"node:path\";\nimport { fileURLToPath } from \"node:url\";\nimport { log } from \"../utils/log.js\";\nimport { renderTemplate } from \"../utils/template.js\";\nimport { saveKbPath } from \"../utils/config.js\";\nimport { initRepo } from \"../utils/git.js\";\n\nconst __dirname = path.dirname(fileURLToPath(import.meta.url));\nconst TEMPLATES_DIR = path.join(__dirname, \"..\", \"templates\", \"kb-structure\");\n\nconst KB_DIRS = [\n \"global\",\n \"rules\",\n \"analysis\",\n \"decisions\",\n \"troubleshoot\",\n \"drafts\",\n \"areas\",\n \"templates\",\n \"ai-context\",\n \"archive\",\n \"00-inbox\",\n \"99-personal\",\n \".kb/hooks\",\n \".kb/scripts\",\n \".kb/setup\",\n \".github/workflows\",\n];\n\nexport async function initCommand(): Promise<void> {\n log.info(\"KB 최초 생성을 시작합니다.\");\n\n const defaultPath = path.join(process.env.HOME || \"~\", \"team-kb\");\n const kbPath = await input({\n message: \"KB 경로\",\n default: defaultPath,\n });\n const resolvedPath = kbPath.startsWith(\"~\")\n ? kbPath.replace(\"~\", process.env.HOME || \"\")\n : path.resolve(kbPath);\n\n if (fs.existsSync(resolvedPath) && fs.readdirSync(resolvedPath).length > 0) {\n log.error(`${resolvedPath} 가 이미 존재하고 비어있지 않습니다.`);\n return;\n }\n\n const remoteUrl = await input({\n message: \"Git remote URL (없으면 엔터)\",\n default: \"\",\n });\n\n const today = new Date().toISOString().split(\"T\")[0];\n const vars = { date: today };\n\n // 1. Create directory structure\n log.info(\"폴더 구조 생성 중...\");\n for (const dir of KB_DIRS) {\n await fs.ensureDir(path.join(resolvedPath, dir));\n }\n log.success(\"폴더 구조 생성 완료\");\n\n // 2. Copy .gitignore\n const gitignoreSrc = path.join(TEMPLATES_DIR, \"gitignore\");\n await fs.copy(gitignoreSrc, path.join(resolvedPath, \".gitignore\"));\n log.step(\".gitignore 생성\");\n\n // 3. Copy and render note templates\n const noteTemplatesDir = path.join(TEMPLATES_DIR, \"note-templates\");\n const noteTemplates = await fs.readdir(noteTemplatesDir);\n for (const file of noteTemplates) {\n const content = await fs.readFile(path.join(noteTemplatesDir, file), \"utf-8\");\n const rendered = renderTemplate(content, vars);\n await fs.writeFile(path.join(resolvedPath, \"templates\", file), rendered);\n }\n log.step(\"노트 템플릿 생성\");\n\n // 4. Copy pre-commit hook\n const preCommitSrc = path.join(TEMPLATES_DIR, \"pre-commit\");\n const preCommitDest = path.join(resolvedPath, \".kb\", \"hooks\", \"pre-commit\");\n await fs.copy(preCommitSrc, preCommitDest);\n await fs.chmod(preCommitDest, 0o755);\n log.step(\"pre-commit hook 생성\");\n\n // 5. Copy rebuild-index.sh\n const rebuildSrc = path.join(TEMPLATES_DIR, \"rebuild-index.sh\");\n const rebuildDest = path.join(resolvedPath, \".kb\", \"scripts\", \"rebuild-index.sh\");\n await fs.copy(rebuildSrc, rebuildDest);\n await fs.chmod(rebuildDest, 0o755);\n log.step(\"rebuild-index.sh 생성\");\n\n // 6. Copy GitHub Actions workflows\n const healthSrc = path.join(TEMPLATES_DIR, \"kb-health.yml\");\n const coverageSrc = path.join(TEMPLATES_DIR, \"kb-coverage.yml\");\n await fs.copy(healthSrc, path.join(resolvedPath, \".github\", \"workflows\", \"kb-health.yml\"));\n await fs.copy(coverageSrc, path.join(resolvedPath, \".github\", \"workflows\", \"kb-coverage.yml\"));\n log.step(\"GitHub Actions 워크플로우 생성\");\n\n // 7. Create kb-index.json (empty)\n await fs.writeJson(path.join(resolvedPath, \"kb-index.json\"), []);\n log.step(\"kb-index.json 초기화 (빈 배열)\");\n\n // 8. Create ai-context files\n const kbRulesSrc = path.join(TEMPLATES_DIR, \"kb-rules.md\");\n const kbRulesContent = await fs.readFile(kbRulesSrc, \"utf-8\");\n await fs.writeFile(\n path.join(resolvedPath, \"ai-context\", \"kb-rules.md\"),\n renderTemplate(kbRulesContent, vars),\n );\n\n const teamFocusSrc = path.join(TEMPLATES_DIR, \"team-focus.md\");\n const teamFocusContent = await fs.readFile(teamFocusSrc, \"utf-8\");\n await fs.writeFile(\n path.join(resolvedPath, \"ai-context\", \"team-focus.md\"),\n renderTemplate(teamFocusContent, vars),\n );\n log.step(\"ai-context/ 파일 생성 (kb-rules.md, team-focus.md)\");\n\n // 9. Git init + remote\n await initRepo(resolvedPath, remoteUrl || undefined);\n log.step(\"git init\" + (remoteUrl ? ` + remote: ${remoteUrl}` : \"\"));\n\n // 10. Install pre-commit hook\n const gitHookDest = path.join(resolvedPath, \".git\", \"hooks\", \"pre-commit\");\n await fs.copy(preCommitDest, gitHookDest);\n await fs.chmod(gitHookDest, 0o755);\n log.step(\"pre-commit hook 설치 (.git/hooks/)\");\n\n // 11. Save config\n await saveKbPath(resolvedPath);\n\n // 12. Initial commit\n const git = (await import(\"simple-git\")).default(resolvedPath);\n await git.add(\".\");\n await git.commit(\"init: KB 구조 생성\");\n log.step(\"초기 커밋 완료\");\n\n log.success(`KB 생성 완료: ${resolvedPath}`);\n log.info(\"다음 단계:\");\n log.step(\"ai-context/ 오버뷰 초안 작성\");\n log.step(\"git push\");\n log.step(\"팀원에게 kb join 안내\");\n}\n","import pc from \"picocolors\";\n\nexport const log = {\n info: (msg: string) => console.log(pc.blue(\"ℹ\") + \" \" + msg),\n success: (msg: string) => console.log(pc.green(\"✔\") + \" \" + msg),\n warn: (msg: string) => console.log(pc.yellow(\"⚠\") + \" \" + msg),\n error: (msg: string) => console.error(pc.red(\"✖\") + \" \" + msg),\n step: (msg: string) => console.log(pc.gray(\" →\") + \" \" + msg),\n};\n","/**\n * Simple template variable replacement.\n * Replaces {{VAR_NAME}} with provided values.\n */\nexport function renderTemplate(\n template: string,\n vars: Record<string, string>,\n): string {\n let result = template;\n for (const [key, value] of Object.entries(vars)) {\n result = result.replaceAll(`{{${key}}}`, value);\n }\n return result;\n}\n","import fs from \"fs-extra\";\nimport path from \"node:path\";\nimport { log } from \"./log.js\";\n\nconst CONFIG_DIR = path.join(\n process.env.HOME || \"~\",\n \".config\",\n \"kb-cli\",\n);\nconst CONFIG_PATH = path.join(CONFIG_DIR, \"config.json\");\n\ninterface KbConfig {\n kbPath: string;\n}\n\n/**\n * Read KB path from config file.\n */\nexport function getKbPath(): string | undefined {\n try {\n if (fs.existsSync(CONFIG_PATH)) {\n const config: KbConfig = fs.readJsonSync(CONFIG_PATH);\n return config.kbPath;\n }\n } catch {\n // ignore parse errors\n }\n return undefined;\n}\n\n/**\n * Save KB path to config file.\n */\nexport async function saveKbPath(kbPath: string): Promise<void> {\n await fs.ensureDir(CONFIG_DIR);\n await fs.writeJson(CONFIG_PATH, { kbPath }, { spaces: 2 });\n log.step(`설정 저장: ${CONFIG_PATH}`);\n}\n\n/**\n * Remove config file.\n */\nexport async function removeConfig(): Promise<boolean> {\n if (fs.existsSync(CONFIG_PATH)) {\n await fs.remove(CONFIG_PATH);\n return true;\n }\n return false;\n}\n\nexport { CONFIG_PATH };\n","import simpleGit, { type SimpleGit } from \"simple-git\";\nimport fs from \"fs-extra\";\n\nexport function getGit(cwd?: string): SimpleGit {\n return simpleGit(cwd);\n}\n\nexport async function isGitRepo(dir: string): Promise<boolean> {\n try {\n const git = getGit(dir);\n return await git.checkIsRepo();\n } catch {\n return false;\n }\n}\n\nexport async function initRepo(\n dir: string,\n remote?: string,\n): Promise<void> {\n const git = getGit(dir);\n await git.init();\n if (remote) {\n await git.addRemote(\"origin\", remote);\n }\n}\n\nexport async function cloneRepo(\n url: string,\n dir: string,\n): Promise<void> {\n await fs.ensureDir(dir);\n const git = simpleGit();\n await git.clone(url, dir);\n}\n","import { input } from \"@inquirer/prompts\";\nimport fs from \"fs-extra\";\nimport path from \"node:path\";\nimport { log } from \"../utils/log.js\";\nimport { saveKbPath } from \"../utils/config.js\";\nimport { cloneRepo } from \"../utils/git.js\";\n\nexport async function joinCommand(remoteUrl: string): Promise<void> {\n log.info(\"기존 KB에 합류합니다.\");\n\n const defaultPath = path.join(process.env.HOME || \"~\", \"team-kb\");\n const kbPath = await input({\n message: \"로컬 경로\",\n default: defaultPath,\n });\n const resolvedPath = kbPath.startsWith(\"~\")\n ? kbPath.replace(\"~\", process.env.HOME || \"\")\n : path.resolve(kbPath);\n\n if (fs.existsSync(resolvedPath) && fs.readdirSync(resolvedPath).length > 0) {\n log.error(`${resolvedPath} 가 이미 존재하고 비어있지 않습니다.`);\n return;\n }\n\n // 1. Clone\n log.info(\"git clone 중...\");\n await cloneRepo(remoteUrl, resolvedPath);\n log.success(\"clone 완료\");\n\n // 2. Install pre-commit hook\n const hookSrc = path.join(resolvedPath, \".kb\", \"hooks\", \"pre-commit\");\n const hookDest = path.join(resolvedPath, \".git\", \"hooks\", \"pre-commit\");\n if (fs.existsSync(hookSrc)) {\n await fs.copy(hookSrc, hookDest);\n await fs.chmod(hookDest, 0o755);\n log.step(\"pre-commit hook 설치\");\n } else {\n log.warn(\"pre-commit hook 원본이 없습니다 (.kb/hooks/pre-commit)\");\n }\n\n // 3. Save config\n await saveKbPath(resolvedPath);\n\n log.success(`KB 합류 완료: ${resolvedPath}`);\n log.info(\"다음 단계:\");\n log.step(\"cd ~/repos/{project} && kb wire claude (또는 gemini / codex)\");\n}\n","import { input } from \"@inquirer/prompts\";\nimport { log } from \"../utils/log.js\";\nimport { getKbPath } from \"../utils/config.js\";\nimport { wireClaude } from \"./wire-claude.js\";\nimport { wireGemini } from \"./wire-gemini.js\";\nimport { wireCodex } from \"./wire-codex.js\";\n\nexport interface WireContext {\n /** Absolute path to the KB repo */\n kbPath: string;\n /** Current project root (cwd) */\n projectRoot: string;\n /** Tech stack (e.g., \"Spring Boot + Kotlin, Gradle\") */\n techStack: string;\n /** Domain areas (e.g., \"할인/쿠폰, 수수료\") */\n domains: string;\n /** Current repo name (e.g., \"coupon-api\") */\n repoName: string;\n}\n\nasync function collectWireContext(): Promise<WireContext | null> {\n // Resolve KB path\n let kbPath = getKbPath();\n if (!kbPath) {\n kbPath = await input({\n message: \"KB 경로를 찾을 수 없습니다. KB 절대 경로를 입력하세요\",\n });\n }\n\n if (!kbPath) {\n log.error(\"KB 경로가 필요합니다. kb init 또는 kb join을 먼저 실행하세요.\");\n return null;\n }\n\n const projectRoot = process.cwd();\n const repoName =\n projectRoot.split(\"/\").pop() || \"unknown\";\n\n const techStack = await input({\n message: \"기술 스택\",\n default: \"Spring Boot + Kotlin, Gradle\",\n });\n\n const domains = await input({\n message: \"담당 도메인\",\n default: \"\",\n });\n\n return { kbPath, projectRoot, techStack, domains, repoName };\n}\n\nexport async function wireCommand(tool: string): Promise<void> {\n const validTools = [\"claude\", \"gemini\", \"codex\"];\n if (!validTools.includes(tool)) {\n log.error(`지원하지 않는 도구: ${tool}. (claude, gemini, codex 중 선택)`);\n return;\n }\n\n log.info(`프로젝트에 ${tool} 연결을 시작합니다.`);\n\n const ctx = await collectWireContext();\n if (!ctx) return;\n\n switch (tool) {\n case \"claude\":\n await wireClaude(ctx);\n break;\n case \"gemini\":\n await wireGemini(ctx);\n break;\n case \"codex\":\n await wireCodex(ctx);\n break;\n }\n}\n","import fs from \"fs-extra\";\nimport path from \"node:path\";\nimport { log } from \"../utils/log.js\";\nimport { createSymlink } from \"../utils/symlink.js\";\nimport { ensureGitignorePatterns } from \"../utils/gitignore.js\";\nimport type { WireContext } from \"./wire.js\";\n\nfunction buildProjectSection(ctx: WireContext): string {\n let section = \"\\n## 프로젝트\\n\";\n section += `- ${ctx.techStack}\\n`;\n if (ctx.domains) section += `- 담당: ${ctx.domains}\\n`;\n section += `- 현재 repo: ${ctx.repoName}\\n`;\n\n return section;\n}\n\nfunction buildKbLocationContent(ctx: WireContext): string {\n return `## KB 절대 경로\nLLM은 파일 접근 및 쉘 스크립트 실행 시 반드시 아래의 절대 경로를 그대로 사용할 것.\n- KB 루트: ${ctx.kbPath}\n- 전체 인덱스: ${ctx.kbPath}/kb-index.json\n- 로컬 인덱스: ${ctx.kbPath}/.kb-index.local.json\n- 로컬 인덱스 재생성 스크립트: ${ctx.kbPath}/.kb/scripts/rebuild-index.sh\n`;\n}\n\nexport async function wireClaude(ctx: WireContext): Promise<void> {\n const rulesDir = path.join(ctx.projectRoot, \".claude\", \"rules\");\n await fs.ensureDir(rulesDir);\n\n // 1. CLAUDE.md — append project info (don't overwrite)\n const claudeMdPath = path.join(ctx.projectRoot, \"CLAUDE.md\");\n const projectSection = buildProjectSection(ctx);\n\n if (fs.existsSync(claudeMdPath)) {\n const existing = await fs.readFile(claudeMdPath, \"utf-8\");\n if (!existing.includes(\"## 프로젝트\")) {\n await fs.appendFile(claudeMdPath, projectSection);\n log.step(\"CLAUDE.md에 프로젝트 정보 추가\");\n } else {\n log.step(\"CLAUDE.md에 프로젝트 정보 이미 존재 — 스킵\");\n }\n } else {\n await fs.writeFile(claudeMdPath, projectSection.trimStart());\n log.step(\"CLAUDE.md 생성\");\n }\n\n // 2. Symlinks to KB ai-context files\n const aiContextDir = path.join(ctx.kbPath, \"ai-context\");\n const symlinkTargets = [\n { name: \"kb-rules.md\", target: path.join(aiContextDir, \"kb-rules.md\") },\n { name: \"team-focus.md\", target: path.join(aiContextDir, \"team-focus.md\") },\n ];\n\n // Also symlink any *-overview.md files\n if (fs.existsSync(aiContextDir)) {\n const files = await fs.readdir(aiContextDir);\n for (const file of files) {\n if (file.endsWith(\"-overview.md\")) {\n symlinkTargets.push({\n name: file,\n target: path.join(aiContextDir, file),\n });\n }\n }\n }\n\n for (const { name, target } of symlinkTargets) {\n await createSymlink(target, path.join(rulesDir, name));\n }\n\n // 3. kb-location.md — explicit paths (local-only)\n const locationPath = path.join(rulesDir, \"kb-location.md\");\n await fs.writeFile(locationPath, buildKbLocationContent(ctx));\n log.step(\"kb-location.md 생성 (KB 절대 경로)\");\n\n // 4. .claude/settings.json\n const settingsPath = path.join(ctx.projectRoot, \".claude\", \"settings.json\");\n if (!fs.existsSync(settingsPath)) {\n await fs.writeJson(settingsPath, {}, { spaces: 2 });\n log.step(\".claude/settings.json 생성\");\n }\n\n // 5. Update .gitignore\n await ensureGitignorePatterns(ctx.projectRoot, [\n \".claude/rules/\",\n ]);\n\n log.success(\"Claude Code 연결 완료\");\n}\n","import fs from \"fs-extra\";\nimport path from \"node:path\";\nimport { log } from \"./log.js\";\n\n/**\n * Create a symlink. If target doesn't exist, warn but still create.\n */\nexport async function createSymlink(\n target: string,\n linkPath: string,\n): Promise<void> {\n await fs.ensureDir(path.dirname(linkPath));\n\n if (fs.existsSync(linkPath)) {\n const stat = await fs.lstat(linkPath);\n if (stat.isSymbolicLink()) {\n const existing = await fs.readlink(linkPath);\n if (existing === target) {\n log.step(`symlink 이미 존재: ${path.basename(linkPath)}`);\n return;\n }\n await fs.remove(linkPath);\n } else {\n log.warn(`${linkPath} 이 일반 파일로 존재. symlink로 교체합니다.`);\n await fs.remove(linkPath);\n }\n }\n\n if (!fs.existsSync(target)) {\n log.warn(`symlink 대상 파일 없음: ${target} (나중에 생성 필요)`);\n }\n\n await fs.symlink(target, linkPath);\n log.step(`symlink 생성: ${path.basename(linkPath)} → ${target}`);\n}\n","import fs from \"fs-extra\";\nimport path from \"node:path\";\nimport { log } from \"./log.js\";\n\n/**\n * Ensure patterns exist in a .gitignore file.\n * Creates the file if it doesn't exist. Skips patterns already present.\n */\nexport async function ensureGitignorePatterns(\n dir: string,\n patterns: string[],\n): Promise<void> {\n const gitignorePath = path.join(dir, \".gitignore\");\n\n let content = \"\";\n if (fs.existsSync(gitignorePath)) {\n content = await fs.readFile(gitignorePath, \"utf-8\");\n }\n\n const lines = content.split(\"\\n\");\n const toAdd: string[] = [];\n\n for (const pattern of patterns) {\n const trimmed = pattern.trim();\n if (!lines.some((line) => line.trim() === trimmed)) {\n toAdd.push(trimmed);\n }\n }\n\n if (toAdd.length === 0) {\n return;\n }\n\n const separator = content.length > 0 && !content.endsWith(\"\\n\") ? \"\\n\" : \"\";\n const section =\n separator +\n \"\\n# KB wiring (local-only)\\n\" +\n toAdd.join(\"\\n\") +\n \"\\n\";\n\n await fs.appendFile(gitignorePath, section);\n log.step(`.gitignore에 ${toAdd.length}개 패턴 추가`);\n}\n","import fs from \"fs-extra\";\nimport path from \"node:path\";\nimport { log } from \"../utils/log.js\";\nimport { ensureGitignorePatterns } from \"../utils/gitignore.js\";\nimport type { WireContext } from \"./wire.js\";\n\nfunction buildGeminiMd(ctx: WireContext): string {\n let content = \"@.gemini/kb-import.md\\n\";\n content += \"\\n## 프로젝트\\n\";\n content += `- ${ctx.techStack}\\n`;\n if (ctx.domains) content += `- 담당: ${ctx.domains}\\n`;\n content += `- 현재 repo: ${ctx.repoName}\\n`;\n\n return content;\n}\n\nfunction buildKbImportMd(ctx: WireContext): string {\n const aiContext = path.join(ctx.kbPath, \"ai-context\");\n\n let content = `## KB 절대 경로\nLLM은 파일 접근 및 쉘 스크립트 실행 시 반드시 아래의 절대 경로를 그대로 사용할 것.\n- KB 루트: ${ctx.kbPath}\n- 전체 인덱스: ${ctx.kbPath}/kb-index.json\n- 로컬 인덱스: ${ctx.kbPath}/.kb-index.local.json\n- 로컬 인덱스 재생성 스크립트: ${ctx.kbPath}/.kb/scripts/rebuild-index.sh\n\n`;\n\n // @import lines\n content += `@${aiContext}/kb-rules.md\\n`;\n content += `@${aiContext}/team-focus.md\\n`;\n\n // Also import any *-overview.md files\n if (fs.existsSync(aiContext)) {\n const files = fs.readdirSync(aiContext);\n for (const file of files) {\n if (file.endsWith(\"-overview.md\")) {\n content += `@${aiContext}/${file}\\n`;\n }\n }\n }\n\n return content;\n}\n\nexport async function wireGemini(ctx: WireContext): Promise<void> {\n const geminiDir = path.join(ctx.projectRoot, \".gemini\");\n await fs.ensureDir(geminiDir);\n\n // 1. GEMINI.md (tracked — project info + @import)\n const geminiMdPath = path.join(ctx.projectRoot, \"GEMINI.md\");\n if (fs.existsSync(geminiMdPath)) {\n const existing = await fs.readFile(geminiMdPath, \"utf-8\");\n if (!existing.includes(\"## 프로젝트\")) {\n await fs.appendFile(geminiMdPath, \"\\n\" + buildGeminiMd(ctx));\n log.step(\"GEMINI.md에 프로젝트 정보 추가\");\n } else {\n log.step(\"GEMINI.md에 프로젝트 정보 이미 존재 — 스킵\");\n }\n } else {\n await fs.writeFile(geminiMdPath, buildGeminiMd(ctx));\n log.step(\"GEMINI.md 생성\");\n }\n\n // 2. .gemini/kb-import.md (local-only — absolute paths + @imports)\n const importPath = path.join(geminiDir, \"kb-import.md\");\n await fs.writeFile(importPath, buildKbImportMd(ctx));\n log.step(\".gemini/kb-import.md 생성 (KB 경로 + @import)\");\n\n // 3. .gemini/settings.json\n const settingsPath = path.join(geminiDir, \"settings.json\");\n if (!fs.existsSync(settingsPath)) {\n await fs.writeJson(settingsPath, {}, { spaces: 2 });\n log.step(\".gemini/settings.json 생성\");\n }\n\n // 4. Update .gitignore\n await ensureGitignorePatterns(ctx.projectRoot, [\n \".gemini/kb-import.md\",\n ]);\n\n log.success(\"Gemini CLI 연결 완료\");\n}\n","import fs from \"fs-extra\";\nimport path from \"node:path\";\nimport { log } from \"../utils/log.js\";\nimport { ensureGitignorePatterns } from \"../utils/gitignore.js\";\nimport type { WireContext } from \"./wire.js\";\n\nfunction buildAgentsMd(ctx: WireContext): string {\n let content = \"# Project\\n\";\n content += `- ${ctx.techStack}\\n`;\n if (ctx.domains) content += `- 담당: ${ctx.domains}\\n`;\n content += `- 현재 repo: ${ctx.repoName}\\n`;\n content += \"\\n# Knowledge Base\\n\";\n content += \"- 세션 시작 시 반드시 .codex/kb-directive.md 파일을 먼저 읽고 그 안의 경로 지시를 따를 것\\n\";\n\n return content;\n}\n\nfunction buildDirectiveMd(ctx: WireContext): string {\n const aiContext = path.join(ctx.kbPath, \"ai-context\");\n\n return `## KB 작동 지시\n- 세션 시작 시 반드시 ${aiContext}/kb-rules.md 를 먼저 읽을 것\n\n## KB 절대 경로\nLLM은 파일 접근 및 쉘 스크립트 실행 시 반드시 아래의 절대 경로를 그대로 사용할 것.\n- KB 루트: ${ctx.kbPath}\n- 전체 인덱스: ${ctx.kbPath}/kb-index.json\n- 로컬 인덱스: ${ctx.kbPath}/.kb-index.local.json\n- 로컬 인덱스 재생성 스크립트: ${ctx.kbPath}/.kb/scripts/rebuild-index.sh\n`;\n}\n\nexport async function wireCodex(ctx: WireContext): Promise<void> {\n const codexDir = path.join(ctx.projectRoot, \".codex\");\n await fs.ensureDir(codexDir);\n\n // 1. AGENTS.md (tracked — project info + directive reference)\n const agentsMdPath = path.join(ctx.projectRoot, \"AGENTS.md\");\n if (fs.existsSync(agentsMdPath)) {\n const existing = await fs.readFile(agentsMdPath, \"utf-8\");\n if (!existing.includes(\"# Project\")) {\n await fs.appendFile(agentsMdPath, \"\\n\" + buildAgentsMd(ctx));\n log.step(\"AGENTS.md에 프로젝트 정보 추가\");\n } else {\n log.step(\"AGENTS.md에 프로젝트 정보 이미 존재 — 스킵\");\n }\n } else {\n await fs.writeFile(agentsMdPath, buildAgentsMd(ctx));\n log.step(\"AGENTS.md 생성\");\n }\n\n // 2. .codex/kb-directive.md (local-only — absolute paths)\n const directivePath = path.join(codexDir, \"kb-directive.md\");\n await fs.writeFile(directivePath, buildDirectiveMd(ctx));\n log.step(\".codex/kb-directive.md 생성 (KB 경로 + 지시)\");\n\n // 3. Update .gitignore\n await ensureGitignorePatterns(ctx.projectRoot, [\n \".codex/kb-directive.md\",\n ]);\n\n log.success(\"Codex CLI 연결 완료\");\n}\n","import fs from \"fs-extra\";\nimport path from \"node:path\";\nimport { log } from \"../utils/log.js\";\nimport { getKbPath, CONFIG_PATH } from \"../utils/config.js\";\n\ninterface CheckResult {\n name: string;\n ok: boolean;\n detail: string;\n}\n\nexport async function doctorCommand(): Promise<void> {\n log.info(\"KB 환경 진단을 시작합니다.\\n\");\n const results: CheckResult[] = [];\n\n // 1. KB config\n const kbPath = getKbPath();\n results.push({\n name: `설정 파일 (${CONFIG_PATH})`,\n ok: !!kbPath,\n detail: kbPath || \"미설정. kb init 또는 kb join을 먼저 실행하세요.\",\n });\n\n if (!kbPath) {\n printResults(results);\n return;\n }\n\n // 2. KB directory exists and is accessible\n const kbExists = fs.existsSync(kbPath);\n results.push({\n name: \"KB 디렉토리 접근\",\n ok: kbExists,\n detail: kbExists ? kbPath : `${kbPath} 경로가 존재하지 않습니다.`,\n });\n\n if (!kbExists) {\n printResults(results);\n return;\n }\n\n // 3. ai-context/kb-rules.md exists\n const kbRulesPath = path.join(kbPath, \"ai-context\", \"kb-rules.md\");\n const kbRulesExists = fs.existsSync(kbRulesPath);\n results.push({\n name: \"ai-context/kb-rules.md\",\n ok: kbRulesExists,\n detail: kbRulesExists ? \"존재\" : \"없음. ai-context/ 초기 파일을 작성하세요.\",\n });\n\n // 4. kb-index.json exists\n const indexPath = path.join(kbPath, \"kb-index.json\");\n const indexExists = fs.existsSync(indexPath);\n results.push({\n name: \"kb-index.json\",\n ok: indexExists,\n detail: indexExists ? \"존재\" : \"없음. git push 후 CI가 생성합니다.\",\n });\n\n // 5. pre-commit hook installed\n const hookPath = path.join(kbPath, \".git\", \"hooks\", \"pre-commit\");\n const hookExists = fs.existsSync(hookPath);\n results.push({\n name: \"pre-commit hook\",\n ok: hookExists,\n detail: hookExists ? \"설치됨\" : \"미설치. kb join을 다시 실행하세요.\",\n });\n\n // 6. Check project wiring (if in a project directory)\n const cwd = process.cwd();\n if (cwd !== kbPath) {\n // Claude\n const claudeRulesDir = path.join(cwd, \".claude\", \"rules\");\n if (fs.existsSync(claudeRulesDir)) {\n const kbRulesLink = path.join(claudeRulesDir, \"kb-rules.md\");\n if (fs.existsSync(kbRulesLink)) {\n const stat = await fs.lstat(kbRulesLink);\n if (stat.isSymbolicLink()) {\n const target = await fs.readlink(kbRulesLink);\n const targetValid = fs.existsSync(target);\n results.push({\n name: \"Claude symlink (kb-rules.md)\",\n ok: targetValid,\n detail: targetValid ? `→ ${target}` : `깨진 symlink → ${target}`,\n });\n }\n }\n\n const locationFile = path.join(claudeRulesDir, \"kb-location.md\");\n results.push({\n name: \"Claude kb-location.md\",\n ok: fs.existsSync(locationFile),\n detail: fs.existsSync(locationFile) ? \"존재\" : \"없음. kb wire claude를 실행하세요.\",\n });\n }\n\n // Gemini\n const geminiImport = path.join(cwd, \".gemini\", \"kb-import.md\");\n if (fs.existsSync(path.join(cwd, \"GEMINI.md\"))) {\n results.push({\n name: \"Gemini kb-import.md\",\n ok: fs.existsSync(geminiImport),\n detail: fs.existsSync(geminiImport) ? \"존재\" : \"없음. kb wire gemini를 실행하세요.\",\n });\n }\n\n // Codex\n const codexDirective = path.join(cwd, \".codex\", \"kb-directive.md\");\n if (fs.existsSync(path.join(cwd, \"AGENTS.md\"))) {\n results.push({\n name: \"Codex kb-directive.md\",\n ok: fs.existsSync(codexDirective),\n detail: fs.existsSync(codexDirective) ? \"존재\" : \"없음. kb wire codex를 실행하세요.\",\n });\n }\n }\n\n printResults(results);\n}\n\nfunction printResults(results: CheckResult[]): void {\n let allOk = true;\n for (const r of results) {\n if (r.ok) {\n log.success(`${r.name}: ${r.detail}`);\n } else {\n log.error(`${r.name}: ${r.detail}`);\n allOk = false;\n }\n }\n\n console.log();\n if (allOk) {\n log.success(\"모든 검증 통과\");\n } else {\n log.warn(\"일부 항목에 문제가 있습니다. 위 메시지를 확인하세요.\");\n }\n}\n","import { confirm } from \"@inquirer/prompts\";\nimport fs from \"fs-extra\";\nimport path from \"node:path\";\nimport { log } from \"../utils/log.js\";\nimport { getKbPath, removeConfig, CONFIG_PATH } from \"../utils/config.js\";\n\nexport async function uninstallCommand(): Promise<void> {\n log.info(\"KB wiring 제거를 시작합니다.\\n\");\n\n const cwd = process.cwd();\n let removed = 0;\n\n // 1. Remove Claude wiring (local-only files only)\n const claudeRulesDir = path.join(cwd, \".claude\", \"rules\");\n if (fs.existsSync(claudeRulesDir)) {\n // Remove symlinks (KB-related only)\n const files = await fs.readdir(claudeRulesDir);\n for (const file of files) {\n const filePath = path.join(claudeRulesDir, file);\n const stat = await fs.lstat(filePath);\n if (stat.isSymbolicLink()) {\n await fs.remove(filePath);\n log.step(`symlink 삭제: .claude/rules/${file}`);\n removed++;\n }\n }\n\n // Remove kb-location.md\n const locationPath = path.join(claudeRulesDir, \"kb-location.md\");\n if (fs.existsSync(locationPath)) {\n await fs.remove(locationPath);\n log.step(\"삭제: .claude/rules/kb-location.md\");\n removed++;\n }\n }\n\n // 2. Remove Gemini wiring (local-only file only)\n const geminiImport = path.join(cwd, \".gemini\", \"kb-import.md\");\n if (fs.existsSync(geminiImport)) {\n await fs.remove(geminiImport);\n log.step(\"삭제: .gemini/kb-import.md\");\n removed++;\n }\n\n // 3. Remove Codex wiring (local-only file only)\n const codexDirective = path.join(cwd, \".codex\", \"kb-directive.md\");\n if (fs.existsSync(codexDirective)) {\n await fs.remove(codexDirective);\n log.step(\"삭제: .codex/kb-directive.md\");\n removed++;\n }\n\n if (removed > 0) {\n log.success(`프로젝트 wiring ${removed}개 파일 제거 완료`);\n } else {\n log.info(\"현재 디렉토리에 제거할 wiring 파일이 없습니다.\");\n }\n\n // 4. Tracked files (CLAUDE.md, GEMINI.md, AGENTS.md) — don't touch\n const trackedFiles = [\"CLAUDE.md\", \"GEMINI.md\", \"AGENTS.md\"].filter(\n (f) => fs.existsSync(path.join(cwd, f)),\n );\n if (trackedFiles.length > 0) {\n log.warn(\n `${trackedFiles.join(\", \")}의 프로젝트 섹션은 수동으로 정리하세요 (사용자 내용과 섞여있을 수 있음).`,\n );\n }\n\n // 5. Remove config file\n const kbPath = getKbPath();\n const shouldRemoveConfig = await confirm({\n message: `설정 파일을 삭제할까요? (${CONFIG_PATH})`,\n default: true,\n });\n\n if (shouldRemoveConfig) {\n const didRemove = await removeConfig();\n if (didRemove) {\n log.step(\"설정 파일 삭제 완료\");\n }\n }\n\n // 6. KB directory — ask but warn\n if (kbPath && fs.existsSync(kbPath)) {\n const shouldRemoveKb = await confirm({\n message: `KB 디렉토리를 삭제할까요? (${kbPath}) — 팀 지식이 모두 삭제됩니다!`,\n default: false,\n });\n\n if (shouldRemoveKb) {\n await fs.remove(kbPath);\n log.step(`KB 디렉토리 삭제: ${kbPath}`);\n } else {\n log.info(`KB 디렉토리 유지: ${kbPath}`);\n }\n }\n\n console.log();\n log.success(\"uninstall 완료\");\n log.info(\"npm uninstall -g kb-cli 로 CLI 자체도 제거할 수 있습니다.\");\n}\n"],"mappings":"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","names":["fs","path","fs","fs","path","fs","input","fs","path","path","input","fs","input","fs","path","fs","path","fs","path","fs","path","path","fs","path","fs","fs","path","path","fs","fs","path","path","fs","input","fs","path","fs","path","fs","path","path","fs","require"]}
1
+ {"version":3,"sources":["../src/index.ts","../src/commands/init.ts","../src/utils/log.ts","../src/utils/template.ts","../src/utils/config.ts","../src/utils/git.ts","../src/commands/join.ts","../src/commands/wire.ts","../src/commands/wire-claude.ts","../src/utils/symlink.ts","../src/utils/gitignore.ts","../src/commands/wire-gemini.ts","../src/commands/wire-codex.ts","../src/commands/doctor.ts","../src/commands/uninstall.ts"],"sourcesContent":["import { Command } from \"commander\";\nimport { createRequire } from \"node:module\";\nimport { initCommand } from \"./commands/init.js\";\nimport { joinCommand } from \"./commands/join.js\";\nimport { wireCommand } from \"./commands/wire.js\";\nimport { doctorCommand } from \"./commands/doctor.js\";\nimport { uninstallCommand } from \"./commands/uninstall.js\";\n\nconst require = createRequire(import.meta.url);\nconst { version } = require(\"../package.json\");\n\nconst program = new Command();\n\nprogram\n .name(\"kb\")\n .description(\"Team Knowledge Base harness CLI\")\n .version(version);\n\nprogram\n .command(\"init\")\n .description(\"KB 최초 생성 (팀 리드)\")\n .action(initCommand);\n\nprogram\n .command(\"join\")\n .description(\"기존 KB에 합류 (팀원)\")\n .argument(\"<remote-url>\", \"Git remote URL\")\n .action(joinCommand);\n\nprogram\n .command(\"wire\")\n .description(\"프로젝트에 LLM 도구 연결\")\n .argument(\"<tool>\", \"claude | gemini | codex\")\n .action(wireCommand);\n\nprogram\n .command(\"doctor\")\n .description(\"KB 환경 무결성 검증\")\n .action(doctorCommand);\n\nprogram\n .command(\"uninstall\")\n .description(\"KB wiring 제거 + 설정 정리\")\n .action(uninstallCommand);\n\nprogram.parse();\n","import { input } from \"@inquirer/prompts\";\nimport fs from \"fs-extra\";\nimport path from \"node:path\";\nimport { fileURLToPath } from \"node:url\";\nimport { log } from \"../utils/log.js\";\nimport { renderTemplate } from \"../utils/template.js\";\nimport { saveKbPath } from \"../utils/config.js\";\nimport { initRepo } from \"../utils/git.js\";\n\nconst __dirname = path.dirname(fileURLToPath(import.meta.url));\nconst TEMPLATES_DIR = path.join(__dirname, \"..\", \"templates\", \"kb-structure\");\n\nconst KB_DIRS = [\n \"global\",\n \"rules\",\n \"analysis\",\n \"decisions\",\n \"troubleshoot\",\n \"drafts\",\n \"areas\",\n \"templates\",\n \"ai-context\",\n \"archive\",\n \"00-inbox\",\n \"99-personal\",\n \".kb/hooks\",\n \".kb/scripts\",\n \".kb/setup\",\n \".github/workflows\",\n];\n\nexport async function initCommand(): Promise<void> {\n log.info(\"KB 최초 생성을 시작합니다.\");\n\n const defaultPath = path.join(process.env.HOME || \"~\", \"team-kb\");\n const kbPath = await input({\n message: \"KB 경로\",\n default: defaultPath,\n });\n const resolvedPath = kbPath.startsWith(\"~\")\n ? kbPath.replace(\"~\", process.env.HOME || \"\")\n : path.resolve(kbPath);\n\n if (fs.existsSync(resolvedPath) && fs.readdirSync(resolvedPath).length > 0) {\n log.error(`${resolvedPath} 가 이미 존재하고 비어있지 않습니다.`);\n return;\n }\n\n const remoteUrl = await input({\n message: \"Git remote URL (없으면 엔터)\",\n default: \"\",\n });\n\n const today = new Date().toISOString().split(\"T\")[0];\n const vars = { date: today };\n\n // 1. Create directory structure\n log.info(\"폴더 구조 생성 중...\");\n for (const dir of KB_DIRS) {\n await fs.ensureDir(path.join(resolvedPath, dir));\n }\n log.success(\"폴더 구조 생성 완료\");\n\n // 2. Copy .gitignore\n const gitignoreSrc = path.join(TEMPLATES_DIR, \"gitignore\");\n await fs.copy(gitignoreSrc, path.join(resolvedPath, \".gitignore\"));\n log.step(\".gitignore 생성\");\n\n // 3. Copy and render note templates\n const noteTemplatesDir = path.join(TEMPLATES_DIR, \"note-templates\");\n const noteTemplates = await fs.readdir(noteTemplatesDir);\n for (const file of noteTemplates) {\n const content = await fs.readFile(path.join(noteTemplatesDir, file), \"utf-8\");\n const rendered = renderTemplate(content, vars);\n await fs.writeFile(path.join(resolvedPath, \"templates\", file), rendered);\n }\n log.step(\"노트 템플릿 생성\");\n\n // 4. Copy pre-commit hook\n const preCommitSrc = path.join(TEMPLATES_DIR, \"pre-commit\");\n const preCommitDest = path.join(resolvedPath, \".kb\", \"hooks\", \"pre-commit\");\n await fs.copy(preCommitSrc, preCommitDest);\n await fs.chmod(preCommitDest, 0o755);\n log.step(\"pre-commit hook 생성\");\n\n // 5. Copy rebuild-index.sh\n const rebuildSrc = path.join(TEMPLATES_DIR, \"rebuild-index.sh\");\n const rebuildDest = path.join(resolvedPath, \".kb\", \"scripts\", \"rebuild-index.sh\");\n await fs.copy(rebuildSrc, rebuildDest);\n await fs.chmod(rebuildDest, 0o755);\n log.step(\"rebuild-index.sh 생성\");\n\n // 6. Copy GitHub Actions workflows\n const healthSrc = path.join(TEMPLATES_DIR, \"kb-health.yml\");\n const coverageSrc = path.join(TEMPLATES_DIR, \"kb-coverage.yml\");\n await fs.copy(healthSrc, path.join(resolvedPath, \".github\", \"workflows\", \"kb-health.yml\"));\n await fs.copy(coverageSrc, path.join(resolvedPath, \".github\", \"workflows\", \"kb-coverage.yml\"));\n log.step(\"GitHub Actions 워크플로우 생성\");\n\n // 7. Create kb-index.json (empty)\n await fs.writeJson(path.join(resolvedPath, \"kb-index.json\"), []);\n log.step(\"kb-index.json 초기화 (빈 배열)\");\n\n // 8. Create ai-context files\n const kbRulesSrc = path.join(TEMPLATES_DIR, \"kb-rules.md\");\n const kbRulesContent = await fs.readFile(kbRulesSrc, \"utf-8\");\n await fs.writeFile(\n path.join(resolvedPath, \"ai-context\", \"kb-rules.md\"),\n renderTemplate(kbRulesContent, vars),\n );\n\n const teamFocusSrc = path.join(TEMPLATES_DIR, \"team-focus.md\");\n const teamFocusContent = await fs.readFile(teamFocusSrc, \"utf-8\");\n await fs.writeFile(\n path.join(resolvedPath, \"ai-context\", \"team-focus.md\"),\n renderTemplate(teamFocusContent, vars),\n );\n log.step(\"ai-context/ 파일 생성 (kb-rules.md, team-focus.md)\");\n\n // 9. Git init + remote\n await initRepo(resolvedPath, remoteUrl || undefined);\n log.step(\"git init\" + (remoteUrl ? ` + remote: ${remoteUrl}` : \"\"));\n\n // 10. Install pre-commit hook\n const gitHookDest = path.join(resolvedPath, \".git\", \"hooks\", \"pre-commit\");\n await fs.copy(preCommitDest, gitHookDest);\n await fs.chmod(gitHookDest, 0o755);\n log.step(\"pre-commit hook 설치 (.git/hooks/)\");\n\n // 11. Save config\n await saveKbPath(resolvedPath);\n\n // 12. Initial commit\n const git = (await import(\"simple-git\")).default(resolvedPath);\n await git.add(\".\");\n await git.commit(\"init: KB 구조 생성\");\n log.step(\"초기 커밋 완료\");\n\n log.success(`KB 생성 완료: ${resolvedPath}`);\n log.info(\"다음 단계:\");\n log.step(\"ai-context/ 오버뷰 초안 작성\");\n log.step(\"git push\");\n log.step(\"팀원에게 kb join 안내\");\n}\n","import pc from \"picocolors\";\n\nexport const log = {\n info: (msg: string) => console.log(pc.blue(\"ℹ\") + \" \" + msg),\n success: (msg: string) => console.log(pc.green(\"✔\") + \" \" + msg),\n warn: (msg: string) => console.log(pc.yellow(\"⚠\") + \" \" + msg),\n error: (msg: string) => console.error(pc.red(\"✖\") + \" \" + msg),\n step: (msg: string) => console.log(pc.gray(\" →\") + \" \" + msg),\n};\n","/**\n * Simple template variable replacement.\n * Replaces {{VAR_NAME}} with provided values.\n */\nexport function renderTemplate(\n template: string,\n vars: Record<string, string>,\n): string {\n let result = template;\n for (const [key, value] of Object.entries(vars)) {\n result = result.replaceAll(`{{${key}}}`, value);\n }\n return result;\n}\n","import fs from \"fs-extra\";\nimport path from \"node:path\";\nimport { log } from \"./log.js\";\n\nconst CONFIG_DIR = path.join(\n process.env.HOME || \"~\",\n \".config\",\n \"kb-cli\",\n);\nconst CONFIG_PATH = path.join(CONFIG_DIR, \"config.json\");\n\ninterface KbConfig {\n kbPath: string;\n}\n\n/**\n * Read KB path from config file.\n */\nexport function getKbPath(): string | undefined {\n try {\n if (fs.existsSync(CONFIG_PATH)) {\n const config: KbConfig = fs.readJsonSync(CONFIG_PATH);\n return config.kbPath;\n }\n } catch {\n // ignore parse errors\n }\n return undefined;\n}\n\n/**\n * Save KB path to config file.\n */\nexport async function saveKbPath(kbPath: string): Promise<void> {\n await fs.ensureDir(CONFIG_DIR);\n await fs.writeJson(CONFIG_PATH, { kbPath }, { spaces: 2 });\n log.step(`설정 저장: ${CONFIG_PATH}`);\n}\n\n/**\n * Remove config file.\n */\nexport async function removeConfig(): Promise<boolean> {\n if (fs.existsSync(CONFIG_PATH)) {\n await fs.remove(CONFIG_PATH);\n return true;\n }\n return false;\n}\n\nexport { CONFIG_PATH };\n","import simpleGit, { type SimpleGit } from \"simple-git\";\nimport fs from \"fs-extra\";\n\nexport function getGit(cwd?: string): SimpleGit {\n return simpleGit(cwd);\n}\n\nexport async function isGitRepo(dir: string): Promise<boolean> {\n try {\n const git = getGit(dir);\n return await git.checkIsRepo();\n } catch {\n return false;\n }\n}\n\nexport async function initRepo(\n dir: string,\n remote?: string,\n): Promise<void> {\n const git = getGit(dir);\n await git.init();\n if (remote) {\n await git.addRemote(\"origin\", remote);\n }\n}\n\nexport async function cloneRepo(\n url: string,\n dir: string,\n): Promise<void> {\n await fs.ensureDir(dir);\n const git = simpleGit();\n await git.clone(url, dir);\n}\n","import { input } from \"@inquirer/prompts\";\nimport fs from \"fs-extra\";\nimport path from \"node:path\";\nimport { log } from \"../utils/log.js\";\nimport { saveKbPath } from \"../utils/config.js\";\nimport { cloneRepo } from \"../utils/git.js\";\n\nexport async function joinCommand(remoteUrl: string): Promise<void> {\n log.info(\"기존 KB에 합류합니다.\");\n\n const defaultPath = path.join(process.env.HOME || \"~\", \"team-kb\");\n const kbPath = await input({\n message: \"로컬 경로\",\n default: defaultPath,\n });\n const resolvedPath = kbPath.startsWith(\"~\")\n ? kbPath.replace(\"~\", process.env.HOME || \"\")\n : path.resolve(kbPath);\n\n if (fs.existsSync(resolvedPath) && fs.readdirSync(resolvedPath).length > 0) {\n log.error(`${resolvedPath} 가 이미 존재하고 비어있지 않습니다.`);\n return;\n }\n\n // 1. Clone\n log.info(\"git clone 중...\");\n await cloneRepo(remoteUrl, resolvedPath);\n log.success(\"clone 완료\");\n\n // 2. Install pre-commit hook\n const hookSrc = path.join(resolvedPath, \".kb\", \"hooks\", \"pre-commit\");\n const hookDest = path.join(resolvedPath, \".git\", \"hooks\", \"pre-commit\");\n if (fs.existsSync(hookSrc)) {\n await fs.copy(hookSrc, hookDest);\n await fs.chmod(hookDest, 0o755);\n log.step(\"pre-commit hook 설치\");\n } else {\n log.warn(\"pre-commit hook 원본이 없습니다 (.kb/hooks/pre-commit)\");\n }\n\n // 3. Save config\n await saveKbPath(resolvedPath);\n\n log.success(`KB 합류 완료: ${resolvedPath}`);\n log.info(\"다음 단계:\");\n log.step(\"cd ~/repos/{project} && kb wire claude (또는 gemini / codex)\");\n}\n","import { input } from \"@inquirer/prompts\";\nimport { log } from \"../utils/log.js\";\nimport { getKbPath } from \"../utils/config.js\";\nimport { wireClaude } from \"./wire-claude.js\";\nimport { wireGemini } from \"./wire-gemini.js\";\nimport { wireCodex } from \"./wire-codex.js\";\n\nexport interface WireContext {\n /** Absolute path to the KB repo */\n kbPath: string;\n /** Current project root (cwd) */\n projectRoot: string;\n /** Current repo name (e.g., \"coupon-api\") */\n repoName: string;\n}\n\nasync function collectWireContext(): Promise<WireContext | null> {\n // Resolve KB path\n let kbPath = getKbPath();\n if (!kbPath) {\n kbPath = await input({\n message: \"KB 경로를 찾을 수 없습니다. KB 절대 경로를 입력하세요\",\n });\n }\n\n if (!kbPath) {\n log.error(\"KB 경로가 필요합니다. kb init 또는 kb join을 먼저 실행하세요.\");\n return null;\n }\n\n const projectRoot = process.cwd();\n const repoName =\n projectRoot.split(\"/\").pop() || \"unknown\";\n\n return { kbPath, projectRoot, repoName };\n}\n\nexport async function wireCommand(tool: string): Promise<void> {\n const validTools = [\"claude\", \"gemini\", \"codex\"];\n if (!validTools.includes(tool)) {\n log.error(`지원하지 않는 도구: ${tool}. (claude, gemini, codex 중 선택)`);\n return;\n }\n\n log.info(`프로젝트에 ${tool} 연결을 시작합니다.`);\n\n const ctx = await collectWireContext();\n if (!ctx) return;\n\n switch (tool) {\n case \"claude\":\n await wireClaude(ctx);\n break;\n case \"gemini\":\n await wireGemini(ctx);\n break;\n case \"codex\":\n await wireCodex(ctx);\n break;\n }\n}\n","import fs from \"fs-extra\";\nimport path from \"node:path\";\nimport { log } from \"../utils/log.js\";\nimport { createSymlink } from \"../utils/symlink.js\";\nimport { ensureGitignorePatterns } from \"../utils/gitignore.js\";\nimport type { WireContext } from \"./wire.js\";\n\nfunction buildKbLocationContent(ctx: WireContext): string {\n return `## KB 절대 경로\nLLM은 파일 접근 및 쉘 스크립트 실행 시 반드시 아래의 절대 경로를 그대로 사용할 것.\n- KB 루트: ${ctx.kbPath}\n- 전체 인덱스: ${ctx.kbPath}/kb-index.json\n- 로컬 인덱스: ${ctx.kbPath}/.kb-index.local.json\n- 로컬 인덱스 재생성 스크립트: ${ctx.kbPath}/.kb/scripts/rebuild-index.sh\n`;\n}\n\nexport async function wireClaude(ctx: WireContext): Promise<void> {\n const rulesDir = path.join(ctx.projectRoot, \".claude\", \"rules\");\n await fs.ensureDir(rulesDir);\n\n // 1. Symlinks to KB ai-context files\n const aiContextDir = path.join(ctx.kbPath, \"ai-context\");\n const symlinkTargets = [\n { name: \"kb-rules.md\", target: path.join(aiContextDir, \"kb-rules.md\") },\n { name: \"team-focus.md\", target: path.join(aiContextDir, \"team-focus.md\") },\n ];\n\n // Also symlink any *-overview.md files\n if (fs.existsSync(aiContextDir)) {\n const files = await fs.readdir(aiContextDir);\n for (const file of files) {\n if (file.endsWith(\"-overview.md\")) {\n symlinkTargets.push({\n name: file,\n target: path.join(aiContextDir, file),\n });\n }\n }\n }\n\n for (const { name, target } of symlinkTargets) {\n await createSymlink(target, path.join(rulesDir, name));\n }\n\n // 3. kb-location.md — explicit paths (local-only)\n const locationPath = path.join(rulesDir, \"kb-location.md\");\n await fs.writeFile(locationPath, buildKbLocationContent(ctx));\n log.step(\"kb-location.md 생성 (KB 절대 경로)\");\n\n // 3. .claude/settings.json\n const settingsPath = path.join(ctx.projectRoot, \".claude\", \"settings.json\");\n if (!fs.existsSync(settingsPath)) {\n await fs.writeJson(settingsPath, {}, { spaces: 2 });\n log.step(\".claude/settings.json 생성\");\n }\n\n // 4. Update .gitignore\n await ensureGitignorePatterns(ctx.projectRoot, [\n \".claude/rules/\",\n ]);\n\n log.success(\"Claude Code 연결 완료\");\n}\n","import fs from \"fs-extra\";\nimport path from \"node:path\";\nimport { log } from \"./log.js\";\n\n/**\n * Create a symlink. If target doesn't exist, warn but still create.\n */\nexport async function createSymlink(\n target: string,\n linkPath: string,\n): Promise<void> {\n await fs.ensureDir(path.dirname(linkPath));\n\n if (fs.existsSync(linkPath)) {\n const stat = await fs.lstat(linkPath);\n if (stat.isSymbolicLink()) {\n const existing = await fs.readlink(linkPath);\n if (existing === target) {\n log.step(`symlink 이미 존재: ${path.basename(linkPath)}`);\n return;\n }\n await fs.remove(linkPath);\n } else {\n log.warn(`${linkPath} 이 일반 파일로 존재. symlink로 교체합니다.`);\n await fs.remove(linkPath);\n }\n }\n\n if (!fs.existsSync(target)) {\n log.warn(`symlink 대상 파일 없음: ${target} (나중에 생성 필요)`);\n }\n\n await fs.symlink(target, linkPath);\n log.step(`symlink 생성: ${path.basename(linkPath)} → ${target}`);\n}\n","import fs from \"fs-extra\";\nimport path from \"node:path\";\nimport { log } from \"./log.js\";\n\n/**\n * Ensure patterns exist in a .gitignore file.\n * Creates the file if it doesn't exist. Skips patterns already present.\n */\nexport async function ensureGitignorePatterns(\n dir: string,\n patterns: string[],\n): Promise<void> {\n const gitignorePath = path.join(dir, \".gitignore\");\n\n let content = \"\";\n if (fs.existsSync(gitignorePath)) {\n content = await fs.readFile(gitignorePath, \"utf-8\");\n }\n\n const lines = content.split(\"\\n\");\n const toAdd: string[] = [];\n\n for (const pattern of patterns) {\n const trimmed = pattern.trim();\n if (!lines.some((line) => line.trim() === trimmed)) {\n toAdd.push(trimmed);\n }\n }\n\n if (toAdd.length === 0) {\n return;\n }\n\n const separator = content.length > 0 && !content.endsWith(\"\\n\") ? \"\\n\" : \"\";\n const section =\n separator +\n \"\\n# KB wiring (local-only)\\n\" +\n toAdd.join(\"\\n\") +\n \"\\n\";\n\n await fs.appendFile(gitignorePath, section);\n log.step(`.gitignore에 ${toAdd.length}개 패턴 추가`);\n}\n","import fs from \"fs-extra\";\nimport path from \"node:path\";\nimport { log } from \"../utils/log.js\";\nimport { createSymlink } from \"../utils/symlink.js\";\nimport { ensureGitignorePatterns } from \"../utils/gitignore.js\";\nimport type { WireContext } from \"./wire.js\";\n\nfunction buildGeminiMd(): string {\n return \"@.gemini/kb-import.md\\n\";\n}\n\nfunction buildKbImportMd(ctx: WireContext): string {\n let content = `## KB 절대 경로\nLLM은 파일 접근 및 쉘 스크립트 실행 시 반드시 아래의 절대 경로를 그대로 사용할 것.\n- KB 루트: ${ctx.kbPath}\n- 전체 인덱스: ${ctx.kbPath}/kb-index.json\n- 로컬 인덱스: ${ctx.kbPath}/.kb-index.local.json\n- 로컬 인덱스 재생성 스크립트: ${ctx.kbPath}/.kb/scripts/rebuild-index.sh\n\n`;\n\n // @import via symlink (relative to this file's location)\n content += \"@kb-context/kb-rules.md\\n\";\n content += \"@kb-context/team-focus.md\\n\";\n\n // Also import any *-overview.md files\n const aiContext = path.join(ctx.kbPath, \"ai-context\");\n if (fs.existsSync(aiContext)) {\n const files = fs.readdirSync(aiContext);\n for (const file of files) {\n if (file.endsWith(\"-overview.md\")) {\n content += `@kb-context/${file}\\n`;\n }\n }\n }\n\n return content;\n}\n\nexport async function wireGemini(ctx: WireContext): Promise<void> {\n const geminiDir = path.join(ctx.projectRoot, \".gemini\");\n await fs.ensureDir(geminiDir);\n\n // 1. GEMINI.md (tracked — @import only)\n const geminiMdPath = path.join(ctx.projectRoot, \"GEMINI.md\");\n const importLine = buildGeminiMd();\n if (fs.existsSync(geminiMdPath)) {\n const existing = await fs.readFile(geminiMdPath, \"utf-8\");\n if (!existing.includes(\"@.gemini/kb-import.md\")) {\n const updated = importLine + \"\\n\" + existing;\n await fs.writeFile(geminiMdPath, updated);\n log.step(\"GEMINI.md에 KB @import 추가\");\n } else {\n log.step(\"GEMINI.md에 KB @import 이미 존재 — 스킵\");\n }\n } else {\n await fs.writeFile(geminiMdPath, importLine);\n log.step(\"GEMINI.md 생성\");\n }\n\n // 2. .gemini/kb-context symlink → KB ai-context/\n const aiContextDir = path.join(ctx.kbPath, \"ai-context\");\n const kbContextLink = path.join(geminiDir, \"kb-context\");\n await createSymlink(aiContextDir, kbContextLink);\n\n // 3. .gemini/kb-import.md (local-only — paths + @import via symlink)\n const importPath = path.join(geminiDir, \"kb-import.md\");\n await fs.writeFile(importPath, buildKbImportMd(ctx));\n log.step(\".gemini/kb-import.md 생성 (KB 경로 + @import)\");\n\n // 4. .gemini/settings.json\n const settingsPath = path.join(geminiDir, \"settings.json\");\n if (!fs.existsSync(settingsPath)) {\n await fs.writeJson(settingsPath, {}, { spaces: 2 });\n log.step(\".gemini/settings.json 생성\");\n }\n\n // 5. Update .gitignore\n await ensureGitignorePatterns(ctx.projectRoot, [\n \".gemini/kb-import.md\",\n \".gemini/kb-context\",\n ]);\n\n log.success(\"Gemini CLI 연결 완료\");\n}\n","import fs from \"fs-extra\";\nimport path from \"node:path\";\nimport { log } from \"../utils/log.js\";\nimport { ensureGitignorePatterns } from \"../utils/gitignore.js\";\nimport type { WireContext } from \"./wire.js\";\n\nfunction buildAgentsMd(): string {\n return \"# Knowledge Base\\n- 세션 시작 시 반드시 .codex/kb-directive.md 파일을 먼저 읽고 그 안의 경로 지시를 따를 것\\n\";\n}\n\nfunction buildDirectiveMd(ctx: WireContext): string {\n const aiContext = path.join(ctx.kbPath, \"ai-context\");\n\n return `## KB 작동 지시\n- 세션 시작 시 반드시 ${aiContext}/kb-rules.md 를 먼저 읽을 것\n\n## KB 절대 경로\nLLM은 파일 접근 및 쉘 스크립트 실행 시 반드시 아래의 절대 경로를 그대로 사용할 것.\n- KB 루트: ${ctx.kbPath}\n- 전체 인덱스: ${ctx.kbPath}/kb-index.json\n- 로컬 인덱스: ${ctx.kbPath}/.kb-index.local.json\n- 로컬 인덱스 재생성 스크립트: ${ctx.kbPath}/.kb/scripts/rebuild-index.sh\n`;\n}\n\nexport async function wireCodex(ctx: WireContext): Promise<void> {\n const codexDir = path.join(ctx.projectRoot, \".codex\");\n await fs.ensureDir(codexDir);\n\n // 1. AGENTS.md (tracked — KB directive reference only)\n const agentsMdPath = path.join(ctx.projectRoot, \"AGENTS.md\");\n const kbDirective = buildAgentsMd();\n if (fs.existsSync(agentsMdPath)) {\n const existing = await fs.readFile(agentsMdPath, \"utf-8\");\n if (!existing.includes(\"# Knowledge Base\")) {\n await fs.appendFile(agentsMdPath, \"\\n\" + kbDirective);\n log.step(\"AGENTS.md에 KB 지시문 추가\");\n } else {\n log.step(\"AGENTS.md에 KB 지시문 이미 존재 — 스킵\");\n }\n } else {\n await fs.writeFile(agentsMdPath, kbDirective);\n log.step(\"AGENTS.md 생성\");\n }\n\n // 2. .codex/kb-directive.md (local-only — absolute paths)\n const directivePath = path.join(codexDir, \"kb-directive.md\");\n await fs.writeFile(directivePath, buildDirectiveMd(ctx));\n log.step(\".codex/kb-directive.md 생성 (KB 경로 + 지시)\");\n\n // 3. Update .gitignore\n await ensureGitignorePatterns(ctx.projectRoot, [\n \".codex/kb-directive.md\",\n ]);\n\n log.success(\"Codex CLI 연결 완료\");\n}\n","import fs from \"fs-extra\";\nimport path from \"node:path\";\nimport { log } from \"../utils/log.js\";\nimport { getKbPath, CONFIG_PATH } from \"../utils/config.js\";\n\ninterface CheckResult {\n name: string;\n ok: boolean;\n detail: string;\n}\n\nexport async function doctorCommand(): Promise<void> {\n log.info(\"KB 환경 진단을 시작합니다.\\n\");\n const results: CheckResult[] = [];\n\n // 1. KB config\n const kbPath = getKbPath();\n results.push({\n name: `설정 파일 (${CONFIG_PATH})`,\n ok: !!kbPath,\n detail: kbPath || \"미설정. kb init 또는 kb join을 먼저 실행하세요.\",\n });\n\n if (!kbPath) {\n printResults(results);\n return;\n }\n\n // 2. KB directory exists and is accessible\n const kbExists = fs.existsSync(kbPath);\n results.push({\n name: \"KB 디렉토리 접근\",\n ok: kbExists,\n detail: kbExists ? kbPath : `${kbPath} 경로가 존재하지 않습니다.`,\n });\n\n if (!kbExists) {\n printResults(results);\n return;\n }\n\n // 3. ai-context/kb-rules.md exists\n const kbRulesPath = path.join(kbPath, \"ai-context\", \"kb-rules.md\");\n const kbRulesExists = fs.existsSync(kbRulesPath);\n results.push({\n name: \"ai-context/kb-rules.md\",\n ok: kbRulesExists,\n detail: kbRulesExists ? \"존재\" : \"없음. ai-context/ 초기 파일을 작성하세요.\",\n });\n\n // 4. kb-index.json exists\n const indexPath = path.join(kbPath, \"kb-index.json\");\n const indexExists = fs.existsSync(indexPath);\n results.push({\n name: \"kb-index.json\",\n ok: indexExists,\n detail: indexExists ? \"존재\" : \"없음. git push 후 CI가 생성합니다.\",\n });\n\n // 5. pre-commit hook installed\n const hookPath = path.join(kbPath, \".git\", \"hooks\", \"pre-commit\");\n const hookExists = fs.existsSync(hookPath);\n results.push({\n name: \"pre-commit hook\",\n ok: hookExists,\n detail: hookExists ? \"설치됨\" : \"미설치. kb join을 다시 실행하세요.\",\n });\n\n // 6. Check project wiring (if in a project directory)\n const cwd = process.cwd();\n if (cwd !== kbPath) {\n // Claude\n const claudeRulesDir = path.join(cwd, \".claude\", \"rules\");\n if (fs.existsSync(claudeRulesDir)) {\n const kbRulesLink = path.join(claudeRulesDir, \"kb-rules.md\");\n if (fs.existsSync(kbRulesLink)) {\n const stat = await fs.lstat(kbRulesLink);\n if (stat.isSymbolicLink()) {\n const target = await fs.readlink(kbRulesLink);\n const targetValid = fs.existsSync(target);\n results.push({\n name: \"Claude symlink (kb-rules.md)\",\n ok: targetValid,\n detail: targetValid ? `→ ${target}` : `깨진 symlink → ${target}`,\n });\n }\n }\n\n const locationFile = path.join(claudeRulesDir, \"kb-location.md\");\n results.push({\n name: \"Claude kb-location.md\",\n ok: fs.existsSync(locationFile),\n detail: fs.existsSync(locationFile) ? \"존재\" : \"없음. kb wire claude를 실행하세요.\",\n });\n }\n\n // Gemini\n const geminiImport = path.join(cwd, \".gemini\", \"kb-import.md\");\n if (fs.existsSync(path.join(cwd, \"GEMINI.md\"))) {\n results.push({\n name: \"Gemini kb-import.md\",\n ok: fs.existsSync(geminiImport),\n detail: fs.existsSync(geminiImport) ? \"존재\" : \"없음. kb wire gemini를 실행하세요.\",\n });\n }\n\n // Codex\n const codexDirective = path.join(cwd, \".codex\", \"kb-directive.md\");\n if (fs.existsSync(path.join(cwd, \"AGENTS.md\"))) {\n results.push({\n name: \"Codex kb-directive.md\",\n ok: fs.existsSync(codexDirective),\n detail: fs.existsSync(codexDirective) ? \"존재\" : \"없음. kb wire codex를 실행하세요.\",\n });\n }\n }\n\n printResults(results);\n}\n\nfunction printResults(results: CheckResult[]): void {\n let allOk = true;\n for (const r of results) {\n if (r.ok) {\n log.success(`${r.name}: ${r.detail}`);\n } else {\n log.error(`${r.name}: ${r.detail}`);\n allOk = false;\n }\n }\n\n console.log();\n if (allOk) {\n log.success(\"모든 검증 통과\");\n } else {\n log.warn(\"일부 항목에 문제가 있습니다. 위 메시지를 확인하세요.\");\n }\n}\n","import { confirm } from \"@inquirer/prompts\";\nimport fs from \"fs-extra\";\nimport path from \"node:path\";\nimport { log } from \"../utils/log.js\";\nimport { getKbPath, removeConfig, CONFIG_PATH } from \"../utils/config.js\";\n\nexport async function uninstallCommand(): Promise<void> {\n log.info(\"KB wiring 제거를 시작합니다.\\n\");\n\n const cwd = process.cwd();\n let removed = 0;\n\n // 1. Remove Claude wiring (local-only files only)\n const claudeRulesDir = path.join(cwd, \".claude\", \"rules\");\n if (fs.existsSync(claudeRulesDir)) {\n // Remove symlinks (KB-related only)\n const files = await fs.readdir(claudeRulesDir);\n for (const file of files) {\n const filePath = path.join(claudeRulesDir, file);\n const stat = await fs.lstat(filePath);\n if (stat.isSymbolicLink()) {\n await fs.remove(filePath);\n log.step(`symlink 삭제: .claude/rules/${file}`);\n removed++;\n }\n }\n\n // Remove kb-location.md\n const locationPath = path.join(claudeRulesDir, \"kb-location.md\");\n if (fs.existsSync(locationPath)) {\n await fs.remove(locationPath);\n log.step(\"삭제: .claude/rules/kb-location.md\");\n removed++;\n }\n }\n\n // 2. Remove Gemini wiring (local-only file only)\n const geminiImport = path.join(cwd, \".gemini\", \"kb-import.md\");\n if (fs.existsSync(geminiImport)) {\n await fs.remove(geminiImport);\n log.step(\"삭제: .gemini/kb-import.md\");\n removed++;\n }\n\n // 3. Remove Codex wiring (local-only file only)\n const codexDirective = path.join(cwd, \".codex\", \"kb-directive.md\");\n if (fs.existsSync(codexDirective)) {\n await fs.remove(codexDirective);\n log.step(\"삭제: .codex/kb-directive.md\");\n removed++;\n }\n\n if (removed > 0) {\n log.success(`프로젝트 wiring ${removed}개 파일 제거 완료`);\n } else {\n log.info(\"현재 디렉토리에 제거할 wiring 파일이 없습니다.\");\n }\n\n // 4. Tracked files (CLAUDE.md, GEMINI.md, AGENTS.md) — don't touch\n const trackedFiles = [\"CLAUDE.md\", \"GEMINI.md\", \"AGENTS.md\"].filter(\n (f) => fs.existsSync(path.join(cwd, f)),\n );\n if (trackedFiles.length > 0) {\n log.warn(\n `${trackedFiles.join(\", \")}의 프로젝트 섹션은 수동으로 정리하세요 (사용자 내용과 섞여있을 수 있음).`,\n );\n }\n\n // 5. Remove config file\n const kbPath = getKbPath();\n const shouldRemoveConfig = await confirm({\n message: `설정 파일을 삭제할까요? (${CONFIG_PATH})`,\n default: true,\n });\n\n if (shouldRemoveConfig) {\n const didRemove = await removeConfig();\n if (didRemove) {\n log.step(\"설정 파일 삭제 완료\");\n }\n }\n\n // 6. KB directory — ask but warn\n if (kbPath && fs.existsSync(kbPath)) {\n const shouldRemoveKb = await confirm({\n message: `KB 디렉토리를 삭제할까요? (${kbPath}) — 팀 지식이 모두 삭제됩니다!`,\n default: false,\n });\n\n if (shouldRemoveKb) {\n await fs.remove(kbPath);\n log.step(`KB 디렉토리 삭제: ${kbPath}`);\n } else {\n log.info(`KB 디렉토리 유지: ${kbPath}`);\n }\n }\n\n console.log();\n log.success(\"uninstall 완료\");\n log.info(\"npm uninstall -g kb-cli 로 CLI 자체도 제거할 수 있습니다.\");\n}\n"],"mappings":"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","names":["fs","path","fs","fs","path","fs","input","fs","path","path","input","fs","input","fs","path","fs","path","fs","path","fs","path","path","fs","path","fs","fs","path","path","fs","fs","path","path","fs","input","fs","path","fs","path","fs","path","path","fs","require"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@01b/team-kb",
3
- "version": "0.1.3",
3
+ "version": "0.2.1",
4
4
  "description": "Team Knowledge Base harness CLI - scaffold, wire, and manage KB for LLM-assisted development",
5
5
  "type": "module",
6
6
  "bin": {
@@ -5,10 +5,13 @@ updated: {{date}}
5
5
  ---
6
6
 
7
7
  ## KB 검색 규칙
8
+ - 도메인 지식 질문(비즈니스 룰, 시스템 동작, 아키텍처)은 코드 탐색 전에 KB를 먼저 확인할 것
9
+ - KB는 가이드, 코드가 source of truth. 코드 동작에 대한 답변 시 관련 코드도 가볍게 확인할 것
10
+ - KB와 코드가 불일치하면 코드 기준 답변 + 불일치 보고 + KB 업데이트 제안
8
11
  - KB 절대 경로는 이 세션에 자동 로딩된 KB 경로 설정을 참조할 것
9
- - 검색 시 인덱스를 먼저 읽어 관련 노트를 특정할 것
10
- - kb-index.json을 읽기 (CI가 관리하는 정본)
11
- - .kb-index.local.json이 존재하면 함께 읽기 (로컬 최신 상태)
12
+ - 검색 시 인덱스에서 관련 노트를 특정할 것
13
+ - kb-index.json 또는 .kb-index.local.json에서 tags/tldrGrep으로 키워드 검색
14
+ - 인덱스가 작으면(50항목 이하) 전체 읽기도 가능
12
15
  - 두 인덱스의 항목을 합집합(Union)으로 병합하여 검색
13
16
  - 인덱스의 tags, tldr로 관련성을 판단하고, 필요한 노트만 전체 읽기
14
17
  - 현재 repo 관련 노트 우선: `repo:` 태그 또는 repo 태그 없는 공통 노트
@@ -40,6 +43,10 @@ updated: {{date}}
40
43
  - drafts/: 미검증, 참고만
41
44
  - archive/: 비활성, 최신 정보가 아닐 수 있음
42
45
 
46
+ ## KB 도메인 용어
47
+ - 코딩/분석 중 도메인 특화 용어(비즈니스 용어, 약어, 내부 명칭)를 발견하면 KB에 정의를 기록할 것
48
+ - 기록 전 기존 용어집(있다면)을 먼저 확인하여 중복/모순을 방지할 것
49
+
43
50
  ## KB 보안
44
51
  - KB에 credential, 접속 정보, API 키를 절대 포함하지 말 것
45
52