Skip to content

Improvement proposals: tool mapping, unified types, and frontend enhancements #102

@realDuang

Description

@realDuang

Overview

Based on a deep analysis of Claude Code v2.1.88 internals combined with CodeMux's multi-engine architecture constraints, we've identified a set of layered improvement proposals. All suggestions strictly follow CodeMux's engine-agnostic frontend principle: the frontend dispatches rendering only via NormalizedToolName and EngineCapabilities, never branching on engineType.

Ref: #79

Change Tiers

Tier Scope Cross-engine Risk
A (Adapter only) Only modifies a specific engine adapter; no unified types or frontend changes None
B (Unified type extensions) Extends optional fields or capability flags in unified.ts Low (unfilled adapters unaffected)
C (Frontend features) Modifies frontend components, gated by unified types/capabilities Medium (must ensure all engines remain compatible)

Tier A: Adapter-Only Changes (Zero Cross-Engine Risk)

A1. Complete Claude Tool Mapping

Files: src/types/tool-mapping.ts

The current CLAUDE_TOOL_MAP is missing several tools that Claude Code actually uses, causing them all to map to "unknown":

// Currently missing, should be added:
const CLAUDE_TOOL_MAP = {
  ...existing,
  PowerShell: "shell",     // CC uses PowerShell instead of Bash on Windows
  FileWrite: "write",      // CC's FileWriteTool (currently only "Write" is mapped)
  WebSearch: "web_fetch",  // CC native search tool
  NotebookEdit: "edit",    // Jupyter notebook editing
};

Effort: ~30 min

A2. Claude Adapter Error Classification

Files: electron/main/engines/claude/index.ts

Claude Code internally distinguishes multiple recoverable errors and has auto-recovery mechanisms. When the adapter receives SDK error events:

  • Attach structured info to UnifiedMessage.error (e.g., "[rate_limited] Please wait..." instead of raw stack traces)
  • Ensure truncated text is not swallowed when max_output_tokens truncation occurs (the SDK may have already sent partial content before the error event)

Effort: ~3 hours

A3. Populate Permission Diff in Claude Adapter

Files: electron/main/engines/claude/index.ts

Claude Code's FileEditTool includes a diff preview in permission requests. Ensure the diff content is extracted from SDK permission events and populated into UnifiedPermission.diff. Currently only title and rawInput may be populated.

Effort: ~1 hour


Tier B: Unified Type Extensions

B1. Add "web_search" to NormalizedToolName

Files: src/types/unified.ts, src/types/tool-mapping.ts, src/components/share/part.tsx

Motivation: Currently both WebSearch (Claude) and web_search (Copilot) map to "web_fetch", but they behave very differently:

  • web_search returns multiple search result summaries
  • web_fetch returns the full content of a single page

Changes:

  1. unified.ts: Add "web_search" to the NormalizedToolName union type
  2. tool-mapping.ts: Map Claude's WebSearch and Copilot's web_search to "web_search"
  3. part.tsx: Add a render branch for "web_search" (search result list style, distinct from web_fetch page preview)
  4. ContextGroup.tsx: Add "web_search" to the CONTEXT_TOOLS set

Effort: ~2 hours

B2. Add costTracking: boolean to EngineCapabilities

Files: src/types/unified.ts, each adapter

Motivation: The cost field is optional on all engines' UnifiedMessage, but the semantics differ:

  • Claude: USD token pricing
  • OpenCode: USD token pricing (with provider pricing table)
  • Copilot: Premium Requests (not USD)

Changes:

  1. Add costTracking: boolean to EngineCapabilities
  2. Claude adapter: costTracking: true
  3. OpenCode adapter: costTracking: true
  4. Copilot adapter: costTracking: false
  5. Frontend shows/hides cost badge based on this flag

Effort: ~2 hours

B3. Add activityDescription?: string to UnifiedMessage

Files: src/types/unified.ts, each adapter

Motivation: Claude Code's tools each have getActivityDescription(), returning human-readable strings like "Reading src/foo.ts" or "Running bun test". Currently ToolPart.title partially serves this role but with inconsistent quality.

Changes:

  1. Each adapter extracts a better activity description from SDK events
  2. Frontend spinner/progress area prefers activityDescription, falls back to title

Effort: ~3 hours


Tier C: Frontend Features (Gated by Unified Types/Capabilities)

C1. Context Compaction Visualization

Files: src/components/SessionTurn.tsx

Current state: The isCompaction field already exists on UnifiedMessage, and SessionTurn.tsx already detects it but handles it silently.

Change: Render a collapsible divider at compaction messages (e.g., "Context compacted"), helping users understand why conversation history was truncated.

Compatibility: Engine-agnostic — renders whenever isCompaction === true (both OpenCode and Claude produce compaction messages).

Effort: ~1 hour

C2. Diff Rendering in Permission Dialog

Files: src/components/PermissionDialog.tsx (or related permission UI components)

Current state: UnifiedPermission.diff already exists in unified types, but the frontend may only display title.

Change: When diff is present, render a diff preview using shiki (already a project dependency) in the permission dialog, so users can see exactly what will be modified before deciding.

Compatibility: All engines can populate diff (OpenCode already has diff support, Claude via A3, Copilot edit permissions can also be enhanced).

Effort: ~2 hours

C3. Queued Messages UI Enhancement

Files: src/stores/message.ts, related UI components

Current state: The messageEnqueue capability exists and QueuedMessage type is defined.

Changes:

Compatibility: Gated by messageEnqueue capability; engines that don't support it are unaffected.

Effort: ~2 hours


Intentionally Excluded

Proposal Reason
Sub-agent nested visualization Only CC has a full multi-layer agent system. Designing a unified AgentPart type with adapters for all three engines has uncertain ROI
Plan Mode special UI Mode semantics differ significantly across engines (CC = permission toggle, OpenCode = provider behavior, Copilot = global mode)
Channel permission remote approval Would require defining a cross-engine permission forwarding protocol; channels currently only forward messages
Session forking Only CC has robust session fork; other engines would need their own implementations

Suggested Priority

P1 — Low risk, high reward (~2.5 hours):

  • A1: Complete Claude tool mapping
  • A3: Populate permission diff
  • C1: Compaction divider

P2 — Small type extensions + UI (~6 hours):

  • B1: Add web_search normalized tool
  • C2: Permission diff rendering
  • B2: costTracking capability

P3 — Experience enhancements (~8 hours):

  • B3: activityDescription field
  • A2: Error classification
  • C3: Queued messages UI

Total estimated effort: ~16.5 hours


Contributions welcome! Each item is designed to be independently implementable. Feel free to pick up any task — starting with P1 items is recommended.

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or requesthelp wantedExtra attention is needed

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions