Codex Skill はディレクトリにあるのに、なぜ表示されないのか?

Codex skill が ~/.codex/skills に存在しているのに、SKILL.md の先頭に UTF-8 BOM があったため YAML front matter を認識できなかった事例の記録。

今回の問題はかなり見落としやすいものでした。~/.codex/skills には複数の skill が置かれているのに、新しい Codex スレッドを開いても、サイドバーには一部しか表示されませんでした。

最初はキャッシュやインデックスの問題に見えました。実際の原因はもっと具体的で、いくつかの SKILL.md ファイルの先頭に UTF-8 BOM が付いていました。Codex 0.111.0 の skill loader はこのバイト列を読み飛ばさず、結果として有効な YAML front matter がないと誤判定していました。

現象

ローカルディレクトリには次の skill がありました。

1
2
3
4
~/.codex/skills/git-commit-push/SKILL.md
~/.codex/skills/hugo-rsync-deploy/SKILL.md
~/.codex/skills/bilibili-speech-transcriber/SKILL.md
~/.codex/skills/product-cutout-normalize/SKILL.md

しかし新しいスレッドで実際に公開された skill は次の二つだけでした。

1
2
bilibili-speech-transcriber
product-cutout-normalize

つまり、ファイルが存在することと、現在のセッションで読み込めることは別です。Codex は各 SKILL.md の front matter を先に解析し、解析に失敗した skill はそのまま除外します。

調査

codex exec で新しいセッションを起動すると、より直接的なエラーが見えます。VS Code などの IDE では、こうした log が見えない場合があります。

1
2
failed to load skill C:\Users\knightli\.codex\skills\git-commit-push\SKILL.md: missing YAML frontmatter delimited by ---
failed to load skill C:\Users\knightli\.codex\skills\hugo-rsync-deploy\SKILL.md: missing YAML frontmatter delimited by ---

これらのファイルは、見た目には正常な先頭を持っていました。

1
2
3
4
---
name: post-rewrite
description: ...
---

本当の問題はバイト列にありました。

失敗するファイルの先頭は:

1
EF-BB-BF-2D-2D-2D

正常に読み込まれるファイルの先頭は:

1
2D-2D-2D

2D-2D-2D--- です。その前にある EF-BB-BF が UTF-8 BOM です。

原因

Codex 0.111.0 の skill loader は、SKILL.md の最初のバイトが --- の最初の - であることを期待しています。

ファイルの先頭に UTF-8 BOM があると、実際の先頭は次のようになります。

1
BOM + ---

そのため loader は、ファイルが front matter の区切りで始まっていないと判断し、最終的に次のエラーを出します。

1
missing YAML frontmatter delimited by ---

skill の内容が間違っていたわけでも、ディレクトリが間違っていたわけでもありません。エンコーディングの細部が原因で、パーサーがファイルを認識できなかっただけです。

修正

問題のある SKILL.md を BOM なしの UTF-8 に変換します。

PowerShell では次のように処理できます。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
$paths = @(
  'C:\Users\knightli\.codex\skills\git-commit-push\SKILL.md',
  'C:\Users\knightli\.codex\skills\hugo-rsync-deploy\SKILL.md',
)

$utf8NoBom = New-Object System.Text.UTF8Encoding($false)

foreach ($p in $paths) {
  $text = [IO.File]::ReadAllText($p, [Text.Encoding]::UTF8)
  [IO.File]::WriteAllText($p, $text, $utf8NoBom)
}

処理後にファイルヘッダーを確認すると、次の状態から:

1
EF-BB-BF-2D-2D-2D

次の状態に変わっているはずです。

1
2D-2D-2D

検証

Codex セッションを再起動すると、表示される skill は次のように戻りました。

1
2
3
4
git-commit-push-zh
hugo-rsync-deploy
bilibili-speech-transcriber
product-cutout-normalize

それでもサイドバーに古い一覧しか表示されない場合は、現在の Codex sidebar またはウィンドウを閉じて、プロジェクトを開き直します。skill 一覧は通常セッション開始時に読み込まれるため、途中でファイルを変更してもすぐには反映されないことがあります。

最後に

この種の問題は、「Codex が再インデックスしていない」または「skill のインストールに失敗した」と誤解しやすいです。

実際に調べるときは、まず次の三点を確認するとよいです。

  • SKILL.md が正しいディレクトリにあるか
  • ファイル先頭に有効な --- front matter があるか
  • ファイルが BOM なしの UTF-8 か

今回のポイントは三つ目です。ファイルは見た目には問題ありませんでしたが、最初のバイトが - ではなかったため、Codex はそれを有効な skill として扱いませんでした。

记录并分享
Hugo で構築されています。
テーマ StackJimmy によって設計されています。