@01b/team-kb 0.1.3 → 0.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.js +18 -64
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
- package/templates/kb-structure/kb-rules.md +10 -3
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,16 +325,8 @@ 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(
|
|
353
|
-
|
|
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
332
|
const aiContext = path7.join(ctx.kbPath, "ai-context");
|
|
@@ -389,16 +357,18 @@ async function wireGemini(ctx) {
|
|
|
389
357
|
const geminiDir = path7.join(ctx.projectRoot, ".gemini");
|
|
390
358
|
await fs8.ensureDir(geminiDir);
|
|
391
359
|
const geminiMdPath = path7.join(ctx.projectRoot, "GEMINI.md");
|
|
360
|
+
const importLine = buildGeminiMd();
|
|
392
361
|
if (fs8.existsSync(geminiMdPath)) {
|
|
393
362
|
const existing = await fs8.readFile(geminiMdPath, "utf-8");
|
|
394
|
-
if (!existing.includes("
|
|
395
|
-
|
|
396
|
-
|
|
363
|
+
if (!existing.includes("@.gemini/kb-import.md")) {
|
|
364
|
+
const updated = importLine + "\n" + existing;
|
|
365
|
+
await fs8.writeFile(geminiMdPath, updated);
|
|
366
|
+
log.step("GEMINI.md\uC5D0 KB @import \uCD94\uAC00");
|
|
397
367
|
} else {
|
|
398
|
-
log.step("GEMINI.md\uC5D0
|
|
368
|
+
log.step("GEMINI.md\uC5D0 KB @import \uC774\uBBF8 \uC874\uC7AC \u2014 \uC2A4\uD0B5");
|
|
399
369
|
}
|
|
400
370
|
} else {
|
|
401
|
-
await fs8.writeFile(geminiMdPath,
|
|
371
|
+
await fs8.writeFile(geminiMdPath, importLine);
|
|
402
372
|
log.step("GEMINI.md \uC0DD\uC131");
|
|
403
373
|
}
|
|
404
374
|
const importPath = path7.join(geminiDir, "kb-import.md");
|
|
@@ -418,17 +388,8 @@ async function wireGemini(ctx) {
|
|
|
418
388
|
// src/commands/wire-codex.ts
|
|
419
389
|
import fs9 from "fs-extra";
|
|
420
390
|
import path8 from "path";
|
|
421
|
-
function buildAgentsMd(
|
|
422
|
-
|
|
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;
|
|
391
|
+
function buildAgentsMd() {
|
|
392
|
+
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
393
|
}
|
|
433
394
|
function buildDirectiveMd(ctx) {
|
|
434
395
|
const aiContext = path8.join(ctx.kbPath, "ai-context");
|
|
@@ -447,16 +408,17 @@ async function wireCodex(ctx) {
|
|
|
447
408
|
const codexDir = path8.join(ctx.projectRoot, ".codex");
|
|
448
409
|
await fs9.ensureDir(codexDir);
|
|
449
410
|
const agentsMdPath = path8.join(ctx.projectRoot, "AGENTS.md");
|
|
411
|
+
const kbDirective = buildAgentsMd();
|
|
450
412
|
if (fs9.existsSync(agentsMdPath)) {
|
|
451
413
|
const existing = await fs9.readFile(agentsMdPath, "utf-8");
|
|
452
|
-
if (!existing.includes("#
|
|
453
|
-
await fs9.appendFile(agentsMdPath, "\n" +
|
|
454
|
-
log.step("AGENTS.md\uC5D0 \
|
|
414
|
+
if (!existing.includes("# Knowledge Base")) {
|
|
415
|
+
await fs9.appendFile(agentsMdPath, "\n" + kbDirective);
|
|
416
|
+
log.step("AGENTS.md\uC5D0 KB \uC9C0\uC2DC\uBB38 \uCD94\uAC00");
|
|
455
417
|
} else {
|
|
456
|
-
log.step("AGENTS.md\uC5D0 \
|
|
418
|
+
log.step("AGENTS.md\uC5D0 KB \uC9C0\uC2DC\uBB38 \uC774\uBBF8 \uC874\uC7AC \u2014 \uC2A4\uD0B5");
|
|
457
419
|
}
|
|
458
420
|
} else {
|
|
459
|
-
await fs9.writeFile(agentsMdPath,
|
|
421
|
+
await fs9.writeFile(agentsMdPath, kbDirective);
|
|
460
422
|
log.step("AGENTS.md \uC0DD\uC131");
|
|
461
423
|
}
|
|
462
424
|
const directivePath = path8.join(codexDir, "kb-directive.md");
|
|
@@ -482,15 +444,7 @@ async function collectWireContext() {
|
|
|
482
444
|
}
|
|
483
445
|
const projectRoot = process.cwd();
|
|
484
446
|
const repoName = projectRoot.split("/").pop() || "unknown";
|
|
485
|
-
|
|
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 };
|
|
447
|
+
return { kbPath, projectRoot, repoName };
|
|
494
448
|
}
|
|
495
449
|
async function wireCommand(tool) {
|
|
496
450
|
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":";;;AAAA,SAAS,eAAe;AACxB,SAAS,qBAAqB;;;ACD9B,SAAS,aAAa;AACtB,OAAOA,SAAQ;AACf,OAAOC,WAAU;AACjB,SAAS,qBAAqB;;;ACH9B,OAAO,QAAQ;AAER,IAAM,MAAM;AAAA,EACjB,MAAM,CAAC,QAAgB,QAAQ,IAAI,GAAG,KAAK,QAAG,IAAI,MAAM,GAAG;AAAA,EAC3D,SAAS,CAAC,QAAgB,QAAQ,IAAI,GAAG,MAAM,QAAG,IAAI,MAAM,GAAG;AAAA,EAC/D,MAAM,CAAC,QAAgB,QAAQ,IAAI,GAAG,OAAO,QAAG,IAAI,MAAM,GAAG;AAAA,EAC7D,OAAO,CAAC,QAAgB,QAAQ,MAAM,GAAG,IAAI,QAAG,IAAI,MAAM,GAAG;AAAA,EAC7D,MAAM,CAAC,QAAgB,QAAQ,IAAI,GAAG,KAAK,UAAK,IAAI,MAAM,GAAG;AAC/D;;;ACJO,SAAS,eACd,UACA,MACQ;AACR,MAAI,SAAS;AACb,aAAW,CAAC,KAAK,KAAK,KAAK,OAAO,QAAQ,IAAI,GAAG;AAC/C,aAAS,OAAO,WAAW,KAAK,GAAG,MAAM,KAAK;AAAA,EAChD;AACA,SAAO;AACT;;;ACbA,OAAO,QAAQ;AACf,OAAO,UAAU;AAGjB,IAAM,aAAa,KAAK;AAAA,EACtB,QAAQ,IAAI,QAAQ;AAAA,EACpB;AAAA,EACA;AACF;AACA,IAAM,cAAc,KAAK,KAAK,YAAY,aAAa;AAShD,SAAS,YAAgC;AAC9C,MAAI;AACF,QAAI,GAAG,WAAW,WAAW,GAAG;AAC9B,YAAM,SAAmB,GAAG,aAAa,WAAW;AACpD,aAAO,OAAO;AAAA,IAChB;AAAA,EACF,QAAQ;AAAA,EAER;AACA,SAAO;AACT;AAKA,eAAsB,WAAW,QAA+B;AAC9D,QAAM,GAAG,UAAU,UAAU;AAC7B,QAAM,GAAG,UAAU,aAAa,EAAE,OAAO,GAAG,EAAE,QAAQ,EAAE,CAAC;AACzD,MAAI,KAAK,8BAAU,WAAW,EAAE;AAClC;AAKA,eAAsB,eAAiC;AACrD,MAAI,GAAG,WAAW,WAAW,GAAG;AAC9B,UAAM,GAAG,OAAO,WAAW;AAC3B,WAAO;AAAA,EACT;AACA,SAAO;AACT;;;AChDA,OAAO,eAAmC;AAC1C,OAAOC,SAAQ;AAER,SAAS,OAAO,KAAyB;AAC9C,SAAO,UAAU,GAAG;AACtB;AAWA,eAAsB,SACpB,KACA,QACe;AACf,QAAM,MAAM,OAAO,GAAG;AACtB,QAAM,IAAI,KAAK;AACf,MAAI,QAAQ;AACV,UAAM,IAAI,UAAU,UAAU,MAAM;AAAA,EACtC;AACF;AAEA,eAAsB,UACpB,KACA,KACe;AACf,QAAMC,IAAG,UAAU,GAAG;AACtB,QAAM,MAAM,UAAU;AACtB,QAAM,IAAI,MAAM,KAAK,GAAG;AAC1B;;;AJzBA,IAAM,YAAYC,MAAK,QAAQ,cAAc,YAAY,GAAG,CAAC;AAC7D,IAAM,gBAAgBA,MAAK,KAAK,WAAW,MAAM,aAAa,cAAc;AAE5E,IAAM,UAAU;AAAA,EACd;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF;AAEA,eAAsB,cAA6B;AACjD,MAAI,KAAK,oEAAkB;AAE3B,QAAM,cAAcA,MAAK,KAAK,QAAQ,IAAI,QAAQ,KAAK,SAAS;AAChE,QAAM,SAAS,MAAM,MAAM;AAAA,IACzB,SAAS;AAAA,IACT,SAAS;AAAA,EACX,CAAC;AACD,QAAM,eAAe,OAAO,WAAW,GAAG,IACtC,OAAO,QAAQ,KAAK,QAAQ,IAAI,QAAQ,EAAE,IAC1CA,MAAK,QAAQ,MAAM;AAEvB,MAAIC,IAAG,WAAW,YAAY,KAAKA,IAAG,YAAY,YAAY,EAAE,SAAS,GAAG;AAC1E,QAAI,MAAM,GAAG,YAAY,kGAAuB;AAChD;AAAA,EACF;AAEA,QAAM,YAAY,MAAM,MAAM;AAAA,IAC5B,SAAS;AAAA,IACT,SAAS;AAAA,EACX,CAAC;AAED,QAAM,SAAQ,oBAAI,KAAK,GAAE,YAAY,EAAE,MAAM,GAAG,EAAE,CAAC;AACnD,QAAM,OAAO,EAAE,MAAM,MAAM;AAG3B,MAAI,KAAK,kDAAe;AACxB,aAAW,OAAO,SAAS;AACzB,UAAMA,IAAG,UAAUD,MAAK,KAAK,cAAc,GAAG,CAAC;AAAA,EACjD;AACA,MAAI,QAAQ,qDAAa;AAGzB,QAAM,eAAeA,MAAK,KAAK,eAAe,WAAW;AACzD,QAAMC,IAAG,KAAK,cAAcD,MAAK,KAAK,cAAc,YAAY,CAAC;AACjE,MAAI,KAAK,yBAAe;AAGxB,QAAM,mBAAmBA,MAAK,KAAK,eAAe,gBAAgB;AAClE,QAAM,gBAAgB,MAAMC,IAAG,QAAQ,gBAAgB;AACvD,aAAW,QAAQ,eAAe;AAChC,UAAM,UAAU,MAAMA,IAAG,SAASD,MAAK,KAAK,kBAAkB,IAAI,GAAG,OAAO;AAC5E,UAAM,WAAW,eAAe,SAAS,IAAI;AAC7C,UAAMC,IAAG,UAAUD,MAAK,KAAK,cAAc,aAAa,IAAI,GAAG,QAAQ;AAAA,EACzE;AACA,MAAI,KAAK,8CAAW;AAGpB,QAAM,eAAeA,MAAK,KAAK,eAAe,YAAY;AAC1D,QAAM,gBAAgBA,MAAK,KAAK,cAAc,OAAO,SAAS,YAAY;AAC1E,QAAMC,IAAG,KAAK,cAAc,aAAa;AACzC,QAAMA,IAAG,MAAM,eAAe,GAAK;AACnC,MAAI,KAAK,8BAAoB;AAG7B,QAAM,aAAaD,MAAK,KAAK,eAAe,kBAAkB;AAC9D,QAAM,cAAcA,MAAK,KAAK,cAAc,OAAO,WAAW,kBAAkB;AAChF,QAAMC,IAAG,KAAK,YAAY,WAAW;AACrC,QAAMA,IAAG,MAAM,aAAa,GAAK;AACjC,MAAI,KAAK,+BAAqB;AAG9B,QAAM,YAAYD,MAAK,KAAK,eAAe,eAAe;AAC1D,QAAM,cAAcA,MAAK,KAAK,eAAe,iBAAiB;AAC9D,QAAMC,IAAG,KAAK,WAAWD,MAAK,KAAK,cAAc,WAAW,aAAa,eAAe,CAAC;AACzF,QAAMC,IAAG,KAAK,aAAaD,MAAK,KAAK,cAAc,WAAW,aAAa,iBAAiB,CAAC;AAC7F,MAAI,KAAK,4DAAyB;AAGlC,QAAMC,IAAG,UAAUD,MAAK,KAAK,cAAc,eAAe,GAAG,CAAC,CAAC;AAC/D,MAAI,KAAK,wDAA0B;AAGnC,QAAM,aAAaA,MAAK,KAAK,eAAe,aAAa;AACzD,QAAM,iBAAiB,MAAMC,IAAG,SAAS,YAAY,OAAO;AAC5D,QAAMA,IAAG;AAAA,IACPD,MAAK,KAAK,cAAc,cAAc,aAAa;AAAA,IACnD,eAAe,gBAAgB,IAAI;AAAA,EACrC;AAEA,QAAM,eAAeA,MAAK,KAAK,eAAe,eAAe;AAC7D,QAAM,mBAAmB,MAAMC,IAAG,SAAS,cAAc,OAAO;AAChE,QAAMA,IAAG;AAAA,IACPD,MAAK,KAAK,cAAc,cAAc,eAAe;AAAA,IACrD,eAAe,kBAAkB,IAAI;AAAA,EACvC;AACA,MAAI,KAAK,oEAAgD;AAGzD,QAAM,SAAS,cAAc,aAAa,MAAS;AACnD,MAAI,KAAK,cAAc,YAAY,cAAc,SAAS,KAAK,GAAG;AAGlE,QAAM,cAAcA,MAAK,KAAK,cAAc,QAAQ,SAAS,YAAY;AACzE,QAAMC,IAAG,KAAK,eAAe,WAAW;AACxC,QAAMA,IAAG,MAAM,aAAa,GAAK;AACjC,MAAI,KAAK,4CAAkC;AAG3C,QAAM,WAAW,YAAY;AAG7B,QAAM,OAAO,MAAM,OAAO,YAAY,GAAG,QAAQ,YAAY;AAC7D,QAAM,IAAI,IAAI,GAAG;AACjB,QAAM,IAAI,OAAO,oCAAgB;AACjC,MAAI,KAAK,wCAAU;AAEnB,MAAI,QAAQ,iCAAa,YAAY,EAAE;AACvC,MAAI,KAAK,4BAAQ;AACjB,MAAI,KAAK,0DAAuB;AAChC,MAAI,KAAK,UAAU;AACnB,MAAI,KAAK,+CAAiB;AAC5B;;;AK/IA,SAAS,SAAAC,cAAa;AACtB,OAAOC,SAAQ;AACf,OAAOC,WAAU;AAKjB,eAAsB,YAAY,WAAkC;AAClE,MAAI,KAAK,uDAAe;AAExB,QAAM,cAAcC,MAAK,KAAK,QAAQ,IAAI,QAAQ,KAAK,SAAS;AAChE,QAAM,SAAS,MAAMC,OAAM;AAAA,IACzB,SAAS;AAAA,IACT,SAAS;AAAA,EACX,CAAC;AACD,QAAM,eAAe,OAAO,WAAW,GAAG,IACtC,OAAO,QAAQ,KAAK,QAAQ,IAAI,QAAQ,EAAE,IAC1CD,MAAK,QAAQ,MAAM;AAEvB,MAAIE,IAAG,WAAW,YAAY,KAAKA,IAAG,YAAY,YAAY,EAAE,SAAS,GAAG;AAC1E,QAAI,MAAM,GAAG,YAAY,kGAAuB;AAChD;AAAA,EACF;AAGA,MAAI,KAAK,qBAAgB;AACzB,QAAM,UAAU,WAAW,YAAY;AACvC,MAAI,QAAQ,oBAAU;AAGtB,QAAM,UAAUF,MAAK,KAAK,cAAc,OAAO,SAAS,YAAY;AACpE,QAAM,WAAWA,MAAK,KAAK,cAAc,QAAQ,SAAS,YAAY;AACtE,MAAIE,IAAG,WAAW,OAAO,GAAG;AAC1B,UAAMA,IAAG,KAAK,SAAS,QAAQ;AAC/B,UAAMA,IAAG,MAAM,UAAU,GAAK;AAC9B,QAAI,KAAK,8BAAoB;AAAA,EAC/B,OAAO;AACL,QAAI,KAAK,oFAAiD;AAAA,EAC5D;AAGA,QAAM,WAAW,YAAY;AAE7B,MAAI,QAAQ,iCAAa,YAAY,EAAE;AACvC,MAAI,KAAK,4BAAQ;AACjB,MAAI,KAAK,sEAA4D;AACvE;;;AC9CA,SAAS,SAAAC,cAAa;;;ACAtB,OAAOC,SAAQ;AACf,OAAOC,WAAU;;;ACDjB,OAAOC,SAAQ;AACf,OAAOC,WAAU;AAMjB,eAAsB,cACpB,QACA,UACe;AACf,QAAMC,IAAG,UAAUC,MAAK,QAAQ,QAAQ,CAAC;AAEzC,MAAID,IAAG,WAAW,QAAQ,GAAG;AAC3B,UAAM,OAAO,MAAMA,IAAG,MAAM,QAAQ;AACpC,QAAI,KAAK,eAAe,GAAG;AACzB,YAAM,WAAW,MAAMA,IAAG,SAAS,QAAQ;AAC3C,UAAI,aAAa,QAAQ;AACvB,YAAI,KAAK,sCAAkBC,MAAK,SAAS,QAAQ,CAAC,EAAE;AACpD;AAAA,MACF;AACA,YAAMD,IAAG,OAAO,QAAQ;AAAA,IAC1B,OAAO;AACL,UAAI,KAAK,GAAG,QAAQ,qGAA+B;AACnD,YAAMA,IAAG,OAAO,QAAQ;AAAA,IAC1B;AAAA,EACF;AAEA,MAAI,CAACA,IAAG,WAAW,MAAM,GAAG;AAC1B,QAAI,KAAK,mDAAqB,MAAM,iDAAc;AAAA,EACpD;AAEA,QAAMA,IAAG,QAAQ,QAAQ,QAAQ;AACjC,MAAI,KAAK,yBAAeC,MAAK,SAAS,QAAQ,CAAC,WAAM,MAAM,EAAE;AAC/D;;;AClCA,OAAOC,SAAQ;AACf,OAAOC,WAAU;AAOjB,eAAsB,wBACpB,KACA,UACe;AACf,QAAM,gBAAgBC,MAAK,KAAK,KAAK,YAAY;AAEjD,MAAI,UAAU;AACd,MAAIC,IAAG,WAAW,aAAa,GAAG;AAChC,cAAU,MAAMA,IAAG,SAAS,eAAe,OAAO;AAAA,EACpD;AAEA,QAAM,QAAQ,QAAQ,MAAM,IAAI;AAChC,QAAM,QAAkB,CAAC;AAEzB,aAAW,WAAW,UAAU;AAC9B,UAAM,UAAU,QAAQ,KAAK;AAC7B,QAAI,CAAC,MAAM,KAAK,CAAC,SAAS,KAAK,KAAK,MAAM,OAAO,GAAG;AAClD,YAAM,KAAK,OAAO;AAAA,IACpB;AAAA,EACF;AAEA,MAAI,MAAM,WAAW,GAAG;AACtB;AAAA,EACF;AAEA,QAAM,YAAY,QAAQ,SAAS,KAAK,CAAC,QAAQ,SAAS,IAAI,IAAI,OAAO;AACzE,QAAM,UACJ,YACA,iCACA,MAAM,KAAK,IAAI,IACf;AAEF,QAAMA,IAAG,WAAW,eAAe,OAAO;AAC1C,MAAI,KAAK,oBAAe,MAAM,MAAM,kCAAS;AAC/C;;;AFnCA,SAAS,oBAAoB,KAA0B;AACrD,MAAI,UAAU;AACd,aAAW,KAAK,IAAI,SAAS;AAAA;AAC7B,MAAI,IAAI,QAAS,YAAW,mBAAS,IAAI,OAAO;AAAA;AAChD,aAAW,wBAAc,IAAI,QAAQ;AAAA;AAErC,SAAO;AACT;AAEA,SAAS,uBAAuB,KAA0B;AACxD,SAAO;AAAA;AAAA,qBAEE,IAAI,MAAM;AAAA,qCACT,IAAI,MAAM;AAAA,qCACV,IAAI,MAAM;AAAA,iFACD,IAAI,MAAM;AAAA;AAE/B;AAEA,eAAsB,WAAW,KAAiC;AAChE,QAAM,WAAWC,MAAK,KAAK,IAAI,aAAa,WAAW,OAAO;AAC9D,QAAMC,IAAG,UAAU,QAAQ;AAG3B,QAAM,eAAeD,MAAK,KAAK,IAAI,aAAa,WAAW;AAC3D,QAAM,iBAAiB,oBAAoB,GAAG;AAE9C,MAAIC,IAAG,WAAW,YAAY,GAAG;AAC/B,UAAM,WAAW,MAAMA,IAAG,SAAS,cAAc,OAAO;AACxD,QAAI,CAAC,SAAS,SAAS,6BAAS,GAAG;AACjC,YAAMA,IAAG,WAAW,cAAc,cAAc;AAChD,UAAI,KAAK,oEAAuB;AAAA,IAClC,OAAO;AACL,UAAI,KAAK,qGAA+B;AAAA,IAC1C;AAAA,EACF,OAAO;AACL,UAAMA,IAAG,UAAU,cAAc,eAAe,UAAU,CAAC;AAC3D,QAAI,KAAK,wBAAc;AAAA,EACzB;AAGA,QAAM,eAAeD,MAAK,KAAK,IAAI,QAAQ,YAAY;AACvD,QAAM,iBAAiB;AAAA,IACrB,EAAE,MAAM,eAAe,QAAQA,MAAK,KAAK,cAAc,aAAa,EAAE;AAAA,IACtE,EAAE,MAAM,iBAAiB,QAAQA,MAAK,KAAK,cAAc,eAAe,EAAE;AAAA,EAC5E;AAGA,MAAIC,IAAG,WAAW,YAAY,GAAG;AAC/B,UAAM,QAAQ,MAAMA,IAAG,QAAQ,YAAY;AAC3C,eAAW,QAAQ,OAAO;AACxB,UAAI,KAAK,SAAS,cAAc,GAAG;AACjC,uBAAe,KAAK;AAAA,UAClB,MAAM;AAAA,UACN,QAAQD,MAAK,KAAK,cAAc,IAAI;AAAA,QACtC,CAAC;AAAA,MACH;AAAA,IACF;AAAA,EACF;AAEA,aAAW,EAAE,MAAM,OAAO,KAAK,gBAAgB;AAC7C,UAAM,cAAc,QAAQA,MAAK,KAAK,UAAU,IAAI,CAAC;AAAA,EACvD;AAGA,QAAM,eAAeA,MAAK,KAAK,UAAU,gBAAgB;AACzD,QAAMC,IAAG,UAAU,cAAc,uBAAuB,GAAG,CAAC;AAC5D,MAAI,KAAK,4DAA8B;AAGvC,QAAM,eAAeD,MAAK,KAAK,IAAI,aAAa,WAAW,eAAe;AAC1E,MAAI,CAACC,IAAG,WAAW,YAAY,GAAG;AAChC,UAAMA,IAAG,UAAU,cAAc,CAAC,GAAG,EAAE,QAAQ,EAAE,CAAC;AAClD,QAAI,KAAK,oCAA0B;AAAA,EACrC;AAGA,QAAM,wBAAwB,IAAI,aAAa;AAAA,IAC7C;AAAA,EACF,CAAC;AAED,MAAI,QAAQ,uCAAmB;AACjC;;;AGzFA,OAAOC,SAAQ;AACf,OAAOC,WAAU;AAKjB,SAAS,cAAc,KAA0B;AAC/C,MAAI,UAAU;AACd,aAAW;AACX,aAAW,KAAK,IAAI,SAAS;AAAA;AAC7B,MAAI,IAAI,QAAS,YAAW,mBAAS,IAAI,OAAO;AAAA;AAChD,aAAW,wBAAc,IAAI,QAAQ;AAAA;AAErC,SAAO;AACT;AAEA,SAAS,gBAAgB,KAA0B;AACjD,QAAM,YAAYC,MAAK,KAAK,IAAI,QAAQ,YAAY;AAEpD,MAAI,UAAU;AAAA;AAAA,qBAEL,IAAI,MAAM;AAAA,qCACT,IAAI,MAAM;AAAA,qCACV,IAAI,MAAM;AAAA,iFACD,IAAI,MAAM;AAAA;AAAA;AAK7B,aAAW,IAAI,SAAS;AAAA;AACxB,aAAW,IAAI,SAAS;AAAA;AAGxB,MAAIC,IAAG,WAAW,SAAS,GAAG;AAC5B,UAAM,QAAQA,IAAG,YAAY,SAAS;AACtC,eAAW,QAAQ,OAAO;AACxB,UAAI,KAAK,SAAS,cAAc,GAAG;AACjC,mBAAW,IAAI,SAAS,IAAI,IAAI;AAAA;AAAA,MAClC;AAAA,IACF;AAAA,EACF;AAEA,SAAO;AACT;AAEA,eAAsB,WAAW,KAAiC;AAChE,QAAM,YAAYD,MAAK,KAAK,IAAI,aAAa,SAAS;AACtD,QAAMC,IAAG,UAAU,SAAS;AAG5B,QAAM,eAAeD,MAAK,KAAK,IAAI,aAAa,WAAW;AAC3D,MAAIC,IAAG,WAAW,YAAY,GAAG;AAC/B,UAAM,WAAW,MAAMA,IAAG,SAAS,cAAc,OAAO;AACxD,QAAI,CAAC,SAAS,SAAS,6BAAS,GAAG;AACjC,YAAMA,IAAG,WAAW,cAAc,OAAO,cAAc,GAAG,CAAC;AAC3D,UAAI,KAAK,oEAAuB;AAAA,IAClC,OAAO;AACL,UAAI,KAAK,qGAA+B;AAAA,IAC1C;AAAA,EACF,OAAO;AACL,UAAMA,IAAG,UAAU,cAAc,cAAc,GAAG,CAAC;AACnD,QAAI,KAAK,wBAAc;AAAA,EACzB;AAGA,QAAM,aAAaD,MAAK,KAAK,WAAW,cAAc;AACtD,QAAMC,IAAG,UAAU,YAAY,gBAAgB,GAAG,CAAC;AACnD,MAAI,KAAK,+DAA2C;AAGpD,QAAM,eAAeD,MAAK,KAAK,WAAW,eAAe;AACzD,MAAI,CAACC,IAAG,WAAW,YAAY,GAAG;AAChC,UAAMA,IAAG,UAAU,cAAc,CAAC,GAAG,EAAE,QAAQ,EAAE,CAAC;AAClD,QAAI,KAAK,oCAA0B;AAAA,EACrC;AAGA,QAAM,wBAAwB,IAAI,aAAa;AAAA,IAC7C;AAAA,EACF,CAAC;AAED,MAAI,QAAQ,sCAAkB;AAChC;;;AClFA,OAAOC,SAAQ;AACf,OAAOC,WAAU;AAKjB,SAAS,cAAc,KAA0B;AAC/C,MAAI,UAAU;AACd,aAAW,KAAK,IAAI,SAAS;AAAA;AAC7B,MAAI,IAAI,QAAS,YAAW,mBAAS,IAAI,OAAO;AAAA;AAChD,aAAW,wBAAc,IAAI,QAAQ;AAAA;AACrC,aAAW;AACX,aAAW;AAEX,SAAO;AACT;AAEA,SAAS,iBAAiB,KAA0B;AAClD,QAAM,YAAYC,MAAK,KAAK,IAAI,QAAQ,YAAY;AAEpD,SAAO;AAAA,wDACO,SAAS;AAAA;AAAA;AAAA;AAAA,qBAId,IAAI,MAAM;AAAA,qCACT,IAAI,MAAM;AAAA,qCACV,IAAI,MAAM;AAAA,iFACD,IAAI,MAAM;AAAA;AAE/B;AAEA,eAAsB,UAAU,KAAiC;AAC/D,QAAM,WAAWA,MAAK,KAAK,IAAI,aAAa,QAAQ;AACpD,QAAMC,IAAG,UAAU,QAAQ;AAG3B,QAAM,eAAeD,MAAK,KAAK,IAAI,aAAa,WAAW;AAC3D,MAAIC,IAAG,WAAW,YAAY,GAAG;AAC/B,UAAM,WAAW,MAAMA,IAAG,SAAS,cAAc,OAAO;AACxD,QAAI,CAAC,SAAS,SAAS,WAAW,GAAG;AACnC,YAAMA,IAAG,WAAW,cAAc,OAAO,cAAc,GAAG,CAAC;AAC3D,UAAI,KAAK,oEAAuB;AAAA,IAClC,OAAO;AACL,UAAI,KAAK,qGAA+B;AAAA,IAC1C;AAAA,EACF,OAAO;AACL,UAAMA,IAAG,UAAU,cAAc,cAAc,GAAG,CAAC;AACnD,QAAI,KAAK,wBAAc;AAAA,EACzB;AAGA,QAAM,gBAAgBD,MAAK,KAAK,UAAU,iBAAiB;AAC3D,QAAMC,IAAG,UAAU,eAAe,iBAAiB,GAAG,CAAC;AACvD,MAAI,KAAK,sEAAwC;AAGjD,QAAM,wBAAwB,IAAI,aAAa;AAAA,IAC7C;AAAA,EACF,CAAC;AAED,MAAI,QAAQ,qCAAiB;AAC/B;;;AL1CA,eAAe,qBAAkD;AAE/D,MAAI,SAAS,UAAU;AACvB,MAAI,CAAC,QAAQ;AACX,aAAS,MAAMC,OAAM;AAAA,MACnB,SAAS;AAAA,IACX,CAAC;AAAA,EACH;AAEA,MAAI,CAAC,QAAQ;AACX,QAAI,MAAM,uIAA6C;AACvD,WAAO;AAAA,EACT;AAEA,QAAM,cAAc,QAAQ,IAAI;AAChC,QAAM,WACJ,YAAY,MAAM,GAAG,EAAE,IAAI,KAAK;AAElC,QAAM,YAAY,MAAMA,OAAM;AAAA,IAC5B,SAAS;AAAA,IACT,SAAS;AAAA,EACX,CAAC;AAED,QAAM,UAAU,MAAMA,OAAM;AAAA,IAC1B,SAAS;AAAA,IACT,SAAS;AAAA,EACX,CAAC;AAED,SAAO,EAAE,QAAQ,aAAa,WAAW,SAAS,SAAS;AAC7D;AAEA,eAAsB,YAAY,MAA6B;AAC7D,QAAM,aAAa,CAAC,UAAU,UAAU,OAAO;AAC/C,MAAI,CAAC,WAAW,SAAS,IAAI,GAAG;AAC9B,QAAI,MAAM,uDAAe,IAAI,+CAAgC;AAC7D;AAAA,EACF;AAEA,MAAI,KAAK,kCAAS,IAAI,qDAAa;AAEnC,QAAM,MAAM,MAAM,mBAAmB;AACrC,MAAI,CAAC,IAAK;AAEV,UAAQ,MAAM;AAAA,IACZ,KAAK;AACH,YAAM,WAAW,GAAG;AACpB;AAAA,IACF,KAAK;AACH,YAAM,WAAW,GAAG;AACpB;AAAA,IACF,KAAK;AACH,YAAM,UAAU,GAAG;AACnB;AAAA,EACJ;AACF;;;AM1EA,OAAOC,UAAQ;AACf,OAAOC,WAAU;AAUjB,eAAsB,gBAA+B;AACnD,MAAI,KAAK,sEAAoB;AAC7B,QAAM,UAAyB,CAAC;AAGhC,QAAM,SAAS,UAAU;AACzB,UAAQ,KAAK;AAAA,IACX,MAAM,8BAAU,WAAW;AAAA,IAC3B,IAAI,CAAC,CAAC;AAAA,IACN,QAAQ,UAAU;AAAA,EACpB,CAAC;AAED,MAAI,CAAC,QAAQ;AACX,iBAAa,OAAO;AACpB;AAAA,EACF;AAGA,QAAM,WAAWC,KAAG,WAAW,MAAM;AACrC,UAAQ,KAAK;AAAA,IACX,MAAM;AAAA,IACN,IAAI;AAAA,IACJ,QAAQ,WAAW,SAAS,GAAG,MAAM;AAAA,EACvC,CAAC;AAED,MAAI,CAAC,UAAU;AACb,iBAAa,OAAO;AACpB;AAAA,EACF;AAGA,QAAM,cAAcC,MAAK,KAAK,QAAQ,cAAc,aAAa;AACjE,QAAM,gBAAgBD,KAAG,WAAW,WAAW;AAC/C,UAAQ,KAAK;AAAA,IACX,MAAM;AAAA,IACN,IAAI;AAAA,IACJ,QAAQ,gBAAgB,iBAAO;AAAA,EACjC,CAAC;AAGD,QAAM,YAAYC,MAAK,KAAK,QAAQ,eAAe;AACnD,QAAM,cAAcD,KAAG,WAAW,SAAS;AAC3C,UAAQ,KAAK;AAAA,IACX,MAAM;AAAA,IACN,IAAI;AAAA,IACJ,QAAQ,cAAc,iBAAO;AAAA,EAC/B,CAAC;AAGD,QAAM,WAAWC,MAAK,KAAK,QAAQ,QAAQ,SAAS,YAAY;AAChE,QAAM,aAAaD,KAAG,WAAW,QAAQ;AACzC,UAAQ,KAAK;AAAA,IACX,MAAM;AAAA,IACN,IAAI;AAAA,IACJ,QAAQ,aAAa,uBAAQ;AAAA,EAC/B,CAAC;AAGD,QAAM,MAAM,QAAQ,IAAI;AACxB,MAAI,QAAQ,QAAQ;AAElB,UAAM,iBAAiBC,MAAK,KAAK,KAAK,WAAW,OAAO;AACxD,QAAID,KAAG,WAAW,cAAc,GAAG;AACjC,YAAM,cAAcC,MAAK,KAAK,gBAAgB,aAAa;AAC3D,UAAID,KAAG,WAAW,WAAW,GAAG;AAC9B,cAAM,OAAO,MAAMA,KAAG,MAAM,WAAW;AACvC,YAAI,KAAK,eAAe,GAAG;AACzB,gBAAM,SAAS,MAAMA,KAAG,SAAS,WAAW;AAC5C,gBAAM,cAAcA,KAAG,WAAW,MAAM;AACxC,kBAAQ,KAAK;AAAA,YACX,MAAM;AAAA,YACN,IAAI;AAAA,YACJ,QAAQ,cAAc,UAAK,MAAM,KAAK,+BAAgB,MAAM;AAAA,UAC9D,CAAC;AAAA,QACH;AAAA,MACF;AAEA,YAAM,eAAeC,MAAK,KAAK,gBAAgB,gBAAgB;AAC/D,cAAQ,KAAK;AAAA,QACX,MAAM;AAAA,QACN,IAAID,KAAG,WAAW,YAAY;AAAA,QAC9B,QAAQA,KAAG,WAAW,YAAY,IAAI,iBAAO;AAAA,MAC/C,CAAC;AAAA,IACH;AAGA,UAAM,eAAeC,MAAK,KAAK,KAAK,WAAW,cAAc;AAC7D,QAAID,KAAG,WAAWC,MAAK,KAAK,KAAK,WAAW,CAAC,GAAG;AAC9C,cAAQ,KAAK;AAAA,QACX,MAAM;AAAA,QACN,IAAID,KAAG,WAAW,YAAY;AAAA,QAC9B,QAAQA,KAAG,WAAW,YAAY,IAAI,iBAAO;AAAA,MAC/C,CAAC;AAAA,IACH;AAGA,UAAM,iBAAiBC,MAAK,KAAK,KAAK,UAAU,iBAAiB;AACjE,QAAID,KAAG,WAAWC,MAAK,KAAK,KAAK,WAAW,CAAC,GAAG;AAC9C,cAAQ,KAAK;AAAA,QACX,MAAM;AAAA,QACN,IAAID,KAAG,WAAW,cAAc;AAAA,QAChC,QAAQA,KAAG,WAAW,cAAc,IAAI,iBAAO;AAAA,MACjD,CAAC;AAAA,IACH;AAAA,EACF;AAEA,eAAa,OAAO;AACtB;AAEA,SAAS,aAAa,SAA8B;AAClD,MAAI,QAAQ;AACZ,aAAW,KAAK,SAAS;AACvB,QAAI,EAAE,IAAI;AACR,UAAI,QAAQ,GAAG,EAAE,IAAI,KAAK,EAAE,MAAM,EAAE;AAAA,IACtC,OAAO;AACL,UAAI,MAAM,GAAG,EAAE,IAAI,KAAK,EAAE,MAAM,EAAE;AAClC,cAAQ;AAAA,IACV;AAAA,EACF;AAEA,UAAQ,IAAI;AACZ,MAAI,OAAO;AACT,QAAI,QAAQ,wCAAU;AAAA,EACxB,OAAO;AACL,QAAI,KAAK,8IAAgC;AAAA,EAC3C;AACF;;;ACzIA,SAAS,eAAe;AACxB,OAAOE,UAAQ;AACf,OAAOC,YAAU;AAIjB,eAAsB,mBAAkC;AACtD,MAAI,KAAK,gEAAwB;AAEjC,QAAM,MAAM,QAAQ,IAAI;AACxB,MAAI,UAAU;AAGd,QAAM,iBAAiBC,OAAK,KAAK,KAAK,WAAW,OAAO;AACxD,MAAIC,KAAG,WAAW,cAAc,GAAG;AAEjC,UAAM,QAAQ,MAAMA,KAAG,QAAQ,cAAc;AAC7C,eAAW,QAAQ,OAAO;AACxB,YAAM,WAAWD,OAAK,KAAK,gBAAgB,IAAI;AAC/C,YAAM,OAAO,MAAMC,KAAG,MAAM,QAAQ;AACpC,UAAI,KAAK,eAAe,GAAG;AACzB,cAAMA,KAAG,OAAO,QAAQ;AACxB,YAAI,KAAK,uCAA6B,IAAI,EAAE;AAC5C;AAAA,MACF;AAAA,IACF;AAGA,UAAM,eAAeD,OAAK,KAAK,gBAAgB,gBAAgB;AAC/D,QAAIC,KAAG,WAAW,YAAY,GAAG;AAC/B,YAAMA,KAAG,OAAO,YAAY;AAC5B,UAAI,KAAK,4CAAkC;AAC3C;AAAA,IACF;AAAA,EACF;AAGA,QAAM,eAAeD,OAAK,KAAK,KAAK,WAAW,cAAc;AAC7D,MAAIC,KAAG,WAAW,YAAY,GAAG;AAC/B,UAAMA,KAAG,OAAO,YAAY;AAC5B,QAAI,KAAK,oCAA0B;AACnC;AAAA,EACF;AAGA,QAAM,iBAAiBD,OAAK,KAAK,KAAK,UAAU,iBAAiB;AACjE,MAAIC,KAAG,WAAW,cAAc,GAAG;AACjC,UAAMA,KAAG,OAAO,cAAc;AAC9B,QAAI,KAAK,sCAA4B;AACrC;AAAA,EACF;AAEA,MAAI,UAAU,GAAG;AACf,QAAI,QAAQ,mCAAe,OAAO,+CAAY;AAAA,EAChD,OAAO;AACL,QAAI,KAAK,oHAA+B;AAAA,EAC1C;AAGA,QAAM,eAAe,CAAC,aAAa,aAAa,WAAW,EAAE;AAAA,IAC3D,CAAC,MAAMA,KAAG,WAAWD,OAAK,KAAK,KAAK,CAAC,CAAC;AAAA,EACxC;AACA,MAAI,aAAa,SAAS,GAAG;AAC3B,QAAI;AAAA,MACF,GAAG,aAAa,KAAK,IAAI,CAAC;AAAA,IAC5B;AAAA,EACF;AAGA,QAAM,SAAS,UAAU;AACzB,QAAM,qBAAqB,MAAM,QAAQ;AAAA,IACvC,SAAS,oEAAkB,WAAW;AAAA,IACtC,SAAS;AAAA,EACX,CAAC;AAED,MAAI,oBAAoB;AACtB,UAAM,YAAY,MAAM,aAAa;AACrC,QAAI,WAAW;AACb,UAAI,KAAK,qDAAa;AAAA,IACxB;AAAA,EACF;AAGA,MAAI,UAAUC,KAAG,WAAW,MAAM,GAAG;AACnC,UAAM,iBAAiB,MAAM,QAAQ;AAAA,MACnC,SAAS,sEAAoB,MAAM;AAAA,MACnC,SAAS;AAAA,IACX,CAAC;AAED,QAAI,gBAAgB;AAClB,YAAMA,KAAG,OAAO,MAAM;AACtB,UAAI,KAAK,6CAAe,MAAM,EAAE;AAAA,IAClC,OAAO;AACL,UAAI,KAAK,6CAAe,MAAM,EAAE;AAAA,IAClC;AAAA,EACF;AAEA,UAAQ,IAAI;AACZ,MAAI,QAAQ,wBAAc;AAC1B,MAAI,KAAK,2GAA+C;AAC1D;;;Ad5FA,IAAMC,WAAU,cAAc,YAAY,GAAG;AAC7C,IAAM,EAAE,QAAQ,IAAIA,SAAQ,iBAAiB;AAE7C,IAAM,UAAU,IAAI,QAAQ;AAE5B,QACG,KAAK,IAAI,EACT,YAAY,iCAAiC,EAC7C,QAAQ,OAAO;AAElB,QACG,QAAQ,MAAM,EACd,YAAY,oDAAiB,EAC7B,OAAO,WAAW;AAErB,QACG,QAAQ,MAAM,EACd,YAAY,mDAAgB,EAC5B,SAAS,gBAAgB,gBAAgB,EACzC,OAAO,WAAW;AAErB,QACG,QAAQ,MAAM,EACd,YAAY,8DAAiB,EAC7B,SAAS,UAAU,yBAAyB,EAC5C,OAAO,WAAW;AAErB,QACG,QAAQ,QAAQ,EAChB,YAAY,iDAAc,EAC1B,OAAO,aAAa;AAEvB,QACG,QAAQ,WAAW,EACnB,YAAY,oDAAsB,EAClC,OAAO,gBAAgB;AAE1B,QAAQ,MAAM;","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 { 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 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 — @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-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(): 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":";;;AAAA,SAAS,eAAe;AACxB,SAAS,qBAAqB;;;ACD9B,SAAS,aAAa;AACtB,OAAOA,SAAQ;AACf,OAAOC,WAAU;AACjB,SAAS,qBAAqB;;;ACH9B,OAAO,QAAQ;AAER,IAAM,MAAM;AAAA,EACjB,MAAM,CAAC,QAAgB,QAAQ,IAAI,GAAG,KAAK,QAAG,IAAI,MAAM,GAAG;AAAA,EAC3D,SAAS,CAAC,QAAgB,QAAQ,IAAI,GAAG,MAAM,QAAG,IAAI,MAAM,GAAG;AAAA,EAC/D,MAAM,CAAC,QAAgB,QAAQ,IAAI,GAAG,OAAO,QAAG,IAAI,MAAM,GAAG;AAAA,EAC7D,OAAO,CAAC,QAAgB,QAAQ,MAAM,GAAG,IAAI,QAAG,IAAI,MAAM,GAAG;AAAA,EAC7D,MAAM,CAAC,QAAgB,QAAQ,IAAI,GAAG,KAAK,UAAK,IAAI,MAAM,GAAG;AAC/D;;;ACJO,SAAS,eACd,UACA,MACQ;AACR,MAAI,SAAS;AACb,aAAW,CAAC,KAAK,KAAK,KAAK,OAAO,QAAQ,IAAI,GAAG;AAC/C,aAAS,OAAO,WAAW,KAAK,GAAG,MAAM,KAAK;AAAA,EAChD;AACA,SAAO;AACT;;;ACbA,OAAO,QAAQ;AACf,OAAO,UAAU;AAGjB,IAAM,aAAa,KAAK;AAAA,EACtB,QAAQ,IAAI,QAAQ;AAAA,EACpB;AAAA,EACA;AACF;AACA,IAAM,cAAc,KAAK,KAAK,YAAY,aAAa;AAShD,SAAS,YAAgC;AAC9C,MAAI;AACF,QAAI,GAAG,WAAW,WAAW,GAAG;AAC9B,YAAM,SAAmB,GAAG,aAAa,WAAW;AACpD,aAAO,OAAO;AAAA,IAChB;AAAA,EACF,QAAQ;AAAA,EAER;AACA,SAAO;AACT;AAKA,eAAsB,WAAW,QAA+B;AAC9D,QAAM,GAAG,UAAU,UAAU;AAC7B,QAAM,GAAG,UAAU,aAAa,EAAE,OAAO,GAAG,EAAE,QAAQ,EAAE,CAAC;AACzD,MAAI,KAAK,8BAAU,WAAW,EAAE;AAClC;AAKA,eAAsB,eAAiC;AACrD,MAAI,GAAG,WAAW,WAAW,GAAG;AAC9B,UAAM,GAAG,OAAO,WAAW;AAC3B,WAAO;AAAA,EACT;AACA,SAAO;AACT;;;AChDA,OAAO,eAAmC;AAC1C,OAAOC,SAAQ;AAER,SAAS,OAAO,KAAyB;AAC9C,SAAO,UAAU,GAAG;AACtB;AAWA,eAAsB,SACpB,KACA,QACe;AACf,QAAM,MAAM,OAAO,GAAG;AACtB,QAAM,IAAI,KAAK;AACf,MAAI,QAAQ;AACV,UAAM,IAAI,UAAU,UAAU,MAAM;AAAA,EACtC;AACF;AAEA,eAAsB,UACpB,KACA,KACe;AACf,QAAMC,IAAG,UAAU,GAAG;AACtB,QAAM,MAAM,UAAU;AACtB,QAAM,IAAI,MAAM,KAAK,GAAG;AAC1B;;;AJzBA,IAAM,YAAYC,MAAK,QAAQ,cAAc,YAAY,GAAG,CAAC;AAC7D,IAAM,gBAAgBA,MAAK,KAAK,WAAW,MAAM,aAAa,cAAc;AAE5E,IAAM,UAAU;AAAA,EACd;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF;AAEA,eAAsB,cAA6B;AACjD,MAAI,KAAK,oEAAkB;AAE3B,QAAM,cAAcA,MAAK,KAAK,QAAQ,IAAI,QAAQ,KAAK,SAAS;AAChE,QAAM,SAAS,MAAM,MAAM;AAAA,IACzB,SAAS;AAAA,IACT,SAAS;AAAA,EACX,CAAC;AACD,QAAM,eAAe,OAAO,WAAW,GAAG,IACtC,OAAO,QAAQ,KAAK,QAAQ,IAAI,QAAQ,EAAE,IAC1CA,MAAK,QAAQ,MAAM;AAEvB,MAAIC,IAAG,WAAW,YAAY,KAAKA,IAAG,YAAY,YAAY,EAAE,SAAS,GAAG;AAC1E,QAAI,MAAM,GAAG,YAAY,kGAAuB;AAChD;AAAA,EACF;AAEA,QAAM,YAAY,MAAM,MAAM;AAAA,IAC5B,SAAS;AAAA,IACT,SAAS;AAAA,EACX,CAAC;AAED,QAAM,SAAQ,oBAAI,KAAK,GAAE,YAAY,EAAE,MAAM,GAAG,EAAE,CAAC;AACnD,QAAM,OAAO,EAAE,MAAM,MAAM;AAG3B,MAAI,KAAK,kDAAe;AACxB,aAAW,OAAO,SAAS;AACzB,UAAMA,IAAG,UAAUD,MAAK,KAAK,cAAc,GAAG,CAAC;AAAA,EACjD;AACA,MAAI,QAAQ,qDAAa;AAGzB,QAAM,eAAeA,MAAK,KAAK,eAAe,WAAW;AACzD,QAAMC,IAAG,KAAK,cAAcD,MAAK,KAAK,cAAc,YAAY,CAAC;AACjE,MAAI,KAAK,yBAAe;AAGxB,QAAM,mBAAmBA,MAAK,KAAK,eAAe,gBAAgB;AAClE,QAAM,gBAAgB,MAAMC,IAAG,QAAQ,gBAAgB;AACvD,aAAW,QAAQ,eAAe;AAChC,UAAM,UAAU,MAAMA,IAAG,SAASD,MAAK,KAAK,kBAAkB,IAAI,GAAG,OAAO;AAC5E,UAAM,WAAW,eAAe,SAAS,IAAI;AAC7C,UAAMC,IAAG,UAAUD,MAAK,KAAK,cAAc,aAAa,IAAI,GAAG,QAAQ;AAAA,EACzE;AACA,MAAI,KAAK,8CAAW;AAGpB,QAAM,eAAeA,MAAK,KAAK,eAAe,YAAY;AAC1D,QAAM,gBAAgBA,MAAK,KAAK,cAAc,OAAO,SAAS,YAAY;AAC1E,QAAMC,IAAG,KAAK,cAAc,aAAa;AACzC,QAAMA,IAAG,MAAM,eAAe,GAAK;AACnC,MAAI,KAAK,8BAAoB;AAG7B,QAAM,aAAaD,MAAK,KAAK,eAAe,kBAAkB;AAC9D,QAAM,cAAcA,MAAK,KAAK,cAAc,OAAO,WAAW,kBAAkB;AAChF,QAAMC,IAAG,KAAK,YAAY,WAAW;AACrC,QAAMA,IAAG,MAAM,aAAa,GAAK;AACjC,MAAI,KAAK,+BAAqB;AAG9B,QAAM,YAAYD,MAAK,KAAK,eAAe,eAAe;AAC1D,QAAM,cAAcA,MAAK,KAAK,eAAe,iBAAiB;AAC9D,QAAMC,IAAG,KAAK,WAAWD,MAAK,KAAK,cAAc,WAAW,aAAa,eAAe,CAAC;AACzF,QAAMC,IAAG,KAAK,aAAaD,MAAK,KAAK,cAAc,WAAW,aAAa,iBAAiB,CAAC;AAC7F,MAAI,KAAK,4DAAyB;AAGlC,QAAMC,IAAG,UAAUD,MAAK,KAAK,cAAc,eAAe,GAAG,CAAC,CAAC;AAC/D,MAAI,KAAK,wDAA0B;AAGnC,QAAM,aAAaA,MAAK,KAAK,eAAe,aAAa;AACzD,QAAM,iBAAiB,MAAMC,IAAG,SAAS,YAAY,OAAO;AAC5D,QAAMA,IAAG;AAAA,IACPD,MAAK,KAAK,cAAc,cAAc,aAAa;AAAA,IACnD,eAAe,gBAAgB,IAAI;AAAA,EACrC;AAEA,QAAM,eAAeA,MAAK,KAAK,eAAe,eAAe;AAC7D,QAAM,mBAAmB,MAAMC,IAAG,SAAS,cAAc,OAAO;AAChE,QAAMA,IAAG;AAAA,IACPD,MAAK,KAAK,cAAc,cAAc,eAAe;AAAA,IACrD,eAAe,kBAAkB,IAAI;AAAA,EACvC;AACA,MAAI,KAAK,oEAAgD;AAGzD,QAAM,SAAS,cAAc,aAAa,MAAS;AACnD,MAAI,KAAK,cAAc,YAAY,cAAc,SAAS,KAAK,GAAG;AAGlE,QAAM,cAAcA,MAAK,KAAK,cAAc,QAAQ,SAAS,YAAY;AACzE,QAAMC,IAAG,KAAK,eAAe,WAAW;AACxC,QAAMA,IAAG,MAAM,aAAa,GAAK;AACjC,MAAI,KAAK,4CAAkC;AAG3C,QAAM,WAAW,YAAY;AAG7B,QAAM,OAAO,MAAM,OAAO,YAAY,GAAG,QAAQ,YAAY;AAC7D,QAAM,IAAI,IAAI,GAAG;AACjB,QAAM,IAAI,OAAO,oCAAgB;AACjC,MAAI,KAAK,wCAAU;AAEnB,MAAI,QAAQ,iCAAa,YAAY,EAAE;AACvC,MAAI,KAAK,4BAAQ;AACjB,MAAI,KAAK,0DAAuB;AAChC,MAAI,KAAK,UAAU;AACnB,MAAI,KAAK,+CAAiB;AAC5B;;;AK/IA,SAAS,SAAAC,cAAa;AACtB,OAAOC,SAAQ;AACf,OAAOC,WAAU;AAKjB,eAAsB,YAAY,WAAkC;AAClE,MAAI,KAAK,uDAAe;AAExB,QAAM,cAAcC,MAAK,KAAK,QAAQ,IAAI,QAAQ,KAAK,SAAS;AAChE,QAAM,SAAS,MAAMC,OAAM;AAAA,IACzB,SAAS;AAAA,IACT,SAAS;AAAA,EACX,CAAC;AACD,QAAM,eAAe,OAAO,WAAW,GAAG,IACtC,OAAO,QAAQ,KAAK,QAAQ,IAAI,QAAQ,EAAE,IAC1CD,MAAK,QAAQ,MAAM;AAEvB,MAAIE,IAAG,WAAW,YAAY,KAAKA,IAAG,YAAY,YAAY,EAAE,SAAS,GAAG;AAC1E,QAAI,MAAM,GAAG,YAAY,kGAAuB;AAChD;AAAA,EACF;AAGA,MAAI,KAAK,qBAAgB;AACzB,QAAM,UAAU,WAAW,YAAY;AACvC,MAAI,QAAQ,oBAAU;AAGtB,QAAM,UAAUF,MAAK,KAAK,cAAc,OAAO,SAAS,YAAY;AACpE,QAAM,WAAWA,MAAK,KAAK,cAAc,QAAQ,SAAS,YAAY;AACtE,MAAIE,IAAG,WAAW,OAAO,GAAG;AAC1B,UAAMA,IAAG,KAAK,SAAS,QAAQ;AAC/B,UAAMA,IAAG,MAAM,UAAU,GAAK;AAC9B,QAAI,KAAK,8BAAoB;AAAA,EAC/B,OAAO;AACL,QAAI,KAAK,oFAAiD;AAAA,EAC5D;AAGA,QAAM,WAAW,YAAY;AAE7B,MAAI,QAAQ,iCAAa,YAAY,EAAE;AACvC,MAAI,KAAK,4BAAQ;AACjB,MAAI,KAAK,sEAA4D;AACvE;;;AC9CA,SAAS,SAAAC,cAAa;;;ACAtB,OAAOC,SAAQ;AACf,OAAOC,WAAU;;;ACDjB,OAAOC,SAAQ;AACf,OAAOC,WAAU;AAMjB,eAAsB,cACpB,QACA,UACe;AACf,QAAMC,IAAG,UAAUC,MAAK,QAAQ,QAAQ,CAAC;AAEzC,MAAID,IAAG,WAAW,QAAQ,GAAG;AAC3B,UAAM,OAAO,MAAMA,IAAG,MAAM,QAAQ;AACpC,QAAI,KAAK,eAAe,GAAG;AACzB,YAAM,WAAW,MAAMA,IAAG,SAAS,QAAQ;AAC3C,UAAI,aAAa,QAAQ;AACvB,YAAI,KAAK,sCAAkBC,MAAK,SAAS,QAAQ,CAAC,EAAE;AACpD;AAAA,MACF;AACA,YAAMD,IAAG,OAAO,QAAQ;AAAA,IAC1B,OAAO;AACL,UAAI,KAAK,GAAG,QAAQ,qGAA+B;AACnD,YAAMA,IAAG,OAAO,QAAQ;AAAA,IAC1B;AAAA,EACF;AAEA,MAAI,CAACA,IAAG,WAAW,MAAM,GAAG;AAC1B,QAAI,KAAK,mDAAqB,MAAM,iDAAc;AAAA,EACpD;AAEA,QAAMA,IAAG,QAAQ,QAAQ,QAAQ;AACjC,MAAI,KAAK,yBAAeC,MAAK,SAAS,QAAQ,CAAC,WAAM,MAAM,EAAE;AAC/D;;;AClCA,OAAOC,SAAQ;AACf,OAAOC,WAAU;AAOjB,eAAsB,wBACpB,KACA,UACe;AACf,QAAM,gBAAgBC,MAAK,KAAK,KAAK,YAAY;AAEjD,MAAI,UAAU;AACd,MAAIC,IAAG,WAAW,aAAa,GAAG;AAChC,cAAU,MAAMA,IAAG,SAAS,eAAe,OAAO;AAAA,EACpD;AAEA,QAAM,QAAQ,QAAQ,MAAM,IAAI;AAChC,QAAM,QAAkB,CAAC;AAEzB,aAAW,WAAW,UAAU;AAC9B,UAAM,UAAU,QAAQ,KAAK;AAC7B,QAAI,CAAC,MAAM,KAAK,CAAC,SAAS,KAAK,KAAK,MAAM,OAAO,GAAG;AAClD,YAAM,KAAK,OAAO;AAAA,IACpB;AAAA,EACF;AAEA,MAAI,MAAM,WAAW,GAAG;AACtB;AAAA,EACF;AAEA,QAAM,YAAY,QAAQ,SAAS,KAAK,CAAC,QAAQ,SAAS,IAAI,IAAI,OAAO;AACzE,QAAM,UACJ,YACA,iCACA,MAAM,KAAK,IAAI,IACf;AAEF,QAAMA,IAAG,WAAW,eAAe,OAAO;AAC1C,MAAI,KAAK,oBAAe,MAAM,MAAM,kCAAS;AAC/C;;;AFnCA,SAAS,uBAAuB,KAA0B;AACxD,SAAO;AAAA;AAAA,qBAEE,IAAI,MAAM;AAAA,qCACT,IAAI,MAAM;AAAA,qCACV,IAAI,MAAM;AAAA,iFACD,IAAI,MAAM;AAAA;AAE/B;AAEA,eAAsB,WAAW,KAAiC;AAChE,QAAM,WAAWC,MAAK,KAAK,IAAI,aAAa,WAAW,OAAO;AAC9D,QAAMC,IAAG,UAAU,QAAQ;AAG3B,QAAM,eAAeD,MAAK,KAAK,IAAI,QAAQ,YAAY;AACvD,QAAM,iBAAiB;AAAA,IACrB,EAAE,MAAM,eAAe,QAAQA,MAAK,KAAK,cAAc,aAAa,EAAE;AAAA,IACtE,EAAE,MAAM,iBAAiB,QAAQA,MAAK,KAAK,cAAc,eAAe,EAAE;AAAA,EAC5E;AAGA,MAAIC,IAAG,WAAW,YAAY,GAAG;AAC/B,UAAM,QAAQ,MAAMA,IAAG,QAAQ,YAAY;AAC3C,eAAW,QAAQ,OAAO;AACxB,UAAI,KAAK,SAAS,cAAc,GAAG;AACjC,uBAAe,KAAK;AAAA,UAClB,MAAM;AAAA,UACN,QAAQD,MAAK,KAAK,cAAc,IAAI;AAAA,QACtC,CAAC;AAAA,MACH;AAAA,IACF;AAAA,EACF;AAEA,aAAW,EAAE,MAAM,OAAO,KAAK,gBAAgB;AAC7C,UAAM,cAAc,QAAQA,MAAK,KAAK,UAAU,IAAI,CAAC;AAAA,EACvD;AAGA,QAAM,eAAeA,MAAK,KAAK,UAAU,gBAAgB;AACzD,QAAMC,IAAG,UAAU,cAAc,uBAAuB,GAAG,CAAC;AAC5D,MAAI,KAAK,4DAA8B;AAGvC,QAAM,eAAeD,MAAK,KAAK,IAAI,aAAa,WAAW,eAAe;AAC1E,MAAI,CAACC,IAAG,WAAW,YAAY,GAAG;AAChC,UAAMA,IAAG,UAAU,cAAc,CAAC,GAAG,EAAE,QAAQ,EAAE,CAAC;AAClD,QAAI,KAAK,oCAA0B;AAAA,EACrC;AAGA,QAAM,wBAAwB,IAAI,aAAa;AAAA,IAC7C;AAAA,EACF,CAAC;AAED,MAAI,QAAQ,uCAAmB;AACjC;;;AG/DA,OAAOC,SAAQ;AACf,OAAOC,WAAU;AAKjB,SAAS,gBAAwB;AAC/B,SAAO;AACT;AAEA,SAAS,gBAAgB,KAA0B;AACjD,QAAM,YAAYC,MAAK,KAAK,IAAI,QAAQ,YAAY;AAEpD,MAAI,UAAU;AAAA;AAAA,qBAEL,IAAI,MAAM;AAAA,qCACT,IAAI,MAAM;AAAA,qCACV,IAAI,MAAM;AAAA,iFACD,IAAI,MAAM;AAAA;AAAA;AAK7B,aAAW,IAAI,SAAS;AAAA;AACxB,aAAW,IAAI,SAAS;AAAA;AAGxB,MAAIC,IAAG,WAAW,SAAS,GAAG;AAC5B,UAAM,QAAQA,IAAG,YAAY,SAAS;AACtC,eAAW,QAAQ,OAAO;AACxB,UAAI,KAAK,SAAS,cAAc,GAAG;AACjC,mBAAW,IAAI,SAAS,IAAI,IAAI;AAAA;AAAA,MAClC;AAAA,IACF;AAAA,EACF;AAEA,SAAO;AACT;AAEA,eAAsB,WAAW,KAAiC;AAChE,QAAM,YAAYD,MAAK,KAAK,IAAI,aAAa,SAAS;AACtD,QAAMC,IAAG,UAAU,SAAS;AAG5B,QAAM,eAAeD,MAAK,KAAK,IAAI,aAAa,WAAW;AAC3D,QAAM,aAAa,cAAc;AACjC,MAAIC,IAAG,WAAW,YAAY,GAAG;AAC/B,UAAM,WAAW,MAAMA,IAAG,SAAS,cAAc,OAAO;AACxD,QAAI,CAAC,SAAS,SAAS,uBAAuB,GAAG;AAC/C,YAAM,UAAU,aAAa,OAAO;AACpC,YAAMA,IAAG,UAAU,cAAc,OAAO;AACxC,UAAI,KAAK,yCAA0B;AAAA,IACrC,OAAO;AACL,UAAI,KAAK,0EAAkC;AAAA,IAC7C;AAAA,EACF,OAAO;AACL,UAAMA,IAAG,UAAU,cAAc,UAAU;AAC3C,QAAI,KAAK,wBAAc;AAAA,EACzB;AAGA,QAAM,aAAaD,MAAK,KAAK,WAAW,cAAc;AACtD,QAAMC,IAAG,UAAU,YAAY,gBAAgB,GAAG,CAAC;AACnD,MAAI,KAAK,+DAA2C;AAGpD,QAAM,eAAeD,MAAK,KAAK,WAAW,eAAe;AACzD,MAAI,CAACC,IAAG,WAAW,YAAY,GAAG;AAChC,UAAMA,IAAG,UAAU,cAAc,CAAC,GAAG,EAAE,QAAQ,EAAE,CAAC;AAClD,QAAI,KAAK,oCAA0B;AAAA,EACrC;AAGA,QAAM,wBAAwB,IAAI,aAAa;AAAA,IAC7C;AAAA,EACF,CAAC;AAED,MAAI,QAAQ,sCAAkB;AAChC;;;AC9EA,OAAOC,SAAQ;AACf,OAAOC,WAAU;AAKjB,SAAS,gBAAwB;AAC/B,SAAO;AACT;AAEA,SAAS,iBAAiB,KAA0B;AAClD,QAAM,YAAYC,MAAK,KAAK,IAAI,QAAQ,YAAY;AAEpD,SAAO;AAAA,wDACO,SAAS;AAAA;AAAA;AAAA;AAAA,qBAId,IAAI,MAAM;AAAA,qCACT,IAAI,MAAM;AAAA,qCACV,IAAI,MAAM;AAAA,iFACD,IAAI,MAAM;AAAA;AAE/B;AAEA,eAAsB,UAAU,KAAiC;AAC/D,QAAM,WAAWA,MAAK,KAAK,IAAI,aAAa,QAAQ;AACpD,QAAMC,IAAG,UAAU,QAAQ;AAG3B,QAAM,eAAeD,MAAK,KAAK,IAAI,aAAa,WAAW;AAC3D,QAAM,cAAc,cAAc;AAClC,MAAIC,IAAG,WAAW,YAAY,GAAG;AAC/B,UAAM,WAAW,MAAMA,IAAG,SAAS,cAAc,OAAO;AACxD,QAAI,CAAC,SAAS,SAAS,kBAAkB,GAAG;AAC1C,YAAMA,IAAG,WAAW,cAAc,OAAO,WAAW;AACpD,UAAI,KAAK,oDAAsB;AAAA,IACjC,OAAO;AACL,UAAI,KAAK,qFAA8B;AAAA,IACzC;AAAA,EACF,OAAO;AACL,UAAMA,IAAG,UAAU,cAAc,WAAW;AAC5C,QAAI,KAAK,wBAAc;AAAA,EACzB;AAGA,QAAM,gBAAgBD,MAAK,KAAK,UAAU,iBAAiB;AAC3D,QAAMC,IAAG,UAAU,eAAe,iBAAiB,GAAG,CAAC;AACvD,MAAI,KAAK,sEAAwC;AAGjD,QAAM,wBAAwB,IAAI,aAAa;AAAA,IAC7C;AAAA,EACF,CAAC;AAED,MAAI,QAAQ,qCAAiB;AAC/B;;;ALxCA,eAAe,qBAAkD;AAE/D,MAAI,SAAS,UAAU;AACvB,MAAI,CAAC,QAAQ;AACX,aAAS,MAAMC,OAAM;AAAA,MACnB,SAAS;AAAA,IACX,CAAC;AAAA,EACH;AAEA,MAAI,CAAC,QAAQ;AACX,QAAI,MAAM,uIAA6C;AACvD,WAAO;AAAA,EACT;AAEA,QAAM,cAAc,QAAQ,IAAI;AAChC,QAAM,WACJ,YAAY,MAAM,GAAG,EAAE,IAAI,KAAK;AAElC,SAAO,EAAE,QAAQ,aAAa,SAAS;AACzC;AAEA,eAAsB,YAAY,MAA6B;AAC7D,QAAM,aAAa,CAAC,UAAU,UAAU,OAAO;AAC/C,MAAI,CAAC,WAAW,SAAS,IAAI,GAAG;AAC9B,QAAI,MAAM,uDAAe,IAAI,+CAAgC;AAC7D;AAAA,EACF;AAEA,MAAI,KAAK,kCAAS,IAAI,qDAAa;AAEnC,QAAM,MAAM,MAAM,mBAAmB;AACrC,MAAI,CAAC,IAAK;AAEV,UAAQ,MAAM;AAAA,IACZ,KAAK;AACH,YAAM,WAAW,GAAG;AACpB;AAAA,IACF,KAAK;AACH,YAAM,WAAW,GAAG;AACpB;AAAA,IACF,KAAK;AACH,YAAM,UAAU,GAAG;AACnB;AAAA,EACJ;AACF;;;AM5DA,OAAOC,UAAQ;AACf,OAAOC,WAAU;AAUjB,eAAsB,gBAA+B;AACnD,MAAI,KAAK,sEAAoB;AAC7B,QAAM,UAAyB,CAAC;AAGhC,QAAM,SAAS,UAAU;AACzB,UAAQ,KAAK;AAAA,IACX,MAAM,8BAAU,WAAW;AAAA,IAC3B,IAAI,CAAC,CAAC;AAAA,IACN,QAAQ,UAAU;AAAA,EACpB,CAAC;AAED,MAAI,CAAC,QAAQ;AACX,iBAAa,OAAO;AACpB;AAAA,EACF;AAGA,QAAM,WAAWC,KAAG,WAAW,MAAM;AACrC,UAAQ,KAAK;AAAA,IACX,MAAM;AAAA,IACN,IAAI;AAAA,IACJ,QAAQ,WAAW,SAAS,GAAG,MAAM;AAAA,EACvC,CAAC;AAED,MAAI,CAAC,UAAU;AACb,iBAAa,OAAO;AACpB;AAAA,EACF;AAGA,QAAM,cAAcC,MAAK,KAAK,QAAQ,cAAc,aAAa;AACjE,QAAM,gBAAgBD,KAAG,WAAW,WAAW;AAC/C,UAAQ,KAAK;AAAA,IACX,MAAM;AAAA,IACN,IAAI;AAAA,IACJ,QAAQ,gBAAgB,iBAAO;AAAA,EACjC,CAAC;AAGD,QAAM,YAAYC,MAAK,KAAK,QAAQ,eAAe;AACnD,QAAM,cAAcD,KAAG,WAAW,SAAS;AAC3C,UAAQ,KAAK;AAAA,IACX,MAAM;AAAA,IACN,IAAI;AAAA,IACJ,QAAQ,cAAc,iBAAO;AAAA,EAC/B,CAAC;AAGD,QAAM,WAAWC,MAAK,KAAK,QAAQ,QAAQ,SAAS,YAAY;AAChE,QAAM,aAAaD,KAAG,WAAW,QAAQ;AACzC,UAAQ,KAAK;AAAA,IACX,MAAM;AAAA,IACN,IAAI;AAAA,IACJ,QAAQ,aAAa,uBAAQ;AAAA,EAC/B,CAAC;AAGD,QAAM,MAAM,QAAQ,IAAI;AACxB,MAAI,QAAQ,QAAQ;AAElB,UAAM,iBAAiBC,MAAK,KAAK,KAAK,WAAW,OAAO;AACxD,QAAID,KAAG,WAAW,cAAc,GAAG;AACjC,YAAM,cAAcC,MAAK,KAAK,gBAAgB,aAAa;AAC3D,UAAID,KAAG,WAAW,WAAW,GAAG;AAC9B,cAAM,OAAO,MAAMA,KAAG,MAAM,WAAW;AACvC,YAAI,KAAK,eAAe,GAAG;AACzB,gBAAM,SAAS,MAAMA,KAAG,SAAS,WAAW;AAC5C,gBAAM,cAAcA,KAAG,WAAW,MAAM;AACxC,kBAAQ,KAAK;AAAA,YACX,MAAM;AAAA,YACN,IAAI;AAAA,YACJ,QAAQ,cAAc,UAAK,MAAM,KAAK,+BAAgB,MAAM;AAAA,UAC9D,CAAC;AAAA,QACH;AAAA,MACF;AAEA,YAAM,eAAeC,MAAK,KAAK,gBAAgB,gBAAgB;AAC/D,cAAQ,KAAK;AAAA,QACX,MAAM;AAAA,QACN,IAAID,KAAG,WAAW,YAAY;AAAA,QAC9B,QAAQA,KAAG,WAAW,YAAY,IAAI,iBAAO;AAAA,MAC/C,CAAC;AAAA,IACH;AAGA,UAAM,eAAeC,MAAK,KAAK,KAAK,WAAW,cAAc;AAC7D,QAAID,KAAG,WAAWC,MAAK,KAAK,KAAK,WAAW,CAAC,GAAG;AAC9C,cAAQ,KAAK;AAAA,QACX,MAAM;AAAA,QACN,IAAID,KAAG,WAAW,YAAY;AAAA,QAC9B,QAAQA,KAAG,WAAW,YAAY,IAAI,iBAAO;AAAA,MAC/C,CAAC;AAAA,IACH;AAGA,UAAM,iBAAiBC,MAAK,KAAK,KAAK,UAAU,iBAAiB;AACjE,QAAID,KAAG,WAAWC,MAAK,KAAK,KAAK,WAAW,CAAC,GAAG;AAC9C,cAAQ,KAAK;AAAA,QACX,MAAM;AAAA,QACN,IAAID,KAAG,WAAW,cAAc;AAAA,QAChC,QAAQA,KAAG,WAAW,cAAc,IAAI,iBAAO;AAAA,MACjD,CAAC;AAAA,IACH;AAAA,EACF;AAEA,eAAa,OAAO;AACtB;AAEA,SAAS,aAAa,SAA8B;AAClD,MAAI,QAAQ;AACZ,aAAW,KAAK,SAAS;AACvB,QAAI,EAAE,IAAI;AACR,UAAI,QAAQ,GAAG,EAAE,IAAI,KAAK,EAAE,MAAM,EAAE;AAAA,IACtC,OAAO;AACL,UAAI,MAAM,GAAG,EAAE,IAAI,KAAK,EAAE,MAAM,EAAE;AAClC,cAAQ;AAAA,IACV;AAAA,EACF;AAEA,UAAQ,IAAI;AACZ,MAAI,OAAO;AACT,QAAI,QAAQ,wCAAU;AAAA,EACxB,OAAO;AACL,QAAI,KAAK,8IAAgC;AAAA,EAC3C;AACF;;;ACzIA,SAAS,eAAe;AACxB,OAAOE,UAAQ;AACf,OAAOC,YAAU;AAIjB,eAAsB,mBAAkC;AACtD,MAAI,KAAK,gEAAwB;AAEjC,QAAM,MAAM,QAAQ,IAAI;AACxB,MAAI,UAAU;AAGd,QAAM,iBAAiBC,OAAK,KAAK,KAAK,WAAW,OAAO;AACxD,MAAIC,KAAG,WAAW,cAAc,GAAG;AAEjC,UAAM,QAAQ,MAAMA,KAAG,QAAQ,cAAc;AAC7C,eAAW,QAAQ,OAAO;AACxB,YAAM,WAAWD,OAAK,KAAK,gBAAgB,IAAI;AAC/C,YAAM,OAAO,MAAMC,KAAG,MAAM,QAAQ;AACpC,UAAI,KAAK,eAAe,GAAG;AACzB,cAAMA,KAAG,OAAO,QAAQ;AACxB,YAAI,KAAK,uCAA6B,IAAI,EAAE;AAC5C;AAAA,MACF;AAAA,IACF;AAGA,UAAM,eAAeD,OAAK,KAAK,gBAAgB,gBAAgB;AAC/D,QAAIC,KAAG,WAAW,YAAY,GAAG;AAC/B,YAAMA,KAAG,OAAO,YAAY;AAC5B,UAAI,KAAK,4CAAkC;AAC3C;AAAA,IACF;AAAA,EACF;AAGA,QAAM,eAAeD,OAAK,KAAK,KAAK,WAAW,cAAc;AAC7D,MAAIC,KAAG,WAAW,YAAY,GAAG;AAC/B,UAAMA,KAAG,OAAO,YAAY;AAC5B,QAAI,KAAK,oCAA0B;AACnC;AAAA,EACF;AAGA,QAAM,iBAAiBD,OAAK,KAAK,KAAK,UAAU,iBAAiB;AACjE,MAAIC,KAAG,WAAW,cAAc,GAAG;AACjC,UAAMA,KAAG,OAAO,cAAc;AAC9B,QAAI,KAAK,sCAA4B;AACrC;AAAA,EACF;AAEA,MAAI,UAAU,GAAG;AACf,QAAI,QAAQ,mCAAe,OAAO,+CAAY;AAAA,EAChD,OAAO;AACL,QAAI,KAAK,oHAA+B;AAAA,EAC1C;AAGA,QAAM,eAAe,CAAC,aAAa,aAAa,WAAW,EAAE;AAAA,IAC3D,CAAC,MAAMA,KAAG,WAAWD,OAAK,KAAK,KAAK,CAAC,CAAC;AAAA,EACxC;AACA,MAAI,aAAa,SAAS,GAAG;AAC3B,QAAI;AAAA,MACF,GAAG,aAAa,KAAK,IAAI,CAAC;AAAA,IAC5B;AAAA,EACF;AAGA,QAAM,SAAS,UAAU;AACzB,QAAM,qBAAqB,MAAM,QAAQ;AAAA,IACvC,SAAS,oEAAkB,WAAW;AAAA,IACtC,SAAS;AAAA,EACX,CAAC;AAED,MAAI,oBAAoB;AACtB,UAAM,YAAY,MAAM,aAAa;AACrC,QAAI,WAAW;AACb,UAAI,KAAK,qDAAa;AAAA,IACxB;AAAA,EACF;AAGA,MAAI,UAAUC,KAAG,WAAW,MAAM,GAAG;AACnC,UAAM,iBAAiB,MAAM,QAAQ;AAAA,MACnC,SAAS,sEAAoB,MAAM;AAAA,MACnC,SAAS;AAAA,IACX,CAAC;AAED,QAAI,gBAAgB;AAClB,YAAMA,KAAG,OAAO,MAAM;AACtB,UAAI,KAAK,6CAAe,MAAM,EAAE;AAAA,IAClC,OAAO;AACL,UAAI,KAAK,6CAAe,MAAM,EAAE;AAAA,IAClC;AAAA,EACF;AAEA,UAAQ,IAAI;AACZ,MAAI,QAAQ,wBAAc;AAC1B,MAAI,KAAK,2GAA+C;AAC1D;;;Ad5FA,IAAMC,WAAU,cAAc,YAAY,GAAG;AAC7C,IAAM,EAAE,QAAQ,IAAIA,SAAQ,iBAAiB;AAE7C,IAAM,UAAU,IAAI,QAAQ;AAE5B,QACG,KAAK,IAAI,EACT,YAAY,iCAAiC,EAC7C,QAAQ,OAAO;AAElB,QACG,QAAQ,MAAM,EACd,YAAY,oDAAiB,EAC7B,OAAO,WAAW;AAErB,QACG,QAAQ,MAAM,EACd,YAAY,mDAAgB,EAC5B,SAAS,gBAAgB,gBAAgB,EACzC,OAAO,WAAW;AAErB,QACG,QAAQ,MAAM,EACd,YAAY,8DAAiB,EAC7B,SAAS,UAAU,yBAAyB,EAC5C,OAAO,WAAW;AAErB,QACG,QAAQ,QAAQ,EAChB,YAAY,iDAAc,EAC1B,OAAO,aAAa;AAEvB,QACG,QAAQ,WAAW,EACnB,YAAY,oDAAsB,EAClC,OAAO,gBAAgB;AAE1B,QAAQ,MAAM;","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
|
@@ -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을
|
|
11
|
-
-
|
|
12
|
+
- 검색 시 인덱스에서 관련 노트를 특정할 것
|
|
13
|
+
- kb-index.json 또는 .kb-index.local.json에서 tags/tldr을 Grep으로 키워드 검색
|
|
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
|
|