codex-overleaf-link 2.3.3 → 2.3.5
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 +318 -211
- package/extension/bootstrap/manifest.template.json +1 -1
- package/extension/src/background.js +5 -0
- package/extension/src/content/composerPanel.js +1 -1
- package/extension/src/content/contentRuntime.js +68 -33
- package/extension/src/content/generated/content.bundle.js +604 -132
- package/extension/src/content/generated/content.bundle.meta.json +5 -3
- package/extension/src/content/globalPreferencesController.js +125 -0
- package/extension/src/content/legacyGlobalRegistry.js +2 -0
- package/extension/src/content/modelPicker.js +1 -1
- package/extension/src/content/panelMaintenance.js +2 -0
- package/extension/src/content/panelRenderer.js +86 -2
- package/extension/src/content/projectSettingsCoordinator.js +1 -0
- package/extension/src/content/providerSettingsCoordinator.js +15 -0
- package/extension/src/content/providerSettingsDialog.js +24 -15
- package/extension/src/content/runController.js +35 -0
- package/extension/src/content/settingsPanel.js +5 -3
- package/extension/src/content/themeController.js +3 -0
- package/extension/src/popup.js +10 -10
- package/extension/src/shared/compatibility.js +1 -1
- package/extension/src/shared/globalPreferences.js +131 -0
- package/extension/src/shared/i18n.js +2 -2
- package/extension/styles/panel.css +89 -2
- package/package.json +1 -1
- package/scripts/install-managed.mjs +1 -1
|
@@ -15,6 +15,11 @@ if (!globalThis.CodexOverleafNativeRequestIdentity) {
|
|
|
15
15
|
: 'shared/nativeRequestIdentity.js';
|
|
16
16
|
importScripts(runtimeBase ? chrome.runtime.getURL(identityPath) : identityPath);
|
|
17
17
|
}
|
|
18
|
+
if (!globalThis.CodexOverleafGlobalPreferences) {
|
|
19
|
+
const runtimeBase = String(globalThis.__CODEX_OVERLEAF_RUNTIME_BASE__ || '');
|
|
20
|
+
importScripts(runtimeBase ? chrome.runtime.getURL(`${runtimeBase}/src/shared/globalPreferences.js`) : 'shared/globalPreferences.js');
|
|
21
|
+
}
|
|
22
|
+
globalThis.CodexOverleafGlobalPreferences?.installBackground(chrome);
|
|
18
23
|
|
|
19
24
|
(function initBackground() {
|
|
20
25
|
'use strict';
|
|
@@ -110,7 +110,7 @@
|
|
|
110
110
|
</span>
|
|
111
111
|
</div>
|
|
112
112
|
<div class="codex-context-selection" data-context-selection></div>
|
|
113
|
-
<div class="codex-context-status" data-context-status>Type @ to
|
|
113
|
+
<div class="codex-context-status" data-context-status>Type @ to choose files or add @compile-log. Name the section you want in your request.</div>
|
|
114
114
|
<div class="codex-context-files" data-context-file-list></div>
|
|
115
115
|
</div>
|
|
116
116
|
</form>
|
|
@@ -217,6 +217,7 @@
|
|
|
217
217
|
renderAuditHistoryPanel: () => renderAuditHistoryPanel(),
|
|
218
218
|
renderRecentProjectsVariant: (...args) => renderRecentProjectsVariant(...args),
|
|
219
219
|
saveStateSoon: () => saveStateSoon(),
|
|
220
|
+
updateGlobalPreferences: patch => getGlobalPreferences().update(patch),
|
|
220
221
|
setState: next => { state = next; },
|
|
221
222
|
tr,
|
|
222
223
|
tx,
|
|
@@ -383,7 +384,8 @@
|
|
|
383
384
|
getState: () => state,
|
|
384
385
|
setState: next => { state = next; },
|
|
385
386
|
getCurrentRunView: () => currentRunView,
|
|
386
|
-
getSettingsPanelInstance: () => settingsPanelInstance
|
|
387
|
+
getSettingsPanelInstance: () => settingsPanelInstance,
|
|
388
|
+
prepareRetryReplacement: run => prepareRetryReplacement(run)
|
|
387
389
|
});
|
|
388
390
|
const {
|
|
389
391
|
showUndoFileSelection,
|
|
@@ -663,6 +665,7 @@
|
|
|
663
665
|
const providerSettingsCoordinator = Modules.ProviderSettingsCoordinator.create({
|
|
664
666
|
ProviderProfiles: Modules.ProviderProfiles,
|
|
665
667
|
ProviderSettingsDialog: Modules.ProviderSettingsDialog,
|
|
668
|
+
hasCurrentProject: () => Boolean(getCurrentProjectId()),
|
|
666
669
|
tx,
|
|
667
670
|
sendBackgroundNative,
|
|
668
671
|
document,
|
|
@@ -839,7 +842,9 @@
|
|
|
839
842
|
let composerPanelInstance = null;
|
|
840
843
|
let state = null;
|
|
841
844
|
let storageKey = LEGACY_STORAGE_KEY;
|
|
845
|
+
let globalPreferencesController = null;
|
|
842
846
|
let currentRunView = null;
|
|
847
|
+
let pendingRetryReplacement = null;
|
|
843
848
|
let runQueueScheduler = null;
|
|
844
849
|
let runInputCoordinator = null;
|
|
845
850
|
const activeTurnControl = ActiveTurnControl.create({ chrome });
|
|
@@ -936,6 +941,13 @@
|
|
|
936
941
|
sendResponse?.(getPanelStateResponse());
|
|
937
942
|
return;
|
|
938
943
|
}
|
|
944
|
+
if (message?.type === 'codex-overleaf/toggle-launcher') {
|
|
945
|
+
const visible = !PanelRenderer.isLauncherVisible(panelRendererInstance);
|
|
946
|
+
PanelRenderer.setLauncherVisible(panelRendererInstance, visible, { persist: true });
|
|
947
|
+
if (!visible) closePanel();
|
|
948
|
+
sendResponse?.(getPanelStateResponse());
|
|
949
|
+
return;
|
|
950
|
+
}
|
|
939
951
|
if (message?.type === 'codex-overleaf/toggle-panel') {
|
|
940
952
|
if (isPanelOpen()) {
|
|
941
953
|
closePanel();
|
|
@@ -966,9 +978,10 @@
|
|
|
966
978
|
});
|
|
967
979
|
|
|
968
980
|
async function init() {
|
|
981
|
+
await getGlobalPreferences().initialize();
|
|
969
982
|
await refreshAccountScopeId();
|
|
970
983
|
storageKey = getProjectStorageKey(LEGACY_STORAGE_KEY, window.location.href);
|
|
971
|
-
state = normalizePanelState(await loadStoredState(), { restoreRunningRuns: true });
|
|
984
|
+
state = normalizePanelState(getGlobalPreferences().overlay(await loadStoredState()), { restoreRunningRuns: true });
|
|
972
985
|
initializeRunQueueScheduler();
|
|
973
986
|
recoverInterruptedRunJournals()
|
|
974
987
|
.then(() => applyStateToPanel())
|
|
@@ -990,6 +1003,7 @@
|
|
|
990
1003
|
recentProjects.mountDashboardShell();
|
|
991
1004
|
}
|
|
992
1005
|
applyStateToPanel();
|
|
1006
|
+
getGlobalPreferences().refreshView();
|
|
993
1007
|
// Welcome-panel + write-guard: seed the lifecycle
|
|
994
1008
|
// module-locals from the current URL, install the SPA route hook so
|
|
995
1009
|
// future Overleaf navigations swap variants, and warm the account-scope
|
|
@@ -1186,7 +1200,12 @@
|
|
|
1186
1200
|
maxWidth: PANEL_MAX_WIDTH,
|
|
1187
1201
|
pageMinWidth: PAGE_MIN_WIDTH,
|
|
1188
1202
|
initialWidth: state?.panelWidth || PANEL_DEFAULT_WIDTH,
|
|
1203
|
+
chromeApi: chrome,
|
|
1204
|
+
launcherLabel: tx('Show or hide Codex panel', '显示或隐藏 Codex 边栏'),
|
|
1189
1205
|
callbacks: {
|
|
1206
|
+
onLauncherToggle: () => ensurePanelOpen(),
|
|
1207
|
+
onClosePanel: () => closePanel(),
|
|
1208
|
+
onLauncherVisibilityChange: visible => { if (!visible) closePanel(); },
|
|
1190
1209
|
onRefresh: () => refreshProbe({ userInitiated: true }),
|
|
1191
1210
|
onNewSession: () => startNewSession(),
|
|
1192
1211
|
onChangeHistory: () => openChangeHistory(),
|
|
@@ -1249,7 +1268,7 @@
|
|
|
1249
1268
|
button: panel.querySelector('[data-custom-instructions-settings]'),
|
|
1250
1269
|
callbacks: {
|
|
1251
1270
|
onBack: () => closeCustomInstructionsSettings(),
|
|
1252
|
-
onInputChange:
|
|
1271
|
+
onInputChange: event => persistPanelInputs(event),
|
|
1253
1272
|
onSkillsOpen: () => openSkillsView(),
|
|
1254
1273
|
onSkillsBack: () => closeSkillsView(),
|
|
1255
1274
|
onProvidersOpen: () => providerSettingsCoordinator.open(),
|
|
@@ -1364,7 +1383,8 @@
|
|
|
1364
1383
|
function getPanelStateResponse() {
|
|
1365
1384
|
return {
|
|
1366
1385
|
ok: true,
|
|
1367
|
-
open: isPanelOpen()
|
|
1386
|
+
open: isPanelOpen(),
|
|
1387
|
+
launcherVisible: PanelRenderer.isLauncherVisible(panelRendererInstance)
|
|
1368
1388
|
};
|
|
1369
1389
|
}
|
|
1370
1390
|
|
|
@@ -1789,6 +1809,12 @@
|
|
|
1789
1809
|
// Freeze submitted run identity before the panel can change during the run.
|
|
1790
1810
|
const submittedMode = executionSnapshot.mode;
|
|
1791
1811
|
const submittedRequireReviewing = executionSnapshot.requireReviewing === true;
|
|
1812
|
+
const replaceRunId = queuedInput ? '' : runController.resolveRetryReplacement({
|
|
1813
|
+
candidate: pendingRetryReplacement,
|
|
1814
|
+
activeSessionId: state.activeSessionId,
|
|
1815
|
+
runs: state.runs,
|
|
1816
|
+
projectRunSettlement: run => WritebackSettlement.projectRunSettlement(run)
|
|
1817
|
+
});
|
|
1792
1818
|
|
|
1793
1819
|
runCancellationRequested = false;
|
|
1794
1820
|
runCancellationController = new AbortController();
|
|
@@ -1802,8 +1828,10 @@
|
|
|
1802
1828
|
executionSnapshot,
|
|
1803
1829
|
attachments: submittedAttachments,
|
|
1804
1830
|
skillInvocation: submittedSkillInvocation,
|
|
1805
|
-
queueItemId: queuedInput?.id || ''
|
|
1831
|
+
queueItemId: queuedInput?.id || '',
|
|
1832
|
+
replaceRunId
|
|
1806
1833
|
});
|
|
1834
|
+
if (!queuedInput) pendingRetryReplacement = null;
|
|
1807
1835
|
const runSessionId = currentRunView.sessionId;
|
|
1808
1836
|
let runAuditDraft = null;
|
|
1809
1837
|
try {
|
|
@@ -4309,6 +4337,19 @@
|
|
|
4309
4337
|
return scopedPersistenceCoordinator;
|
|
4310
4338
|
}
|
|
4311
4339
|
|
|
4340
|
+
function getGlobalPreferences() {
|
|
4341
|
+
if (!globalPreferencesController) globalPreferencesController = Modules.GlobalPreferencesController.create({
|
|
4342
|
+
chromeApi: chrome, getState: () => state, setState: next => { state = next; }, getPanel: () => panel,
|
|
4343
|
+
applyTheme: applyPanelTheme, applyLocale: () => { applyLocaleToPanel(); refreshDashboardSoon(); },
|
|
4344
|
+
onPreloadChange: enabled => contextTrayController.scheduleContextPrefetch({ enabled }),
|
|
4345
|
+
onSkillsChange: () => { renderLocalSkillList(); updateSkillsEntrySummary(); },
|
|
4346
|
+
onError: error => showPluginToast(tx(
|
|
4347
|
+
`Global settings could not be saved or loaded: ${error.message}. Please retry.`,
|
|
4348
|
+
`全局设置未能保存或读取:${error.message}。请重试。`), { status: 'failed', sticky: true })
|
|
4349
|
+
});
|
|
4350
|
+
return globalPreferencesController;
|
|
4351
|
+
}
|
|
4352
|
+
|
|
4312
4353
|
async function reloadProjectRunHistory(newProjectId) {
|
|
4313
4354
|
// Rebind the storage key to the new project and reload the panel state
|
|
4314
4355
|
// from chrome.storage.local so the per-project session list reflects
|
|
@@ -4316,7 +4357,7 @@
|
|
|
4316
4357
|
try {
|
|
4317
4358
|
storageKey = getProjectStorageKey(LEGACY_STORAGE_KEY, window.location.href);
|
|
4318
4359
|
const reloaded = await loadStoredState();
|
|
4319
|
-
state = normalizePanelState(reloaded, { restoreRunningRuns: true });
|
|
4360
|
+
state = normalizePanelState(getGlobalPreferences().overlay(reloaded), { restoreRunningRuns: true });
|
|
4320
4361
|
applyStateToPanel();
|
|
4321
4362
|
} catch (_error) {
|
|
4322
4363
|
// Reload failures fall back to the in-memory state; the next saveState
|
|
@@ -5054,8 +5095,8 @@
|
|
|
5054
5095
|
return fileItems.length
|
|
5055
5096
|
? fileItems.join(', ')
|
|
5056
5097
|
: tx(
|
|
5057
|
-
'@whole-project (default); add @
|
|
5058
|
-
'@whole-project
|
|
5098
|
+
'@whole-project (default); choose files or add @compile-log',
|
|
5099
|
+
'@whole-project(默认);可选择文件或添加 @compile-log'
|
|
5059
5100
|
);
|
|
5060
5101
|
}
|
|
5061
5102
|
|
|
@@ -5888,6 +5929,8 @@
|
|
|
5888
5929
|
}
|
|
5889
5930
|
|
|
5890
5931
|
async function persistPanelInputs(event) {
|
|
5932
|
+
const globalWrite = getGlobalPreferences().handleInput(event);
|
|
5933
|
+
if (globalWrite) return globalWrite;
|
|
5891
5934
|
// Typing in the task box is the hottest write path: a full saveState per
|
|
5892
5935
|
// keystroke serializes every session/run/event and rewrites IndexedDB, so
|
|
5893
5936
|
// panels get slower as history grows. Drafts take the debounced saver;
|
|
@@ -5986,29 +6029,8 @@
|
|
|
5986
6029
|
setCustomInstructionsForProject(projectId, customInstructionsInput.value);
|
|
5987
6030
|
}
|
|
5988
6031
|
setGovernanceRulesForCurrentProject(readGovernanceRulesFromSettings());
|
|
5989
|
-
|
|
5990
|
-
|
|
5991
|
-
setSkillLoadingSettings(newSettings);
|
|
5992
|
-
// Theme is a global preference; read it from the settings select (which
|
|
5993
|
-
// lives inside the panel, like the other settings inputs), persist it on
|
|
5994
|
-
// state, and apply immediately. applyPanelTheme normalizes the value.
|
|
5995
|
-
const themePref = panel?.querySelector('[data-theme-select]')?.value || 'dark';
|
|
5996
|
-
if (state) {
|
|
5997
|
-
state.theme = themePref;
|
|
5998
|
-
}
|
|
5999
|
-
applyPanelTheme(themePref);
|
|
6000
|
-
// Language is a global UI preference (moved here from the diagnostics
|
|
6001
|
-
// menu); re-translate the panel when it changes.
|
|
6002
|
-
const languagePref = panel?.querySelector('[data-language-select]')?.value;
|
|
6003
|
-
if (languagePref && state && languagePref !== getLocale()) {
|
|
6004
|
-
state.locale = i18n?.normalizeLocale?.(languagePref) || languagePref;
|
|
6005
|
-
applyLocaleToPanel();
|
|
6006
|
-
}
|
|
6007
|
-
// Re-render skill list when master toggle changes so per-skill toggles update their disabled state.
|
|
6008
|
-
if (prevOverleafSkills !== getSkillLoadingSettings().loadCodexOverleafSkills) {
|
|
6009
|
-
renderLocalSkillList();
|
|
6010
|
-
}
|
|
6011
|
-
updateSkillsEntrySummary();
|
|
6032
|
+
// Global controls are handled as field patches by getGlobalPreferences;
|
|
6033
|
+
// unrelated session autosaves must not read stale settings controls.
|
|
6012
6034
|
}
|
|
6013
6035
|
}
|
|
6014
6036
|
|
|
@@ -6127,6 +6149,17 @@
|
|
|
6127
6149
|
renderPendingInputs();
|
|
6128
6150
|
}
|
|
6129
6151
|
|
|
6152
|
+
function prepareRetryReplacement(run) {
|
|
6153
|
+
const sessionId = state?.activeSessionId || '';
|
|
6154
|
+
const source = findRunRecord(run?.id, sessionId);
|
|
6155
|
+
const eligible = source && runController.isRetryReplacementEligible(
|
|
6156
|
+
source,
|
|
6157
|
+
WritebackSettlement.projectRunSettlement(source)
|
|
6158
|
+
);
|
|
6159
|
+
pendingRetryReplacement = eligible ? { sessionId, runId: source.id } : null;
|
|
6160
|
+
return Boolean(eligible);
|
|
6161
|
+
}
|
|
6162
|
+
|
|
6130
6163
|
function startRunView({
|
|
6131
6164
|
task,
|
|
6132
6165
|
mode,
|
|
@@ -6134,6 +6167,7 @@
|
|
|
6134
6167
|
reasoningEffort,
|
|
6135
6168
|
speedTier,
|
|
6136
6169
|
queueItemId = '',
|
|
6170
|
+
replaceRunId = '',
|
|
6137
6171
|
executionSnapshot = null
|
|
6138
6172
|
}) {
|
|
6139
6173
|
let attachments = [];
|
|
@@ -6185,13 +6219,14 @@
|
|
|
6185
6219
|
}
|
|
6186
6220
|
: {};
|
|
6187
6221
|
state = updateActiveSession(state, {
|
|
6188
|
-
runs:
|
|
6222
|
+
runs: runController.replaceRunForRetry(state.runs, replaceRunId, record),
|
|
6189
6223
|
...titlePatch
|
|
6190
6224
|
});
|
|
6191
|
-
saveStateSoon();
|
|
6225
|
+
saveStateSoon(replaceRunId ? 0 : 120);
|
|
6192
6226
|
|
|
6193
6227
|
const log = panel.querySelector('[data-log]');
|
|
6194
6228
|
removeEmptyRunsMessage(log);
|
|
6229
|
+
if (replaceRunId) log.querySelector(`[data-run-id="${cssEscape(replaceRunId)}"]`)?.remove();
|
|
6195
6230
|
const root = renderRunCard(record);
|
|
6196
6231
|
log.append(root);
|
|
6197
6232
|
scrollLogToBottom({ force: true });
|