File size: 2,565 Bytes
ee0b555
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
#!/usr/bin/env python3
"""Fail CI when parser, sandbox guide, or public-skill inventory drifts."""

from __future__ import annotations

import sys
from pathlib import Path

REPOSITORY = Path(__file__).resolve().parents[2]
sys.path.insert(0, str(REPOSITORY / "standalone_cli" / "src"))

from pwc_cli.cli import build_parser  # noqa: E402

EDIT_COMMANDS = ("auth login", "auth status", "auth logout", "paper edit export", "paper edit preview", "paper edit submit")

COMMANDS = (
    "search",
    "paper info",
    "paper evaluations",
    "paper read",
    "paper list",
    "paper recent",
    "paper trending",
    "paper related",
    "paper lineage list",
    "task",
    "task list",
    "method",
    "method list",
    "conference",
    "conference list",
    "organization",
    "organization list",
    "framework",
    "framework list",
    "benchmark",
    "benchmark list",
    "skills add",
    "version",
)

RESEARCH_COMMANDS = tuple(command for command in COMMANDS if command != "skills add")


def parser_commands() -> set[str]:
    parser = build_parser()
    discovered: set[str] = set()

    def visit(current, prefix: str = ""):
        for action in current._actions:
            choices = getattr(action, "choices", None)
            if not isinstance(choices, dict):
                continue
            for name, child in choices.items():
                command = f"{prefix} {name}".strip()
                nested = any(
                    isinstance(getattr(item, "choices", None), dict)
                    for item in child._actions
                )
                if nested:
                    if "handler" in child._defaults:
                        discovered.add(command)
                    visit(child, command)
                else:
                    discovered.add(command)

    visit(parser)
    return discovered


def main() -> int:
    expected = set(COMMANDS) | set(EDIT_COMMANDS)
    if parser_commands() != expected:
        raise SystemExit("standalone parser command inventory drifted")
    skill = (REPOSITORY / "standalone_cli" / "SKILL.md").read_text()
    for command in EDIT_COMMANDS:
        if f"pwc {command}" not in skill:
            raise SystemExit(f"missing edit command: {command}")
    for command in RESEARCH_COMMANDS:
        if command == "version":
            continue
        invocation = f"pwc {command}"
        if invocation not in skill:
            raise SystemExit(f"missing read-only inventory entry: {invocation}")
    return 0


if __name__ == "__main__":
    raise SystemExit(main())