diff --git a/codex-rs/skills/src/assets/samples/skill-creator/SKILL.md b/codex-rs/skills/src/assets/samples/skill-creator/SKILL.md index 57f4e58b10ce..5944b3d71401 100644 --- a/codex-rs/skills/src/assets/samples/skill-creator/SKILL.md +++ b/codex-rs/skills/src/assets/samples/skill-creator/SKILL.md @@ -233,6 +233,19 @@ Skill creation involves these steps: Follow these steps in order, skipping only if there is a clear reason why they are not applicable. +### Skill Location Contract + +Choose the skill scope before creating files, and use the supported root for that scope: + +- Repository, project, or workspace skills: create the skill under `.agents/skills//SKILL.md` in the current working directory, a parent directory between the current working directory and the repository root, or the repository root itself. If the user asks for a repo-wide skill and the current directory is inside a Git repository, use `$REPO_ROOT/.agents/skills//SKILL.md`. +- User skills: create the skill under `$HOME/.agents/skills//SKILL.md`. +- Admin skills: create the skill under `/etc/codex/skills//SKILL.md` only when the user explicitly requests a machine- or container-wide admin skill and the environment has permission to write there. +- System skills are bundled with Codex by OpenAI and are not a target for user-authored skills. + +Do not create new skills under `/skills`, `/.codex/skills`, `skills/`, `$CODEX_HOME/skills`, or `~/.codex/skills` unless the user explicitly asks for a legacy or custom location and understands it may not match the documented authoring paths. + +If the user asks for a repo-level, project-level, workspace-level, or checked-in skill, treat that as repository scope and use `.agents/skills`. If the user does not specify a scope, ask where to create the skill; when they have no preference, default to a user skill in `$HOME/.agents/skills`. + ### Skill Naming - Use lowercase letters, digits, and hyphens only; normalize user-provided titles to hyphen-case (e.g., "Plan Mode" -> `plan-mode`). @@ -253,7 +266,7 @@ For example, when building an image-editor skill, relevant questions include: - "Can you give some examples of how this skill would be used?" - "I can imagine users asking for things like 'Remove the red-eye from this image' or 'Rotate this image'. Are there other ways you imagine this skill being used?" - "What would a user say that should trigger this skill?" -- "Where should I create this skill? If you do not have a preference, I will place it in `$CODEX_HOME/skills` (or `~/.codex/skills` when `CODEX_HOME` is unset) so Codex can discover it automatically." +- "Should this be a repository skill in `.agents/skills`, or a user skill in `$HOME/.agents/skills`?" To avoid overwhelming users, avoid asking too many questions in a single message. Start with the most important questions and follow up as needed for better effectiveness. @@ -289,7 +302,7 @@ At this point, it is time to actually create the skill. Skip this step only if the skill being developed already exists. In this case, continue to the next step. -Before running `init_skill.py`, ask where the user wants the skill created. If they do not specify a location, default to `$CODEX_HOME/skills`; when `CODEX_HOME` is unset, fall back to `~/.codex/skills` so the skill is auto-discovered. +Before running `init_skill.py`, resolve the skill root from the Skill Location Contract. For repository skills, use `.agents/skills` in the chosen repository directory. For user skills, use `$HOME/.agents/skills`. When creating a new skill from scratch, always run the `init_skill.py` script. The script conveniently generates a new template skill directory that automatically includes everything a skill requires, making the skill creation process much more efficient and reliable. @@ -302,9 +315,10 @@ scripts/init_skill.py --path [--resources script Examples: ```bash -scripts/init_skill.py my-skill --path "${CODEX_HOME:-$HOME/.codex}/skills" -scripts/init_skill.py my-skill --path "${CODEX_HOME:-$HOME/.codex}/skills" --resources scripts,references -scripts/init_skill.py my-skill --path ~/work/skills --resources scripts --examples +scripts/init_skill.py my-repo-skill --path /path/to/repo/.agents/skills +scripts/init_skill.py my-user-skill --path "$HOME/.agents/skills" +scripts/init_skill.py my-user-skill --path "$HOME/.agents/skills" --resources scripts,references +scripts/init_skill.py my-custom-skill --path ~/registered-extra-skill-root --resources scripts --examples ``` The script: diff --git a/codex-rs/skills/src/assets/samples/skill-creator/scripts/init_skill.py b/codex-rs/skills/src/assets/samples/skill-creator/scripts/init_skill.py index 69673eaa048a..deaab2381a24 100644 --- a/codex-rs/skills/src/assets/samples/skill-creator/scripts/init_skill.py +++ b/codex-rs/skills/src/assets/samples/skill-creator/scripts/init_skill.py @@ -6,11 +6,11 @@ init_skill.py --path [--resources scripts,references,assets] [--examples] [--interface key=value] Examples: - init_skill.py my-new-skill --path skills/public - init_skill.py my-new-skill --path skills/public --resources scripts,references - init_skill.py my-api-helper --path skills/private --resources scripts --examples - init_skill.py custom-skill --path /custom/location - init_skill.py my-skill --path skills/public --interface short_description="Short UI label" + init_skill.py my-repo-skill --path /path/to/repo/.agents/skills + init_skill.py my-user-skill --path "$HOME/.agents/skills" + init_skill.py my-api-helper --path /path/to/repo/.agents/skills --resources scripts --examples + init_skill.py custom-skill --path /custom/registered-extra-skill-root + init_skill.py my-skill --path /path/to/repo/.agents/skills --interface short_description="Short UI label" """ import argparse @@ -18,6 +18,10 @@ import sys from pathlib import Path +SCRIPT_DIR = Path(__file__).resolve().parent +if str(SCRIPT_DIR) not in sys.path: + sys.path.insert(0, str(SCRIPT_DIR)) + from generate_openai_yaml import write_openai_yaml MAX_SKILL_NAME_LENGTH = 64 @@ -338,7 +342,14 @@ def main(): description="Create a new skill directory with a SKILL.md template.", ) parser.add_argument("skill_name", help="Skill name (normalized to hyphen-case)") - parser.add_argument("--path", required=True, help="Output directory for the skill") + parser.add_argument( + "--path", + required=True, + help=( + "Output skill root. For repository skills use /.agents/skills; " + "for user skills use $HOME/.agents/skills." + ), + ) parser.add_argument( "--resources", default="",