Conversation
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
Claude/explore codex gui dqyzn
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
Claude/explore codex gui dqyzn
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
There was a problem hiding this comment.
💡 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) |
There was a problem hiding this comment.
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 👍 / 👎.
| 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); |
There was a problem hiding this comment.
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 👍 / 👎.
Summary
.catch(() => {})patterns withconsole.debuglogging for better debuggabilityas anytype casts inuseCustomPromptsanduseCollaborationModeshookslucide-reactimports to use named exports instead of default imports, removing the customlucide-icons.d.tstype declarationDetails
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 withconsole.debugto aid debugging without cluttering the console.Type safety
Removed
as anycasts inuseCustomPromptsanduseCollaborationModes, replacing them with proper type annotations.Import consistency
Migrated all
lucide-reacticon 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 customlucide-icons.d.tsdeclaration 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
console.debugoutput on previously silent errors