diff --git a/.codex/AGENTS.md b/.codex/AGENTS.md index 0364e354c..70a249ccb 100644 --- a/.codex/AGENTS.md +++ b/.codex/AGENTS.md @@ -2,6 +2,9 @@ This supplements the root `AGENTS.md` with Codex-specific guidance. +For repo navigation, surface ownership, and PR diff packet guidance, read +`docs/CODEX-NAVIGATION-GUIDE.md` after this supplement. + ## Model Recommendations | Task Type | Recommended Model | diff --git a/README.md b/README.md index 10b01a457..160fd7277 100644 --- a/README.md +++ b/README.md @@ -1385,7 +1385,7 @@ alwaysApply: false ## Codex macOS App + CLI Support -ECC provides **first-class Codex support** for both the macOS app and CLI, with a reference configuration, Codex-specific AGENTS.md supplement, and shared skills. +ECC provides **first-class Codex support** for both the macOS app and CLI, with a reference configuration, Codex-specific AGENTS.md supplement, and shared skills. For repo navigation, surface ownership, and PR diff packet guidance, start with [`docs/CODEX-NAVIGATION-GUIDE.md`](docs/CODEX-NAVIGATION-GUIDE.md). ### Quick Start (Codex App + CLI) diff --git a/docs/CODEX-NAVIGATION-GUIDE.md b/docs/CODEX-NAVIGATION-GUIDE.md new file mode 100644 index 000000000..8ff4c294c --- /dev/null +++ b/docs/CODEX-NAVIGATION-GUIDE.md @@ -0,0 +1,167 @@ +# Codex ECC Navigation Map + +This guide helps Codex agents navigate ECC without scanning every surface from +scratch. Use it after the root `AGENTS.md` and `.codex/AGENTS.md` when planning +work, preparing a PR-quality diff, or handing context to a reviewer. + +## Start Here + +Read in this order: + +1. `AGENTS.md` - universal project rules, agent routing, testing expectations, + and commit workflow. +2. `.codex/AGENTS.md` - Codex-specific setup, MCP, skill discovery, and + hook-parity limits. +3. `docs/COMMAND-AGENT-MAP.md` - command to agent and skill routing. +4. This guide - repo navigation, diff packet shape, and PR review lanes for + Codex sessions. + +If those files disagree, prefer the more specific file for the current task: +Codex-specific behavior belongs in `.codex/AGENTS.md`; general contribution +policy belongs in `AGENTS.md` and `CONTRIBUTING.md`. + +## Surface Map + +| Surface | What It Owns | Codex Use | +|---------|---------------|-----------| +| `AGENTS.md` | Cross-harness operating rules | Read before any repo work | +| `.codex/AGENTS.md` | Codex-only guidance | Read after root instructions | +| `.codex/config.toml` | Codex sandbox, MCP, profiles, agent roles | Inspect when setup or MCP behavior matters | +| `.codex/agents/` | Codex multi-agent role layers | Use for explorer, reviewer, and docs researcher roles | +| `.agents/skills/` | Codex-facing skill copies | Use when Codex needs native skill loading | +| `skills/` | Canonical skill source | Update first for new workflow knowledge | +| `agents/` | Claude-style subagent prompts | Use as source material for review lanes and delegation intent | +| `commands/` | Legacy slash-command shims | Update only when command compatibility is needed | +| `docs/COMMAND-AGENT-MAP.md` | Command to agent and skill relationships | Check before renaming or adding workflow surfaces | +| `rules/` | Shared coding, security, and workflow rules | Read language or domain rules before implementation | +| `hooks/` | Claude Code hook workflows | Do not assume Codex hook parity | +| `scripts/` | Install, validation, sync, and CLI utilities | Follow existing Node script patterns | +| `manifests/` | Install component and module registration | Update when adding installable surfaces | +| `.github/PULL_REQUEST_TEMPLATE.md` | Required PR body checklist | Preserve sections when creating PRs | + +## Task Routing + +Use this quick routing before editing: + +| Task | First Files | Likely Verification | +|------|-------------|---------------------| +| Add or update a skill | `skills//`, `.agents/skills//`, `manifests/`, `agent.yaml` | `node scripts/ci/validate-skills.js`, `node tests/ci/codex-skill-surface.test.js` | +| Add or update a command | `commands/`, `docs/COMMAND-AGENT-MAP.md`, `COMMANDS-QUICK-REF.md` | `node scripts/ci/validate-commands.js`, `npm run command-registry:check` | +| Add a Codex setup change | `.codex/`, `scripts/codex/`, `scripts/lib/install-targets/codex-home.js` | `node tests/scripts/codex-hooks.test.js`, `node tests/codex-config.test.js` | +| Add installable content | `manifests/`, `scripts/lib/install-*`, `package.json` | `node scripts/ci/validate-install-manifests.js`, targeted install tests | +| Add docs-only guidance | `docs/`, `README.md`, harness supplement files | Targeted docs test plus `markdownlint` if available | +| Review a PR | `commands/review-pr.md`, `agents/*reviewer.md`, `agents/pr-test-analyzer.md` | Diff review plus relevant tests | + +Keep workflow contributions skills-first. Add or update `commands/` only for +legacy slash-entry compatibility or cross-harness parity. + +## Codex Agent Roles + +ECC ships project-local Codex role layers in `.codex/agents/`: + +| Role | File | Use | +|------|------|-----| +| Explorer | `.codex/agents/explorer.toml` | Read-only evidence gathering before edits | +| Reviewer | `.codex/agents/reviewer.toml` | Correctness, security, and missing-test review | +| Docs researcher | `.codex/agents/docs-researcher.toml` | API, release-note, and docs claim verification | + +Use roles for bounded sidecar work. Do the immediate blocking task locally, and +delegate independent evidence or review tasks when they can run in parallel. + +## PR Diff Packet + +Before `/pr`, prepare a local diff packet. This gives reviewers the context +that many PR tools otherwise have to reconstruct. + +Run: + +```bash +git fetch origin +git diff origin/main...HEAD --stat +git diff origin/main...HEAD --name-only +git log origin/main..HEAD --oneline --reverse +``` + +Then capture: + +```markdown +## PR Diff Packet + +### Intent + + +### Diff Map +- Added: +- Modified: +- Unchanged but relevant: + +### Risk and review lanes +- Behavior: +- Security: +- Tests: +- Docs: +- Release/install surface: + +### Testing Done +- + +### Follow-ups +- +``` + +Use `.github/PULL_REQUEST_TEMPLATE.md` as the final PR body structure. The diff +packet feeds that template; it does not replace it. + +## PR Commands + +| Need | Command Surface | Notes | +|------|-----------------|-------| +| Create a PR | `/pr` | Discovers PR template, analyzes commits and files, pushes, and creates a PR | +| Create a PR from PRP workflow | `/prp-pr` | Same core flow with PRP artifact references | +| Review a PR | `/review-pr` | Runs multi-perspective review lanes and aggregates findings | +| Review current changes before PR | `/code-review` | Use before committing when no GitHub PR exists yet | + +Codex may not execute slash commands natively in every environment. When a +slash command is not available, read the command file and perform the same +steps manually. + +## Review Lanes + +For a PR-quality diff, check these lanes before asking for review: + +| Lane | Evidence | +|------|----------| +| Scope | `git diff origin/main...HEAD --name-only` matches the stated intent | +| Tests | New behavior has a targeted test or a clear no-test rationale | +| Security | No secrets, unsafe external writes, broad permissions, or input trust gaps | +| Install surface | New skills, commands, agents, hooks, scripts, or files are registered where required | +| Cross-harness | Codex, OpenCode, Cursor, Claude Code, and docs surfaces are updated only when applicable | +| Docs | README and focused docs link to the new source of truth | + +For code changes, invoke the relevant reviewer lane after implementation. For +docs-only changes, run the targeted docs test and review links for drift. + +## Common Navigation Pitfalls + +- Do not treat `commands/` as the canonical place for new workflow knowledge. + Prefer `skills/` first. +- Do not copy Claude hook claims into Codex docs. Codex enforcement is based on + instructions, sandbox settings, and optional MCP config. +- Do not update `.agents/skills/` without checking the canonical `skills/` + source and Codex `agents/openai.yaml` metadata expectations. +- Do not open broad PRs that mix unrelated skill, command, install, and release + changes unless the user explicitly wants a release bundle. +- Do not leave a Codex docs change discoverable only through README prose. Link + it from `.codex/AGENTS.md` when it affects Codex behavior. + +## Fast Commands + +Useful local checks: + +```bash +node tests/docs/codex-navigation-map.test.js +node tests/ci/codex-skill-surface.test.js +npm run command-registry:check +npm run catalog:check +node tests/run-all.js +``` diff --git a/package.json b/package.json index ae74ebee2..3b056e3b3 100644 --- a/package.json +++ b/package.json @@ -46,6 +46,7 @@ ".codex-plugin/", ".cursor/", ".gemini/", + ".github/PULL_REQUEST_TEMPLATE.md", ".hermes/", ".kimi/", ".opencode/", @@ -54,6 +55,8 @@ ".zed/", ".mcp.json", "AGENTS.md", + "COMMANDS-QUICK-REF.md", + "CONTRIBUTING.md", "VERSION", "agent.yaml", "assets/ecc-icon.svg", @@ -62,6 +65,8 @@ "agents/", "commands/", "docs/de-DE/", + "docs/CODEX-NAVIGATION-GUIDE.md", + "docs/COMMAND-AGENT-MAP.md", "docs/ja-JP/", "docs/ko-KR/", "docs/pt-BR/", @@ -118,6 +123,7 @@ "scripts/setup-package-manager.js", "scripts/skill-create-output.js", "scripts/status.js", + "scripts/sync-ecc-to-codex.sh", "scripts/work-items.js", "scripts/uninstall.js", "skills/agent-architecture-audit/", diff --git a/scripts/sync-ecc-to-codex.sh b/scripts/sync-ecc-to-codex.sh index 8742f539e..43ca4fa53 100755 --- a/scripts/sync-ecc-to-codex.sh +++ b/scripts/sync-ecc-to-codex.sh @@ -29,6 +29,16 @@ AGENTS_ROOT_SRC="$REPO_ROOT/AGENTS.md" AGENTS_CODEX_SUPP_SRC="$REPO_ROOT/.codex/AGENTS.md" CODEX_AGENTS_SRC="$REPO_ROOT/.codex/agents" CODEX_AGENTS_DEST="$CODEX_HOME/agents" +CODEX_NAV_GUIDE_SRC="$REPO_ROOT/docs/CODEX-NAVIGATION-GUIDE.md" +CODEX_NAV_GUIDE_DEST="$CODEX_HOME/docs/CODEX-NAVIGATION-GUIDE.md" +CODEX_COMMAND_AGENT_MAP_SRC="$REPO_ROOT/docs/COMMAND-AGENT-MAP.md" +CODEX_COMMAND_AGENT_MAP_DEST="$CODEX_HOME/docs/COMMAND-AGENT-MAP.md" +CODEX_COMMANDS_QUICK_REF_SRC="$REPO_ROOT/COMMANDS-QUICK-REF.md" +CODEX_COMMANDS_QUICK_REF_DEST="$CODEX_HOME/COMMANDS-QUICK-REF.md" +CODEX_CONTRIBUTING_SRC="$REPO_ROOT/CONTRIBUTING.md" +CODEX_CONTRIBUTING_DEST="$CODEX_HOME/CONTRIBUTING.md" +CODEX_PR_TEMPLATE_SRC="$REPO_ROOT/.github/PULL_REQUEST_TEMPLATE.md" +CODEX_PR_TEMPLATE_DEST="$CODEX_HOME/.github/PULL_REQUEST_TEMPLATE.md" PROMPTS_SRC="$REPO_ROOT/commands" PROMPTS_DEST="$CODEX_HOME/prompts" BASELINE_MERGE_SCRIPT="$REPO_ROOT/scripts/codex/merge-codex-config.js" @@ -150,6 +160,11 @@ MCP_MERGE_SCRIPT="$REPO_ROOT/scripts/codex/merge-mcp-config.js" require_path "$REPO_ROOT/AGENTS.md" "ECC AGENTS.md" require_path "$AGENTS_CODEX_SUPP_SRC" "ECC Codex AGENTS supplement" require_path "$CODEX_AGENTS_SRC" "ECC Codex agent roles" +require_path "$CODEX_NAV_GUIDE_SRC" "ECC Codex navigation guide" +require_path "$CODEX_COMMAND_AGENT_MAP_SRC" "ECC command-agent map" +require_path "$CODEX_COMMANDS_QUICK_REF_SRC" "ECC commands quick reference" +require_path "$CODEX_CONTRIBUTING_SRC" "ECC contributing guide" +require_path "$CODEX_PR_TEMPLATE_SRC" "ECC PR template" require_path "$PROMPTS_SRC" "ECC commands directory" require_path "$BASELINE_MERGE_SCRIPT" "ECC Codex baseline merge script" require_path "$HOOKS_INSTALLER" "ECC global git hooks installer" @@ -259,6 +274,15 @@ else node "$BASELINE_MERGE_SCRIPT" "$CONFIG_FILE" fi +log "Syncing Codex navigation guide" +run_or_echo mkdir -p "$(dirname "$CODEX_NAV_GUIDE_DEST")" +run_or_echo cp "$CODEX_NAV_GUIDE_SRC" "$CODEX_NAV_GUIDE_DEST" +run_or_echo cp "$CODEX_COMMAND_AGENT_MAP_SRC" "$CODEX_COMMAND_AGENT_MAP_DEST" +run_or_echo cp "$CODEX_COMMANDS_QUICK_REF_SRC" "$CODEX_COMMANDS_QUICK_REF_DEST" +run_or_echo cp "$CODEX_CONTRIBUTING_SRC" "$CODEX_CONTRIBUTING_DEST" +run_or_echo mkdir -p "$(dirname "$CODEX_PR_TEMPLATE_DEST")" +run_or_echo cp "$CODEX_PR_TEMPLATE_SRC" "$CODEX_PR_TEMPLATE_DEST" + log "Syncing sample Codex agent role files" run_or_echo mkdir -p "$CODEX_AGENTS_DEST" for agent_file in "$CODEX_AGENTS_SRC"/*.toml; do diff --git a/tests/docs/codex-navigation-map.test.js b/tests/docs/codex-navigation-map.test.js new file mode 100644 index 000000000..9497c8070 --- /dev/null +++ b/tests/docs/codex-navigation-map.test.js @@ -0,0 +1,80 @@ +'use strict'; + +const assert = require('assert'); +const fs = require('fs'); +const path = require('path'); + +const repoRoot = path.resolve(__dirname, '..', '..'); +const guidePath = 'docs/CODEX-NAVIGATION-GUIDE.md'; + +let passed = 0; +let failed = 0; + +function test(name, fn) { + try { + fn(); + console.log(` ✓ ${name}`); + passed++; + } catch (error) { + console.log(` ✗ ${name}`); + console.log(` Error: ${error.message}`); + failed++; + } +} + +function read(relativePath) { + return fs.readFileSync(path.join(repoRoot, relativePath), 'utf8'); +} + +console.log('\n=== Testing Codex ECC navigation map docs ===\n'); + +test('Codex navigation map exists and identifies canonical surfaces', () => { + const source = read(guidePath); + + for (const required of [ + 'AGENTS.md', + '.codex/AGENTS.md', + '.codex/config.toml', + '.codex/agents/', + '.agents/skills/', + 'docs/COMMAND-AGENT-MAP.md', + 'commands/', + 'skills/', + 'agents/', + 'rules/', + 'hooks/', + 'scripts/', + 'manifests/' + ]) { + assert.ok(source.includes(required), `Missing canonical surface ${required}`); + } +}); + +test('Codex navigation map documents PR diff packet workflow', () => { + const source = read(guidePath); + + for (const required of [ + 'PR Diff Packet', + 'git diff origin/main...HEAD --stat', + 'git diff origin/main...HEAD --name-only', + 'git log origin/main..HEAD --oneline --reverse', + '/pr', + '/review-pr', + '.github/PULL_REQUEST_TEMPLATE.md', + 'Testing Done', + 'Risk and review lanes' + ]) { + assert.ok(source.includes(required), `Missing PR workflow marker ${required}`); + } +}); + +test('README and Codex supplement link to the navigation map', () => { + const readme = read('README.md'); + const codexAgents = read('.codex/AGENTS.md'); + + assert.ok(readme.includes(guidePath), 'README.md must link the Codex navigation map'); + assert.ok(codexAgents.includes(guidePath), '.codex/AGENTS.md must link the Codex navigation map'); +}); + +console.log(`\nResults: Passed: ${passed}, Failed: ${failed}`); +process.exit(failed > 0 ? 1 : 0); diff --git a/tests/scripts/npm-publish-surface.test.js b/tests/scripts/npm-publish-surface.test.js index 7aa17ae62..cb556c446 100644 --- a/tests/scripts/npm-publish-surface.test.js +++ b/tests/scripts/npm-publish-surface.test.js @@ -70,6 +70,7 @@ function buildExpectedPublishPaths(repoRoot) { "scripts/session-inspect.js", "scripts/uninstall.js", "scripts/gemini-adapt-agents.js", + "scripts/sync-ecc-to-codex.sh", "scripts/codex/check-plugin-cache.js", "scripts/codex/merge-codex-config.js", "scripts/codex/merge-mcp-config.js", @@ -80,9 +81,14 @@ function buildExpectedPublishPaths(repoRoot) { "install.ps1", "schemas", "agent.yaml", + ".github/PULL_REQUEST_TEMPLATE.md", + "COMMANDS-QUICK-REF.md", + "CONTRIBUTING.md", "VERSION", "assets/ecc-icon.svg", "assets/hero.png", + "docs/CODEX-NAVIGATION-GUIDE.md", + "docs/COMMAND-AGENT-MAP.md", "assets/images/sponsors", ] const exclusionPaths = [ @@ -144,14 +150,20 @@ function main() { "scripts/release-video-suite.js", "scripts/work-items.js", "scripts/platform-audit.js", + "scripts/sync-ecc-to-codex.sh", "scripts/codex/check-plugin-cache.js", ".gemini/GEMINI.md", ".qwen/QWEN.md", ".claude-plugin/plugin.json", + ".github/PULL_REQUEST_TEMPLATE.md", ".codex-plugin/plugin.json", + "COMMANDS-QUICK-REF.md", + "CONTRIBUTING.md", "plugins/ecc/.codex-plugin/plugin.json", "assets/ecc-icon.svg", "assets/hero.png", + "docs/CODEX-NAVIGATION-GUIDE.md", + "docs/COMMAND-AGENT-MAP.md", "schemas/install-state.schema.json", "skills/backend-patterns/SKILL.md", ]) { diff --git a/tests/scripts/sync-ecc-to-codex.test.js b/tests/scripts/sync-ecc-to-codex.test.js index 2626c13c3..61a5b128e 100644 --- a/tests/scripts/sync-ecc-to-codex.test.js +++ b/tests/scripts/sync-ecc-to-codex.test.js @@ -69,11 +69,32 @@ function runTests() { if (test('filesystem-changing calls use argv-form run_or_echo invocations', () => { assert.ok(source.includes('run_or_echo mkdir -p "$BACKUP_DIR"'), 'mkdir should use argv form'); + assert.ok(source.includes('run_or_echo mkdir -p "$(dirname "$CODEX_NAV_GUIDE_DEST")"'), 'Codex guide destination directory should use argv form'); + assert.ok(source.includes('run_or_echo cp "$CODEX_NAV_GUIDE_SRC" "$CODEX_NAV_GUIDE_DEST"'), 'Codex guide copy should use argv form'); + assert.ok(source.includes('run_or_echo cp "$CODEX_COMMAND_AGENT_MAP_SRC" "$CODEX_COMMAND_AGENT_MAP_DEST"'), 'Command-agent map copy should use argv form'); + assert.ok(source.includes('run_or_echo cp "$CODEX_COMMANDS_QUICK_REF_SRC" "$CODEX_COMMANDS_QUICK_REF_DEST"'), 'Commands quick reference copy should use argv form'); + assert.ok(source.includes('run_or_echo cp "$CODEX_CONTRIBUTING_SRC" "$CODEX_CONTRIBUTING_DEST"'), 'Contributing guide copy should use argv form'); + assert.ok(source.includes('run_or_echo mkdir -p "$(dirname "$CODEX_PR_TEMPLATE_DEST")"'), 'PR template destination directory should use argv form'); + assert.ok(source.includes('run_or_echo cp "$CODEX_PR_TEMPLATE_SRC" "$CODEX_PR_TEMPLATE_DEST"'), 'PR template copy should use argv form'); // Skills sync rm/cp calls were removed — Codex reads from ~/.agents/skills/ natively assert.ok(!source.includes('run_or_echo rm -rf "$dest"'), 'skill sync rm should be removed'); assert.ok(!source.includes('run_or_echo cp -R "$skill_dir" "$dest"'), 'skill sync cp should be removed'); })) passed++; else failed++; + if (test('sync script carries the Codex navigation guide referenced by AGENTS', () => { + assert.ok(source.includes('CODEX_NAV_GUIDE_SRC="$REPO_ROOT/docs/CODEX-NAVIGATION-GUIDE.md"'), 'Expected source path for Codex navigation guide'); + assert.ok(source.includes('CODEX_NAV_GUIDE_DEST="$CODEX_HOME/docs/CODEX-NAVIGATION-GUIDE.md"'), 'Expected destination path for Codex navigation guide'); + assert.ok(source.includes('require_path "$CODEX_NAV_GUIDE_SRC" "ECC Codex navigation guide"'), 'Expected sync preflight for Codex navigation guide'); + for (const required of [ + 'CODEX_COMMAND_AGENT_MAP_SRC="$REPO_ROOT/docs/COMMAND-AGENT-MAP.md"', + 'CODEX_COMMANDS_QUICK_REF_SRC="$REPO_ROOT/COMMANDS-QUICK-REF.md"', + 'CODEX_CONTRIBUTING_SRC="$REPO_ROOT/CONTRIBUTING.md"', + 'CODEX_PR_TEMPLATE_SRC="$REPO_ROOT/.github/PULL_REQUEST_TEMPLATE.md"' + ]) { + assert.ok(source.includes(required), `Expected synced reference source ${required}`); + } + })) passed++; else failed++; + if (test('sync script avoids GNU-only grep -P parsing', () => { assert.ok(!source.includes('grep -oP'), 'sync-ecc-to-codex.sh should remain portable across BSD and GNU environments'); })) passed++; else failed++;