Find the KB root: explicit override → walk up from cwd → global default_kb.
(override: Path | None = None)
| 277 | |
| 278 | |
| 279 | def _find_kb_dir(override: Path | None = None) -> Path | None: |
| 280 | """Find the KB root: explicit override → walk up from cwd → global default_kb.""" |
| 281 | # 0. Explicit override (--kb-dir or OPENKB_DIR) |
| 282 | if override is not None: |
| 283 | if (override / ".openkb").is_dir(): |
| 284 | return override |
| 285 | return None |
| 286 | # 1. Walk up from cwd |
| 287 | current = Path.cwd().resolve() |
| 288 | while True: |
| 289 | if (current / ".openkb").is_dir(): |
| 290 | return current |
| 291 | parent = current.parent |
| 292 | if parent == current: |
| 293 | break |
| 294 | current = parent |
| 295 | # 2. Fall back to global config default_kb |
| 296 | gc = load_global_config() |
| 297 | default = gc.get("default_kb") |
| 298 | if default: |
| 299 | p = Path(default) |
| 300 | if (p / ".openkb").is_dir(): |
| 301 | return p |
| 302 | return None |
| 303 | |
| 304 | |
| 305 | def _validate_skill_name(name: str) -> str | None: |