feat(build): fail configuration validation on unknown Claude tool names
Check every generated agent's tools frontmatter against the set of real Claude Code tool names, so an unrecognized name fails validate-config.py (and therefore the build) instead of silently shipping a broken agent. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
1 parent
4da6950062
commit
99c345f551
1 file changed
+14
@@ -15,6 +15,7 @@ CLAUDE_SANDBOX_KEYS = {"enabled", "allowUnsandboxedCommands"}
|
|||||||
CLAUDE_STATUS_LINE_KEYS = {"type", "command"}
|
CLAUDE_STATUS_LINE_KEYS = {"type", "command"}
|
||||||
CLAUDE_HOOK_KEYS = {"type", "command", "timeout"}
|
CLAUDE_HOOK_KEYS = {"type", "command", "timeout"}
|
||||||
CLAUDE_PERMISSION_MODES = {"acceptEdits", "auto", "bypassPermissions", "default", "dontAsk", "plan"}
|
CLAUDE_PERMISSION_MODES = {"acceptEdits", "auto", "bypassPermissions", "default", "dontAsk", "plan"}
|
||||||
|
CLAUDE_VALID_TOOLS = {"Read", "Grep", "Glob", "Edit", "Write", "Bash", "PowerShell", "WebFetch", "WebSearch"}
|
||||||
|
|
||||||
|
|
||||||
def fail(message: str) -> None:
|
def fail(message: str) -> None:
|
||||||
@@ -72,6 +73,18 @@ def validate_rule_skills(package: Path) -> None:
|
|||||||
fail(f"{path}: skill description must be a quoted, nonempty string")
|
fail(f"{path}: skill description must be a quoted, nonempty string")
|
||||||
|
|
||||||
|
|
||||||
|
def validate_agent_tools(package: Path) -> None:
|
||||||
|
for path in (package / "agents").glob("*.md"):
|
||||||
|
lines = path.read_text(encoding="utf-8-sig").splitlines()
|
||||||
|
tools_line = next((line for line in lines if line.startswith("tools: ")), None)
|
||||||
|
if tools_line is None:
|
||||||
|
continue
|
||||||
|
tools = [item.strip() for item in tools_line.removeprefix("tools: ").split(",")]
|
||||||
|
unknown = [tool for tool in tools if tool not in CLAUDE_VALID_TOOLS]
|
||||||
|
if unknown:
|
||||||
|
fail(f"{path}: unknown Claude tool name(s): {', '.join(unknown)}")
|
||||||
|
|
||||||
|
|
||||||
def main() -> int:
|
def main() -> int:
|
||||||
if len(sys.argv) != 3:
|
if len(sys.argv) != 3:
|
||||||
print("usage: validate-config.py <codex-toml> <claude-json>", file=sys.stderr)
|
print("usage: validate-config.py <codex-toml> <claude-json>", file=sys.stderr)
|
||||||
@@ -79,6 +92,7 @@ def main() -> int:
|
|||||||
tomllib.loads(Path(sys.argv[1]).read_text(encoding="utf-8-sig"))
|
tomllib.loads(Path(sys.argv[1]).read_text(encoding="utf-8-sig"))
|
||||||
validate_claude(Path(sys.argv[2]))
|
validate_claude(Path(sys.argv[2]))
|
||||||
validate_rule_skills(Path(sys.argv[2]).parent)
|
validate_rule_skills(Path(sys.argv[2]).parent)
|
||||||
|
validate_agent_tools(Path(sys.argv[2]).parent)
|
||||||
return 0
|
return 0
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
Reference in new issue
Block a user