codex-overleaf-link 1.3.0 → 1.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 CHANGED
@@ -3,7 +3,7 @@
3
3
  <h1>Codex Overleaf Link</h1>
4
4
  <p><strong>Empower Overleaf with Codex.</strong></p>
5
5
  <p>
6
- <img src="https://img.shields.io/badge/version-1.3.0-blue" alt="version">
6
+ <img src="https://img.shields.io/badge/version-1.3.5-blue" alt="version">
7
7
  <img src="https://img.shields.io/badge/platform-macOS%20%2F%20Windows%20%2F%20Linux-lightgrey" alt="platform">
8
8
  <img src="https://img.shields.io/badge/chrome-MV3-green" alt="chrome manifest v3">
9
9
  <img src="https://img.shields.io/badge/node-%3E%3D20-brightgreen" alt="node version">
@@ -21,136 +21,89 @@ Overleaf is great for collaborative LaTeX writing. Codex is great for AI-assiste
21
21
 
22
22
  Codex Overleaf Link bridges the two: it adds a Codex panel directly inside Overleaf, mirrors the project locally for Codex to work on, and writes accepted changes back through the browser — with stale-write guards, diff review, and undo checkpoints to reduce the risk of accidental overwrites.
23
23
 
24
- ## Preview
25
-
26
24
  <p align="center">
27
25
  <img src="assets/codex-preview.png" alt="Codex Overleaf Link running inside Overleaf">
28
26
  </p>
29
27
 
30
28
  ## Install
31
29
 
