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

但新開執行緒時,實際暴露出來的只有:

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 會認為它沒有以前置資料分隔符開頭,最後報:

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 設計