Files
SuperCharged-Claude-Code-Up…/docs/plans/2025-01-21-terminal-approval-ui-design.md
uroma 153e365c7b Fix command truncation and prepare for approval UI
- Fix regex pattern in semantic-validator.js that was truncating
  domain names (google.com -> google)
- Remove unnecessary 'info' type error reporting to bug tracker
- Only add bug tracker activity when errorId is valid
- Add terminal approval UI design document

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2026-01-21 13:14:43 +00:00

8.3 KiB

Terminal Mode Approval UI Design

Date: 2025-01-21 Status: Design Approved, Ready for Implementation

Overview

Redesign terminal mode command approval flow to use interactive UI buttons instead of conversational text responses. This eliminates ambiguity, prevents accidental mode switches, and provides clear visual feedback for command approvals.

Problem Statement

Current Issues:

  1. Terminal commands go to AI agent instead of executing directly via shell
  2. When AI asks for approval, typing "APPROVED" is not recognized as approval
  3. System treats "APPROVED" as conversational message and switches to Chat mode
  4. No clear UI for approving/rejecting commands

User Impact:

  • Confusing approval flow
  • Inadvertent mode switching
  • Commands not executing when expected

Design Solution

1. Approval Request UI Component

Visual Design:

┌─────────────────────────────────────────┐
│ 🤖 Executing: ping google.com          │
│                                         │
│ Network operation - will send ICMP      │
│ packets to google.com                   │
│                                         │
│ [Approve]  [Custom Instructions]  [Reject] │
└─────────────────────────────────────────┘

Custom Instructions Mode: When clicked, expands to show input field:

┌─────────────────────────────────────────┐
│ 🤖 Executing: ping google.com          │
│                                         │
│ [Input: __ping google.com -c 5___]     │
│                                         │
│ [Execute Custom]  [Cancel]              │
└─────────────────────────────────────────┘

Key Features:

  • Inline with chat messages (like tool output)
  • Shows command and explanation
  • Three clear buttons (no ambiguity)
  • Custom instructions option for command modification
  • Auto-highlights pending request

2. Data Flow

Approval Request Flow:

1. AI decides to execute command requiring approval
2. AI sends WebSocket message:
   {
     "type": "approval-request",
     "id": "approval-123456",
     "command": "ping google.com",
     "explanation": "Network operation...",
     "sessionId": "session-abc"
   }
3. Frontend renders approval card
4. User sees buttons

Approve Response:

{
  "type": "approval-response",
  "id": "approval-123456",
  "approved": true,
  "sessionId": "session-abc"
}

Custom Instructions Response:

{
  "type": "approval-response",
  "id": "approval-123456",
  "approved": true,
  "customCommand": "ping google.com -c 3",
  "sessionId": "session-abc"
}

Reject Response:

{
  "type": "approval-response",
  "id": "approval-123456",
  "approved": false,
  "sessionId": "session-abc"
}

3. State Management

Pending Approvals Manager (Server-side):

class PendingApprovalsManager {
  constructor() {
    this.approvals = new Map();
  }

  createApproval(sessionId, command, explanation) {
    const id = `approval-${Date.now()}-${Math.random().toString(36).substr(2, 9)}`;
    this.approvals.set(id, {
      sessionId, command, explanation,
      createdAt: Date.now()
    });
    // Auto-expire after 5 minutes
    setTimeout(() => this.expire(id), 5 * 60 * 1000);
    return id;
  }

  getApproval(id) { /* ... */ }
  removeApproval(id) { /* ... */ }
  expire(id) { /* ... */ }
}

Why This Works:

  • Server tracks pending approvals
  • Approval sent to AI as conversational message: "[APPROVED: ping google.com]"
  • AI sees approval in conversation context
  • AI proceeds with command
  • No complex state needed in AI itself

Auto-Cleanup:

  • Pending approvals expire after 5 minutes
  • Cleared on session disconnect
  • Expired approvals show: "This approval request has expired"

4. Component Architecture

Frontend Components:

approval-card.js

class ApprovalCard {
  render(approvalData) { /* Returns HTML */ }
  handleApprove() { sendApprovalResponse(this.id, true); }
  handleCustom() { this.expandInput(); }
  handleReject() { sendApprovalResponse(this.id, false); }
  executeCustom(customCommand) { sendApprovalResponse(this.id, true, customCommand); }
}

chat-functions.js (Enhancements)

// In handleWebSocketMessage():
if (data.type === 'approval-request') {
  renderApprovalCard(data);
  return;
}

Backend Components:

server.js

class PendingApprovalsManager {
  // Manages pending approval state
}

// WebSocket handlers for approval-request and approval-response

services/claude-service.js

async requestApproval(sessionId, command, explanation) {
  const approvalId = approvalManager.createApproval(...);
  this.emit('approval-request', {id, sessionId, command, explanation});
}

5. Error Handling & Edge Cases

Error Scenarios:

  1. Approval Request Times Out

    • 5-minute auto-expire
    • Buttons disabled, shows "Expired"
    • AI informed of timeout
  2. User Tries New Command During Approval

    • Show: "You have a pending approval. Please approve or reject first."
    • New command queued until approval resolved
  3. Custom Command Significantly Different

    • Original: ping google.com
    • Custom: rm -rf /
    • AI reviews custom command
    • If more dangerous, requests NEW approval
    • Shows: "Modified command requires additional approval"
  4. Session Disconnected During Approval

    • Pending approvals auto-expire
    • Fresh state on reconnect
    • No stale approvals
  5. Duplicate Approval Requests

    • Server checks for existing approval for same command/session
    • Reuses existing ID
    • Prevents duplicate cards
  6. Custom Command Validation

    • Empty input: "Please enter a command or use Approve/Reject"
    • Dangerous commands: AI still reviews, can re-request approval

6. Implementation Plan

Phase 1: Backend Approval Tracking

  • Create PendingApprovalsManager class in server.js
  • Add approval request/response WebSocket handlers
  • Integrate with claude-service.js for approval requests
  • Test: Server can track and expire approvals

Phase 2: Frontend Approval Card

  • Create approval-card.js component
  • Add CSS styling for three-button layout
  • Add expandable input for custom instructions
  • Integrate into handleWebSocketMessage()
  • Test: Card renders correctly, buttons work

Phase 3: Approval Flow

  • Wire Approve button → server
  • Wire Custom Instructions → expand → send custom command
  • Wire Reject → server
  • Test: Full round-trip approval

Phase 4: AI Integration

  • Modify AI to detect when approval needed
  • Send approval request instead of direct execution
  • Receive approval response and proceed
  • Test: AI properly requests and handles approvals

Files to Modify:

  • server.js - Add approval manager, WebSocket handlers
  • services/claude-service.js - Add requestApproval() method
  • public/claude-ide/chat-functions.js - Handle approval messages
  • public/claude-ide/components/approval-card.js - New component
  • public/claude-ide/components/approval-card.css - New styles

Testing Strategy:

  • Unit test approval manager
  • Integration test full approval flow
  • UI test card interactions
  • Test edge cases (timeout, custom commands, disconnects)

Success Criteria

  • Approval requests show interactive card with three buttons
  • Custom instructions option allows command modification
  • No accidental mode switching when responding to approvals
  • Pending approvals auto-expire after 5 minutes
  • AI maintains context through approval flow
  • Clear visual feedback throughout process

Future Enhancements

  • Approval history log
  • Bulk approval for batch operations
  • Approval templates for common command patterns
  • User preferences (auto-approve safe commands)
  • Approval notifications across multiple sessions