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 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.0-blue" alt="version">
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.0 bash -c "$(curl -fsSL https://raw.githubusercontent.com/Ghqqqq/codex-overleaf-link/v2.4.0/install.sh)"
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.0/install.ps1 -OutFile install.ps1
97
- $env:CODEX_OVERLEAF_REF='v2.4.0'
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.0 -- install-managed
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.0 -- install-managed` |
229
- | Diagnose | `npm exec --yes codex-overleaf-link@2.4.0 -- doctor` |
230
- | Uninstall | `npm exec --yes codex-overleaf-link@2.4.0 -- uninstall-managed` |
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.0 -- uninstall-managed
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.0 -- uninstall-native
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.0 -- install-managed
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.0 bash -c "$(curl -fsSL https://raw.githubusercontent.com/Ghqqqq/codex-overleaf-link/v2.4.0/install.sh)" -- --browser chromium
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.0 -- uninstall-managed --browser chromium
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.0 -- install-managed --extension-id "<your-chrome-extension-id>"
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.0 -- install-native --extension-id "<your-chrome-extension-id>"
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.0 GitHub Release contains:
434
+ The v2.4.1 GitHub Release contains:
432
435
 
433
- - `codex-overleaf-link-extension-v2.4.0.zip`: loadable Chrome extension package for manual unpacked installation.
434
- - `codex-overleaf-native-host-v2.4.0.tar.gz`: native host runtime files used by the installer and release verification.
435
- - `codex-overleaf-update-v2.4.0.tar.gz`: coordinated extension/native bundle used by the managed updater.
436
- - `codex-overleaf-link-2.4.0.tgz`: npm native host CLI package for pinned install, doctor, and uninstall flows.
437
- - `install.sh`: release-pinned macOS / Linux installer that defaults to `v2.4.0` when run directly from the release artifact.
438
- - `install.ps1`: release-pinned Windows PowerShell installer that defaults to `v2.4.0` when run directly from the release artifact.
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.0 -- install-managed` | `npm exec --yes codex-overleaf-link@2.4.0 -- install-managed` | `npm exec --yes codex-overleaf-link@2.4.0 -- install-managed` | `npm exec --yes codex-overleaf-link@2.4.0 -- install-managed --browser chromium` |
516
- | Uninstall command | `npm exec --yes codex-overleaf-link@2.4.0 -- uninstall-managed` | `npm exec --yes codex-overleaf-link@2.4.0 -- uninstall-managed` | `npm exec --yes codex-overleaf-link@2.4.0 -- uninstall-managed` | `npm exec --yes codex-overleaf-link@2.4.0 -- uninstall-managed --browser chromium` |
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.0-blue" alt="版本">
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.0 bash -c "$(curl -fsSL https://raw.githubusercontent.com/Ghqqqq/codex-overleaf-link/v2.4.0/install.sh)"
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.0/install.ps1 -OutFile install.ps1
97
- $env:CODEX_OVERLEAF_REF='v2.4.0'
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.0 -- install-managed
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.0 -- install-managed` |
229
- | 诊断 | `npm exec --yes codex-overleaf-link@2.4.0 -- doctor` |
230
- | 卸载 | `npm exec --yes codex-overleaf-link@2.4.0 -- uninstall-managed` |
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.0 -- uninstall-managed
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.0 -- uninstall-native
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.0 -- install-managed
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.0 bash -c "$(curl -fsSL https://raw.githubusercontent.com/Ghqqqq/codex-overleaf-link/v2.4.0/install.sh)" -- --browser chromium
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.0 -- uninstall-managed --browser chromium
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.0 -- install-managed --extension-id "<your-chrome-extension-id>"
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.0 -- install-native --extension-id "<your-chrome-extension-id>"
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.0 的 GitHub Release 包含:
434
+ v2.4.1 的 GitHub Release 包含:
432
435
 
433
- - `codex-overleaf-link-extension-v2.4.0.zip`:用于手动加载已解压扩展的 Chrome 扩展包。
434
- - `codex-overleaf-native-host-v2.4.0.tar.gz`:供安装器和发布验证使用的 Native Host 运行时文件。
435
- - `codex-overleaf-update-v2.4.0.tar.gz`:托管更新器使用的扩展 / Native Host 配套更新包。
436
- - `codex-overleaf-link-2.4.0.tgz`:提供固定版本安装、doctor 诊断和卸载流程的 npm CLI 包。
437
- - `install.sh`:固定发布版本的 macOS / Linux 安装脚本,从 Release 制品直接运行时默认使用 `v2.4.0`。
438
- - `install.ps1`:固定发布版本的 Windows PowerShell 安装脚本,从 Release 制品直接运行时默认使用 `v2.4.0`。
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.0 -- install-managed` | `npm exec --yes codex-overleaf-link@2.4.0 -- install-managed` | `npm exec --yes codex-overleaf-link@2.4.0 -- install-managed` | `npm exec --yes codex-overleaf-link@2.4.0 -- install-managed --browser chromium` |
516
- | 卸载命令 | `npm exec --yes codex-overleaf-link@2.4.0 -- uninstall-managed` | `npm exec --yes codex-overleaf-link@2.4.0 -- uninstall-managed` | `npm exec --yes codex-overleaf-link@2.4.0 -- uninstall-managed` | `npm exec --yes codex-overleaf-link@2.4.0 -- uninstall-managed --browser chromium` |
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
- } finally {
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('runAcceptTrackedFailed'),
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('detailReason')]: tr('runAcceptTrackedFailedReason')
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 (!WritebackSettlement.isSuccessfulTrackedChangeSettlement(result)) {
7065
- refreshRunCardControls(runId);
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
- Object.assign(run, WritebackSettlement.applySettlementTransition(run, settlement));
7128
- saveStateSoon();
7129
- refreshRunCardControls(runId);
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) {