fix: guide mxcx apply-patch stale context recovery
This commit is contained in:
@@ -126,6 +126,7 @@ export function applyPatchV2HelpPayload() {
|
||||
"A blank line in Add File is a line containing only +.",
|
||||
"Update File uses @@ or @@ context markers, followed by context lines starting with one extra space prefix and changed lines starting with - or +; for a column-0 source line `const x`, write ` const x`, and for a two-space-indented source line write three spaces total. Unified-diff line-range headers are accepted with hints for MiniMax compatibility.",
|
||||
"Prefer `trans <route> apply-patch < /tmp/patch.diff` for long patches, Windows paths, or quoting-sensitive content.",
|
||||
"If `failed to find expected lines` reports stale or oversized context for a block/function replacement, re-read the exact current block and retry with a smaller Update File hunk or split hunks around unique anchors.",
|
||||
"MiniMax compatibility: stray @@ or unprefixed content inside Add File, unprefixed Update File context lines, and extra hunk/body lines after Delete File, are accepted with stderr hints.",
|
||||
"MiniMax/MXCX concatenated patch compatibility: repeated nested Begin Patch / End Patch markers are accepted with stderr hints, but the CLI still uses only the v2 engine and never auto-falls back to apply-patch-v1."
|
||||
],
|
||||
@@ -153,6 +154,7 @@ export function applyPatchV2HelpPayload() {
|
||||
"Do not put @@ after `*** Add File:`; @@ is only for Update File.",
|
||||
"Prefer canonical @@ or @@ context over unified diff headers such as `@@ -1,3 +1,4 @@`; v2 accepts those headers with a hint.",
|
||||
"If multiple printf/heredoc fragments were concatenated, keep one outer Begin/End envelope or include complete nested envelopes; v2 will hint on nested markers instead of trying the legacy helper.",
|
||||
"Do not recover from apply-patch context mismatch by switching to download/upload, remote Python/Perl/sed, or whole-file rewrites; retry with corrected v2 hunks.",
|
||||
"Do not use remote Python/Perl/sed heredocs for text patches when `trans <route> apply-patch` is available."
|
||||
],
|
||||
note: "apply-patch reads patch text from stdin and uses the v2 engine by default. Use `apply-patch-v1` only for the legacy helper."
|
||||
@@ -475,6 +477,9 @@ function appendExpectedLineDiagnostics(lines: string[], cause: Record<string, un
|
||||
if (diagnostics.likelyMissingAddedPrefixes === true) {
|
||||
lines.push("Hint: this hunk looks like a large insertion whose new lines were written as context. Prefix every inserted line with +, keep only a few real existing context lines before/after the insertion, and regenerate the patch instead of editing it with sed.");
|
||||
}
|
||||
if (diagnostics.likelyStaleOrOversizedContext === true) {
|
||||
lines.push("Hint: this looks like stale or oversized context for a block/function replacement. Do not switch to download/upload, remote Python/Perl/sed, or a whole-file rewrite. Re-read the exact current block and retry apply-patch with a smaller hunk, or split the edit into hunks around unique anchors.");
|
||||
}
|
||||
}
|
||||
|
||||
function recordValue(value: unknown): Record<string, unknown> | null {
|
||||
@@ -1044,13 +1049,15 @@ function expectedLineDiagnostics(originalLines: string[], chunk: UpdateChunk, pr
|
||||
const firstExpectedLine = chunk.oldLines.find((line) => line.trim().length > 0) ?? "";
|
||||
const firstExpectedLineCandidates = firstExpectedLine.length === 0 ? [] : candidateLineNumbers(originalLines, firstExpectedLine, 8);
|
||||
const prefix = bestPrefixMatch(originalLines, chunk.oldLines, firstExpectedLine, preferredStart);
|
||||
const missingAddedPrefixes = likelyMissingAddedPrefixes(chunk, prefix.matchedLines);
|
||||
return {
|
||||
firstExpectedLine,
|
||||
firstExpectedLineCandidates,
|
||||
firstExpectedLineCandidatesTruncated: firstExpectedLine.length > 0 && candidateLineNumbers(originalLines, firstExpectedLine, 9).length > firstExpectedLineCandidates.length,
|
||||
bestPrefixMatchedLines: prefix.matchedLines,
|
||||
bestPrefixStartLine: prefix.startLine,
|
||||
likelyMissingAddedPrefixes: likelyMissingAddedPrefixes(chunk, prefix.matchedLines),
|
||||
likelyMissingAddedPrefixes: missingAddedPrefixes,
|
||||
likelyStaleOrOversizedContext: !missingAddedPrefixes && likelyStaleOrOversizedContext(chunk, prefix.matchedLines),
|
||||
};
|
||||
}
|
||||
|
||||
@@ -1093,6 +1100,12 @@ function likelyMissingAddedPrefixes(chunk: UpdateChunk, bestPrefixMatchedLines:
|
||||
return bestPrefixMatchedLines > 0 && bestPrefixMatchedLines < chunk.oldLines.length;
|
||||
}
|
||||
|
||||
function likelyStaleOrOversizedContext(chunk: UpdateChunk, bestPrefixMatchedLines: number): boolean {
|
||||
if (chunk.oldLines.length < 4) return false;
|
||||
if (bestPrefixMatchedLines < 2 || bestPrefixMatchedLines >= chunk.oldLines.length) return false;
|
||||
return chunk.addedLineCount > 0 || chunk.deletedLineCount > 0 || chunk.contextLineCount >= 4;
|
||||
}
|
||||
|
||||
function lineEquivalent(left: string, right: string): boolean {
|
||||
return left === right || left.trimEnd() === right.trimEnd() || left.trim() === right.trim() || normalizeLine(left) === normalizeLine(right);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user