Validate one skill (by name) or all compiled skills in this KB.
(ctx, name, strict)
| 2564 | ) |
| 2565 | @click.pass_context |
| 2566 | def skill_validate(ctx, name, strict): |
| 2567 | """Validate one skill (by name) or all compiled skills in this KB.""" |
| 2568 | from openkb.skill import skill_dir, skills_root |
| 2569 | from openkb.skill.validator import validate_skill |
| 2570 | |
| 2571 | kb_dir = _find_kb_dir(ctx.obj.get("kb_dir_override")) |
| 2572 | if kb_dir is None: |
| 2573 | click.echo("No knowledge base found. Run `openkb init` first.", err=True) |
| 2574 | ctx.exit(1) |
| 2575 | |
| 2576 | root = skills_root(kb_dir) |
| 2577 | if not root.is_dir(): |
| 2578 | click.echo("No skills found. Compile one with `openkb skill new`.") |
| 2579 | return |
| 2580 | |
| 2581 | if name: |
| 2582 | target = skill_dir(kb_dir, name) |
| 2583 | if not target.is_dir(): |
| 2584 | click.echo(f"[ERROR] Skill '{name}' not found.", err=True) |
| 2585 | ctx.exit(1) |
| 2586 | targets = [target] |
| 2587 | else: |
| 2588 | targets = sorted( |
| 2589 | d for d in root.iterdir() if d.is_dir() and not d.name.endswith("-workspace") |
| 2590 | ) |
| 2591 | |
| 2592 | any_failed = False |
| 2593 | for t in targets: |
| 2594 | result = validate_skill(t, strict=strict) |
| 2595 | passed = result.passed_strict if strict else result.passed |
| 2596 | prefix = "[OK]" if passed else "[FAIL]" |
| 2597 | click.echo(f"{prefix} {t.name}") |
| 2598 | for err in result.errors: |
| 2599 | click.echo(f" ERROR: {err}") |
| 2600 | for warn in result.warnings: |
| 2601 | click.echo(f" WARN: {warn}") |
| 2602 | if not passed: |
| 2603 | any_failed = True |
| 2604 | |
| 2605 | if any_failed: |
| 2606 | ctx.exit(1) |
| 2607 | |
| 2608 | |
| 2609 | @skill.command("eval") |
nothing calls this directly
no test coverage detected