32
- The recommended release path is npm-first for the native host, plus Chrome's required manual approval for the unpacked extension. The bundled extension key gives the official unpacked build a stable id, so normal release installs do not need `--extension-id`.
33
-
34
- 1. Install or update the native host with the pinned npm package:
35
-
36
- ```bash
37
- npm exec --yes codex-overleaf-link@1.3.0 -- install-native
38
- ```
39
-
40
- 2. Download `codex-overleaf-link-extension-v1.3.0.zip` from the [v1.3.0 GitHub Release](https://github.com/Ghqqqq/codex-overleaf-link/releases/tag/v1.3.0), then unzip it to a stable local folder.
30
+ Codex Overleaf Link has two pieces, installed separately:
41
31
 
42
- 3. Open `chrome://extensions`, enable **Developer mode**, click **Load unpacked**, and select the unzipped extension folder.
32
+ - **Native host** installed and updated with the pinned npm package. npm installs, updates, uninstalls, and diagnoses the native host *only*; it never installs the Chrome extension.
33
+ - **Chrome extension** — loaded manually as an unpacked extension from the GitHub Release zip (or a source checkout). The bundled extension key gives the official build a stable id, so normal installs do not need `--extension-id`.
43
34
 
44
- 4. Open any Overleaf project. The Codex panel appears on the right.
45
-
46
- If you modify the extension key or load a custom build that gets a different id, rerun the native install with `--extension-id <chrome-extension-id>`.
47
-
48
- Source installer fallback for macOS / Linux, mainly for development or source checkout installs:
35
+ **1. Install or update the native host:**
49
36
 
50
37
  ```bash
51
- CODEX_OVERLEAF_REF=v1.3.0 bash -c "$(curl -fsSL https://raw.githubusercontent.com/Ghqqqq/codex-overleaf-link/v1.3.0/install.sh)"
38
+ npm exec --yes codex-overleaf-link@1.3.5 -- install-native
52
39
  ```
53
40
 
54
- Source installer fallback for Windows from PowerShell:
41
+ **2. Load the extension:** Download `codex-overleaf-link-extension-v1.3.5.zip` from the [v1.3.5 GitHub Release](https://github.com/Ghqqqq/codex-overleaf-link/releases/tag/v1.3.5) and unzip it to a stable local folder. In `chrome://extensions`, enable **Developer mode**, click **Load unpacked**, and select that folder.
55
42
 
56
- ```powershell
57
- iwr https://raw.githubusercontent.com/Ghqqqq/codex-overleaf-link/v1.3.0/install.ps1 -OutFile install.ps1
58
- $env:CODEX_OVERLEAF_REF='v1.3.0'
59
- powershell -ExecutionPolicy Bypass -File install.ps1
60
- ```
43
+ **3. Open any Overleaf project.** The Codex panel appears on the right; confirm the native host is connected from the panel diagnostics.
61
44
 
62
- ## npm Native Host CLI
45
+ Start in Ask mode; switch to Suggest mode for reviewed edits, or Auto mode once project governance and checkpoint settings are ready for direct writeback.
63
46
 
64
- npm installs, updates, uninstalls, and diagnoses the native host only. npm does not install the Chrome extension; install the Chrome extension separately from the release source checkout or extension zip.
47
+ If Chrome assigns a custom build a different id, rerun the native install with `--extension-id <chrome-extension-id>` so the native manifest `allowed_origins` entry matches.
65
48
 
66
- Install or update the native host for the official release extension id:
49
+ ### Source installer fallback
67
50
 
68
- ```bash
69
- npm exec --yes codex-overleaf-link@1.3.0 -- install-native
70
- ```
51
+ If npm is unavailable, use the release-pinned script for your platform. These also serve development and source-checkout installs.
71
52
 
72
- Diagnose the registered native host:
53
+ macOS / Linux:
73
54
 
74
55
  ```bash
75
- npm exec --yes codex-overleaf-link@1.3.0 -- doctor
56
+ CODEX_OVERLEAF_REF=v1.3.5 bash -c "$(curl -fsSL https://raw.githubusercontent.com/Ghqqqq/codex-overleaf-link/v1.3.5/install.sh)"
76
57
  ```
77
58
 
78
- Uninstall the native host:
59
+ Windows PowerShell:
79
60
 
80
- ```bash
81
- npm exec --yes codex-overleaf-link@1.3.0 -- uninstall-native
61
+ ```powershell
62
+ iwr https://raw.githubusercontent.com/Ghqqqq/codex-overleaf-link/v1.3.5/install.ps1 -OutFile install.ps1
63
+ $env:CODEX_OVERLEAF_REF='v1.3.5'
64
+ powershell -ExecutionPolicy Bypass -File install.ps1
82
65
  ```
83
66
 
84
- Use `--extension-id <chrome-extension-id>` only for a custom/dev unpacked extension id that differs from the official bundled id.
85
-
86
- Open any Overleaf project - the Codex panel appears on the right.
87
-
88
- ## Quick Start
89
-
90
- 1. Install or update the native host with the version-pinned npm command, or use the GitHub Release script fallback for your platform.
91
- 2. In `chrome://extensions`, enable Developer mode, load or reload the unpacked extension folder, and confirm the native host is connected from the panel diagnostics.
92
- 3. Open an Overleaf project and start in Ask mode; switch to Suggest mode when you want Codex to propose reviewed edits, or Auto mode when the project governance and checkpoint settings are ready for direct writeback.
93
-
94
- <p align="center">
95
- <img src="assets/codex-preview.png" alt="Codex Overleaf Link panel inside Overleaf">
96
- </p>
97
-
98
67
  <details>
99
- <summary><strong>Manual install</strong> (if you prefer a custom location)</summary>
68
+ <summary><strong>Manual checkout install</strong> (custom location)</summary>
100
69
 
101
70
  ```bash
102
71
  git clone https://github.com/Ghqqqq/codex-overleaf-link.git
103
72
  cd codex-overleaf-link
104
- ```
105
-
106
- Then load `extension/` as an unpacked extension in Chrome and register the native host:
107
-
108
- ```bash
109
73
  npm run install:native
110
74
  ```
111
75
 
112
- If Chrome assigns a different extension id, rerun `npm run install:native -- --extension-id <chrome-extension-id>`.
76
+ Then load `extension/` as an unpacked extension in Chrome. If Chrome assigns a different extension id, rerun `npm run install:native -- --extension-id <chrome-extension-id>`.
113
77
 
114
78
  </details>
115
79
 
116
- <details>
117
- <summary><strong>Update</strong></summary>
118
-
119
- For a deterministic v1.3.0 update, run the pinned npm command. This is also the native mismatch recovery command shown by the popup and panel when they report **Native host update required**.
120
-
121
- ```bash
122
- npm exec --yes codex-overleaf-link@1.3.0 -- install-native
123
- ```
80
+ ## npm Native Host CLI
124
81
 
125
- If npm is unavailable, use the GitHub Release script fallback for your platform.
82
+ npm installs, updates, uninstalls, and diagnoses the native host only. npm does not install the Chrome extension; install the Chrome extension separately from the release source checkout or extension zip.
126
83
 
127
- macOS / Linux:
84
+ | Action | Command |
85
+ |--------|---------|
86
+ | Install / update | `npm exec --yes codex-overleaf-link@1.3.5 -- install-native` |
87
+ | Diagnose | `npm exec --yes codex-overleaf-link@1.3.5 -- doctor` |
88
+ | Uninstall | `npm exec --yes codex-overleaf-link@1.3.5 -- uninstall-native` |
128
89
 
129
- ```bash
130
- CODEX_OVERLEAF_REF=v1.3.0 bash -c "$(curl -fsSL https://raw.githubusercontent.com/Ghqqqq/codex-overleaf-link/v1.3.0/install.sh)"
131
- ```
132
-
133
- Windows PowerShell:
90
+ Use `--extension-id <chrome-extension-id>` only for a custom/dev unpacked extension id that differs from the official bundled id.
134
91
 
135
- ```powershell
136
- iwr https://raw.githubusercontent.com/Ghqqqq/codex-overleaf-link/v1.3.0/install.ps1 -OutFile install.ps1
137
- $env:CODEX_OVERLEAF_REF='v1.3.0'
138
- powershell -ExecutionPolicy Bypass -File install.ps1
139
- ```
92
+ ## Update
140
93
 
141
- Then reload the extension in `chrome://extensions` and refresh the Overleaf page.
94
+ For a deterministic v1.3.5 update, run the pinned npm install command above. This is also the native mismatch recovery command shown by the popup and panel when they report **Native host update required** — it fixes extension/native version mismatch and native protocol mismatch.
142
95
 
143
- </details>
96
+ If npm is unavailable, run the [source installer fallback](#source-installer-fallback) for your platform. After updating, reload the extension in `chrome://extensions` and refresh the Overleaf page.
144
97
 
145
98
  ## GitHub Release Artifacts
146
99
 
147
- The v1.3.0 GitHub Release contains:
100
+ The v1.3.5 GitHub Release contains:
148
101
 
149
- - `codex-overleaf-link-extension-v1.3.0.zip`: loadable Chrome extension package for manual unpacked installation.
150
- - `codex-overleaf-native-host-v1.3.0.tar.gz`: native host runtime files used by the installer and release verification.
151
- - `codex-overleaf-link-1.3.0.tgz`: npm native host CLI package for pinned install, doctor, and uninstall flows.
152
- - `install.sh`: release-pinned macOS / Linux installer that defaults to `v1.3.0` when run directly from the release artifact.
153
- - `install.ps1`: release-pinned Windows PowerShell installer that defaults to `v1.3.0` when run directly from the release artifact.
102
+ - `codex-overleaf-link-extension-v1.3.5.zip`: loadable Chrome extension package for manual unpacked installation.
103
+ - `codex-overleaf-native-host-v1.3.5.tar.gz`: native host runtime files used by the installer and release verification.
104
+ - `codex-overleaf-link-1.3.5.tgz`: npm native host CLI package for pinned install, doctor, and uninstall flows.
105
+ - `install.sh`: release-pinned macOS / Linux installer that defaults to `v1.3.5` when run directly from the release artifact.
106
+ - `install.ps1`: release-pinned Windows PowerShell installer that defaults to `v1.3.5` when run directly from the release artifact.
154
107
  - `uninstall-native-host.mjs`: native host uninstaller that removes the Chrome Native Messaging manifest, bridge executable, and runtime copy.
155
108
  - `nativeHostPlatform.js`, `manifest.js`, `runtimeInstaller.js`: helper files required by the loose uninstaller asset.
156
109
  - `SHA256SUMS` and `release-manifest.json`: checksum and artifact metadata for release verification.
@@ -158,23 +111,17 @@ The v1.3.0 GitHub Release contains:
158
111
  <details>
159
112
  <summary><strong>Uninstall</strong></summary>
160
113
 
161
- macOS / Linux:
114
+ Remove the native host (use `--browser chromium` on Linux Chromium):
162
115
 
163
116
  ```bash
164
- npm exec --yes codex-overleaf-link@1.3.0 -- uninstall-native
165
- ```
166
-
167
- Windows PowerShell:
168
-
169
- ```powershell
170
- npm exec --yes codex-overleaf-link@1.3.0 -- uninstall-native
117
+ npm exec --yes codex-overleaf-link@1.3.5 -- uninstall-native
171
118
  ```
172
119
 
173
- If you installed from a manual checkout or source installer, you can also run `npm run uninstall:native` inside the repo, use `node ~/.codex-overleaf/source/scripts/uninstall-native-host.mjs` on macOS / Linux, or use `node $env:LOCALAPPDATA\CodexOverleaf\source\scripts\uninstall-native-host.mjs` on Windows PowerShell.
120
+ The same command works on Windows PowerShell. If you installed from a manual checkout or source installer, you can also run `npm run uninstall:native` inside the repo, use `node ~/.codex-overleaf/source/scripts/uninstall-native-host.mjs` on macOS / Linux, or use `node $env:LOCALAPPDATA\CodexOverleaf\source\scripts\uninstall-native-host.mjs` on Windows PowerShell.
174
121
 
175
- Remove the extension from `chrome://extensions`. Optionally delete `~/.codex-overleaf` on macOS / Linux to remove local mirrors, native runtime files, and plugin history. On Windows, `%LOCALAPPDATA%\CodexOverleaf` contains the native source, runtime, bridge, and native log, while `%USERPROFILE%\.codex-overleaf` contains project mirrors, plugin Codex home/history, and Codex Overleaf skills. Full Windows cleanup requires deleting both roots, or following [Local Data And Cleanup](#local-data-and-cleanup).
122
+ The uninstaller removes the Native Messaging registration, bridge executable, and native runtime copy. It does not remove browser IndexedDB, `chrome.storage.local`, project mirrors, plugin Codex history, or project/plugin skills.
176
123
 
177
- The uninstaller removes the Native Messaging registration, bridge executable, and native runtime copy. It does not remove browser IndexedDB, `chrome.storage.local`, project mirrors, plugin Codex history, or project/plugin skills. See [Local Data And Cleanup](#local-data-and-cleanup) for full deletion steps.
124
+ Then remove the extension from `chrome://extensions`. To delete local data: on macOS / Linux, delete `~/.codex-overleaf`. On Windows, `%LOCALAPPDATA%\CodexOverleaf` holds the native source, runtime, bridge, and native log, while `%USERPROFILE%\.codex-overleaf` holds project mirrors, plugin Codex home/history, and Codex Overleaf skills — full Windows cleanup requires deleting both roots. See [Local Data And Cleanup](#local-data-and-cleanup) for full deletion steps.
178
125
 
179
126
  </details>
180
127
 
@@ -202,13 +149,13 @@ The uninstaller removes the Native Messaging registration, bridge executable, an
202
149
  Linux Chromium install or update:
203
150
 
204
151
  ```bash
205
- CODEX_OVERLEAF_REF=v1.3.0 bash -c "$(curl -fsSL https://raw.githubusercontent.com/Ghqqqq/codex-overleaf-link/v1.3.0/install.sh)" -- --browser chromium
152
+ CODEX_OVERLEAF_REF=v1.3.5 bash -c "$(curl -fsSL https://raw.githubusercontent.com/Ghqqqq/codex-overleaf-link/v1.3.5/install.sh)" -- --browser chromium
206
153
  ```
207
154
 
208
155
  Linux Chromium uninstall:
209
156
 
210
157
  ```bash
211
- npm exec --yes codex-overleaf-link@1.3.0 -- uninstall-native --browser chromium
158
+ npm exec --yes codex-overleaf-link@1.3.5 -- uninstall-native --browser chromium
212
159
  ```
213
160
 
214
161
  ## Features
@@ -222,22 +169,20 @@ npm exec --yes codex-overleaf-link@1.3.0 -- uninstall-native --browser chromium
222
169
  - **Auto-recompile** — triggers Overleaf recompile after writeback; logs compile errors as context.
223
170
  - **@ context** — attach specific files, `@compile-log`, or `@current-section` to the prompt.
224
171
  - **Composer attachments and binary writeback** — paste or drop PDFs, images, and files into the composer as turn-scoped Codex context, and review Codex-created assets before creating or replacing them in Overleaf.
225
- - **Codex Overleaf skills** — install reusable plugin-scoped skills through the slash menu, then let Codex auto-trigger them or select one explicitly for the next turn.
172
+ - **Codex Overleaf skills** — install reusable plugin-scoped skills through the slash menu, then let Codex auto-trigger them or select one explicitly for the next turn. Each skill has its own enable toggle, honored at run time.
226
173
  - **Governance rules** — configure project read-only and writable path rules that block unsafe writeback before browser mutation.
227
174
  - **Sensitive preflight** — scan selected project context for likely secrets before sending it to Codex.
228
175
  - **Audit and diagnostics** — keep local run records and export redacted diagnostic bundles for issue reports.
229
176
  - **Model picker** — discover available Codex models locally, then switch model, reasoning effort, and speed from one compact control.
230
177
  - **Session history** — multi-session management with rename, resume, and delete.
231
- - **Isolated Codex home** — plugin sessions stay under `~/.codex-overleaf/codex-home`, not global `~/.codex/sessions`.
232
- - **Experimental OT warm mirror** - optional read-only observation of active Overleaf text edits to keep focused local mirror files warm. Falls back to full snapshots when unavailable or inconsistent.
233
-
234
- > Note: The OT warm mirror is experimental, off by default, and never writes back to Overleaf through realtime collaboration channels.
178
+ - **Isolated Codex home** — plugin sessions run under `~/.codex-overleaf/codex-home` (not global `~/.codex/sessions`) and do not inherit your global Codex personalization.
179
+ - **Experimental OT warm mirror** optional read-only observation of active Overleaf text edits to keep focused local mirror files warm. Falls back to full snapshots when unavailable or inconsistent. Off by default; it never writes back to Overleaf through realtime collaboration channels.
235
180
 
236
181
  ## Common Workflows
237
182
 
238
- - **Fix a compile error** - choose Suggest mode, attach `@compile-log`, ask Codex to diagnose and patch the failing file, review the diff, apply it, then recompile from the panel.
239
- - **Rewrite a paragraph** - select the target file or `@current-section`, ask for a tone or clarity rewrite in Suggest mode, review the text diff, and accept only the hunks you want.
240
- - **Translate a section** - attach the source section with `@file` or `@current-section`, specify the target language and terminology constraints, then review the proposed replacement before writeback.
183
+ - **Fix a compile error** choose Suggest mode, attach `@compile-log`, ask Codex to diagnose and patch the failing file, review the diff, apply it, then recompile from the panel.
184
+ - **Rewrite a paragraph** select the target file or `@current-section`, ask for a tone or clarity rewrite in Suggest mode, review the text diff, and accept only the hunks you want.
185
+ - **Translate a section** attach the source section with `@file` or `@current-section`, specify the target language and terminology constraints, then review the proposed replacement before writeback.
241
186
 
242
187
  ## How It Works
243
188
 
@@ -278,16 +223,12 @@ This repo ships a stable Chrome extension `key`, producing the deterministic id:
278
223
  illdpneeeopfffmiepaejglgmhpmdhdc
279
224
  ```
280
225
 
281
- The installer uses this id by default. If Chrome assigns a different id, reinstall the native host with the actual id.
282
-
283
- macOS / Linux:
226
+ The installer uses this id by default. If Chrome assigns a different id, reinstall the native host with the actual id:
284
227
 
285
228
  ```bash
286
229
  cd ~/.codex-overleaf/source && npm run install:native -- --extension-id <your-chrome-extension-id>
287
230
  ```
288
231
 
289
- Windows PowerShell:
290
-
291
232
  ```powershell
292
233
  cd $env:LOCALAPPDATA\CodexOverleaf\source
293
234
  npm run install:native -- --extension-id <your-chrome-extension-id>
@@ -308,7 +249,7 @@ Codex Overleaf Link does not use a hosted backend or default telemetry. Data is
308
249
  | macOS/Linux bridge | `~/.codex-overleaf/codex-overleaf-bridge` | Native Messaging launcher executable. |
309
250
  | Windows source/runtime/bridge | `%LOCALAPPDATA%\CodexOverleaf` | `source`, `native-host-runtime`, `codex-overleaf-bridge.cmd`, and native debug log. |
310
251
  | Project mirrors | `~/.codex-overleaf/projects` on macOS/Linux, `%USERPROFILE%\.codex-overleaf\projects` on Windows | Local mirror workspaces and mirror metadata for each Overleaf project. |
311
- | Plugin Codex home | `~/.codex-overleaf/codex-home` on macOS/Linux, `%USERPROFILE%\.codex-overleaf\codex-home` on Windows | Isolated Codex home for plugin runs. It copies auth/config metadata but does not reuse global Codex sessions. |
252
+ | Plugin Codex home | `~/.codex-overleaf/codex-home` on macOS/Linux, `%USERPROFILE%\.codex-overleaf\codex-home` on Windows | Isolated Codex home for plugin runs. It copies auth/config metadata but does not reuse global Codex sessions or inherit global Codex personalization. |
312
253
  | Codex Overleaf skills | `~/.codex-overleaf/skills` on macOS/Linux, `%USERPROFILE%\.codex-overleaf\skills` on Windows | Project/plugin skills managed by the extension. |
313
254
  | Native logs | `~/.codex-overleaf/native-host.log` on macOS/Linux, `%LOCALAPPDATA%\CodexOverleaf\native-host.log` on Windows | Native debug events with content length summaries where possible. |
314
255
  | Launcher logs | `~/.codex-overleaf/native-host-launcher.log` on macOS/Linux | POSIX launcher startup path and Node diagnostics. The Windows `.cmd` launcher does not currently emit a separate launcher log. |
@@ -318,6 +259,8 @@ Skill loading toggles default to enabled. In Project Settings:
318
259
  - `Load local Codex skills` loads the user's local Codex skill environment from the global Codex home into the isolated `~/.codex-overleaf/codex-home`: `~/.codex/skills`, local Codex `plugins`, `superpowers`, and related skill/plugin configuration. Turning it off hides user/system Codex skills and local Codex plugins from Codex Overleaf runs. This affects only the plugin CODEX_HOME prepared for the run; it does not write to or reuse global `~/.codex/sessions`.
319
260
  - `Load Codex Overleaf skills` loads project/plugin skills managed by the extension from `~/.codex-overleaf/skills` on macOS/Linux or `%USERPROFILE%\.codex-overleaf\skills` on Windows into the same isolated Codex home. Turning it off hides those extension-managed skills while preserving the stored skill files. If both toggles are off, the run starts without local Codex skills or Codex Overleaf skills.
320
261
 
262
+ The isolated plugin Codex home copies auth and config metadata but excludes global Codex personalization: it does not copy `~/.codex/AGENTS.md`, strips the top-level `personality` key from the copied `config.toml`, and does not link the global `rules` or `memories` directories.
263
+
321
264
  Native registration paths:
322
265
 
323
266
  | Platform/browser | Registration path |
@@ -341,31 +284,15 @@ Composer attachments are turn-scoped Codex context. Limits are 8 attachments per
341
284
 
342
285
  **Native host missing or update required**
343
286
 
344
- Run the pinned npm native-host installer, reload the extension in `chrome://extensions`, then refresh the Overleaf tab. This also fixes extension/native version mismatch and native protocol mismatch.
287
+ Run the pinned npm native-host installer, reload the extension in `chrome://extensions`, then refresh the Overleaf tab. This also fixes extension/native version mismatch and native protocol mismatch. If npm is unavailable, use the [source installer fallback](#source-installer-fallback) for your platform.
345
288
 
346
289
  ```bash
347
- npm exec --yes codex-overleaf-link@1.3.0 -- install-native
348
- ```
349
-
350
- If npm is unavailable, use the GitHub Release script fallback for your platform.
351
-
352
- macOS/Linux:
353
-
354
- ```bash
355
- CODEX_OVERLEAF_REF=v1.3.0 bash -c "$(curl -fsSL https://raw.githubusercontent.com/Ghqqqq/codex-overleaf-link/v1.3.0/install.sh)"
356
- ```
357
-
358
- Windows PowerShell:
359
-
360
- ```powershell
361
- iwr https://raw.githubusercontent.com/Ghqqqq/codex-overleaf-link/v1.3.0/install.ps1 -OutFile install.ps1
362
- $env:CODEX_OVERLEAF_REF='v1.3.0'
363
- powershell -ExecutionPolicy Bypass -File install.ps1
290
+ npm exec --yes codex-overleaf-link@1.3.5 -- install-native
364
291
  ```
365
292
 
366
293
  **The Windows popup or panel shows a Bash recovery command**
367
294
 
368
- Use the PowerShell recovery command above on Windows. The Bash command is for macOS/Linux installers.
295
+ Use the PowerShell recovery command on Windows. The Bash command is for macOS/Linux installers.
369
296
 
370
297
  **Codex CLI not found**
371
298
 
@@ -373,16 +300,7 @@ Confirm `codex --version` works in a new terminal and that you are logged in. On
373
300
 
374
301
  **Extension id mismatch**
375
302
 
376
- Copy the id shown in `chrome://extensions` and reinstall the native host with that id:
377
-
378
- ```bash
379
- cd ~/.codex-overleaf/source && npm run install:native -- --extension-id <your-chrome-extension-id>
380
- ```
381
-
382
- ```powershell
383
- cd $env:LOCALAPPDATA\CodexOverleaf\source
384
- npm run install:native -- --extension-id <your-chrome-extension-id>
385
- ```
303
+ Copy the id shown in `chrome://extensions` and reinstall the native host with that id (see [Extension ID](#extension-id)).
386
304
 
387
305
  **Linux Chromium does not connect**
388
306
 
@@ -418,8 +336,8 @@ Use this matrix for release-candidate signoff and compatibility reports. Record
418
336
  | Browser/channel/version | Google Chrome channel and version. | Google Chrome channel and version. | Google Chrome channel and version. | Chromium channel/package and version. |
419
337
  | Install mode | Manual unpacked extension from GitHub Release zip or checkout. | Manual unpacked extension from GitHub Release zip or checkout. | Manual unpacked extension from GitHub Release zip or checkout. | Manual unpacked extension from GitHub Release zip or checkout; native host installed with `--browser chromium`. |
420
338
  | 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`. |
421
- | Installer/update command | `npm exec --yes codex-overleaf-link@1.3.0 -- install-native` | `npm exec --yes codex-overleaf-link@1.3.0 -- install-native` | `npm exec --yes codex-overleaf-link@1.3.0 -- install-native` | `npm exec --yes codex-overleaf-link@1.3.0 -- install-native --browser chromium` |
422
- | Uninstall command | `npm exec --yes codex-overleaf-link@1.3.0 -- uninstall-native` | `npm exec --yes codex-overleaf-link@1.3.0 -- uninstall-native` | `npm exec --yes codex-overleaf-link@1.3.0 -- uninstall-native` | `npm exec --yes codex-overleaf-link@1.3.0 -- uninstall-native --browser chromium` |
339
+ | Installer/update command | `npm exec --yes codex-overleaf-link@1.3.5 -- install-native` | `npm exec --yes codex-overleaf-link@1.3.5 -- install-native` | `npm exec --yes codex-overleaf-link@1.3.5 -- install-native` | `npm exec --yes codex-overleaf-link@1.3.5 -- install-native --browser chromium` |
340
+ | Uninstall command | `npm exec --yes codex-overleaf-link@1.3.5 -- uninstall-native` | `npm exec --yes codex-overleaf-link@1.3.5 -- uninstall-native` | `npm exec --yes codex-overleaf-link@1.3.5 -- uninstall-native` | `npm exec --yes codex-overleaf-link@1.3.5 -- uninstall-native --browser chromium` |
423
341
  | 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` |
424
342
  | Bridge/runtime/source path | Bridge `~/.codex-overleaf/codex-overleaf-bridge`; runtime `~/.codex-overleaf/native-host-runtime`; source `~/.codex-overleaf/source`. | Bridge `%LOCALAPPDATA%\CodexOverleaf\codex-overleaf-bridge.cmd`; runtime `%LOCALAPPDATA%\CodexOverleaf\native-host-runtime`; source `%LOCALAPPDATA%\CodexOverleaf\source`. | Bridge `~/.codex-overleaf/codex-overleaf-bridge`; runtime `~/.codex-overleaf/native-host-runtime`; source `~/.codex-overleaf/source`. | Bridge `~/.codex-overleaf/codex-overleaf-bridge`; runtime `~/.codex-overleaf/native-host-runtime`; source `~/.codex-overleaf/source`. |
425
343
  | Node/Git/Codex/TeX | Node.js >= 20; Git; Codex CLI installed and logged in; TeX optional. | Node.js >= 20; Git; Codex CLI installed and logged in; TeX optional. | Node.js >= 20; Git; Codex CLI installed and logged in; TeX optional. | Node.js >= 20; Git; Codex CLI installed and logged in; TeX optional. |
@@ -430,11 +348,11 @@ Use this matrix for release-candidate signoff and compatibility reports. Record
430
348
  ## Development
431
349
 
432
350
  ```bash
433
- npm test # Node.js built-in test runner, zero dependencies
351
+ npm test # Node.js built-in test runner, zero dependencies
434
352
  npm run check:architecture # enforce v1.0 final architecture budgets
435
353
  npm run benchmark:large # run the synthetic large-project regression gate
436
- npm run bridge # run the native host directly for protocol work
437
- npm run install:native # reinstall native host after changing native-host/src or extension/src/shared
354
+ npm run bridge # run the native host directly for protocol work
355
+ npm run install:native # reinstall native host after changing native-host/src or extension/src/shared
438
356
  ```
439
357
 
440
358
  ## Contributing
@@ -12,7 +12,7 @@
12
12
  const MIN_NATIVE_VERSION = '1.0.0';
13
13
  const MIN_COMPATIBLE_NATIVE_VERSION = '1.0.0';
14
14
  const MIN_COMPATIBLE_EXTENSION_VERSION = '1.0.0';
15
- const BUILD_TARGET_VERSION = '1.3.0';
15
+ const BUILD_TARGET_VERSION = '1.3.5';
16
16
  const DEFAULT_CHROME_EXTENSION_ID = 'illdpneeeopfffmiepaejglgmhpmdhdc';
17
17
  const REQUIRED_CAPABILITIES = Object.freeze([
18
18
  'bridgePing',
@@ -155,15 +155,15 @@
155
155
  switchLanguageHint: 'Change panel language',
156
156
  close: 'Close',
157
157
  closeDiagnostics: 'Close diagnostics result',
158
- customInstructionsSettings: 'Custom Instructions',
159
- customInstructionsTitle: 'Custom Instructions',
160
- customInstructionsSubtitle: 'Give Codex extra instructions and context for this Overleaf project.',
161
- customInstructionsLearnMore: 'Learn more',
162
- customInstructionsClose: 'Close custom instructions',
158
+ settingsBack: 'Back',
159
+ projectSettings: 'Project Settings',
163
160
  customInstructionsPlaceholder: 'Style, terminology, venue constraints, and LaTeX conventions for this project.',
164
- projectSettingsSavedToast: 'Project settings saved.',
165
161
  projectSettingsTitle: 'Project Settings',
166
- projectSettingsSubtitle: 'Governance, local skills, and custom instructions for this Overleaf project.',
162
+ projectSettingsSubtitle: 'Customize how Codex behaves in this and all projects.',
163
+ settingsScopeProjectTitle: 'This project',
164
+ settingsScopeProjectSubtitle: 'Instructions and rules applied to this Overleaf project only.',
165
+ settingsScopeGlobalTitle: 'All projects',
166
+ settingsScopeGlobalSubtitle: 'Skill loading settings that apply across all Overleaf projects.',
167
167
  governanceRulesTitle: 'Governance Rules',
168
168
  governanceReadonlyPatterns: 'Read-only patterns',
169
169
  governanceWritablePatterns: 'Writable patterns',
@@ -173,13 +173,21 @@
173
173
  sensitiveConfirmMessage: 'Codex found possible sensitive content. Raw detected secrets are not shown here. Continue only if this project context may be sent to Codex.',
174
174
  sensitiveConfirmRun: 'Run anyway',
175
175
  localSkillsTitle: 'Skills',
176
- codexOverleafSkillsTitle: 'Codex Overleaf skills',
177
176
  codexOverleafSkillsEmpty: 'No Codex Overleaf skills installed.',
178
177
  codexOverleafSkillsDisabled: 'Codex Overleaf skills are disabled for runs.',
179
178
  loadCodexLocalSkills: 'Load local Codex skills',
180
179
  loadCodexOverleafSkills: 'Load Codex Overleaf skills',
181
180
  localSkillRemove: 'Remove',
181
+ localSkillRemoveConfirm: 'Confirm',
182
+ localSkillRemoveCancel: 'Cancel',
183
+ localSkillRemoving: 'Removing…',
184
+ codexOverleafSkillsLoading: 'Loading skills…',
185
+ codexOverleafSkillEnableToggle: 'Enable this skill',
182
186
  codexOverleafSkillRemoveDone: 'Codex Overleaf skill removed.',
187
+ codexOverleafSkillsTitle: 'Codex Overleaf skills',
188
+ codexOverleafSkillsEntry: 'Codex Overleaf skills',
189
+ codexOverleafSkillsSummaryOff: 'Off',
190
+ codexOverleafSkillsSummaryCount: '{count} enabled',
183
191
  slashInstallSkillTitle: 'Install skill',
184
192
  slashInstallSkillSubtitle: 'Use the Codex skill installer with natural language.',
185
193
  slashUseSkillSubtitle: 'Use this skill for the next Codex turn.',
@@ -191,7 +199,8 @@
191
199
  binaryAssetConfirm: 'Write assets',
192
200
  binaryAssetCancel: 'Skip assets',
193
201
  personalizationConfig: 'Personalization',
194
- save: 'Save',
202
+ settingsSaved: 'Saved',
203
+ settingsSaving: 'Saving…',
195
204
  technicalDetails: 'Technical Details',
196
205
  newSession: 'New Session',
197
206
  tasks: 'Tasks',
@@ -414,15 +423,15 @@
414
423
  switchLanguageHint: '切换面板语言',
415
424
  close: '关闭',
416
425
  closeDiagnostics: '关闭诊断结果',
417
- customInstructionsSettings: '自定义指令',
418
- customInstructionsTitle: '自定义指令',
419
- customInstructionsSubtitle: '为当前 Overleaf 项目提供额外指令和上下文。',
420
- customInstructionsLearnMore: '了解更多',
421
- customInstructionsClose: '关闭自定义指令',
426
+ settingsBack: '返回',
427
+ projectSettings: '项目设置',
422
428
  customInstructionsPlaceholder: '写下此项目的风格、术语、会议要求和 LaTeX 约定。',
423
- projectSettingsSavedToast: '项目设置已保存。',
424
429
  projectSettingsTitle: '项目设置',
425
- projectSettingsSubtitle: '当前 Overleaf 项目的治理规则、本地技能和自定义指令。',
430
+ projectSettingsSubtitle: '自定义 Codex 在当前项目和所有项目中的行为。',
431
+ settingsScopeProjectTitle: '当前项目',
432
+ settingsScopeProjectSubtitle: '仅应用于当前 Overleaf 项目的指令和规则。',
433
+ settingsScopeGlobalTitle: '所有项目',
434
+ settingsScopeGlobalSubtitle: '适用于所有 Overleaf 项目的技能加载设置。',
426
435
  governanceRulesTitle: '治理规则',
427
436
  governanceReadonlyPatterns: '只读路径规则',
428
437
  governanceWritablePatterns: '可写路径规则',
@@ -432,13 +441,21 @@
432
441
  sensitiveConfirmMessage: 'Codex 发现了可能的敏感内容。这里不会显示原始密钥或秘密值。只有在确认可以把这些项目上下文发送给 Codex 时才继续。',
433
442
  sensitiveConfirmRun: '仍然运行',
434
443
  localSkillsTitle: '技能',
435
- codexOverleafSkillsTitle: 'Codex Overleaf 专属技能',
436
444
  codexOverleafSkillsEmpty: '没有安装 Codex Overleaf 专属技能。',
437
445
  codexOverleafSkillsDisabled: '运行时已禁用 Codex Overleaf 专属技能。',
438
446
  loadCodexLocalSkills: '加载 Codex 本地技能',
439
447
  loadCodexOverleafSkills: '加载 Codex Overleaf 专属技能',
440
448
  localSkillRemove: '删除',
449
+ localSkillRemoveConfirm: '确认',
450
+ localSkillRemoveCancel: '取消',
451
+ localSkillRemoving: '删除中…',
452
+ codexOverleafSkillsLoading: '正在加载技能…',
453
+ codexOverleafSkillEnableToggle: '启用该技能',
441
454
  codexOverleafSkillRemoveDone: 'Codex Overleaf 技能已删除。',
455
+ codexOverleafSkillsTitle: 'Codex Overleaf 专属技能',
456
+ codexOverleafSkillsEntry: 'Codex Overleaf 专属技能',
457
+ codexOverleafSkillsSummaryOff: '已关闭',
458
+ codexOverleafSkillsSummaryCount: '已启用 {count} 个',
442
459
  slashInstallSkillTitle: '安装 skill',
443
460
  slashInstallSkillSubtitle: '用自然语言调用 Codex 的 skill installer。',
444
461
  slashUseSkillSubtitle: '本轮使用这个 skill。',
@@ -450,7 +467,8 @@
450
467
  binaryAssetConfirm: '写入资源',
451
468
  binaryAssetCancel: '跳过资源',
452
469
  personalizationConfig: '个性化配置',
453
- save: '保存',
470
+ settingsSaved: '已保存',
471
+ settingsSaving: '保存中…',
454
472
  technicalDetails: '技术细节',
455
473
  newSession: '新建会话',
456
474
  tasks: '任务',
@@ -13,8 +13,9 @@
13
13
  'markdown-link-target'
14
14
  ]);
15
15
  const TEXT_EXTENSION_PATTERN = '(?:tex|bib|sty|cls|bst|bbx|cbx|lbx|cfg|def|clo|ist|txt|md|latex)';
16
- const REFERENCE_PREFIX_PATTERN = '(^|[\\s\\[({"\'])';
17
- const PATH_PATTERN = `([^\\s\\[\\](){}<>"'\`,;]+?\\.${TEXT_EXTENSION_PATTERN})`;
16
+ const CJK_PUNCTUATION = '、,;。!?:';
17
+ const REFERENCE_PREFIX_PATTERN = `(^|[\\s\\[({\"',;${CJK_PUNCTUATION}])`;
18
+ const PATH_PATTERN = `([^\\s\\[\\](){}<>"'\`,;${CJK_PUNCTUATION}]+?\\.${TEXT_EXTENSION_PATTERN})`;
18
19
  const BARE_LOCAL_PATH_PATTERN = /(?:file:\/\/\/?[^\s)\]]+|[A-Za-z]:[\\/][^\s)\]]+|\/(?:Users|home|private|var|tmp)\/[^\s)\]]+|[^\s)\]]*[\\/]\.codex-overleaf[\\/]projects[\\/][^\s)\]]+)/gi;
