How the Codex-Skills Sync Script Generates SKILL.md from Skill Files
The scripts/sync-codex-skills.py tool in the ai-berkshire repository transforms Claude Command markdown files in skills/*.md into Codex-compatible SKILL.md artifacts by parsing YAML front-matter, injecting adapter metadata, and prepending a conversion note that maps Claude-specific constructs to Codex capabilities.
The codex-skills sync script maintains consistency between the repository's Claude-focused workflow documentation and its Codex variants. By treating files in skills/*.md as the canonical source, the script ensures that updates to Claude commands automatically propagate to the codex-skills/<skill>/SKILL.md targets without manual duplication.
Five-Stage Transformation Pipeline
The generation process implemented in scripts/sync-codex-skills.py follows a deterministic pipeline, with each stage handled by a specialized helper function.
Stage 1: Splitting Front-Matter from Body
The split_frontmatter function (lines 16-22) detects YAML front-matter blocks delimited by ---\n markers. It returns the header content separately from the document body, handling cases where no front-matter exists by returning None for the header. This allows the script to process both annotated and bare markdown sources uniformly.
Stage 2: Deriving Human-Readable Titles
To ensure every skill carries a meaningful identifier, the first_heading function (lines 25-30) scans the markdown body for the first level-one heading (# …). If the document lacks an H1, the script falls back to the file stem (e.g., my-skill from my-skill.md), guaranteeing consistent title extraction regardless of authoring style.
Stage 3: Building or Preserving Metadata
The metadata_for function (lines 37-61) constructs the YAML header through a merge strategy:
- Existing front-matter: Preserved intact, with automatic injection of missing
nameanddescriptionfields - New files: Creates a metadata block containing the file stem as
nameand a synthesized description referencing the original skill title
This approach ensures backward compatibility while enforcing that all Codex skills include the required identification fields consumed by the platform.
Stage 4: Assembling the Codex-Specific Body
The codex_body function (lines 64-90) prepares the document content by prefixing the original body (minus its front-matter) with a static "## Codex adapter note" section. This note explains how Claude-only concepts such as Task, Agent, and WebSearch map to Codex-compatible actions, referencing guidelines in AGENTS.md to provide platform-specific context.
Stage 5: Writing or Verifying Output
The main function (lines 92-133) orchestrates file operations across two modes:
- Generation mode: Creates the
codex-skills/<name>/directory and writes the assembledSKILL.mdfile - Check mode: When invoked with
--check, compares generated content against existing files without writing, exiting with status 1 if stale
This dual-mode architecture supports both one-time generation and CI enforcement of documentation freshness.
Execution Flow in Practice
The script iterates over source files using a glob pattern and processes each through the transformation pipeline:
# Core iteration logic from scripts/sync-codex-skills.py
for source in sorted(CLAUDE_SKILLS.glob("*.md")):
source_text = source.read_text()
name = source.stem
target_dir = CODEX_SKILLS / name
# Generate components
metadata = metadata_for(name, source.name, source_text)
body = codex_body(name, source.name, source_text)
content = metadata + body
# Write or verify based on mode
if args.check:
verify_unchanged(target_dir / "SKILL.md", content)
else:
target_dir.mkdir(parents=True, exist_ok=True)
(target_dir / "SKILL.md").write_text(content)
Each output path follows the deterministic structure codex-skills/<skill-name>/SKILL.md, containing the generated YAML header, the adapter explanation, and the original workflow instructions.
Command-Line Usage
Regenerate all Codex skills from the repository root:
python3 scripts/sync-codex-skills.py
Validate that generated files match their sources (useful for CI):
python3 scripts/sync-codex-skills.py --check
The check mode ensures that any edit to skills/*.md without a corresponding regeneration of the Codex variant triggers a build failure, preventing documentation drift.
Summary
- Single source of truth: Authors edit only
skills/*.md; the codex-skills sync script automatically derives Codex variants - Metadata preservation: The
metadata_forfunction maintains existing YAML while injecting requirednameanddescriptionfields - Platform bridging: Static adapter notes generated by
codex_bodyclarify Claude-to-Codex conceptual mappings and referenceAGENTS.md - CI integration: The
--checkflag supports automated verification, exiting with status 1 whenSKILL.mdfiles are stale - Deterministic output: Generated files always land in
codex-skills/<skill-name>/SKILL.mdwith predictable structure derived from the source basename
Frequently Asked Questions
What happens if my skill file lacks YAML front-matter?
The script handles bare markdown gracefully. The split_frontmatter function returns None for the header, triggering metadata_for to generate a fresh YAML block containing the filename stem as the skill name and a default description referencing the document title. Your original content remains intact while gaining the required Codex metadata structure.
Can I customize the generated SKILL.md files?
Direct customization of files in codex-skills/ is discouraged because the sync script overwrites them on each execution. Instead, modify the source file in skills/*.md or update the transformation logic—specifically the codex_body function (lines 64-90) if you need to adjust the adapter note template or the metadata_for function (lines 37-61) to change YAML field generation.
How does the --check flag function in CI pipelines?
When invoked with --check, the script generates the expected content for each skill but performs a read-only comparison against the existing codex-skills/<skill>/SKILL.md file. If the generated text differs from the stored version, the script reports the specific file and exits with status 1. This enables GitHub Actions or similar platforms to fail builds when developers commit changes to skills/*.md without synchronizing the Codex outputs.
Where does the adapter note content originate?
The "## Codex adapter note" section comes from static text defined within the codex_body function (lines 64-90) of scripts/sync-codex-skills.py. This content explains Claude-to-Codex capability mapping and references AGENTS.md for quality standards. To update the note across all generated skills, modify this function and rerun the sync script to propagate changes to every SKILL.md target.
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →