Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
40 changes: 40 additions & 0 deletions src/agent_rules_kit/cli.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,12 @@
from __future__ import annotations

import argparse
import sys
from collections.abc import Sequence
from pathlib import Path

from agent_rules_kit import __version__
from agent_rules_kit.discovery import discover_instruction_files


def build_parser() -> argparse.ArgumentParser:
Expand All @@ -19,6 +22,20 @@ def build_parser() -> argparse.ArgumentParser:
action="store_true",
help="Print the package version and exit.",
)

subparsers = parser.add_subparsers(dest="command")

check_parser = subparsers.add_parser(
"check",
help="Discover supported agent instruction files in a repository.",
)
check_parser.add_argument(
"repository",
nargs="?",
default=".",
help="Repository root to inspect. Defaults to the current directory.",
)

return parser


Expand All @@ -31,9 +48,32 @@ def main(argv: Sequence[str] | None = None) -> int:
print(f"agent-rules-kit {__version__}")
return 0

if args.command == "check":
return _run_check(Path(args.repository))

parser.print_help()
return 0


def _run_check(repository_root: Path) -> int:
try:
instruction_files = discover_instruction_files(repository_root)
except ValueError as error:
print(f"ERROR: {error}", file=sys.stderr)
return 2

print(f"agent-rules-kit check: {repository_root}")

if not instruction_files:
print("No supported agent instruction files found.")
return 1

print(f"Found {len(instruction_files)} supported instruction file(s):")
for instruction_file in instruction_files:
print(f"- {instruction_file.path} [{instruction_file.kind.value}]")

return 0


if __name__ == "__main__":
raise SystemExit(main())
44 changes: 43 additions & 1 deletion tests/test_cli.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,13 @@

import io
import unittest
from contextlib import redirect_stdout
from contextlib import redirect_stderr, redirect_stdout
from pathlib import Path

from agent_rules_kit.cli import main

FIXTURE_ROOT = Path(__file__).parent / "fixtures" / "repositories"


class CliTests(unittest.TestCase):
def test_version_flag_prints_version(self) -> None:
Expand All @@ -25,6 +28,45 @@ def test_help_is_default(self) -> None:

self.assertEqual(exit_code, 0)
self.assertIn("usage:", output.getvalue())
self.assertIn("check", output.getvalue())

def test_check_reports_discovered_instruction_files(self) -> None:
output = io.StringIO()

with redirect_stdout(output):
exit_code = main(["check", str(FIXTURE_ROOT / "multi-agent-overlap")])

text = output.getvalue()

self.assertEqual(exit_code, 0)
self.assertIn("Found 6 supported instruction file(s):", text)
self.assertIn("- AGENTS.md [agents]", text)
self.assertIn("- CLAUDE.md [claude]", text)
self.assertIn("- GEMINI.md [gemini]", text)
self.assertIn("- .cursor/rules/agent-rules.mdc [cursor-rule]", text)
self.assertIn("- .github/copilot-instructions.md [copilot]", text)
self.assertIn(
"- .github/instructions/agents.instructions.md [github-instruction]",
text,
)

def test_check_returns_one_when_no_instruction_files_are_found(self) -> None:
output = io.StringIO()

with redirect_stdout(output):
exit_code = main(["check", str(FIXTURE_ROOT / "empty-repo")])

self.assertEqual(exit_code, 1)
self.assertIn("No supported agent instruction files found.", output.getvalue())

def test_check_returns_two_for_invalid_repository_root(self) -> None:
output = io.StringIO()

with redirect_stderr(output):
exit_code = main(["check", str(FIXTURE_ROOT / "missing-repo")])

self.assertEqual(exit_code, 2)
self.assertIn("ERROR: repository root does not exist:", output.getvalue())


if __name__ == "__main__":
Expand Down
Loading