Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 12 additions & 0 deletions .agents/plugins/marketplace.json
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,18 @@
},
"category": "developer-tools"
},
{
"name": "codex-advisor",
"source": {
"source": "local",
"path": "./plugins/codex-advisor"
},
"policy": {
"installation": "AVAILABLE",
"authentication": "ON_INSTALL"
},
"category": "developer-tools"
},
{
"name": "adhd-output-style",
"source": {
Expand Down
15 changes: 15 additions & 0 deletions .claude-plugin/marketplace.json
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,21 @@
"category": "developer-tools",
"tags": ["review", "agent"]
},
{
"name": "codex-advisor",
"source": "./plugins/codex-advisor",
"description": "Get a second opinion from GPT via Codex CLI before big decisions.",
"version": "1.0.0",
"author": {
"name": "Fatih C. Akyon"
},
"homepage": "https://github.com/fcakyon/claude-codex-settings#plugins",
"repository": "https://github.com/fcakyon/claude-codex-settings",
"license": "Apache-2.0",
"keywords": ["advisor", "second-opinion", "cross-model", "plan-review", "code-review"],
"category": "developer-tools",
"tags": ["review", "agent"]
},
{
"name": "adhd-output-style",
"source": "./plugins/adhd-output-style",
Expand Down
7 changes: 7 additions & 0 deletions .cursor-plugin/marketplace.json
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,13 @@
"version": "1.2.0",
"license": "Apache-2.0"
},
{
"name": "codex-advisor",
"source": "./plugins/codex-advisor",
"description": "Get a second opinion from GPT via Codex CLI before big decisions.",
"version": "1.0.0",
"license": "Apache-2.0"
},
{
"name": "adhd-output-style",
"source": "./plugins/adhd-output-style",
Expand Down
21 changes: 20 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -140,6 +140,25 @@ Ask a Fable 5 reviewer to challenge a plan or conclusion before you commit, a dr

</details>

<details>
<summary><strong>codex-advisor</strong> - Get a second opinion from GPT via Codex CLI before big decisions</summary>

| Claude Code | Codex CLI | Gemini CLI |
| ----------------------------------------------------- | ------------------------------------------------ | ---------------------------------------------------------- |
| `claude plugin install codex-advisor@claude-settings` | `codex plugin add codex-advisor@claude-settings` | `gemini extensions install --path ./plugins/codex-advisor` |

Ask GPT to challenge a plan before you build it, the cross-model check the built-in advisor cannot give you. Claude Code attaches the recent conversation, so "ask the codex advisor" is enough. Codex, Cursor, and Gemini reach the same reviewer. Needs the Codex CLI signed in.

**Agents:**

- [`codex-advisor`](./plugins/codex-advisor/claude-agents/codex-advisor.md) - Sends the recent conversation to GPT and returns the verdict verbatim

**Skills:**

- [`codex-advisor`](./plugins/codex-advisor/skills/codex-advisor/SKILL.md) - Routes Claude Code to its native agent and other tools to `codex exec`

</details>

<details>
<summary><strong>adhd-output-style</strong> - Use fewer output tokens with short steps, quick insights, and clear next actions</summary>

Expand Down Expand Up @@ -908,7 +927,7 @@ Configuration in [`.claude/settings.json`](./.claude/settings.json):
- **Environment**: bash working directory, telemetry disabled, MCP output limits
- **Permissions**: bash commands, git operations, MCP tools
- **Auto mode**: `auto` permission mode with a custom `autoMode` classifier block in [`.claude/settings.json`](./.claude/settings.json) - see the [auto mode config reference](https://code.claude.com/docs/en/auto-mode-config) for what each rule section does, and run `claude auto-mode defaults` to print the current built-in block and allow rules
- **Advisor**: a stronger model reviews key decisions via the [advisor tool](https://code.claude.com/docs/en/advisor), paired as Opus main plus Opus advisor. Fable 5 as advisor currently fails with a bare "unavailable" ([#73365](https://github.com/anthropics/claude-code/issues/73365)), so for an on-demand Fable second opinion use the standalone [`fable-advisor`](./plugins/fable-advisor) plugin
- **Advisor**: a stronger model reviews key decisions via the [advisor tool](https://code.claude.com/docs/en/advisor), paired as Opus main plus Opus advisor. Fable 5 as advisor currently fails with a bare "unavailable" ([#73365](https://github.com/anthropics/claude-code/issues/73365)), so for an on-demand Fable second opinion use the standalone [`fable-advisor`](./plugins/fable-advisor) plugin. The advisor only pairs Claude with Claude, so for a review from outside that family use [`codex-advisor`](./plugins/codex-advisor)
- **Plugins**: All plugins enabled

</details>
Expand Down
11 changes: 11 additions & 0 deletions plugins/codex-advisor/.claude-plugin/plugin.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
{
"name": "codex-advisor",
"version": "1.0.0",
"description": "Get a second opinion from GPT via Codex CLI before big decisions.",
"author": {
"name": "Fatih C. Akyon"
},
"agents": "./claude-agents/codex-advisor.md",
"hooks": "./claude-hooks/hooks.json",
"license": "Apache-2.0"
}
9 changes: 9 additions & 0 deletions plugins/codex-advisor/.codex-plugin/plugin.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
{
"name": "codex-advisor",
"version": "1.0.0",
"description": "Get a second opinion from GPT via Codex CLI before big decisions.",
"author": {
"name": "Fatih C. Akyon"
},
"license": "Apache-2.0"
}
9 changes: 9 additions & 0 deletions plugins/codex-advisor/.cursor-plugin/plugin.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
{
"name": "codex-advisor",
"version": "1.0.0",
"description": "Get a second opinion from GPT via Codex CLI before big decisions.",
"author": {
"name": "Fatih C. Akyon"
},
"license": "Apache-2.0"
}
22 changes: 22 additions & 0 deletions plugins/codex-advisor/claude-agents/codex-advisor.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
---
name: codex-advisor
description: |-
Second-opinion reviewer backed by GPT through the Codex CLI, a cross-model stand-in for the built-in advisor. Consult it before suggesting or implementing a plan, when an error keeps recurring, or before declaring a task done. It receives the recent conversation automatically and returns a verdict without running commands.
model: haiku
color: cyan
tools: [Bash]
---

You are a relay, not the reviewer. GPT reviews through the Codex CLI, and your only job is to carry the request over and hand back the answer untouched.

1. A hook gives you the exact `node ...` command to run, and stages the recent conversation for it. Run that command, passing the caller's question on standard input:

```
node "/path/from/the/hook/ask_codex.mjs" --context "/path/from/the/hook/conversation.md" <<'ASK'
the caller's question, verbatim
ASK
```

2. Return the reviewer's answer verbatim, with nothing added. The review is the deliverable, not your reading of it.

Never answer the question yourself, and never soften or summarize the verdict. If the command fails, report the error and say the review did not happen. A missing or unauthenticated `codex` binary means the user needs to install it or sign in, so say that plainly rather than reviewing in its place.
19 changes: 19 additions & 0 deletions plugins/codex-advisor/claude-hooks/hooks.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
{
"description": "Stages the real conversation for the codex-advisor reviewer instead of only the caller's prompt",
"hooks": {
"SubagentStart": [
{
"matcher": "^(codex-advisor:)?codex-advisor$",
"hooks": [
{
"type": "command",
"command": "node",
"args": [
"${CLAUDE_PLUGIN_ROOT}/claude-hooks/scripts/stage_transcript.mjs"
]
}
]
}
]
}
}
116 changes: 116 additions & 0 deletions plugins/codex-advisor/claude-hooks/scripts/stage_transcript.mjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,116 @@
#!/usr/bin/env node
// SubagentStart hook: stages the recent conversation to a file and hands the codex-advisor
// relay the exact command to run. Staging beats inlining here because the reviewer is a
// separate process, so the relay never has to retype the history.
// Node-only, cross-platform, exits 0 on any failure.

import { mkdtempSync, readFileSync, writeFileSync } from "node:fs";
import { tmpdir } from "node:os";
import { join } from "node:path";
import { fileURLToPath } from "node:url";

const script = fileURLToPath(
new URL("../../skills/codex-advisor/scripts/ask_codex.mjs", import.meta.url),
);
const run = (contextFile) =>
contextFile
? `node "${script}" --context "${contextFile}"`
: `node "${script}"`;

const emit = (contextFile) =>
process.stdout.write(
JSON.stringify({
hookSpecificOutput: {
hookEventName: "SubagentStart",
additionalContext: contextFile
? `The recent conversation has been staged for the reviewer, the same history the built-in advisor tool would see. Send the caller's question to the reviewer on standard input with exactly this command:\n\n${run(contextFile)}`
: `The recent conversation could not be reconstructed, so the reviewer will see only your question. Say so in your reply. Run:\n\n${run()}`,
},
}),
);

const clip = (s, n) => (s.length > n ? s.slice(0, n) + " …[truncated]" : s);

const renderBlock = (role, b) => {
switch (b.type) {
case "text":
return `${role}: ${clip(b.text ?? "", 4000)}`;
case "thinking":
return `assistant (thinking): ${clip(b.thinking ?? "", 1200)}`;
case "tool_use":
return `assistant → ${b.name ?? "?"}(${clip(JSON.stringify(b.input ?? {}), 280)})`;
case "tool_result": {
const c = b.content;
const text =
typeof c === "string"
? c
: Array.isArray(c)
? c.map((x) => x.text ?? "").join(" ")
: JSON.stringify(c ?? "");
return ` ↳ result: ${clip(text, 700)}`;
}
default:
return "";
}
};

// Any failure below leaves contextFile unset, which downgrades the review to the caller's
// prompt instead of losing the turn.
let contextFile;
try {
const lines = readFileSync(
JSON.parse(readFileSync(0, "utf8")).transcript_path,
"utf8",
).split("\n");

// Scan newest-first and stop at 80 records, so a multi-MB transcript never parses the head it would discard.
const records = [];
for (let i = lines.length - 1; i >= 0 && records.length < 80; i--) {
if (!lines[i]) continue;
let r;
try {
r = JSON.parse(lines[i]); // skip a half-written or malformed line
} catch {
continue;
}
if (r.isSidechain === true || r.isMeta === true) continue;
if (r.type !== "user" && r.type !== "assistant") continue;
const content = r.message?.content;
let rendered;
if (typeof content === "string")
rendered = `${r.type}: ${clip(content, 4000)}`;
else if (Array.isArray(content))
rendered = content
.map((b) => renderBlock(r.type, b))
.filter(Boolean)
.join("\n");
else continue;
if (rendered) records.push(rendered);
}
records.reverse();

if (records.length) {
// Keep the newest characters so a very chatty session cannot flood the reviewer.
let recent = records.join("\n\n---\n\n");
const MAX = 160000;
if (recent.length > MAX)
recent = "…[older turns truncated for length]\n" + recent.slice(-MAX);

const staged = join(
mkdtempSync(join(tmpdir(), "codex-advisor-")),
"conversation.md",
);
writeFileSync(
staged,
`You are reviewing an in-progress Claude Code session. Below is the recent conversation, most recent last, the same history the built-in advisor tool would see. Weigh the question against this actual context, not just the caller's summary of it.

<recent-conversation>
${recent}
</recent-conversation>
`,
);
contextFile = staged;
}
} catch {}

emit(contextFile);
5 changes: 5 additions & 0 deletions plugins/codex-advisor/gemini-extension.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
{
"name": "codex-advisor",
"version": "1.0.0",
"description": "Get a second opinion from GPT via Codex CLI before big decisions."
}
36 changes: 36 additions & 0 deletions plugins/codex-advisor/skills/codex-advisor/SKILL.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
---
name: codex-advisor
description: This skill should be used when the user asks for a "GPT second opinion", wants a "cross-model review", needs to "check a plan before committing", wants another view after repeated failures, or explicitly invokes "codex-advisor".
---

# Codex Advisor

Get a focused second opinion from GPT through the Codex CLI, without handing the
work over to it.

## Route by tool

1. In Claude Code, delegate to the native `codex-advisor` agent. It receives the
recent conversation automatically, so do not paste the history yourself.
2. In Codex, Cursor, or Gemini CLI, locate this skill's directory and run
`node scripts/ask_codex.mjs`. Pass the review request on standard input.

The request must include the decision or conclusion, the relevant recent
context and evidence, and any constraints or alternatives that affect the
verdict. Include only facts that matter to the decision.

Return the reviewer's answer without rewriting it. If `codex` is missing or not
authenticated, surface the command error and ask the user to install the Codex
CLI or sign in. Do not fall back to the host model.

## Picking the reviewer

The review runs on whatever model `~/.codex/config.toml` sets. In Codex itself
that is the same model already doing the work, which is a weak second opinion,
so set `CODEX_ADVISOR_MODEL` to a different one before calling.

## Weighing the answer

Give the verdict serious weight. If a step it recommends fails when tried, or a
file contradicts a specific claim, surface the conflict instead of following the
review blindly.
17 changes: 17 additions & 0 deletions plugins/codex-advisor/skills/codex-advisor/reviewer-prompt.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
You are a second opinion, the same role as Claude Code's built-in advisor, consulted at a decision point: a plan about to be committed to, a recurring error, or a task about to be declared done. Another model did the work, not you.

You usually receive the recent conversation in a `<recent-conversation>` block. Treat it as the primary context and the `<question>` block as the specific ask. If the conversation is missing, or a load-bearing detail is absent, say what you need instead of guessing.

Open your reply with one marker line: "context: recent-conversation received" or "context: caller prompt only".

Do not investigate: no commands, tests, shell, file reads, or exploring. Answer from what you were given.

Challenge the plan or conclusion, do not rewrite it. Look for what makes it wrong: unstated assumptions, reasoning gaps, missed edge cases, a cheaper or safer alternative, evidence pointing the other way. You are a different model than the one under review, so say plainly where you would have gone another way.

Return:

- A one-word verdict: proceed, proceed-with-changes, or reconsider.
- The risks or gaps that matter, most important first, each with the failure it causes and the fix.
- If you disagree, cite the exact evidence that breaks the conclusion.

Say nothing about what is already sound. Be concrete, not encouraging.
Loading
Loading