#!/usr/bin/env python3 """Generate .github/copilot-instructions.md from AGENTS.md and skills. Necessary until copilot can handle skills. """ from pathlib import Path import sys GENERATED_MESSAGE = ( f"\n\n" ) AGENTS_FILE = Path("AGENTS.md") OUTPUT_FILE = Path(".github/copilot-instructions.md") INTEGRATION_SKILL_FILE = Path(".claude/skills/ha-integration-knowledge/SKILL.md") INTEGRATION_PATH_SPECIFIC_OUTPUT_FILE = Path( ".github/instructions/integrations.instructions.md" ) COPILOT_SPECIFIC_INSTRUCTIONS = """ # Copilot code review instructions - Start review comments with a short, one-sentence summary of the suggested fix. - Do not comment on code style, formatting or linting issues. - A Pull Request with a dependency version bump should only contain changes required for the version bump. If the PR includes other changes, request that they are removed from the PR. """ INTEGRATION_PATH_SPECIFIC_INSTRUCTIONS = """--- applyTo: "homeassistant/components/**, tests/components/**" excludeAgent: "cloud-agent" --- """ def _strip_frontmatter(text: str) -> str: """Strip YAML frontmatter from the start of a markdown document.""" if not text.startswith("---\n"): return text end = text.find("\n---\n", 4) if end == -1: return text return text[end + len("\n---\n") :].lstrip("\n") def generate_integration_path_specific_instructions() -> str: """Generate instructions for integration paths.""" if not INTEGRATION_SKILL_FILE.exists(): print(f"Error: {INTEGRATION_SKILL_FILE} not found") sys.exit(1) skill_content = _strip_frontmatter(INTEGRATION_SKILL_FILE.read_text()) return ( INTEGRATION_PATH_SPECIFIC_INSTRUCTIONS + "\n" + GENERATED_MESSAGE + "\n" + skill_content ) def generate_output() -> str: """Generate the copilot-instructions.md content.""" if not AGENTS_FILE.exists(): print(f"Error: {AGENTS_FILE} not found") sys.exit(1) output_parts: list[str] = [GENERATED_MESSAGE, COPILOT_SPECIFIC_INSTRUCTIONS] # Add AGENTS.md content agents_content = AGENTS_FILE.read_text() output_parts.append(agents_content.strip()) output_parts.append("") return "\n".join(output_parts) def check_file(path: Path, expected_content: str): """Check if the file exists and has the expected content.""" if not path.exists(): print(f"Error: {path} does not exist") sys.exit(1) existing = path.read_text() if existing != expected_content: print(f"Error: {path} is out of date") print("Please run: python -m script.gen_copilot_instructions") sys.exit(1) print(f"{path} is up to date") def main(validate: bool = False) -> int: """Run the script.""" if not Path("homeassistant").is_dir(): print("Run this from HA root dir") return 1 main_content = generate_output() integration_path_specific_content = ( generate_integration_path_specific_instructions() ) if validate: check_file(OUTPUT_FILE, main_content) check_file( INTEGRATION_PATH_SPECIFIC_OUTPUT_FILE, integration_path_specific_content ) return 0 OUTPUT_FILE.write_text(main_content) print(f"Generated {OUTPUT_FILE}") INTEGRATION_PATH_SPECIFIC_OUTPUT_FILE.write_text(integration_path_specific_content) print(f"Generated {INTEGRATION_PATH_SPECIFIC_OUTPUT_FILE}") return 0 if __name__ == "__main__": _validate = len(sys.argv) > 1 and sys.argv[1] == "validate" sys.exit(main(_validate))