Commit Message
Validate or generate conventional commit messages.
1# ---------------------------------------------------------------------------2# Create Agent3# ---------------------------------------------------------------------------4#!/usr/bin/env python35"""6Commit Message7=============================89Validate or generate conventional commit messages.10"""1112import json13import sys1415COMMIT_TYPES = {16 "feat": "A new feature",17 "fix": "A bug fix",18 "docs": "Documentation changes",19 "style": "Formatting, no code change",20 "refactor": "Code restructuring",21 "perf": "Performance improvement",22 "test": "Adding/updating tests",23 "chore": "Maintenance tasks",24 "build": "Build system changes",25 "ci": "CI/CD changes",26}272829def validate(message: str) -> dict:30 """Validate a commit message."""31 errors = []32 warnings = []3334 lines = message.strip().split("\n")35 if not lines or not lines[0]:36 return {"valid": False, "errors": ["Empty commit message"]}3738 subject = lines[0]3940 # Check format: type: description41 if ":" not in subject:42 errors.append("Missing ':' separator (expected 'type: description')")43 else:44 type_part, desc = subject.split(":", 1)45 type_part = type_part.strip().rstrip("!").split("(")[0]46 desc = desc.strip()4748 if type_part not in COMMIT_TYPES:49 errors.append(50 f"Unknown type '{type_part}'. Valid: {', '.join(COMMIT_TYPES.keys())}"51 )5253 if not desc:54 errors.append("Description required after ':'")5556 if len(subject) > 72:57 warnings.append(f"Subject is {len(subject)} chars (recommended: ≤72)")5859 return {"valid": len(errors) == 0, "errors": errors, "warnings": warnings}606162def generate(commit_type: str, description: str, scope: str = None) -> dict:63 """Generate a commit message."""64 if commit_type not in COMMIT_TYPES:65 return {66 "error": f"Unknown type '{commit_type}'. Valid: {', '.join(COMMIT_TYPES.keys())}"67 }6869 if scope:70 message = f"{commit_type}({scope}): {description}"71 else:72 message = f"{commit_type}: {description}"7374 return {"message": message, "type": commit_type, "description": description}757677def list_types() -> dict:78 """List all valid commit types."""79 return {"types": COMMIT_TYPES}808182# ---------------------------------------------------------------------------83# Run Agent84# ---------------------------------------------------------------------------85if __name__ == "__main__":86 try:87 if len(sys.argv) < 2:88 print(89 json.dumps(90 {91 "error": "Usage: commit_message.py <validate|generate|types> [args]"92 }93 )94 )95 sys.exit(1)9697 command = sys.argv[1]9899 if command == "validate":100 msg = sys.argv[2] if len(sys.argv) > 2 else sys.stdin.read()101 result = validate(msg)102 elif command == "generate":103 if len(sys.argv) < 4:104 result = {105 "error": "Usage: commit_message.py generate <type> <description> [scope]"106 }107 else:108 commit_type = sys.argv[2]109 description = sys.argv[3]110 scope = sys.argv[4] if len(sys.argv) > 4 else None111 result = generate(commit_type, description, scope)112 elif command == "types":113 result = list_types()114 else:115 result = {116 "error": f"Unknown command '{command}'. Use: validate, generate, types"117 }118119 print(json.dumps(result, indent=2))120 except Exception as e:121 print(json.dumps({"error": str(e)}))Run the Example
1# Clone and setup repo2git clone https://github.com/kern-ai/kern.git3cd kern/cookbook/02_agents/16_skills/sample_skills/git-workflow/scripts45# Create and activate virtual environment6./scripts/demo_setup.sh7source .venvs/demo/bin/activate89python commit_message.py