diff --git a/README.md b/README.md index 5972e97ce..63766fc3a 100644 --- a/README.md +++ b/README.md @@ -222,7 +222,7 @@ For the full configuration reference — all settings, git branching strategies, **Commands not showing up?** Restart your runtime after install. GSD installs to `~/.claude/skills/gsd-*/` (Claude Code), `~/.codex/skills/gsd-*/` (Codex), or the equivalent for your runtime. -**Codex users — minimum supported CLI version is `0.130.0`.** Codex CLI 0.130.0 ([release notes](https://github.com/openai/codex/releases/tag/rust-v0.130.0)) removed extra-skill-roots discovery via [openai/codex#21485](https://github.com/openai/codex/pull/21485); from that version onward Codex only discovers skills from `~/.codex/skills//SKILL.md`. GSD installs there directly. Earlier Codex CLI versions may show duplicate `gsd-*` entries (one from extra-roots discovery, one from `~/.codex/skills/`); restart Codex after install and either upgrade or accept the duplicate listing. +**Codex users — minimum supported CLI version is `0.130.0`.** Codex CLI 0.130.0 ([release notes](https://github.com/openai/codex/releases/tag/rust-v0.130.0)) removed extra-skill-roots discovery via [openai/codex#21485](https://github.com/openai/codex/pull/21485); from that version onward Codex discovers skills from standard roots (including `~/.codex/skills//SKILL.md`). GSD installs there directly. Earlier Codex CLI versions may still discover additional roots, which can surface duplicate `gsd-*` entries (one from extra-roots discovery, one from `~/.codex/skills/`); restart Codex after install and either upgrade or accept the duplicate listing. **Something broken?** Re-run the installer — it's idempotent: ```bash diff --git a/tests/bug-3427-3433-codex-install-shape.test.cjs b/tests/bug-3427-3433-codex-install-shape.test.cjs index fbcccf286..e4fd522b8 100644 --- a/tests/bug-3427-3433-codex-install-shape.test.cjs +++ b/tests/bug-3427-3433-codex-install-shape.test.cjs @@ -10,7 +10,7 @@ const crypto = require('node:crypto'); const { execFileSync } = require('node:child_process'); const { install, uninstall, parseTomlToObject } = require('../bin/install.js'); -const { createTempDir, cleanup } = require('./helpers.cjs'); +const { createTempDir, cleanup, parseFrontmatter } = require('./helpers.cjs'); const HOOKS_DIST = path.join(__dirname, '..', 'hooks', 'dist'); const BUILD_HOOKS_SCRIPT = path.join(__dirname, '..', 'scripts', 'build-hooks.js'); @@ -85,7 +85,8 @@ describe('#3427 + #3433 — Codex installer avoids duplicate skills and mixed ho assert.equal(entries.includes('gsd-help'), true); const refreshedBody = fs.readFileSync(path.join(skillsDir, 'gsd-help', 'SKILL.md'), 'utf8'); assert.notEqual(refreshedBody, legacySkillBody, 'stale legacy body must be overwritten'); - assert.ok(refreshedBody.startsWith('---'), 'refreshed SKILL.md must be valid frontmatter shape'); + const frontmatter = parseFrontmatter(refreshedBody); + assert.equal(frontmatter.name, 'gsd-help', 'refreshed SKILL.md frontmatter must declare name: gsd-help'); // Unrelated user skills are preserved — the regen scope is `gsd-*` only. assert.equal(entries.includes('custom-user-skill'), true); diff --git a/tests/bug-3562-codex-install-skill-surface.test.cjs b/tests/bug-3562-codex-install-skill-surface.test.cjs index 2f1f18c58..a0875922c 100644 --- a/tests/bug-3562-codex-install-skill-surface.test.cjs +++ b/tests/bug-3562-codex-install-skill-surface.test.cjs @@ -26,7 +26,7 @@ const path = require('node:path'); const { execFileSync } = require('node:child_process'); const { install } = require('../bin/install.js'); -const { createTempDir, cleanup } = require('./helpers.cjs'); +const { createTempDir, cleanup, parseFrontmatter } = require('./helpers.cjs'); const HOOKS_DIST = path.join(__dirname, '..', 'hooks', 'dist'); const BUILD_HOOKS_SCRIPT = path.join(__dirname, '..', 'scripts', 'build-hooks.js'); @@ -77,16 +77,8 @@ describe('#3562 — Codex install produces discoverable $gsd-* skill surface', { assert.ok(fs.existsSync(skillPath), 'precondition: SKILL.md exists'); const content = fs.readFileSync(skillPath, 'utf8'); - // SKILL.md is YAML frontmatter then body; convertClaudeCommandToCodexSkill - // emits at minimum a `name:` field on the leading frontmatter block. - assert.ok( - content.startsWith('---'), - 'SKILL.md must begin with YAML frontmatter (---) for Codex discovery', - ); - assert.ok( - /^name:\s*["']?gsd-help["']?\s*$/m.test(content), - 'SKILL.md frontmatter must declare name: gsd-help so $gsd-help resolves', - ); + const frontmatter = parseFrontmatter(content); + assert.equal(frontmatter.name, 'gsd-help', 'SKILL.md frontmatter must declare name: gsd-help so $gsd-help resolves'); }); test('multiple core $gsd-* skills are produced (not just gsd-help)', () => {