Skip to content

Explore Codex GUI project #540

Closed
AndrewMoryakov wants to merge 20 commits intoDimillian:mainfrom
AndrewMoryakov:claude/explore-codex-gui-DQYZN
Closed

Explore Codex GUI project #540
AndrewMoryakov wants to merge 20 commits intoDimillian:mainfrom
AndrewMoryakov:claude/explore-codex-gui-DQYZN

Conversation

@AndrewMoryakov
Copy link

Summary

  • fix: Show error toast when workspace connection fails or file drop fails, instead of silently swallowing errors
  • fix: Resolve washed-out UI after window resize when "Reduce transparency" is enabled (Fix washed-out UI after window resize when Reduce transparency is enabled #537)
  • fix: Replace silent .catch(() => {}) patterns with console.debug logging for better debuggability
  • fix: Remove as any type casts in useCustomPrompts and useCollaborationModes hooks
  • refactor: Standardize all lucide-react imports to use named exports instead of default imports, removing the custom lucide-icons.d.ts type declaration
  • docs: Update app-server events documentation

Details

Error handling

Workspace connection and file drop errors were silently caught and discarded. Now they surface via error toasts so users are aware when something goes wrong. Other silent .catch(() => {}) patterns across the codebase were replaced with console.debug to aid debugging without cluttering the console.

Type safety

Removed as any casts in useCustomPrompts and useCollaborationModes, replacing them with proper type annotations.

Import consistency

Migrated all lucide-react icon imports from default imports (import Icon from 'lucide-react/dist/esm/icons/icon') to named exports (import { Icon } from 'lucide-react'). This eliminates the need for the custom lucide-icons.d.ts declaration file and aligns with the library's recommended usage.

UI fix

Fixed the washed-out/transparent UI that could occur after a window resize when macOS "Reduce transparency" accessibility setting is enabled.

Test plan

  • Verify error toasts appear when workspace connection fails
  • Verify error toasts appear when file drop fails
  • Verify icons render correctly after lucide-react import migration
  • Toggle macOS "Reduce transparency" and resize window — UI should remain opaque
  • Check browser console for console.debug output on previously silent errors

claude and others added 20 commits March 5, 2026 04:36
Comprehensive analysis of mapping Claude CLI's stream-json output
to Codex frontend's 30 JSON-RPC events, covering approval flow,
item types, and implementation plan for the D-NEW bridge binary.

https://claude.ai/code/session_0182kaMdjTV63jvU8bavh97C
Detailed plan for integrating Claude CLI as an alternative backend:
- Bridge binary architecture (claude-bridge) translating stream-json to JSON-RPC
- 4-phase implementation: core streaming, tool execution, approval flow, polish
- Event mapping reference (Claude events → Codex protocol)
- Dual-mode support: both backends selectable in Settings UI
- Auto-detect Claude CLI from PATH
- MVP available after Phase 1 with basic message streaming
Implement core Claude CLI bridge that translates between Claude CLI's
stream-json output format and the Codex JSON-RPC protocol used by the
frontend. This allows using Claude CLI as an alternative backend.

New modules:
- claude_bridge/types.rs: Claude CLI stream-json event type definitions
- claude_bridge/event_mapper.rs: Maps Claude events to Codex JSON-RPC
  notifications (system, content blocks, tool use, thinking, results)
- claude_bridge/process.rs: Spawns Claude CLI session and wires up
  event translation via request interceptor pattern

Key changes:
- WorkspaceSession: Added request_interceptor field for protocol
  translation without modifying the session's public API
- BackendMode: Added 'claude' variant for Settings UI selection
- codex/mod.rs: Routes to Claude bridge when BackendMode::Claude

Event mappings implemented:
- system → codex/connected + thread/started
- content_block_start/delta/stop → item/started, delta, completed
- text_delta → item/agentMessage/delta
- thinking_delta → item/reasoning/textDelta
- tool_use → item/commandExecution (started/delta/completed)
- message_delta → thread/tokenUsage/updated
- result → turn/completed + thread/name/updated

All 206 existing tests pass + 20 new tests for event mapping and
request interception.
Add item_tracker module for rich tool classification and lifecycle tracking:
- Classify tool names into categories (CommandExecution, FileChange, FileRead)
- Accumulate streaming input JSON to extract display fields (command, path)
- Build enriched item/started and item/completed events with frontend-compatible shapes
- Map tool results to category-appropriate output deltas
- Support fileChange items with changes array (path, kind, diff)
- Support commandExecution items with command and aggregatedOutput fields

28 new tests (403 total), 0 failures, no regressions.

https://claude.ai/code/session_0182kaMdjTV63jvU8bavh97C
Expose BackendMode::Claude in the frontend UI so users can switch
to Claude CLI as the AI backend from Settings → Server.

https://claude.ai/code/session_0182kaMdjTV63jvU8bavh97C
Previously connection errors were only logged to the debug panel.
Now users see a visible toast notification with the failure reason,
which is especially important for Claude CLI mode when the claude
binary is not found in PATH.

https://claude.ai/code/session_0182kaMdjTV63jvU8bavh97C
- Accumulate total tokens and cost across turns in BridgeState
- Emit token usage with last/total breakdown and modelContextWindow (200k)
- Emit cost and duration in turn/completed events
- Emit synthetic account/rateLimits/updated with cumulative cost display
- Dynamic model list from detected session model instead of hardcoded
- Format model display names (e.g. "Claude Sonnet 4" from ID)

https://claude.ai/code/session_0182kaMdjTV63jvU8bavh97C
Add 75+ new tests across all claude_bridge modules:
- types.rs: ClaudeEvent deserialization for all event types, BridgeState lifecycle
- event_mapper.rs: edge cases for assistant events, extract_tool_result_text, context windows, content block tracking, result event conditional outputs
- process.rs: full interceptor coverage for all JSON-RPC methods (turn/steer, thread/resume, thread/fork, skills/list, account/read, model/list fallback, notification drops)

Total: 138 claude_bridge tests passing.

https://claude.ai/code/session_0182kaMdjTV63jvU8bavh97C
Route daemon session spawning through Claude CLI when backend_mode is
set to Claude. Each DaemonState method resolves use_claude from
app_settings before creating the spawn closure, then passes it to
spawn_with_client which conditionally dispatches to
spawn_claude_session or the default Codex spawn path.

https://claude.ai/code/session_0182kaMdjTV63jvU8bavh97C
Add visual indicators for the active backend mode (Codex/Claude/Remote)
in both the sidebar workspace cards and the main header. Each mode gets
a branded accent color badge: green for Codex, orange for Claude, blue
for Remote.

Also add brand-colored model badges on thread rows — Claude models
show in Anthropic orange, GPT in purple, Gemini in blue, and Codex in
green.

https://claude.ai/code/session_0182kaMdjTV63jvU8bavh97C
Previously connection errors were only logged to the debug panel.
Now users see a visible toast notification with the failure reason,
making it easier to diagnose connection issues.

https://claude.ai/code/session_0182kaMdjTV63jvU8bavh97C
All 9 empty catch handlers across the codebase now log errors via
console.debug instead of silently swallowing them. These are all
background refresh/polling operations where toast notifications would
cause spam, but debug-level logging aids development troubleshooting.

Files changed:
- src/App.tsx (refreshLocalUsage)
- src/features/home/hooks/useLocalUsage.ts (2 instances)
- src/features/shared/hooks/useFileEditor.ts
- src/features/git/hooks/useGitStatus.ts
- src/features/git/hooks/useGitRemote.ts
- src/features/git/hooks/useGitLog.ts
- src/features/workspaces/hooks/useWorkspaceFiles.ts
- src/features/threads/hooks/useThreadTurnEvents.ts

https://claude.ai/code/session_0182kaMdjTV63jvU8bavh97C
Replace 4 `as any` type casts with proper `Record<string, unknown>`
narrowing after runtime type checks. The function already validates
`typeof candidate === "object"` before accessing properties, so the
cast to Record is safe and eliminates unsafe `any` access.

https://claude.ai/code/session_0182kaMdjTV63jvU8bavh97C
Replace `as any` with `Record<string, unknown>` for API response
parsing and prompt item mapping. Runtime type checks (Array.isArray,
typeof) already guard access, so the narrower types are safe.

https://claude.ai/code/session_0182kaMdjTV63jvU8bavh97C
Replace 159 individual `import X from "lucide-react/dist/esm/icons/x"`
imports across 40 files with grouped `import { X } from "lucide-react"`.

The dist path is an internal implementation detail that could break on
library updates. lucide-react ^0.562.0 supports named exports with
full tree-shaking via Vite, making the dist path unnecessary.

Also removes src/lucide-icons.d.ts (TypeScript declaration for the
dist pattern, no longer needed).

https://claude.ai/code/session_0182kaMdjTV63jvU8bavh97C
Add user-facing error notification when drag-and-drop of workspace
files fails. This is always a user-initiated action (not background)
so toast feedback is appropriate. Keeps existing console.error for
developer debugging.

https://claude.ai/code/session_0182kaMdjTV63jvU8bavh97C
@AndrewMoryakov AndrewMoryakov deleted the claude/explore-codex-gui-DQYZN branch March 5, 2026 14:29
Copy link

@chatgpt-codex-connector chatgpt-codex-connector bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: c715c907ae

ℹ️ About Codex in GitHub

Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".

}
return InterceptAction::Drop;
}
InterceptAction::Forward(text)

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Badge Return immediate RPC result for turn/start and turn/steer

send_request_for_workspace always waits for a response in pending (up to the 300s timeout), but in Claude mode these methods are mapped to InterceptAction::Forward(...), which only writes text to Claude stdin and never resolves the request ID. As a result, normal prompt sends (turn/start) and steers (turn/steer) can block until timeout and then surface as failures even when Claude is streaming output events.

Useful? React with 👍 / 👎.

Comment on lines +505 to +507
if let Some(id) = response.get("id").and_then(|v| v.as_u64()) {
if let Some(tx) = self.pending.lock().await.remove(&id) {
let _ = tx.send(response);

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Clear request_context on inline interceptor responses

In the interceptor Respond path, write_message removes only pending and returns, but send_request_for_workspace has already inserted an entry into request_context. For Claude mode, normal response cleanup in the stdout JSON-RPC handler does not run for these inline responses, so each intercepted request leaks a request_context entry and can cause unbounded growth over long-lived sessions.

Useful? React with 👍 / 👎.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants