diff --git a/packages/vscode-ide-companion/src/webview/components/PermissionDrawer.css b/packages/vscode-ide-companion/src/webview/components/PermissionDrawer.css index 9f1f1920..f78223d0 100644 --- a/packages/vscode-ide-companion/src/webview/components/PermissionDrawer.css +++ b/packages/vscode-ide-companion/src/webview/components/PermissionDrawer.css @@ -154,3 +154,319 @@ } } +/* =========================================== + Permission Request Card Styles + =========================================== */ + +.permission-request-card { + background: var(--app-primary-background); + border-radius: 8px; + padding: 16px; +} + +.permission-card-body { + display: flex; + flex-direction: column; + gap: 16px; +} + +/* Permission Header */ +.permission-header { + display: flex; + align-items: flex-start; + gap: 12px; +} + +.permission-icon-wrapper { + flex-shrink: 0; +} + +.permission-icon { + font-size: 24px; + line-height: 1; +} + +.permission-info { + flex: 1; + display: flex; + flex-direction: column; + gap: 4px; +} + +.permission-title { + font-size: 14px; + font-weight: 500; + color: var(--app-primary-foreground); + line-height: 1.5; + word-break: break-word; +} + +.permission-subtitle { + font-size: 12px; + color: var(--app-secondary-foreground); + opacity: 0.7; +} + +/* Command Section - Bash style */ +.permission-command-section { + display: flex; + flex-direction: column; + gap: 8px; + background: var(--app-secondary-background); + border: 1px solid var(--app-transparent-inner-border); + border-radius: 6px; + overflow: hidden; +} + +.permission-command-header { + display: flex; + align-items: center; + padding: 8px 12px; + background: var(--app-secondary-background); + border-bottom: 1px solid var(--app-transparent-inner-border); +} + +.permission-command-status { + display: flex; + align-items: center; + gap: 6px; +} + +.permission-command-dot { + color: var(--app-qwen-orange, #ff8c00); + font-size: 8px; + line-height: 1; +} + +.permission-command-label { + font-size: 11px; + font-weight: 600; + color: var(--app-secondary-foreground); + text-transform: uppercase; + letter-spacing: 0.5px; +} + +.permission-command-content { + display: flex; + flex-direction: column; + gap: 0; +} + +.permission-command-input-section { + display: grid; + grid-template-columns: 32px 1fr; + align-items: flex-start; + padding: 8px 0; + background: var(--app-primary-background); +} + +.permission-command-io-label { + font-size: 11px; + font-weight: 600; + color: var(--app-secondary-foreground); + opacity: 0.6; + text-align: right; + padding-right: 12px; + padding-top: 2px; +} + +.permission-command-code { + font-family: var(--vscode-editor-font-family, 'Monaco', 'Courier New', monospace); + font-size: 12px; + line-height: 1.6; + color: var(--app-primary-foreground); + background: transparent; + border: none; + padding: 0 12px 0 0; + white-space: pre-wrap; + word-break: break-word; + overflow-wrap: break-word; +} + +.permission-command-description { + font-size: 12px; + color: var(--app-secondary-foreground); + opacity: 0.7; + padding: 8px 12px; + border-top: 1px solid var(--app-transparent-inner-border); + background: var(--app-secondary-background); +} + +/* Locations Section */ +.permission-locations-section { + display: flex; + flex-direction: column; + gap: 6px; +} + +.permission-locations-label { + font-size: 12px; + font-weight: 500; + color: var(--app-secondary-foreground); + opacity: 0.8; +} + +.permission-location-item { + display: flex; + align-items: center; + gap: 6px; + padding: 6px 8px; + background: var(--app-secondary-background); + border-radius: 4px; + font-size: 12px; +} + +.permission-location-icon { + font-size: 14px; + flex-shrink: 0; +} + +.permission-location-path { + flex: 1; + color: var(--app-primary-foreground); + font-family: var(--vscode-editor-font-family, 'Monaco', 'Courier New', monospace); + overflow: hidden; + text-overflow: ellipsis; + white-space: nowrap; +} + +.permission-location-line { + color: var(--app-secondary-foreground); + opacity: 0.6; + font-family: var(--vscode-editor-font-family, 'Monaco', 'Courier New', monospace); +} + +/* Options Section */ +.permission-options-section { + display: flex; + flex-direction: column; + gap: 12px; +} + +.permission-options-label { + font-size: 12px; + font-weight: 500; + color: var(--app-secondary-foreground); + opacity: 0.8; +} + +.permission-options-list { + display: flex; + flex-direction: column; + gap: 6px; +} + +.permission-option { + display: flex; + align-items: center; + gap: 8px; + padding: 10px 12px; + background: var(--app-secondary-background); + border: 1px solid var(--app-transparent-inner-border); + border-radius: 6px; + cursor: pointer; + transition: all 0.15s; +} + +.permission-option:hover { + background: var(--app-ghost-button-hover-background); + border-color: var(--app-primary-border-color); +} + +.permission-option.selected { + background: var(--app-qwen-clay-button-orange); + border-color: var(--app-qwen-orange, #ff8c00); +} + +.permission-radio { + width: 16px; + height: 16px; + margin: 0; + cursor: pointer; +} + +.permission-option-content { + flex: 1; + display: flex; + align-items: center; + gap: 6px; + font-size: 13px; + color: var(--app-primary-foreground); +} + +.permission-option-number { + display: inline-flex; + align-items: center; + justify-content: center; + width: 20px; + height: 20px; + background: var(--app-qwen-orange, #ff8c00); + color: var(--app-qwen-ivory, #fff); + border-radius: 4px; + font-size: 11px; + font-weight: 600; + flex-shrink: 0; +} + +.permission-always-badge { + font-size: 14px; + flex-shrink: 0; +} + +.permission-no-options { + padding: 12px; + text-align: center; + color: var(--app-secondary-foreground); + opacity: 0.6; + font-size: 12px; +} + +/* Actions */ +.permission-actions { + display: flex; + justify-content: flex-end; + gap: 8px; + padding-top: 8px; +} + +.permission-confirm-button { + padding: 8px 16px; + background: var(--app-qwen-orange, #ff8c00); + color: var(--app-qwen-ivory, #fff); + border: none; + border-radius: 6px; + font-size: 13px; + font-weight: 500; + cursor: pointer; + transition: all 0.15s; +} + +.permission-confirm-button:hover:not(:disabled) { + opacity: 0.9; +} + +.permission-confirm-button:disabled { + opacity: 0.5; + cursor: not-allowed; +} + +/* Success Message */ +.permission-success { + display: flex; + align-items: center; + gap: 8px; + padding: 12px; + background: var(--app-qwen-green, #6BCF7F); + color: var(--app-qwen-ivory, #fff); + border-radius: 6px; + font-size: 13px; +} + +.permission-success-icon { + font-size: 16px; + flex-shrink: 0; +} + +.permission-success-text { + flex: 1; +} diff --git a/packages/vscode-ide-companion/src/webview/components/PermissionRequest.tsx b/packages/vscode-ide-companion/src/webview/components/PermissionRequest.tsx index 3671b974..8aa63de1 100644 --- a/packages/vscode-ide-companion/src/webview/components/PermissionRequest.tsx +++ b/packages/vscode-ide-companion/src/webview/components/PermissionRequest.tsx @@ -117,10 +117,25 @@ export const PermissionRequest: React.FC = ({ {/* Show command if available */} {(toolCall.rawInput?.command || toolCall.title) && (
-
Command
- - {toolCall.rawInput?.command || toolCall.title} - +
+
+ + COMMAND +
+
+
+
+ IN + + {toolCall.rawInput?.command || toolCall.title} + +
+ {toolCall.rawInput?.description && ( +
+ {toolCall.rawInput.description} +
+ )} +
)} diff --git a/packages/vscode-ide-companion/src/webview/components/PlanDisplay.css b/packages/vscode-ide-companion/src/webview/components/PlanDisplay.css index eed90c21..33413b26 100644 --- a/packages/vscode-ide-companion/src/webview/components/PlanDisplay.css +++ b/packages/vscode-ide-companion/src/webview/components/PlanDisplay.css @@ -6,65 +6,54 @@ /** * PlanDisplay.css - Styles for the task plan component - * Simple, clean timeline-style design + * Clean checklist-style design matching Claude Code CLI */ .plan-display { - background: var(--app-secondary-background); - border: 1px solid var(--app-transparent-inner-border); - border-radius: var(--corner-radius-medium); - padding: 16px; - margin: 12px 0; - animation: fadeIn 0.3s ease-in; + background: transparent; + border: none; + padding: 8px 16px; + margin: 8px 0; } .plan-header { display: flex; align-items: center; - gap: 8px; - margin-bottom: 16px; - color: var(--app-primary-foreground); + gap: 6px; + margin-bottom: 8px; } -.plan-header-icon { +.plan-progress-icons { + display: flex; + align-items: center; + gap: 2px; +} + +.plan-progress-icon { flex-shrink: 0; - opacity: 0.8; + color: var(--app-secondary-foreground); + opacity: 0.6; } .plan-title { - font-size: 14px; - font-weight: 600; - color: var(--app-primary-foreground); + font-size: 12px; + font-weight: 400; + color: var(--app-secondary-foreground); + opacity: 0.8; } .plan-entries { display: flex; flex-direction: column; - gap: 0; - position: relative; + gap: 1px; } .plan-entry { display: flex; - align-items: flex-start; - gap: 12px; - padding: 8px 0; - position: relative; -} - -/* Vertical line on the left */ -.plan-entry-line { - position: absolute; - left: 7px; - top: 24px; - bottom: -8px; - width: 2px; - background: var(--app-qwen-clay-button-orange); - opacity: 0.3; -} - -.plan-entry:last-child .plan-entry-line { - display: none; + align-items: center; + gap: 8px; + padding: 3px 0; + min-height: 20px; } /* Icon container */ @@ -73,60 +62,62 @@ display: flex; align-items: center; justify-content: center; - width: 16px; - height: 16px; - position: relative; - z-index: 1; + width: 14px; + height: 14px; } .plan-icon { display: block; + width: 14px; + height: 14px; +} + +/* 不同状态的图标颜色 */ +.plan-icon.pending { + color: var(--app-secondary-foreground); + opacity: 0.35; +} + +.plan-icon.in-progress { + color: var(--app-secondary-foreground); + opacity: 0.7; +} + +.plan-icon.completed { + color: #4caf50; /* 绿色勾号 */ + opacity: 0.8; } /* Content */ .plan-entry-content { flex: 1; display: flex; - align-items: flex-start; - gap: 8px; - min-height: 24px; - padding-top: 1px; -} - -.plan-entry-number { - font-size: 13px; - font-weight: 500; - color: var(--app-secondary-foreground); - flex-shrink: 0; - min-width: 24px; + align-items: center; } .plan-entry-text { flex: 1; - font-size: 13px; - line-height: 1.6; + font-size: 12px; + line-height: 1.5; color: var(--app-primary-foreground); + opacity: 0.85; } /* Status-specific styles */ .plan-entry.completed .plan-entry-text { - opacity: 0.6; + opacity: 0.5; text-decoration: line-through; } .plan-entry.in_progress .plan-entry-text { - font-weight: 500; -} - -.plan-entry.in_progress .plan-entry-number { - color: var(--app-qwen-orange); - font-weight: 600; + font-weight: 400; + opacity: 0.9; } @keyframes fadeIn { from { opacity: 0; - transform: translateY(-8px); + transform: translateY(-4px); } to { opacity: 1; diff --git a/packages/vscode-ide-companion/src/webview/components/PlanDisplay.tsx b/packages/vscode-ide-companion/src/webview/components/PlanDisplay.tsx index ba97d841..2e0f2b58 100644 --- a/packages/vscode-ide-companion/src/webview/components/PlanDisplay.tsx +++ b/packages/vscode-ide-companion/src/webview/components/PlanDisplay.tsx @@ -21,77 +21,67 @@ interface PlanDisplayProps { * PlanDisplay component - displays AI's task plan/todo list */ export const PlanDisplay: React.FC = ({ entries }) => { - const getStatusIcon = (status: string, _index: number) => { + // 计算完成进度 + const completedCount = entries.filter((e) => e.status === 'completed').length; + const totalCount = entries.length; + + const getStatusIcon = (status: string) => { switch (status) { - case 'in_progress': - return ( - - - - - ); case 'completed': return ( - + ); - default: + case 'in_progress': return ( + + + ); + default: + // pending + return ( + - ); @@ -101,41 +91,49 @@ export const PlanDisplay: React.FC = ({ entries }) => { return (
- - + - - - Task Plan + className="plan-progress-icon" + > + + + + + + +
+ + {completedCount} of {totalCount} Done +
{entries.map((entry, index) => (
-
-
- {getStatusIcon(entry.status, index)} -
+
{getStatusIcon(entry.status)}
- {index + 1}. {entry.content}