codex-overleaf-link 1.8.6 → 1.9.1
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 +45 -21
- package/bin/codex-overleaf-link.mjs +58 -0
- package/extension/assets/icons/codex-overleaf-dialog-icon.png +0 -0
- package/extension/assets/icons/codex-overleaf-icon.png +0 -0
- package/extension/assets/icons/icon128.png +0 -0
- package/extension/assets/icons/icon16.png +0 -0
- package/extension/assets/icons/icon32.png +0 -0
- package/extension/assets/icons/icon48.png +0 -0
- package/extension/bootstrap/background.js +404 -0
- package/extension/bootstrap/manifest.template.json +51 -0
- package/extension/bootstrap/popup.css +26 -0
- package/extension/bootstrap/popup.html +38 -0
- package/extension/bootstrap/popup.js +44 -0
- package/extension/bootstrap/runtimeContext.js +2 -0
- package/extension/runtime-manifest.json +60 -0
- package/extension/src/background.js +532 -0
- package/extension/src/content/applyResultFormatters.js +387 -0
- package/extension/src/content/composerAttachments.js +522 -0
- package/extension/src/content/composerPanel.js +254 -0
- package/extension/src/content/contentRuntime.js +8897 -0
- package/extension/src/content/contextTray.js +686 -0
- package/extension/src/content/diagnosticsController.js +659 -0
- package/extension/src/content/diagnosticsPanel.js +342 -0
- package/extension/src/content/diffReviewPanel.js +797 -0
- package/extension/src/content/localSkillsPanel.js +280 -0
- package/extension/src/content/markdownText.js +606 -0
- package/extension/src/content/mirrorHealth.js +92 -0
- package/extension/src/content/modelPicker.js +489 -0
- package/extension/src/content/nativeChannel.js +62 -0
- package/extension/src/content/otWarmMirror.js +964 -0
- package/extension/src/content/otWarmMirrorController.js +174 -0
- package/extension/src/content/panelMaintenance.js +367 -0
- package/extension/src/content/panelRenderer.js +253 -0
- package/extension/src/content/recentProjects.js +1063 -0
- package/extension/src/content/reviewHunks.js +247 -0
- package/extension/src/content/runController.js +242 -0
- package/extension/src/content/runTimelineView.js +1131 -0
- package/extension/src/content/sessionManager.js +487 -0
- package/extension/src/content/sessionPanel.js +263 -0
- package/extension/src/content/settingsPanel.js +527 -0
- package/extension/src/content/themeController.js +91 -0
- package/extension/src/content/updateIdle.js +67 -0
- package/extension/src/content/writebackController.js +300 -0
- package/extension/src/content/writebackOrchestrator.js +850 -0
- package/extension/src/contentScript.js +8 -0
- package/extension/src/page/compileBridge.js +460 -0
- package/extension/src/page/overleafCapabilities.js +100 -0
- package/extension/src/page/overleafEditor.js +282 -0
- package/extension/src/page/overleafProjectSnapshot.js +234 -0
- package/extension/src/page/overleafRealtimeObserver.js +491 -0
- package/extension/src/page/pageBridgeCapability.js +71 -0
- package/extension/src/page/snapshotRouter.js +948 -0
- package/extension/src/page/trackedChangesLifecycle.js +1506 -0
- package/extension/src/page/treeOperations.js +1584 -0
- package/extension/src/page/writeGuard.js +142 -0
- package/extension/src/page/writebackRouter.js +1934 -0
- package/extension/src/pageBridge.js +2224 -0
- package/extension/src/popup.js +247 -0
- package/extension/src/shared/agentTranscript.js +18 -4
- package/extension/src/shared/compatibility.js +1 -1
- package/extension/styles/panel.css +4048 -0
- package/native-host/src/index.js +9 -2
- package/native-host/src/managedInstall.js +393 -0
- package/native-host/src/managedLauncherRuntime.js +71 -0
- package/native-host/src/nativeHostPlatform.js +16 -0
- package/native-host/src/runtimeInstaller.js +6 -1
- package/native-host/src/taskRunnerRuntime.js +8 -0
- package/native-host/src/updateArchive.js +253 -0
- package/native-host/src/updateManager.js +548 -0
- package/native-host/src/updateTrust.js +156 -0
- package/package.json +11 -2
- package/scripts/install-managed.mjs +64 -0
- package/scripts/uninstall-managed.mjs +48 -0
|
@@ -0,0 +1,142 @@
|
|
|
1
|
+
// Writeback project-ID guard: page-side dispatch gate that runs BEFORE any
|
|
2
|
+
// other readiness / openFile / staleness check on every writeback.
|
|
3
|
+
//
|
|
4
|
+
// Three fail-closed abort branches:
|
|
5
|
+
// • editorProjectId === null → editor_project_id_unavailable
|
|
6
|
+
// • runProjectId missing/empty → editor_project_id_unavailable
|
|
7
|
+
// • runProjectId !== editorPID → aborted_project_changed
|
|
8
|
+
//
|
|
9
|
+
// Hydration tolerance: Overleaf's `window._ide.project._id` is observably null
|
|
10
|
+
// for ~200–1000 ms after page load / SPA route change while the editor module
|
|
11
|
+
// hydrates. The guard retries the page-side reader with a 100/300/700 ms
|
|
12
|
+
// backoff (~1100 ms ceiling) before the null abort. Mismatch (runId !==
|
|
13
|
+
// editorId) short-circuits without retry because that means hydration
|
|
14
|
+
// completed to a *different* project and waiting won't fix it.
|
|
15
|
+
//
|
|
16
|
+
// Extracted from pageBridge.js to keep that file under its 2200-line budget;
|
|
17
|
+
// this module is the single source of truth for the guard surface and the
|
|
18
|
+
// only place that constructs the abort dispatch result shape.
|
|
19
|
+
(function initCodexOverleafWriteGuard(root, factory) {
|
|
20
|
+
if (typeof module === 'object' && module.exports) {
|
|
21
|
+
module.exports = factory();
|
|
22
|
+
} else {
|
|
23
|
+
root.CodexOverleafWriteGuard = factory();
|
|
24
|
+
}
|
|
25
|
+
})(typeof window !== 'undefined' ? window : globalThis, function writeGuardFactory() {
|
|
26
|
+
'use strict';
|
|
27
|
+
|
|
28
|
+
const WRITE_GUARD_HYDRATION_RETRY_MS = [100, 300, 700]; // ~1100 ms ceiling
|
|
29
|
+
|
|
30
|
+
const ABORT_USER_MESSAGES = {
|
|
31
|
+
aborted_project_changed: 'Codex stopped a write because Overleaf switched to a different project mid-run.',
|
|
32
|
+
editor_project_id_unavailable: 'Codex could not confirm which Overleaf project the editor is showing, so it did not write.'
|
|
33
|
+
};
|
|
34
|
+
|
|
35
|
+
const ABORT_NEXT_ACTIONS = {
|
|
36
|
+
aborted_project_changed: 'Reopen the original project and rerun the task if you still want this change.',
|
|
37
|
+
editor_project_id_unavailable: 'Refresh Overleaf and retry; if it persists, reload the extension.'
|
|
38
|
+
};
|
|
39
|
+
|
|
40
|
+
function create(deps = {}) {
|
|
41
|
+
const win = deps.window || (typeof globalThis !== 'undefined' ? globalThis : {});
|
|
42
|
+
const doc = deps.document || win.document || {};
|
|
43
|
+
// treeOperations is optional — only needed for the URL fallback in
|
|
44
|
+
// getEditorProjectIdPageSide. When omitted the URL source short-circuits
|
|
45
|
+
// and the guard relies only on `_ide.project._id` and `[data-project-id]`.
|
|
46
|
+
const treeOperations = deps.treeOperations || null;
|
|
47
|
+
const sleep = deps.sleep || (ms => new Promise(resolve => setTimeout(resolve, ms)));
|
|
48
|
+
|
|
49
|
+
// The acceptable sources for the editor's currently-shown project id, in
|
|
50
|
+
// order:
|
|
51
|
+
// 1. `window._ide.project._id` — the in-page IDE module's authoritative
|
|
52
|
+
// project id once the SPA has bound the project.
|
|
53
|
+
// 2. `[data-project-id]` on the CodeMirror root — best-effort second
|
|
54
|
+
// source for cases where `_ide.project` is still hydrating.
|
|
55
|
+
// 3. URL project id, but ONLY when it exactly matches the immutable
|
|
56
|
+
// runProjectId captured at run start. This keeps SPA-navigation
|
|
57
|
+
// safety: a different URL project still fails closed, while current
|
|
58
|
+
// Overleaf builds that no longer expose `_ide.project._id` can still
|
|
59
|
+
// write on a stable same-project page.
|
|
60
|
+
// When none of these sources can prove the same project, return null so
|
|
61
|
+
// the guard fails closed.
|
|
62
|
+
function getEditorProjectIdPageSide(expectedRunProjectId = '') {
|
|
63
|
+
try {
|
|
64
|
+
const ideId = win._ide && win._ide.project && win._ide.project._id;
|
|
65
|
+
if (typeof ideId === 'string' && ideId) return ideId;
|
|
66
|
+
} catch (_error) { /* swallow; fall through */ }
|
|
67
|
+
try {
|
|
68
|
+
const cmRoot = doc.querySelector && doc.querySelector('[data-project-id]');
|
|
69
|
+
const attr = cmRoot && cmRoot.getAttribute && cmRoot.getAttribute('data-project-id');
|
|
70
|
+
if (typeof attr === 'string' && attr) return attr;
|
|
71
|
+
} catch (_error) { /* swallow */ }
|
|
72
|
+
try {
|
|
73
|
+
const urlProjectId = treeOperations && treeOperations.getProjectId
|
|
74
|
+
? (treeOperations.getProjectId() || null)
|
|
75
|
+
: null;
|
|
76
|
+
if (expectedRunProjectId && urlProjectId === expectedRunProjectId) {
|
|
77
|
+
return urlProjectId;
|
|
78
|
+
}
|
|
79
|
+
} catch (_error) { /* swallow */ }
|
|
80
|
+
return null;
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
async function runWriteGuard(params) {
|
|
84
|
+
const runId = params && typeof params.runProjectId === 'string' ? params.runProjectId : '';
|
|
85
|
+
let editorId = getEditorProjectIdPageSide(runId);
|
|
86
|
+
for (let attempt = 0; attempt < WRITE_GUARD_HYDRATION_RETRY_MS.length; attempt++) {
|
|
87
|
+
if (editorId) break;
|
|
88
|
+
await sleep(WRITE_GUARD_HYDRATION_RETRY_MS[attempt]);
|
|
89
|
+
editorId = getEditorProjectIdPageSide(runId);
|
|
90
|
+
}
|
|
91
|
+
if (!editorId) {
|
|
92
|
+
return abortDispatchResult('editor_project_id_unavailable', runId || null, null);
|
|
93
|
+
}
|
|
94
|
+
if (!runId) {
|
|
95
|
+
return abortDispatchResult('editor_project_id_unavailable', null, editorId);
|
|
96
|
+
}
|
|
97
|
+
if (runId !== editorId) {
|
|
98
|
+
return abortDispatchResult('aborted_project_changed', runId, editorId);
|
|
99
|
+
}
|
|
100
|
+
return null;
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
// operation: {} (not null) — the guard fires before any per-op dispatch
|
|
104
|
+
// so there's no specific operation to attribute the block to, but
|
|
105
|
+
// downstream audit/transcript code traverses operation.path and the
|
|
106
|
+
// like; an empty object lets defaults flow through cleanly.
|
|
107
|
+
function abortDispatchResult(code, runProjectId, editorProjectId) {
|
|
108
|
+
return {
|
|
109
|
+
ok: false,
|
|
110
|
+
applied: [],
|
|
111
|
+
skipped: [{
|
|
112
|
+
operation: {},
|
|
113
|
+
result: {
|
|
114
|
+
ok: false,
|
|
115
|
+
code,
|
|
116
|
+
reason: ABORT_USER_MESSAGES[code],
|
|
117
|
+
failure: {
|
|
118
|
+
code,
|
|
119
|
+
stage: 'write',
|
|
120
|
+
severity: 'blocked',
|
|
121
|
+
userMessage: ABORT_USER_MESSAGES[code],
|
|
122
|
+
nextAction: ABORT_NEXT_ACTIONS[code],
|
|
123
|
+
retryable: true,
|
|
124
|
+
terminalState: 'blocked',
|
|
125
|
+
changedDocument: false,
|
|
126
|
+
evidence: { runProjectId, editorProjectId }
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
}]
|
|
130
|
+
};
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
return {
|
|
134
|
+
runWriteGuard,
|
|
135
|
+
abortDispatchResult,
|
|
136
|
+
getEditorProjectIdPageSide,
|
|
137
|
+
WRITE_GUARD_HYDRATION_RETRY_MS
|
|
138
|
+
};
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
return { create, WRITE_GUARD_HYDRATION_RETRY_MS };
|
|
142
|
+
});
|