19
20
 
20
21
  function parseLineReferencesFromText({ text, mode }) {
@@ -76,9 +77,6 @@
76
77
  placeholderBrackets: true
77
78
  });
78
79
 
79
- if (context === 'render' || context === 'persist') {
80
- return sanitized;
81
- }
82
80
  return sanitized;
83
81
  }
84
82
 
@@ -460,7 +458,7 @@
460
458
  }
461
459
 
462
460
  function splitTrailingPunctuation(value) {
463
- const match = String(value || '').match(/^(.*?)([.,;!?]+)$/);
461
+ const match = String(value || '').match(/^(.*?)([.,;!?、,;。!?:]+)$/);
464
462
  if (!match) {
465
463
  return { value, trailing: '' };
466
464
  }
@@ -17,6 +17,7 @@
17
17
  autoOpen: true,
18
18
  loadCodexLocalSkills: true,
19
19
  loadCodexOverleafSkills: true,
20
+ codexOverleafSkillEnabled: {},
20
21
  panelWidth: 380,
21
22
  task: '',
22
23
  focusFiles: [],
@@ -105,6 +106,7 @@
105
106
  state.autoOpen = state.autoOpen !== false;
106
107
  state.loadCodexLocalSkills = state.loadCodexLocalSkills !== false;
107
108
  state.loadCodexOverleafSkills = state.loadCodexOverleafSkills !== false;
109
+ state.codexOverleafSkillEnabled = normalizeCodexOverleafSkillEnabled(state.codexOverleafSkillEnabled);
108
110
  state.panelWidth = normalizePanelWidth(state.panelWidth);
109
111
  state.task = typeof state.task === 'string' ? state.task : '';
110
112
  state.model = typeof state.model === 'string' && state.model ? state.model : DEFAULT_PANEL_STATE.model;
@@ -669,6 +671,23 @@
669
671
  return result;
670
672
  }
