Force working-tree review

How the Codex Plugin Resolves Review Targets: Working Tree vs Branch Detection

The Codex plugin resolves review targets through a priority-based algorithm in resolveReviewTarget that first checks for explicit --base or --scope flags, then automatically selects working-tree mode when uncommitted changes exist or branch mode against the default branch when the repository is clean.

The openai/codex-plugin-cc repository implements intelligent target resolution to determine whether a code review should analyze your working directory changes or compare branches. Understanding how the plugin chooses between working-tree and branch modes helps you control exactly what gets reviewed when running codex review commands. The resolution logic lives in plugins/codex/scripts/lib/git.mjs and follows a strict priority order to balance explicit user intent with automatic detection.

The Core Resolution Function

The resolveReviewTarget function in plugins/codex/scripts/lib/git.mjs (lines 35-90) serves as the single source of truth for determining review scope. This function analyzes repository state and user-provided flags to return a structured target object that downstream components consume when building review requests.

The function examines three potential inputs in strict priority order:

  1. Explicit --base flag – Forces branch comparison against a specific reference
  2. Explicit --scope flag – Directly selects either working-tree or branch mode
  3. Automatic detection – Inspects repository cleanliness to choose intelligently

Priority 1: The --base Flag Override

When you supply --base <ref>, the plugin immediately enters branch mode. This flag takes precedence over all other options, diffing the current HEAD against your specified base reference.

codex review --base main

This returns a target object with mode: "branch", baseRef: "main", and explicit: true, bypassing all automatic detection logic.

Priority 2: The --scope Flag Selection

The --scope flag provides explicit mode selection without specifying a particular branch reference:

  • --scope working-tree → Targets uncommitted changes in your working directory
  • --scope branch → Compares against the repository's default branch (detected via detectDefaultBranch)

# Force working-tree review

codex review --scope working-tree

# Force branch review against default branch

codex review --scope branch

When using --scope branch without --base, the system calls detectDefaultBranch (also in git.mjs) to identify whether to diff against main, master, or another default reference.

Priority 3: Automatic Selection Logic

When no explicit flags are provided, the plugin enters auto mode and inspects repository state via the state.isDirty property. This boolean aggregates status across staged, unstaged, and untracked files.

If the repository contains any uncommitted changes, the function selects working-tree mode to review your active edits. If the repository is completely clean, it falls back to branch mode, comparing the current HEAD against the default branch.

This automatic behavior ensures that codex review without arguments does the right thing: reviewing your current work when you have edits, or reviewing branch divergence when you don't.

Return Value Structure

Regardless of how the mode is determined, resolveReviewTarget returns a standardized object consumed by plugins/codex/scripts/lib/codex.mjs and validated in plugins/codex/scripts/codex-companion.mjs:

{
  mode: "working-tree" | "branch",
  label: "working tree diff" | "branch diff against main",
  baseRef: "main" | undefined,  // Only present for branch mode
  explicit: true | false        // True if from --base or --scope
}

The explicit field allows the CLI to distinguish between user-intended overrides and automatic selections, which affects how results are displayed and cached.

Practical Usage Examples

Example 1: Default Behavior on Dirty Repository

When your working directory has unstaged modifications:

codex review

Resulting target object:

{
  "mode": "working-tree",
  "label": "working tree diff",
  "explicit": false
}

The function detects state.isDirty === true and returns the working-tree target.

Example 2: Explicit Base Reference

codex review --base feature/123

Result:

{
  "mode": "branch",
  "label": "branch diff against feature/123",
  "baseRef": "feature/123",
  "explicit": true
}

Example 3: Explicit Scope to Branch with Default Detection

codex review --scope branch

Assuming the default branch is main:

{
  "mode": "branch",
  "label": "branch diff against main",
  "baseRef": "main",
  "explicit": true
}

Example 4: Explicit Scope to Working Tree

codex review --scope working-tree

Result:

{
  "mode": "working-tree",
  "label": "working tree diff",
  "explicit": true
}

Summary

  • The resolveReviewTarget function in plugins/codex/scripts/lib/git.mjs (lines 35-90) implements a three-tier priority system for target resolution.
  • Explicit --base always wins, forcing branch mode against the specified reference.
  • Explicit --scope selects working-tree or branch mode, with branch mode using detectDefaultBranch to find the comparison target.
  • Automatic mode inspects state.isDirty: uncommitted changes trigger working-tree review, while clean repositories trigger branch comparison against the default.
  • The function returns a structured object with mode, label, baseRef, and explicit properties used by codex.mjs to construct native review requests.

Frequently Asked Questions

What happens if I specify both --base and --scope?

The --base flag takes precedence over --scope according to the priority logic in git.mjs. If you provide both, the plugin ignores the --scope value and uses the explicit base reference for branch comparison.

How does the plugin detect whether to use main or master as the default branch?

The detectDefaultBranch function (located in plugins/codex/scripts/lib/git.mjs) interrogates the repository's symbolic refs and remote configuration to determine whether to diff against main, master, or another default branch when running in --scope branch mode or automatic branch fallback.

Can I review untracked files in working-tree mode?

Yes. The automatic state.isDirty detection includes untracked files alongside staged and unstaged changes. When the plugin detects any uncommitted content—including new untracked files—it selects working-tree mode to ensure those files appear in the review context.

Where are the tests for target resolution located?

Unit tests verifying resolveReviewTarget behavior live in tests/git.test.mjs, covering scenarios for dirty repositories, clean repositories, and explicit flag handling. Integration tests confirming CLI respect for chosen targets appear in tests/runtime.test.mjs.

Have a question about this repo?

These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →