Setting the file. One moment. List Skills · Skill Installer · openai/skills · Skills DocsPrevious
Script Install Skill From GitHub
scripts/list-skills.py
Python·107 lines·3 KB
=
"openai/skills"
15DEFAULT_PATH = "skills/.curated"
16DEFAULT_REF = "main"
17
18
19class ListError(Exception):
20 pass
21
22
23class Args(argparse.Namespace):
24 repo: str
25 path: str
26 ref: str
27 format: str
28
29
30def _request(url: str) -> bytes:
31 return github_request(url, "codex-skill-list")
32
33
34def _codex_home() -> str:
35 return os.environ.get("CODEX_HOME", os.path.expanduser("~/.codex"))
36
37
38def _installed_skills() -> set[str]:
39 root = os.path.join(_codex_home(), "skills")
40 if not os.path.isdir(root):
41 return set()
42 entries = set()
43 for name in os.listdir(root):
44 path = os.path.join(root, name)
45 if os.path.isdir(path):
46 entries.add(name)
47 return entries
48
49
50def _list_skills(repo: str, path: str, ref: str) -> list[str]:
51 api_url = github_api_contents_url(repo, path, ref)
52 try:
53 payload = _request(api_url)
54 except urllib.error.HTTPError as exc:
55 if exc.code == 404:
56 raise ListError(
57 "Skills path not found: "
58 f"https://github.com/{repo}/tree/{ref}/{path}"
59 ) from exc
60 raise ListError(f"Failed to fetch skills: HTTP {exc.code}") from exc
61 data = json.loads(payload.decode("utf-8"))
62 if not isinstance(data, list):
63 raise ListError("Unexpected skills listing response.")
64 skills = [item["name"] for item in data if item.get("type") == "dir"]
65 return sorted(skills)
66
67
68def _parse_args(argv: list[str]) -> Args:
69 parser = argparse.ArgumentParser(description="List skills.")
70 parser.add_argument("--repo", default=DEFAULT_REPO)
71 parser.add_argument(
72 "--path",
73 default=DEFAULT_PATH,
74 help="Repo path to list (default: skills/.curated)",
75 )
76 parser.add_argument("--ref", default=DEFAULT_REF)
77 parser.add_argument(
78 "--format",
79 choices=["text", "json"],
80 default="text",
81 help="Output format",
82 )
83 return parser.parse_args(argv, namespace=Args())
84
85
86def main(argv: list[str]) -> int:
87 args = _parse_args(argv)
88 try:
89 skills = _list_skills(args.repo, args.path, args.ref)
90 installed = _installed_skills()
91 if args.format == "json":
92 payload = [
93 {"name": name, "installed": name in installed} for name in skills
94 ]
95 print(json.dumps(payload))
96 else:
97 for idx, name in enumerate(skills, start=1):
98 suffix = " (already installed)" if name in installed else ""
99 print(f"{idx}. {name}{suffix}")
100 return 0
101 except ListError as exc:
102 print(f"Error: {exc}", file=sys.stderr)
103 return 1
104
105
106if __name__ == "__main__":
107 raise SystemExit(main(sys.argv[1:]))