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

277 lines
8.3 KiB
Markdown

# 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:**
```json
{
"type": "approval-response",
"id": "approval-123456",
"approved": true,
"sessionId": "session-abc"
}
```
**Custom Instructions Response:**
```json
{
"type": "approval-response",
"id": "approval-123456",
"approved": true,
"customCommand": "ping google.com -c 3",
"sessionId": "session-abc"
}
```
**Reject Response:**
```json
{
"type": "approval-response",
"id": "approval-123456",
"approved": false,
"sessionId": "session-abc"
}
```
### 3. State Management
**Pending Approvals Manager** (Server-side):
```javascript
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`**
```javascript
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)**
```javascript
// In handleWebSocketMessage():
if (data.type === 'approval-request') {
renderApprovalCard(data);
return;
}
```
**Backend Components:**
**`server.js`**
```javascript
class PendingApprovalsManager {
// Manages pending approval state
}
// WebSocket handlers for approval-request and approval-response
```
**`services/claude-service.js`**
```javascript
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
- [x] Approval requests show interactive card with three buttons
- [x] Custom instructions option allows command modification
- [x] No accidental mode switching when responding to approvals
- [x] Pending approvals auto-expire after 5 minutes
- [x] AI maintains context through approval flow
- [x] 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