671
673
 
674
+ function normalizeCodexOverleafSkillEnabled(value) {
675
+ const result = {};
676
+ if (!value || typeof value !== 'object' || Array.isArray(value)) {
677
+ return result;
678
+ }
679
+ for (const key of Object.keys(value)) {
680
+ if (typeof key !== 'string' || !key) {
681
+ continue;
682
+ }
683
+ if (typeof value[key] !== 'boolean') {
684
+ continue;
685
+ }
686
+ result[key] = value[key];
687
+ }
688
+ return result;
689
+ }
690
+
672
691
  function normalizeProjectPrefKey(value) {
673
692
  const key = typeof value === 'string' ? value.trim() : '';
674
693
  if (!key) {
@@ -714,6 +733,7 @@
714
733
  autoOpen: source.autoOpen !== false,
715
734
  loadCodexLocalSkills: source.loadCodexLocalSkills !== false,
716
735
  loadCodexOverleafSkills: source.loadCodexOverleafSkills !== false,
736
+ codexOverleafSkillEnabled: normalizeCodexOverleafSkillEnabled(source.codexOverleafSkillEnabled),
717
737
  panelWidth: normalizePanelWidth(source.panelWidth),
718
738
  task: summarizeTextForStorage(active?.task || source.task || '', 'task'),
719
739
  focusFiles: normalizeFocusFiles(active?.focusFiles || source.focusFiles),
@@ -342,11 +342,31 @@
342
342
  experimentalOtByProject: normalizeBooleanMap(state.experimentalOtByProject),
343
343
  customInstructionsByProject: normalizeStringMap(state.customInstructionsByProject),
344
344
  governanceRulesByProject: normalizeGovernanceRulesMap(state.governanceRulesByProject),
345
- selectedLocalSkillIdsByProject: normalizeStringListMap(state.selectedLocalSkillIdsByProject)
345
+ selectedLocalSkillIdsByProject: normalizeStringListMap(state.selectedLocalSkillIdsByProject),
346
+ codexOverleafSkillEnabled: normalizeCodexOverleafSkillEnabledMap(state.codexOverleafSkillEnabled)
346
347
  };
347
348
  return prefs;
348
349
  }
