# How the Codex Plugin Determines Review Target: Working Tree vs Branch

> Discover how the Codex plugin determines review targets. Learn its logic for choosing between working tree changes or branch diffs based on flags and repo state.

- Repository: [OpenAI/codex-plugin-cc](https://github.com/openai/codex-plugin-cc)
- Tags: internals
- Published: 2026-08-01

---

**The Codex plugin uses the `resolveReviewTarget` function in `plugins/codex/scripts/lib/git.mjs` to decide whether to review uncommitted working-tree changes or a branch diff, based on explicit flags (`--base`, `--scope`) and automatic detection of repository state.**

Reviewing code with the OpenAI Codex companion plugin requires knowing exactly what changes you're targeting. The plugin intelligently switches between two modes: examining your **working tree** (unstaged, staged, and untracked changes) or comparing your current branch against a **base reference** (branch diff). This article explains the precise decision logic implemented in the `openai/codex-plugin-cc` source code.

## The Core Decision Logic in `resolveReviewTarget`

The `resolveReviewTarget` function (lines 35-91 in `plugins/codex/scripts/lib/git.mjs`) implements a five-step priority flow. The plugin evaluates conditions in strict order and returns immediately when a match is found.

### Priority Order for Target Selection

1. **Explicit `--base` flag** — Branch mode with supplied reference
2. **Explicit `--scope working-tree`** — Working-tree mode forced
3. **Explicit `--scope branch`** — Branch mode with auto-detected default branch
4. **`--scope auto` + dirty working tree** — Working-tree mode (default behavior)
5. **`--scope auto` + clean working tree** — Branch mode with auto-detected default branch

Each step corresponds to specific source code blocks that set the `mode`, `label`, `baseRef` (when applicable), and `explicit` boolean on the returned target object.

### The Resolved Target Object Structure

When `resolveReviewTarget` completes, it returns a JavaScript object with this shape:

```javascript
{
  mode: "working-tree" | "branch",
  label: "...",          // Human-readable description for CLI output
  baseRef?: string,      // Present only in branch mode
  explicit: boolean      // true if user forced via flag
}

```

This object feeds directly into `executeReviewRun` in `plugins/codex/scripts/codex-companion.mjs` (lines 58-78), which routes to either `buildNativeReviewTarget` or adversarial review prompt construction.

## How the Plugin Detects Working Tree State

Before making automatic decisions, the plugin must determine if your repository has **uncommitted changes**. This happens via `getWorkingTreeState` (lines 22-33 in `git.mjs`).

The function executes Git commands to check for:

- **Staged files** (`git diff --cached --quiet`)
- **Unstaged files** (`git diff --quiet`)
- **Untracked files** (`git ls-files --others --exclude-standard`)

If any check fails (returns non-zero), `state.isDirty` becomes `true`, triggering the working-tree path in auto mode.

## Explicit Flags That Override Detection

### The `--base` Flag (Highest Priority)

When you provide a specific reference, the plugin bypasses all other logic:

```bash
codex review --base develop

```

Code path: `if (options.base)` → returns branch target with `baseRef: "develop"` (lines 43-49).

### The `--scope` Flag (Explicit Mode Selection)

| Flag Value | Behavior |
|------------|----------|
| `--scope working-tree` | Forces working-tree review regardless of repo state (lines 52-58) |
| `--scope branch` | Forces branch review against auto-detected default branch (lines 60-74) |
| `--scope auto` | **Default.** Delegates to working-tree state detection (lines 76-90) |

## The Default Branch Detection Mechanism

When branch mode requires automatic base reference selection, `detectDefaultBranch` (lines 13-16 in `git.mjs`) attempts to find:

1. `main`
2. `master`
3. `trunk`

If none exist, the function throws an error instructing the user to:
- Supply `--base <ref>` explicitly, OR
- Force `--scope working-tree`

## Practical Usage Examples

### Review Current Uncommitted Changes (Auto-Detected)

```bash

# Inside a repo with staged, unstaged, or untracked files

codex review

```

The plugin detects `state.isDirty === true` and returns `mode: "working-tree"`.

### Force Working-Tree Review on Clean Repository

```bash
codex review --scope working-tree

```

Use this to review staged changes even when no other modifications exist.

### Review Against Default Branch

```bash
codex review --scope branch

```

The plugin calls `detectDefaultBranch`, finds `main` (or `master`/`trunk`), and returns a branch target with that `baseRef`.

### Review Against Specific Branch

```bash
codex review --base release/v2.0

```

Bypasses detection entirely; compares current HEAD against `release/v2.0`.

### Explicit Auto Mode (Documented Default)

```bash
codex review --scope auto

```

Matches the behavior of running `codex review` without flags: dirty → working-tree, clean → branch.

## Key Source Files and Their Roles

| File | Purpose |
|------|---------|
| `plugins/codex/scripts/lib/git.mjs` | Implements `resolveReviewTarget`, `getWorkingTreeState`, and `detectDefaultBranch` |
| `plugins/codex/scripts/codex-companion.mjs` | Entry point for `codex review`; consumes target object and builds appropriate review |
| [`plugins/codex/commands/review.md`](https://github.com/openai/codex-plugin-cc/blob/main/plugins/codex/commands/review.md) | CLI documentation defining `--scope` and `--base` options |

## Summary

- **`resolveReviewTarget`** in `git.mjs` is the single source of truth for target determination.
- **Explicit flags win**: `--base` overrides everything; `--scope` overrides auto-detection.
- **`state.isDirty`** from `getWorkingTreeState` drives the default behavior.
- **Branch mode requires a base reference**: either supplied (`--base`) or detected (`main`/`master`/`trunk`).
- The returned target object (`mode`, `label`, `baseRef`, `explicit`) determines which review path executes in `codex-companion.mjs`.

## Frequently Asked Questions

### What happens if I run `codex review` with no flags in a completely clean repository?

The plugin detects `isDirty === false`, enters the `--scope auto` clean-branch path, calls `detectDefaultBranch` to find your default branch (typically `main`), and performs a branch diff review comparing your current HEAD against that base. This effectively reviews all commits on your branch that aren't on `main`.

### Can I review staged changes but ignore unstaged files?

Not directly through target resolution. The `getWorkingTreeState` function treats any staged, unstaged, or untracked files as "dirty," forcing working-tree mode. To review only staged changes, you could stash unstaged work, run `codex review --scope working-tree`, then unstash.

### Why does the plugin fail with "cannot detect default branch"?

Your repository lacks the three standard default branch names (`main`, `master`, `trunk`). The `detectDefaultBranch` function throws this error (lines 13-16 in `git.mjs`) to prevent ambiguous branch comparisons. Resolve by passing `--base <your-branch-name>` explicitly or using `--scope working-tree`.

### What's the difference between `--scope branch` and `--base main`?

`--scope branch` triggers branch mode but still runs `detectDefaultBranch` to find which reference to use. `--base main` explicitly sets the base reference, skipping detection entirely. Use `--base` when your default branch has a non-standard name or when comparing against a specific feature or release branch.