mirror of
https://github.com/catlog22/Claude-Code-Workflow.git
synced 2026-02-05 01:50:27 +08:00
feat: 增加失败历史详情渲染功能,展示失败反馈信息
This commit is contained in:
@@ -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;
|
||||
|
||||
@@ -431,8 +431,6 @@ function renderIssueCard(issue) {
|
||||
<span>Archived on ${archivedDate}</span>
|
||||
</div>
|
||||
` : ''}
|
||||
|
||||
${renderFailureInfo(issue)}
|
||||
</div>
|
||||
`;
|
||||
}
|
||||
@@ -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 `
|
||||
<div class="detail-section">
|
||||
<label class="detail-label">${t('issues.failureHistory') || 'Failure History'} (${failures.length})</label>
|
||||
<div class="failure-history-list">
|
||||
${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 `
|
||||
<div class="failure-history-item">
|
||||
<div class="failure-history-header">
|
||||
<i data-lucide="alert-circle" class="w-4 h-4"></i>
|
||||
<span class="failure-history-count">Failure ${index + 1}</span>
|
||||
<span class="failure-history-timestamp text-xs text-muted-foreground">${timestamp}</span>
|
||||
</div>
|
||||
<div class="failure-history-content">
|
||||
${taskId ? `
|
||||
<div class="failure-history-task">
|
||||
<span class="detail-label-sm">Task:</span>
|
||||
<span class="font-mono text-xs">${taskId}</span>
|
||||
</div>
|
||||
` : ''}
|
||||
<div class="failure-history-error">
|
||||
<span class="detail-label-sm">Error Type:</span>
|
||||
<span class="font-mono text-xs">${errorType}</span>
|
||||
</div>
|
||||
<div class="failure-history-message">
|
||||
<span class="detail-label-sm">Message:</span>
|
||||
<pre class="detail-pre text-xs">${escapeHtml(errorMessage)}</pre>
|
||||
</div>
|
||||
${failureDetail.stack_trace ? `
|
||||
<details class="failure-history-stacktrace">
|
||||
<summary class="cursor-pointer text-xs text-muted-foreground">Show Stack Trace</summary>
|
||||
<pre class="detail-pre text-xs mt-1 max-h-60 overflow-auto">${escapeHtml(failureDetail.stack_trace)}</pre>
|
||||
</details>
|
||||
` : ''}
|
||||
</div>
|
||||
</div>
|
||||
`;
|
||||
}).join('')}
|
||||
</div>
|
||||
</div>
|
||||
`;
|
||||
}
|
||||
|
||||
// Helper: Truncate text to max length
|
||||
function truncateText(text, maxLength) {
|
||||
if (!text || text.length <= maxLength) return text;
|
||||
@@ -1691,6 +1755,9 @@ function renderIssueDetailPanel(issue) {
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Failure History -->
|
||||
${renderFailureHistoryDetail(issue)}
|
||||
|
||||
<!-- Solutions -->
|
||||
<div class="detail-section">
|
||||
<label class="detail-label">${t('issues.solutions') || 'Solutions'} (${issue.solutions?.length || 0})</label>
|
||||
|
||||
Reference in New Issue
Block a user