How the Codex‑CC Plugin Resolves Workspace Roots: Git Detection and Fallback Strategy

The Codex‑CC plugin resolves workspace roots by first attempting to locate the Git repository top‑level via git rev-parse --show-toplevel, then falling back to the current working directory if Git is unavailable or the directory is not a repository.

The openai/codex-plugin-cc repository provides a deterministic mechanism for establishing workspace roots across various operations. This resolution strategy, implemented in the plugin's utility modules, ensures that Git-centric projects use the repository root while maintaining compatibility with non-Git contexts.

Core Resolution Logic in workspace.mjs

The primary entry point for workspace root resolution is the resolveWorkspaceRoot function exported from plugins/codex/scripts/lib/workspace.mjs. This function accepts a cwd parameter and implements a two-tier resolution strategy that prioritizes Git repository detection.

// plugins/codex/scripts/lib/workspace.mjs
import { ensureGitRepository } from "./git.mjs";

export function resolveWorkspaceRoot(cwd) {
  try {
    // If the current directory is inside a Git repository,
    // `ensureGitRepository` returns the repository's top-level path.
    return ensureGitRepository(cwd);
  } catch {
    // When Git is unavailable or the directory isn't a repository,
    // fall back to the supplied cwd.
    return cwd;
  }
}

Git Repository Detection

When resolving a workspace root, the function first delegates to ensureGitRepository imported from ./git.mjs. This utility executes the Git command rev-parse --show-toplevel to determine the absolute path of the repository root according to the Git metadata.

Graceful Fallback to Current Working Directory

If ensureGitRepository throws an error—either because Git is not installed or the directory is not inside a Git repository—the catch block returns the original cwd parameter unchanged. This ensures the plugin continues functioning in temporary directories, test fixtures, or standalone files without crashing.

The Git Resolution Implementation

The ensureGitRepository function in plugins/codex/scripts/lib/git.mjs handles the actual Git interaction. It validates that Git is installed and that the command executes successfully before returning the trimmed stdout output containing the repository top-level path.

// plugins/codex/scripts/lib/git.mjs
export function ensureGitRepository(cwd) {
  const result = git(cwd, ["rev-parse", "--show-toplevel"]);
  const errorCode = result.error && "code" in result.error ? result.error.code : null;
  if (errorCode === "ENOENT") {
    throw new Error("git is not installed. Install Git and retry.");
  }
  if (result.status !== 0) {
    throw new Error("This command must run inside a Git repository.");
  }
  return result.stdout.trim();   // <-- repository top-level path
}

Usage Throughout the Plugin

Multiple modules import and utilize resolveWorkspaceRoot to maintain consistent working directories across the codebase:

  • plugins/codex/scripts/stop-review-gate-hook.mjs (line 145) – Determines the root before performing a stop-review gate.
  • plugins/codex/scripts/session-lifecycle-hook.mjs (line 47) – Resolves the workspace for session-lifecycle handling.
  • plugins/codex/scripts/lib/state.mjs (line 30) – Initializes state relative to the repo root.
  • plugins/codex/scripts/lib/job-control.mjs (lines 214, 243, 257, 282) – Manages jobs using a consistent root path.
  • plugins/codex/scripts/codex-companion.mjs (lines 183, 337, 462) – Resolves the root for various companion commands.

All these modules import the function using:

import { resolveWorkspaceRoot } from "./lib/workspace.mjs";

Practical Implementation Example

Developers working with the Codex‑CC plugin can import the resolver to ensure consistent workspace handling in custom scripts:

import { resolveWorkspaceRoot } from "./plugins/codex/scripts/lib/workspace.mjs";

const cwd = process.cwd();               // current working directory
const workspaceRoot = resolveWorkspaceRoot(cwd);

console.log(`Workspace root is: ${workspaceRoot}`);

When you need to guarantee Git-specific operations after resolution:

import { getRepoRoot } from "./plugins/codex/scripts/lib/git.mjs";
import { resolveWorkspaceRoot } from "./plugins/codex/scripts/lib/workspace.mjs";

function listRepoFiles() {
  const cwd = process.cwd();
  const root = resolveWorkspaceRoot(cwd);
  const repoRoot = getRepoRoot(root);   // guaranteed to be the Git top-level
  // Now you can safely run Git commands relative to `repoRoot`.
}

Summary

  • The resolveWorkspaceRoot function in plugins/codex/scripts/lib/workspace.mjs provides deterministic workspace resolution for the Codex‑CC plugin.
  • It attempts Git repository detection via ensureGitRepository using git rev-parse --show-toplevel to find the repository top-level.
  • When Git detection fails (ENOENT or non-zero exit), the function gracefully falls back to the supplied cwd parameter.
  • This resolution pattern is used across hooks, state management, job control, and companion scripts to ensure consistent workspace handling.

Frequently Asked Questions

What happens if Git is not installed when resolving workspace roots?

The plugin catches the ENOENT error thrown by ensureGitRepository and returns the original cwd parameter, allowing operations to continue using the current directory without requiring Git installation.

Which file contains the main workspace resolution logic?

The resolveWorkspaceRoot function is defined in plugins/codex/scripts/lib/workspace.mjs and relies on ensureGitRepository from plugins/codex/scripts/lib/git.mjs to perform Git-based detection.

How does the plugin handle directories outside of Git repositories?

When git rev-parse --show-toplevel fails or returns a non-zero exit code indicating the directory is not inside a Git repository, the resolver falls back to the provided cwd rather than throwing an error, enabling usage in non-Git contexts.

Where is resolveWorkspaceRoot used in the codebase?

Key call sites include stop-review-gate-hook.mjs (line 145), session-lifecycle-hook.mjs (line 47), state.mjs (line 30), job-control.mjs (lines 214, 243, 257, 282), and codex-companion.mjs (lines 183, 337, 462), ensuring consistent workspace handling across session lifecycle management and job control operations.

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 →