codex-overleaf-link 2.3.6 → 2.4.0
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/README.md +59 -34
- package/README.zh-CN.md +543 -0
- package/extension/bootstrap/manifest.template.json +1 -1
- package/extension/src/background.js +3 -0
- package/extension/src/content/activeTurnControl.js +1 -0
- package/extension/src/content/assetTransferBroker.js +2 -0
- package/extension/src/content/contentRuntime.js +53 -50
- package/extension/src/content/contextTray.js +4 -0
- package/extension/src/content/diagnosticsController.js +4 -0
- package/extension/src/content/diagnosticsPanel.js +128 -4
- package/extension/src/content/generated/content.bundle.js +583 -112
- package/extension/src/content/generated/content.bundle.meta.json +4 -3
- package/extension/src/content/legacyGlobalRegistry.js +1 -0
- package/extension/src/content/modelPicker.js +21 -9
- package/extension/src/content/modelPickerSupport.js +38 -1
- package/extension/src/content/nativeCompatibilityController.js +4 -1
- package/extension/src/content/otWarmMirror.js +34 -30
- package/extension/src/content/otWarmMirrorController.js +20 -0
- package/extension/src/content/pageBridgeClient.js +2 -0
- package/extension/src/content/runResultActions.js +16 -1
- package/extension/src/content/runTimelineView.js +1 -1
- package/extension/src/content/sessionForkController.js +20 -11
- package/extension/src/content/trackedChangeCaptureController.js +153 -0
- package/extension/src/content/writebackOrchestrator.js +31 -0
- package/extension/src/page/binaryAssetUploader.js +101 -29
- package/extension/src/page/overleafRealtimeObserver.js +4 -1
- package/extension/src/page/textFileCreator.js +493 -0
- package/extension/src/page/trackedChangeCapture.js +342 -0
- package/extension/src/page/trackedChangesLifecycle.js +145 -149
- package/extension/src/page/treeOperations.js +30 -2
- package/extension/src/page/writebackRouter.js +94 -48
- package/extension/src/pageBridge.js +62 -25
- package/extension/src/shared/compatibility.js +1 -1
- package/extension/src/shared/pageRpcContract.js +2 -1
- package/extension/src/shared/sessionState.js +6 -2
- package/extension/src/shared/storageDb.js +10 -12
- package/extension/src/shared/storageRunActions.js +29 -1
- package/extension/src/shared/writebackSettlement.js +19 -5
- package/extension/styles/panel.css +55 -10
- package/native-host/src/taskRunnerRuntime.js +25 -0
- package/package.json +5 -1
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
if (typeof document !== 'undefined' && document.documentElement) document.documentElement.setAttribute('data-codex-overleaf-source-digest', "f146d7e07b67706193fa5fcff26d7c9719826ac745aec9b745dd95c52413d27c");
|
|
1
2
|
(() => {
|
|
2
3
|
// extension/entries/content-entry.mjs
|
|
3
4
|
(function runClassicContentModule(module, exports, require2) {
|
|
@@ -7886,7 +7887,7 @@ ${block}`;
|
|
|
7886
7887
|
if (!result || typeof result !== "object" || result.ok === false) return result;
|
|
7887
7888
|
if (Array.isArray(result.skipped) && result.skipped.length > 0) return result;
|
|
7888
7889
|
const expectedFiles = Array.isArray(run?.undoExpectedFiles) ? run.undoExpectedFiles : [];
|
|
7889
|
-
if (!expectedFiles.length || isUndoVerifiedContentMatching(run, result)) return result;
|
|
7890
|
+
if (!expectedFiles.length || isUndoVerifiedContentMatching(run, result, options2)) return result;
|
|
7890
7891
|
const path = expectedFiles.find((entry) => typeof entry?.path === "string")?.path || "";
|
|
7891
7892
|
appendSyntheticFailure(result, options2.buildFailure?.("undo_not_verified", { path, type: "undo" }, {
|
|
7892
7893
|
changedDocument: true,
|
|
@@ -7895,12 +7896,13 @@ ${block}`;
|
|
|
7895
7896
|
}), path, "undo_not_verified", "undo");
|
|
7896
7897
|
return result;
|
|
7897
7898
|
}
|
|
7898
|
-
function isUndoVerifiedContentMatching(run, result) {
|
|
7899
|
+
function isUndoVerifiedContentMatching(run, result, options2 = {}) {
|
|
7899
7900
|
const expectedByPath = new Map((run?.undoExpectedFiles || []).filter((file) => typeof file?.path === "string" && typeof file?.content === "string").map((file) => [normalizeSettlementPath(file.path), file.content]).filter(([path]) => path));
|
|
7900
7901
|
if (!expectedByPath.size) return true;
|
|
7902
|
+
const postByPath = new Map((Array.isArray(options2?.postFiles) ? options2.postFiles : []).filter((file) => typeof file?.path === "string" && typeof file?.content === "string").map((file) => [normalizeSettlementPath(file.path), file.content]));
|
|
7901
7903
|
const applied = Array.isArray(result?.applied) ? result.applied : [];
|
|
7902
7904
|
return Array.from(expectedByPath).every(
|
|
7903
|
-
([path, expected]) => applied.some((entry) => isVerifiedUndoEntryForPath(entry, path, expected))
|
|
7905
|
+
([path, expected]) => applied.some((entry) => isVerifiedUndoEntryForPath(entry, path, expected, postByPath.get(path)))
|
|
7904
7906
|
);
|
|
7905
7907
|
}
|
|
7906
7908
|
function isUndoResultEffectivelyApplied(run, result, undoOperations = []) {
|
|
@@ -7914,7 +7916,7 @@ ${block}`;
|
|
|
7914
7916
|
(item) => isVerifiedUndoEntryForPath(item, path, expectedByPath.get(path))
|
|
7915
7917
|
));
|
|
7916
7918
|
}
|
|
7917
|
-
function isVerifiedUndoEntryForPath(entry, path, expectedContent) {
|
|
7919
|
+
function isVerifiedUndoEntryForPath(entry, path, expectedContent, postContent) {
|
|
7918
7920
|
const inner = entry?.result || {};
|
|
7919
7921
|
if (inner.ok === false) return false;
|
|
7920
7922
|
const normalizedPath = normalizeSettlementPath(path);
|
|
@@ -7929,7 +7931,12 @@ ${block}`;
|
|
|
7929
7931
|
return inner.method === "overleaf-editor-undo" && inner.verified === true && inner.verifiedContent === expectedContent;
|
|
7930
7932
|
}
|
|
7931
7933
|
if (key === `snapshot-undo:${normalizedPath}`) {
|
|
7932
|
-
|
|
7934
|
+
if (inner.verifiedContent === expectedContent) return true;
|
|
7935
|
+
const proof = inner.undoRebaseProof, before = proof?.beforeUndoContent;
|
|
7936
|
+
if (inner.verified !== true || proof?.version !== 1 || normalizeSettlementPath(proof.path) !== normalizedPath || typeof before !== "string" || typeof postContent !== "string" || !postContent || typeof inner.verifiedContent !== "string") return false;
|
|
7937
|
+
const start = before.indexOf(postContent);
|
|
7938
|
+
if (start < 0 || before.indexOf(postContent, start + 1) >= 0) return false;
|
|
7939
|
+
return inner.verifiedContent === before.slice(0, start) + expectedContent + before.slice(start + postContent.length);
|
|
7933
7940
|
}
|
|
7934
7941
|
return false;
|
|
7935
7942
|
}
|
|
@@ -8775,6 +8782,7 @@ ${block}`;
|
|
|
8775
8782
|
undoExpectedFiles: normalizeRunFiles(run.undoExpectedFiles),
|
|
8776
8783
|
undoStatus: sanitizeAssistantVisibleText(run.undoStatus),
|
|
8777
8784
|
nativeRequestId: sanitizeAssistantVisibleText(run.nativeRequestId),
|
|
8785
|
+
codexThreadId: sanitizeAssistantVisibleText(run.codexThreadId),
|
|
8778
8786
|
codexTurnId: sanitizeAssistantVisibleText(run.codexTurnId),
|
|
8779
8787
|
forkSnapshot: run.forkSnapshot === true,
|
|
8780
8788
|
forkSourceRunId: sanitizeAssistantVisibleText(run.forkSourceRunId),
|
|
@@ -8792,6 +8800,9 @@ ${block}`;
|
|
|
8792
8800
|
if (run.changedDocument === true) {
|
|
8793
8801
|
normalized.changedDocument = true;
|
|
8794
8802
|
}
|
|
8803
|
+
if (Array.isArray(run.trackedChangeCaptures) && run.trackedChangeCaptures.length && !run.forkSnapshot) {
|
|
8804
|
+
normalized.trackedChangeCaptures = sanitizeAssistantVisibleValue(run.trackedChangeCaptures);
|
|
8805
|
+
}
|
|
8795
8806
|
applyTrackedChangeStatus(normalized, run.trackedChangeStatus);
|
|
8796
8807
|
return normalized;
|
|
8797
8808
|
}
|
|
@@ -9226,6 +9237,7 @@ ${block}`;
|
|
|
9226
9237
|
undoExpectedFiles: undoPayload.undoExpectedFiles,
|
|
9227
9238
|
undoStatus: summarizeTextForStorage(run.undoStatus, "undo status"),
|
|
9228
9239
|
nativeRequestId: normalizeTextField(run.nativeRequestId, 160),
|
|
9240
|
+
codexThreadId: normalizeTextField(run.codexThreadId, 160),
|
|
9229
9241
|
codexTurnId: normalizeTextField(run.codexTurnId, 160),
|
|
9230
9242
|
forkSnapshot: run.forkSnapshot === true,
|
|
9231
9243
|
forkSourceRunId: normalizeTextField(run.forkSourceRunId, 160),
|
|
@@ -9558,6 +9570,7 @@ ${block}`;
|
|
|
9558
9570
|
setActiveSession,
|
|
9559
9571
|
updateActiveSession,
|
|
9560
9572
|
normalizeRuns,
|
|
9573
|
+
normalizeProjectReferenceFiles,
|
|
9561
9574
|
prepareStateForStorage,
|
|
9562
9575
|
estimateJsonBytes,
|
|
9563
9576
|
computeSafeTaskSummary
|
|
@@ -9798,7 +9811,13 @@ ${block}`;
|
|
|
9798
9811
|
} catch (_error) {
|
|
9799
9812
|
return empty;
|
|
9800
9813
|
}
|
|
9801
|
-
|
|
9814
|
+
if (getUtf8ByteLength(serialized) > MAX_PERSISTED_ACTION_BYTES_PER_RUN) return empty;
|
|
9815
|
+
const captures = cloneSerializableArray(run.trackedChangeCaptures);
|
|
9816
|
+
if (captures.length) {
|
|
9817
|
+
const extended = { ...payload, trackedChangeCaptures: captures };
|
|
9818
|
+
if (getUtf8ByteLength(JSON.stringify(extended)) <= MAX_PERSISTED_ACTION_BYTES_PER_RUN) return extended;
|
|
9819
|
+
}
|
|
9820
|
+
return payload;
|
|
9802
9821
|
}
|
|
9803
9822
|
function emptyActionPayload() {
|
|
9804
9823
|
return {
|
|
@@ -9826,6 +9845,37 @@ ${block}`;
|
|
|
9826
9845
|
}
|
|
9827
9846
|
return value.length * 2;
|
|
9828
9847
|
}
|
|
9848
|
+
function compactRunExecutionSnapshot(run, normalizeString) {
|
|
9849
|
+
var snapshot = run && run.executionSnapshot;
|
|
9850
|
+
if (!snapshot || typeof snapshot !== "object" || Array.isArray(snapshot)) return {};
|
|
9851
|
+
var normalize = typeof normalizeString === "function" ? normalizeString : String;
|
|
9852
|
+
var compact = {};
|
|
9853
|
+
var fields = [
|
|
9854
|
+
"schemaVersion",
|
|
9855
|
+
"mode",
|
|
9856
|
+
"providerId",
|
|
9857
|
+
"providerRevision",
|
|
9858
|
+
"model",
|
|
9859
|
+
"reasoningEffort",
|
|
9860
|
+
"speedTier",
|
|
9861
|
+
"autoRecompile",
|
|
9862
|
+
"requireReviewing",
|
|
9863
|
+
"capturedAt",
|
|
9864
|
+
"source"
|
|
9865
|
+
];
|
|
9866
|
+
for (var key of fields) {
|
|
9867
|
+
if (!Object.prototype.hasOwnProperty.call(snapshot, key)) continue;
|
|
9868
|
+
var value = snapshot[key];
|
|
9869
|
+
if (typeof value === "string") compact[key] = normalize(value);
|
|
9870
|
+
else if (value === null || typeof value === "number" || typeof value === "boolean") compact[key] = value;
|
|
9871
|
+
}
|
|
9872
|
+
if (Array.isArray(snapshot.focusFiles)) {
|
|
9873
|
+
compact.focusFiles = snapshot.focusFiles.slice(0, 100).filter(function(value2) {
|
|
9874
|
+
return typeof value2 === "string";
|
|
9875
|
+
}).map(normalize);
|
|
9876
|
+
}
|
|
9877
|
+
return { executionSnapshot: compact };
|
|
9878
|
+
}
|
|
9829
9879
|
function compactProviderSnapshot(value) {
|
|
9830
9880
|
return {
|
|
9831
9881
|
providerId: typeof value.providerId === "string" && value.providerId ? value.providerId : "builtin",
|
|
@@ -9868,6 +9918,7 @@ ${block}`;
|
|
|
9868
9918
|
compactRunsForStorage,
|
|
9869
9919
|
compactRunActionPayload,
|
|
9870
9920
|
compactProviderSnapshot,
|
|
9921
|
+
compactRunExecutionSnapshot,
|
|
9871
9922
|
hashString
|
|
9872
9923
|
};
|
|
9873
9924
|
});
|
|
@@ -9945,19 +9996,21 @@ ${block}`;
|
|
|
9945
9996
|
require2("./storageRunActions"),
|
|
9946
9997
|
require2("./runInputQueue"),
|
|
9947
9998
|
require2("./settlementFacts"),
|
|
9948
|
-
require2("./storageSessionClaims")
|
|
9999
|
+
require2("./storageSessionClaims"),
|
|
10000
|
+
require2("./sessionState")
|
|
9949
10001
|
);
|
|
9950
10002
|
} else {
|
|
9951
10003
|
root.CodexOverleafModuleRegistry.define("StorageDb", [
|
|
9952
10004
|
"StorageRunActions",
|
|
9953
10005
|
"RunInputQueue",
|
|
9954
10006
|
"SettlementFacts",
|
|
9955
|
-
"StorageSessionClaims"
|
|
10007
|
+
"StorageSessionClaims",
|
|
10008
|
+
"SessionState"
|
|
9956
10009
|
], factory);
|
|
9957
10010
|
}
|
|
9958
|
-
})(typeof globalThis !== "undefined" ? globalThis : window, function storageDbFactory(StorageRunActions, RunInputQueue, SettlementFacts, StorageSessionClaims) {
|
|
10011
|
+
})(typeof globalThis !== "undefined" ? globalThis : window, function storageDbFactory(StorageRunActions, RunInputQueue, SettlementFacts, StorageSessionClaims, SessionState) {
|
|
9959
10012
|
"use strict";
|
|
9960
|
-
if (!StorageRunActions?.compactRunsForStorage || !StorageRunActions?.compactRunActionPayload || !StorageRunActions?.compactProviderSnapshot || !StorageRunActions?.compactStructuredEventValue || !StorageRunActions?.hashString || !RunInputQueue?.compactForStorage || !SettlementFacts?.compactSettlementFacts || !StorageSessionClaims?.createSessionClaimer) {
|
|
10013
|
+
if (!StorageRunActions?.compactRunsForStorage || !StorageRunActions?.compactRunActionPayload || !StorageRunActions?.compactProviderSnapshot || !StorageRunActions?.compactRunExecutionSnapshot || !StorageRunActions?.compactStructuredEventValue || !StorageRunActions?.hashString || !RunInputQueue?.compactForStorage || !SettlementFacts?.compactSettlementFacts || !StorageSessionClaims?.createSessionClaimer) {
|
|
9961
10014
|
throw new Error("Codex Overleaf storage run-action helpers are unavailable.");
|
|
9962
10015
|
}
|
|
9963
10016
|
var TARGET_SCHEMA_VERSION = 3;
|
|
@@ -10225,6 +10278,7 @@ ${block}`;
|
|
|
10225
10278
|
codexThreadId: typeof input.codexThreadId === "string" ? input.codexThreadId : "",
|
|
10226
10279
|
status: typeof input.status === "string" && input.status ? input.status : "active",
|
|
10227
10280
|
focusFiles: normalizePathList(input.focusFiles),
|
|
10281
|
+
projectReferenceFiles: SessionState.normalizeProjectReferenceFiles(input.projectReferenceFiles),
|
|
10228
10282
|
pendingInputs: RunInputQueue.compactForStorage(input.pendingInputs, {
|
|
10229
10283
|
normalizeField: normalizeTextField,
|
|
10230
10284
|
normalizeDisplay: normalizeDisplayTextForStorage,
|
|
@@ -10264,8 +10318,8 @@ ${block}`;
|
|
|
10264
10318
|
}
|
|
10265
10319
|
}
|
|
10266
10320
|
function deriveSafeTaskSummaryFromInput(input) {
|
|
10267
|
-
var
|
|
10268
|
-
if (!
|
|
10321
|
+
var SessionState2 = loadSessionState();
|
|
10322
|
+
if (!SessionState2 || !(SessionState2.computeSafeTaskSummary instanceof Function)) {
|
|
10269
10323
|
return "";
|
|
10270
10324
|
}
|
|
10271
10325
|
var task = typeof input.task === "string" && input.task ? input.task : "";
|
|
@@ -10275,7 +10329,7 @@ ${block}`;
|
|
|
10275
10329
|
task = firstRun.task;
|
|
10276
10330
|
}
|
|
10277
10331
|
}
|
|
10278
|
-
return
|
|
10332
|
+
return SessionState2.computeSafeTaskSummary(task);
|
|
10279
10333
|
}
|
|
10280
10334
|
var _sessionStateCache = null;
|
|
10281
10335
|
function loadSessionState() {
|
|
@@ -10560,12 +10614,7 @@ ${block}`;
|
|
|
10560
10614
|
});
|
|
10561
10615
|
}
|
|
10562
10616
|
function compactRunsForStorage(runs, options2) {
|
|
10563
|
-
return StorageRunActions.compactRunsForStorage(
|
|
10564
|
-
runs,
|
|
10565
|
-
options2,
|
|
10566
|
-
SESSION_STORAGE_LIMITS.maxRunsPerSession,
|
|
10567
|
-
compactRunForStorage
|
|
10568
|
-
);
|
|
10617
|
+
return StorageRunActions.compactRunsForStorage(runs, options2, SESSION_STORAGE_LIMITS.maxRunsPerSession, compactRunForStorage);
|
|
10569
10618
|
}
|
|
10570
10619
|
function compactRunForStorage(run, keepActionPayload) {
|
|
10571
10620
|
var actionPayload = StorageRunActions.compactRunActionPayload(run, keepActionPayload);
|
|
@@ -10574,6 +10623,9 @@ ${block}`;
|
|
|
10574
10623
|
task: normalizeDisplayTextForStorage(run.task || "untitled task", SESSION_STORAGE_LIMITS.taskChars),
|
|
10575
10624
|
mode: typeof run.mode === "string" ? redactSecretLikeText(run.mode) : "",
|
|
10576
10625
|
...StorageRunActions.compactProviderSnapshot(run),
|
|
10626
|
+
...StorageRunActions.compactRunExecutionSnapshot(run, function(text) {
|
|
10627
|
+
return normalizeTextField(text, 4096);
|
|
10628
|
+
}),
|
|
10577
10629
|
model: normalizeTextField(run.model, 80),
|
|
10578
10630
|
reasoningEffort: typeof run.reasoningEffort === "string" ? redactSecretLikeText(run.reasoningEffort) : "",
|
|
10579
10631
|
speedTier: typeof run.speedTier === "string" ? redactSecretLikeText(run.speedTier) : "",
|
|
@@ -10589,8 +10641,10 @@ ${block}`;
|
|
|
10589
10641
|
undoBaseFiles: actionPayload.undoBaseFiles,
|
|
10590
10642
|
undoTrackedChanges: actionPayload.undoTrackedChanges,
|
|
10591
10643
|
undoExpectedFiles: actionPayload.undoExpectedFiles,
|
|
10644
|
+
...actionPayload.trackedChangeCaptures ? { trackedChangeCaptures: actionPayload.trackedChangeCaptures } : {},
|
|
10592
10645
|
undoStatus: normalizeDisplayTextForStorage(run.undoStatus, SESSION_STORAGE_LIMITS.statusTextChars),
|
|
10593
10646
|
nativeRequestId: normalizeTextField(run.nativeRequestId, 160),
|
|
10647
|
+
codexThreadId: normalizeTextField(run.codexThreadId, 160),
|
|
10594
10648
|
codexTurnId: normalizeTextField(run.codexTurnId, 160),
|
|
10595
10649
|
nativeEventSeq: Number.isFinite(Number(run.nativeEventSeq)) ? Number(run.nativeEventSeq) : 0,
|
|
10596
10650
|
queueItemId: normalizeTextField(run.queueItemId, 160)
|
|
@@ -11775,7 +11829,7 @@ ${block}`;
|
|
|
11775
11829
|
const MIN_NATIVE_VERSION = "1.0.0";
|
|
11776
11830
|
const MIN_COMPATIBLE_NATIVE_VERSION = "1.0.0";
|
|
11777
11831
|
const MIN_COMPATIBLE_EXTENSION_VERSION = "1.0.0";
|
|
11778
|
-
const BUILD_TARGET_VERSION = "2.
|
|
11832
|
+
const BUILD_TARGET_VERSION = "2.4.0";
|
|
11779
11833
|
const DEFAULT_CHROME_EXTENSION_ID = "illdpneeeopfffmiepaejglgmhpmdhdc";
|
|
11780
11834
|
const REQUIRED_CAPABILITIES = Object.freeze([
|
|
11781
11835
|
"bridgePing",
|
|
@@ -12078,7 +12132,7 @@ ${block}`;
|
|
|
12078
12132
|
if (root) root.CodexOverleafPageRpcContract = api;
|
|
12079
12133
|
})(typeof window !== "undefined" ? window : typeof globalThis !== "undefined" ? globalThis : this, function() {
|
|
12080
12134
|
"use strict";
|
|
12081
|
-
var REVISION = "2026-
|
|
12135
|
+
var REVISION = "2026-09-14-native-text-upload-v28";
|
|
12082
12136
|
var METHODS = freezeCatalog({
|
|
12083
12137
|
initializeCapability: entry("bridge.initialize", "control", "none", "default", false, "none"),
|
|
12084
12138
|
probe: entry("bridge.probe", "read", "none", "default", false, "safe"),
|
|
@@ -12095,6 +12149,7 @@ ${block}`;
|
|
|
12095
12149
|
binaryUploadCommit: entry("asset.write", "document", "required", "writeback", true, "no_retry"),
|
|
12096
12150
|
binaryUploadAbort: entry("asset.stage", "cache", "none", "default", false, "idempotent"),
|
|
12097
12151
|
jumpToPosition: entry("editor.navigate", "navigation", "required", "default", false, "idempotent"),
|
|
12152
|
+
reconcileTrackedChangeCapture: entry("tracked_changes.read", "read", "required", "default", false, "safe"),
|
|
12098
12153
|
rejectTrackedChanges: entry("tracked_changes.reject", "document", "required", "lifecycle", true, "no_retry"),
|
|
12099
12154
|
acceptTrackedChanges: entry("tracked_changes.accept", "document", "required", "lifecycle", true, "no_retry"),
|
|
12100
12155
|
triggerCompile: entry("compile.trigger", "page_state", "required", "compile", false, "no_retry"),
|
|
@@ -13463,9 +13518,11 @@ ${block}`;
|
|
|
13463
13518
|
["src/page/overleafProjectSnapshot.js", "codex-overleaf-project-snapshot-script"],
|
|
13464
13519
|
["src/page/pageBridgeCapability.js", "codex-overleaf-page-bridge-capability-script"],
|
|
13465
13520
|
["src/page/treeOperations.js", "codex-overleaf-tree-operations-script", true],
|
|
13521
|
+
["src/page/textFileCreator.js", "codex-overleaf-text-file-creator-script", true],
|
|
13466
13522
|
["src/page/binaryAssetUploader.js", "codex-overleaf-binary-asset-uploader-script", true],
|
|
13467
13523
|
["src/page/snapshotRouter.js", "codex-overleaf-snapshot-router-script"],
|
|
13468
13524
|
["src/page/writeGuard.js", "codex-overleaf-write-guard-script", true],
|
|
13525
|
+
["src/page/trackedChangeCapture.js", "codex-overleaf-tracked-change-capture-script", true],
|
|
13469
13526
|
["src/page/trackedChangesLifecycle.js", "codex-overleaf-tracked-changes-lifecycle-script", true],
|
|
13470
13527
|
["src/page/writebackRouter.js", "codex-overleaf-writeback-router-script", true],
|
|
13471
13528
|
["src/pageBridge.js", "codex-overleaf-page-bridge-script", true]
|
|
@@ -13665,7 +13722,9 @@ ${block}`;
|
|
|
13665
13722
|
async function dispatch(payload, channelMethod) {
|
|
13666
13723
|
const compatibilityGate = await ensureForMethod(payload?.method);
|
|
13667
13724
|
if (!compatibilityGate.ok) return compatibilityGate.response;
|
|
13668
|
-
if (gatedMethods.has(payload?.method)
|
|
13725
|
+
if (gatedMethods.has(payload?.method) && payload.method !== "mirror.invalidate") {
|
|
13726
|
+
options2.throwIfCancellationRequested?.();
|
|
13727
|
+
}
|
|
13669
13728
|
return nativeChannel[channelMethod](
|
|
13670
13729
|
attachEvidence(payload, compatibilityGate.compatibility)
|
|
13671
13730
|
);
|
|
@@ -14318,8 +14377,10 @@ ${block}`;
|
|
|
14318
14377
|
merged.applied.push(...Array.isArray(result?.applied) ? result.applied : []);
|
|
14319
14378
|
merged.skipped.push(...Array.isArray(result?.skipped) ? result.skipped : []);
|
|
14320
14379
|
merged.trackedChanges.push(...Array.isArray(result?.trackedChanges) ? result.trackedChanges : []);
|
|
14380
|
+
if (result?.trackedChangeCaptures?.length) (merged.trackedChangeCaptures || (merged.trackedChangeCaptures = [])).push(...result.trackedChangeCaptures);
|
|
14321
14381
|
if (result?.ok !== true) merged.ok = false;
|
|
14322
14382
|
}
|
|
14383
|
+
if (merged.trackedChangeCaptures?.some((capture) => capture.state !== "observed")) merged.trackedChanges = [];
|
|
14323
14384
|
if (merged.skipped.length) merged.ok = false;
|
|
14324
14385
|
return merged;
|
|
14325
14386
|
}
|
|
@@ -15315,6 +15376,8 @@ ${block}`;
|
|
|
15315
15376
|
saveState = null,
|
|
15316
15377
|
saveStateSoon = () => {
|
|
15317
15378
|
},
|
|
15379
|
+
onProjectFilesReady = () => {
|
|
15380
|
+
},
|
|
15318
15381
|
updateActiveSession = defaultUpdateActiveSession,
|
|
15319
15382
|
callPageBridge = () => Promise.resolve({ ok: false }),
|
|
15320
15383
|
getCurrentProjectId = () => "",
|
|
@@ -15478,6 +15541,7 @@ ${block}`;
|
|
|
15478
15541
|
renderContextFiles(contextProject);
|
|
15479
15542
|
if (isExactContextFileListProject(contextProject)) {
|
|
15480
15543
|
setContextSyncState("exact-ready");
|
|
15544
|
+
onProjectFilesReady(contextProject);
|
|
15481
15545
|
} else if (contextSyncState !== "partial") {
|
|
15482
15546
|
setContextSyncState("exact-loading");
|
|
15483
15547
|
void enhanceContextFilesFromExactSnapshot({ loadId: contextLoadId });
|
|
@@ -15499,6 +15563,7 @@ ${block}`;
|
|
|
15499
15563
|
contextProject = project;
|
|
15500
15564
|
setContextSyncState(isExactContextFileListProject(project) ? "exact-ready" : "exact-loading");
|
|
15501
15565
|
renderContextFiles(project);
|
|
15566
|
+
if (isExactContextFileListProject(project)) onProjectFilesReady(project);
|
|
15502
15567
|
if (!isExactContextFileListProject(project)) {
|
|
15503
15568
|
void enhanceContextFilesFromExactSnapshot({
|
|
15504
15569
|
force: Boolean(options2.force),
|
|
@@ -15556,6 +15621,7 @@ ${block}`;
|
|
|
15556
15621
|
contextProject = project;
|
|
15557
15622
|
setContextSyncState("exact-ready");
|
|
15558
15623
|
renderContextFiles(project);
|
|
15624
|
+
onProjectFilesReady(project);
|
|
15559
15625
|
} catch (_error) {
|
|
15560
15626
|
if (loadId === contextLoadId) {
|
|
15561
15627
|
setContextSyncState("partial");
|
|
@@ -16756,6 +16822,20 @@ ${block}`;
|
|
|
16756
16822
|
})) return { ok: false, reason: "ot_event_expired" };
|
|
16757
16823
|
return { ok: true };
|
|
16758
16824
|
}
|
|
16825
|
+
function readOtBridgeStatus(response) {
|
|
16826
|
+
if (!response || response.ok === false) return "unavailable";
|
|
16827
|
+
return response.state || response.status || response.result?.state || response.result?.status || "unavailable";
|
|
16828
|
+
}
|
|
16829
|
+
function readOtBridgeEvents(response) {
|
|
16830
|
+
if (Array.isArray(response)) return response;
|
|
16831
|
+
if (Array.isArray(response?.events)) return response.events;
|
|
16832
|
+
if (Array.isArray(response?.result?.events)) return response.result.events;
|
|
16833
|
+
return [];
|
|
16834
|
+
}
|
|
16835
|
+
function readOtBridgeErrorCode(response, fallback) {
|
|
16836
|
+
const value = response?.lastErrorCode || response?.reason || response?.error?.code || response?.error || fallback;
|
|
16837
|
+
return typeof value === "string" ? value : fallback;
|
|
16838
|
+
}
|
|
16759
16839
|
function normalizeFailureCode(value, fallback = "ot_error") {
|
|
16760
16840
|
const code = typeof value === "string" ? value : value?.code;
|
|
16761
16841
|
if (/^[a-z][a-z0-9_]{0,79}$/.test(code || "")) return code;
|
|
@@ -16833,6 +16913,9 @@ ${block}`;
|
|
|
16833
16913
|
takePatchBatch,
|
|
16834
16914
|
validatePatchReceipt,
|
|
16835
16915
|
normalizeFailureCode,
|
|
16916
|
+
readOtBridgeStatus,
|
|
16917
|
+
readOtBridgeEvents,
|
|
16918
|
+
readOtBridgeErrorCode,
|
|
16836
16919
|
getFailureMessageKey,
|
|
16837
16920
|
buildPatchFilesRequest,
|
|
16838
16921
|
canUseOtWarmStart,
|
|
@@ -20428,7 +20511,8 @@ ${block}`;
|
|
|
20428
20511
|
container,
|
|
20429
20512
|
callbacks: options2.callbacks || {},
|
|
20430
20513
|
i18n: options2.i18n || {},
|
|
20431
|
-
dismissInstalled: false
|
|
20514
|
+
dismissInstalled: false,
|
|
20515
|
+
cleanup: []
|
|
20432
20516
|
};
|
|
20433
20517
|
container.innerHTML = `
|
|
20434
20518
|
<div class="codex-diagnostics-wrap">
|
|
@@ -20512,6 +20596,11 @@ ${block}`;
|
|
|
20512
20596
|
instance.callbacks.onBeforeOpen?.();
|
|
20513
20597
|
}
|
|
20514
20598
|
popover.hidden = !open;
|
|
20599
|
+
if (open) {
|
|
20600
|
+
openFloating(instance, popover, 300);
|
|
20601
|
+
} else {
|
|
20602
|
+
hideFloating(popover);
|
|
20603
|
+
}
|
|
20515
20604
|
button.dataset.active = open ? "true" : "false";
|
|
20516
20605
|
button.setAttribute("aria-expanded", open ? "true" : "false");
|
|
20517
20606
|
}
|
|
@@ -20522,7 +20611,7 @@ ${block}`;
|
|
|
20522
20611
|
if (!popover || !button) {
|
|
20523
20612
|
return;
|
|
20524
20613
|
}
|
|
20525
|
-
popover
|
|
20614
|
+
hideFloating(popover);
|
|
20526
20615
|
button.dataset.active = "false";
|
|
20527
20616
|
button.setAttribute("aria-expanded", "false");
|
|
20528
20617
|
}
|
|
@@ -20530,7 +20619,7 @@ ${block}`;
|
|
|
20530
20619
|
const instance = target?._instance || target;
|
|
20531
20620
|
const result = instance?.container?.querySelector("[data-diagnostics-result]");
|
|
20532
20621
|
if (result) {
|
|
20533
|
-
result
|
|
20622
|
+
hideFloating(result);
|
|
20534
20623
|
}
|
|
20535
20624
|
}
|
|
20536
20625
|
function showLoading(target, title, subtitle) {
|
|
@@ -20586,6 +20675,65 @@ ${block}`;
|
|
|
20586
20675
|
details.open = false;
|
|
20587
20676
|
details.hidden = !technicalText;
|
|
20588
20677
|
technical.textContent = technicalText;
|
|
20678
|
+
closeMenu(instance);
|
|
20679
|
+
openFloating(instance, root, 560);
|
|
20680
|
+
}
|
|
20681
|
+
function openFloating(instance, element, preferredWidth) {
|
|
20682
|
+
if (element.isConnected === false) return;
|
|
20683
|
+
element.hidden = false;
|
|
20684
|
+
if (typeof element.showPopover === "function") {
|
|
20685
|
+
element.setAttribute("popover", "manual");
|
|
20686
|
+
try {
|
|
20687
|
+
if (!element.matches(":popover-open")) element.showPopover();
|
|
20688
|
+
} catch (_error) {
|
|
20689
|
+
element.removeAttribute("popover");
|
|
20690
|
+
}
|
|
20691
|
+
}
|
|
20692
|
+
positionFloating(instance, element, preferredWidth);
|
|
20693
|
+
}
|
|
20694
|
+
function hideFloating(element) {
|
|
20695
|
+
if (!element) return;
|
|
20696
|
+
if (typeof element.hidePopover === "function" && element.getAttribute("popover") === "manual") {
|
|
20697
|
+
try {
|
|
20698
|
+
if (element.matches(":popover-open")) element.hidePopover();
|
|
20699
|
+
} catch (_error) {
|
|
20700
|
+
element.removeAttribute("popover");
|
|
20701
|
+
}
|
|
20702
|
+
}
|
|
20703
|
+
element.hidden = true;
|
|
20704
|
+
}
|
|
20705
|
+
function positionFloating(instance, element, preferredWidth) {
|
|
20706
|
+
if (!element || element.hidden) return;
|
|
20707
|
+
const button = instance.container.querySelector("[data-diagnostics-menu]");
|
|
20708
|
+
if (!button?.getBoundingClientRect || !element.getBoundingClientRect) return;
|
|
20709
|
+
if (button.getClientRects && !button.getClientRects().length) {
|
|
20710
|
+
closeMenu(instance);
|
|
20711
|
+
closeResult(instance);
|
|
20712
|
+
return;
|
|
20713
|
+
}
|
|
20714
|
+
const doc = instance.container.ownerDocument || document;
|
|
20715
|
+
const view = doc.defaultView || window;
|
|
20716
|
+
const viewport = view.visualViewport;
|
|
20717
|
+
const width = viewport?.width || view.innerWidth || doc.documentElement?.clientWidth;
|
|
20718
|
+
const height = viewport?.height || view.innerHeight || doc.documentElement?.clientHeight;
|
|
20719
|
+
if (!(width > 0 && height > 0)) return;
|
|
20720
|
+
const margin = 12;
|
|
20721
|
+
const gap = 8;
|
|
20722
|
+
const leftEdge = (viewport?.offsetLeft || 0) + margin;
|
|
20723
|
+
const topEdge = (viewport?.offsetTop || 0) + margin;
|
|
20724
|
+
const rightEdge = leftEdge + Math.max(0, width - margin * 2);
|
|
20725
|
+
const bottomEdge = topEdge + Math.max(0, height - margin * 2);
|
|
20726
|
+
element.style.width = `${Math.min(preferredWidth, Math.max(0, width - margin * 2))}px`;
|
|
20727
|
+
element.style.maxHeight = `${Math.min(640, Math.max(0, height - margin * 2))}px`;
|
|
20728
|
+
const anchor = button.getBoundingClientRect();
|
|
20729
|
+
const bounds = element.getBoundingClientRect();
|
|
20730
|
+
const below = Math.max(0, bottomEdge - anchor.bottom - gap);
|
|
20731
|
+
const above = Math.max(0, anchor.top - topEdge - gap);
|
|
20732
|
+
const desiredTop = bounds.height > below && above > below ? anchor.top - gap - bounds.height : anchor.bottom + gap;
|
|
20733
|
+
element.style.left = `${Math.max(leftEdge, Math.min(anchor.right - bounds.width, rightEdge - bounds.width))}px`;
|
|
20734
|
+
element.style.top = `${Math.max(topEdge, Math.min(desiredTop, bottomEdge - bounds.height))}px`;
|
|
20735
|
+
element.style.right = "auto";
|
|
20736
|
+
element.style.bottom = "auto";
|
|
20589
20737
|
}
|
|
20590
20738
|
function renderInstallCommand(instance, container, command) {
|
|
20591
20739
|
const wrap = document.createElement("div");
|
|
@@ -20660,13 +20808,60 @@ ${block}`;
|
|
|
20660
20808
|
return;
|
|
20661
20809
|
}
|
|
20662
20810
|
instance.dismissInstalled = true;
|
|
20663
|
-
|
|
20811
|
+
const doc = instance.container.ownerDocument || document;
|
|
20812
|
+
const view = doc.defaultView || window;
|
|
20813
|
+
const listen = (target, type, handler, options2) => {
|
|
20814
|
+
if (!target?.addEventListener) return;
|
|
20815
|
+
target.addEventListener(type, handler, options2);
|
|
20816
|
+
instance.cleanup.push(() => target.removeEventListener(type, handler, options2));
|
|
20817
|
+
};
|
|
20818
|
+
listen(doc, "click", (event) => {
|
|
20664
20819
|
const wrap = instance.container?.querySelector(".codex-diagnostics-wrap");
|
|
20665
20820
|
if (!wrap || wrap.contains(event.target)) {
|
|
20666
20821
|
return;
|
|
20667
20822
|
}
|
|
20668
20823
|
closeMenu(instance);
|
|
20669
20824
|
}, true);
|
|
20825
|
+
listen(doc, "keydown", (event) => {
|
|
20826
|
+
if (event.key !== "Escape") return;
|
|
20827
|
+
const menu = instance.container.querySelector("[data-diagnostics-popover]");
|
|
20828
|
+
const result = instance.container.querySelector("[data-diagnostics-result]");
|
|
20829
|
+
if (menu && !menu.hidden) closeMenu(instance);
|
|
20830
|
+
else if (result && !result.hidden) closeResult(instance);
|
|
20831
|
+
else return;
|
|
20832
|
+
event.preventDefault();
|
|
20833
|
+
event.stopPropagation();
|
|
20834
|
+
instance.container.querySelector("[data-diagnostics-menu]")?.focus();
|
|
20835
|
+
}, true);
|
|
20836
|
+
let frame = null;
|
|
20837
|
+
const reposition = () => {
|
|
20838
|
+
frame = null;
|
|
20839
|
+
positionFloating(instance, instance.container.querySelector("[data-diagnostics-popover]"), 300);
|
|
20840
|
+
positionFloating(instance, instance.container.querySelector("[data-diagnostics-result]"), 560);
|
|
20841
|
+
};
|
|
20842
|
+
const schedule = () => {
|
|
20843
|
+
if (frame !== null) return;
|
|
20844
|
+
if (view.requestAnimationFrame) frame = view.requestAnimationFrame(reposition);
|
|
20845
|
+
else reposition();
|
|
20846
|
+
};
|
|
20847
|
+
listen(view, "resize", schedule);
|
|
20848
|
+
listen(doc, "scroll", schedule, true);
|
|
20849
|
+
listen(view.visualViewport, "resize", schedule);
|
|
20850
|
+
listen(view.visualViewport, "scroll", schedule);
|
|
20851
|
+
if (typeof view.ResizeObserver === "function") {
|
|
20852
|
+
const observer = new view.ResizeObserver(schedule);
|
|
20853
|
+
for (const node of [
|
|
20854
|
+
instance.container.closest("#codex-overleaf-panel") || instance.container,
|
|
20855
|
+
instance.container.querySelector("[data-diagnostics-popover]"),
|
|
20856
|
+
instance.container.querySelector("[data-diagnostics-result]")
|
|
20857
|
+
]) {
|
|
20858
|
+
if (node) observer.observe(node);
|
|
20859
|
+
}
|
|
20860
|
+
instance.cleanup.push(() => observer.disconnect());
|
|
20861
|
+
}
|
|
20862
|
+
instance.cleanup.push(() => {
|
|
20863
|
+
if (frame !== null) view.cancelAnimationFrame?.(frame);
|
|
20864
|
+
});
|
|
20670
20865
|
}
|
|
20671
20866
|
const HEALTH_STATES = ["ok", "warn", "fail", "unknown"];
|
|
20672
20867
|
function updateStatus(target, status = {}) {
|
|
@@ -20823,6 +21018,10 @@ ${block}`;
|
|
|
20823
21018
|
return key;
|
|
20824
21019
|
}
|
|
20825
21020
|
function destroy(instance) {
|
|
21021
|
+
closeMenu(instance);
|
|
21022
|
+
closeResult(instance);
|
|
21023
|
+
for (const cleanup of instance.cleanup || []) cleanup();
|
|
21024
|
+
instance.cleanup = [];
|
|
20826
21025
|
instance.container.textContent = "";
|
|
20827
21026
|
}
|
|
20828
21027
|
window.CodexOverleafDiagnosticsPanel = {
|
|
@@ -21290,6 +21489,7 @@ ${block}`;
|
|
|
21290
21489
|
const raw = entry?.event || {};
|
|
21291
21490
|
if (raw.type === "codex.turn.bound") {
|
|
21292
21491
|
session.codexThreadId = String(raw.detail?.threadId || session.codexThreadId || "");
|
|
21492
|
+
record.codexThreadId = String(raw.detail?.threadId || record.codexThreadId || "");
|
|
21293
21493
|
record.codexTurnId = String(raw.detail?.turnId || record.codexTurnId || "");
|
|
21294
21494
|
record.nativeEventSeq = sequence;
|
|
21295
21495
|
continue;
|
|
@@ -29322,6 +29522,8 @@ failedAt: ${new Date(failure.at).toISOString()}`;
|
|
|
29322
29522
|
lines.push(`CodeMirror: docLength=${view.docLength || 0}; dispatch=${Boolean(view.hasDispatch)}; source=${view.source || "unknown"}`);
|
|
29323
29523
|
}
|
|
29324
29524
|
}
|
|
29525
|
+
const capture = probe?.trackedChangeCapture;
|
|
29526
|
+
if (capture) lines.push(tx("Tracked ledger: ", "\u7559\u75D5\u8BB0\u5F55\uFF1A") + "source=" + capture.source + "; ready=" + capture.ready + "; count=" + capture.count + "; doc=" + (capture.docId || "none") + "; adapter=" + capture.adapter + "; reason=" + (capture.reason || "none"));
|
|
29325
29527
|
const projectDiagnostics = probe?.projectDiagnostics;
|
|
29326
29528
|
if (projectDiagnostics) {
|
|
29327
29529
|
lines.push(`Project records: ${projectDiagnostics.docRecordCount || 0}; roots=${(projectDiagnostics.internalRootKeys || []).slice(0, 6).join(", ") || "none"}`);
|
|
@@ -29548,7 +29750,17 @@ failedAt: ${new Date(failure.at).toISOString()}`;
|
|
|
29548
29750
|
textarea.remove();
|
|
29549
29751
|
if (!copied) throw new Error("clipboard_copy_failed");
|
|
29550
29752
|
}
|
|
29551
|
-
return Object.freeze({ configureResultActions });
|
|
29753
|
+
return Object.freeze({ configureResultActions, projectUndoAvailability });
|
|
29754
|
+
}
|
|
29755
|
+
function projectUndoAvailability(run, projectRunSettlement) {
|
|
29756
|
+
const payload = run.recoveryPayload && typeof run.recoveryPayload === "object" ? run.recoveryPayload : run;
|
|
29757
|
+
if (!Array.isArray(payload.appliedOperations)) return projectRunSettlement(run);
|
|
29758
|
+
const appliedOperations = payload.appliedOperations.filter((operation) => operation?.type !== "binary-create" && operation?.type !== "overwrite-binary");
|
|
29759
|
+
if (appliedOperations.length === payload.appliedOperations.length) return projectRunSettlement(run);
|
|
29760
|
+
return projectRunSettlement({
|
|
29761
|
+
...run,
|
|
29762
|
+
recoveryPayload: { ...payload, appliedOperations }
|
|
29763
|
+
});
|
|
29552
29764
|
}
|
|
29553
29765
|
return Object.freeze({ create });
|
|
29554
29766
|
});
|
|
@@ -30580,7 +30792,7 @@ ${conclusion}` : `${label} ${conclusion}`;
|
|
|
30580
30792
|
configureLifecycleUndoButton(button, run);
|
|
30581
30793
|
return;
|
|
30582
30794
|
}
|
|
30583
|
-
const projection =
|
|
30795
|
+
const projection = RunResultActions.projectUndoAvailability(run, projectRunSettlement);
|
|
30584
30796
|
if (!projection.canUndo && run.undoStatus !== "applied") {
|
|
30585
30797
|
button.hidden = true;
|
|
30586
30798
|
return;
|
|
@@ -31578,19 +31790,26 @@ ${conclusion}` : `${label} ${conclusion}`;
|
|
|
31578
31790
|
const source = findSource(previousState, runId);
|
|
31579
31791
|
if (!source) return failFork("session_fork_source_missing", tr("forkRunUnavailable"));
|
|
31580
31792
|
const { session, run, runIndex } = source;
|
|
31581
|
-
|
|
31793
|
+
const draftThreadId = run.codexTurnId && run.interruptedDraft?.turnId === run.codexTurnId ? run.interruptedDraft.threadId : "";
|
|
31794
|
+
const sourceThreadId = String(run.codexThreadId || draftThreadId || session.codexThreadId || "").trim();
|
|
31795
|
+
if (run.status === "running" || !sourceThreadId || !run.codexTurnId) {
|
|
31582
31796
|
return failFork("session_fork_unavailable", tr("forkRunUnavailable"));
|
|
31583
31797
|
}
|
|
31584
|
-
|
|
31585
|
-
|
|
31586
|
-
|
|
31587
|
-
|
|
31588
|
-
|
|
31589
|
-
|
|
31590
|
-
|
|
31591
|
-
|
|
31592
|
-
|
|
31593
|
-
|
|
31798
|
+
let response;
|
|
31799
|
+
try {
|
|
31800
|
+
response = await sendBackgroundNative({
|
|
31801
|
+
method: "codex.thread.fork",
|
|
31802
|
+
params: {
|
|
31803
|
+
threadId: sourceThreadId,
|
|
31804
|
+
lastTurnId: run.codexTurnId,
|
|
31805
|
+
speedTier: session.speedTier,
|
|
31806
|
+
loadCodexLocalSkills: previousState.loadCodexLocalSkills !== false,
|
|
31807
|
+
loadCodexOverleafSkills: previousState.loadCodexOverleafSkills !== false
|
|
31808
|
+
}
|
|
31809
|
+
});
|
|
31810
|
+
} catch (error) {
|
|
31811
|
+
return failFork(error?.code || "session_fork_failed", error?.message || tr("forkRunFailed"));
|
|
31812
|
+
}
|
|
31594
31813
|
if (!response?.ok || !response.result?.threadId) {
|
|
31595
31814
|
return failFork(response?.error?.code || "session_fork_failed", response?.error?.message || tr("forkRunFailed"));
|
|
31596
31815
|
}
|
|
@@ -32027,11 +32246,45 @@ ${conclusion}` : `${label} ${conclusion}`;
|
|
|
32027
32246
|
function formatCompactModelLabel(label) {
|
|
32028
32247
|
return String(label || "").replace(/^gpt[-\s]*/i, "");
|
|
32029
32248
|
}
|
|
32030
|
-
function retainSelectedModel(models, selectedModel) {
|
|
32249
|
+
function retainSelectedModel(models, selectedModel, options2 = {}) {
|
|
32031
32250
|
const selectedId = normalizeModelOptionId(selectedModel);
|
|
32032
32251
|
if (!selectedId) return "";
|
|
32252
|
+
if (options2.preserveUnavailable === true) return selectedId;
|
|
32033
32253
|
return (Array.isArray(models) ? models : []).some((model) => normalizeModelOptionId(typeof model === "string" ? model : model?.id) === selectedId) ? selectedId : "";
|
|
32034
32254
|
}
|
|
32255
|
+
function preserveSelectedCapabilities(models, selectedModel, preferences = {}, provisional = false) {
|
|
32256
|
+
const selectedId = normalizeModelOptionId(selectedModel);
|
|
32257
|
+
const saved = preferences || {};
|
|
32258
|
+
return (Array.isArray(models) ? models : []).map((model) => {
|
|
32259
|
+
if (model.id !== selectedId || !provisional && !model.unverified) return model;
|
|
32260
|
+
const reasoningEfforts = normalizeReasoningEffortsForSelect([
|
|
32261
|
+
...model.reasoningEfforts || [],
|
|
32262
|
+
saved.reasoningEffort
|
|
32263
|
+
]);
|
|
32264
|
+
const speedTiers = normalizeSpeedTiersForSelect(model.speedTiers);
|
|
32265
|
+
const speed = ["standard", "fast"].includes(saved.speedTier) ? saved.speedTier : "";
|
|
32266
|
+
if (speed && !speedTiers.includes(speed)) speedTiers.push(speed);
|
|
32267
|
+
return {
|
|
32268
|
+
...model,
|
|
32269
|
+
unverified: true,
|
|
32270
|
+
reasoningEfforts,
|
|
32271
|
+
speedTiers,
|
|
32272
|
+
defaultReasoningEffort: reasoningEfforts.includes(saved.reasoningEffort) ? saved.reasoningEffort : model.defaultReasoningEffort,
|
|
32273
|
+
defaultSpeedTier: speed || model.defaultSpeedTier || "standard"
|
|
32274
|
+
};
|
|
32275
|
+
});
|
|
32276
|
+
}
|
|
32277
|
+
function getRenderedModelEntries(panel) {
|
|
32278
|
+
return Array.from(panel?.querySelector("[data-model]")?.options || []).map((option) => ({
|
|
32279
|
+
id: option.value,
|
|
32280
|
+
label: option.textContent,
|
|
32281
|
+
reasoningEfforts: (option.dataset.reasoningEfforts || "").split(",").filter(Boolean),
|
|
32282
|
+
defaultReasoningEffort: option.dataset.defaultReasoningEffort || "",
|
|
32283
|
+
reasoningPresentation: option.dataset.reasoningPresentation || "",
|
|
32284
|
+
speedTiers: (option.dataset.speedTiers || "standard").split(",").filter(Boolean),
|
|
32285
|
+
defaultSpeedTier: option.dataset.defaultSpeedTier || "standard"
|
|
32286
|
+
}));
|
|
32287
|
+
}
|
|
32035
32288
|
function shouldUseBuiltInFallback(response) {
|
|
32036
32289
|
const providerId = normalizeModelOptionId(response?.result?.providerId);
|
|
32037
32290
|
return response?.ok === true && (!providerId || providerId === "builtin");
|
|
@@ -32100,6 +32353,8 @@ ${conclusion}` : `${label} ${conclusion}`;
|
|
|
32100
32353
|
normalizeReasoningEffortsForSelect,
|
|
32101
32354
|
normalizeSpeedTiersForSelect,
|
|
32102
32355
|
retainSelectedModel,
|
|
32356
|
+
preserveSelectedCapabilities,
|
|
32357
|
+
getRenderedModelEntries,
|
|
32103
32358
|
shouldUseBuiltInFallback
|
|
32104
32359
|
};
|
|
32105
32360
|
return api;
|
|
@@ -32222,7 +32477,8 @@ ${conclusion}` : `${label} ${conclusion}`;
|
|
|
32222
32477
|
return { stale: false, error: response?.error || { code: "provider_models_unavailable" } };
|
|
32223
32478
|
}
|
|
32224
32479
|
const sourceModels = hasDiscoveredModels ? response.result.models : fallbackModels;
|
|
32225
|
-
const
|
|
32480
|
+
const preserveBuiltin = (selection?.providerId || "builtin") === "builtin" && (getState()?.providerId || "builtin") === "builtin";
|
|
32481
|
+
const retainedSelectedModel = retainSelectedModel(sourceModels, currentSelectedModel, { preserveUnavailable: preserveBuiltin });
|
|
32226
32482
|
const normalized = modelCatalog.normalizeDiscoveredModels({ models: sourceModels, selectedModel: retainedSelectedModel });
|
|
32227
32483
|
if (normalized.usedFallback && response.result?.providerId && response.result.providerId !== "builtin") {
|
|
32228
32484
|
applyUnavailableModelOptions({ code: "provider_model_catalog_invalid", message: "The active provider returned no usable models." });
|
|
@@ -32231,9 +32487,10 @@ ${conclusion}` : `${label} ${conclusion}`;
|
|
|
32231
32487
|
error: { code: "provider_model_catalog_invalid", message: "The active provider returned no usable models." }
|
|
32232
32488
|
};
|
|
32233
32489
|
}
|
|
32234
|
-
|
|
32490
|
+
const renderedModels = preserveBuiltin ? Support.preserveSelectedCapabilities(normalized.models, retainedSelectedModel, getState(), !hasDiscoveredModels || response.result?.source === "fallback") : normalized.models;
|
|
32491
|
+
renderModelOptions(renderedModels, retainedSelectedModel, { allowUnknownSelected: false });
|
|
32235
32492
|
modelDiscovery = {
|
|
32236
|
-
status: hasDiscoveredModels && !normalized.usedFallback ? "discovered" : "fallback",
|
|
32493
|
+
status: hasDiscoveredModels && !normalized.usedFallback && response.result?.source !== "fallback" ? "discovered" : "fallback",
|
|
32237
32494
|
source: hasDiscoveredModels ? response.result?.source || "unknown" : "fallback",
|
|
32238
32495
|
fetchedAt: hasDiscoveredModels ? response.result?.fetchedAt || "" : "",
|
|
32239
32496
|
errorCode: hasDiscoveredModels ? "" : response?.error?.code || "",
|
|
@@ -32259,15 +32516,16 @@ ${conclusion}` : `${label} ${conclusion}`;
|
|
|
32259
32516
|
}
|
|
32260
32517
|
}
|
|
32261
32518
|
function applyUnavailableModelOptions(error) {
|
|
32519
|
+
const selectedModel = resolveSelectedModel();
|
|
32262
32520
|
const modelSelect = getPanel()?.querySelector("[data-model]");
|
|
32263
32521
|
if (modelSelect) {
|
|
32264
32522
|
modelSelect.textContent = "";
|
|
32265
32523
|
const option = document.createElement("option");
|
|
32266
|
-
option.value =
|
|
32524
|
+
option.value = selectedModel;
|
|
32267
32525
|
option.textContent = tx("Models unavailable", "\u6A21\u578B\u4E0D\u53EF\u7528");
|
|
32268
32526
|
option.disabled = true;
|
|
32269
32527
|
modelSelect.append(option);
|
|
32270
|
-
modelSelect.value =
|
|
32528
|
+
modelSelect.value = selectedModel;
|
|
32271
32529
|
modelSelect.disabled = true;
|
|
32272
32530
|
}
|
|
32273
32531
|
modelDiscovery = {
|
|
@@ -32277,8 +32535,18 @@ ${conclusion}` : `${label} ${conclusion}`;
|
|
|
32277
32535
|
errorCode: error?.code || "",
|
|
32278
32536
|
errorMessage: error?.message || (error ? String(error) : "")
|
|
32279
32537
|
};
|
|
32280
|
-
|
|
32281
|
-
|
|
32538
|
+
const pendingModels = Support.preserveSelectedCapabilities(
|
|
32539
|
+
[{ id: selectedModel, unverified: true }],
|
|
32540
|
+
selectedModel,
|
|
32541
|
+
getState(),
|
|
32542
|
+
true
|
|
32543
|
+
);
|
|
32544
|
+
renderReasoningOptions(pendingModels);
|
|
32545
|
+
renderSpeedOptions(pendingModels);
|
|
32546
|
+
for (const selector of ["[data-reasoning]", "[data-speed]"]) {
|
|
32547
|
+
const input = getPanel()?.querySelector(selector);
|
|
32548
|
+
if (input) input.disabled = true;
|
|
32549
|
+
}
|
|
32282
32550
|
renderModelConfigChoices();
|
|
32283
32551
|
updateModelDisplay();
|
|
32284
32552
|
}
|
|
@@ -32286,9 +32554,9 @@ ${conclusion}` : `${label} ${conclusion}`;
|
|
|
32286
32554
|
const modelCatalog = getModelCatalog();
|
|
32287
32555
|
const fallbackModels = modelCatalog.FALLBACK_MODELS;
|
|
32288
32556
|
const sourceModels = fallbackModels;
|
|
32289
|
-
const retainedSelectedModel = retainSelectedModel(sourceModels, selectedModel);
|
|
32557
|
+
const retainedSelectedModel = retainSelectedModel(sourceModels, selectedModel, { preserveUnavailable: (getState()?.providerId || "builtin") === "builtin" });
|
|
32290
32558
|
const normalized = modelCatalog.normalizeDiscoveredModels({ models: sourceModels, selectedModel: retainedSelectedModel });
|
|
32291
|
-
renderModelOptions(normalized.models, retainedSelectedModel);
|
|
32559
|
+
renderModelOptions(Support.preserveSelectedCapabilities(normalized.models, retainedSelectedModel, getState(), true), retainedSelectedModel);
|
|
32292
32560
|
modelDiscovery = {
|
|
32293
32561
|
status: "fallback",
|
|
32294
32562
|
source: "fallback",
|
|
@@ -33653,6 +33921,7 @@ ${conclusion}` : `${label} ${conclusion}`;
|
|
|
33653
33921
|
let currentOtStatus = "off";
|
|
33654
33922
|
let otTogglePending = false;
|
|
33655
33923
|
let otSyncRequestId = 0;
|
|
33924
|
+
let otStartRetryCount = 0;
|
|
33656
33925
|
let otWarmMirrorProjectId = "";
|
|
33657
33926
|
let lastExperimentalOtProjectId = "";
|
|
33658
33927
|
let otWarmMirrorState = {
|
|
@@ -33802,6 +34071,7 @@ ${conclusion}` : `${label} ${conclusion}`;
|
|
|
33802
34071
|
const projectId = getCurrentProjectId();
|
|
33803
34072
|
otWarmMirrorState.failureActive = false;
|
|
33804
34073
|
lastExperimentalOtProjectId = projectId;
|
|
34074
|
+
otStartRetryCount = 0;
|
|
33805
34075
|
setExperimentalOtEnabledForProject(projectId, checkbox.checked);
|
|
33806
34076
|
updateExperimentalOtToggleControl(checkbox.checked);
|
|
33807
34077
|
const savedBadge = getPanel()?.querySelector('details[data-set-group="experimental"] [data-set-saved]');
|
|
@@ -33877,8 +34147,10 @@ ${conclusion}` : `${label} ${conclusion}`;
|
|
|
33877
34147
|
await pauseOtWarmMirror(pauseAfterStart.reason || "paused");
|
|
33878
34148
|
return response;
|
|
33879
34149
|
}
|
|
33880
|
-
|
|
34150
|
+
if (status === "starting") recordOtFailure("missing_active_path", "start");
|
|
34151
|
+
else otWarmMirrorState.failureActive = false;
|
|
33881
34152
|
updateOtStatusDisplay(status);
|
|
34153
|
+
otStartRetryCount = 0;
|
|
33882
34154
|
scheduleOtEventPolling(projectId, { immediate: true });
|
|
33883
34155
|
return response;
|
|
33884
34156
|
}
|
|
@@ -33905,23 +34177,31 @@ ${conclusion}` : `${label} ${conclusion}`;
|
|
|
33905
34177
|
clearOtEventPolling({ clearPatchQueue: true });
|
|
33906
34178
|
recordOtFailure(readOtBridgeErrorCode(response, "ot_start_failed"), "start");
|
|
33907
34179
|
otWarmMirrorState.suspended = true;
|
|
33908
|
-
|
|
33909
|
-
const experimentalOtCheckbox = getPanel()?.querySelector("[data-experimental-ot]");
|
|
33910
|
-
if (experimentalOtCheckbox) {
|
|
33911
|
-
experimentalOtCheckbox.checked = false;
|
|
33912
|
-
}
|
|
34180
|
+
updateExperimentalOtToggleControl(isExperimentalOtEnabledForProject(projectId));
|
|
33913
34181
|
updateOtStatusDisplay("unavailable");
|
|
33914
|
-
saveStateSoon();
|
|
33915
34182
|
try {
|
|
33916
34183
|
await callPageBridge("stopOtObserver", { projectId });
|
|
33917
34184
|
} catch (_error) {
|
|
33918
34185
|
}
|
|
34186
|
+
scheduleOtStartRetry(projectId, requestId);
|
|
34187
|
+
}
|
|
34188
|
+
function scheduleOtStartRetry(projectId, requestId) {
|
|
34189
|
+
const retryDelays = [1e3, 3e3, 6e3];
|
|
34190
|
+
const canRetry = () => isCurrentOtSync(requestId, projectId) && getCurrentProjectId() === projectId && isExperimentalOtEnabledForProject(projectId) && !getCurrentRunView();
|
|
34191
|
+
if (!canRetry() || otStartRetryCount >= retryDelays.length) return;
|
|
34192
|
+
const delayMs = retryDelays[otStartRetryCount++];
|
|
34193
|
+
otWarmMirrorState.pollTimer = window.setTimeout(() => {
|
|
34194
|
+
otWarmMirrorState.pollTimer = null;
|
|
34195
|
+
if (!canRetry()) return;
|
|
34196
|
+
syncOtWarmMirrorController().catch(() => {
|
|
34197
|
+
if (getCurrentProjectId() === projectId && isExperimentalOtEnabledForProject(projectId)) {
|
|
34198
|
+
updateOtStatusDisplay("unavailable");
|
|
34199
|
+
}
|
|
34200
|
+
});
|
|
34201
|
+
}, delayMs);
|
|
33919
34202
|
}
|
|
33920
34203
|
function readOtBridgeStatus(response) {
|
|
33921
|
-
|
|
33922
|
-
return "unavailable";
|
|
33923
|
-
}
|
|
33924
|
-
return response.state || response.status || response.result?.state || response.result?.status || "unavailable";
|
|
34204
|
+
return otWarmMirrorController.readOtBridgeStatus(response);
|
|
33925
34205
|
}
|
|
33926
34206
|
function ensureOtWarmMirrorStateProject(projectId) {
|
|
33927
34207
|
if (!projectId || otWarmMirrorState.projectId === projectId) {
|
|
@@ -33929,6 +34209,7 @@ ${conclusion}` : `${label} ${conclusion}`;
|
|
|
33929
34209
|
}
|
|
33930
34210
|
clearOtEventPolling({ clearPatchQueue: true });
|
|
33931
34211
|
otWarmMirrorState.projectId = projectId;
|
|
34212
|
+
otStartRetryCount = 0;
|
|
33932
34213
|
otWarmMirrorState.lastPatchAt = 0;
|
|
33933
34214
|
otWarmMirrorState.lastErrorCode = "";
|
|
33934
34215
|
otWarmMirrorState.failureActive = false;
|
|
@@ -33992,6 +34273,7 @@ ${conclusion}` : `${label} ${conclusion}`;
|
|
|
33992
34273
|
return statusResponse;
|
|
33993
34274
|
}
|
|
33994
34275
|
const status = readOtBridgeStatus(statusResponse);
|
|
34276
|
+
if (status === "observing" && otWarmMirrorState.lastFailure?.phase === "start") Object.assign(otWarmMirrorState, { failureActive: false, lastErrorCode: "", lastFailure: null });
|
|
33995
34277
|
if (["unavailable", "inconsistent"].includes(status)) recordOtFailure(readOtBridgeErrorCode(statusResponse, "ot_observer_unavailable"), "observe");
|
|
33996
34278
|
if (status) {
|
|
33997
34279
|
updateOtStatusDisplay(status);
|
|
@@ -34022,20 +34304,10 @@ ${conclusion}` : `${label} ${conclusion}`;
|
|
|
34022
34304
|
}
|
|
34023
34305
|
}
|
|
34024
34306
|
function readOtBridgeEvents(response) {
|
|
34025
|
-
|
|
34026
|
-
return response;
|
|
34027
|
-
}
|
|
34028
|
-
if (Array.isArray(response?.events)) {
|
|
34029
|
-
return response.events;
|
|
34030
|
-
}
|
|
34031
|
-
if (Array.isArray(response?.result?.events)) {
|
|
34032
|
-
return response.result.events;
|
|
34033
|
-
}
|
|
34034
|
-
return [];
|
|
34307
|
+
return otWarmMirrorController.readOtBridgeEvents(response);
|
|
34035
34308
|
}
|
|
34036
34309
|
function readOtBridgeErrorCode(response, fallback) {
|
|
34037
|
-
|
|
34038
|
-
return typeof value === "string" ? value : fallback;
|
|
34310
|
+
return otWarmMirrorController.readOtBridgeErrorCode(response, fallback);
|
|
34039
34311
|
}
|
|
34040
34312
|
function recordOtFailure(code, phase) {
|
|
34041
34313
|
code = otWarmMirrorController.normalizeFailureCode(code);
|
|
@@ -34511,6 +34783,7 @@ ${conclusion}` : `${label} ${conclusion}`;
|
|
|
34511
34783
|
let tx;
|
|
34512
34784
|
let getLocale;
|
|
34513
34785
|
let appendRunEvent;
|
|
34786
|
+
let appendRunRecordEvent;
|
|
34514
34787
|
let pendingMirrorRefresh = null;
|
|
34515
34788
|
let appendChangeSummary;
|
|
34516
34789
|
let appendCompletionReport;
|
|
@@ -34557,6 +34830,34 @@ ${conclusion}` : `${label} ${conclusion}`;
|
|
|
34557
34830
|
function buildSettlement(input = {}) {
|
|
34558
34831
|
return writebackSettlement?.settle instanceof Function ? writebackSettlement.settle(input) : null;
|
|
34559
34832
|
}
|
|
34833
|
+
function invalidateMirrorAfterUndo(runId, projectId, result = {}) {
|
|
34834
|
+
if (!projectId || result?.changedDocument !== true && !result?.applied?.length) return Promise.resolve("not-attempted");
|
|
34835
|
+
const pending = Promise.resolve(pendingMirrorRefresh).catch(() => {
|
|
34836
|
+
}).then(async () => {
|
|
34837
|
+
const response = await sendBackgroundNative({ method: "mirror.invalidate", params: { projectId } });
|
|
34838
|
+
if (!response?.ok || response.result?.invalidated !== true) {
|
|
34839
|
+
throw new Error(response?.error?.message || "Native host did not confirm mirror invalidation.");
|
|
34840
|
+
}
|
|
34841
|
+
if (getCurrentProjectId() === projectId) {
|
|
34842
|
+
resetContextProject();
|
|
34843
|
+
await callPageBridge("invalidateProjectSnapshot", { invalidateFileList: true });
|
|
34844
|
+
}
|
|
34845
|
+
return "invalidated";
|
|
34846
|
+
}).catch((error) => {
|
|
34847
|
+
appendRunRecordEvent?.(runId, {
|
|
34848
|
+
status: "warning",
|
|
34849
|
+
title: tx(
|
|
34850
|
+
`Overleaf undo finished, but local mirror invalidation failed: ${error.message}. Refresh this project or reconnect the native host before running again.`,
|
|
34851
|
+
`Overleaf \u64A4\u9500\u5DF2\u5B8C\u6210\uFF0C\u4F46\u672C\u5730\u955C\u50CF\u5931\u6548\u5904\u7406\u5931\u8D25\uFF1A${error.message}\u3002\u8BF7\u5237\u65B0\u9879\u76EE\u6216\u91CD\u65B0\u8FDE\u63A5 Native Host \u540E\u518D\u8FD0\u884C\u3002`
|
|
34852
|
+
)
|
|
34853
|
+
});
|
|
34854
|
+
return "failed";
|
|
34855
|
+
}).finally(() => {
|
|
34856
|
+
if (pendingMirrorRefresh === pending) pendingMirrorRefresh = null;
|
|
34857
|
+
});
|
|
34858
|
+
pendingMirrorRefresh = pending;
|
|
34859
|
+
return pending;
|
|
34860
|
+
}
|
|
34560
34861
|
async function applySyncChangesToOverleaf(syncChanges = [], project = {}, options2 = {}) {
|
|
34561
34862
|
const runMode = options2.mode || getState().mode;
|
|
34562
34863
|
const runRequireReviewing = typeof options2.requireReviewing === "boolean" ? options2.requireReviewing : getState().requireReviewing === true;
|
|
@@ -35209,6 +35510,7 @@ ${tx("Writeback note: Codex could not confirm any Overleaf write result entries,
|
|
|
35209
35510
|
tx,
|
|
35210
35511
|
getLocale,
|
|
35211
35512
|
appendRunEvent,
|
|
35513
|
+
appendRunRecordEvent,
|
|
35212
35514
|
appendChangeSummary,
|
|
35213
35515
|
appendCompletionReport,
|
|
35214
35516
|
appendOperationsPreview,
|
|
@@ -35254,6 +35556,7 @@ ${tx("Writeback note: Codex could not confirm any Overleaf write result entries,
|
|
|
35254
35556
|
return {
|
|
35255
35557
|
applySyncChangesToOverleaf,
|
|
35256
35558
|
resolveCompileLogContext,
|
|
35559
|
+
invalidateMirrorAfterUndo,
|
|
35257
35560
|
getPendingMirrorRefresh: () => pendingMirrorRefresh
|
|
35258
35561
|
};
|
|
35259
35562
|
}
|
|
@@ -35261,6 +35564,153 @@ ${tx("Writeback note: Codex could not confirm any Overleaf write result entries,
|
|
|
35261
35564
|
})();
|
|
35262
35565
|
}).call(globalThis, void 0, void 0, void 0);
|
|
35263
35566
|
(function runClassicContentModule94(module, exports, require2) {
|
|
35567
|
+
(function(root, factory) {
|
|
35568
|
+
const api = factory();
|
|
35569
|
+
if (typeof module === "object" && module.exports) module.exports = api;
|
|
35570
|
+
if (root) root.CodexOverleafTrackedChangeCaptureController = api;
|
|
35571
|
+
})(typeof window !== "undefined" ? window : globalThis, function() {
|
|
35572
|
+
"use strict";
|
|
35573
|
+
function create(deps = {}) {
|
|
35574
|
+
const now = deps.now || (() => Date.now());
|
|
35575
|
+
const defer = deps.setTimeout || setTimeout;
|
|
35576
|
+
const cancelTimer = deps.clearTimeout || clearTimeout;
|
|
35577
|
+
let timer = null, busy = false, disposed = false;
|
|
35578
|
+
const runs = () => deps.getRuns() || [];
|
|
35579
|
+
const pending = (run) => Array.isArray(run.trackedChangeCaptures) && run.trackedChangeCaptures.some((capture) => capture.state === "pending");
|
|
35580
|
+
const terminal = (run) => ["accepted", "rejected"].includes(run.trackedChangeStatus) || run.undoStatus === "applied" || run.forkSnapshot === true;
|
|
35581
|
+
function buildPostFiles(run) {
|
|
35582
|
+
const expectedFiles = Array.isArray(run?.undoExpectedFiles) ? run.undoExpectedFiles : [];
|
|
35583
|
+
const appliedOperations = Array.isArray(run?.appliedOperations) ? run.appliedOperations : [];
|
|
35584
|
+
if (!expectedFiles.length || !appliedOperations.length) return [];
|
|
35585
|
+
const postFilesByPath = deps.buildExpectedFilesAfterOperations({ files: expectedFiles }, appliedOperations);
|
|
35586
|
+
const expectedPaths = new Set(expectedFiles.map((file) => file?.path).filter(Boolean));
|
|
35587
|
+
return Array.from(postFilesByPath.entries()).filter(([path, content]) => expectedPaths.has(path) && typeof content === "string").map(([path, content]) => ({ path, content }));
|
|
35588
|
+
}
|
|
35589
|
+
function hasLegacyUntrackedCheckpoint(run) {
|
|
35590
|
+
if (!run || run.executionSnapshot || run.trackedChangeStatus || run.undoStatus === "applied" || run.forkSnapshot || run.undoTrackedChanges?.length || run.trackedChangeCaptures?.length) return false;
|
|
35591
|
+
const operations = Array.isArray(run.undoOperations) ? run.undoOperations : [];
|
|
35592
|
+
const before = Array.isArray(run.undoExpectedFiles) ? run.undoExpectedFiles : [];
|
|
35593
|
+
if (!operations.length || !before.length || before.some((file) => !file?.path || typeof file.content !== "string")) return false;
|
|
35594
|
+
const paths = new Set(before.map((file) => file.path));
|
|
35595
|
+
if (paths.size !== before.length || operations.some((op) => op?.type !== "edit" || !paths.has(op.path))) return false;
|
|
35596
|
+
const complete = (files) => Array.isArray(files) && files.length === paths.size && new Set(files.map((file) => file?.path)).size === paths.size && files.every((file) => paths.has(file?.path) && typeof file.content === "string");
|
|
35597
|
+
const storedPost = run.undoBaseFiles;
|
|
35598
|
+
try {
|
|
35599
|
+
const post = buildPostFiles(run);
|
|
35600
|
+
if (!complete(storedPost) || !complete(post)) return false;
|
|
35601
|
+
const postByPath = new Map(post.map((file) => [file.path, file.content]));
|
|
35602
|
+
if (!storedPost.every((file) => postByPath.get(file.path) === file.content)) return false;
|
|
35603
|
+
const restored = deps.buildExpectedFilesAfterOperations({ files: storedPost }, operations);
|
|
35604
|
+
return before.every((file) => restored.get(file.path) === file.content);
|
|
35605
|
+
} catch (_error) {
|
|
35606
|
+
return false;
|
|
35607
|
+
}
|
|
35608
|
+
}
|
|
35609
|
+
function schedule() {
|
|
35610
|
+
if (disposed || timer !== null || busy || !runs().some(pending)) return;
|
|
35611
|
+
timer = defer(() => {
|
|
35612
|
+
timer = null;
|
|
35613
|
+
flush().catch((error) => deps.onError?.(error));
|
|
35614
|
+
}, 500);
|
|
35615
|
+
}
|
|
35616
|
+
function record(run, captures) {
|
|
35617
|
+
if (!Array.isArray(captures) || !captures.length) return;
|
|
35618
|
+
const next = [...run.trackedChangeCaptures || [], ...captures.filter(Boolean)];
|
|
35619
|
+
if (next.every((capture) => capture.state === "observed")) return;
|
|
35620
|
+
run.trackedChangeCaptures = next;
|
|
35621
|
+
deps.notify?.(run, next.some((capture) => capture.state === "pending") ? "pending" : "needs_review", {
|
|
35622
|
+
captures: next.map((capture) => ({ path: capture.path, reason: capture.reason, ...capture.diagnostics }))
|
|
35623
|
+
});
|
|
35624
|
+
deps.persist().then(schedule).catch((error) => deps.onError?.(error));
|
|
35625
|
+
}
|
|
35626
|
+
async function flush() {
|
|
35627
|
+
if (disposed || busy) return;
|
|
35628
|
+
busy = true;
|
|
35629
|
+
try {
|
|
35630
|
+
for (const run of runs().filter(pending)) {
|
|
35631
|
+
if (terminal(run)) {
|
|
35632
|
+
run.trackedChangeCaptures = [];
|
|
35633
|
+
await deps.persist();
|
|
35634
|
+
continue;
|
|
35635
|
+
}
|
|
35636
|
+
if (run.runProjectId !== deps.getProjectId()) continue;
|
|
35637
|
+
const newer = runs().some((other) => other.id !== run.id && other.runProjectId === run.runProjectId && Date.parse(other.startedAt) > Date.parse(run.startedAt));
|
|
35638
|
+
const original = run.trackedChangeCaptures;
|
|
35639
|
+
const captures = original.map((capture) => ({ ...capture }));
|
|
35640
|
+
const postFiles = buildPostFiles(run);
|
|
35641
|
+
for (let i = 0; i < captures.length; i++) {
|
|
35642
|
+
const capture = captures[i];
|
|
35643
|
+
if (capture.state !== "pending") continue;
|
|
35644
|
+
const expected = postFiles.find((file) => file.path === capture.path);
|
|
35645
|
+
if (newer || !expected || now() >= capture.expiresAt || run.status === "cancelled") {
|
|
35646
|
+
capture.state = "needs_review";
|
|
35647
|
+
capture.reason = newer ? "capture_superseded" : !expected ? "capture_baseline_missing" : run.status === "cancelled" ? "capture_cancelled" : "capture_expired";
|
|
35648
|
+
continue;
|
|
35649
|
+
}
|
|
35650
|
+
let response;
|
|
35651
|
+
try {
|
|
35652
|
+
response = await deps.callPageBridge("reconcileTrackedChangeCapture", {
|
|
35653
|
+
runProjectId: run.runProjectId,
|
|
35654
|
+
capture,
|
|
35655
|
+
expectedContent: expected.content
|
|
35656
|
+
});
|
|
35657
|
+
} catch (_error) {
|
|
35658
|
+
response = null;
|
|
35659
|
+
}
|
|
35660
|
+
if (disposed || deps.getProjectId() !== run.runProjectId || !runs().includes(run) || terminal(run) || run.trackedChangeCaptures !== original) return;
|
|
35661
|
+
const superseded = runs().some((other) => other.id !== run.id && other.runProjectId === run.runProjectId && Date.parse(other.startedAt) > Date.parse(run.startedAt));
|
|
35662
|
+
if (superseded || run.status === "cancelled") {
|
|
35663
|
+
captures[i] = { ...capture, state: "needs_review", reason: "capture_superseded" };
|
|
35664
|
+
} else if (response?.capture?.path === capture.path && response.capture.runProjectId === run.runProjectId && ["observed", "pending", "needs_review"].includes(response.capture.state)) {
|
|
35665
|
+
captures[i] = response.capture;
|
|
35666
|
+
} else {
|
|
35667
|
+
captures[i] = { ...capture, state: "needs_review", reason: "capture_bridge_unavailable" };
|
|
35668
|
+
}
|
|
35669
|
+
}
|
|
35670
|
+
if (!runs().includes(run) || terminal(run) || deps.getProjectId() !== run.runProjectId) continue;
|
|
35671
|
+
if (captures.length && captures.every((capture) => capture.state === "observed")) {
|
|
35672
|
+
const refs = deps.normalizeTrackedChanges([
|
|
35673
|
+
...run.undoTrackedChanges || [],
|
|
35674
|
+
...captures.flatMap((capture) => capture.refs || [])
|
|
35675
|
+
]);
|
|
35676
|
+
if (refs.length) {
|
|
35677
|
+
run.undoTrackedChanges = refs;
|
|
35678
|
+
run.trackedChangeStatus = "pending";
|
|
35679
|
+
run.trackedChangeCaptures = [];
|
|
35680
|
+
await deps.persist();
|
|
35681
|
+
deps.refresh(run);
|
|
35682
|
+
deps.notify?.(run, "observed", { count: refs.length });
|
|
35683
|
+
continue;
|
|
35684
|
+
}
|
|
35685
|
+
}
|
|
35686
|
+
const changed = JSON.stringify(original.map(summary)) !== JSON.stringify(captures.map(summary));
|
|
35687
|
+
if (changed) {
|
|
35688
|
+
run.trackedChangeCaptures = captures;
|
|
35689
|
+
await deps.persist();
|
|
35690
|
+
if (!pending(run)) deps.notify?.(run, "needs_review", {
|
|
35691
|
+
reasons: captures.filter((capture) => capture.state !== "observed").map((capture) => capture.reason)
|
|
35692
|
+
});
|
|
35693
|
+
}
|
|
35694
|
+
}
|
|
35695
|
+
} finally {
|
|
35696
|
+
busy = false;
|
|
35697
|
+
if (runs().some((run) => pending(run) && run.runProjectId === deps.getProjectId())) schedule();
|
|
35698
|
+
}
|
|
35699
|
+
}
|
|
35700
|
+
function summary(capture) {
|
|
35701
|
+
return { state: capture.state, reason: capture.reason, refs: (capture.refs || []).map((ref) => ref.key) };
|
|
35702
|
+
}
|
|
35703
|
+
function dispose() {
|
|
35704
|
+
disposed = true;
|
|
35705
|
+
if (timer !== null) cancelTimer(timer);
|
|
35706
|
+
timer = null;
|
|
35707
|
+
}
|
|
35708
|
+
return { record, schedule, flush, dispose, buildPostFiles, hasLegacyUntrackedCheckpoint };
|
|
35709
|
+
}
|
|
35710
|
+
return { create };
|
|
35711
|
+
});
|
|
35712
|
+
}).call(globalThis, void 0, void 0, void 0);
|
|
35713
|
+
(function runClassicContentModule95(module, exports, require2) {
|
|
35264
35714
|
(function initCodexOverleafRunSettlementPersistence(root, factory) {
|
|
35265
35715
|
const api = factory();
|
|
35266
35716
|
if (typeof module === "object" && module.exports) module.exports = api;
|
|
@@ -35303,7 +35753,7 @@ ${tx("Writeback note: Codex could not confirm any Overleaf write result entries,
|
|
|
35303
35753
|
return Object.freeze({ create });
|
|
35304
35754
|
});
|
|
35305
35755
|
}).call(globalThis, void 0, void 0, void 0);
|
|
35306
|
-
(function
|
|
35756
|
+
(function runClassicContentModule96(module, exports, require2) {
|
|
35307
35757
|
(function initPostNavigationSettlementPersistence(root, factory) {
|
|
35308
35758
|
const api = factory();
|
|
35309
35759
|
if (typeof module === "object" && module.exports) module.exports = api;
|
|
@@ -35395,7 +35845,7 @@ ${tx("Writeback note: Codex could not confirm any Overleaf write result entries,
|
|
|
35395
35845
|
return Object.freeze({ persist, persistRequired });
|
|
35396
35846
|
});
|
|
35397
35847
|
}).call(globalThis, void 0, void 0, void 0);
|
|
35398
|
-
(function
|
|
35848
|
+
(function runClassicContentModule97(module, exports, require2) {
|
|
35399
35849
|
(function initCodexOverleafPanelMaintenance() {
|
|
35400
35850
|
"use strict";
|
|
35401
35851
|
function create(deps = {}) {
|
|
@@ -35726,7 +36176,7 @@ ${tx("Writeback note: Codex could not confirm any Overleaf write result entries,
|
|
|
35726
36176
|
window.CodexOverleafPanelMaintenance = { create };
|
|
35727
36177
|
})();
|
|
35728
36178
|
}).call(globalThis, void 0, void 0, void 0);
|
|
35729
|
-
(function
|
|
36179
|
+
(function runClassicContentModule98(module, exports, require2) {
|
|
35730
36180
|
(function initCodexOverleafUpdateIdle(root) {
|
|
35731
36181
|
"use strict";
|
|
35732
36182
|
function create(options2 = {}) {
|
|
@@ -35794,7 +36244,7 @@ ${tx("Writeback note: Codex could not confirm any Overleaf write result entries,
|
|
|
35794
36244
|
root.CodexOverleafUpdateIdle = Object.freeze({ create });
|
|
35795
36245
|
})(typeof window !== "undefined" ? window : globalThis);
|
|
35796
36246
|
}).call(globalThis, void 0, void 0, void 0);
|
|
35797
|
-
(function
|
|
36247
|
+
(function runClassicContentModule99(module, exports, require2) {
|
|
35798
36248
|
(function initCodexOverleafUpdateNotice(root, factory) {
|
|
35799
36249
|
if (typeof module === "object" && module.exports) {
|
|
35800
36250
|
module.exports = factory(require2("../shared/managedUpdateProjection"));
|
|
@@ -36259,7 +36709,7 @@ ${tx("Writeback note: Codex could not confirm any Overleaf write result entries,
|
|
|
36259
36709
|
return Object.freeze({ mount });
|
|
36260
36710
|
});
|
|
36261
36711
|
}).call(globalThis, void 0, void 0, void 0);
|
|
36262
|
-
(function
|
|
36712
|
+
(function runClassicContentModule100(module, exports, require2) {
|
|
36263
36713
|
(function initCodexOverleafContentRuntime(root) {
|
|
36264
36714
|
"use strict";
|
|
36265
36715
|
function init(dependencies2) {
|
|
@@ -36312,6 +36762,7 @@ ${tx("Writeback note: Codex could not confirm any Overleaf write result entries,
|
|
|
36312
36762
|
"mirror.sync",
|
|
36313
36763
|
"mirror.patchFiles",
|
|
36314
36764
|
"mirror.confirmWriteback",
|
|
36765
|
+
"mirror.invalidate",
|
|
36315
36766
|
"mirror.scanSensitive",
|
|
36316
36767
|
"codex.history.clearPlugin",
|
|
36317
36768
|
"skills.list",
|
|
@@ -36812,6 +37263,7 @@ ${tx("Writeback note: Codex could not confirm any Overleaf write result entries,
|
|
|
36812
37263
|
RUN_SNAPSHOT_ZIP_TIMEOUT_MS,
|
|
36813
37264
|
getState: () => state,
|
|
36814
37265
|
getCurrentRunView: () => currentRunView,
|
|
37266
|
+
appendRunRecordEvent,
|
|
36815
37267
|
onMirrorRefreshSettled: runSettlementPersistence.settleMirrorRefresh
|
|
36816
37268
|
});
|
|
36817
37269
|
const {
|
|
@@ -37013,6 +37465,7 @@ ${tx("Writeback note: Codex could not confirm any Overleaf write result entries,
|
|
|
37013
37465
|
},
|
|
37014
37466
|
saveState,
|
|
37015
37467
|
saveStateSoon,
|
|
37468
|
+
onProjectFilesReady: refreshHistoricalProjectReferences,
|
|
37016
37469
|
updateActiveSession,
|
|
37017
37470
|
callPageBridge,
|
|
37018
37471
|
getCurrentProjectId,
|
|
@@ -38483,15 +38936,19 @@ ${tx("Writeback note: Codex could not confirm any Overleaf write result entries,
|
|
|
38483
38936
|
setRunning(false);
|
|
38484
38937
|
nativeChannel.clearActiveRequest();
|
|
38485
38938
|
stopRunElapsedTick();
|
|
38486
|
-
if (isExperimentalOtEnabled()) {
|
|
38487
|
-
await resumeOtWarmMirror("run-settled");
|
|
38488
|
-
}
|
|
38489
38939
|
await flushQueuedSaveState().catch(() => {
|
|
38490
38940
|
});
|
|
38491
38941
|
currentRunView = null;
|
|
38492
38942
|
runCancellationRequested = false;
|
|
38493
38943
|
runCancellationController = null;
|
|
38494
38944
|
activeTurnControl.release(settlement.requestId);
|
|
38945
|
+
if (isExperimentalOtEnabled()) {
|
|
38946
|
+
try {
|
|
38947
|
+
await resumeOtWarmMirror("run-settled");
|
|
38948
|
+
} catch (_error) {
|
|
38949
|
+
updateOtStatusDisplay("unavailable");
|
|
38950
|
+
}
|
|
38951
|
+
}
|
|
38495
38952
|
if (settlement.requestId) {
|
|
38496
38953
|
activeTurnControl.acknowledge(settlement.requestId).catch(() => {
|
|
38497
38954
|
});
|
|
@@ -41060,6 +41517,7 @@ ${tx("Writeback note: Codex could not confirm any Overleaf write result entries,
|
|
|
41060
41517
|
title: session.title || "",
|
|
41061
41518
|
titleSource: session.titleSource || "auto",
|
|
41062
41519
|
focusFiles: session.focusFiles || [],
|
|
41520
|
+
projectReferenceFiles: session.projectReferenceFiles || [],
|
|
41063
41521
|
codexThreadId: session.codexThreadId || "",
|
|
41064
41522
|
createdAt: session.createdAt,
|
|
41065
41523
|
updatedAt: session.updatedAt,
|
|
@@ -41371,15 +41829,7 @@ ${tx("Writeback note: Codex could not confirm any Overleaf write result entries,
|
|
|
41371
41829
|
renderSessionList();
|
|
41372
41830
|
}
|
|
41373
41831
|
function getRenderedModelEntries() {
|
|
41374
|
-
return
|
|
41375
|
-
id: option.value,
|
|
41376
|
-
label: option.textContent,
|
|
41377
|
-
reasoningEfforts: (option.dataset.reasoningEfforts || "").split(",").filter(Boolean),
|
|
41378
|
-
defaultReasoningEffort: option.dataset.defaultReasoningEffort || "",
|
|
41379
|
-
reasoningPresentation: option.dataset.reasoningPresentation || "",
|
|
41380
|
-
speedTiers: (option.dataset.speedTiers || "standard").split(",").filter(Boolean),
|
|
41381
|
-
defaultSpeedTier: option.dataset.defaultSpeedTier || "standard"
|
|
41382
|
-
}));
|
|
41832
|
+
return Modules.ModelPickerSupport.getRenderedModelEntries(panel);
|
|
41383
41833
|
}
|
|
41384
41834
|
async function selectMode(mode) {
|
|
41385
41835
|
if (!["ask", "auto"].includes(mode)) {
|
|
@@ -41500,6 +41950,7 @@ ${tx("Writeback note: Codex could not confirm any Overleaf write result entries,
|
|
|
41500
41950
|
applySessionLabel();
|
|
41501
41951
|
renderSessionList();
|
|
41502
41952
|
renderRunHistory(options2);
|
|
41953
|
+
getTrackedChangeCaptureController().schedule();
|
|
41503
41954
|
renderContextSelection();
|
|
41504
41955
|
renderContextSummary();
|
|
41505
41956
|
if (!composerAttachmentsRestoredOnce && Array.isArray(state.composerAttachments) && state.composerAttachments.length && !composerAttachmentController.getAttachmentsForRun?.().length && typeof composerAttachmentController.restorePersistedAttachments === "function") {
|
|
@@ -41578,6 +42029,7 @@ ${tx("Writeback note: Codex could not confirm any Overleaf write result entries,
|
|
|
41578
42029
|
undoStatus: "",
|
|
41579
42030
|
queueItemId,
|
|
41580
42031
|
nativeRequestId: "",
|
|
42032
|
+
codexThreadId: "",
|
|
41581
42033
|
codexTurnId: "",
|
|
41582
42034
|
nativeEventSeq: 0,
|
|
41583
42035
|
executionSnapshot: executionSnapshot ? RunExecutionSnapshot.cloneSnapshot(executionSnapshot) : void 0,
|
|
@@ -41716,6 +42168,7 @@ ${tx("Writeback note: Codex could not confirm any Overleaf write result entries,
|
|
|
41716
42168
|
currentRunView.activeTurn = { threadId, turnId };
|
|
41717
42169
|
const record = findRunRecord(currentRunView.recordId, currentRunView.sessionId);
|
|
41718
42170
|
if (record) {
|
|
42171
|
+
record.codexThreadId = threadId;
|
|
41719
42172
|
record.codexTurnId = turnId;
|
|
41720
42173
|
record.nativeEventSeq = Math.max(Number(record.nativeEventSeq || 0), Number(journalSeq || 0));
|
|
41721
42174
|
}
|
|
@@ -42029,6 +42482,12 @@ ${tx("Writeback note: Codex could not confirm any Overleaf write result entries,
|
|
|
42029
42482
|
}
|
|
42030
42483
|
return files;
|
|
42031
42484
|
}
|
|
42485
|
+
function refreshHistoricalProjectReferences(project) {
|
|
42486
|
+
if (!project?.id || String(project.id) !== getCurrentProjectId()) return;
|
|
42487
|
+
state = updateActiveSession(state, { projectReferenceFiles: captureProjectReferenceFiles(project) });
|
|
42488
|
+
saveStateSoon();
|
|
42489
|
+
if (!currentRunView && !trackedChangeInFlight.size) renderRunHistory({ preserveScroll: true });
|
|
42490
|
+
}
|
|
42032
42491
|
function persistCurrentProjectReferenceFiles(project) {
|
|
42033
42492
|
const projectFiles = captureProjectReferenceFiles(project);
|
|
42034
42493
|
if (currentRunView) {
|
|
@@ -42143,6 +42602,7 @@ ${tx("Writeback note: Codex could not confirm any Overleaf write result entries,
|
|
|
42143
42602
|
runProjectId: getRunProjectIdForWriteback(run)
|
|
42144
42603
|
});
|
|
42145
42604
|
const undoApplied = isUndoResultEffectivelyApplied(run, result);
|
|
42605
|
+
writebackOrchestrator.invalidateMirrorAfterUndo(runId, getRunProjectIdForWriteback(run), result);
|
|
42146
42606
|
appendUndoReviewingPolicyEvent(runId, result.reviewingPolicy);
|
|
42147
42607
|
appendRunRecordEvent(runId, {
|
|
42148
42608
|
title: tr("undoResult", { applied: result.applied?.length || 0, skipped: result.skipped?.length || 0 }),
|
|
@@ -42195,11 +42655,14 @@ ${tx("Writeback note: Codex could not confirm any Overleaf write result entries,
|
|
|
42195
42655
|
detail: { [tr("detailWillUndo")]: trackedUndo ? formatTrackedChangeFiles(run.undoTrackedChanges) : formatTrackedUndoFiles(run) }
|
|
42196
42656
|
});
|
|
42197
42657
|
let result;
|
|
42658
|
+
let trackedUndoPostFilesAtDispatch;
|
|
42198
42659
|
try {
|
|
42660
|
+
trackedUndoPostFilesAtDispatch = buildTrackedUndoPostFiles(run);
|
|
42199
42661
|
result = await callPageBridge("rejectTrackedChanges", {
|
|
42200
42662
|
trackedChanges: run.undoTrackedChanges || [],
|
|
42201
42663
|
expectedFiles: run.undoExpectedFiles || [],
|
|
42202
|
-
postFiles:
|
|
42664
|
+
postFiles: trackedUndoPostFilesAtDispatch,
|
|
42665
|
+
untrackedUndo: run.executionSnapshot ? run.executionSnapshot.requireReviewing === false && ["submitted", "legacy-captured"].includes(run.executionSnapshot.source) : getTrackedChangeCaptureController().hasLegacyUntrackedCheckpoint(run),
|
|
42203
42666
|
// Welcome-panel + write-guard:
|
|
42204
42667
|
// bind the reject to the run's original project. If the user has
|
|
42205
42668
|
// navigated away the page-side guard refuses with
|
|
@@ -42211,6 +42674,7 @@ ${tx("Writeback note: Codex could not confirm any Overleaf write result entries,
|
|
|
42211
42674
|
trackedChangeInFlight.delete(runId);
|
|
42212
42675
|
}
|
|
42213
42676
|
}
|
|
42677
|
+
writebackOrchestrator.invalidateMirrorAfterUndo(runId, getRunProjectIdForWriteback(run), result);
|
|
42214
42678
|
appendRunRecordEvent(runId, {
|
|
42215
42679
|
title: trackedUndo ? tr("undoTrackedResult", { applied: result.applied?.length || 0, skipped: result.skipped?.length || 0 }) : tr("undoNativeResult", { applied: result.applied?.length || 0, skipped: result.skipped?.length || 0 }),
|
|
42216
42680
|
status: result.skipped?.length ? "failed" : "completed",
|
|
@@ -42228,7 +42692,8 @@ ${tx("Writeback note: Codex could not confirm any Overleaf write result entries,
|
|
|
42228
42692
|
});
|
|
42229
42693
|
if (lifecycleReject) {
|
|
42230
42694
|
WritebackSettlement.attachUndoNotVerifiedFailure(run, result, {
|
|
42231
|
-
buildFailure: buildContentFailure
|
|
42695
|
+
buildFailure: buildContentFailure,
|
|
42696
|
+
postFiles: trackedUndoPostFilesAtDispatch
|
|
42232
42697
|
});
|
|
42233
42698
|
applyTrackedChangeSettlement(runId, "reject", result);
|
|
42234
42699
|
return;
|
|
@@ -42408,6 +42873,28 @@ ${tx("Writeback note: Codex could not confirm any Overleaf write result entries,
|
|
|
42408
42873
|
function attachVerifiedContentToOperation(operation, result) {
|
|
42409
42874
|
return WritebackSettlement.attachVerifiedContentToOperation(operation, result);
|
|
42410
42875
|
}
|
|
42876
|
+
let trackedChangeCaptureController = null;
|
|
42877
|
+
function getTrackedChangeCaptureController() {
|
|
42878
|
+
return trackedChangeCaptureController || (trackedChangeCaptureController = Modules.TrackedChangeCaptureController.create({
|
|
42879
|
+
getRuns: () => (state.sessions || []).flatMap((session) => session.runs || []),
|
|
42880
|
+
getProjectId: () => window.location.pathname.match(/^\/project\/([^/]+)/)?.[1] || "",
|
|
42881
|
+
buildExpectedFilesAfterOperations,
|
|
42882
|
+
normalizeTrackedChanges: normalizeApplyTrackedChanges,
|
|
42883
|
+
callPageBridge,
|
|
42884
|
+
persist: () => flushQueuedSaveState({ preserveRunActionPayload: true }),
|
|
42885
|
+
refresh: (run) => refreshRunCardControls(run.id),
|
|
42886
|
+
notify: (run, kind, detail) => appendRunRecordEvent(run.id, {
|
|
42887
|
+
title: {
|
|
42888
|
+
pending: tx("Files written; confirming tracked changes.", "\u6587\u4EF6\u5DF2\u5199\u5165\uFF0C\u6B63\u5728\u786E\u8BA4\u7559\u75D5\u8BB0\u5F55\u3002"),
|
|
42889
|
+
observed: tx("Tracked changes confirmed; Accept is available.", "\u7559\u75D5\u8BB0\u5F55\u5DF2\u786E\u8BA4\uFF0C\u53EF\u4EE5\u63A5\u53D7\u6539\u52A8\u3002"),
|
|
42890
|
+
needs_review: tx("Tracked changes could not be safely attributed. Review them in Overleaf; Undo is preserved.", "\u7559\u75D5\u5F52\u5C5E\u5C1A\u672A\u786E\u8BA4\uFF0C\u8BF7\u5728 Overleaf \u5BA1\u9605\uFF1B\u539F\u6709\u64A4\u9500\u80FD\u529B\u5DF2\u4FDD\u7559\u3002")
|
|
42891
|
+
}[kind],
|
|
42892
|
+
status: "info",
|
|
42893
|
+
detail
|
|
42894
|
+
}),
|
|
42895
|
+
onError: (error) => appendPlainLog(tx("Tracked-change confirmation unavailable: ", "\u7559\u75D5\u786E\u8BA4\u6682\u4E0D\u53EF\u7528\uFF1A") + error.message)
|
|
42896
|
+
}));
|
|
42897
|
+
}
|
|
42411
42898
|
function recordUndoFromApply(project, applyResult) {
|
|
42412
42899
|
const appliedEntries = getAppliedEntries(applyResult);
|
|
42413
42900
|
if (!currentRunView?.recordId || !appliedEntries.length) {
|
|
@@ -42444,6 +42931,7 @@ ${tx("Writeback note: Codex could not confirm any Overleaf write result entries,
|
|
|
42444
42931
|
if (combinedTrackedChanges.length) {
|
|
42445
42932
|
record.trackedChangeStatus = "pending";
|
|
42446
42933
|
}
|
|
42934
|
+
getTrackedChangeCaptureController().record(record, applyResult?.trackedChangeCaptures);
|
|
42447
42935
|
refreshRunCardControls(record.id);
|
|
42448
42936
|
if (combinedTrackedChanges.length) {
|
|
42449
42937
|
appendRunEvent({
|
|
@@ -42505,28 +42993,10 @@ ${tx("Writeback note: Codex could not confirm any Overleaf write result entries,
|
|
|
42505
42993
|
return WritebackSettlement.normalizeApplyTrackedChanges(changes);
|
|
42506
42994
|
}
|
|
42507
42995
|
function selectExpectedFilesForTrackedUndo(project, operations = [], trackedChanges = [], previousExpectedFiles = []) {
|
|
42508
|
-
return WritebackSettlement.selectExpectedFilesForTrackedUndo(
|
|
42509
|
-
project,
|
|
42510
|
-
operations,
|
|
42511
|
-
trackedChanges,
|
|
42512
|
-
previousExpectedFiles
|
|
42513
|
-
);
|
|
42996
|
+
return WritebackSettlement.selectExpectedFilesForTrackedUndo(project, operations, trackedChanges, previousExpectedFiles);
|
|
42514
42997
|
}
|
|
42515
42998
|
function buildTrackedUndoPostFiles(run) {
|
|
42516
|
-
|
|
42517
|
-
const appliedOperations = Array.isArray(run?.appliedOperations) ? run.appliedOperations : [];
|
|
42518
|
-
if (!expectedFiles.length || !appliedOperations.length) {
|
|
42519
|
-
return [];
|
|
42520
|
-
}
|
|
42521
|
-
const postFilesByPath = buildExpectedFilesAfterOperations(
|
|
42522
|
-
{ files: expectedFiles },
|
|
42523
|
-
appliedOperations
|
|
42524
|
-
);
|
|
42525
|
-
const expectedPaths = new Set(expectedFiles.map((file) => file?.path).filter(Boolean));
|
|
42526
|
-
return Array.from(postFilesByPath.entries()).filter(([path, content]) => expectedPaths.has(path) && typeof content === "string").map(([path, content]) => ({
|
|
42527
|
-
path,
|
|
42528
|
-
content
|
|
42529
|
-
}));
|
|
42999
|
+
return getTrackedChangeCaptureController().buildPostFiles(run);
|
|
42530
43000
|
}
|
|
42531
43001
|
function hasTrackedEditorUndo(run) {
|
|
42532
43002
|
return buildTrackedUndoPostFiles(run).length > 0;
|
|
@@ -43103,7 +43573,7 @@ Reason: ${item.reason || "No reason provided"}`),
|
|
|
43103
43573
|
root.CodexOverleafContentRuntime = { init };
|
|
43104
43574
|
})(typeof window !== "undefined" ? window : globalThis);
|
|
43105
43575
|
}).call(globalThis, void 0, void 0, void 0);
|
|
43106
|
-
(function
|
|
43576
|
+
(function runClassicContentModule101(module, exports, require2) {
|
|
43107
43577
|
(function initCodexOverleafLegacyGlobalRegistry(root, factory) {
|
|
43108
43578
|
"use strict";
|
|
43109
43579
|
const api = factory();
|
|
@@ -43179,6 +43649,7 @@ Reason: ${item.reason || "No reason provided"}`),
|
|
|
43179
43649
|
"StorageMigration",
|
|
43180
43650
|
"Summary",
|
|
43181
43651
|
"Theme",
|
|
43652
|
+
"TrackedChangeCaptureController",
|
|
43182
43653
|
"UndoOperations",
|
|
43183
43654
|
"UpdateIdle",
|
|
43184
43655
|
"UpdateNotice",
|