codex-overleaf-link 2.4.0 → 2.4.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 +27 -24
- package/README.zh-CN.md +27 -24
- package/extension/src/content/contentRuntime.js +74 -73
- package/extension/src/content/generated/content.bundle.js +657 -445
- package/extension/src/content/generated/content.bundle.meta.json +3 -3
- package/extension/src/content/panelMaintenance.js +8 -4
- package/extension/src/content/recentProjects.js +354 -355
- package/extension/src/content/runTimelineView.js +8 -10
- package/extension/src/content/scopedPersistenceCoordinator.js +2 -1
- package/extension/src/content/scopedPersistencePanelState.js +45 -2
- package/extension/src/content/sessionPersistence.js +4 -1
- package/extension/src/content/settingsPanel.js +16 -2
- package/extension/src/page/saveState.js +44 -1
- package/extension/src/page/trackedChangesLifecycle.js +4 -1
- package/extension/src/page/treeOperations.js +10 -27
- package/extension/src/page/writebackRouter.js +1 -1
- package/extension/src/pageBridge.js +3 -0
- package/extension/src/shared/compatibility.js +1 -1
- package/extension/src/shared/i18n.js +94 -40
- package/extension/src/shared/storageDb.js +1 -0
- package/extension/src/shared/storageRunActions.js +44 -0
- package/extension/styles/panel.css +199 -395
- package/native-host/src/codexSessionRunner.js +41 -38
- package/native-host/src/codexSessionTiming.js +68 -0
- package/native-host/src/readProgressGuard.js +84 -17
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -1,10 +1,13 @@
|
|
|
1
|
+
> [!NOTE]
|
|
2
|
+
> This development branch can contain unreleased changes. Version-pinned commands below apply after the corresponding release is published. Published installers are available from the [latest stable release](https://github.com/Ghqqqq/codex-overleaf-link/releases/latest).
|
|
3
|
+
|
|
1
4
|
<div align="center">
|
|
2
5
|
<img src="extension/assets/icons/codex-overleaf-icon.png" width="96" alt="Codex Overleaf Link">
|
|
3
6
|
<h1>Codex Overleaf Link</h1>
|
|
4
7
|
<p><strong>English</strong> | <a href="README.zh-CN.md" lang="zh-CN">简体中文</a></p>
|
|
5
8
|
<p><strong>Empower Overleaf with Codex.</strong></p>
|
|
6
9
|
<p>
|
|
7
|
-
<img src="https://img.shields.io/badge/version-2.4.
|
|
10
|
+
<img src="https://img.shields.io/badge/version-2.4.1-blue" alt="version">
|
|
8
11
|
<img src="https://img.shields.io/badge/platform-macOS%20%2F%20Windows%20%2F%20Linux-lightgrey" alt="platform">
|
|
9
12
|
<img src="https://img.shields.io/badge/chrome-MV3-green" alt="chrome manifest v3">
|
|
10
13
|
<img src="https://img.shields.io/badge/node-%3E%3D20-brightgreen" alt="node version">
|
|
@@ -87,14 +90,14 @@ One command installs the managed native host **and** managed extension runtime.
|
|
|
87
90
|
macOS / Linux:
|
|
88
91
|
|
|
89
92
|
```bash
|
|
90
|
-
CODEX_OVERLEAF_REF=v2.4.
|
|
93
|
+
CODEX_OVERLEAF_REF=v2.4.1 bash -c "$(curl -fsSL https://raw.githubusercontent.com/Ghqqqq/codex-overleaf-link/v2.4.1/install.sh)"
|
|
91
94
|
```
|
|
92
95
|
|
|
93
96
|
Windows PowerShell:
|
|
94
97
|
|
|
95
98
|
```powershell
|
|
96
|
-
iwr https://raw.githubusercontent.com/Ghqqqq/codex-overleaf-link/v2.4.
|
|
97
|
-
$env:CODEX_OVERLEAF_REF='v2.4.
|
|
99
|
+
iwr https://raw.githubusercontent.com/Ghqqqq/codex-overleaf-link/v2.4.1/install.ps1 -OutFile install.ps1
|
|
100
|
+
$env:CODEX_OVERLEAF_REF='v2.4.1'
|
|
98
101
|
powershell -ExecutionPolicy Bypass -File install.ps1
|
|
99
102
|
```
|
|
100
103
|
|
|
@@ -105,7 +108,7 @@ Then open `chrome://extensions`, enable **Developer mode**, click **Load unpacke
|
|
|
105
108
|
`npm exec` installs the same managed native host and extension runtime without keeping a source checkout. Use it if you prefer a pinned npm package.
|
|
106
109
|
|
|
107
110
|
```bash
|
|
108
|
-
npm exec --yes codex-overleaf-link@2.4.
|
|
111
|
+
npm exec --yes codex-overleaf-link@2.4.1 -- install-managed
|
|
109
112
|
```
|
|
110
113
|
|
|
111
114
|
Then, in `chrome://extensions`, enable **Developer mode**, click **Load unpacked**, and select the managed extension path printed by the command. The Release extension zip remains available for explicitly unmanaged/manual installations.
|
|
@@ -225,9 +228,9 @@ npm installs, updates, and uninstalls the coordinated managed extension/native p
|
|
|
225
228
|
|
|
226
229
|
| Action | Command |
|
|
227
230
|
|--------|---------|
|
|
228
|
-
| Install / recover / migrate | `npm exec --yes codex-overleaf-link@2.4.
|
|
229
|
-
| Diagnose | `npm exec --yes codex-overleaf-link@2.4.
|
|
230
|
-
| Uninstall | `npm exec --yes codex-overleaf-link@2.4.
|
|
231
|
+
| Install / recover / migrate | `npm exec --yes codex-overleaf-link@2.4.1 -- install-managed` |
|
|
232
|
+
| Diagnose | `npm exec --yes codex-overleaf-link@2.4.1 -- doctor` |
|
|
233
|
+
| Uninstall | `npm exec --yes codex-overleaf-link@2.4.1 -- uninstall-managed` |
|
|
231
234
|
|
|
232
235
|
Use `--extension-id <chrome-extension-id>` only for a custom/dev unpacked extension id that differs from the official bundled id.
|
|
233
236
|
|
|
@@ -238,7 +241,7 @@ Use `--extension-id <chrome-extension-id>` only for a custom/dev unpacked extens
|
|
|
238
241
|
Remove the managed extension/native installation (append `--browser chromium` on Linux Chromium):
|
|
239
242
|
|
|
240
243
|
```bash
|
|
241
|
-
npm exec --yes codex-overleaf-link@2.4.
|
|
244
|
+
npm exec --yes codex-overleaf-link@2.4.1 -- uninstall-managed
|
|
242
245
|
```
|
|
243
246
|
|
|
244
247
|
The same command works in Windows PowerShell. It also applies to current `install.sh` / `install.ps1` installations, which install the managed pair.
|
|
@@ -246,7 +249,7 @@ The same command works in Windows PowerShell. It also applies to current `instal
|
|
|
246
249
|
For an unmanaged checkout or native-only installation, use `npm run uninstall:native` from the checkout, or:
|
|
247
250
|
|
|
248
251
|
```bash
|
|
249
|
-
npm exec --yes codex-overleaf-link@2.4.
|
|
252
|
+
npm exec --yes codex-overleaf-link@2.4.1 -- uninstall-native
|
|
250
253
|
```
|
|
251
254
|
|
|
252
255
|
If you are removing an older native-only source installation and still have its source checkout, its bundled uninstaller can also be invoked directly:
|
|
@@ -272,7 +275,7 @@ Remove the extension entry from `chrome://extensions` as well. To erase saved Co
|
|
|
272
275
|
For a managed installation, rerun the [managed installer](#install), reload the extension in `chrome://extensions`, then refresh the Overleaf tab. This recovers the coordinated extension/native pair after an incomplete installation or incompatible runtime update.
|
|
273
276
|
|
|
274
277
|
```bash
|
|
275
|
-
npm exec --yes codex-overleaf-link@2.4.
|
|
278
|
+
npm exec --yes codex-overleaf-link@2.4.1 -- install-managed
|
|
276
279
|
```
|
|
277
280
|
|
|
278
281
|
For an unmanaged checkout, rebuild the extension and reinstall its native host from the same checkout. Use PowerShell installation commands on Windows.
|
|
@@ -395,13 +398,13 @@ The shipped extension targets `https://overleaf.com/project` and `https://www.ov
|
|
|
395
398
|
Linux Chromium install or update:
|
|
396
399
|
|
|
397
400
|
```bash
|
|
398
|
-
CODEX_OVERLEAF_REF=v2.4.
|
|
401
|
+
CODEX_OVERLEAF_REF=v2.4.1 bash -c "$(curl -fsSL https://raw.githubusercontent.com/Ghqqqq/codex-overleaf-link/v2.4.1/install.sh)" -- --browser chromium
|
|
399
402
|
```
|
|
400
403
|
|
|
401
404
|
Linux Chromium uninstall:
|
|
402
405
|
|
|
403
406
|
```bash
|
|
404
|
-
npm exec --yes codex-overleaf-link@2.4.
|
|
407
|
+
npm exec --yes codex-overleaf-link@2.4.1 -- uninstall-managed --browser chromium
|
|
405
408
|
```
|
|
406
409
|
|
|
407
410
|
## Extension ID
|
|
@@ -415,27 +418,27 @@ illdpneeeopfffmiepaejglgmhpmdhdc
|
|
|
415
418
|
The installer uses this id by default. For a managed installation with a custom id, rerun the managed installer with the id shown in `chrome://extensions`:
|
|
416
419
|
|
|
417
420
|
```bash
|
|
418
|
-
npm exec --yes codex-overleaf-link@2.4.
|
|
421
|
+
npm exec --yes codex-overleaf-link@2.4.1 -- install-managed --extension-id "<your-chrome-extension-id>"
|
|
419
422
|
```
|
|
420
423
|
|
|
421
424
|
For an unmanaged extension, use the native-only installer:
|
|
422
425
|
|
|
423
426
|
```bash
|
|
424
|
-
npm exec --yes codex-overleaf-link@2.4.
|
|
427
|
+
npm exec --yes codex-overleaf-link@2.4.1 -- install-native --extension-id "<your-chrome-extension-id>"
|
|
425
428
|
```
|
|
426
429
|
|
|
427
430
|
Both npm commands work in PowerShell. Source installers also accept the `CODEX_OVERLEAF_EXTENSION_ID` environment variable. The Native Messaging manifest's `allowed_origins` must match the loaded extension id.
|
|
428
431
|
|
|
429
432
|
## GitHub Release Artifacts
|
|
430
433
|
|
|
431
|
-
The v2.4.
|
|
434
|
+
The v2.4.1 GitHub Release contains:
|
|
432
435
|
|
|
433
|
-
- `codex-overleaf-link-extension-v2.4.
|
|
434
|
-
- `codex-overleaf-native-host-v2.4.
|
|
435
|
-
- `codex-overleaf-update-v2.4.
|
|
436
|
-
- `codex-overleaf-link-2.4.
|
|
437
|
-
- `install.sh`: release-pinned macOS / Linux installer that defaults to `v2.4.
|
|
438
|
-
- `install.ps1`: release-pinned Windows PowerShell installer that defaults to `v2.4.
|
|
436
|
+
- `codex-overleaf-link-extension-v2.4.1.zip`: loadable Chrome extension package for manual unpacked installation.
|
|
437
|
+
- `codex-overleaf-native-host-v2.4.1.tar.gz`: native host runtime files used by the installer and release verification.
|
|
438
|
+
- `codex-overleaf-update-v2.4.1.tar.gz`: coordinated extension/native bundle used by the managed updater.
|
|
439
|
+
- `codex-overleaf-link-2.4.1.tgz`: npm native host CLI package for pinned install, doctor, and uninstall flows.
|
|
440
|
+
- `install.sh`: release-pinned macOS / Linux installer that defaults to `v2.4.1` when run directly from the release artifact.
|
|
441
|
+
- `install.ps1`: release-pinned Windows PowerShell installer that defaults to `v2.4.1` when run directly from the release artifact.
|
|
439
442
|
- `uninstall-native-host.mjs`: native host uninstaller that removes the Chrome Native Messaging manifest, bridge executable, and runtime copy.
|
|
440
443
|
- `nativeHostPlatform.js`, `manifest.js`, `runtimeInstaller.js`: helper files required by the loose uninstaller asset.
|
|
441
444
|
- `SHA256SUMS`, `release-manifest.json`, and `release-manifest.sig`: checksums, release metadata, and its Ed25519 signature.
|
|
@@ -512,8 +515,8 @@ Use this matrix for release-candidate signoff and compatibility reports. Record
|
|
|
512
515
|
| Browser/channel/version | Google Chrome channel and version. | Google Chrome channel and version. | Google Chrome channel and version. | Chromium channel/package and version. |
|
|
513
516
|
| Install mode | Managed pair recommended; unmanaged Release zip or checkout also available. | Same as macOS Chrome. | Same as macOS Chrome. | Managed or unmanaged; register with `--browser chromium`. |
|
|
514
517
|
| Extension id | Bundled id `illdpneeeopfffmiepaejglgmhpmdhdc`, or actual custom id passed with `--extension-id`. | Bundled id `illdpneeeopfffmiepaejglgmhpmdhdc`, or actual custom id passed with `--extension-id`. | Bundled id `illdpneeeopfffmiepaejglgmhpmdhdc`, or actual custom id passed with `--extension-id`. | Bundled id `illdpneeeopfffmiepaejglgmhpmdhdc`, or actual custom id passed with `--extension-id`. |
|
|
515
|
-
| Installer/update command | `npm exec --yes codex-overleaf-link@2.4.
|
|
516
|
-
| Uninstall command | `npm exec --yes codex-overleaf-link@2.4.
|
|
518
|
+
| Installer/update command | `npm exec --yes codex-overleaf-link@2.4.1 -- install-managed` | `npm exec --yes codex-overleaf-link@2.4.1 -- install-managed` | `npm exec --yes codex-overleaf-link@2.4.1 -- install-managed` | `npm exec --yes codex-overleaf-link@2.4.1 -- install-managed --browser chromium` |
|
|
519
|
+
| Uninstall command | `npm exec --yes codex-overleaf-link@2.4.1 -- uninstall-managed` | `npm exec --yes codex-overleaf-link@2.4.1 -- uninstall-managed` | `npm exec --yes codex-overleaf-link@2.4.1 -- uninstall-managed` | `npm exec --yes codex-overleaf-link@2.4.1 -- uninstall-managed --browser chromium` |
|
|
517
520
|
| Manifest/registry path | `~/Library/Application Support/Google/Chrome/NativeMessagingHosts/com.codex.overleaf.json` | `HKCU\Software\Google\Chrome\NativeMessagingHosts\com.codex.overleaf` -> `%LOCALAPPDATA%\CodexOverleaf\native-host-runtime\com.codex.overleaf.json` | `~/.config/google-chrome/NativeMessagingHosts/com.codex.overleaf.json` | `~/.config/chromium/NativeMessagingHosts/com.codex.overleaf.json` |
|
|
518
521
|
| Managed runtime paths | `~/.codex-overleaf/managed/extension` and `~/.codex-overleaf/managed/native`. | `%LOCALAPPDATA%\CodexOverleaf\managed\extension` and `%LOCALAPPDATA%\CodexOverleaf\managed\native`. | Same as macOS Chrome. | Same as macOS Chrome. |
|
|
519
522
|
| Node/Git/Codex/TeX | Record exact versions; see [Requirements](#requirements) for installation and provider prerequisites. | Same as macOS Chrome. | Same as macOS Chrome. | Same as macOS Chrome. |
|
package/README.zh-CN.md
CHANGED
|
@@ -1,10 +1,13 @@
|
|
|
1
|
+
> [!NOTE]
|
|
2
|
+
> 开发分支可能包含尚未发布的改动。下方固定版本命令适用于对应版本发布之后;已发布的安装器可从[最新稳定版](https://github.com/Ghqqqq/codex-overleaf-link/releases/latest)获取。
|
|
3
|
+
|
|
1
4
|
<div align="center">
|
|
2
5
|
<img src="extension/assets/icons/codex-overleaf-icon.png" width="96" alt="Codex Overleaf Link">
|
|
3
6
|
<h1>Codex Overleaf Link</h1>
|
|
4
7
|
<p><a href="README.md" lang="en">English</a> | <strong>简体中文</strong></p>
|
|
5
8
|
<p><strong>让 Codex 融入 Overleaf。</strong></p>
|
|
6
9
|
<p>
|
|
7
|
-
<img src="https://img.shields.io/badge/version-2.4.
|
|
10
|
+
<img src="https://img.shields.io/badge/version-2.4.1-blue" alt="版本">
|
|
8
11
|
<img src="https://img.shields.io/badge/platform-macOS%20%2F%20Windows%20%2F%20Linux-lightgrey" alt="支持平台">
|
|
9
12
|
<img src="https://img.shields.io/badge/chrome-MV3-green" alt="Chrome Manifest V3">
|
|
10
13
|
<img src="https://img.shields.io/badge/node-%3E%3D20-brightgreen" alt="Node.js 版本要求">
|
|
@@ -87,14 +90,14 @@ Chrome 可能要求手动执行 **Load unpacked(加载已解压的扩展程序
|
|
|
87
90
|
macOS / Linux:
|
|
88
91
|
|
|
89
92
|
```bash
|
|
90
|
-
CODEX_OVERLEAF_REF=v2.4.
|
|
93
|
+
CODEX_OVERLEAF_REF=v2.4.1 bash -c "$(curl -fsSL https://raw.githubusercontent.com/Ghqqqq/codex-overleaf-link/v2.4.1/install.sh)"
|
|
91
94
|
```
|
|
92
95
|
|
|
93
96
|
Windows PowerShell:
|
|
94
97
|
|
|
95
98
|
```powershell
|
|
96
|
-
iwr https://raw.githubusercontent.com/Ghqqqq/codex-overleaf-link/v2.4.
|
|
97
|
-
$env:CODEX_OVERLEAF_REF='v2.4.
|
|
99
|
+
iwr https://raw.githubusercontent.com/Ghqqqq/codex-overleaf-link/v2.4.1/install.ps1 -OutFile install.ps1
|
|
100
|
+
$env:CODEX_OVERLEAF_REF='v2.4.1'
|
|
98
101
|
powershell -ExecutionPolicy Bypass -File install.ps1
|
|
99
102
|
```
|
|
100
103
|
|
|
@@ -105,7 +108,7 @@ powershell -ExecutionPolicy Bypass -File install.ps1
|
|
|
105
108
|
`npm exec` 会安装相同的托管 Native Host 和扩展运行时,无需保留源码检出目录。适合希望固定 npm 包版本的安装方式。
|
|
106
109
|
|
|
107
110
|
```bash
|
|
108
|
-
npm exec --yes codex-overleaf-link@2.4.
|
|
111
|
+
npm exec --yes codex-overleaf-link@2.4.1 -- install-managed
|
|
109
112
|
```
|
|
110
113
|
|
|
111
114
|
随后在 `chrome://extensions` 中启用开发者模式,点击加载已解压的扩展程序,并选择命令打印的托管扩展目录。Release 中的扩展 ZIP 也仍可用于明确采用非托管方式的手动安装。
|
|
@@ -225,9 +228,9 @@ npm 命令负责配套扩展与 Native Host 的托管安装、更新和卸载;
|
|
|
225
228
|
|
|
226
229
|
| 操作 | 命令 |
|
|
227
230
|
|------|------|
|
|
228
|
-
| 安装 / 恢复 / 迁移 | `npm exec --yes codex-overleaf-link@2.4.
|
|
229
|
-
| 诊断 | `npm exec --yes codex-overleaf-link@2.4.
|
|
230
|
-
| 卸载 | `npm exec --yes codex-overleaf-link@2.4.
|
|
231
|
+
| 安装 / 恢复 / 迁移 | `npm exec --yes codex-overleaf-link@2.4.1 -- install-managed` |
|
|
232
|
+
| 诊断 | `npm exec --yes codex-overleaf-link@2.4.1 -- doctor` |
|
|
233
|
+
| 卸载 | `npm exec --yes codex-overleaf-link@2.4.1 -- uninstall-managed` |
|
|
231
234
|
|
|
232
235
|
仅当自定义或开发版扩展 ID 与官方内置 ID 不同时,才需要使用 `--extension-id <chrome-extension-id>`。
|
|
233
236
|
|
|
@@ -238,7 +241,7 @@ npm 命令负责配套扩展与 Native Host 的托管安装、更新和卸载;
|
|
|
238
241
|
移除托管扩展 / Native Host 安装;Linux Chromium 需要追加 `--browser chromium`:
|
|
239
242
|
|
|
240
243
|
```bash
|
|
241
|
-
npm exec --yes codex-overleaf-link@2.4.
|
|
244
|
+
npm exec --yes codex-overleaf-link@2.4.1 -- uninstall-managed
|
|
242
245
|
```
|
|
243
246
|
|
|
244
247
|
同一命令也适用于 Windows PowerShell,以及当前 `install.sh` / `install.ps1` 创建的托管安装。
|
|
@@ -246,7 +249,7 @@ npm exec --yes codex-overleaf-link@2.4.0 -- uninstall-managed
|
|
|
246
249
|
非托管源码安装或仅安装 Native Host 的情况,可在源码目录中运行 `npm run uninstall:native`,或执行:
|
|
247
250
|
|
|
248
251
|
```bash
|
|
249
|
-
npm exec --yes codex-overleaf-link@2.4.
|
|
252
|
+
npm exec --yes codex-overleaf-link@2.4.1 -- uninstall-native
|
|
250
253
|
```
|
|
251
254
|
|
|
252
255
|
如果需要移除较旧的 Native Host 源码安装,且仍保留源码目录,也可直接调用其中的卸载脚本:
|
|
@@ -272,7 +275,7 @@ node "$env:LOCALAPPDATA\CodexOverleaf\source\scripts\uninstall-native-host.mjs"
|
|
|
272
275
|
托管安装可重新运行[托管安装器](#安装),在 `chrome://extensions` 中重新加载扩展,再刷新 Overleaf 标签页。这会恢复安装不完整或运行时更新不兼容时的配套扩展 / Native Host。
|
|
273
276
|
|
|
274
277
|
```bash
|
|
275
|
-
npm exec --yes codex-overleaf-link@2.4.
|
|
278
|
+
npm exec --yes codex-overleaf-link@2.4.1 -- install-managed
|
|
276
279
|
```
|
|
277
280
|
|
|
278
281
|
非托管源码安装应从同一个检出目录重新构建扩展并安装 Native Host。Windows 使用对应的 PowerShell 安装命令。
|
|
@@ -395,13 +398,13 @@ npm run smoke:extension -- --url 'https://www.overleaf.com/project/<project-id>'
|
|
|
395
398
|
Linux Chromium 安装或更新:
|
|
396
399
|
|
|
397
400
|
```bash
|
|
398
|
-
CODEX_OVERLEAF_REF=v2.4.
|
|
401
|
+
CODEX_OVERLEAF_REF=v2.4.1 bash -c "$(curl -fsSL https://raw.githubusercontent.com/Ghqqqq/codex-overleaf-link/v2.4.1/install.sh)" -- --browser chromium
|
|
399
402
|
```
|
|
400
403
|
|
|
401
404
|
Linux Chromium 卸载:
|
|
402
405
|
|
|
403
406
|
```bash
|
|
404
|
-
npm exec --yes codex-overleaf-link@2.4.
|
|
407
|
+
npm exec --yes codex-overleaf-link@2.4.1 -- uninstall-managed --browser chromium
|
|
405
408
|
```
|
|
406
409
|
|
|
407
410
|
## 扩展 ID
|
|
@@ -415,27 +418,27 @@ illdpneeeopfffmiepaejglgmhpmdhdc
|
|
|
415
418
|
安装器默认使用该 ID。托管安装使用自定义 ID 时,应以 `chrome://extensions` 中显示的值重新运行安装器:
|
|
416
419
|
|
|
417
420
|
```bash
|
|
418
|
-
npm exec --yes codex-overleaf-link@2.4.
|
|
421
|
+
npm exec --yes codex-overleaf-link@2.4.1 -- install-managed --extension-id "<your-chrome-extension-id>"
|
|
419
422
|
```
|
|
420
423
|
|
|
421
424
|
非托管扩展使用 Native-only 安装器:
|
|
422
425
|
|
|
423
426
|
```bash
|
|
424
|
-
npm exec --yes codex-overleaf-link@2.4.
|
|
427
|
+
npm exec --yes codex-overleaf-link@2.4.1 -- install-native --extension-id "<your-chrome-extension-id>"
|
|
425
428
|
```
|
|
426
429
|
|
|
427
430
|
这两条 npm 命令也适用于 PowerShell。源码安装器还接受 `CODEX_OVERLEAF_EXTENSION_ID` 环境变量。Native Messaging 清单的 `allowed_origins` 必须与实际加载的扩展 ID 一致。
|
|
428
431
|
|
|
429
432
|
## GitHub Release 制品
|
|
430
433
|
|
|
431
|
-
v2.4.
|
|
434
|
+
v2.4.1 的 GitHub Release 包含:
|
|
432
435
|
|
|
433
|
-
- `codex-overleaf-link-extension-v2.4.
|
|
434
|
-
- `codex-overleaf-native-host-v2.4.
|
|
435
|
-
- `codex-overleaf-update-v2.4.
|
|
436
|
-
- `codex-overleaf-link-2.4.
|
|
437
|
-
- `install.sh`:固定发布版本的 macOS / Linux 安装脚本,从 Release 制品直接运行时默认使用 `v2.4.
|
|
438
|
-
- `install.ps1`:固定发布版本的 Windows PowerShell 安装脚本,从 Release 制品直接运行时默认使用 `v2.4.
|
|
436
|
+
- `codex-overleaf-link-extension-v2.4.1.zip`:用于手动加载已解压扩展的 Chrome 扩展包。
|
|
437
|
+
- `codex-overleaf-native-host-v2.4.1.tar.gz`:供安装器和发布验证使用的 Native Host 运行时文件。
|
|
438
|
+
- `codex-overleaf-update-v2.4.1.tar.gz`:托管更新器使用的扩展 / Native Host 配套更新包。
|
|
439
|
+
- `codex-overleaf-link-2.4.1.tgz`:提供固定版本安装、doctor 诊断和卸载流程的 npm CLI 包。
|
|
440
|
+
- `install.sh`:固定发布版本的 macOS / Linux 安装脚本,从 Release 制品直接运行时默认使用 `v2.4.1`。
|
|
441
|
+
- `install.ps1`:固定发布版本的 Windows PowerShell 安装脚本,从 Release 制品直接运行时默认使用 `v2.4.1`。
|
|
439
442
|
- `uninstall-native-host.mjs`:删除 Chrome Native Messaging 清单、桥接启动程序和运行时副本的卸载脚本。
|
|
440
443
|
- `nativeHostPlatform.js`、`manifest.js`、`runtimeInstaller.js`:独立卸载脚本所需的配套文件。
|
|
441
444
|
- `SHA256SUMS`、`release-manifest.json`、`release-manifest.sig`:校验和、发布元数据及其 Ed25519 签名。
|
|
@@ -512,8 +515,8 @@ Remove-Item -Recurse -Force "$env:LOCALAPPDATA\CodexOverleaf", "$env:USERPROFILE
|
|
|
512
515
|
| 浏览器 / 通道 / 版本 | 记录 Google Chrome 通道和版本。 | 记录 Google Chrome 通道和版本。 | 记录 Google Chrome 通道和版本。 | 记录 Chromium 通道 / 软件包和版本。 |
|
|
513
516
|
| 安装方式 | 推荐托管安装;也支持非托管 Release ZIP 或源码安装。 | 同 macOS Chrome。 | 同 macOS Chrome。 | 托管或非托管安装均需使用 `--browser chromium` 注册。 |
|
|
514
517
|
| 扩展 ID | 内置 ID 为 `illdpneeeopfffmiepaejglgmhpmdhdc`;自定义 ID 使用 `--extension-id` 传入。 | 同 macOS Chrome。 | 同 macOS Chrome。 | 同 macOS Chrome。 |
|
|
515
|
-
| 安装 / 更新命令 | `npm exec --yes codex-overleaf-link@2.4.
|
|
516
|
-
| 卸载命令 | `npm exec --yes codex-overleaf-link@2.4.
|
|
518
|
+
| 安装 / 更新命令 | `npm exec --yes codex-overleaf-link@2.4.1 -- install-managed` | `npm exec --yes codex-overleaf-link@2.4.1 -- install-managed` | `npm exec --yes codex-overleaf-link@2.4.1 -- install-managed` | `npm exec --yes codex-overleaf-link@2.4.1 -- install-managed --browser chromium` |
|
|
519
|
+
| 卸载命令 | `npm exec --yes codex-overleaf-link@2.4.1 -- uninstall-managed` | `npm exec --yes codex-overleaf-link@2.4.1 -- uninstall-managed` | `npm exec --yes codex-overleaf-link@2.4.1 -- uninstall-managed` | `npm exec --yes codex-overleaf-link@2.4.1 -- uninstall-managed --browser chromium` |
|
|
517
520
|
| 清单 / 注册表路径 | `~/Library/Application Support/Google/Chrome/NativeMessagingHosts/com.codex.overleaf.json` | `HKCU\Software\Google\Chrome\NativeMessagingHosts\com.codex.overleaf` 指向 `%LOCALAPPDATA%\CodexOverleaf\native-host-runtime\com.codex.overleaf.json` | `~/.config/google-chrome/NativeMessagingHosts/com.codex.overleaf.json` | `~/.config/chromium/NativeMessagingHosts/com.codex.overleaf.json` |
|
|
518
521
|
| 托管运行时路径 | `~/.codex-overleaf/managed/extension` 和 `~/.codex-overleaf/managed/native`。 | `%LOCALAPPDATA%\CodexOverleaf\managed\extension` 和 `%LOCALAPPDATA%\CodexOverleaf\managed\native`。 | 同 macOS Chrome。 | 同 macOS Chrome。 |
|
|
519
522
|
| Node / Git / Codex / TeX | 记录准确版本,安装和服务前提见[环境要求](#环境要求)。 | 同 macOS Chrome。 | 同 macOS Chrome。 | 同 macOS Chrome。 |
|
|
@@ -5666,7 +5666,7 @@
|
|
|
5666
5666
|
const urlProjectId = getCurrentProjectId();
|
|
5667
5667
|
const projectId = projectIdOverride || urlProjectId;
|
|
5668
5668
|
if (!projectId) {
|
|
5669
|
-
return;
|
|
5669
|
+
if (options?.reviewRunIds?.length) throw new Error('Review persistence lost its project.'); return;
|
|
5670
5670
|
}
|
|
5671
5671
|
// Read currentRunView through a defensive accessor so historical test
|
|
5672
5672
|
// harnesses that inline `saveState` without re-declaring the module-
|
|
@@ -5678,7 +5678,7 @@
|
|
|
5678
5678
|
'Skipped saveState: run is in flight on a different project than the current URL; settlement owns persistence.',
|
|
5679
5679
|
'已跳过 saveState:本次运行所属项目与当前 URL 不一致,写回由 settlement 负责。'
|
|
5680
5680
|
));
|
|
5681
|
-
return;
|
|
5681
|
+
if (options?.reviewRunIds?.length) throw new Error('Review persistence project changed.'); return;
|
|
5682
5682
|
}
|
|
5683
5683
|
const compactState = prepareStateForStorage(state, { onAggressive: notifyAggressiveCompactionOnce });
|
|
5684
5684
|
compactState.autoRecompile = state.autoRecompile;
|
|
@@ -5699,7 +5699,7 @@
|
|
|
5699
5699
|
state: stateSnapshot,
|
|
5700
5700
|
compactState: compactStateSnapshot,
|
|
5701
5701
|
projectId,
|
|
5702
|
-
deletedSessionIds: options?.deletedSessionIds,
|
|
5702
|
+
deletedSessionIds: options?.deletedSessionIds, reviewRunIds: options?.reviewRunIds,
|
|
5703
5703
|
Migration,
|
|
5704
5704
|
StorageDb,
|
|
5705
5705
|
SessionPersistence: Modules.SessionPersistence,
|
|
@@ -5727,7 +5727,7 @@
|
|
|
5727
5727
|
persistScopedState
|
|
5728
5728
|
);
|
|
5729
5729
|
if (!committed.ok && (
|
|
5730
|
-
options?.queueMutation
|
|
5730
|
+
options?.reviewRunIds?.length || options?.queueMutation
|
|
5731
5731
|
|| options?.queueMutations?.length
|
|
5732
5732
|
|| committed.reason !== 'stale_view'
|
|
5733
5733
|
)) {
|
|
@@ -5739,12 +5739,12 @@
|
|
|
5739
5739
|
} catch (error) {
|
|
5740
5740
|
if (
|
|
5741
5741
|
error?.code === 'account_scope_unavailable' &&
|
|
5742
|
-
!options?.queueMutation &&
|
|
5742
|
+
!options?.reviewRunIds?.length && !options?.queueMutation &&
|
|
5743
5743
|
!(Array.isArray(options?.queueMutations) && options.queueMutations.length)
|
|
5744
5744
|
) {
|
|
5745
5745
|
return;
|
|
5746
5746
|
}
|
|
5747
|
-
if (options?.queueMutation || options?.queueMutations?.length) {
|
|
5747
|
+
if (options?.reviewRunIds?.length || options?.queueMutation || options?.queueMutations?.length) {
|
|
5748
5748
|
throw error;
|
|
5749
5749
|
}
|
|
5750
5750
|
let fallbackError = null;
|
|
@@ -5869,6 +5869,7 @@
|
|
|
5869
5869
|
// here (e.g. fallback chrome.storage.local.set rethrew).
|
|
5870
5870
|
emitStorageQuotaFailure(error, null);
|
|
5871
5871
|
}
|
|
5872
|
+
if (persistenceOptions?.reviewRunIds?.length) throw error;
|
|
5872
5873
|
appendPlainLog(tx(`Failed to save session state: ${formatStateSaveError(error)}`, `保存会话状态失败:${formatStateSaveError(error)}`));
|
|
5873
5874
|
})
|
|
5874
5875
|
.finally(() => {
|
|
@@ -5923,6 +5924,7 @@
|
|
|
5923
5924
|
...(current || {}),
|
|
5924
5925
|
...incoming,
|
|
5925
5926
|
queueMutation: undefined,
|
|
5927
|
+
reviewRunIds: Array.from(new Set([...(current?.reviewRunIds || []), ...(incoming?.reviewRunIds || [])])),
|
|
5926
5928
|
queueMutations,
|
|
5927
5929
|
deletedSessionIds: Array.from(new Set([
|
|
5928
5930
|
...(current?.deletedSessionIds || []),
|
|
@@ -6947,11 +6949,9 @@
|
|
|
6947
6949
|
detail: { [tr('detailWillUndo')]: trackedUndo ? formatTrackedChangeFiles(run.undoTrackedChanges) : formatTrackedUndoFiles(run) }
|
|
6948
6950
|
});
|
|
6949
6951
|
|
|
6950
|
-
let result;
|
|
6951
|
-
let trackedUndoPostFilesAtDispatch;
|
|
6952
6952
|
try {
|
|
6953
|
-
trackedUndoPostFilesAtDispatch = buildTrackedUndoPostFiles(run);
|
|
6954
|
-
result = await callPageBridge('rejectTrackedChanges', {
|
|
6953
|
+
const trackedUndoPostFilesAtDispatch = buildTrackedUndoPostFiles(run);
|
|
6954
|
+
const result = await callPageBridge('rejectTrackedChanges', {
|
|
6955
6955
|
trackedChanges: run.undoTrackedChanges || [],
|
|
6956
6956
|
expectedFiles: run.undoExpectedFiles || [],
|
|
6957
6957
|
postFiles: trackedUndoPostFilesAtDispatch,
|
|
@@ -6964,38 +6964,39 @@
|
|
|
6964
6964
|
// `aborted_project_changed` and the document is left untouched.
|
|
6965
6965
|
runProjectId: getRunProjectIdForWriteback(run)
|
|
6966
6966
|
});
|
|
6967
|
+
writebackOrchestrator.invalidateMirrorAfterUndo(runId, getRunProjectIdForWriteback(run), result);
|
|
6968
|
+
appendRunRecordEvent(runId, {
|
|
6969
|
+
title: trackedUndo
|
|
6970
|
+
? tr('undoTrackedResult', { applied: result.applied?.length || 0, skipped: result.skipped?.length || 0 })
|
|
6971
|
+
: tr('undoNativeResult', { applied: result.applied?.length || 0, skipped: result.skipped?.length || 0 }),
|
|
6972
|
+
status: result.skipped?.length ? 'failed' : 'completed',
|
|
6973
|
+
detail: {
|
|
6974
|
+
[trackedUndo ? tr('detailRejected') : tr('detailUndone')]: (result.applied || []).map(item => ({
|
|
6975
|
+
[tr('detailFile')]: item.trackedChange?.path || tr('unknownFile'),
|
|
6976
|
+
[tr('detailRecord')]: item.trackedChange?.label || item.trackedChange?.id || item.trackedChange?.key
|
|
6977
|
+
})),
|
|
6978
|
+
[tr('detailSkipped')]: (result.skipped || []).map(item => ({
|
|
6979
|
+
[tr('detailFile')]: item.trackedChange?.path || tr('unknownFile'),
|
|
6980
|
+
[tr('detailRecord')]: item.trackedChange?.label || item.trackedChange?.id || item.trackedChange?.key || '',
|
|
6981
|
+
[tr('detailReason')]: formatBridgeResultReason(item.result, item.trackedChange?.path)
|
|
6982
|
+
}))
|
|
6983
|
+
}
|
|
6984
|
+
});
|
|
6985
|
+
if (lifecycleReject) {
|
|
6986
|
+
WritebackSettlement.attachUndoNotVerifiedFailure(run, result, {
|
|
6987
|
+
buildFailure: buildContentFailure,
|
|
6988
|
+
postFiles: trackedUndoPostFilesAtDispatch
|
|
6989
|
+
});
|
|
6990
|
+
await applyTrackedChangeSettlement(runId, 'reject', result);
|
|
6991
|
+
return;
|
|
6992
|
+
}
|
|
6993
|
+
applyLegacyUndoSettlement(runId, result.skipped?.length ? 'partial' : 'applied', result);
|
|
6967
6994
|
} finally {
|
|
6968
6995
|
if (lifecycleReject) {
|
|
6969
6996
|
trackedChangeInFlight.delete(runId);
|
|
6997
|
+
refreshRunCardControls(runId);
|
|
6970
6998
|
}
|
|
6971
6999
|
}
|
|
6972
|
-
writebackOrchestrator.invalidateMirrorAfterUndo(runId, getRunProjectIdForWriteback(run), result);
|
|
6973
|
-
appendRunRecordEvent(runId, {
|
|
6974
|
-
title: trackedUndo
|
|
6975
|
-
? tr('undoTrackedResult', { applied: result.applied?.length || 0, skipped: result.skipped?.length || 0 })
|
|
6976
|
-
: tr('undoNativeResult', { applied: result.applied?.length || 0, skipped: result.skipped?.length || 0 }),
|
|
6977
|
-
status: result.skipped?.length ? 'failed' : 'completed',
|
|
6978
|
-
detail: {
|
|
6979
|
-
[trackedUndo ? tr('detailRejected') : tr('detailUndone')]: (result.applied || []).map(item => ({
|
|
6980
|
-
[tr('detailFile')]: item.trackedChange?.path || tr('unknownFile'),
|
|
6981
|
-
[tr('detailRecord')]: item.trackedChange?.label || item.trackedChange?.id || item.trackedChange?.key
|
|
6982
|
-
})),
|
|
6983
|
-
[tr('detailSkipped')]: (result.skipped || []).map(item => ({
|
|
6984
|
-
[tr('detailFile')]: item.trackedChange?.path || tr('unknownFile'),
|
|
6985
|
-
[tr('detailRecord')]: item.trackedChange?.label || item.trackedChange?.id || item.trackedChange?.key || '',
|
|
6986
|
-
[tr('detailReason')]: formatBridgeResultReason(item.result, item.trackedChange?.path)
|
|
6987
|
-
}))
|
|
6988
|
-
}
|
|
6989
|
-
});
|
|
6990
|
-
if (lifecycleReject) {
|
|
6991
|
-
WritebackSettlement.attachUndoNotVerifiedFailure(run, result, {
|
|
6992
|
-
buildFailure: buildContentFailure,
|
|
6993
|
-
postFiles: trackedUndoPostFilesAtDispatch
|
|
6994
|
-
});
|
|
6995
|
-
applyTrackedChangeSettlement(runId, 'reject', result);
|
|
6996
|
-
return;
|
|
6997
|
-
}
|
|
6998
|
-
applyLegacyUndoSettlement(runId, result.skipped?.length ? 'partial' : 'applied', result);
|
|
6999
7000
|
}
|
|
7000
7001
|
|
|
7001
7002
|
async function acceptRun(runId) {
|
|
@@ -7025,50 +7026,50 @@
|
|
|
7025
7026
|
detail: { [tr('detailAccepted')]: formatTrackedChangeFiles(run.undoTrackedChanges) }
|
|
7026
7027
|
});
|
|
7027
7028
|
|
|
7028
|
-
let result;
|
|
7029
7029
|
try {
|
|
7030
|
-
result = await callPageBridge('acceptTrackedChanges', {
|
|
7030
|
+
const result = await callPageBridge('acceptTrackedChanges', {
|
|
7031
7031
|
trackedChanges: run.undoTrackedChanges || [],
|
|
7032
7032
|
expectedFiles: run.undoExpectedFiles || [],
|
|
7033
7033
|
postFiles: buildTrackedUndoPostFiles(run),
|
|
7034
7034
|
appliedOperations: Array.isArray(run.appliedOperations) ? run.appliedOperations : [],
|
|
7035
7035
|
runProjectId: getRunProjectIdForWriteback(run)
|
|
7036
7036
|
});
|
|
7037
|
-
|
|
7038
|
-
trackedChangeInFlight.delete(runId);
|
|
7039
|
-
}
|
|
7040
|
-
appendAcceptDiagnosticEvents(runId, Array.isArray(result.diagnostics) ? result.diagnostics : []);
|
|
7041
|
-
appendRunRecordEvent(runId, {
|
|
7042
|
-
title: tr('runAcceptTrackedResult', { applied: result.applied?.length || 0, skipped: result.skipped?.length || 0 }),
|
|
7043
|
-
status: result.skipped?.length ? 'failed' : 'completed',
|
|
7044
|
-
detail: {
|
|
7045
|
-
[tr('detailAccepted')]: (result.applied || []).map(item => ({
|
|
7046
|
-
[tr('detailFile')]: item.trackedChange?.path || tr('unknownFile'),
|
|
7047
|
-
[tr('detailRecord')]: item.trackedChange?.label || item.trackedChange?.id || item.trackedChange?.key
|
|
7048
|
-
})),
|
|
7049
|
-
[tr('detailSkipped')]: (result.skipped || []).map(item => ({
|
|
7050
|
-
[tr('detailFile')]: item.trackedChange?.path || tr('unknownFile'),
|
|
7051
|
-
[tr('detailRecord')]: item.trackedChange?.label || item.trackedChange?.id || item.trackedChange?.key || '',
|
|
7052
|
-
[tr('detailReason')]: formatBridgeResultReason(item.result, item.trackedChange?.path)
|
|
7053
|
-
}))
|
|
7054
|
-
}
|
|
7055
|
-
});
|
|
7056
|
-
if (result.ok === false) {
|
|
7037
|
+
appendAcceptDiagnosticEvents(runId, Array.isArray(result.diagnostics) ? result.diagnostics : []);
|
|
7057
7038
|
appendRunRecordEvent(runId, {
|
|
7058
|
-
title: tr('
|
|
7059
|
-
status: 'failed',
|
|
7039
|
+
title: tr('runAcceptTrackedResult', { applied: result.applied?.length || 0, skipped: result.skipped?.length || 0 }),
|
|
7040
|
+
status: result.skipped?.length ? 'failed' : 'completed',
|
|
7060
7041
|
detail: {
|
|
7061
|
-
[tr('
|
|
7042
|
+
[tr('detailAccepted')]: (result.applied || []).map(item => ({
|
|
7043
|
+
[tr('detailFile')]: item.trackedChange?.path || tr('unknownFile'),
|
|
7044
|
+
[tr('detailRecord')]: item.trackedChange?.label || item.trackedChange?.id || item.trackedChange?.key
|
|
7045
|
+
})),
|
|
7046
|
+
[tr('detailSkipped')]: (result.skipped || []).map(item => ({
|
|
7047
|
+
[tr('detailFile')]: item.trackedChange?.path || tr('unknownFile'),
|
|
7048
|
+
[tr('detailRecord')]: item.trackedChange?.label || item.trackedChange?.id || item.trackedChange?.key || '',
|
|
7049
|
+
[tr('detailReason')]: formatBridgeResultReason(item.result, item.trackedChange?.path)
|
|
7050
|
+
}))
|
|
7062
7051
|
}
|
|
7063
7052
|
});
|
|
7064
|
-
if (
|
|
7065
|
-
|
|
7053
|
+
if (result.ok === false) {
|
|
7054
|
+
appendRunRecordEvent(runId, {
|
|
7055
|
+
title: tr('runAcceptTrackedFailed'),
|
|
7056
|
+
status: 'failed',
|
|
7057
|
+
detail: {
|
|
7058
|
+
[tr('detailReason')]: tr('runAcceptTrackedFailedReason')
|
|
7059
|
+
}
|
|
7060
|
+
});
|
|
7061
|
+
if (!WritebackSettlement.isSuccessfulTrackedChangeSettlement(result)) {
|
|
7062
|
+
refreshRunCardControls(runId);
|
|
7063
|
+
}
|
|
7066
7064
|
}
|
|
7065
|
+
WritebackSettlement.attachAcceptNotVerifiedFailure(run, result, {
|
|
7066
|
+
buildFailure: buildContentFailure
|
|
7067
|
+
});
|
|
7068
|
+
await applyTrackedChangeSettlement(runId, 'accept', result);
|
|
7069
|
+
} finally {
|
|
7070
|
+
trackedChangeInFlight.delete(runId);
|
|
7071
|
+
refreshRunCardControls(runId);
|
|
7067
7072
|
}
|
|
7068
|
-
WritebackSettlement.attachAcceptNotVerifiedFailure(run, result, {
|
|
7069
|
-
buildFailure: buildContentFailure
|
|
7070
|
-
});
|
|
7071
|
-
applyTrackedChangeSettlement(runId, 'accept', result);
|
|
7072
7073
|
}
|
|
7073
7074
|
|
|
7074
7075
|
function getRunProjectIdForWriteback(run) {
|
|
@@ -7112,7 +7113,7 @@
|
|
|
7112
7113
|
);
|
|
7113
7114
|
}
|
|
7114
7115
|
|
|
7115
|
-
function applyTrackedChangeSettlement(runId, kind, result) {
|
|
7116
|
+
async function applyTrackedChangeSettlement(runId, kind, result) {
|
|
7116
7117
|
const run = findRunRecord(runId);
|
|
7117
7118
|
const settlement = WritebackSettlement.settleTrackedChangeLifecycle({
|
|
7118
7119
|
kind,
|
|
@@ -7121,12 +7122,12 @@
|
|
|
7121
7122
|
failureReasons: FailureReasons
|
|
7122
7123
|
});
|
|
7123
7124
|
if (settlement.decision === 'blocked') {
|
|
7124
|
-
refreshRunCardControls(runId);
|
|
7125
7125
|
return;
|
|
7126
7126
|
}
|
|
7127
|
-
|
|
7128
|
-
|
|
7129
|
-
|
|
7127
|
+
await Modules.ScopedPersistenceCoordinator.applyReviewTransition({
|
|
7128
|
+
getState: () => state, runId, transition: WritebackSettlement.applySettlementTransition(run, settlement),
|
|
7129
|
+
persist: flushQueuedSaveState
|
|
7130
|
+
});
|
|
7130
7131
|
}
|
|
7131
7132
|
|
|
7132
7133
|
function getRunUndoCount(run) {
|