diff --git a/.agents/skills/local-review-codex/SKILL.md b/.agents/skills/local-review-codex/SKILL.md new file mode 100644 index 0000000000..cc932f7a4b --- /dev/null +++ b/.agents/skills/local-review-codex/SKILL.md @@ -0,0 +1,50 @@ +--- +name: local-review-codex +description: Run the CI Codex PR review locally against this branch's unpushed work (committed + uncommitted) before pushing. Same policy, model, and reasoning effort as the codex-pr-review GitHub action. +--- + +# Local Codex Review (pre-push) + +Runs the exact same review Codex performs in CI (`.github/workflows/codex-pr-review.yml`), +but locally and scoped to work you have not pushed yet — so you catch what CI would flag +before the PR exists. Use this before `git push` on a non-trivial change. + +**Correspondence with CI** — identical: +- Policy: `REVIEW.md` (severity triage, public-surface checklist, AGENTS.md compliance, test coverage). +- Model: `gpt-5.6-sol`, `model_reasoning_effort="xhigh"`. +- Output: markdown starting with `## Codex Review`, findings tagged P0 / P1 / P2 with file:line. + +**Differences from CI** — local-only: +- Scope is the current branch vs `main` at the merge-base, **including uncommitted changes** (CI reviews a pushed PR diff). +- Sandbox is `read-only` (CI uses `danger-full-access` on an ephemeral runner). Codex reads the diff and files but cannot modify your working tree. +- Fresh context is inherent: `codex exec` is a separate cold process, so it does not anchor on the current chat session — the same reason `local-review` insists on a subagent. + +## Prerequisites + +- `codex` CLI **>= 0.144.1** installed and authed (`codex login` or `OPENAI_API_KEY`). Older CLIs reject `gpt-5.6-sol` with "requires a newer version of Codex". Upgrade with `npm install --global @openai/codex@0.144.1` (may need `sudo` for a global install). Keep this in sync with the pin in `.github/workflows/codex-pr-review.yml`. +- `git fetch` the base ref if it's stale, so the merge-base is accurate. + +## Run + +```bash +bash .agents/skills/local-review-codex/run.sh # review vs main (default) +bash .agents/skills/local-review-codex/run.sh # review vs a different base ref +``` + +Invoke with `bash` (or run the executable directly) — the script needs Bash for +`set -o pipefail`; `sh` is Dash on Debian/Ubuntu and would fail. If `main` isn't a +local branch (e.g. a fresh single-branch checkout), the runner falls back to +`origin/main` automatically. + +The script computes `BASE_SHA = git merge-base HEAD `, feeds Codex `REVIEW.md` plus a +diff context pointing at `git diff ` (which folds in uncommitted edits), and prints +the review. It writes only temp files — nothing lands in the working tree. + +## Relaying the result + +Print the Codex output verbatim. Do not re-summarize or filter it — the value of a cold Codex +pass is surfacing what the current session would rationalize away. Then decide with the user +whether to address findings before pushing. + +For a Claude-native review instead, use `local-review` (branch-diff-reviewer subagent). This +skill is the Codex counterpart; run both for independent perspectives. diff --git a/.agents/skills/local-review-codex/run.sh b/.agents/skills/local-review-codex/run.sh new file mode 100755 index 0000000000..d6491099c2 --- /dev/null +++ b/.agents/skills/local-review-codex/run.sh @@ -0,0 +1,91 @@ +#!/usr/bin/env bash +# Local Codex review — mirrors the .github/workflows/codex-pr-review.yml CI job, +# but scoped to this branch's unpushed work (committed + uncommitted) so you can +# review before pushing. Same policy (REVIEW.md), same model (gpt-5.6-sol) and +# reasoning effort (xhigh) as CI. Runs read-only: Codex cannot modify your tree. +# +# Usage: run.sh [BASE_REF] (BASE_REF defaults to "main") +set -euo pipefail + +BASE_REF="${1:-main}" +REPO_ROOT="$(git rev-parse --show-toplevel)" +cd "$REPO_ROOT" + +if ! command -v codex >/dev/null 2>&1; then + echo "codex CLI not found. Install with: npm install --global @openai/codex@0.144.1" >&2 + exit 1 +fi + +# Resolve the base to a concrete commit, preferring a local ref but falling back to +# the remote-tracking ref — checkouts (CI, single-branch clones) often have only +# origin/main, not a local main. +if git rev-parse --verify --quiet "${BASE_REF}^{commit}" >/dev/null; then + BASE_COMMITISH="$BASE_REF" +elif git rev-parse --verify --quiet "origin/${BASE_REF}^{commit}" >/dev/null; then + BASE_COMMITISH="origin/${BASE_REF}" +else + echo "Base ref '$BASE_REF' not found as '$BASE_REF' or 'origin/$BASE_REF'. Try: git fetch origin $BASE_REF" >&2 + exit 1 +fi + +# Diff from the merge-base so only this branch's changes are reviewed. Using the +# base SHA with a single-ref `git diff` also folds in uncommitted working-tree edits, +# but `git diff` never sees untracked files — those are gathered separately below so +# brand-new files (a whole new module, a new skill dir) are not silently skipped. +BASE_SHA="$(git merge-base HEAD "$BASE_COMMITISH")" +HEAD_SHA="$(git rev-parse HEAD)" +UNTRACKED="$(git ls-files --others --exclude-standard)" + +if [ "$BASE_SHA" = "$HEAD_SHA" ] && git diff --quiet "$BASE_SHA" && [ -z "$UNTRACKED" ]; then + echo "No changes vs $BASE_REF — nothing to review." >&2 + exit 0 +fi + +PROMPT="$(mktemp)" +OUT="$(mktemp)" +trap 'rm -f "$PROMPT" "$OUT"' EXIT + +# REVIEW.md is the shared policy CI feeds Codex. Append the local output-format +# and diff context inline (CI reads these from a generated context file; inlining +# keeps the working tree clean — no scratch files land in the repo). +cat REVIEW.md > "$PROMPT" +cat >> "$PROMPT" < /tmp/codex-prompt.md codex exec \ -C "$GITHUB_WORKSPACE" \ - -m gpt-5.5 \ + -m gpt-5.6-sol \ -c 'model_reasoning_effort="xhigh"' \ -s danger-full-access \ -o codex-final-message.md \ diff --git a/AGENTS.md b/AGENTS.md index 83b68f7d36..fa7889c4c2 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -16,7 +16,7 @@ Open-source platform for internal tools, workflows, API integrations, background - **Backend patterns**: use the `rust-backend` skill when writing Rust code - **Frontend patterns**: use the `svelte-frontend` skill when writing Svelte code. Do NOT edit svelte files unless you have read that skill. - **Frontend UUIDs**: do not call `crypto.randomUUID()` in frontend code. Import `randomUUID` from `$lib/utils/uuid` instead. -- **Code review**: review the current PR or branch against the shared review policy in `REVIEW.md` (severity triage, public-surface checklist, AGENTS.md compliance, test-coverage assessment). The skill at `.agents/skills/local-review/SKILL.md` orchestrates it. All three CLIs auto-discover the same SKILL — Claude reads `.claude/skills/` (symlinked to the canonical `.agents/skills/` file), Codex and Pi read `.agents/skills/` directly. Invoke with `/local-review` in Claude Code, `$local-review` (or `/skills` selector) in Codex, or `pi --skill local-review` / `/skill:local-review` in Pi. +- **Code review**: review the current PR or branch against the shared review policy in `REVIEW.md` (severity triage, public-surface checklist, AGENTS.md compliance, test-coverage assessment). The skill at `.agents/skills/local-review/SKILL.md` orchestrates it. All three CLIs auto-discover the same SKILL — Claude reads `.claude/skills/` (symlinked to the canonical `.agents/skills/` file), Codex and Pi read `.agents/skills/` directly. Invoke with `/local-review` in Claude Code, `$local-review` (or `/skills` selector) in Codex, or `pi --skill local-review` / `/skill:local-review` in Pi. For a Codex-driven pass that mirrors the `codex-pr-review` GitHub action against your unpushed work (committed + uncommitted) before you push, use `/local-review-codex` (`.agents/skills/local-review-codex/`) — same `REVIEW.md` policy, `gpt-5.6-sol`, `xhigh` reasoning; requires the `codex` CLI >= 0.144.1. - **Domain guides**: `.claude/skills/native-trigger/` and `frontend/tutorial-system-guide.mdc` - **Brand/UI guidelines**: `frontend/brand-guidelines.md` - **CLI commands**: when adding/modifying/removing a command, subcommand, option, or description in `cli/src/commands/`, run `python system_prompts/generate.py` to refresh `system_prompts/auto-generated/` and `cli/src/guidance/skills.gen.ts`. The CLI docs the agents use to operate `wmill` are derived from the source — stale generated files give agents the wrong flags.