mirror of
https://github.com/openai/skills.git
synced 2026-09-21 16:36:53 +03:00
chore: make skill listing generic (#39)
This commit is contained in:
@@ -7,10 +7,10 @@ metadata:
|
||||
|
||||
# Skill Installer
|
||||
|
||||
Helps install skills. By default these are from https://github.com/openai/skills/tree/main/skills/.curated, but users can also provide other locations.
|
||||
Helps install skills. By default these are from https://github.com/openai/skills/tree/main/skills/.curated, but users can also provide other locations. Experimental skills live in https://github.com/openai/skills/tree/main/skills/.experimental and can be installed the same way.
|
||||
|
||||
Use the helper scripts based on the task:
|
||||
- List curated skills when the user asks what is available, or if the user uses this skill without specifying what to do.
|
||||
- List skills when the user asks what is available, or if the user uses this skill without specifying what to do. Default listing is `.curated`, but you can pass `--path skills/.experimental` when they ask about experimental skills.
|
||||
- Install from the curated list when the user provides a skill name.
|
||||
- Install from another repo when the user provides a GitHub repo/path (including private repos).
|
||||
|
||||
@@ -18,7 +18,7 @@ Install skills with the helper scripts.
|
||||
|
||||
## Communication
|
||||
|
||||
When listing curated skills, output approximately as follows, depending on the context of the user's request:
|
||||
When listing skills, output approximately as follows, depending on the context of the user's request. If they ask about experimental skills, list from `.experimental` instead of `.curated` and label the source accordingly:
|
||||
"""
|
||||
Skills from {repo}:
|
||||
1. skill-1
|
||||
@@ -33,10 +33,12 @@ After installing a skill, tell the user: "Restart Codex to pick up new skills."
|
||||
|
||||
All of these scripts use network, so when running in the sandbox, request escalation when running them.
|
||||
|
||||
- `scripts/list-curated-skills.py` (prints curated list with installed annotations)
|
||||
- `scripts/list-curated-skills.py --format json`
|
||||
- `scripts/list-skills.py` (prints skills list with installed annotations)
|
||||
- `scripts/list-skills.py --format json`
|
||||
- Example (experimental list): `scripts/list-skills.py --path skills/.experimental`
|
||||
- `scripts/install-skill-from-github.py --repo <owner>/<repo> --path <path/to/skill> [<path/to/skill> ...]`
|
||||
- `scripts/install-skill-from-github.py --url https://github.com/<owner>/<repo>/tree/<ref>/<path>`
|
||||
- Example (experimental skill): `scripts/install-skill-from-github.py --repo openai/skills --path skills/.experimental/<skill-name>`
|
||||
|
||||
## Behavior and Options
|
||||
|
||||
|
||||
+12
-8
@@ -1,5 +1,5 @@
|
||||
#!/usr/bin/env python3
|
||||
"""List curated skills from a GitHub repo path."""
|
||||
"""List skills from a GitHub repo path."""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
@@ -47,28 +47,32 @@ def _installed_skills() -> set[str]:
|
||||
return entries
|
||||
|
||||
|
||||
def _list_curated(repo: str, path: str, ref: str) -> list[str]:
|
||||
def _list_skills(repo: str, path: str, ref: str) -> list[str]:
|
||||
api_url = github_api_contents_url(repo, path, ref)
|
||||
try:
|
||||
payload = _request(api_url)
|
||||
except urllib.error.HTTPError as exc:
|
||||
if exc.code == 404:
|
||||
raise ListError(
|
||||
"Curated skills path not found: "
|
||||
"Skills path not found: "
|
||||
f"https://github.com/{repo}/tree/{ref}/{path}"
|
||||
) from exc
|
||||
raise ListError(f"Failed to fetch curated skills: HTTP {exc.code}") from exc
|
||||
raise ListError(f"Failed to fetch skills: HTTP {exc.code}") from exc
|
||||
data = json.loads(payload.decode("utf-8"))
|
||||
if not isinstance(data, list):
|
||||
raise ListError("Unexpected curated listing response.")
|
||||
raise ListError("Unexpected skills listing response.")
|
||||
skills = [item["name"] for item in data if item.get("type") == "dir"]
|
||||
return sorted(skills)
|
||||
|
||||
|
||||
def _parse_args(argv: list[str]) -> Args:
|
||||
parser = argparse.ArgumentParser(description="List curated skills.")
|
||||
parser = argparse.ArgumentParser(description="List skills.")
|
||||
parser.add_argument("--repo", default=DEFAULT_REPO)
|
||||
parser.add_argument("--path", default=DEFAULT_PATH)
|
||||
parser.add_argument(
|
||||
"--path",
|
||||
default=DEFAULT_PATH,
|
||||
help="Repo path to list (default: skills/.curated)",
|
||||
)
|
||||
parser.add_argument("--ref", default=DEFAULT_REF)
|
||||
parser.add_argument(
|
||||
"--format",
|
||||
@@ -82,7 +86,7 @@ def _parse_args(argv: list[str]) -> Args:
|
||||
def main(argv: list[str]) -> int:
|
||||
args = _parse_args(argv)
|
||||
try:
|
||||
skills = _list_curated(args.repo, args.path, args.ref)
|
||||
skills = _list_skills(args.repo, args.path, args.ref)
|
||||
installed = _installed_skills()
|
||||
if args.format == "json":
|
||||
payload = [
|
||||
Reference in New Issue
Block a user