feat(adapters): codex T3 — skills mirroring the vouch slash commands#394
Conversation
|
Important Review skippedAuto reviews are disabled on base/target branches other than the default branch. Please check the settings in the CodeRabbit UI or the ⚙️ Run configurationConfiguration used: defaults Review profile: CHILL Plan: Pro Plus Run ID: You can disable this status message by setting the Use the checkbox below for a quick retry:
✨ Finishing Touches🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
Pull request overview
Adds Codex Tier-3 support so Codex users get the same guided vouch workflows that Claude Code already has, using project-local Codex skills to preserve the “no home-directory writes” invariant. The PR also expands the adapter installer to support Codex-specific integration needs (fenced snippet refresh + TOML deep-merge) and adds tests that lock these surfaces in sync.
Changes:
- Add Codex T3 project-local skills under
.codex/skills/, reusing the existing OpenClaw skill bodies and sync-testing them against Claude Code commands. - Extend
install_adapterwithtoml_mergesupport (for.codex/config.toml) and refresh-in-place behavior for fenced snippets. - Add Codex adapter docs + AGENTS snippet and broaden installer tests to cover T2/T3/TOML merge invariants.
Reviewed changes
Copilot reviewed 5 out of 5 changed files in this pull request and generated 3 comments.
Show a summary per file
| File | Description |
|---|---|
src/vouch/install_adapter.py |
Adds toml_merge install strategy and refresh-in-place fenced snippet behavior. |
tests/test_install_adapter.py |
Adds coverage for Codex T2/T3 installs, scope checks, idempotency, and body sync. |
adapters/codex/install.yaml |
Declares Codex tiers: T1 toml-merge config, T2 fenced AGENTS snippet, T3 skills installation. |
adapters/codex/README.md |
Documents Codex T3 skills behavior and rationale vs global prompts. |
adapters/codex/AGENTS.md.snippet |
Adds Codex-specific AGENTS snippet (kept in lockstep with Cursor). |
| fenced = bool(raw.get("fenced_append", False)) | ||
| json_merge = bool(raw.get("json_merge", False)) | ||
| toml_merge = bool(raw.get("toml_merge", False)) | ||
| parsed_entries.append( | ||
| _FileEntry(src=src, dst=dst, fenced_append=fenced, json_merge=json_merge) | ||
| _FileEntry( | ||
| src=src, dst=dst, fenced_append=fenced, | ||
| json_merge=json_merge, toml_merge=toml_merge, | ||
| ) |
| ## Skills (T3) | ||
|
|
||
| `vouch install-mcp codex --tier T3` also drops the vouch guided flows | ||
| (`vouch-recall`, `vouch-status`, `vouch-resolve-issue`, | ||
| `vouch-propose-from-pr`, plus the company-brain set) into the | ||
| project-local `.codex/skills/` directory. Codex discovers skills from | ||
| `<project>/.codex/skills/` in trusted projects, so they surface in the | ||
| session automatically — ask for a skill by name (e.g. "use the | ||
| vouch-recall skill for X") or let codex pick them up from context. |
| for name in _CODEX_SKILL_NAMES: | ||
| text = (tmp_path / ".codex" / "skills" / name / "SKILL.md").read_text( | ||
| encoding="utf-8" | ||
| ) | ||
| assert f"name: {name}" in text.split("---", 2)[1], name | ||
|
|
vouchdev#361 inserted `_log = logging.getLogger(...)` between two import groups in jsonl_server.py. that statement-among-imports trips ruff's E402 on every import that follows it, so `ruff check src tests` — the lint gate in ci — now fails on the whole repo. move the logger definition below the imports (where storage.py already keeps its own module logger); no behaviour change.
.codex/config.toml is codex's primary config file, so the plain-copy path silently skipped any project where codex was already configured and vouch never got wired. add a toml_merge entry flag mirroring json_merge: parse the existing destination with tomllib, deep-merge the template's tables into it (existing user values always win on conflict), and write back. flip the codex T1 entry to toml_merge. writing uses a minimal hand-rolled serializer (tables, arrays, inline tables in arrays, scalars, datetimes) so the dependency set stays unchanged; the output must survive a tomllib round-trip back to the merged data, and anything the serializer can't faithfully re-emit degrades to skipped rather than risking the user's config. closes vouchdev#384
codex reads AGENTS.md for project instructions the way cursor does, but the codex adapter stopped at T1, so a codex session got the kb tools with no standing guidance on recall-first or the review gate. ship adapters/codex/AGENTS.md.snippet as a T2 tier with the standard fence markers, kept in lockstep with cursor's snippet modulo the host name (enforced by a sync test). also close the edited-fence gap in _install_fenced per the ticket's acceptance criteria: a fence body that drifted from the shipped snippet is replaced within the markers (reported as merged) instead of being skipped forever, while user content outside the fence stays untouched. a begin marker without an end marker is treated as corrupt and left alone. closes vouchdev#385
claude-code T3 ships nine slash commands; codex users got none of the guided flows. ship them as codex skills under the project-local .codex/skills/ as a T3 tier. scope decision the ticket asked to resolve first: codex loads custom prompts only from ~/.codex/prompts/ (user-global) and has deprecated them upstream in favour of skills, which do have a project-local home at <project>/.codex/skills/ in trusted projects. the vouchdev#179 rule forbids a project-scoped install from touching home-directory state, so prompts are out and skills are in — recorded in the manifest comment and the adapter readme, with a manual-copy pointer for users who still want ~/.codex/prompts. the SKILL.md files are referenced from the openclaw mirror rather than duplicated (same reuse pattern openclaw itself applies to the claude-code commands), so one edit updates every host. a parametrized sync test asserts each installed codex skill body equals the matching claude-code command body, and a scope test asserts every installed path stays under the project target. closes vouchdev#386
91bd494 to
109a3a3
Compare
|
addressed the copilot review on both points: the skill-name test now matches the whole |
claude-code T3 ships nine slash commands (the four core flows plus the company-brain set); codex users got none of them, so the guided flows were claude-code-only. this ships them to codex as a T3 tier.
the scope decision the ticket asked to resolve first: checked against the current codex cli — custom prompts load only from
~/.codex/prompts/(user-global, no project-local location was ever added) and are deprecated upstream in favour of skills. skills do have a project-local home at<project>/.codex/skills/in trusted projects. since the #179 rule forbids a project-scoped install from touching home-directory state, prompts are out and project-local skills are in. the choice is recorded in the manifest comment as the ticket requested, and the adapter readme documents how the surface appears inside codex plus a manual-copy pointer for anyone who still wants~/.codex/prompts/.the SKILL.md files are referenced in place from the openclaw mirror rather than duplicated — the same reuse pattern openclaw's own manifest applies to the claude-code commands — so there is exactly one copy of each skill body in the repo and one edit updates every host. openclaw's existing sync test already pins those bodies to the claude-code commands; a new parametrized test asserts each installed codex skill body equals the matching claude-code command body, closing the loop from the codex side.
tests also cover: all nine skills land at T3, frontmatter names match their directory names (codex resolves skills by name), idempotent re-run, and a #179 scope check that every installed path stays under the project target. verified end-to-end with
vouch install-mcp codex --tier T3into a temp project — 11 files written (config + snippet + 9 skills), all under the target.stacks on #392 and #393 (shared
adapters/codex/install.yaml) — merge after them; the diff reduces to the T3 change once they land.closes #386