From 5693d6e6f5da7b836a88483e75e8c2d8c45ddbb2 Mon Sep 17 00:00:00 2001 From: Hamhire Hu Date: Tue, 23 Jun 2026 13:38:59 +0800 Subject: [PATCH 01/14] =?UTF-8?q?fix(ask):=20=E5=A4=8D=E8=AF=84=E5=BC=95?= =?UTF-8?q?=E7=94=A8=E5=BE=BD=E6=A0=87=E8=A1=8C=E5=8F=B7=E8=B7=9F=E9=9A=8F?= =?UTF-8?q?=E8=B7=AF=E5=BE=84=E6=9C=AB=E8=A1=8C=E8=80=8C=E9=9D=9E=E5=8F=A6?= =?UTF-8?q?=E8=B5=B7=E4=B8=80=E8=A1=8C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 定位路径过长换行时,路径(code)与行号(span)作为各自独立的 flex 项,行号被挤到第三行左侧。 改为定位文本以行内文本流排版(非 flex),路径与行号连续换行——行号紧跟路径末行(path:line), 首行仍与图标同排。 Co-Authored-By: Claude Opus 4.8 --- .../src/renderer/src/styles/features/chat/run.scss | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/apps/desktop/src/renderer/src/styles/features/chat/run.scss b/apps/desktop/src/renderer/src/styles/features/chat/run.scss index a6444a92..814529c8 100644 --- a/apps/desktop/src/renderer/src/styles/features/chat/run.scss +++ b/apps/desktop/src/renderer/src/styles/features/chat/run.scss @@ -297,11 +297,9 @@ margin-top: 2px; } .chat-run-ref-loc { - display: inline-flex; - // 路径过长在定位文本内部换行(首行仍与图标同排),而非整体掉到图标下一行。 - flex-wrap: wrap; - align-items: baseline; - gap: $space-1; + // 行内文本流(非 flex):路径与行号作为连续行内内容换行——行号紧跟路径末行,而非作为独立 flex + // 项掉到新行。作为徽标 flex 子项 display 被 blockify 为块、占余宽并在内部换行(首行仍与图标同排)。 + display: block; min-width: 0; flex: 1 1 auto; } From 91d6163157a779c83363d304029c2b10d7432323 Mon Sep 17 00:00:00 2001 From: Hamhire Hu Date: Tue, 23 Jun 2026 13:44:21 +0800 Subject: [PATCH 02/14] =?UTF-8?q?fix(ask):=20=E5=AE=9A=E4=BD=8D=E5=8E=9F?= =?UTF-8?q?=20finding=20=E5=8D=A1=E7=89=87=E7=94=A8=E8=A6=86=E7=9B=96?= =?UTF-8?q?=E5=BC=8F=E9=AB=98=E4=BA=AE=EF=BC=8C=E5=8C=BA=E5=88=86=E5=90=AF?= =?UTF-8?q?=E7=94=A8/=E5=85=B3=E9=97=AD=E8=89=B2=E7=9B=B8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 点击复评引用徽标定位到原 finding 卡片时背景渐隐高亮看不出来——finding 卡有实底 $bg-elev, 背景渐隐(chat-run-flash)会被洗掉。改用与卡片底色无关的「覆盖式高亮环 + inset 淡色填充」 (chat-finding-flash),任意底色都清晰可见;启用卡用主蓝、已关闭/拒绝卡用中性灰,色相区分两类 状态。run 级定位(查看复评)仍沿用背景渐隐。 Co-Authored-By: Claude Opus 4.8 --- .../src/components/features/chat/ChatPane.tsx | 17 ++++++---- .../src/styles/features/chat/findings.scss | 34 +++++++++++++++++++ 2 files changed, 44 insertions(+), 7 deletions(-) diff --git a/apps/desktop/src/renderer/src/components/features/chat/ChatPane.tsx b/apps/desktop/src/renderer/src/components/features/chat/ChatPane.tsx index 9248efd0..2c728b43 100644 --- a/apps/desktop/src/renderer/src/components/features/chat/ChatPane.tsx +++ b/apps/desktop/src/renderer/src/components/features/chat/ChatPane.tsx @@ -212,23 +212,26 @@ export function ChatPane({ const { runs, error, loadingSession, matchedRule, bodyRef, hasMoreOlder, loadingOlder } = session; - // 复评卡 ↔ 原 finding 卡互链:按 data-run-id 在时间线里滚动定位 + 短暂高亮。 - const flash = (el: Element): void => { + // 复评卡 ↔ 原 finding 卡互链:滚动定位 + 短暂高亮。flash class 因目标而异:run 卡用 chat-run-flash + // (背景渐隐,run 卡本身透明底可见);finding 卡用 chat-finding-flash(覆盖式高亮环——finding 卡有 + // 实底 $bg-elev,背景渐隐会被洗掉、看不出闪烁)。 + const flash = (el: Element, cls: 'chat-run-flash' | 'chat-finding-flash'): void => { el.scrollIntoView({ behavior: 'smooth', block: 'center' }); - el.classList.add('chat-run-flash'); - window.setTimeout(() => el.classList.remove('chat-run-flash'), 1500); + el.classList.add(cls); + window.setTimeout(() => el.classList.remove(cls), 1600); }; const scrollToRun = (runId: string): void => { const el = bodyRef.current?.querySelector(`[data-run-id="${CSS.escape(runId)}"]`); - if (el) flash(el); + if (el) flash(el, 'chat-run-flash'); }; // 点击复评卡顶部引用徽标:精确定位到原 run 内被引用的那条 finding 卡片并闪烁高亮(找不到该卡片—— // 如已分页移出 / 折叠——回退到整条 run 高亮,至少给出定位反馈)。 const scrollToFinding = (runId: string, findingId: string): void => { const runEl = bodyRef.current?.querySelector(`[data-run-id="${CSS.escape(runId)}"]`); if (!runEl) return; - const el = runEl.querySelector(`[data-finding-id="${CSS.escape(findingId)}"]`) ?? runEl; - flash(el); + const findingEl = runEl.querySelector(`[data-finding-id="${CSS.escape(findingId)}"]`); + if (findingEl) flash(findingEl, 'chat-finding-flash'); + else flash(runEl, 'chat-run-flash'); }; return ( diff --git a/apps/desktop/src/renderer/src/styles/features/chat/findings.scss b/apps/desktop/src/renderer/src/styles/features/chat/findings.scss index 4c83d3ca..85a7de34 100644 --- a/apps/desktop/src/renderer/src/styles/features/chat/findings.scss +++ b/apps/desktop/src/renderer/src/styles/features/chat/findings.scss @@ -62,6 +62,40 @@ opacity: 0.68; } } + +// 点击复评引用徽标定位到原 finding 卡片时的短暂高亮:用「覆盖式高亮环 + inset 淡色填充」而非背景渐隐 +// ——finding 卡有实底 $bg-elev,背景渐隐会被洗掉看不出闪烁;覆盖式与卡片底色无关、任意底色都清晰可见, +// 动画结束自动回落(fill-mode 默认 none)。启用卡用主蓝、已关闭/拒绝卡用中性灰,色相区分两类状态。 +.chat-finding-flash { + animation: chat-finding-flash-kf 1.5s ease-out; +} +@keyframes chat-finding-flash-kf { + 0% { + box-shadow: + 0 0 0 2px $color-accent, + inset 0 0 0 9999px $color-accent-bg-fade; + } + 100% { + box-shadow: + 0 0 0 2px transparent, + inset 0 0 0 9999px transparent; + } +} +.chat-finding-rejected.chat-finding-flash { + animation-name: chat-finding-flash-closed-kf; +} +@keyframes chat-finding-flash-closed-kf { + 0% { + box-shadow: + 0 0 0 2px $text-muted, + inset 0 0 0 9999px rgba($text-muted, 0.18); + } + 100% { + box-shadow: + 0 0 0 2px transparent, + inset 0 0 0 9999px transparent; + } +} .chat-finding-head { display: flex; align-items: center; From e45746eab6dc00ce60969803023da63dfead7702 Mon Sep 17 00:00:00 2001 From: Hamhire Hu Date: Tue, 23 Jun 2026 13:53:10 +0800 Subject: [PATCH 03/14] =?UTF-8?q?fix(agent):=20=E5=88=A4=E5=AE=9A=E8=A7=A3?= =?UTF-8?q?=E6=9E=90=E5=A4=B1=E8=B4=A5=E7=9A=84=E5=85=9C=E5=BA=95=E4=B8=8D?= =?UTF-8?q?=E5=86=8D=E8=BE=93=E5=87=BA=E3=80=8C=E6=97=A0=E6=B3=95=E8=A7=A3?= =?UTF-8?q?=E6=9E=90=E5=BB=BA=E8=AE=AE=E3=80=8D=E7=81=B0=E5=AD=97?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 走到 manual_review 解析兜底时,理由文案对用户无价值。改为兜底 reason 置空——前端按空 reason 隐藏灰字(ConversationMessage 已有 `reason &&` 守卫),仅保留判定徽标。模型给出的合法 manual_review 理由仍照常展示。同步移除已无用的 parseFail label 与各 locale 文案。 Co-Authored-By: Claude Opus 4.8 --- apps/desktop/src/main/i18n/locales/de-DE.json | 1 - apps/desktop/src/main/i18n/locales/en-US.json | 1 - apps/desktop/src/main/i18n/locales/ja-JP.json | 1 - apps/desktop/src/main/i18n/locales/zh-CN.json | 1 - apps/desktop/src/main/services/agent/labels.ts | 1 - packages/agent/src/orchestrator.ts | 10 +++------- packages/agent/src/steps/review/summary-step.ts | 4 +++- 7 files changed, 6 insertions(+), 13 deletions(-) diff --git a/apps/desktop/src/main/i18n/locales/de-DE.json b/apps/desktop/src/main/i18n/locales/de-DE.json index 786a1abf..c321f76f 100644 --- a/apps/desktop/src/main/i18n/locales/de-DE.json +++ b/apps/desktop/src/main/i18n/locales/de-DE.json @@ -7,7 +7,6 @@ "judgeNone": "Keine wichtigen Probleme — keine Rückfrage", "judgeSevere_one": "Wichtig — {{count}} Rückfrage", "judgeSevere_other": "Wichtig — {{count}} Rückfragen", - "parseFail": "Empfehlung konnte nicht geparst werden — manuelle Prüfung", "rejectedPrefix": "Abgelehnt: ", "summary": "Beschreibung und Befunde zu einer Review-Zusammenfassung zusammenfassen" }, diff --git a/apps/desktop/src/main/i18n/locales/en-US.json b/apps/desktop/src/main/i18n/locales/en-US.json index e403349b..1e98f87b 100644 --- a/apps/desktop/src/main/i18n/locales/en-US.json +++ b/apps/desktop/src/main/i18n/locales/en-US.json @@ -7,7 +7,6 @@ "judgeNone": "No important issues — no follow-up", "judgeSevere_one": "Important — {{count}} follow-up question", "judgeSevere_other": "Important — {{count}} follow-up questions", - "parseFail": "Could not parse a recommendation — routing to manual review", "rejectedPrefix": "Rejected: ", "summary": "Synthesize the description and findings into a review summary" }, diff --git a/apps/desktop/src/main/i18n/locales/ja-JP.json b/apps/desktop/src/main/i18n/locales/ja-JP.json index 74c97412..b655b7a3 100644 --- a/apps/desktop/src/main/i18n/locales/ja-JP.json +++ b/apps/desktop/src/main/i18n/locales/ja-JP.json @@ -6,7 +6,6 @@ "judge": "追加質問が必要な重要な問題があるか判断", "judgeNone": "重要な問題なし、追加質問なし", "judgeSevere_other": "重要、追加質問 {{count}} 件", - "parseFail": "提案を解析できないため、手動レビューに回します", "rejectedPrefix": "却下:", "summary": "説明とレビュー指摘を統合してレビュー要約を生成" }, diff --git a/apps/desktop/src/main/i18n/locales/zh-CN.json b/apps/desktop/src/main/i18n/locales/zh-CN.json index 21ae5e36..34ab3bd6 100644 --- a/apps/desktop/src/main/i18n/locales/zh-CN.json +++ b/apps/desktop/src/main/i18n/locales/zh-CN.json @@ -6,7 +6,6 @@ "judge": "判断是否存在需追问的重要问题", "judgeNone": "无重要问题,不追问", "judgeSevere_other": "重要,追问 {{count}} 个", - "parseFail": "无法解析建议,转人工复核", "rejectedPrefix": "拒绝:", "summary": "综合描述与审查发现,生成评审总结" }, diff --git a/apps/desktop/src/main/services/agent/labels.ts b/apps/desktop/src/main/services/agent/labels.ts index f08d8983..510ccbda 100644 --- a/apps/desktop/src/main/services/agent/labels.ts +++ b/apps/desktop/src/main/services/agent/labels.ts @@ -16,7 +16,6 @@ export function buildStepLabels(): AgentStepLabels { judgeSevere: (n) => t('agent.steps.judgeSevere', { count: n }), judgeNone: t('agent.steps.judgeNone'), summary: t('agent.steps.summary'), - parseFail: t('agent.steps.parseFail'), rejectedPrefix: t('agent.steps.rejectedPrefix'), }; } diff --git a/packages/agent/src/orchestrator.ts b/packages/agent/src/orchestrator.ts index b6ca2171..402975ad 100644 --- a/packages/agent/src/orchestrator.ts +++ b/packages/agent/src/orchestrator.ts @@ -126,8 +126,6 @@ export interface AgentStepLabels { judgeNone: string; /** 收尾步思考。 */ summary: string; - /** 收尾建议解析失败、转人工复核的兜底理由。 */ - parseFail: string; /** 规划步:工具调用被红线拒绝的结果前缀(后接具体原因)。 */ rejectedPrefix: string; } @@ -139,7 +137,6 @@ export const DEFAULT_STEP_LABELS: AgentStepLabels = { judgeSevere: (n) => `Important — ${String(n)} follow-up question${n === 1 ? '' : 's'}`, judgeNone: 'No important issues — no follow-up', summary: 'Synthesize the description and findings into a review summary', - parseFail: 'Could not parse a recommendation — routing to manual review', rejectedPrefix: 'Rejected: ', }; @@ -185,10 +182,9 @@ export async function runReviewMicroflow( return { steps: rec.steps, summary: ctx.bag.summary ?? '', - recommendation: ctx.bag.recommendation ?? { - verdict: 'manual_review', - reason: labels.parseFail, - }, + // 兜底(收尾步未产出 recommendation):转人工复核、不带理由——解析失败的兜底无用户价值,前端按 + // 空 reason 隐藏灰字(与 summary-step 同口径)。 + recommendation: ctx.bag.recommendation ?? { verdict: 'manual_review', reason: '' }, tokenUsage: rec.usage, }; } diff --git a/packages/agent/src/steps/review/summary-step.ts b/packages/agent/src/steps/review/summary-step.ts index 9dd51078..a1df9845 100644 --- a/packages/agent/src/steps/review/summary-step.ts +++ b/packages/agent/src/steps/review/summary-step.ts @@ -40,10 +40,12 @@ export class SummaryStep extends Step { recommendation?: { verdict?: unknown; reason?: unknown }; }>(sum.text); const rec = obj?.recommendation ?? obj; + // 判定解析失败 → 转人工复核、不带理由:该兜底对用户无价值,前端按空 reason 隐藏灰字(不再输出 + // 「无法解析建议,转人工复核」)。模型给出的合法 manual_review 理由仍照常展示。 const recommendation: AgentRecommendation = rec && isVerdict(rec.verdict) ? { verdict: rec.verdict, reason: typeof rec.reason === 'string' ? rec.reason : '' } - : { verdict: 'manual_review', reason: ctx.labels.parseFail }; + : { verdict: 'manual_review', reason: '' }; ctx.bag.summary = summary; ctx.bag.recommendation = recommendation; await ctx.rec.record({ From 5c8e2d88a7a04f32a5d4decdb983954f1e0582ca Mon Sep 17 00:00:00 2001 From: Hamhire Hu Date: Tue, 23 Jun 2026 13:53:23 +0800 Subject: [PATCH 04/14] =?UTF-8?q?fix(ask):=20=E5=90=AF=E7=94=A8=E5=8D=A1?= =?UTF-8?q?=E5=AE=9A=E4=BD=8D=E9=97=AA=E7=83=81=E5=8F=96=E5=8D=A1=E7=89=87?= =?UTF-8?q?=E5=B7=A6=E6=9D=A1=E4=B8=BB=E9=A2=98=E8=89=B2=EF=BC=88=E9=9D=9E?= =?UTF-8?q?=E7=BB=9F=E4=B8=80=E8=93=9D=EF=BC=89?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 启用 finding 卡的定位高亮原先统一用主蓝,与卡片左条类别色不一致。改为高亮色 = 左条主题色 (--flash-color 按 sectionKey 取,逐一对应 border-left-color 分组):代码反馈/建议=橙黄、 元信息=蓝、概览/总结=绿、过程/评分=灰;已关闭/拒绝卡仍统一中性灰。 Co-Authored-By: Claude Opus 4.8 --- .../src/styles/features/chat/findings.scss | 50 ++++++++++++------- 1 file changed, 33 insertions(+), 17 deletions(-) diff --git a/apps/desktop/src/renderer/src/styles/features/chat/findings.scss b/apps/desktop/src/renderer/src/styles/features/chat/findings.scss index 85a7de34..afda0091 100644 --- a/apps/desktop/src/renderer/src/styles/features/chat/findings.scss +++ b/apps/desktop/src/renderer/src/styles/features/chat/findings.scss @@ -65,30 +65,46 @@ // 点击复评引用徽标定位到原 finding 卡片时的短暂高亮:用「覆盖式高亮环 + inset 淡色填充」而非背景渐隐 // ——finding 卡有实底 $bg-elev,背景渐隐会被洗掉看不出闪烁;覆盖式与卡片底色无关、任意底色都清晰可见, -// 动画结束自动回落(fill-mode 默认 none)。启用卡用主蓝、已关闭/拒绝卡用中性灰,色相区分两类状态。 +// 动画结束自动回落(fill-mode 默认 none)。高亮色 = 卡片左条主题色(--flash-color,按 sectionKey 取), +// 让定位反馈与卡片类别视觉一致(如代码建议=橙黄);已关闭/拒绝卡统一中性灰(盖过类别色)。 .chat-finding-flash { + --flash-color: #{$border-default}; animation: chat-finding-flash-kf 1.5s ease-out; } -@keyframes chat-finding-flash-kf { - 0% { - box-shadow: - 0 0 0 2px $color-accent, - inset 0 0 0 9999px $color-accent-bg-fade; - } - 100% { - box-shadow: - 0 0 0 2px transparent, - inset 0 0 0 9999px transparent; - } -} +// 类别色:与上面 .chat-finding 的 border-left-color 分组逐一对应。 +.chat-finding-title.chat-finding-flash, +.chat-finding-pr-type.chat-finding-flash, +.chat-finding-diagram.chat-finding-flash, +.chat-finding-assessment.chat-finding-flash, +.chat-finding-effort.chat-finding-flash { + --flash-color: #{$color-info}; +} +.chat-finding-summary.chat-finding-flash, +.chat-finding-description.chat-finding-flash, +.chat-finding-walkthrough.chat-finding-flash, +.chat-finding-relevant-tests.chat-finding-flash, +.chat-finding-security.chat-finding-flash, +.chat-finding-ask-summary.chat-finding-flash { + --flash-color: #{$color-approved}; +} +.chat-finding-score.chat-finding-flash, +.chat-finding-ask-analysis.chat-finding-flash { + --flash-color: #{$text-muted}; +} +.chat-finding-code-feedback.chat-finding-flash, +.chat-finding-code-suggestion.chat-finding-flash, +.chat-finding-ask-suggestions.chat-finding-flash { + --flash-color: #{$color-warning}; +} +// 已关闭/拒绝卡:统一中性灰(语义=非活跃,盖过类别色)。须置于类别规则之后以同特异性覆盖。 .chat-finding-rejected.chat-finding-flash { - animation-name: chat-finding-flash-closed-kf; + --flash-color: #{$text-muted}; } -@keyframes chat-finding-flash-closed-kf { +@keyframes chat-finding-flash-kf { 0% { box-shadow: - 0 0 0 2px $text-muted, - inset 0 0 0 9999px rgba($text-muted, 0.18); + 0 0 0 2px var(--flash-color), + inset 0 0 0 9999px color-mix(in srgb, var(--flash-color) 18%, transparent); } 100% { box-shadow: From 19705c49b917cf68e56a312e2a9281c07127e0af Mon Sep 17 00:00:00 2001 From: Hamhire Hu Date: Tue, 23 Jun 2026 14:02:48 +0800 Subject: [PATCH 05/14] =?UTF-8?q?fix(pr):=20diff=20=E5=A4=B4=E9=83=A8=20re?= =?UTF-8?q?viewer=20=E6=89=93=E5=8B=BE=E8=A7=92=E6=A0=87=E7=BC=A9=E5=B0=8F?= =?UTF-8?q?=E4=B8=80=E5=8F=B7=E5=B9=B6=E5=8E=BB=E9=99=A4=E6=8F=8F=E8=BE=B9?= =?UTF-8?q?=E7=8E=AF?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 状态角标(绿勾/琥珀叹号)尺寸 16→14、内部符号同步 16→14;去掉角标彩底的灰色描边环 (box-shadow),纯彩底靠颜色与头像区分。头像本身不变。 Co-Authored-By: Claude Opus 4.8 --- .../src/components/features/pr/ReviewerStack.tsx | 2 +- .../renderer/src/styles/features/pr/reviewer-stack.scss | 9 ++++----- 2 files changed, 5 insertions(+), 6 deletions(-) diff --git a/apps/desktop/src/renderer/src/components/features/pr/ReviewerStack.tsx b/apps/desktop/src/renderer/src/components/features/pr/ReviewerStack.tsx index 508a0849..516ba60c 100644 --- a/apps/desktop/src/renderer/src/components/features/pr/ReviewerStack.tsx +++ b/apps/desktop/src/renderer/src/components/features/pr/ReviewerStack.tsx @@ -91,7 +91,7 @@ export function ReviewerStack({ className={`reviewer-stack-badge reviewer-stack-badge-${r.status}`} aria-hidden="true" > - + )} diff --git a/apps/desktop/src/renderer/src/styles/features/pr/reviewer-stack.scss b/apps/desktop/src/renderer/src/styles/features/pr/reviewer-stack.scss index 3075a789..e7a0a9ea 100644 --- a/apps/desktop/src/renderer/src/styles/features/pr/reviewer-stack.scss +++ b/apps/desktop/src/renderer/src/styles/features/pr/reviewer-stack.scss @@ -21,25 +21,24 @@ display: inline-flex; } // 角标:钉在头像右上角(待评审无角标)。反色处理——实心彩色圆底 + 白色勾/叹号符号(此前是白底彩符, -// 白色面积过大不够醒目);外加与头像同款的灰色描边环($border-default 1px),与头像分隔且视觉一致。 +// 白色面积过大不够醒目)。无描边环(纯彩底,靠颜色与头像区分)。 .reviewer-stack-badge { position: absolute; top: -1px; right: -1px; - width: 16px; - height: 16px; + width: 14px; + height: 14px; display: inline-flex; align-items: center; justify-content: center; - // 实心彩色圆底(按状态着色,撑满角标)+ 头部底色外环分隔。 + // 实心彩色圆底(按状态着色,撑满角标)。 &::before { content: ''; position: absolute; inset: 0; border-radius: $radius-full; background: var(--reviewer-badge-color); - box-shadow: 0 0 0 1px $border-default; } svg { display: block; From 3faab6139b56cb3faa8d3c92c4e39f6bc62aca9b Mon Sep 17 00:00:00 2001 From: Hamhire Hu Date: Tue, 23 Jun 2026 14:08:49 +0800 Subject: [PATCH 06/14] =?UTF-8?q?feat(diff):=20=E5=B7=B2=E6=9C=89=E8=AF=84?= =?UTF-8?q?=E8=AE=BA=E7=9A=84=E8=A1=8C=E5=85=81=E8=AE=B8=E7=BB=A7=E7=BB=AD?= =?UTF-8?q?=E8=BF=BD=E5=8A=A0=E8=A1=8C=E5=86=85=E8=AF=84=E8=AE=BA?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 此前已有远端评论的行被算作「占用」、hover 不出 + 图标,无法在同一行继续追加评论。改为仅 「已有未发布草稿」的行才抑制 +(避免同行两个编辑器),已有远端评论的行照常 hover 出 +; 点击新建的草稿 zone 挂在评论 zone 之下(useCommentZones 先于 useDraftZones 挂载 → 草稿 ordinal 更大、渲染在已有评论下方),按时间序展示在已有评论下方。 Co-Authored-By: Claude Opus 4.8 --- .../features/pr/tabs/diff/DiffView.tsx | 1 - .../pr/tabs/diff/hooks/useLineCommentAdder.ts | 17 ++++++----------- 2 files changed, 6 insertions(+), 12 deletions(-) diff --git a/apps/desktop/src/renderer/src/components/features/pr/tabs/diff/DiffView.tsx b/apps/desktop/src/renderer/src/components/features/pr/tabs/diff/DiffView.tsx index e55b4b04..cbbd31a1 100644 --- a/apps/desktop/src/renderer/src/components/features/pr/tabs/diff/DiffView.tsx +++ b/apps/desktop/src/renderer/src/components/features/pr/tabs/diff/DiffView.tsx @@ -213,7 +213,6 @@ export function DiffView({ content, selected, drafts, - comments, prLocalId: pr.localId, platform: pr.platform, scopeKind: scope.kind, diff --git a/apps/desktop/src/renderer/src/components/features/pr/tabs/diff/hooks/useLineCommentAdder.ts b/apps/desktop/src/renderer/src/components/features/pr/tabs/diff/hooks/useLineCommentAdder.ts index 49ee14fe..e1bfe69e 100644 --- a/apps/desktop/src/renderer/src/components/features/pr/tabs/diff/hooks/useLineCommentAdder.ts +++ b/apps/desktop/src/renderer/src/components/features/pr/tabs/diff/hooks/useLineCommentAdder.ts @@ -1,7 +1,7 @@ import { useEffect } from 'react'; import { editor as MonacoEditorNs, type editor as MonacoEditor } from 'monaco-editor'; import type { TFunction } from 'i18next'; -import type { DiffHunkRange, PlatformKind, PrComment, ReviewDraft } from '@meebox/shared'; +import type { DiffHunkRange, PlatformKind, ReviewDraft } from '@meebox/shared'; import { policyForPlatform } from '@meebox/shared'; import type { DiffChangedFile } from '@meebox/ipc'; import { invoke } from '../../../../../../api'; @@ -9,8 +9,9 @@ import type { LoadedContent } from '../diff-types'; /** * 行 hover '+' 新建 manual 草稿:modifiedEditor (head 侧) + 并排视图下 originalEditor (base 侧) - * 上加 mousemove + mousedown 监听。已有评论 / 草稿的行不重复出 + glyph。点击 → drafts:create + - * autoEdit 立即进入编辑。 + * 上加 mousemove + mousedown 监听。**已有评论的行仍可继续追加**(hover 照常出 +,新草稿 zone 挂在评论 + * zone 之下、按时间序在已有评论下方);仅「已有未发布草稿」的行不重复出 +(避免同行两个编辑器)。点击 → + * drafts:create + autoEdit 立即进入编辑。 * * Platform policy 过滤:Bitbucket 只允许 hunk 内的行加 inline comment;GitHub/GitLab 宽松。从 * diffEditor.getLineChanges() 拿 hunks,不允许的行不画 glyph、点击也不创建草稿。commit 只读视图 @@ -21,7 +22,6 @@ export function useLineCommentAdder(opts: { content: LoadedContent | null; selected: DiffChangedFile | null; drafts: readonly ReviewDraft[] | null; - comments: PrComment[]; prLocalId: string; platform: PlatformKind; scopeKind: 'all' | 'commit'; @@ -34,7 +34,6 @@ export function useLineCommentAdder(opts: { content, selected, drafts, - comments, prLocalId, platform, scopeKind, @@ -49,13 +48,10 @@ export function useLineCommentAdder(opts: { if (scopeKind !== 'all') return; const modifiedEditor = diffEditor.getModifiedEditor(); const originalEditor = diffEditor.getOriginalEditor(); - // 已有评论 / 草稿占用的行,按侧分别记(避免在这些行额外显示 +) + // 仅「已有未发布草稿」的行算占用、不重复出 +(避免同行两个编辑器);已有远端评论的行不算占用—— + // 允许继续追加新评论(新草稿 zone 会挂在评论 zone 之下,按时间序展示在已有评论下方)。 const occupiedNew = new Set(); const occupiedOld = new Set(); - for (const c of comments) { - if (!c.anchor) continue; - (c.anchor.side === 'old' ? occupiedOld : occupiedNew).add(c.anchor.line); - } for (const d of drafts ?? []) { if (d.status === 'rejected') continue; // 跟 zone 创建时一致用 startLine — 之前用 endLine 会让 hover '+' 把行 403 @@ -208,7 +204,6 @@ export function useLineCommentAdder(opts: { content, selected, drafts, - comments, prLocalId, platform, t, From dc0ad79869be001f23d57f3571b04e1aa9ae10b2 Mon Sep 17 00:00:00 2001 From: Hamhire Hu Date: Tue, 23 Jun 2026 14:14:46 +0800 Subject: [PATCH 07/14] =?UTF-8?q?fix(chat):=20=E5=8F=AF=E6=8A=98=E5=8F=A0?= =?UTF-8?q?=20finding=20=E5=8D=A1=E6=94=B6=E8=B5=B7=E6=80=81=E4=B8=8A?= =?UTF-8?q?=E4=B8=8B=E5=AF=B9=E7=A7=B0=20+=20=E6=95=B4=E8=A1=8C=E6=A0=87?= =?UTF-8?q?=E9=A2=98=E5=8C=BA=E4=BD=9C=E6=8A=98=E5=8F=A0=E7=83=AD=E5=8C=BA?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 收起态头部归零 margin-bottom:正文隐藏后下方多出的间距导致上下不对称,归零后内边距对称。 - 可折叠卡(分析过程 / 已拒绝 / 被复评关闭的代码反馈)整行标题区即展开/收起热区,扩大可点 面积(不止右侧 chevron);忽略来自内部按钮(编辑/拒绝/引用/chevron)的点击避免误触。 Co-Authored-By: Claude Opus 4.8 --- .../features/chat/components/FindingCard.tsx | 15 ++++++++++++++- .../src/styles/features/chat/findings.scss | 8 ++++++++ 2 files changed, 22 insertions(+), 1 deletion(-) diff --git a/apps/desktop/src/renderer/src/components/features/chat/components/FindingCard.tsx b/apps/desktop/src/renderer/src/components/features/chat/components/FindingCard.tsx index f5e838a3..d1cad37a 100644 --- a/apps/desktop/src/renderer/src/components/features/chat/components/FindingCard.tsx +++ b/apps/desktop/src/renderer/src/components/features/chat/components/FindingCard.tsx @@ -252,7 +252,20 @@ export function FindingCard({ data-finding-id={finding.id} className={`chat-finding chat-finding-${key}${isRejected || isClosed ? ' chat-finding-rejected' : ''}${collapsed ? ' chat-finding-collapsed' : ''}`} > -
+
{ + if ((e.target as HTMLElement).closest('button')) return; + setExpanded((v) => !v); + } + : undefined + } + > {/* 已知 sectionKey 用中文标签 chip;general / 未知不显示,避免 UI 噪音 */} {label && ( diff --git a/apps/desktop/src/renderer/src/styles/features/chat/findings.scss b/apps/desktop/src/renderer/src/styles/features/chat/findings.scss index afda0091..1da60ade 100644 --- a/apps/desktop/src/renderer/src/styles/features/chat/findings.scss +++ b/apps/desktop/src/renderer/src/styles/features/chat/findings.scss @@ -118,6 +118,14 @@ gap: $space-3; margin-bottom: $space-3; } +// 收起态:正文已隐藏,头部的下间距会让卡片上下不对称(下方多出 margin-bottom)→ 归零,使上下内边距对称。 +.chat-finding-collapsed .chat-finding-head { + margin-bottom: 0; +} +// 可折叠卡:整行标题区即展开/收起热区(扩大可点面积,不止右侧 chevron)。 +.chat-finding-head-toggle { + cursor: pointer; +} // 分析解读(ask-analysis)展开时:chip 行下加一条分割线,与下方富文本内容(表格 / 代码块)衔接更自然, // 避免头部 chip 直接贴正文显得突兀。仅展开态(无 chat-finding-collapsed)出现。 .chat-finding-ask-analysis:not(.chat-finding-collapsed) .chat-finding-head { From 81b1eca23b0728bae7e5ec3f1f12a3294576c1ea Mon Sep 17 00:00:00 2001 From: Hamhire Hu Date: Tue, 23 Jun 2026 14:22:26 +0800 Subject: [PATCH 08/14] =?UTF-8?q?feat(chat):=20=E5=8F=AF=E6=8A=98=E5=8F=A0?= =?UTF-8?q?=20finding=20=E5=8D=A1=E6=8A=98=E5=8F=A0/=E5=B1=95=E5=BC=80?= =?UTF-8?q?=E9=AB=98=E5=BA=A6=E8=BF=87=E6=B8=A1=E5=8A=A8=E7=94=BB?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 正文 + 代码对比包进 grid 容器始终挂载,按 .chat-finding-collapsed 用 grid-template-rows 0fr↔1fr 做高度过渡(inner overflow:hidden 裁切),收/展平滑而非瞬时跳变;chevron 旋转已有 过渡。尊重系统「减少动效」关掉过渡。仅可折叠卡触发,其余卡恒展开无动画。 Co-Authored-By: Claude Opus 4.8 --- .../features/chat/components/FindingCard.tsx | 81 ++++++++++--------- .../src/styles/features/chat/findings.scss | 22 +++++ 2 files changed, 66 insertions(+), 37 deletions(-) diff --git a/apps/desktop/src/renderer/src/components/features/chat/components/FindingCard.tsx b/apps/desktop/src/renderer/src/components/features/chat/components/FindingCard.tsx index d1cad37a..24bf9e4a 100644 --- a/apps/desktop/src/renderer/src/components/features/chat/components/FindingCard.tsx +++ b/apps/desktop/src/renderer/src/components/features/chat/components/FindingCard.tsx @@ -364,43 +364,50 @@ export function FindingCard({ )} )} - {/* 已拒绝折叠态隐藏正文与代码对比,只留头部 chip + 锚点行 + 撤销入口。 - pr-type 的值胶囊已并入头部行(见上),此处不再单独成段。 */} - {!collapsed && key !== 'pr-type' && ( -
- {/* remarkBreaks 把 finding body 里的单换行也当成
。pr-agent 的 trace、 - 或一般段落里 reviewer 习惯按软换行折行,不加 remarkBreaks 会被 markdown - 合并成长一行。Findings 主要是富文本说明,不存在"故意软换行连接"的场景 */} - 的覆盖,使各文件分类默认折叠收起。 - components={key === 'walkthrough' ? walkthroughMdComponents : mermaidComponents} - > - {translatedBody} - -
- )} - {/* /improve 给的 existing → improved 代码对比。两段都是片段,独立
 块
-          + 红/绿背景 模拟 diff 视觉 (不用 Monaco DiffEditor 节省开销) */}
-      {!collapsed && finding.codeChange && (
-        
- {finding.codeChange.existing && ( -
-              {finding.codeChange.existing}
-            
- )} - {finding.codeChange.improved && ( -
-              {finding.codeChange.improved}
-            
- )} + {/* 可折叠内容(正文 + 代码对比):grid-rows 0fr↔1fr 平滑收展(auto 高度可动画)。内容始终挂载, + 由 CSS 按 .chat-finding-collapsed 收起、inner overflow:hidden 裁切——故折叠/展开有高度过渡动画。 + pr-type 的值胶囊已并入头部行、无正文段;无 codeChange 时整体不渲染。 */} + {(key !== 'pr-type' || finding.codeChange) && ( +
+
+ {key !== 'pr-type' && ( +
+ {/* remarkBreaks 把 finding body 里的单换行也当成
。pr-agent 的 trace、 + 或一般段落里 reviewer 习惯按软换行折行,不加 remarkBreaks 会被 markdown + 合并成长一行。Findings 主要是富文本说明,不存在"故意软换行连接"的场景 */} + 的覆盖,使各文件分类默认折叠收起。 + components={key === 'walkthrough' ? walkthroughMdComponents : mermaidComponents} + > + {translatedBody} + +
+ )} + {/* /improve 给的 existing → improved 代码对比。两段都是片段,独立
 块
+                + 红/绿背景 模拟 diff 视觉 (不用 Monaco DiffEditor 节省开销) */}
+            {finding.codeChange && (
+              
+ {finding.codeChange.existing && ( +
+                    {finding.codeChange.existing}
+                  
+ )} + {finding.codeChange.improved && ( +
+                    {finding.codeChange.improved}
+                  
+ )} +
+ )} +
)} diff --git a/apps/desktop/src/renderer/src/styles/features/chat/findings.scss b/apps/desktop/src/renderer/src/styles/features/chat/findings.scss index 1da60ade..48ae1540 100644 --- a/apps/desktop/src/renderer/src/styles/features/chat/findings.scss +++ b/apps/desktop/src/renderer/src/styles/features/chat/findings.scss @@ -126,6 +126,28 @@ .chat-finding-head-toggle { cursor: pointer; } +// 折叠/展开高度动画:grid-template-rows 0fr↔1fr(可对 auto 高度做过渡)。内容始终挂载,inner +// overflow:hidden + min-height:0 在收起时裁切——故收/展是平滑的高度过渡。仅可折叠卡会切到 +// collapsed → 0fr;其余卡恒 1fr、无动画。 +.chat-finding-collapsible { + display: grid; + grid-template-rows: 1fr; + transition: grid-template-rows 0.2s ease; +} +.chat-finding-collapsed .chat-finding-collapsible { + grid-template-rows: 0fr; +} +.chat-finding-collapsible-inner { + min-height: 0; + overflow: hidden; +} +// 尊重系统「减少动效」:关掉高度过渡与 chevron 旋转过渡。 +@media (prefers-reduced-motion: reduce) { + .chat-finding-collapsible, + .chat-finding-collapse-toggle svg { + transition: none; + } +} // 分析解读(ask-analysis)展开时:chip 行下加一条分割线,与下方富文本内容(表格 / 代码块)衔接更自然, // 避免头部 chip 直接贴正文显得突兀。仅展开态(无 chat-finding-collapsed)出现。 .chat-finding-ask-analysis:not(.chat-finding-collapsed) .chat-finding-head { From 85997c712ff5eb885e588ef37dc46740329cb23e Mon Sep 17 00:00:00 2001 From: Hamhire Hu Date: Tue, 23 Jun 2026 14:36:41 +0800 Subject: [PATCH 09/14] =?UTF-8?q?fix(chat):=20=E8=AF=84=E5=AE=A1=E6=80=BB?= =?UTF-8?q?=E7=BB=93=E5=8D=A1=E4=B8=8E=20finding=20=E5=8D=A1=E5=90=8C?= =?UTF-8?q?=E5=AE=BD=E5=B9=B6=E5=8A=A0=E8=93=9D=E8=89=B2=E5=B7=A6=E6=9D=A1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 去掉评审总结卡横向额外内缩(margin $space-6→0),与 finding 卡同宽(同处 chat-pane-body 的 $space-6 内边距内);加 3px 左侧色条,统一用蓝色,与卡片蓝色淡底成一套(不随判定变色)。 Co-Authored-By: Claude Opus 4.8 --- .../desktop/src/renderer/src/styles/features/chat/agent.scss | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/apps/desktop/src/renderer/src/styles/features/chat/agent.scss b/apps/desktop/src/renderer/src/styles/features/chat/agent.scss index 47a12947..fc283a6d 100644 --- a/apps/desktop/src/renderer/src/styles/features/chat/agent.scss +++ b/apps/desktop/src/renderer/src/styles/features/chat/agent.scss @@ -6,9 +6,12 @@ // === Agent 自动评审:触发条 + 收尾总结卡 === .chat-agent-summary { - margin: $space-4 $space-6; + // 横向不再额外内缩(去掉原 $space-6)——与 finding 卡同宽(二者同处 .chat-pane-body 的 $space-6 内边距内)。 + margin: $space-4 0; padding: $space-4 $space-5; border: 1px solid $border-muted; + // 左侧主题色条:统一用蓝色,与卡片蓝色淡底($color-accent-bg-fade)成一套(不随判定变色)。 + border-left: 3px solid $color-accent; border-radius: $radius-md; background: $color-accent-bg-fade; flex-shrink: 0; From 3ba6532844fdcb9654eeb8efe69dcf5e8957c4ae Mon Sep 17 00:00:00 2001 From: Hamhire Hu Date: Tue, 23 Jun 2026 14:36:57 +0800 Subject: [PATCH 10/14] =?UTF-8?q?fix(chat):=20=E5=8E=9F=E5=A7=8B=E8=BE=93?= =?UTF-8?q?=E5=87=BA=E6=8A=98=E5=8F=A0=E6=A0=87=E9=A2=98=E5=8E=BB=E6=8E=89?= =?UTF-8?q?=E3=80=8C(xx=20chars)=E3=80=8D=E5=AD=97=E6=95=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 字符数对用户无实际价值,标题简化为「原始输出」。各 locale 去掉 {{n}} 占位,调用处不再传 n。 Co-Authored-By: Claude Opus 4.8 --- .../src/components/features/chat/components/RunResultView.tsx | 2 +- apps/desktop/src/renderer/src/i18n/locales/de-DE.json | 2 +- apps/desktop/src/renderer/src/i18n/locales/en-US.json | 2 +- apps/desktop/src/renderer/src/i18n/locales/ja-JP.json | 2 +- apps/desktop/src/renderer/src/i18n/locales/zh-CN.json | 2 +- 5 files changed, 5 insertions(+), 5 deletions(-) diff --git a/apps/desktop/src/renderer/src/components/features/chat/components/RunResultView.tsx b/apps/desktop/src/renderer/src/components/features/chat/components/RunResultView.tsx index 7f98e7fa..be89a32a 100644 --- a/apps/desktop/src/renderer/src/components/features/chat/components/RunResultView.tsx +++ b/apps/desktop/src/renderer/src/components/features/chat/components/RunResultView.tsx @@ -181,7 +181,7 @@ export function RunResultView({ if (e.currentTarget.open !== showRawStdout) setShowRawStdout(e.currentTarget.open); }} > - {t('chatPane.rawOutput', { n: stdout.length })} + {t('chatPane.rawOutput')} )} diff --git a/apps/desktop/src/renderer/src/i18n/locales/de-DE.json b/apps/desktop/src/renderer/src/i18n/locales/de-DE.json index a934b86c..05797066 100644 --- a/apps/desktop/src/renderer/src/i18n/locales/de-DE.json +++ b/apps/desktop/src/renderer/src/i18n/locales/de-DE.json @@ -104,7 +104,7 @@ "placeholderReady": "Geben Sie eine Frage ein oder verwenden Sie /, um einen Befehl zu wählen (↑↓ für Verlauf)", "planTitle": "Plan", "queuedPosition": "Eingereiht · Position {{position}}", - "rawOutput": "Rohausgabe ({{n}} chars)", + "rawOutput": "Rohausgabe", "reference": { "clearTitle": "Referenz entfernen", "closedDropped": "Durch Nachprüfung geschlossen", diff --git a/apps/desktop/src/renderer/src/i18n/locales/en-US.json b/apps/desktop/src/renderer/src/i18n/locales/en-US.json index 27ac5847..f9f47dd4 100644 --- a/apps/desktop/src/renderer/src/i18n/locales/en-US.json +++ b/apps/desktop/src/renderer/src/i18n/locales/en-US.json @@ -104,7 +104,7 @@ "placeholderReady": "Type a question, or use / to pick a command (↑↓ for history)", "planTitle": "Plan", "queuedPosition": "Queued · position {{position}}", - "rawOutput": "Raw output ({{n}} chars)", + "rawOutput": "Raw output", "reference": { "clearTitle": "Remove reference", "closedDropped": "Closed by re-review", diff --git a/apps/desktop/src/renderer/src/i18n/locales/ja-JP.json b/apps/desktop/src/renderer/src/i18n/locales/ja-JP.json index 5c4cdc6a..f3f76191 100644 --- a/apps/desktop/src/renderer/src/i18n/locales/ja-JP.json +++ b/apps/desktop/src/renderer/src/i18n/locales/ja-JP.json @@ -104,7 +104,7 @@ "placeholderReady": "質問を入力するか、/ でコマンドを選択(↑↓ で履歴)", "planTitle": "計画", "queuedPosition": "待機中 · {{position}} 番目", - "rawOutput": "生出力 ({{n}} chars)", + "rawOutput": "生出力", "reference": { "clearTitle": "参照を解除", "closedDropped": "再レビューで閉じました", diff --git a/apps/desktop/src/renderer/src/i18n/locales/zh-CN.json b/apps/desktop/src/renderer/src/i18n/locales/zh-CN.json index 61474e84..1064cfad 100644 --- a/apps/desktop/src/renderer/src/i18n/locales/zh-CN.json +++ b/apps/desktop/src/renderer/src/i18n/locales/zh-CN.json @@ -104,7 +104,7 @@ "placeholderReady": "输入问题,或用 / 选择命令 (↑↓ 翻历史)", "planTitle": "计划", "queuedPosition": "排队中 · 第 {{position}} 位", - "rawOutput": "原始输出 ({{n}} chars)", + "rawOutput": "原始输出", "reference": { "clearTitle": "移除引用", "closedDropped": "已被复评关闭", From 38c85605573947a82c29df6b738b2a522e7dbf23 Mon Sep 17 00:00:00 2001 From: Hamhire Hu Date: Tue, 23 Jun 2026 14:42:46 +0800 Subject: [PATCH 11/14] =?UTF-8?q?docs(changelog):=20=E8=A1=A5=E9=BD=90?= =?UTF-8?q?=E6=9C=AC=E6=89=B9=20PR/=E8=AF=84=E5=AE=A1/=E5=A4=8D=E8=AF=84?= =?UTF-8?q?=E4=BA=A4=E4=BA=92=E6=94=B9=E8=89=AF=E4=B8=8E=E4=BF=AE=E5=A4=8D?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-Authored-By: Claude Opus 4.8 --- CHANGELOG.md | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index dfc6de47..d9592df3 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -45,7 +45,7 @@ - finding 卡的「编辑 / 拒绝」由 anchor 行的文字按钮改为头部右上角图标栏的图标(评论气泡 / 圆形禁止),排在「引用」转发箭头左侧,与标题同排成组;anchor 行仅保留草稿状态 / 复评关闭 chip。 - 删除按钮统一为高饱和危险红:单条记录删除(垃圾桶)与顶部「清空历史」hover 由偏浅鲑红改为 `$color-danger-strong`,与拒绝 finding / `.btn-icon-danger` 一致。 - `/review` 输出隐藏「评估工作量」(effort)段——实用价值低,不再展示。 -- 复评 `/ask` 取代 / 撤销改为静默自动关闭:引用某条 review/improve 评论发起的复评 `/ask`,裁决为「取代 / 撤销」时**自动**关闭被引用的原 finding(建立关闭关系),无需再手动点「关闭原」;裁决「取代」时把建议提升为**带代码定位**的代码反馈卡(取原评论的 anchor),渲染 / 采纳同 `/review` 代码反馈(点头部评论图标即转为锚定原位置的行内评论草稿)。裁决「保留」不动、且不再展示「保留原评论」标记(无破坏性动作,标记冗余)。自动关闭失败时仍回退到结果卡的手动动作。 +- 复评 `/ask` 取代 / 撤销改为静默自动关闭:引用某条 review/improve 评论发起的复评 `/ask`,裁决为「取代 / 撤销」时**自动**关闭被引用的原 finding(建立关闭关系),无需再手动点「关闭原」;裁决「取代」时把建议提升为**带代码定位**的代码反馈卡(取原评论的 anchor),渲染 / 采纳同 `/review` 代码反馈(点头部评论图标即转为锚定原位置的行内评论草稿)。裁决「保留」不动、且不再展示「保留原评论」标记(无破坏性动作,标记冗余)。关闭纯由后端裁决驱动:移除结果卡面向用户的「采纳并关闭原 / 仅关闭原 / 关闭原评论」与原 finding 卡的「撤销关闭」按钮,前端仅**只读**展示「已被复评取代/关闭」chip + 「查看复评」导航(引用发起复评、点击引用徽标定位高亮原卡仍在)。 - `/ask` 引用展示简化与文案微调:复评结果卡顶部徽标与输入框引用 chip 不再用「复评自 / 复评 …」文案,直接显示引用定位(结果卡:转发箭头 + **完整路径:行号**,换行规则同代码建议定位、点击回链原评论;输入框 chip:只显示**文件名**),删除 `chipLabel` / `reviewedFrom` / `reviewedFromTitle` 三个 i18n key 减少维护;`/ask` 结构化「分析过程」段标签改为「分析解读」,其正文 H2 小节标题字号调小(靠加粗区分)、小节间用分割线隔开;该段展开时在 chip 行下加一条分割线,与下方富文本内容衔接更自然。 - agent「评审总结」聚焦 PR 整体结论:`/ask` 改富文本后,追问答案(表格 / 代码块 / 逐条建议)此前被整段灌进总结输入、诱导模型照搬明细,背离「总结=控制篇幅的整体结论」初衷。现总结只吃每条追问的**结论**(ask-summary),提示词重写为「综合描述 / 评审发现 / 追问结论 → 输出 PR 整体结论,不复制明细」,并允许总结内适度用表格 / 引用 / emoji;「概述 / 发现 / 建议」三段间加分割线。 - `/ask` 结论段标签由「概述」改为「结论」(四语言对齐:Conclusion / 結論 / Fazit),更贴合其「直接结论」定位。 @@ -72,6 +72,10 @@ - 设置面板「连接 / LLM 配置」模态复用首启向导的左右布局:左侧选集成平台 / LLM provider、右侧填表单(复用的 `PlatformPicker` / `LlmProviderPicker` 统一在 settings 域维护,首启向导同步复用)。LLM 模态与向导 LLM 步改为固定高度、两栏各自滚动——切换 provider 不再抖动、provider 列表后续扩展也不撑高,向导两子步等高对齐;CLI 模式补「实验性」标记、名称 / 命令占位提示 `claude / codex`、文案精简(去品牌名与内部细节);必填校验改为只标红框(去错误文案、消除控件位置抖动);「测试连接」按钮收窄为 `btn-sm` 并与结果文案垂直对齐。 - 危险按钮统一为高饱和度红描边:新增 `$color-danger-strong` token,删除评论(评论 tab + 行内)/ 删除草稿 / 删除连接 / LLM、停止、拒绝 finding 等按钮 hover 由偏浅鲑红改为与模态删除按钮同色系的饱和红,警示力更强、全局一致(保留 ghost 描边风格,不改为实底)。 +- PR 提交列表 / 活动时间线按 first-parent 过滤合入的他人提交:平台 `/commits` 返回 `target..source` 全集,长期分支 / fork 同步分支历史上反复把别的分支 merge 进源分支,会带出大量 merge 提交与合入的他人提交、淹没本 PR 真正引入的提交。改用本地镜像 `git rev-list --first-parent --no-merges merge-base..source` 算「本 PR 自产提交」SHA 集合对平台返回做交集过滤;提交数角标同口径对齐;镜像未就位 / 算不出时回退未过滤列表、不丢信息(三平台统一收口)。 + +- ChatPane / Diff 评审界面一批交互打磨:评审总结卡与 finding 卡同宽、加蓝色左条(与蓝色淡底成一套);可折叠卡(分析解读 / 已拒绝 / 被复评关闭的代码反馈)整行标题区即展开 / 收起热区、收起态上下内边距对称、折叠 / 展开带高度过渡动画(尊重「减少动效」);已有评论的行也可 hover「+」继续追加行内评论(新评论按时间序展示在已有评论下方);点击复评引用徽标精确定位到原 finding 卡并按其类别色闪烁高亮(已关闭 / 拒绝卡用中性灰),引用徽标图标随首行、行号跟随路径末行排版修正;diff 头部 reviewer 打勾角标缩小一号并去描边环;「原始输出」折叠标题去掉「(xx chars)」字数;判定解析失败的兜底不再输出「无法解析建议,转人工复核」灰字(仅保留判定徽标)。 + ### Fixed - 复评 `/ask` 取代裁决的「改进建议」改为可直接发布的评论本身:此前 `` 常被写成「建议将原评论替换为…/请确认…」这类**关于评论的元讨论**(还出现「原评论」概念),无法被评审者直接采用。现提示词要求 `replace` 裁决下 `` **只包含替代评论本身**——以标准 review 评论的口吻直接针对代码、按问题 → 影响 → 建议分段、可原样发布,不提「原评论 / 替换 / 请确认」等元信息;被取代的原评论仍按 `replace`/`drop` 裁决自动关闭。 @@ -92,9 +96,11 @@ - PR 主面板各 tab(diff / 评论 / 草稿 / 提交 / 信息)切换抖动:此前 tab 内容按条件渲染,每次切换旧面板卸载、新面板重挂 → 重新拉数据、闪「加载中」、内嵌 Monaco 重建。改为 keep-alive——tab 首访才挂载(保留懒加载)、之后保活仅 CSS 显隐不卸载,切走再切回瞬时、无重拉、滚动位置与展开态保留;配合 Monaco `automaticLayout` 处理显隐后的重排。 - 刷新(后台轮询 / 窗口聚焦)时编辑器渲染抖动:评论页内嵌代码片段(Monaco)与 diff 编辑器此前每次刷新都重渲染 / 重建。根因有二——其一,i18n 语言切换 effect 依赖整个 boot 对象,poll 刷新 setBoot 后对同一语言反复 `changeLanguage`,触发 `languageChanged` 致所有 `useTranslation` 的 `t` 换新引用,凡 effect 依赖 `t` 的组件(如内嵌代码片段抓取逻辑)都被无谓重跑、连带 Monaco 卸载重建;其二,DiffEditor 的 `options` 为渲染期新建对象,被 `@monaco-editor/react` 按引用判变而反复 `updateOptions`。现语言 effect 仅在语言真正变化时切换、DiffEditor options 稳定化,刷新不再抖动。 - PR 详情页与评论页排版:正文限宽 960px 并居中,滚动条回到外层容器右缘(此前 max-width 加在滚动容器上,滚动条停在中部);详情页 reviewers 列表按字典序固定排序,刷新不再随平台返回顺序抖动。 -- 拉取变更文件列表偶发失败(`ENOENT … diff-base.json`):状态存储对同一 key 的并发写共用同一临时文件,先完成者 rename 后,后完成者 rename 即 ENOENT。临时文件名追加进程内自增序号去重,并发写各用独立临时文件。 +- 拉取变更文件列表偶发失败(`ENOENT … diff-base.json`):状态存储对同一 key 的并发写共用同一临时文件,先完成者 rename 后,后完成者 rename 即 ENOENT。临时文件名追加进程内自增序号去重,并发写各用独立临时文件。Windows 上并发写同一 key 还会撞 `fs.rename` 覆盖既有文件的瞬时 EPERM/EACCES/EBUSY(打开 / 切换 PR 时多 handler 同写 diff-base.json)→ rename 加退避重试自愈(并打 warn 定位日志),同时对 diff-base 解析按 PR 去重、从源头收敛并发写。 - Agent 评审 / 规划步骤行的固定文案(如「判断是否存在需追问的严重问题」「严重,追问 N 个」)此前在 `@meebox/agent` 层写死中文、被渲染层逐字显示,日 / 英 / 德界面下漏出中文;现按会话语言落地(zh-CN / en-US / ja-JP / de-DE,缺省回落英文),与评审总结骨架同策略。 - 设置页手动「检查更新」查到的新版此前不同步到状态栏、也不缓存:手动检查只把结果回给设置页本地,与定时检查各自为政、无共享。现 main 侧统一为单一真相源——手动 / 定时检查都缓存结果并在有新版时广播 `app:updateAvailable`,状态栏即时出现升级 chip;新增只读 `app:getUpdateStatus`,窗口 / 状态栏挂载时水合已知结果,不因重挂载而丢失。 +- 合并已合并 / 已关闭的 PR 报错不友好:Bitbucket 对已合并 PR 的合并请求回 409 + `IllegalPullRequestStateException`(本地状态滞后于远端:他人已合 / 重复点击),此前把原始 409 stack 抛给用户。归一为错误码 `EPR0003`,前端按码做 i18n 友好提示(四语言对等);其它 409(冲突 / veto)原样冒泡。 +- 评审总结被截断 / 无法解析(回落「无法解析建议」):原把整段 markdown 总结塞进 JSON 字符串字段,正文里的引号 / 换行 / 代码块会破坏 JSON 解析,回退打捞时又在首个内层引号处把正文腰斩、且判定一并丢失 → 回落 manual_review。改为模型直接输出纯 markdown 正文 + 末尾一行扁平判定 JSON,正文走 `stripTrailingJson`(含对被截断 dangling 判定 JSON 的兜底剥除)、判定走新增 `extractTrailingJson` 单独解析(兼容旧嵌套格式),并给收尾 chat 显式输出 token 上限避免被 provider 默认上限截断。 ## [0.5.0] - 2026-06-17 From 4070e27c7c147d16ce8505123719394e59b2342a Mon Sep 17 00:00:00 2001 From: Hamhire Hu Date: Tue, 23 Jun 2026 14:55:13 +0800 Subject: [PATCH 12/14] =?UTF-8?q?feat(chat):=20=E6=80=9D=E8=B7=AF=E5=BB=BA?= =?UTF-8?q?=E8=AE=AE=E6=8A=98=E5=8F=A0=E6=A0=87=E9=A2=98=E6=94=AF=E6=8C=81?= =?UTF-8?q?=E5=86=85=E8=81=94=20markdown?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit raw HTML 的
内文本不会被 markdown 二次解析(反引号原样漏出)。新增 withInlineSummary 给 套 MdInline,让折叠标题里的 `代码` / **强调** 等内联格式生效; finding 卡 markdown(含 walkthrough)统一叠加。同步放开 shim 的 describe assessment 提示词 ——原强制标题纯文本「禁用反引号」,改为允许标题内用 `inline code` 标识符。 Co-Authored-By: Claude Opus 4.8 --- .../patches/describe_assessment.py | 4 +-- .../features/chat/components/FindingCard.tsx | 10 +++++-- .../features/chat/components/shared.tsx | 28 ++++++++++++++++++- 3 files changed, 37 insertions(+), 5 deletions(-) diff --git a/apps/desktop/scripts/pragent-shim/meebox_pragent_shim/patches/describe_assessment.py b/apps/desktop/scripts/pragent-shim/meebox_pragent_shim/patches/describe_assessment.py index 15040d9e..6cdcee0b 100644 --- a/apps/desktop/scripts/pragent-shim/meebox_pragent_shim/patches/describe_assessment.py +++ b/apps/desktop/scripts/pragent-shim/meebox_pragent_shim/patches/describe_assessment.py @@ -18,8 +18,8 @@ "this exact structure: (1) the intro line \\'The following are alternative approaches to this PR:\\'; " "(2) then 2-4 plausible ALTERNATIVE implementation approaches, EACH formatted as a
block " "with BLANK LINES inside so the body is parsed as markdown (this exact layout, blank lines required): " - "a line '
N. concise PLAIN-TEXT approach title (NO backticks or markdown inside the " - "summary)', then a blank line, then 1-3 sentences explaining the approach and its main " + "a line '
N. concise approach title (you MAY use `inline code` for identifiers in the " + "summary; keep it short)', then a blank line, then 1-3 sentences explaining the approach and its main " "trade-off (you MAY use `inline code` for identifiers in this body), then a blank line, then the line " "'
'; (3) after the last
leave ONE blank line, then a paragraph starting with " "**Recommendation:** that compares the current approach against the alternatives and recommends one. " diff --git a/apps/desktop/src/renderer/src/components/features/chat/components/FindingCard.tsx b/apps/desktop/src/renderer/src/components/features/chat/components/FindingCard.tsx index 24bf9e4a..d3634dca 100644 --- a/apps/desktop/src/renderer/src/components/features/chat/components/FindingCard.tsx +++ b/apps/desktop/src/renderer/src/components/features/chat/components/FindingCard.tsx @@ -21,7 +21,12 @@ import { stripEffortScoreNumber, stripFindingMarker, } from '../utils/findings'; -import { BreakablePath, MdInline } from './shared'; +import { BreakablePath, MdInline, withInlineSummary } from './shared'; + +// 折叠标题(
)支持内联 markdown:思路建议各方案标题里的 `代码` / **强调** 等生效。 +// 预算在模块级,避免每次渲染重建 components 对象。 +const DEFAULT_MD_COMPONENTS = withInlineSummary(mermaidComponents); +const WALKTHROUGH_MD_COMPONENTS = withInlineSummary(walkthroughMdComponents); // chip 配色 tone → chat-chip-(色板见 styles/features/chat/chip.scss)。 // finding 类别:元信息/图/工作量→accent,内容/测试/安全→approved,代码反馈/建议→warning,评分/兜底→neutral。 @@ -379,7 +384,8 @@ export function FindingCard({ remarkPlugins={[remarkGfm, remarkBreaks]} rehypePlugins={REMOTE_REHYPE_PLUGINS} // 「文件变更」walkthrough 用去掉
的覆盖,使各文件分类默认折叠收起。 - components={key === 'walkthrough' ? walkthroughMdComponents : mermaidComponents} + // 两套均叠加「 内联 markdown」(折叠标题支持 `代码` 等预格式化)。 + components={key === 'walkthrough' ? WALKTHROUGH_MD_COMPONENTS : DEFAULT_MD_COMPONENTS} > {translatedBody} diff --git a/apps/desktop/src/renderer/src/components/features/chat/components/shared.tsx b/apps/desktop/src/renderer/src/components/features/chat/components/shared.tsx index 228898b4..d6d9b02d 100644 --- a/apps/desktop/src/renderer/src/components/features/chat/components/shared.tsx +++ b/apps/desktop/src/renderer/src/components/features/chat/components/shared.tsx @@ -1,6 +1,6 @@ import type { ReactNode, Ref } from 'react'; import { useTranslation } from 'react-i18next'; -import ReactMarkdown from 'react-markdown'; +import ReactMarkdown, { type Components } from 'react-markdown'; import remarkBreaks from 'remark-breaks'; import remarkGfm from 'remark-gfm'; import { QuestionIcon, mermaidComponents } from '../../../common'; @@ -51,6 +51,32 @@ export function MdInline({ children }: { children: string }) { ); } +/** + * `` 内联 markdown 渲染:raw HTML 的折叠标题(如「思路建议」各方案的
)内的 + * 文本不会被 markdown 二次解析,反引号 / 强调等会原样漏出。这里把其纯文本走 {@link MdInline},让标题里的 + * `代码` / **强调** 生效。children 多为纯文本串;含非文本节点时原样渲染兜底。 + */ +const SummaryInlineMd: Components['summary'] = ({ children }) => { + const text = + typeof children === 'string' + ? children + : Array.isArray(children) && children.every((c) => typeof c === 'string') + ? children.join('') + : null; + return text != null ? ( + + {text} + + ) : ( + {children} + ); +}; + +/** 在给定 markdown components 之上叠加「 内联 markdown」渲染(折叠标题支持 md 预格式化)。 */ +export function withInlineSummary(base: Components): Components { + return { ...base, summary: SummaryInlineMd }; +} + /** * 代码路径折行优化:在分隔符 `/` 与连接符 `.` `_` `-` 之后插入 软断点,配合 CSS * `word-break: normal`,让长路径优先按这些字符折断(而非从单词中间断开),保证可读性。 From dc9720f50ead80d6e6f4859f9567935ef61e2e34 Mon Sep 17 00:00:00 2001 From: Hamhire Hu Date: Tue, 23 Jun 2026 14:55:24 +0800 Subject: [PATCH 13/14] =?UTF-8?q?fix(chat):=20=E8=AF=84=E5=AE=A1=E6=80=BB?= =?UTF-8?q?=E7=BB=93=E6=AD=A3=E6=96=87=E8=A1=8C=E8=B7=9D/=E5=AD=97?= =?UTF-8?q?=E5=8F=B7=E4=B8=8E=E5=85=B6=E5=AE=83=E5=8D=A1=E7=89=87=E7=BB=9F?= =?UTF-8?q?=E4=B8=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 评审总结正文此前 $fs-md + 默认行高,比 finding 卡($fs-lg / $lh-normal)显得更窄。改为 同字号同行高;标题(h1-4)同步由 $fs-md 提到 $fs-lg(不小于正文、靠加粗区分层级)。 Co-Authored-By: Claude Opus 4.8 --- .../src/renderer/src/styles/features/chat/agent.scss | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/apps/desktop/src/renderer/src/styles/features/chat/agent.scss b/apps/desktop/src/renderer/src/styles/features/chat/agent.scss index fc283a6d..f9b83d0e 100644 --- a/apps/desktop/src/renderer/src/styles/features/chat/agent.scss +++ b/apps/desktop/src/renderer/src/styles/features/chat/agent.scss @@ -51,7 +51,9 @@ } .chat-agent-summary-text { margin: 0 0 $space-3; - font-size: $fs-md; + // 与 finding 卡正文统一字号 / 行高(此前 $fs-md + 默认行高显得比其它卡片更窄)。 + font-size: $fs-lg; + line-height: $lh-normal; color: $text-body; } // 评审总结 / 对话回复内的 markdown 章节标题(## 摘要 等)压到不超过卡片标题(评审总结)字号, @@ -62,7 +64,8 @@ h2, h3, h4 { - font-size: $fs-md; + // 与正文同字号(靠加粗区分层级),不小于正文、也不放大成 markdown 默认大标题。 + font-size: $fs-lg; margin: $space-3 0 $space-1; } > :first-child { From f6d34b6554fb31b8e1ada95a1d40b0a1d7e6d546 Mon Sep 17 00:00:00 2001 From: Hamhire Hu Date: Tue, 23 Jun 2026 14:56:31 +0800 Subject: [PATCH 14/14] =?UTF-8?q?docs(changelog):=20=E8=A1=A5=E8=AE=B0?= =?UTF-8?q?=E6=80=9D=E8=B7=AF=E5=BB=BA=E8=AE=AE=E6=A0=87=E9=A2=98=E5=86=85?= =?UTF-8?q?=E8=81=94=20md=20=E4=B8=8E=E8=AF=84=E5=AE=A1=E6=80=BB=E7=BB=93?= =?UTF-8?q?=E8=A1=8C=E8=B7=9D=E7=BB=9F=E4=B8=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-Authored-By: Claude Opus 4.8 --- CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index d9592df3..7de2fcdb 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -74,7 +74,7 @@ - PR 提交列表 / 活动时间线按 first-parent 过滤合入的他人提交:平台 `/commits` 返回 `target..source` 全集,长期分支 / fork 同步分支历史上反复把别的分支 merge 进源分支,会带出大量 merge 提交与合入的他人提交、淹没本 PR 真正引入的提交。改用本地镜像 `git rev-list --first-parent --no-merges merge-base..source` 算「本 PR 自产提交」SHA 集合对平台返回做交集过滤;提交数角标同口径对齐;镜像未就位 / 算不出时回退未过滤列表、不丢信息(三平台统一收口)。 -- ChatPane / Diff 评审界面一批交互打磨:评审总结卡与 finding 卡同宽、加蓝色左条(与蓝色淡底成一套);可折叠卡(分析解读 / 已拒绝 / 被复评关闭的代码反馈)整行标题区即展开 / 收起热区、收起态上下内边距对称、折叠 / 展开带高度过渡动画(尊重「减少动效」);已有评论的行也可 hover「+」继续追加行内评论(新评论按时间序展示在已有评论下方);点击复评引用徽标精确定位到原 finding 卡并按其类别色闪烁高亮(已关闭 / 拒绝卡用中性灰),引用徽标图标随首行、行号跟随路径末行排版修正;diff 头部 reviewer 打勾角标缩小一号并去描边环;「原始输出」折叠标题去掉「(xx chars)」字数;判定解析失败的兜底不再输出「无法解析建议,转人工复核」灰字(仅保留判定徽标)。 +- ChatPane / Diff 评审界面一批交互打磨:评审总结卡与 finding 卡同宽、加蓝色左条(与蓝色淡底成一套);可折叠卡(分析解读 / 已拒绝 / 被复评关闭的代码反馈)整行标题区即展开 / 收起热区、收起态上下内边距对称、折叠 / 展开带高度过渡动画(尊重「减少动效」);已有评论的行也可 hover「+」继续追加行内评论(新评论按时间序展示在已有评论下方);点击复评引用徽标精确定位到原 finding 卡并按其类别色闪烁高亮(已关闭 / 拒绝卡用中性灰),引用徽标图标随首行、行号跟随路径末行排版修正;diff 头部 reviewer 打勾角标缩小一号并去描边环;「原始输出」折叠标题去掉「(xx chars)」字数;判定解析失败的兜底不再输出「无法解析建议,转人工复核」灰字(仅保留判定徽标);「思路建议」折叠方案标题支持内联 markdown(`代码` / **强调**,shim 提示词同步放开标题禁用反引号的限制);评审总结正文行距 / 字号与其它卡片统一($fs-md → $fs-lg / $lh-normal)。 ### Fixed