Skip to content

Upstream CLI drift (follow-up to #25): gemini-cli v0.39.1 ships workspace-trust gate for headless mode — likely first real breakage for fresh installs #26

@Lykhoyda

Description

@Lykhoyda

Summary

Second follow-up to #24 / #25. Both upstreams cut releases again on 2026-04-24 (24h after #25 was filed).

Versions re-audited:

Bottom line: #25 was right that no prior release had hard-breakage. v0.39.1 changes that. Gemini v0.39.1 adds a workspace-trust gate to headless mode that our executor does not handle, so users who invoke ask-gemini-mcp against a directory they have never opened in interactive gemini will now get a FatalUntrustedWorkspaceError instead of a response. This is the first concrete upstream regression surface since the audit series began.

Codex rust-v0.124.0 graduated to stable cleanly; no CLI/JSONL changes from our perspective, but hooks have stabilized and one new non-breaking convenience (stdin prompts) is worth adopting.


1. 🔴 Breaking: Gemini CLI v0.39.1 — workspace trust now enforced in headless mode

Upstream change: gemini-cli#25814secure .env loading and enforce workspace trust in headless mode, shipped in v0.39.1.

What changed

Starting v0.39.1, invoking gemini -p … (headless, which is exactly how we call it in packages/gemini-mcp/src/utils/geminiExecutor.ts:467) against a directory that was never marked trusted fails with:

Gemini CLI is not running in a trusted directory. To proceed, either use
`--skip-trust`, set the `GEMINI_TRUST_WORKSPACE=true` environment variable,
or trust this directory in interactive mode.

A new FatalUntrustedWorkspaceError is thrown before any model call. .env loading is also restricted to an allowlist in untrusted workspaces.

Why it affects us

  • Our buildArgs (packages/gemini-mcp/src/utils/geminiExecutor.ts:358) passes -m, -s, --resume, --include-directories, --output-format stream-json, -pno --skip-trust.
  • We do not export GEMINI_TRUST_WORKSPACE in executeCommand (packages/shared/src/commandExecutor.ts).
  • Confirmed via grep -rn "skip-trust\|GEMINI_TRUST_WORKSPACE\|FatalUntrusted" — zero references across the repo.
  • First-time MCP users on v0.39.1 will see a raw stderr dump bubbled through our createGeminiStderrHandler (which only special-cases RESOURCE_EXHAUSTED) and a non-descriptive failure at the client. The retry/fallback path won't help — it's not a quota error.

Recommended fix

Two layers, in order of priority:

  1. Default to safe in an MCP/non-interactive context — emit --skip-trust from buildArgs by default, since MCP is already running the user's own CLI on the user's own machine at the user's explicit request. This mirrors how upstream CI sets GEMINI_TRUST_WORKSPACE=true in its own E2E workflows. Gate it behind an opt-out env var (ASK_GEMINI_REQUIRE_WORKSPACE_TRUST=1) for users who deliberately want trust-gating.
  2. Friendly error mapping — teach parseGeminiStreamJsonl / the stderr handler to detect FatalUntrustedWorkspaceError and surface a one-line instruction to the MCP caller (e.g. "Gemini workspace trust required — run gemini interactively once in this directory or set ASK_GEMINI_REQUIRE_WORKSPACE_TRUST=0"). The retry/fallback path (geminiExecutor.ts:494) should short-circuit on this error — it's not a quota problem.

Also bump the minimum-recommended Gemini CLI entry in the README from ≥ v0.39.0 (implied by #25) to ≥ v0.39.1, and document the new behavior on docs/providers/gemini.

Regression test

Extend the sessionId round-trip test proposed in #25 §1.2 to also exercise a fresh untrusted $TMPDIR and confirm we get a readable error (or success, if we default to --skip-trust).


2. Gemini CLI v0.39.1 — other changes (non-breaking)

From v0.39.0…v0.39.1:

  • Shell command validation + core tools allowlist (#25720). Internal to Gemini's own shell tool; doesn't touch the stream-json event contract we consume. Safe.
  • FatalUntrustedWorkspaceError doc link (#25874). Docs-only.

No other watch-items from #24 / #25 were triggered:

  • -m, -s, -p, --output-format stream-json, --resume, --include-directories — all unchanged.
  • initmessageresult event shape parsed by parseGeminiStreamJsonl (geminiExecutor.ts:265) — unchanged.
  • gemini-3.1-pro-preview / gemini-3-flash-preview aliases still current (confirmed via ai.google.dev model list); graduation to gemini-3.1-pro / gemini-3-flash still pending.

3. Gemini CLI v0.40.0-preview.3 (2026-04-24) — nothing new vs preview.2

Identical surface to v0.40.0-preview.2 (covered in #25 §1.4). The ripgrep-bundled, colorblind-theme, MCP-resource-tools, and autoMemory items all carry over. No additional action beyond what #25 proposed.


4. Codex CLI rust-v0.124.0 (stable, 2026-04-23)

#25 §2 covered up to v0.123.0 stable. v0.124.0 graduated out of alpha on the same day #25 was filed — a few items worth capturing separately:

4.1 Flags / JSONL events — still unchanged

exec, resume, --skip-git-repo-check, --ephemeral, --full-auto, --json, -m all intact. thread.started / item.completed (agent_message) / turn.completed.usage.{input,output,cached_input}_tokens event shape matched by parseCodexJsonlOutput (packages/codex-mcp/src/utils/codexExecutor.ts:69) — unchanged.

4.2 Hooks stabilized → no direct effect, one indirect watch-item

v0.124.0 marks hooks as stable (docs): PreToolUse, PostToolUse, PermissionRequest, UserPromptSubmit, Stop. Configurable in config.toml / requirements.toml, can observe MCP tools + apply_patch + long-running bash.

Indirect concern: hooks run in codex exec too, and project hooks and exec policies now require trusted workspaces (parallel to the Gemini change above — release notes). Because we already pass --skip-git-repo-check and --ephemeral on non-resume calls, we should be fine today — but if a user installs hooks in their ~/.codex/config.toml, those hooks will now fail against the ephemeral sandbox we spawn, and that failure may bubble up as an error event rather than a silent skip. Worth a follow-up smoke test.

4.3 ⚡ New opportunity: codex exec accepts prompt-plus-stdin

v0.124.0 notes: "codex exec now supports the prompt-plus-stdin workflow, so you can pipe input and still pass a separate prompt on the command line."

Why we want this: our buildArgs (codex-mcp/src/utils/codexExecutor.ts:129) appends the full user prompt as the final positional argv element. That's fine for short prompts, but /multi-review, /brainstorm, and anything with @largefile expansion from Gemini can push argv close to ARG_MAX (2097152 on Linux, 262144 on macOS). Piping the large blob via stdin while keeping a short positional prompt removes that ceiling and also keeps full prompts out of ps output (minor privacy win).

Proposed change (low risk):

  • When prompt.length > 16 KiB, feed the prompt via process.stdin and pass only a short summary argv ("see stdin"). Requires small changes in packages/shared/src/commandExecutor.ts (the executeCommand helper) to accept an optional stdin payload — which would also benefit the Ollama executor.

4.4 Fast service tier default — confirm no user-visible change for API-key users

v0.124.0 makes eligible ChatGPT plans default to Fast tier (PR #19053). API-key-authenticated users (the other common Codex auth path) are unaffected. Our executor doesn't touch service_tier config, so no action — but we should mention it in the docs as "ChatGPT-plan users may see lower latency; API-key users unchanged."

4.5 Other v0.124.0 items (neutral / TUI-only)

4.6 Items from #24 / #25 still open


5. Proposed action items (diff vs #25)

Ordered by urgency:

  1. [🔴 New, urgent — first real breakage surface] Add --skip-trust to the default geminiExecutor argv, and map FatalUntrustedWorkspaceError to a friendly error that short-circuits the fallback retry. See §1. Touches packages/gemini-mcp/src/constants.ts:29 (add SKIP_TRUST: "--skip-trust"), packages/gemini-mcp/src/utils/geminiExecutor.ts:358 (emit flag), packages/gemini-mcp/src/utils/geminiExecutor.ts:379 (map stderr error), plus README bump to "Gemini CLI ≥ v0.39.1 recommended."
  2. [New, medium] Add stdin-piping support for large prompts in packages/shared/src/commandExecutor.ts; wire it into codexExecutor.ts:140 and geminiExecutor.ts:397 for any prompt > 16 KiB. See §4.3.
  3. [New, low] Smoke-test that Codex v0.124.0's stabilized hook surface doesn't break our --ephemeral exec path when the user has ~/.codex/config.toml hooks defined. §4.2.
  4. [Carried from Upstream CLI drift (follow-up to #24): gemini-cli v0.39.0 & codex rust-v0.123.0 — still no hard breakage, one watch-item triggered #25, now more urgent alongside #1] sessionId round-trip + untrusted-workspace integration test for Gemini.
  5. [Carried from Upstream CLI drift report: gemini-cli v0.38/v0.39 & codex v0.122 — no hard breakage, several improvement opportunities #24 / Upstream CLI drift (follow-up to #24): gemini-cli v0.39.0 & codex rust-v0.123.0 — still no hard breakage, one watch-item triggered #25] --ignore-user-config + --ignore-rules on the ephemeral Codex exec path.
  6. [Carried from Upstream CLI drift report: gemini-cli v0.38/v0.39 & codex v0.122 — no hard breakage, several improvement opportunities #24 / Upstream CLI drift (follow-up to #24): gemini-cli v0.39.0 & codex rust-v0.123.0 — still no hard breakage, one watch-item triggered #25] Gemini tool-event progress forwarding and typed exit codes.
  7. [Tracking] Watch for gemini-cli v0.40 graduation from preview; watch codex rust-v0.125.0 (alphas already appearing, alpha.3 out).

Hotfix required? Arguably yes for action #1 — any user installing ask-gemini-mcp fresh on v0.39.1 in a directory they haven't previously opened in interactive gemini will hit the workspace-trust wall. A one-line --skip-trust addition is enough to restore parity with the ≤ v0.39.0 behavior.


Report generated from an incremental upstream release audit against issues #24 and #25. Sources: gemini-cli releases, gemini-cli PR #25814, codex releases, codex rust-v0.124.0 notes, codex hooks docs, codex PR #19053, upstream PRs/issues linked inline.

Metadata

Metadata

Assignees

No one assigned

    Labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions