From 82b8fcc6089bb993153a62bbdf32bb05cc10066e Mon Sep 17 00:00:00 2001 From: catlog22 Date: Wed, 21 Jan 2026 18:32:52 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20=E5=A2=9E=E5=8A=A0=E5=A4=B1=E8=B4=A5?= =?UTF-8?q?=E5=8E=86=E5=8F=B2=E8=AF=A6=E6=83=85=E6=B8=B2=E6=9F=93=E5=8A=9F?= =?UTF-8?q?=E8=83=BD=EF=BC=8C=E5=B1=95=E7=A4=BA=E5=A4=B1=E8=B4=A5=E5=8F=8D?= =?UTF-8?q?=E9=A6=88=E4=BF=A1=E6=81=AF?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../dashboard-css/32-issue-manager.css | 73 +++++++++++++++++++ .../dashboard-js/views/issue-manager.js | 71 +++++++++++++++++- 2 files changed, 142 insertions(+), 2 deletions(-) diff --git a/ccw/src/templates/dashboard-css/32-issue-manager.css b/ccw/src/templates/dashboard-css/32-issue-manager.css index b28690f6..e7b8d6f0 100644 --- a/ccw/src/templates/dashboard-css/32-issue-manager.css +++ b/ccw/src/templates/dashboard-css/32-issue-manager.css @@ -331,6 +331,79 @@ word-break: break-word; } +/* Failure History Detail */ +.failure-history-list { + display: flex; + flex-direction: column; + gap: 0.75rem; +} + +.failure-history-item { + padding: 0.75rem; + background: hsl(var(--destructive) / 0.06); + border: 1px solid hsl(var(--destructive) / 0.15); + border-radius: 0.5rem; +} + +.failure-history-header { + display: flex; + align-items: center; + gap: 0.5rem; + margin-bottom: 0.5rem; + color: hsl(var(--destructive)); +} + +.failure-history-count { + font-size: 0.875rem; + font-weight: 500; +} + +.failure-history-timestamp { + margin-left: auto; +} + +.failure-history-content { + display: flex; + flex-direction: column; + gap: 0.375rem; + padding-left: 0.5rem; +} + +.failure-history-task, +.failure-history-error { + display: flex; + align-items: center; + gap: 0.375rem; +} + +.failure-history-message pre { + margin: 0; + white-space: pre-wrap; +} + +.failure-history-stacktrace { + margin-top: 0.375rem; +} + +.failure-history-stacktrace summary { + margin-bottom: 0.25rem; +} + +.failure-history-stacktrace pre { + margin: 0; + background: hsl(var(--background)); + padding: 0.5rem; + border-radius: 0.25rem; + border: 1px solid hsl(var(--border)); +} + +.detail-label-sm { + font-size: 0.75rem; + font-weight: 500; + color: hsl(var(--muted-foreground)); + min-width: 60px; +} + /* Priority Badges */ .issue-priority { display: inline-flex; diff --git a/ccw/src/templates/dashboard-js/views/issue-manager.js b/ccw/src/templates/dashboard-js/views/issue-manager.js index 4079ef7b..e0a3d677 100644 --- a/ccw/src/templates/dashboard-js/views/issue-manager.js +++ b/ccw/src/templates/dashboard-js/views/issue-manager.js @@ -431,8 +431,6 @@ function renderIssueCard(issue) { Archived on ${archivedDate} ` : ''} - - ${renderFailureInfo(issue)} `; } @@ -479,6 +477,72 @@ function renderFailureInfo(issue) { `; } +function renderFailureHistoryDetail(issue) { + // Check if issue has failure feedback + if (!issue.feedback || issue.feedback.length === 0) { + return ''; + } + + // Extract failure feedbacks + const failures = issue.feedback.filter(f => f.type === 'failure' && f.stage === 'execute'); + if (failures.length === 0) { + return ''; + } + + return ` +
+ +
+ ${failures.map((failure, index) => { + let failureDetail; + try { + failureDetail = JSON.parse(failure.content); + } catch { + return ''; + } + + const errorMessage = failureDetail.message || 'Unknown error'; + const errorType = failureDetail.error_type || 'error'; + const taskId = failureDetail.task_id; + const timestamp = failure.created_at ? new Date(failure.created_at).toLocaleString() : 'Unknown time'; + + return ` +
+
+ + Failure ${index + 1} + ${timestamp} +
+
+ ${taskId ? ` +
+ Task: + ${taskId} +
+ ` : ''} +
+ Error Type: + ${errorType} +
+
+ Message: +
${escapeHtml(errorMessage)}
+
+ ${failureDetail.stack_trace ? ` +
+ Show Stack Trace +
${escapeHtml(failureDetail.stack_trace)}
+
+ ` : ''} +
+
+ `; + }).join('')} +
+
+ `; +} + // Helper: Truncate text to max length function truncateText(text, maxLength) { if (!text || text.length <= maxLength) return text; @@ -1691,6 +1755,9 @@ function renderIssueDetailPanel(issue) { + + ${renderFailureHistoryDetail(issue)} +