hillclimb 0.9.14 → 0.9.15
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/main.js +171 -28
- package/package.json +1 -1
package/dist/main.js
CHANGED
|
@@ -16608,6 +16608,8 @@ function failureText(result) {
|
|
|
16608
16608
|
// src/git-traces/git-ops.ts
|
|
16609
16609
|
var DEFAULT_GIT_COMMAND_TIMEOUT_MS = 12e4;
|
|
16610
16610
|
var DEFAULT_BUNDLE_TIMEOUT_MS = 3e5;
|
|
16611
|
+
var MAX_BASELINE_BUNDLE_BYTES = 1024 * 1024 * 1024;
|
|
16612
|
+
var DEFAULT_UNTRACKED_INDEX_TIMEOUT_MS = 3e5;
|
|
16611
16613
|
var FULL_TREE_SCAN_TIMEOUT_MS = 3e5;
|
|
16612
16614
|
function resolveGitCommandTimeoutMs(fallback = DEFAULT_GIT_COMMAND_TIMEOUT_MS) {
|
|
16613
16615
|
const raw = process.env.HILLCLIMB_GIT_COMMAND_TIMEOUT_MS;
|
|
@@ -16901,6 +16903,7 @@ function createGitError(args, err, timeoutMs = GIT_COMMAND_TIMEOUT_MS, elapsedMs
|
|
|
16901
16903
|
const stdout = outputToString(failure.stdout);
|
|
16902
16904
|
wrapped.gitStdout = stdout ? truncateOutput(stdout) : void 0;
|
|
16903
16905
|
wrapped.isGitMissingObject = !isTimeout && failure.code !== "ENOBUFS" && matchesMissingObject(stderr);
|
|
16906
|
+
wrapped.isGitMissingWorktreeFile = args[0] === "update-index" && failure.status === 128 && !failure.signal && (!failure.code || failure.code === "EPIPE") && !!stderr?.includes("does not exist and --remove not passed");
|
|
16904
16907
|
return wrapped;
|
|
16905
16908
|
}
|
|
16906
16909
|
function commitTree(repoRoot, treeSha, message) {
|
|
@@ -17560,6 +17563,9 @@ function buildUntrackedTree(repoRoot, options = {}, attempt = 1) {
|
|
|
17560
17563
|
() => gitBuffer(repoRoot, ["update-index", "--add", "-z", "--stdin"], {
|
|
17561
17564
|
input: `${kept.join("\0")}\0`,
|
|
17562
17565
|
env,
|
|
17566
|
+
timeoutMs: resolveGitCommandTimeoutMs(
|
|
17567
|
+
DEFAULT_UNTRACKED_INDEX_TIMEOUT_MS
|
|
17568
|
+
),
|
|
17563
17569
|
diagnostics: { stage: "untracked-hash-and-index" }
|
|
17564
17570
|
})
|
|
17565
17571
|
);
|
|
@@ -17570,8 +17576,7 @@ function buildUntrackedTree(repoRoot, options = {}, attempt = 1) {
|
|
|
17570
17576
|
);
|
|
17571
17577
|
} catch (err) {
|
|
17572
17578
|
const failure = err;
|
|
17573
|
-
if (attempt !== 1 ||
|
|
17574
|
-
throw err;
|
|
17579
|
+
if (attempt !== 1 || !failure.isGitMissingWorktreeFile) throw err;
|
|
17575
17580
|
appendLog(
|
|
17576
17581
|
"warn",
|
|
17577
17582
|
`git-traces: retrying untracked capture after files disappeared (repo=${repoRoot}, attempt=${attempt}, maxAttempts=2)`
|
|
@@ -17708,6 +17713,12 @@ function createBundleFromTree(repoRoot, treeSha, sessionId, label) {
|
|
|
17708
17713
|
diagnostics: { stage: "bundle-create", bundleFile: tmpFile }
|
|
17709
17714
|
})
|
|
17710
17715
|
);
|
|
17716
|
+
const bytes = fs19.statSync(tmpFile).size;
|
|
17717
|
+
if (bytes > MAX_BASELINE_BUNDLE_BYTES) {
|
|
17718
|
+
throw new Error(
|
|
17719
|
+
`Git baseline bundle exceeds the upload limit (bytes=${bytes}, maxBytes=${MAX_BASELINE_BUNDLE_BYTES}); capture retained`
|
|
17720
|
+
);
|
|
17721
|
+
}
|
|
17711
17722
|
const bundle = fs19.readFileSync(tmpFile);
|
|
17712
17723
|
appendLog(
|
|
17713
17724
|
"info",
|
|
@@ -17723,7 +17734,21 @@ function createBundleFromTree(repoRoot, treeSha, sessionId, label) {
|
|
|
17723
17734
|
}
|
|
17724
17735
|
}
|
|
17725
17736
|
var MAX_PATCH_GZ_BYTES = 500 * 1024 * 1024;
|
|
17726
|
-
|
|
17737
|
+
var MAX_PATCH_RAW_BYTES = 1023 * 1024 * 1024 - 1;
|
|
17738
|
+
var GitPatchTooLargeError = class extends Error {
|
|
17739
|
+
constructor(rawBytes, maxRawBytes) {
|
|
17740
|
+
super(
|
|
17741
|
+
`git diff raw output exceeded the ${maxRawBytes}-byte replay limit (observedBytes=${rawBytes}); a new baseline is required`
|
|
17742
|
+
);
|
|
17743
|
+
this.rawBytes = rawBytes;
|
|
17744
|
+
this.maxRawBytes = maxRawBytes;
|
|
17745
|
+
this.name = "GitPatchTooLargeError";
|
|
17746
|
+
}
|
|
17747
|
+
};
|
|
17748
|
+
function resolveMaxPatchRawBytes(value) {
|
|
17749
|
+
return typeof value === "number" && Number.isSafeInteger(value) && value > 0 ? Math.min(value, MAX_PATCH_RAW_BYTES) : MAX_PATCH_RAW_BYTES;
|
|
17750
|
+
}
|
|
17751
|
+
function gitGzipStream(repoRoot, args, maxGzBytes, maxRawBytes) {
|
|
17727
17752
|
return new Promise((resolve, reject) => {
|
|
17728
17753
|
const started = Date.now();
|
|
17729
17754
|
const child = spawn2("git", args, {
|
|
@@ -17740,6 +17765,7 @@ function gitGzipStream(repoRoot, args, maxGzBytes) {
|
|
|
17740
17765
|
let settled = false;
|
|
17741
17766
|
let timedOut = false;
|
|
17742
17767
|
let overflowed = false;
|
|
17768
|
+
let rawOverflowed = false;
|
|
17743
17769
|
let streamError = null;
|
|
17744
17770
|
let exitCode = null;
|
|
17745
17771
|
let exitSignal = null;
|
|
@@ -17766,6 +17792,8 @@ function gitGzipStream(repoRoot, args, maxGzBytes) {
|
|
|
17766
17792
|
);
|
|
17767
17793
|
probeObjectStore(repoRoot, "timeout", wrapped.gitStderr, args);
|
|
17768
17794
|
reject(wrapped);
|
|
17795
|
+
} else if (rawOverflowed) {
|
|
17796
|
+
reject(new GitPatchTooLargeError(rawBytes, maxRawBytes));
|
|
17769
17797
|
} else if (overflowed) {
|
|
17770
17798
|
reject(
|
|
17771
17799
|
createGitError(args, { code: "ENOBUFS", maxBufferBytes: maxGzBytes })
|
|
@@ -17784,8 +17812,22 @@ function gitGzipStream(repoRoot, args, maxGzBytes) {
|
|
|
17784
17812
|
resolve({ gz: Buffer.concat(gzChunks), rawBytes });
|
|
17785
17813
|
}
|
|
17786
17814
|
};
|
|
17815
|
+
const stopForOverflow = () => {
|
|
17816
|
+
child.stdout.unpipe(gzip);
|
|
17817
|
+
child.stdout.resume();
|
|
17818
|
+
child.kill("SIGTERM");
|
|
17819
|
+
gzip.destroy();
|
|
17820
|
+
gzChunks.length = 0;
|
|
17821
|
+
gzipDone = true;
|
|
17822
|
+
finish();
|
|
17823
|
+
};
|
|
17787
17824
|
child.stdout.on("data", (chunk) => {
|
|
17825
|
+
if (rawOverflowed || overflowed) return;
|
|
17788
17826
|
rawBytes += chunk.length;
|
|
17827
|
+
if (rawBytes > maxRawBytes) {
|
|
17828
|
+
rawOverflowed = true;
|
|
17829
|
+
stopForOverflow();
|
|
17830
|
+
}
|
|
17789
17831
|
});
|
|
17790
17832
|
child.stdout.on("error", (err) => {
|
|
17791
17833
|
streamError ??= err;
|
|
@@ -17794,17 +17836,11 @@ function gitGzipStream(repoRoot, args, maxGzBytes) {
|
|
|
17794
17836
|
});
|
|
17795
17837
|
child.stdout.pipe(gzip);
|
|
17796
17838
|
gzip.on("data", (chunk) => {
|
|
17839
|
+
if (rawOverflowed || overflowed) return;
|
|
17797
17840
|
gzBytes += chunk.length;
|
|
17798
17841
|
if (gzBytes > maxGzBytes) {
|
|
17799
|
-
|
|
17800
|
-
|
|
17801
|
-
child.stdout.unpipe(gzip);
|
|
17802
|
-
child.stdout.resume();
|
|
17803
|
-
child.kill("SIGTERM");
|
|
17804
|
-
gzip.destroy();
|
|
17805
|
-
gzipDone = true;
|
|
17806
|
-
finish();
|
|
17807
|
-
}
|
|
17842
|
+
overflowed = true;
|
|
17843
|
+
stopForOverflow();
|
|
17808
17844
|
return;
|
|
17809
17845
|
}
|
|
17810
17846
|
gzChunks.push(chunk);
|
|
@@ -17814,7 +17850,7 @@ function gitGzipStream(repoRoot, args, maxGzBytes) {
|
|
|
17814
17850
|
finish();
|
|
17815
17851
|
});
|
|
17816
17852
|
gzip.on("error", (err) => {
|
|
17817
|
-
if (!overflowed) streamError ??= err;
|
|
17853
|
+
if (!overflowed && !rawOverflowed) streamError ??= err;
|
|
17818
17854
|
gzipDone = true;
|
|
17819
17855
|
finish();
|
|
17820
17856
|
});
|
|
@@ -17855,7 +17891,8 @@ async function createTreeDiffPatchGz(repoRoot, fromTreeSha, toTreeSha, options =
|
|
|
17855
17891
|
const { gz, rawBytes } = await gitGzipStream(
|
|
17856
17892
|
repoRoot,
|
|
17857
17893
|
["diff", "--binary", filteredFromTreeSha, filteredToTreeSha],
|
|
17858
|
-
options.maxPatchGzBytes ?? MAX_PATCH_GZ_BYTES
|
|
17894
|
+
options.maxPatchGzBytes ?? MAX_PATCH_GZ_BYTES,
|
|
17895
|
+
resolveMaxPatchRawBytes(options.maxPatchRawBytes)
|
|
17859
17896
|
);
|
|
17860
17897
|
if (rawBytes === 0) return null;
|
|
17861
17898
|
return gz;
|
|
@@ -18452,6 +18489,8 @@ async function sweepStaleLockFiles(ttlMs = STALE_LOCK_TTL_MS3, now = Date.now())
|
|
|
18452
18489
|
// src/git-traces/pending-captures.ts
|
|
18453
18490
|
var MAX_CAPTURES = 128;
|
|
18454
18491
|
var MAX_PENDING_BYTES2 = 2 * 1024 * 1024 * 1024;
|
|
18492
|
+
var MAX_OVERSIZED_CAPTURE_BYTES = 4 * 1024 * 1024 * 1024;
|
|
18493
|
+
var MAX_OVERSIZED_ARTIFACT_BYTES = 4 * 1024 * 1024 * 1024;
|
|
18455
18494
|
var PendingCaptureLimitError = class extends Error {
|
|
18456
18495
|
};
|
|
18457
18496
|
var STRANDED_MIN_AGE_MS = 10 * 60 * 1e3;
|
|
@@ -18664,6 +18703,11 @@ function pendingBytes(records) {
|
|
|
18664
18703
|
0
|
|
18665
18704
|
);
|
|
18666
18705
|
}
|
|
18706
|
+
function artifactByteLimit(records, captureId) {
|
|
18707
|
+
const record = records.length === 1 ? records[0] : void 0;
|
|
18708
|
+
const retained = record ? chargedBytes(record) : 0;
|
|
18709
|
+
return record?.id === captureId && record.oversized === true && retained >= 0 && retained <= MAX_OVERSIZED_CAPTURE_BYTES ? retained + MAX_OVERSIZED_ARTIFACT_BYTES : MAX_PENDING_BYTES2;
|
|
18710
|
+
}
|
|
18667
18711
|
function warnMissingBase(repoRoot, base) {
|
|
18668
18712
|
appendLog(
|
|
18669
18713
|
"warn",
|
|
@@ -18818,10 +18862,15 @@ function storePendingCapture(params) {
|
|
|
18818
18862
|
const pendingBefore = queueDiskBytes(
|
|
18819
18863
|
queueDirectory(params.repoRoot, params.tool, params.sessionId)
|
|
18820
18864
|
) + existing.reduce((sum, item) => sum + chargedBytes(item), 0);
|
|
18821
|
-
|
|
18822
|
-
if (existing.length
|
|
18865
|
+
let incomingBytes = retainedBytes + Buffer.byteLength(JSON.stringify(record));
|
|
18866
|
+
if (existing.length === 0 && pendingBefore === 0 && incomingBytes > MAX_PENDING_BYTES2) {
|
|
18867
|
+
record.oversized = true;
|
|
18868
|
+
incomingBytes = retainedBytes + Buffer.byteLength(JSON.stringify(record));
|
|
18869
|
+
}
|
|
18870
|
+
const maxBytes = record.oversized ? MAX_OVERSIZED_CAPTURE_BYTES : MAX_PENDING_BYTES2;
|
|
18871
|
+
if (existing.some((item) => item.oversized === true) || existing.length >= MAX_CAPTURES || pendingBefore + incomingBytes > maxBytes) {
|
|
18823
18872
|
throw new PendingCaptureLimitError(
|
|
18824
|
-
`Pending Git capture limit reached (count=${existing.length}, maxCount=${MAX_CAPTURES}, pendingBytes=${pendingBefore}, incomingBytes=${incomingBytes}, retainedBytes=${retainedBytes}, maxBytes=${
|
|
18873
|
+
`Pending Git capture limit reached (count=${existing.length}, maxCount=${MAX_CAPTURES}, pendingBytes=${pendingBefore}, incomingBytes=${incomingBytes}, retainedBytes=${retainedBytes}, maxBytes=${maxBytes}); existing captures retained`
|
|
18825
18874
|
);
|
|
18826
18875
|
}
|
|
18827
18876
|
const directory = captureDirectory(record);
|
|
@@ -18863,7 +18912,7 @@ function storePendingCapture(params) {
|
|
|
18863
18912
|
durableDetails = `capture=${record.id}, durableCapturedAt=${durableCapturedAt}`;
|
|
18864
18913
|
appendLog(
|
|
18865
18914
|
"info",
|
|
18866
|
-
`git-traces: capture queued (repo=${record.repoRoot}, session=${record.sessionId}, capture=${record.id}, recordedAt=${record.recordedAt}, captureStartedAt=${record.captureStartedAt}, capturedAt=${record.capturedAt}, sourceCapturedAt=${record.capturedAt}, durableCapturedAt=${durableCapturedAt}, pending=${existing.length + 1}, oldestPendingAgeMs=${Date.now() - (existing[0]?.capturedAt ?? record.capturedAt)}, retainedBytes=${record.retainedBytes}, pendingBytes=${pendingBefore + incomingBytes})`
|
|
18915
|
+
`git-traces: capture queued (repo=${record.repoRoot}, session=${record.sessionId}, capture=${record.id}, recordedAt=${record.recordedAt}, captureStartedAt=${record.captureStartedAt}, capturedAt=${record.capturedAt}, sourceCapturedAt=${record.capturedAt}, durableCapturedAt=${durableCapturedAt}, pending=${existing.length + 1}, oldestPendingAgeMs=${Date.now() - (existing[0]?.capturedAt ?? record.capturedAt)}, retainedBytes=${record.retainedBytes}, pendingBytes=${pendingBefore + incomingBytes}, oversized=${record.oversized === true})`
|
|
18867
18916
|
);
|
|
18868
18917
|
return record;
|
|
18869
18918
|
} finally {
|
|
@@ -18913,18 +18962,30 @@ async function preparePendingUpload(context, contributionId, filename, buffer) {
|
|
|
18913
18962
|
context.record.tool,
|
|
18914
18963
|
context.record.sessionId
|
|
18915
18964
|
);
|
|
18916
|
-
if (pendingBytes(records) + buffer.byteLength > MAX_PENDING_BYTES2) {
|
|
18917
|
-
throw new Error(
|
|
18918
|
-
`Pending Git artifact byte limit reached (${MAX_PENDING_BYTES2}); capture retained`
|
|
18919
|
-
);
|
|
18920
|
-
}
|
|
18921
18965
|
const file = `${crypto7.createHash("sha256").update(key).digest("hex")}.artifact`;
|
|
18922
|
-
|
|
18923
|
-
context.record.uploads[key] = {
|
|
18966
|
+
const upload = {
|
|
18924
18967
|
file,
|
|
18925
18968
|
bytes: buffer.byteLength,
|
|
18926
18969
|
sha256: crypto7.createHash("sha256").update(buffer).digest("hex")
|
|
18927
18970
|
};
|
|
18971
|
+
const nextRecordBytes = Buffer.byteLength(
|
|
18972
|
+
JSON.stringify({
|
|
18973
|
+
...context.record,
|
|
18974
|
+
uploads: { ...context.record.uploads, [key]: upload }
|
|
18975
|
+
})
|
|
18976
|
+
);
|
|
18977
|
+
const recordGrowth = Math.max(
|
|
18978
|
+
0,
|
|
18979
|
+
nextRecordBytes - fs21.statSync(path20.join(directory, "capture.json")).size
|
|
18980
|
+
);
|
|
18981
|
+
const maxBytes = artifactByteLimit(records, context.record.id);
|
|
18982
|
+
if (pendingBytes(records) + buffer.byteLength + recordGrowth > maxBytes) {
|
|
18983
|
+
throw new Error(
|
|
18984
|
+
`Pending Git artifact byte limit reached (${maxBytes}); capture retained`
|
|
18985
|
+
);
|
|
18986
|
+
}
|
|
18987
|
+
writeDurable(path20.join(directory, file), buffer);
|
|
18988
|
+
context.record.uploads[key] = upload;
|
|
18928
18989
|
try {
|
|
18929
18990
|
context.save();
|
|
18930
18991
|
} catch (err) {
|
|
@@ -19054,7 +19115,7 @@ async function uploadArtifact(client, contributionId, filename, mimeType, buffer
|
|
|
19054
19115
|
}
|
|
19055
19116
|
|
|
19056
19117
|
// package.json
|
|
19057
|
-
var version = "0.9.
|
|
19118
|
+
var version = "0.9.15";
|
|
19058
19119
|
|
|
19059
19120
|
// src/version.ts
|
|
19060
19121
|
var CLI_VERSION = version;
|
|
@@ -20643,7 +20704,6 @@ import path22 from "path";
|
|
|
20643
20704
|
var GIT_TRACES_SLUG = "git-traces";
|
|
20644
20705
|
var MAX_FORK_SWEEP_THREADS2 = 8;
|
|
20645
20706
|
var MAX_UPLOAD_BYTES = 500 * 1024 * 1024;
|
|
20646
|
-
var MAX_BASELINE_BUNDLE_UPLOAD_BYTES = 1024 * 1024 * 1024;
|
|
20647
20707
|
var STALE_SCOPED_STATE_TTL_MS = 24 * 60 * 60 * 1e3;
|
|
20648
20708
|
var REBASELINE_AFTER_DIFF_FAILURES = 2;
|
|
20649
20709
|
async function withRepoCaptureLock(repoRoot, capture) {
|
|
@@ -20788,7 +20848,7 @@ function execGit(cwd, args) {
|
|
|
20788
20848
|
}).toString("utf-8").trim();
|
|
20789
20849
|
}
|
|
20790
20850
|
function canUploadFile(filename, buffer) {
|
|
20791
|
-
const limit = filename.endsWith("-baseline.bundle") ?
|
|
20851
|
+
const limit = filename.endsWith("-baseline.bundle") ? MAX_BASELINE_BUNDLE_BYTES : MAX_UPLOAD_BYTES;
|
|
20792
20852
|
if (buffer.byteLength <= limit) return true;
|
|
20793
20853
|
appendLog(
|
|
20794
20854
|
"warn",
|
|
@@ -21871,6 +21931,75 @@ async function refreshLineageBaseline(params) {
|
|
|
21871
21931
|
return false;
|
|
21872
21932
|
}
|
|
21873
21933
|
}
|
|
21934
|
+
async function uploadLargeCaptureBaseline(params) {
|
|
21935
|
+
const { repo, state, tool, persistState, limits } = params;
|
|
21936
|
+
const pending = currentPendingCapture(repo.repoRoot);
|
|
21937
|
+
if (!pending) return "failed";
|
|
21938
|
+
const client = await loadRepoClient(repo);
|
|
21939
|
+
if (!client) return "skipped";
|
|
21940
|
+
if (state.contributionId === null || !state.baselineUploaded) {
|
|
21941
|
+
const initial = buildInitialBaselineArtifactsForState(
|
|
21942
|
+
repo.repoRoot,
|
|
21943
|
+
tool,
|
|
21944
|
+
state,
|
|
21945
|
+
limits
|
|
21946
|
+
);
|
|
21947
|
+
if (!initial || !canUploadEpochBaselineArtifacts(state.epoch, initial))
|
|
21948
|
+
return "failed";
|
|
21949
|
+
if (!await registerInitialContribution({
|
|
21950
|
+
...params,
|
|
21951
|
+
client,
|
|
21952
|
+
artifacts: initial
|
|
21953
|
+
}))
|
|
21954
|
+
return "failed";
|
|
21955
|
+
}
|
|
21956
|
+
if (state.contributionId === null) return "failed";
|
|
21957
|
+
const nextEpoch = await reserveEpoch(state, persistState);
|
|
21958
|
+
const artifacts = await openEpoch({
|
|
21959
|
+
repoRoot: repo.repoRoot,
|
|
21960
|
+
client,
|
|
21961
|
+
contributionId: state.contributionId,
|
|
21962
|
+
sessionId: state.sessionId,
|
|
21963
|
+
tool,
|
|
21964
|
+
epoch: nextEpoch,
|
|
21965
|
+
prevHeadSha: state.headSha || null,
|
|
21966
|
+
transitionKind: "initial",
|
|
21967
|
+
startedAt: state.startedAt,
|
|
21968
|
+
limits,
|
|
21969
|
+
lineage: state.codexLineage,
|
|
21970
|
+
previousScan: pending.record.scan,
|
|
21971
|
+
provenance: {
|
|
21972
|
+
recovery: {
|
|
21973
|
+
reason: "patch-too-large",
|
|
21974
|
+
trigger: "stop-diff",
|
|
21975
|
+
detectedAt: new Date(pending.record.capturedAt).toISOString(),
|
|
21976
|
+
abandonedEpoch: state.epoch,
|
|
21977
|
+
abandonedBaselineSha: state.baselineSha,
|
|
21978
|
+
abandonedUploadedTurns: state.turnCount
|
|
21979
|
+
}
|
|
21980
|
+
}
|
|
21981
|
+
});
|
|
21982
|
+
if (!artifacts) return "failed";
|
|
21983
|
+
Object.assign(state, {
|
|
21984
|
+
baselineSha: artifacts.baselineSha,
|
|
21985
|
+
baselineTreeSha: artifacts.baselineTreeSha,
|
|
21986
|
+
lastSnapshotSha: artifacts.baselineSha,
|
|
21987
|
+
lastSnapshotTreeSha: artifacts.baselineTreeSha,
|
|
21988
|
+
epoch: nextEpoch,
|
|
21989
|
+
turnCount: 0,
|
|
21990
|
+
headSha: artifacts.headSha,
|
|
21991
|
+
omittedKeys: artifacts.omittedKeys,
|
|
21992
|
+
omissionScan: artifacts.scan,
|
|
21993
|
+
codexLineageStamped: artifacts.uploadedLineage
|
|
21994
|
+
});
|
|
21995
|
+
delete state.diffFailureCount;
|
|
21996
|
+
await persistState(state);
|
|
21997
|
+
appendLog(
|
|
21998
|
+
"info",
|
|
21999
|
+
`git-traces: large patch captured as baseline (repo=${repo.repoRoot}, session=${state.sessionId}, capture=${pending.record.id}, epoch=${nextEpoch}, tree=${artifacts.baselineTreeSha})`
|
|
22000
|
+
);
|
|
22001
|
+
return "uploaded";
|
|
22002
|
+
}
|
|
21874
22003
|
async function recoverFromWedgedDiff(params) {
|
|
21875
22004
|
const {
|
|
21876
22005
|
repo,
|
|
@@ -22362,6 +22491,20 @@ async function processStopRepo(repo, tool, sessionId, recordedAt, lineageCheck,
|
|
|
22362
22491
|
}
|
|
22363
22492
|
);
|
|
22364
22493
|
} catch (err) {
|
|
22494
|
+
if (err instanceof GitPatchTooLargeError) {
|
|
22495
|
+
appendLog(
|
|
22496
|
+
"warn",
|
|
22497
|
+
`git-traces: turn patch exceeds Git apply limit; attempting frozen baseline fallback (repo=${repoRoot}, session=${state.sessionId}, rawBytes=${err.rawBytes}, maxRawBytes=${err.maxRawBytes})`
|
|
22498
|
+
);
|
|
22499
|
+
const outcome = await uploadLargeCaptureBaseline({
|
|
22500
|
+
repo,
|
|
22501
|
+
state,
|
|
22502
|
+
tool,
|
|
22503
|
+
persistState,
|
|
22504
|
+
limits
|
|
22505
|
+
});
|
|
22506
|
+
return outcome === "uploaded" ? await finishSuccessfulStop("uploaded") : outcome;
|
|
22507
|
+
}
|
|
22365
22508
|
if (isMissingObjectError(err)) {
|
|
22366
22509
|
logMissingBaselineObjects(repoRoot, state, "stop-diff", err);
|
|
22367
22510
|
state.diffFailureCount = REBASELINE_AFTER_DIFF_FAILURES;
|