349
350
 
351
+ function normalizeCodexOverleafSkillEnabledMap(value) {
352
+ var result = {};
353
+ if (!value || typeof value !== 'object' || Array.isArray(value)) {
354
+ return result;
355
+ }
356
+ var keys = Object.keys(value);
357
+ for (var i = 0; i < keys.length; i++) {
358
+ var key = keys[i];
359
+ if (typeof key !== 'string' || !key) {
360
+ continue;
361
+ }
362
+ if (typeof value[key] !== 'boolean') {
363
+ continue;
364
+ }
365
+ result[key] = value[key];
366
+ }
367
+ return result;
368
+ }
369
+
350
370
  function normalizeBooleanMap(value) {
351
371
  var result = {};
352
372
  if (!value || typeof value !== 'object' || Array.isArray(value)) {
@@ -7,25 +7,31 @@ const {
7
7
  getNativeHostPlatform
8
8
  } = require('./nativeHostPlatform');
9
9
  const {
10
+ ensureCodexOverleafSkillInstalled,
10
11
  getCodexOverleafSkillsRoot,
11
- materializeProjectSkillsAsCodexSkills
12
+ materializeProjectSkillsAsCodexSkills,
13
+ OFFICIAL_CODEX_OVERLEAF_SKILL_IDS
12
14
  } = require('./localSkills');
13
15
 
14
16
  const COPIED_USER_CODEX_FILES = [
15
17
  'auth.json',
16
18
  'config.toml',
17
- 'AGENTS.md',
18
19
  'installation_id',
19
20
  'models_cache.json',
20
21
  'version.json'
21
22
  ];
22
23
 
23
24
  const LINKED_USER_CODEX_DIRS = [
24
- 'rules',
25
- 'memories',
26
25
  'vendor_imports'
27
26
  ];
28
27
 
28
+ // User-global Codex instruction/memory entries that must never enter the plugin
29
+ // Codex home. The extension supplies its own per-project personalization via the
30
+ // prompt; inheriting the user's global Codex guidance here is a leak. The plugin
31
+ // home is reused across runs, so these are removed every prepare to also clear
32
+ // entries left by earlier extension versions.
33
+ const ISOLATED_USER_INSTRUCTION_ENTRIES = ['AGENTS.md', 'rules', 'memories'];
34
+
29
35
  const LOCAL_SKILL_USER_CODEX_DIRS = [
30
36
  'plugins',
31
37
  'superpowers'
@@ -93,6 +99,18 @@ function preparePluginCodexHome(env = process.env, options = {}) {
93
99
  copied.push(fileName);
94
100
  }
95
101
 
102
+ // Personalization isolation: the plugin Codex home must never inherit the
103
+ // user's global Codex instructions/memory. Remove them every run — this also
104
+ // clears stale entries left by earlier extension versions. This runs after
105
+ // the samePath early-return above, so it never touches the user's real
106
+ // ~/.codex when the plugin home and user home are the same directory.
107
+ for (const entryName of ISOLATED_USER_INSTRUCTION_ENTRIES) {
108
+ removePluginHomeEntry(pluginHome, entryName, skippedLinks);
109
+ }
110
+ if (!isRegularFile(path.join(userHome, 'config.toml'))) {
111
+ removePluginHomeEntry(pluginHome, 'config.toml', skippedLinks);
112
+ }
113
+
96
114
  if (!loadCodexLocalSkills) {
97
115
  for (const entryName of LOCAL_SKILL_PLUGIN_HOME_ENTRIES) {
98
116
  removePluginHomeEntry(pluginHome, entryName, skippedLinks);
@@ -119,6 +137,8 @@ function preparePluginCodexHome(env = process.env, options = {}) {
119
137
  linked.push(dirName);
120
138
  }
121
139
 
140
+ ensureDefaultCodexOverleafSkills({ env });
141
+
122
142
  const skillsResult = composePluginSkillsDirectory({
123
143
  userHome,
124
144
  pluginHome,
@@ -137,13 +157,68 @@ function preparePluginCodexHome(env = process.env, options = {}) {
137
157
  return { userHome, pluginHome, copied, linked, skippedLinks };
138
158
  }
139
159
 
160
+ function ensureDefaultCodexOverleafSkills({ env = process.env } = {}) {
161
+ for (const id of OFFICIAL_CODEX_OVERLEAF_SKILL_IDS) {
162
+ const src = path.resolve(__dirname, 'skills', id, 'SKILL.md');
163
+ const content = fs.readFileSync(src, 'utf8');
164
+ ensureCodexOverleafSkillInstalled({ skillId: id, content, env });
165
+ }
166
+ }
167
+
140
168
  function copyUserCodexFile(source, target, fileName, options = {}) {
141
- if (fileName !== 'config.toml' || options.loadCodexLocalSkills !== false) {
169
+ if (fileName !== 'config.toml') {
142
170
  fs.copyFileSync(source, target);
143
171
  return;
144
172
  }
145
- const content = fs.readFileSync(source, 'utf8');
146
- fs.writeFileSync(target, sanitizeCodexConfigForLocalSkillIsolation(content), 'utf8');
173
+ let content = stripPersonalizationFromCodexConfig(fs.readFileSync(source, 'utf8'));
174
+ if (options.loadCodexLocalSkills === false) {
175
+ content = sanitizeCodexConfigForLocalSkillIsolation(content);
176
+ }
177
+ fs.writeFileSync(target, content, 'utf8');
178
+ }
179
+
180
+ // Removes the top-level `personality` key (Codex's built-in "personality"
181
+ // feature) so the plugin Codex home never inherits the user's global
182
+ // personalization. Only the top-level key is removed — a `personality` key
183
+ // inside a [section] is a different key and is preserved. Handles single-line
184
+ // values and both multi-line string forms (""" basic and ''' literal). All
185
+ // other lines pass through unchanged, aside from line endings being normalized to LF.
186
+ function stripPersonalizationFromCodexConfig(content) {
187
+ const lines = String(content || '').split(/\r?\n/);
188
+ const output = [];
189
+ let beforeFirstSection = true;
190
+ let closingDelimiter = '';
191
+
192
+ for (const line of lines) {
193
+ if (closingDelimiter) {
194
+ if (line.includes(closingDelimiter)) {
195
+ closingDelimiter = '';
196
+ }
197
+ // Drop every line of the multi-line value, including the one that closes it.
198
+ continue;
199
+ }
200
+ if (parseTomlSectionName(line)) {
201
+ beforeFirstSection = false;
202
+ output.push(line);
203
+ continue;
204
+ }
205
+ if (beforeFirstSection) {
206
+ const match = line.match(/^\s*personality\s*=\s*(.*)$/);
207
+ if (match) {
208
+ const value = match[1];
209
+ const opener = value.startsWith('"""') ? '"""'
210
+ : value.startsWith("'''") ? "'''"
211
+ : '';
212
+ if (opener && value.indexOf(opener, opener.length) === -1) {
213
+ closingDelimiter = opener;
214
+ }
215
+ continue;
216
+ }
217
+ }
218
+ output.push(line);
219
+ }
220
+
221
+ return output.join('\n');
147
222
  }
148
223
 
149
224
  function sanitizeCodexConfigForLocalSkillIsolation(content) {
@@ -532,6 +607,7 @@ module.exports = {
532
607
  buildCodexHomeEnv,
533
608
  clearPluginCodexHistory,
534
609
  composePluginSkillsDirectory,
610
+ ensureDefaultCodexOverleafSkills,
535
611
  getPluginCodexHome,
536
612
  getUserCodexHome,
537
613
  preparePluginCodexHome
@@ -68,6 +68,7 @@ async function runCodexSession({ params = {}, env = process.env, emit = () => {}
68
68
  const codexSkillInvocationContext = loadCodexSkillInvocationContext({
69
69
  skillInvocation,
70
70
  loadCodexOverleafSkills: skillLoading.loadCodexOverleafSkills,
71
+ enabledCodexOverleafSkillIds: params.enabledCodexOverleafSkillIds,
71
72
  env,
72
73
  emit
73
74
  });
@@ -385,6 +386,7 @@ function normalizeSkillLoadingSettings(params = {}) {
385
386
  function loadCodexSkillInvocationContext({
386
387
  skillInvocation,
387
388
  loadCodexOverleafSkills = true,
389
+ enabledCodexOverleafSkillIds,
388
390
  env = process.env,
389
391
  emit = () => {}
390
392
  } = {}) {
@@ -399,6 +401,7 @@ function loadCodexSkillInvocationContext({
399
401
  const result = loadSelectedCodexOverleafSkill({
400
402
  skillId: invocation.id,
401
403
  loadCodexOverleafSkills,
404
+ enabledCodexOverleafSkillIds,
402
405
  env
403
406
  });
404
407
  if (result.missing.length) {
@@ -13,6 +13,7 @@ const MAX_SKILL_CONTENT_CHARS = MAX_SKILL_CONTENT_BYTES;
13
13
  const MAX_SKILL_PREVIEW_CHARS = 240;
14
14
  const PROJECT_SKILL_SCOPE = 'project';
15
15
  const CODEX_OVERLEAF_SKILL_SCOPE = 'codex-overleaf';
16
+ const OFFICIAL_CODEX_OVERLEAF_SKILL_IDS = ['annotated-rewrite'];
16
17
 
17
18
  function listProjectSkills({ projectId, rootDir } = {}) {
18
19
  const skillsDir = getProjectSkillsDir(projectId, { rootDir });
@@ -110,13 +111,18 @@ function listCodexOverleafSkills({ env = process.env, skillsRoot } = {}) {
110
111
  continue;
111
112
  }
112
113
  const content = fs.readFileSync(filePath, 'utf8');
113
- skills.push(buildSkillMetadata({
114
- id: entry.name,
115
- content,
116
- size: stat.size,
117
- updatedAt: stat.mtime.toISOString(),
118
- scope: CODEX_OVERLEAF_SKILL_SCOPE
119
- }));
114
+ const isOfficial = OFFICIAL_CODEX_OVERLEAF_SKILL_IDS.includes(entry.name);
115
+ skills.push({
116
+ ...buildSkillMetadata({
117
+ id: entry.name,
118
+ content,
119
+ size: stat.size,
120
+ updatedAt: stat.mtime.toISOString(),
121
+ scope: CODEX_OVERLEAF_SKILL_SCOPE
122
+ }),
123
+ official: isOfficial,
124
+ removable: !isOfficial
125
+ });
120
126
  }
121
127
 
122
128
  return { skills: skills.sort((left, right) => left.id.localeCompare(right.id)) };
@@ -147,6 +153,9 @@ function installCodexOverleafSkill({ skillId, content, env = process.env, skills
147
153
 
148
154
  function removeCodexOverleafSkill({ skillId, env = process.env, skillsRoot } = {}) {
149
155
  const id = validateSkillId(skillId);
156
+ if (OFFICIAL_CODEX_OVERLEAF_SKILL_IDS.includes(id)) {
157
+ throw new Error(`Cannot remove official skill: ${id}`);
158
+ }
150
159
  const root = getCodexOverleafSkillsRoot({ env, skillsRoot });
151
160
  const skillDir = resolveInside(root, id, 'Unsafe Codex Overleaf skill path');
152
161
  const removed = fs.existsSync(skillDir);
@@ -156,6 +165,21 @@ function removeCodexOverleafSkill({ skillId, env = process.env, skillsRoot } = {
156
165
  return { id, scope: CODEX_OVERLEAF_SKILL_SCOPE, removed };
157
166
  }
158
167
 
168
+ function ensureCodexOverleafSkillInstalled({ skillId, content, env = process.env } = {}) {
169
+ const root = getCodexOverleafSkillsRoot({ env });
170
+ const skillPath = resolveCodexOverleafSkillPath(skillId, { env });
171
+ if (fs.existsSync(skillPath)) {
172
+ assertNoSymlinkEscape(skillPath, root, 'Existing official skill path is unsafe');
173
+ const stat = fs.lstatSync(skillPath);
174
+ if (stat.isFile()) {
175
+ return;
176
+ }
177
+ // symlink, directory, or other — remove and reinstall
178
+ fs.rmSync(skillPath, { recursive: true, force: true });
179
+ }
180
+ installCodexOverleafSkill({ skillId, content, env });
181
+ }
182
+
159
183
  function loadSelectedProjectSkills({ projectId, selectedSkillIds, rootDir, projectRoot } = {}) {
160
184
  const ids = normalizeSelectedSkillIds(selectedSkillIds);
161
185
  const skills = [];
@@ -230,6 +254,7 @@ function materializeProjectSkillsAsCodexSkills({
230
254
  function loadSelectedCodexOverleafSkill({
231
255
  skillId,
232
256
  loadCodexOverleafSkills = true,
257
+ enabledCodexOverleafSkillIds,
233
258
  env = process.env,
234
259
  skillsRoot
235
260
  } = {}) {
@@ -248,6 +273,18 @@ function loadSelectedCodexOverleafSkill({
248
273
  }]
249
274
  };
250
275
  }
276
+ // Per-skill enable check: if enabledCodexOverleafSkillIds is provided and does not include
277
+ // this skill, treat it as not available. Absent param = all enabled (backward-safe).
278
+ if (Array.isArray(enabledCodexOverleafSkillIds) && !enabledCodexOverleafSkillIds.includes(id)) {
279
+ return {
280
+ skill: null,
281
+ missing: [],
282
+ ignored: [{
283
+ id,
284
+ reason: 'codex_overleaf_skill_disabled'
285
+ }]
286
+ };
287
+ }
251
288
 
252
289
  const filePath = resolveCodexOverleafSkillPath(id, { env, skillsRoot });
253
290
  if (!fs.existsSync(filePath)) {
@@ -461,7 +498,9 @@ module.exports = {
461
498
  CODEX_OVERLEAF_SKILL_SCOPE,
462
499
  MAX_SKILL_CONTENT_BYTES,
463
500
  MAX_SKILL_CONTENT_CHARS,
501
+ OFFICIAL_CODEX_OVERLEAF_SKILL_IDS,
464
502
  PROJECT_SKILL_SCOPE,
503
+ ensureCodexOverleafSkillInstalled,
465
504
  getDefaultCodexOverleafSkillsRoot,
466
505
  getCodexOverleafSkillsRoot,
467
506
  installCodexOverleafSkill,
@@ -0,0 +1,71 @@
1
+ ---
2
+ name: annotated-rewrite
3
+ description: >
4
+ When editing `.tex` files, use this skill as often as possible. When
5
+ rewriting `.tex` content spanning more than a few words, comment out the
6
+ original and write the replacement below it so the user can review the
7
+ before/after diff directly in the source.
8
+ ---
9
+
10
+ # Annotated Rewrite
11
+
12
+ When rewriting `.tex` file content (paragraphs, sentences, equations, list
13
+ bodies, or any block larger than a few words), preserve the original by
14
+ commenting it out rather than deleting it, then write the replacement below.
15
+ This lets the user review exactly what changed before accepting the edit.
16
+
17
+ ## When to apply
18
+
19
+ Default to this pattern whenever the replaced content is **more than a short inline phrase** (see the word-level exception below), regardless of content type — prose, equations, lists, environment bodies, or any contiguous block. Use it as often as possible — when in doubt, use it.
20
+
21
+ A useful guide: if the replaced content is **3 or more source lines**, always apply it. For shorter replacements (1-2 source lines), lean toward applying it unless the change is purely **word-level**: replacing a single word, fixing a typo, or changing a run of 1-5 words within an unbroken clause.
22
+
23
+ Word-level edits are the only case where skipping the annotated format is clearly appropriate (subject to the structural exceptions in Rule 8).
24
+
25
+ ## Edit format
26
+
27
+ ```tex
28
+ % [original]
29
+ % The proposed method encodes user history as a fixed-length vector,
30
+ % then applies a linear projection before computing dot-product scores.
31
+ % Training uses binary cross-entropy loss over sampled negatives.
32
+ %
33
+ % \begin{equation}
34
+ % \hat{y}_{ui} = \mathbf{u}_i^\top \mathbf{v}_j
35
+ % \end{equation}
36
+
37
+ % [revised]
38
+ We encode user history with a transformer encoder, producing a
39
+ context-aware representation that is projected into the item space.
40
+ Training minimises a softmax loss over in-batch negatives.
41
+
42
+ \begin{equation}
43
+ \hat{y}_{ui} = \mathrm{softmax}(\mathbf{U}\mathbf{V}^\top)_{ij}
44
+ \end{equation}
45
+ ```
46
+
47
+ ## Rules
48
+
49
+ 1. Copy the original lines **verbatim** into the comment block — do not alter them
50
+ 2. Include every line of the replaced content verbatim with `%` prepended;
51
+ blank lines within the block become `%` empty-comment lines (a line
52
+ containing only `%`). Include `\begin{...}` / `\end{...}` markers only when
53
+ they are part of the replaced content — do not comment out enclosing
54
+ environment markers that are not themselves changing
55
+ 3. No blank line between `% [original]` and the first commented line
56
+ 4. One blank line between the last commented line and `% [revised]`; one blank
57
+ line before `% [original]` and after the last line of the replacement (to
58
+ separate the annotated construct from surrounding document text)
59
+ 5. The new content after `% [revised]` is normal LaTeX (not commented)
60
+ 6. For multiple non-adjacent replaced blocks, apply the pattern independently
61
+ to each block
62
+ 7. **Idempotency**: if the content being edited already contains a
63
+ `% [original]` / `% [revised]` block, edit only the active content after
64
+ `% [revised]` — do not re-wrap the existing annotated block or create a new
65
+ outer annotation around it
66
+ 8. **Structure safety**: only apply this pattern at **block level** (paragraph,
67
+ sentence, equation block, list body, or environment body). Do NOT insert
68
+ `% [original]` / `% [revised]` inside
69
+ macro arguments, table rows, math expressions, `\caption{...}`,
70
+ `\item[...]`, or preamble commands — make minimal direct edits there instead,
71
+ or ask for confirmation before changing structurally sensitive content
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "codex-overleaf-link",
3
- "version": "1.3.0",
3
+ "version": "1.3.5",
4
4
  "description": "Cross-platform Chrome bridge that connects Codex to the active Overleaf project.",
5
5
  "license": "MIT",
6
6
  "type": "commonjs",