@01b/team-kb 0.2.1 → 0.2.3

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
@@ -326,7 +326,7 @@ async function wireClaude(ctx) {
326
326
  import fs8 from "fs-extra";
327
327
  import path7 from "path";
328
328
  function buildGeminiMd() {
329
- return "@.gemini/kb-import.md\n";
329
+ return "\uB3C4\uBA54\uC778 \uC9C0\uC2DD \uC9C8\uBB38\uC740 \uCF54\uB4DC \uD0D0\uC0C9 \uC804\uC5D0 \uBC18\uB4DC\uC2DC KB\uB97C \uBA3C\uC800 \uD655\uC778\uD560 \uAC83.\n\n@.gemini/kb-import.md\n";
330
330
  }
331
331
  function buildKbImportMd(ctx) {
332
332
  let content = `## KB \uC808\uB300 \uACBD\uB85C
@@ -391,7 +391,7 @@ async function wireGemini(ctx) {
391
391
  import fs9 from "fs-extra";
392
392
  import path8 from "path";
393
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";
394
+ return "# Knowledge Base\n- \uB3C4\uBA54\uC778 \uC9C0\uC2DD \uC9C8\uBB38\uC740 \uCF54\uB4DC \uD0D0\uC0C9 \uC804\uC5D0 \uBC18\uB4DC\uC2DC KB\uB97C \uBA3C\uC800 \uD655\uC778\uD560 \uAC83\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";
395
395
  }
396
396
  function buildDirectiveMd(ctx) {
397
397
  const aiContext = path8.join(ctx.kbPath, "ai-context");
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 /** 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"]}
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 \"도메인 지식 질문은 코드 탐색 전에 반드시 KB를 먼저 확인할 것.\\n\\n@.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- 도메인 지식 질문은 코드 탐색 전에 반드시 KB를 먼저 확인할 것\\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.2.1",
3
+ "version": "0.2.3",
4
4
  "description": "Team Knowledge Base harness CLI - scaffold, wire, and manage KB for LLM-assisted development",
5
5
  "type": "module",
6
6
  "bin": {
@@ -23,7 +23,7 @@ jobs:
23
23
  -not -path './templates/*' \
24
24
  -not -path './99-personal/*' \
25
25
  -not -path './00-inbox/*' \
26
- -not -path './.github/*'); do
26
+ -not -path './.github/*' -not -name 'README.md'); do
27
27
  if ! head -1 "$f" | grep -q '^---'; then
28
28
  echo "MISSING frontmatter: $f"; ERRORS=$((ERRORS+1))
29
29
  fi