fix(rectification): unblock range-card tsc and restore post-adopt windows (BUG-583)
Independent Staging Quality Gate / validate (push) Successful in 13m23s
Independent Staging Quality Gate / publish (push) Successful in 30m54s

Null-check the candidate result before reading resultId so next build can ship. Adopt reconnects prospective windows on the first verify turn, and dismissing the range card now shows the collect hint.

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
Jesse_Chen
2026-09-07 20:22:24 +08:00
co-authored by Cursor
parent f3e7270237
commit a00b069dcc
13 changed files with 194 additions and 16 deletions
@@ -39,7 +39,7 @@ import {
workingRectificationHouseTable,
type RectificationCandidateResult,
} from "@/lib/rectification-candidate-result";
import { RectificationRangeDelivery } from "@/components/rectification-range-delivery";
import { RangeDeliveryContinueHint, RectificationRangeDelivery } from "@/components/rectification-range-delivery";
import {
diffRectificationBoard,
RECTIFICATION_BOARD_SPLIT_MIN_PX,
@@ -1506,6 +1506,15 @@ export function RectificationAgenticChat(props: RectificationAgenticChatProps) {
void submitStructuredChoice(STOP_ACTION, "stop");
}
const rangeCardDismissed = Boolean(
candidateResult
&& dismissedRangeResultId === candidateResult.resultId
&& !candidateResult.selectedTime
&& savedStatus !== "accepted"
&& savedStatus !== "confirmed"
&& !readonly
);
const spokenCollectOpen = currentQuestion?.kind === "collect_spoken" && !readonly && !busy;
const boardPeek = compactBoard && !boardOpen ? (
<RectificationBoardPeek
result={candidateResult}
@@ -1652,7 +1661,7 @@ export function RectificationAgenticChat(props: RectificationAgenticChatProps) {
onRegenerate={() => void regenerateMessage(message)}
/>
)}
{showSelectionCards && dismissedRangeResultId !== candidateResult.resultId && message.renderKey === selectionCardMessageKey && candidateResult && (
{showSelectionCards && candidateResult && dismissedRangeResultId !== candidateResult.resultId && message.renderKey === selectionCardMessageKey && (
<RectificationRangeDelivery
result={candidateResult}
acceptingCandidateId={acceptingCandidateId}
@@ -1724,8 +1733,10 @@ export function RectificationAgenticChat(props: RectificationAgenticChatProps) {
<span className="rectification-adopt-status__hint"></span>
</div>
)}
{currentQuestion?.kind === "collect_spoken" && !readonly && !busy && (
{(rangeCardDismissed || spokenCollectOpen) && (
<div className="rectification-composer-meta">
<RangeDeliveryContinueHint visible={rangeCardDismissed && !busy} />
{spokenCollectOpen && (
<button
type="button"
className="rectification-collect-stop"
@@ -1733,6 +1744,7 @@ export function RectificationAgenticChat(props: RectificationAgenticChatProps) {
>
{CHOICE_STOP_LABEL}
</button>
)}
</div>
)}
<ChatComposer
@@ -9,6 +9,7 @@ import {
rangeDeliverySensitiveCopy,
rangeDeliveryStableCopy,
} from "@/lib/rectification-agentic/user-copy";
import { STEP_STATE_COPY } from "@/lib/rectification-agentic/v9/step-state";
import type { RangeDeliveryProjection } from "@/lib/rectification-agentic/v9/divergence-panel";
function adoptCandidateId(
@@ -25,6 +26,17 @@ function adoptCandidateId(
?? null;
}
export function RangeDeliveryContinueHint({ visible }: Readonly<{ visible: boolean }>) {
if (!visible) return null;
return (
<p className="rectification-continue-hint" role="status">
<strong>{STEP_STATE_COPY.collect.headline}</strong>
{" "}
{RECTIFICATION_USER_COPY.continueCollectFallback}
</p>
);
}
export function RectificationRangeDelivery({
result,
acceptingCandidateId,