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:
unified.ts: Add "web_search" to the NormalizedToolName union type
tool-mapping.ts: Map Claude's WebSearch and Copilot's web_search to "web_search"
part.tsx: Add a render branch for "web_search" (search result list style, distinct from web_fetch page preview)
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:
- Add
costTracking: boolean to EngineCapabilities
- Claude adapter:
costTracking: true
- OpenCode adapter:
costTracking: true
- Copilot adapter:
costTracking: false
- 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:
- Each adapter extracts a better activity description from SDK events
- 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):
P2 — Small type extensions + UI (~6 hours):
P3 — Experience enhancements (~8 hours):
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.
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
NormalizedToolNameandEngineCapabilities, never branching onengineType.Ref: #79
Change Tiers
unified.tsTier A: Adapter-Only Changes (Zero Cross-Engine Risk)
A1. Complete Claude Tool Mapping
Files:
src/types/tool-mapping.tsThe current
CLAUDE_TOOL_MAPis missing several tools that Claude Code actually uses, causing them all to map to"unknown":Effort: ~30 min
A2. Claude Adapter Error Classification
Files:
electron/main/engines/claude/index.tsClaude Code internally distinguishes multiple recoverable errors and has auto-recovery mechanisms. When the adapter receives SDK error events:
UnifiedMessage.error(e.g.,"[rate_limited] Please wait..."instead of raw stack traces)max_output_tokenstruncation 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.tsClaude Code's
FileEditToolincludes a diff preview in permission requests. Ensure the diff content is extracted from SDK permission events and populated intoUnifiedPermission.diff. Currently onlytitleandrawInputmay be populated.Effort: ~1 hour
Tier B: Unified Type Extensions
B1. Add
"web_search"to NormalizedToolNameFiles:
src/types/unified.ts,src/types/tool-mapping.ts,src/components/share/part.tsxMotivation: Currently both
WebSearch(Claude) andweb_search(Copilot) map to"web_fetch", but they behave very differently:web_searchreturns multiple search result summariesweb_fetchreturns the full content of a single pageChanges:
unified.ts: Add"web_search"to theNormalizedToolNameunion typetool-mapping.ts: Map Claude'sWebSearchand Copilot'sweb_searchto"web_search"part.tsx: Add a render branch for"web_search"(search result list style, distinct fromweb_fetchpage preview)ContextGroup.tsx: Add"web_search"to theCONTEXT_TOOLSsetEffort: ~2 hours
B2. Add
costTracking: booleanto EngineCapabilitiesFiles:
src/types/unified.ts, each adapterMotivation: The
costfield is optional on all engines'UnifiedMessage, but the semantics differ:Changes:
costTracking: booleantoEngineCapabilitiescostTracking: truecostTracking: truecostTracking: falseEffort: ~2 hours
B3. Add
activityDescription?: stringto UnifiedMessageFiles:
src/types/unified.ts, each adapterMotivation: Claude Code's tools each have
getActivityDescription(), returning human-readable strings like "Reading src/foo.ts" or "Running bun test". CurrentlyToolPart.titlepartially serves this role but with inconsistent quality.Changes:
activityDescription, falls back totitleEffort: ~3 hours
Tier C: Frontend Features (Gated by Unified Types/Capabilities)
C1. Context Compaction Visualization
Files:
src/components/SessionTurn.tsxCurrent state: The
isCompactionfield already exists onUnifiedMessage, andSessionTurn.tsxalready 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.diffalready exists in unified types, but the frontend may only displaytitle.Change: When
diffis 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 componentsCurrent state: The
messageEnqueuecapability exists andQueuedMessagetype is defined.Changes:
Compatibility: Gated by
messageEnqueuecapability; engines that don't support it are unaffected.Effort: ~2 hours
Intentionally Excluded
AgentParttype with adapters for all three engines has uncertain ROISuggested Priority
P1 — Low risk, high reward (~2.5 hours):
P2 — Small type extensions + UI (~6 hours):
web_searchnormalized toolcostTrackingcapabilityP3 — Experience enhancements (~8 hours):
activityDescriptionfieldTotal 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.