Context
Upstream openai/codex-plugin-cc v1.0.6 includes a security/robustness fix: Git commands are no longer routed through a shell.
References:
The upstream issue is that Git reference names can legally contain characters that Windows shells may interpret specially. Repository-derived Git arguments should therefore be passed as a literal argv array rather than re-parsed by a shell.
gemini-plugin-cc has the same relevant command path:
plugins/gemini/scripts/lib/git.mjs
git(cwd, args, options = {}) calls runCommand("git", args, { cwd, ...options })
gitChecked(cwd, args, options = {}) calls runCommandChecked("git", args, { cwd, ...options })
plugins/gemini/scripts/lib/process.mjs
runCommand() already supports options.shell
- bare command names on Windows default to shell usage for
.cmd/.ps1 wrapper compatibility
That Windows fallback is useful for npm/global CLI wrappers, but Git is directly executable on Windows and does not need shell expansion. Git arguments derived from repository state should be passed literally.
One important nuance in this fork: explicit --base refs are already validated by isSafeGitRef(), but auto-detected default branches come from repository state via refs/remotes/origin/HEAD and can still flow into branch diff collection.
Proposed change
Mirror the upstream hardening pattern in the Gemini helper layer:
-
Update plugins/gemini/scripts/lib/git.mjs so all Git helper calls force shell: false, applied after caller-provided options:
function git(cwd, args, options = {}) {
return runCommand("git", args, { cwd, ...options, shell: false });
}
function gitChecked(cwd, args, options = {}) {
return runCommandChecked("git", args, { cwd, ...options, shell: false });
}
-
Keep the existing Windows shell fallback for commands that actually need wrapper resolution, such as npm/global CLI binaries.
-
Add regression coverage for an automatically detected default branch/ref name containing Windows shell-special characters.
-
If the regression fixture needs direct Git invocation with shell: false, update tests/helpers.mjs to honor an explicit options.shell override, matching the upstream test-helper change.
Acceptance criteria
- Git helper paths always invoke Git with
shell: false.
- Existing Gemini/AGY engine execution behavior remains unchanged.
- Windows wrapper compatibility for non-Git commands is preserved.
- A regression test covers an auto-detected default branch/ref name with shell-special characters.
- The regression verifies that:
- the branch name is passed to Git literally;
- no adjacent shell command/helper is executed;
- branch review target detection and diff collection still work.
- Existing test suite passes.
Notes
This is not primarily a user-facing feature. It is a parity hardening change based on upstream openai/codex-plugin-cc v1.0.6 and should be prioritized ahead of a possible /gemini:transfer backlog item.
Context
Upstream
openai/codex-plugin-ccv1.0.6 includes a security/robustness fix: Git commands are no longer routed through a shell.References:
The upstream issue is that Git reference names can legally contain characters that Windows shells may interpret specially. Repository-derived Git arguments should therefore be passed as a literal argv array rather than re-parsed by a shell.
gemini-plugin-cchas the same relevant command path:plugins/gemini/scripts/lib/git.mjsgit(cwd, args, options = {})callsrunCommand("git", args, { cwd, ...options })gitChecked(cwd, args, options = {})callsrunCommandChecked("git", args, { cwd, ...options })plugins/gemini/scripts/lib/process.mjsrunCommand()already supportsoptions.shell.cmd/.ps1wrapper compatibilityThat Windows fallback is useful for npm/global CLI wrappers, but Git is directly executable on Windows and does not need shell expansion. Git arguments derived from repository state should be passed literally.
One important nuance in this fork: explicit
--baserefs are already validated byisSafeGitRef(), but auto-detected default branches come from repository state viarefs/remotes/origin/HEADand can still flow into branch diff collection.Proposed change
Mirror the upstream hardening pattern in the Gemini helper layer:
Update
plugins/gemini/scripts/lib/git.mjsso all Git helper calls forceshell: false, applied after caller-provided options:Keep the existing Windows shell fallback for commands that actually need wrapper resolution, such as npm/global CLI binaries.
Add regression coverage for an automatically detected default branch/ref name containing Windows shell-special characters.
If the regression fixture needs direct Git invocation with
shell: false, updatetests/helpers.mjsto honor an explicitoptions.shelloverride, matching the upstream test-helper change.Acceptance criteria
shell: false.Notes
This is not primarily a user-facing feature. It is a parity hardening change based on upstream
openai/codex-plugin-ccv1.0.6 and should be prioritized ahead of a possible/gemini:transferbacklog item.