codex-overleaf-link 2.3.2 → 2.3.4
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 +23 -23
- package/extension/bootstrap/manifest.template.json +1 -1
- package/extension/src/content/contentRuntime.js +42 -5
- package/extension/src/content/generated/content.bundle.js +227 -11
- package/extension/src/content/generated/content.bundle.meta.json +3 -3
- package/extension/src/content/markdownDomRenderer.js +70 -0
- package/extension/src/content/modelPicker.js +1 -1
- package/extension/src/content/panelMaintenance.js +2 -0
- package/extension/src/content/panelRenderer.js +80 -1
- package/extension/src/content/pendingInputView.js +16 -3
- package/extension/src/content/providerSettingsDialog.js +1 -0
- package/extension/src/content/runController.js +35 -0
- package/extension/src/content/runTimelineView.js +3 -0
- package/extension/src/popup.js +10 -10
- package/extension/src/shared/compatibility.js +1 -1
- package/extension/styles/panel.css +243 -31
- package/native-host/src/codexRuntimeIdentity.js +79 -4
- package/native-host/src/nativeEnvironment.js +4 -1
- package/native-host/src/textPatch.js +707 -259
- package/package.json +1 -1
|
@@ -11368,7 +11368,7 @@ ${block}`;
|
|
|
11368
11368
|
const MIN_NATIVE_VERSION = "1.0.0";
|
|
11369
11369
|
const MIN_COMPATIBLE_NATIVE_VERSION = "1.0.0";
|
|
11370
11370
|
const MIN_COMPATIBLE_EXTENSION_VERSION = "1.0.0";
|
|
11371
|
-
const BUILD_TARGET_VERSION = "2.3.
|
|
11371
|
+
const BUILD_TARGET_VERSION = "2.3.4";
|
|
11372
11372
|
const DEFAULT_CHROME_EXTENSION_ID = "illdpneeeopfffmiepaejglgmhpmdhdc";
|
|
11373
11373
|
const REQUIRED_CAPABILITIES = Object.freeze([
|
|
11374
11374
|
"bridgePing",
|
|
@@ -16058,11 +16058,39 @@ ${block}`;
|
|
|
16058
16058
|
function defaultIsUsableProjectFileContent(content) {
|
|
16059
16059
|
return String(content || "").trim().length > 0;
|
|
16060
16060
|
}
|
|
16061
|
+
function isRetryReplacementEligible(run = {}, projection = {}) {
|
|
16062
|
+
if (!run.id || !["failed", "interrupted"].includes(run.status)) return false;
|
|
16063
|
+
if (run.trackedChangeStatus || run.undoStatus) return false;
|
|
16064
|
+
if (["undoOperations", "undoTrackedChanges", "undoExpectedFiles", "undoBaseFiles", "appliedOperations"].some((field) => Array.isArray(run[field]) && run[field].length)) return false;
|
|
16065
|
+
if (projection.canAccept || projection.canUndo || projection.changedDocument === true) return false;
|
|
16066
|
+
if (projection.failureTerminalState === "needs_review" || projection.terminalState === "needs_review") return false;
|
|
16067
|
+
return projection.changedDocument === false || run.mode === "ask" || hasZeroWriteReport(run.events);
|
|
16068
|
+
}
|
|
16069
|
+
function hasZeroWriteReport(events = []) {
|
|
16070
|
+
return (Array.isArray(events) ? events : []).some((event) => {
|
|
16071
|
+
const rows = Array.isArray(event?.detailStructured?.meta) ? event.detailStructured.meta : [];
|
|
16072
|
+
return rows.some((row) => row?.key === "writeResult" && /(?:wrote|写入)\s*0\b[\s\S]*(?:skipped|跳过)\s*0\b/i.test(String(row.value || "")));
|
|
16073
|
+
});
|
|
16074
|
+
}
|
|
16075
|
+
function resolveRetryReplacement({ candidate, activeSessionId, runs, projectRunSettlement } = {}) {
|
|
16076
|
+
if (!candidate?.runId || candidate.sessionId !== activeSessionId) return "";
|
|
16077
|
+
const source = (Array.isArray(runs) ? runs : []).find((run) => run?.id === candidate.runId);
|
|
16078
|
+
if (!source) return "";
|
|
16079
|
+
const projection = typeof projectRunSettlement === "function" ? projectRunSettlement(source) : {};
|
|
16080
|
+
return isRetryReplacementEligible(source, projection) ? source.id : "";
|
|
16081
|
+
}
|
|
16082
|
+
function replaceRunForRetry(runs, sourceRunId, nextRun, maxRuns = 20) {
|
|
16083
|
+
const retained = (Array.isArray(runs) ? runs : []).filter((run) => !sourceRunId || run?.id !== sourceRunId);
|
|
16084
|
+
return [...retained, nextRun].slice(-Math.max(1, maxRuns));
|
|
16085
|
+
}
|
|
16061
16086
|
return {
|
|
16062
16087
|
buildCodexRunParams,
|
|
16063
16088
|
canUseFocusedPartialSnapshot,
|
|
16064
16089
|
shouldRestrictWritebackToFocus,
|
|
16065
16090
|
buildSessionHistoryResult,
|
|
16091
|
+
isRetryReplacementEligible,
|
|
16092
|
+
replaceRunForRetry,
|
|
16093
|
+
resolveRetryReplacement,
|
|
16066
16094
|
truncateSessionHistoryText,
|
|
16067
16095
|
normalizeComposerAttachments,
|
|
16068
16096
|
normalizeSkillInvocation
|
|
@@ -16772,10 +16800,13 @@ ${block}`;
|
|
|
16772
16800
|
const ROOT_CLASS = "codex-overleaf-panel-mounted";
|
|
16773
16801
|
const RESIZE_CLASS = "codex-overleaf-panel-resizing";
|
|
16774
16802
|
const COMPACT_CLASS = "codex-overleaf-panel-compact";
|
|
16803
|
+
const LAUNCHER_VISIBILITY_STORAGE_KEY = "codex-overleaf:launcher-visible";
|
|
16775
16804
|
function codexIcon(name) {
|
|
16776
16805
|
const icons = {
|
|
16777
16806
|
refresh: '<path d="M4.2 5.3A5 5 0 1 1 3.6 10"/><path d="M4.2 2.2v3.1H1.1"/>',
|
|
16778
16807
|
plus: '<path d="M8 3.2v9.6"/><path d="M3.2 8h9.6"/>',
|
|
16808
|
+
panel: '<rect x="2.3" y="2.3" width="11.4" height="11.4" rx="2"/><path d="M9.2 2.5v11"/><path d="M5.1 6.1h1.5M5.1 8h1.5M5.1 9.9h1.5"/>',
|
|
16809
|
+
collapse: '<path d="m6.1 3.3 4.7 4.7-4.7 4.7"/>',
|
|
16779
16810
|
settings: '<path d="M3.4 5.2h5.9"/><path d="M11.7 5.2h.9"/><path d="M10.1 3.6v3.2"/><path d="M3.4 10.8h1"/><path d="M6.8 10.8h5.8"/><path d="M5.9 9.2v3.2"/>'
|
|
16780
16811
|
};
|
|
16781
16812
|
const safeName = Object.prototype.hasOwnProperty.call(icons, name) ? name : "settings";
|
|
@@ -16785,9 +16816,11 @@ ${block}`;
|
|
|
16785
16816
|
const doc = options2.document || document;
|
|
16786
16817
|
const container = options2.container || doc.documentElement;
|
|
16787
16818
|
const panelEl = doc.createElement("aside");
|
|
16819
|
+
const launcherEl = doc.createElement("button");
|
|
16788
16820
|
const callbacks = options2.callbacks || {};
|
|
16789
16821
|
const instance = {
|
|
16790
16822
|
panelEl,
|
|
16823
|
+
launcherEl,
|
|
16791
16824
|
callbacks,
|
|
16792
16825
|
defaultWidth: options2.defaultWidth || 380,
|
|
16793
16826
|
minWidth: options2.minWidth || 340,
|
|
@@ -16796,8 +16829,16 @@ ${block}`;
|
|
|
16796
16829
|
lastDesktopWidth: options2.initialWidth || options2.defaultWidth || 380,
|
|
16797
16830
|
listeners: [],
|
|
16798
16831
|
document: doc,
|
|
16799
|
-
window: options2.window || window
|
|
16832
|
+
window: options2.window || window,
|
|
16833
|
+
chromeApi: options2.chromeApi || (typeof chrome !== "undefined" ? chrome : null),
|
|
16834
|
+
storageChangeListener: null
|
|
16800
16835
|
};
|
|
16836
|
+
launcherEl.id = "codex-overleaf-launcher";
|
|
16837
|
+
launcherEl.type = "button";
|
|
16838
|
+
launcherEl.title = options2.launcherLabel || "Show or hide Codex panel";
|
|
16839
|
+
launcherEl.setAttribute("aria-label", launcherEl.title);
|
|
16840
|
+
launcherEl.setAttribute("aria-expanded", "false");
|
|
16841
|
+
launcherEl.innerHTML = codexIcon("panel");
|
|
16801
16842
|
panelEl.id = options2.panelId || "codex-overleaf-panel";
|
|
16802
16843
|
panelEl.dataset.view = "session";
|
|
16803
16844
|
panelEl.innerHTML = `
|
|
@@ -16809,6 +16850,7 @@ ${block}`;
|
|
|
16809
16850
|
<div data-diagnostics-slot></div>
|
|
16810
16851
|
<button type="button" data-new-session title="New Session" aria-label="New Session">${codexIcon("plus")}</button>
|
|
16811
16852
|
<button type="button" data-custom-instructions-settings title="Project Settings" aria-label="Project Settings" aria-expanded="false">${codexIcon("settings")}</button>
|
|
16853
|
+
<button type="button" data-close-panel title="Close Codex panel" aria-label="Close Codex panel">${codexIcon("collapse")}</button>
|
|
16812
16854
|
</div>
|
|
16813
16855
|
</div>
|
|
16814
16856
|
<div data-settings-slot></div>
|
|
@@ -16823,6 +16865,7 @@ ${block}`;
|
|
|
16823
16865
|
<div data-composer-slot></div>
|
|
16824
16866
|
`;
|
|
16825
16867
|
container.append(panelEl);
|
|
16868
|
+
container.append(launcherEl);
|
|
16826
16869
|
doc.documentElement.classList.add(ROOT_CLASS);
|
|
16827
16870
|
instance.headerEl = panelEl.querySelector("[data-panel-header]");
|
|
16828
16871
|
instance.bodyEl = panelEl.querySelector("[data-main]");
|
|
@@ -16835,6 +16878,8 @@ ${block}`;
|
|
|
16835
16878
|
bind(instance, panelEl.querySelector("[data-refresh]"), "click", () => callbacks.onRefresh?.());
|
|
16836
16879
|
bind(instance, panelEl.querySelector("[data-new-session]"), "click", () => callbacks.onNewSession?.());
|
|
16837
16880
|
bind(instance, panelEl.querySelector("[data-custom-instructions-settings]"), "click", () => callbacks.onSettingsClick?.());
|
|
16881
|
+
bind(instance, panelEl.querySelector("[data-close-panel]"), "click", () => callbacks.onClosePanel?.());
|
|
16882
|
+
bind(instance, launcherEl, "click", () => callbacks.onLauncherToggle?.());
|
|
16838
16883
|
bind(instance, panelEl.querySelector("[data-panel-resize-handle]"), "pointerdown", (event) => startResize(instance, event));
|
|
16839
16884
|
bind(instance, panelEl.querySelector("[data-panel-resize-handle]"), "dblclick", (event) => {
|
|
16840
16885
|
event?.preventDefault?.();
|
|
@@ -16848,8 +16893,10 @@ ${block}`;
|
|
|
16848
16893
|
setWidth(instance, instance.lastDesktopWidth || instance.defaultWidth, { notify: true, persist: false });
|
|
16849
16894
|
});
|
|
16850
16895
|
setWidth(instance, options2.initialWidth || instance.defaultWidth, { notify: false });
|
|
16896
|
+
initializeLauncherVisibility(instance);
|
|
16851
16897
|
return {
|
|
16852
16898
|
panelEl,
|
|
16899
|
+
launcherEl,
|
|
16853
16900
|
headerEl: instance.headerEl,
|
|
16854
16901
|
bodyEl: instance.bodyEl,
|
|
16855
16902
|
diagnosticsSlot: instance.diagnosticsSlot,
|
|
@@ -16944,10 +16991,58 @@ ${block}`;
|
|
|
16944
16991
|
function setVisible(panelEl, visible) {
|
|
16945
16992
|
panelEl?.classList?.toggle("is-open", Boolean(visible));
|
|
16946
16993
|
document.documentElement.classList.toggle(ROOT_CLASS, Boolean(visible));
|
|
16994
|
+
const launcherEl = panelEl?.ownerDocument?.getElementById?.("codex-overleaf-launcher");
|
|
16995
|
+
launcherEl?.classList?.toggle("is-panel-open", Boolean(visible));
|
|
16996
|
+
launcherEl?.setAttribute?.("aria-expanded", visible ? "true" : "false");
|
|
16997
|
+
if (launcherEl) {
|
|
16998
|
+
launcherEl.hidden = Boolean(visible) || launcherEl.dataset.enabled === "false";
|
|
16999
|
+
launcherEl.setAttribute("aria-hidden", launcherEl.hidden ? "true" : "false");
|
|
17000
|
+
}
|
|
16947
17001
|
if (!visible) {
|
|
16948
17002
|
document.documentElement.classList.remove(RESIZE_CLASS, COMPACT_CLASS);
|
|
16949
17003
|
}
|
|
16950
17004
|
}
|
|
17005
|
+
function initializeLauncherVisibility(instance) {
|
|
17006
|
+
const storage = instance.chromeApi?.storage;
|
|
17007
|
+
if (!storage?.local?.get) {
|
|
17008
|
+
setLauncherVisible(instance, true, { persist: false });
|
|
17009
|
+
return;
|
|
17010
|
+
}
|
|
17011
|
+
Promise.resolve(storage.local.get({ [LAUNCHER_VISIBILITY_STORAGE_KEY]: true })).then((values) => applyLauncherVisibility(instance, values?.[LAUNCHER_VISIBILITY_STORAGE_KEY])).catch(() => applyLauncherVisibility(instance, true));
|
|
17012
|
+
if (storage.onChanged?.addListener) {
|
|
17013
|
+
instance.storageChangeListener = (changes, areaName) => {
|
|
17014
|
+
if (areaName === "local" && changes?.[LAUNCHER_VISIBILITY_STORAGE_KEY]) {
|
|
17015
|
+
applyLauncherVisibility(instance, changes[LAUNCHER_VISIBILITY_STORAGE_KEY].newValue);
|
|
17016
|
+
}
|
|
17017
|
+
};
|
|
17018
|
+
storage.onChanged.addListener(instance.storageChangeListener);
|
|
17019
|
+
}
|
|
17020
|
+
}
|
|
17021
|
+
function applyLauncherVisibility(instance, value) {
|
|
17022
|
+
const visible = value !== false;
|
|
17023
|
+
setLauncherVisible(instance, visible, { persist: false });
|
|
17024
|
+
instance.callbacks.onLauncherVisibilityChange?.(visible);
|
|
17025
|
+
}
|
|
17026
|
+
function setLauncherVisible(target, visible, options2 = {}) {
|
|
17027
|
+
const instance = target?._instance || target;
|
|
17028
|
+
const launcherEl = instance?.launcherEl;
|
|
17029
|
+
if (!launcherEl) return false;
|
|
17030
|
+
const nextVisible = Boolean(visible);
|
|
17031
|
+
launcherEl.dataset.enabled = nextVisible ? "true" : "false";
|
|
17032
|
+
launcherEl.hidden = !nextVisible || instance.panelEl?.classList?.contains("is-open") === true;
|
|
17033
|
+
launcherEl.setAttribute("aria-hidden", launcherEl.hidden ? "true" : "false");
|
|
17034
|
+
if (options2.persist === true) {
|
|
17035
|
+
Promise.resolve(instance.chromeApi?.storage?.local?.set?.({
|
|
17036
|
+
[LAUNCHER_VISIBILITY_STORAGE_KEY]: nextVisible
|
|
17037
|
+
})).catch(() => {
|
|
17038
|
+
});
|
|
17039
|
+
}
|
|
17040
|
+
return nextVisible;
|
|
17041
|
+
}
|
|
17042
|
+
function isLauncherVisible(target) {
|
|
17043
|
+
const instance = target?._instance || target;
|
|
17044
|
+
return Boolean(instance?.launcherEl && instance.launcherEl.dataset.enabled !== "false");
|
|
17045
|
+
}
|
|
16951
17046
|
function setBadge(headerEl, badge = {}) {
|
|
16952
17047
|
const actions = headerEl?.querySelector?.(".codex-vscode-head-actions");
|
|
16953
17048
|
if (!actions) {
|
|
@@ -17075,12 +17170,18 @@ ${block}`;
|
|
|
17075
17170
|
target.removeEventListener?.(type, listener, options2);
|
|
17076
17171
|
}
|
|
17077
17172
|
instance.panelEl?.remove?.();
|
|
17173
|
+
instance.launcherEl?.remove?.();
|
|
17174
|
+
if (instance.storageChangeListener) {
|
|
17175
|
+
instance.chromeApi?.storage?.onChanged?.removeListener?.(instance.storageChangeListener);
|
|
17176
|
+
}
|
|
17078
17177
|
instance.document.documentElement.classList.remove(ROOT_CLASS, RESIZE_CLASS, COMPACT_CLASS);
|
|
17079
17178
|
}
|
|
17080
17179
|
window.CodexOverleafPanelRenderer = {
|
|
17081
17180
|
create,
|
|
17082
17181
|
createConfirmController,
|
|
17083
17182
|
setVisible,
|
|
17183
|
+
setLauncherVisible,
|
|
17184
|
+
isLauncherVisible,
|
|
17084
17185
|
setBadge,
|
|
17085
17186
|
setWidth
|
|
17086
17187
|
};
|
|
@@ -18735,6 +18836,7 @@ ${block}`;
|
|
|
18735
18836
|
return;
|
|
18736
18837
|
}
|
|
18737
18838
|
const style = instance.document.defaultView.getComputedStyle(panel);
|
|
18839
|
+
instance.root.dataset.theme = panel.dataset.theme === "light" ? "light" : "dark";
|
|
18738
18840
|
instance.root.style.setProperty("--provider-panel-bg", style.backgroundColor || "#151716");
|
|
18739
18841
|
instance.root.style.setProperty("--provider-panel-color", style.color || "#eceeea");
|
|
18740
18842
|
}
|
|
@@ -20687,10 +20789,17 @@ ${block}`;
|
|
|
20687
20789
|
}
|
|
20688
20790
|
container.replaceChildren();
|
|
20689
20791
|
container.hidden = !items.length;
|
|
20792
|
+
if (!items.length) {
|
|
20793
|
+
return;
|
|
20794
|
+
}
|
|
20690
20795
|
for (const item of items) {
|
|
20691
20796
|
const row = document.createElement("article");
|
|
20692
20797
|
row.className = "codex-pending-input";
|
|
20693
20798
|
row.dataset.status = item.status || "queued";
|
|
20799
|
+
const marker = document.createElement("span");
|
|
20800
|
+
marker.className = "codex-pending-input-marker";
|
|
20801
|
+
marker.setAttribute("aria-hidden", "true");
|
|
20802
|
+
marker.append(createIcon("queue"));
|
|
20694
20803
|
const copy = document.createElement("div");
|
|
20695
20804
|
copy.className = "codex-pending-input-copy";
|
|
20696
20805
|
const status = document.createElement("span");
|
|
@@ -20699,7 +20808,10 @@ ${block}`;
|
|
|
20699
20808
|
const text = document.createElement("span");
|
|
20700
20809
|
text.className = "codex-pending-input-text";
|
|
20701
20810
|
text.textContent = item.text;
|
|
20702
|
-
copy.append(
|
|
20811
|
+
copy.append(text);
|
|
20812
|
+
if (item.status && item.status !== "queued") {
|
|
20813
|
+
copy.append(status);
|
|
20814
|
+
}
|
|
20703
20815
|
const actions = document.createElement("div");
|
|
20704
20816
|
actions.className = "codex-pending-input-actions";
|
|
20705
20817
|
if (item.status === "paused") {
|
|
@@ -20723,7 +20835,8 @@ ${block}`;
|
|
|
20723
20835
|
remove.disabled = item.status === "steering" || item.status === "executing";
|
|
20724
20836
|
text.title = item.text;
|
|
20725
20837
|
actions.append(remove);
|
|
20726
|
-
row.
|
|
20838
|
+
row.setAttribute("aria-label", `${status.textContent || options2.tr?.("queuedInputQueued") || "Queued"}: ${item.text}`);
|
|
20839
|
+
row.append(marker, copy, actions);
|
|
20727
20840
|
container.append(row);
|
|
20728
20841
|
}
|
|
20729
20842
|
}
|
|
@@ -20750,7 +20863,7 @@ ${block}`;
|
|
|
20750
20863
|
svg.setAttribute("viewBox", "0 0 20 20");
|
|
20751
20864
|
svg.setAttribute("aria-hidden", "true");
|
|
20752
20865
|
svg.setAttribute("focusable", "false");
|
|
20753
|
-
const paths = icon === "guide" ? ["M4 4.5v4a4 4 0 0 0 4 4h7", "m12 9 3.5 3.5L12 16"] : ["M6 6h8", "M8 6V4.5h4V6", "m7.2 8 0.6 7.5h4.4l.6-7.5"];
|
|
20866
|
+
const paths = icon === "guide" ? ["M4 4.5v4a4 4 0 0 0 4 4h7", "m12 9 3.5 3.5L12 16"] : icon === "queue" ? ["M4 5.5h12", "M4 10h12", "M4 14.5h8"] : ["M6 6h8", "M8 6V4.5h4V6", "m7.2 8 0.6 7.5h4.4l.6-7.5"];
|
|
20754
20867
|
for (const value of paths) {
|
|
20755
20868
|
const path = document.createElementNS("http://www.w3.org/2000/svg", "path");
|
|
20756
20869
|
path.setAttribute("d", value);
|
|
@@ -27385,9 +27498,69 @@ ${block}`;
|
|
|
27385
27498
|
error.code = code;
|
|
27386
27499
|
return error;
|
|
27387
27500
|
}
|
|
27501
|
+
function decorateCompletionReport(container, options2 = {}) {
|
|
27502
|
+
const tx = typeof options2.tx === "function" ? options2.tx : (en) => en;
|
|
27503
|
+
const document2 = container?.ownerDocument || globalThis.document;
|
|
27504
|
+
if (!container || !document2) return;
|
|
27505
|
+
for (const block of Array.from(container.children || [])) {
|
|
27506
|
+
const textNode = Array.from(block.childNodes || []).find((node) => node?.nodeType === 3 && String(node.textContent || "").trim());
|
|
27507
|
+
if (!textNode) continue;
|
|
27508
|
+
const text = String(textNode.textContent || "");
|
|
27509
|
+
const match = text.match(/^(\s*)(Conclusion:|结论:|Changes:|修改:)(\s*)/);
|
|
27510
|
+
if (!match || !textNode.parentNode) continue;
|
|
27511
|
+
const label = document2.createElement("span");
|
|
27512
|
+
label.className = "run-system-label";
|
|
27513
|
+
label.dataset.systemLabel = ["Conclusion:", "\u7ED3\u8BBA\uFF1A"].includes(match[2]) ? "conclusion" : "changes";
|
|
27514
|
+
label.textContent = `${match[2]}${match[3]}`;
|
|
27515
|
+
textNode.textContent = `${match[1]}${text.slice(match[0].length)}`;
|
|
27516
|
+
textNode.parentNode.insertBefore(label, textNode);
|
|
27517
|
+
}
|
|
27518
|
+
decorateChangeReceipts(container, document2, tx);
|
|
27519
|
+
}
|
|
27520
|
+
function decorateChangeReceipts(container, document2, tx) {
|
|
27521
|
+
const label = container.querySelector?.('.run-system-label[data-system-label="changes"]');
|
|
27522
|
+
const list = label?.closest?.("p")?.nextElementSibling;
|
|
27523
|
+
if (!list || !["UL", "OL"].includes(list.tagName)) return;
|
|
27524
|
+
const receipts = [];
|
|
27525
|
+
for (const item of Array.from(list.children || [])) {
|
|
27526
|
+
const original = String(item.textContent || "").trim();
|
|
27527
|
+
const match = original.match(/^(.+?):\s+(edit|create|rename|move|delete)(?:\s+\((.+)\))?$/i) || original.match(/^(.+?):\s*(编辑|新建|重命名|移动|删除)(?:((.+)))?$/);
|
|
27528
|
+
if (!match) return;
|
|
27529
|
+
receipts.push({ item, original, file: match[1], operation: match[2] });
|
|
27530
|
+
}
|
|
27531
|
+
if (!receipts.length) return;
|
|
27532
|
+
const syncedFiles = new Set(receipts.map((receipt) => receipt.file)).size;
|
|
27533
|
+
const summary = document2.createElement("div");
|
|
27534
|
+
summary.className = "run-change-summary";
|
|
27535
|
+
const check = document2.createElement("span");
|
|
27536
|
+
check.className = "run-change-summary__check";
|
|
27537
|
+
check.setAttribute("aria-hidden", "true");
|
|
27538
|
+
check.textContent = "\u2713";
|
|
27539
|
+
const text = document2.createElement("span");
|
|
27540
|
+
text.textContent = tx(
|
|
27541
|
+
`${syncedFiles} ${syncedFiles === 1 ? "file" : "files"} synced`,
|
|
27542
|
+
`\u5DF2\u540C\u6B65 ${syncedFiles} \u4E2A\u6587\u4EF6`
|
|
27543
|
+
);
|
|
27544
|
+
summary.append(check, text);
|
|
27545
|
+
list.parentNode?.insertBefore(summary, list);
|
|
27546
|
+
list.classList.add("run-change-receipts");
|
|
27547
|
+
for (const receipt of receipts) {
|
|
27548
|
+
const file = document2.createElement("span");
|
|
27549
|
+
file.className = "run-change-receipt__file";
|
|
27550
|
+
file.textContent = receipt.file;
|
|
27551
|
+
const operation = document2.createElement("span");
|
|
27552
|
+
operation.className = "run-change-receipt__operation";
|
|
27553
|
+
operation.textContent = receipt.operation;
|
|
27554
|
+
receipt.item.classList.add("run-change-receipt");
|
|
27555
|
+
receipt.item.setAttribute("aria-label", receipt.original);
|
|
27556
|
+
receipt.item.title = receipt.original;
|
|
27557
|
+
receipt.item.replaceChildren(file, operation);
|
|
27558
|
+
}
|
|
27559
|
+
}
|
|
27388
27560
|
return {
|
|
27389
27561
|
DEFAULT_LIMITS,
|
|
27390
27562
|
countTokens,
|
|
27563
|
+
decorateCompletionReport,
|
|
27391
27564
|
renderMarkdown,
|
|
27392
27565
|
stripEmptyHtmlComments
|
|
27393
27566
|
};
|
|
@@ -28820,6 +28993,7 @@ ${block}`;
|
|
|
28820
28993
|
cssEscape,
|
|
28821
28994
|
renderMarkdownInlineText,
|
|
28822
28995
|
renderMarkdownBlockText,
|
|
28996
|
+
decorateCompletionReport,
|
|
28823
28997
|
sanitizeAssistantVisibleText,
|
|
28824
28998
|
sanitizeAssistantVisibleValue,
|
|
28825
28999
|
stripEmptyHtmlCommentPlaceholders = (value) => value,
|
|
@@ -29400,6 +29574,7 @@ ${lines}`
|
|
|
29400
29574
|
}
|
|
29401
29575
|
if (mainSections.length) {
|
|
29402
29576
|
renderMarkdownBlockText(main, mainSections.join("\n\n"));
|
|
29577
|
+
decorateCompletionReport(main, { tx });
|
|
29403
29578
|
report.append(main);
|
|
29404
29579
|
}
|
|
29405
29580
|
appendCompletionMetaBlock(report, structured.meta);
|
|
@@ -29413,6 +29588,7 @@ ${lines}`
|
|
|
29413
29588
|
const body = document.createElement("div");
|
|
29414
29589
|
body.className = "run-final-answer";
|
|
29415
29590
|
renderMarkdownBlockText(body, split.body || flatText);
|
|
29591
|
+
decorateCompletionReport(body, { tx });
|
|
29416
29592
|
report.append(body);
|
|
29417
29593
|
appendCompileFix(report);
|
|
29418
29594
|
appendRejectedRedo(report);
|
|
@@ -31395,7 +31571,7 @@ ${conclusion}` : `${label} ${conclusion}`;
|
|
|
31395
31571
|
if (!efforts.length) {
|
|
31396
31572
|
efforts = presentation === "none" ? ["none"] : ["low", "medium", "high", "xhigh"];
|
|
31397
31573
|
}
|
|
31398
|
-
const current =
|
|
31574
|
+
const current = getState()?.reasoningEffort || reasoningSelect.value || "";
|
|
31399
31575
|
const fallback = efforts.includes(model?.defaultReasoningEffort) ? model.defaultReasoningEffort : efforts.includes("high") ? "high" : efforts[0];
|
|
31400
31576
|
reasoningSelect.textContent = "";
|
|
31401
31577
|
for (const effort of efforts) {
|
|
@@ -34381,6 +34557,7 @@ ${tx("Writeback note: Codex could not confirm any Overleaf write result entries,
|
|
|
34381
34557
|
setState,
|
|
34382
34558
|
getCurrentRunView,
|
|
34383
34559
|
getSettingsPanelInstance,
|
|
34560
|
+
prepareRetryReplacement,
|
|
34384
34561
|
StorageDb
|
|
34385
34562
|
} = deps;
|
|
34386
34563
|
let auditHistoryRecords = [];
|
|
@@ -34533,6 +34710,7 @@ ${tx("Writeback note: Codex could not confirm any Overleaf write result entries,
|
|
|
34533
34710
|
showPluginToast(tx("Nothing to refill: the original task text is unavailable.", "\u65E0\u6CD5\u56DE\u586B\uFF1A\u539F\u4EFB\u52A1\u6587\u672C\u4E0D\u53EF\u7528\u3002"));
|
|
34534
34711
|
return;
|
|
34535
34712
|
}
|
|
34713
|
+
prepareRetryReplacement?.(run || null);
|
|
34536
34714
|
input.value = task;
|
|
34537
34715
|
getState().task = task;
|
|
34538
34716
|
autosizeTaskTextarea();
|
|
@@ -35543,7 +35721,8 @@ ${tx("Writeback note: Codex could not confirm any Overleaf write result entries,
|
|
|
35543
35721
|
state = next;
|
|
35544
35722
|
},
|
|
35545
35723
|
getCurrentRunView: () => currentRunView,
|
|
35546
|
-
getSettingsPanelInstance: () => settingsPanelInstance
|
|
35724
|
+
getSettingsPanelInstance: () => settingsPanelInstance,
|
|
35725
|
+
prepareRetryReplacement: (run) => prepareRetryReplacement(run)
|
|
35547
35726
|
});
|
|
35548
35727
|
const {
|
|
35549
35728
|
showUndoFileSelection,
|
|
@@ -35593,6 +35772,7 @@ ${tx("Writeback note: Codex could not confirm any Overleaf write result entries,
|
|
|
35593
35772
|
cssEscape,
|
|
35594
35773
|
renderMarkdownInlineText,
|
|
35595
35774
|
renderMarkdownBlockText,
|
|
35775
|
+
decorateCompletionReport: Modules.MarkdownDomRenderer.decorateCompletionReport,
|
|
35596
35776
|
sanitizeAssistantVisibleText,
|
|
35597
35777
|
sanitizeAssistantVisibleValue,
|
|
35598
35778
|
buildMarkdownInlineNodes,
|
|
@@ -35984,6 +36164,7 @@ ${tx("Writeback note: Codex could not confirm any Overleaf write result entries,
|
|
|
35984
36164
|
let state = null;
|
|
35985
36165
|
let storageKey = LEGACY_STORAGE_KEY;
|
|
35986
36166
|
let currentRunView = null;
|
|
36167
|
+
let pendingRetryReplacement = null;
|
|
35987
36168
|
let runQueueScheduler = null;
|
|
35988
36169
|
let runInputCoordinator = null;
|
|
35989
36170
|
const activeTurnControl = ActiveTurnControl.create({ chrome });
|
|
@@ -36074,6 +36255,13 @@ ${tx("Writeback note: Codex could not confirm any Overleaf write result entries,
|
|
|
36074
36255
|
sendResponse?.(getPanelStateResponse());
|
|
36075
36256
|
return;
|
|
36076
36257
|
}
|
|
36258
|
+
if (message?.type === "codex-overleaf/toggle-launcher") {
|
|
36259
|
+
const visible = !PanelRenderer.isLauncherVisible(panelRendererInstance);
|
|
36260
|
+
PanelRenderer.setLauncherVisible(panelRendererInstance, visible, { persist: true });
|
|
36261
|
+
if (!visible) closePanel();
|
|
36262
|
+
sendResponse?.(getPanelStateResponse());
|
|
36263
|
+
return;
|
|
36264
|
+
}
|
|
36077
36265
|
if (message?.type === "codex-overleaf/toggle-panel") {
|
|
36078
36266
|
if (isPanelOpen()) {
|
|
36079
36267
|
closePanel();
|
|
@@ -36287,7 +36475,14 @@ ${tx("Writeback note: Codex could not confirm any Overleaf write result entries,
|
|
|
36287
36475
|
maxWidth: PANEL_MAX_WIDTH,
|
|
36288
36476
|
pageMinWidth: PAGE_MIN_WIDTH,
|
|
36289
36477
|
initialWidth: state?.panelWidth || PANEL_DEFAULT_WIDTH,
|
|
36478
|
+
chromeApi: chrome,
|
|
36479
|
+
launcherLabel: tx("Show or hide Codex panel", "\u663E\u793A\u6216\u9690\u85CF Codex \u8FB9\u680F"),
|
|
36290
36480
|
callbacks: {
|
|
36481
|
+
onLauncherToggle: () => ensurePanelOpen(),
|
|
36482
|
+
onClosePanel: () => closePanel(),
|
|
36483
|
+
onLauncherVisibilityChange: (visible) => {
|
|
36484
|
+
if (!visible) closePanel();
|
|
36485
|
+
},
|
|
36291
36486
|
onRefresh: () => refreshProbe({ userInitiated: true }),
|
|
36292
36487
|
onNewSession: () => startNewSession(),
|
|
36293
36488
|
onChangeHistory: () => openChangeHistory(),
|
|
@@ -36451,7 +36646,8 @@ ${tx("Writeback note: Codex could not confirm any Overleaf write result entries,
|
|
|
36451
36646
|
function getPanelStateResponse() {
|
|
36452
36647
|
return {
|
|
36453
36648
|
ok: true,
|
|
36454
|
-
open: isPanelOpen()
|
|
36649
|
+
open: isPanelOpen(),
|
|
36650
|
+
launcherVisible: PanelRenderer.isLauncherVisible(panelRendererInstance)
|
|
36455
36651
|
};
|
|
36456
36652
|
}
|
|
36457
36653
|
function toggleDiagnosticsMenu() {
|
|
@@ -36811,6 +37007,12 @@ ${tx("Writeback note: Codex could not confirm any Overleaf write result entries,
|
|
|
36811
37007
|
) : captureCurrentExecutionSnapshot(submittedPanelState);
|
|
36812
37008
|
const submittedMode = executionSnapshot.mode;
|
|
36813
37009
|
const submittedRequireReviewing = executionSnapshot.requireReviewing === true;
|
|
37010
|
+
const replaceRunId = queuedInput ? "" : runController.resolveRetryReplacement({
|
|
37011
|
+
candidate: pendingRetryReplacement,
|
|
37012
|
+
activeSessionId: state.activeSessionId,
|
|
37013
|
+
runs: state.runs,
|
|
37014
|
+
projectRunSettlement: (run) => WritebackSettlement.projectRunSettlement(run)
|
|
37015
|
+
});
|
|
36814
37016
|
runCancellationRequested = false;
|
|
36815
37017
|
runCancellationController = new AbortController();
|
|
36816
37018
|
setRunning(true);
|
|
@@ -36823,8 +37025,10 @@ ${tx("Writeback note: Codex could not confirm any Overleaf write result entries,
|
|
|
36823
37025
|
executionSnapshot,
|
|
36824
37026
|
attachments: submittedAttachments,
|
|
36825
37027
|
skillInvocation: submittedSkillInvocation,
|
|
36826
|
-
queueItemId: queuedInput?.id || ""
|
|
37028
|
+
queueItemId: queuedInput?.id || "",
|
|
37029
|
+
replaceRunId
|
|
36827
37030
|
});
|
|
37031
|
+
if (!queuedInput) pendingRetryReplacement = null;
|
|
36828
37032
|
const runSessionId = currentRunView.sessionId;
|
|
36829
37033
|
let runAuditDraft = null;
|
|
36830
37034
|
try {
|
|
@@ -40397,6 +40601,16 @@ ${tx("Writeback note: Codex could not confirm any Overleaf write result entries,
|
|
|
40397
40601
|
panel.dataset.cancelling = running && runCancellationRequested ? "true" : "false";
|
|
40398
40602
|
renderPendingInputs();
|
|
40399
40603
|
}
|
|
40604
|
+
function prepareRetryReplacement(run) {
|
|
40605
|
+
const sessionId = state?.activeSessionId || "";
|
|
40606
|
+
const source = findRunRecord(run?.id, sessionId);
|
|
40607
|
+
const eligible = source && runController.isRetryReplacementEligible(
|
|
40608
|
+
source,
|
|
40609
|
+
WritebackSettlement.projectRunSettlement(source)
|
|
40610
|
+
);
|
|
40611
|
+
pendingRetryReplacement = eligible ? { sessionId, runId: source.id } : null;
|
|
40612
|
+
return Boolean(eligible);
|
|
40613
|
+
}
|
|
40400
40614
|
function startRunView({
|
|
40401
40615
|
task,
|
|
40402
40616
|
mode,
|
|
@@ -40404,6 +40618,7 @@ ${tx("Writeback note: Codex could not confirm any Overleaf write result entries,
|
|
|
40404
40618
|
reasoningEffort,
|
|
40405
40619
|
speedTier,
|
|
40406
40620
|
queueItemId = "",
|
|
40621
|
+
replaceRunId = "",
|
|
40407
40622
|
executionSnapshot = null
|
|
40408
40623
|
}) {
|
|
40409
40624
|
let attachments = [];
|
|
@@ -40451,12 +40666,13 @@ ${tx("Writeback note: Codex could not confirm any Overleaf write result entries,
|
|
|
40451
40666
|
titleSource: "auto"
|
|
40452
40667
|
} : {};
|
|
40453
40668
|
state = updateActiveSession(state, {
|
|
40454
|
-
runs:
|
|
40669
|
+
runs: runController.replaceRunForRetry(state.runs, replaceRunId, record),
|
|
40455
40670
|
...titlePatch
|
|
40456
40671
|
});
|
|
40457
|
-
saveStateSoon();
|
|
40672
|
+
saveStateSoon(replaceRunId ? 0 : 120);
|
|
40458
40673
|
const log = panel.querySelector("[data-log]");
|
|
40459
40674
|
removeEmptyRunsMessage(log);
|
|
40675
|
+
if (replaceRunId) log.querySelector(`[data-run-id="${cssEscape(replaceRunId)}"]`)?.remove();
|
|
40460
40676
|
const root2 = renderRunCard(record);
|
|
40461
40677
|
log.append(root2);
|
|
40462
40678
|
scrollLogToBottom({ force: true });
|
|
@@ -2,9 +2,9 @@
|
|
|
2
2
|
"schemaVersion": 1,
|
|
3
3
|
"entry": "extension/entries/content-entry.mjs",
|
|
4
4
|
"output": "extension/src/content/generated/content.bundle.js",
|
|
5
|
-
"sourceDigest": "
|
|
6
|
-
"outputDigest": "
|
|
7
|
-
"byteLength":
|
|
5
|
+
"sourceDigest": "48e7ba193b0723f8e135c4b52e3af1416b1fe35b3cb780207fb0600e7e0f8019",
|
|
6
|
+
"outputDigest": "866811d95e8bd58d369e0790bf2af5becc93946eb8ad987b80f0be0f80fa965f",
|
|
7
|
+
"byteLength": 2321914,
|
|
8
8
|
"inputs": [
|
|
9
9
|
"extension/entries/content-entry.mjs",
|
|
10
10
|
"extension/src/content/activeTurnControl.js",
|
|
@@ -442,9 +442,79 @@
|
|
|
442
442
|
return error;
|
|
443
443
|
}
|
|
444
444
|
|
|
445
|
+
function decorateCompletionReport(container, options = {}) {
|
|
446
|
+
const tx = typeof options.tx === 'function' ? options.tx : en => en;
|
|
447
|
+
const document = container?.ownerDocument || globalThis.document;
|
|
448
|
+
if (!container || !document) return;
|
|
449
|
+
|
|
450
|
+
for (const block of Array.from(container.children || [])) {
|
|
451
|
+
const textNode = Array.from(block.childNodes || [])
|
|
452
|
+
.find(node => node?.nodeType === 3 && String(node.textContent || '').trim());
|
|
453
|
+
if (!textNode) continue;
|
|
454
|
+
const text = String(textNode.textContent || '');
|
|
455
|
+
const match = text.match(/^(\s*)(Conclusion:|结论:|Changes:|修改:)(\s*)/);
|
|
456
|
+
if (!match || !textNode.parentNode) continue;
|
|
457
|
+
const label = document.createElement('span');
|
|
458
|
+
label.className = 'run-system-label';
|
|
459
|
+
label.dataset.systemLabel = ['Conclusion:', '结论:'].includes(match[2])
|
|
460
|
+
? 'conclusion'
|
|
461
|
+
: 'changes';
|
|
462
|
+
label.textContent = `${match[2]}${match[3]}`;
|
|
463
|
+
textNode.textContent = `${match[1]}${text.slice(match[0].length)}`;
|
|
464
|
+
textNode.parentNode.insertBefore(label, textNode);
|
|
465
|
+
}
|
|
466
|
+
decorateChangeReceipts(container, document, tx);
|
|
467
|
+
}
|
|
468
|
+
|
|
469
|
+
function decorateChangeReceipts(container, document, tx) {
|
|
470
|
+
const label = container.querySelector?.('.run-system-label[data-system-label="changes"]');
|
|
471
|
+
const list = label?.closest?.('p')?.nextElementSibling;
|
|
472
|
+
if (!list || !['UL', 'OL'].includes(list.tagName)) return;
|
|
473
|
+
|
|
474
|
+
const receipts = [];
|
|
475
|
+
for (const item of Array.from(list.children || [])) {
|
|
476
|
+
const original = String(item.textContent || '').trim();
|
|
477
|
+
const match = original.match(/^(.+?):\s+(edit|create|rename|move|delete)(?:\s+\((.+)\))?$/i)
|
|
478
|
+
|| original.match(/^(.+?):\s*(编辑|新建|重命名|移动|删除)(?:((.+)))?$/);
|
|
479
|
+
if (!match) return;
|
|
480
|
+
receipts.push({ item, original, file: match[1], operation: match[2] });
|
|
481
|
+
}
|
|
482
|
+
if (!receipts.length) return;
|
|
483
|
+
|
|
484
|
+
const syncedFiles = new Set(receipts.map(receipt => receipt.file)).size;
|
|
485
|
+
const summary = document.createElement('div');
|
|
486
|
+
summary.className = 'run-change-summary';
|
|
487
|
+
const check = document.createElement('span');
|
|
488
|
+
check.className = 'run-change-summary__check';
|
|
489
|
+
check.setAttribute('aria-hidden', 'true');
|
|
490
|
+
check.textContent = '✓';
|
|
491
|
+
const text = document.createElement('span');
|
|
492
|
+
text.textContent = tx(
|
|
493
|
+
`${syncedFiles} ${syncedFiles === 1 ? 'file' : 'files'} synced`,
|
|
494
|
+
`已同步 ${syncedFiles} 个文件`
|
|
495
|
+
);
|
|
496
|
+
summary.append(check, text);
|
|
497
|
+
list.parentNode?.insertBefore(summary, list);
|
|
498
|
+
list.classList.add('run-change-receipts');
|
|
499
|
+
|
|
500
|
+
for (const receipt of receipts) {
|
|
501
|
+
const file = document.createElement('span');
|
|
502
|
+
file.className = 'run-change-receipt__file';
|
|
503
|
+
file.textContent = receipt.file;
|
|
504
|
+
const operation = document.createElement('span');
|
|
505
|
+
operation.className = 'run-change-receipt__operation';
|
|
506
|
+
operation.textContent = receipt.operation;
|
|
507
|
+
receipt.item.classList.add('run-change-receipt');
|
|
508
|
+
receipt.item.setAttribute('aria-label', receipt.original);
|
|
509
|
+
receipt.item.title = receipt.original;
|
|
510
|
+
receipt.item.replaceChildren(file, operation);
|
|
511
|
+
}
|
|
512
|
+
}
|
|
513
|
+
|
|
445
514
|
return {
|
|
446
515
|
DEFAULT_LIMITS,
|
|
447
516
|
countTokens,
|
|
517
|
+
decorateCompletionReport,
|
|
448
518
|
renderMarkdown,
|
|
449
519
|
stripEmptyHtmlComments
|
|
450
520
|
};
|
|
@@ -319,7 +319,7 @@
|
|
|
319
319
|
if (!efforts.length) {
|
|
320
320
|
efforts = presentation === 'none' ? ['none'] : ['low', 'medium', 'high', 'xhigh'];
|
|
321
321
|
}
|
|
322
|
-
const current =
|
|
322
|
+
const current = getState()?.reasoningEffort || reasoningSelect.value || '';
|
|
323
323
|
const fallback = efforts.includes(model?.defaultReasoningEffort)
|
|
324
324
|
? model.defaultReasoningEffort
|
|
325
325
|
: efforts.includes('high') ? 'high' : efforts[0];
|
|
@@ -29,6 +29,7 @@
|
|
|
29
29
|
setState,
|
|
30
30
|
getCurrentRunView,
|
|
31
31
|
getSettingsPanelInstance,
|
|
32
|
+
prepareRetryReplacement,
|
|
32
33
|
StorageDb
|
|
33
34
|
} = deps;
|
|
34
35
|
|
|
@@ -218,6 +219,7 @@
|
|
|
218
219
|
showPluginToast(tx('Nothing to refill: the original task text is unavailable.', '无法回填:原任务文本不可用。'));
|
|
219
220
|
return;
|
|
220
221
|
}
|
|
222
|
+
prepareRetryReplacement?.(run || null);
|
|
221
223
|
input.value = task;
|
|
222
224
|
getState().task = task;
|
|
223
225
|
autosizeTaskTextarea();
|