from __future__ import annotations from beaver.skills.assembler.task_assembler import SkillAssembler from beaver.skills.catalog.loader import SkillsLoader from beaver.skills.catalog.utils import extract_skill_team_template def test_extract_team_template_returns_none_when_block_is_absent() -> None: result = extract_skill_team_template("# Ordinary Skill") assert result.template is None assert result.warnings == [] def test_extract_team_template_parses_valid_json_block() -> None: result = extract_skill_team_template( "```beaver-team-template\n" '{"version": 1, "nodes": [{"node_id": "collect", "task": "Collect"}]}\n' "```" ) assert result.template == { "version": 1, "nodes": [{"node_id": "collect", "task": "Collect"}], } assert result.warnings == [] def test_invalid_template_is_warning_not_skill_load_failure() -> None: result = extract_skill_team_template("```beaver-team-template\nnot-json\n```") assert result.template is None assert result.warnings == ["team template JSON is invalid"] def test_loader_and_assembler_propagate_team_template_to_skill_context(tmp_path) -> None: skill_dir = tmp_path / "plugin-skills" / "financial-comparison" skill_dir.mkdir(parents=True) (skill_dir / "SKILL.md").write_text( "---\n" "description: Compare financial disclosures.\n" "---\n\n" "# Financial Comparison\n\n" "```beaver-team-template\n" '{"version": 1, "nodes": [{"node_id": "collect", "task": "Collect official sources"}]}\n' "```\n", encoding="utf-8", ) loader = SkillsLoader( tmp_path, builtin_skills_dir=tmp_path / "no-builtins", extra_dirs=[tmp_path / "plugin-skills"], ) record = loader.get_skill_record("financial-comparison") context = SkillAssembler(loader)._activate_skill_contexts(["financial-comparison"])[0] assert record is not None assert record.team_template == { "version": 1, "nodes": [{"node_id": "collect", "task": "Collect official sources"}], } assert record.team_template_warnings == [] assert context.team_template == record.team_template assert context.team_template_warnings == []