Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -415,6 +415,10 @@ Sum of the table: **1061**. Zero leftover.

`phase100-native-parity.test.ts`

#### `tests/chatgpt-unblock/` (1)

`rewrite.test.ts`

## 3. Cross-cutting coupling

### 3.A tests/helpers imported by how many tests (unique files)
Expand Down
1 change: 1 addition & 0 deletions docs-site/astro.config.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -100,6 +100,7 @@ export default defineConfig({
{ label: "Native Context Compatibility", translations: { ko: "네이티브 컨텍스트 호환성", fr: "Compatibilité du contexte natif", "zh-CN": "原生上下文兼容性", "zh-TW": "原生脈絡相容性", ru: "Совместимость с нативным контекстом", ja: "ネイティブコンテキストの互換性", tr: "Yerel bağlam uyumluluğu" }, slug: "guides/codex-native-context" },
{ label: "macOS Menu Bar App", translations: { fr: "Application barre de menus macOS", ko: "macOS 메뉴바 앱", "zh-CN": "macOS 菜单栏应用", "zh-TW": "macOS 選單列 App", ru: "Приложение в строке меню macOS", ja: "macOS メニューバーアプリ", tr: "macOS Menü Çubuğu Uygulaması" }, slug: "guides/macos-menu-bar" },
{ label: "Desktop App", translations: { fr: "Application de bureau", ko: "데스크톱 앱", "zh-CN": "桌面应用", "zh-TW": "桌面 App", ru: "Настольное приложение", ja: "デスクトップアプリ", tr: "Masaüstü Uygulaması" }, slug: "guides/desktop-app" },
{ label: "ChatGPT Desktop Send Unblock", translations: { fr: "Déblocage de l'envoi dans ChatGPT Desktop", ko: "ChatGPT 데스크톱 전송 잠금 해제", "zh-CN": "ChatGPT 桌面版发送键解锁", "zh-TW": "ChatGPT 桌面版傳送鍵解鎖", ru: "Разблокировка отправки в ChatGPT Desktop", ja: "ChatGPT デスクトップの送信ロック解除", tr: "ChatGPT Masaüstü Gönderme Kilidini Açma" }, slug: "guides/chatgpt-desktop" },
{ label: "Model Ordering", translations: { fr: "Ordre des modèles", ko: "모델 정렬에 관하여", "zh-CN": "模型排序", "zh-TW": "模型排序", ru: "Сортировка моделей", ja: "モデルの並び順", tr: "Model Sıralaması" }, slug: "guides/model-ordering" },
{ label: "Combos", translations: { fr: "Combinaisons", ko: "콤보", "zh-CN": "组合", "zh-TW": "組合", ru: "Комбо", ja: "コンボ", tr: "Kombolar" }, slug: "guides/combos" },
{ label: "Protocol Paths", translations: { fr: "Chemins de protocole", ko: "프로토콜 경로", "zh-CN": "协议路径", "zh-TW": "協定路徑", ru: "Пути протоколов", ja: "プロトコル経路", tr: "Protokol Yolları" }, slug: "guides/protocol-paths" },
Expand Down
146 changes: 146 additions & 0 deletions docs-site/src/content/docs/fr/guides/chatgpt-desktop.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,146 @@
---
title: Déblocage de l'envoi dans ChatGPT Desktop
description: Garder utilisable la zone de saisie de l'application ChatGPT de bureau quand le quota d'utilisation du compte est épuisé (macOS, sur activation).
---

Quand le compte ChatGPT connecté épuise son quota d'utilisation, l'application de bureau ChatGPT
grise son bouton d'envoi, même pour les conversations dont opencodex route les appels de modèle vers
d'autres fournisseurs. Cette intégration macOS, à activer explicitement, garde la zone de saisie
utilisable. Elle est désactivée par défaut.

## Ce qu'elle modifie

opencodex exécute un écouteur TLS local pour `chatgpt.com`. L'application est lancée avec une option
Chromium qui envoie `chatgpt.com` vers cet écouteur ; tous les autres hôtes, sous-domaines compris,
gardent leur route habituelle. Les requêtes sont relayées vers le vrai `chatgpt.com` avec les
identifiants de l'application, et les WebSockets (comme la dictée vocale) sont relayés aussi. Rien
n'est journalisé ni stocké.

Les réponses passent sans modification, sauf pour deux points de terminaison :

- les métadonnées de conversation (`/backend-api/conversation/init` et le flux de conversation) : les
verrous d'envoi dus au quota d'utilisation sont retirés ;
- l'instantané d'utilisation (`/backend-api/wham/usage`) : la barrière « limite atteinte » est ouverte.

Les verrous d'envoi ayant une autre raison, comme un abonnement requis, sont conservés et listés par
`ocx chatgpt status`. L'utilisation affichée (pourcentages, heures de réinitialisation, bannières)
n'est jamais modifiée, et les serveurs d'OpenAI appliquent toujours toutes les limites à leurs propres
requêtes.

## Configuration

1. Activez la fonctionnalité dans `~/.opencodex/config.json` puis redémarrez opencodex :

```json
{ "chatgptDesktop": { "unblockSend": true } }
```

L'écouteur utilise le port du proxy plus 200 (`10300` par défaut). Définissez
`chatgptDesktop.port` pour choisir un autre port.

2. Faites confiance une fois à l'autorité de certification locale. La commande demande votre mot de
passe de session ; exécutez-la vous-même :

```bash
security add-trusted-cert -r trustRoot -p ssl \
-k ~/Library/Keychains/login.keychain-db ~/.opencodex/claude-intercept/ca.pem
```

Sans cette confiance, l'application ne peut pas charger les pages de compte, d'utilisation ni de
réglages. Si vous utilisez un répertoire opencodex personnalisé, `ocx chatgpt status` affiche la
commande exacte pour votre configuration.

3. Lancez l'application via opencodex :

```bash
ocx chatgpt launch
```

4. Facultatif : faire utiliser la route aussi aux lancements normaux depuis le Dock ou Spotlight :

```bash
ocx chatgpt install-watcher
```

Le surveillant s'exécute à chaque démarrage de l'application. Si l'application a été ouverte
normalement pendant qu'opencodex tourne, il la quitte juste après son lancement et la rouvre avec
la route. Il n'agit jamais sur une application déjà en cours d'utilisation et ne fait rien quand
opencodex ne tourne pas. La commande demande une confirmation ; `--yes` confirme sans interaction.

## Configurations réseau

Aucune règle de VPN ou de proxy n'est nécessaire. En mode par défaut, les arguments de lancement sont
choisis d'après le proxy système à chaque démarrage de l'application :

| Configuration | Arguments de lancement de l'application |
|---|---|
| Sans proxy | La route `chatgpt.com` seule. |
| VPN en mode proxy système | La route, le proxy système avec repli direct, et un contournement pour `chatgpt.com` seulement. |
| VPN en mode TUN | La route seule ; le trafic de boucle locale n'entre jamais dans le tunnel. |
| Fichier PAC | La route seule. Le fichier PAC peut laisser `chatgpt.com` sur le proxy, la zone de saisie peut donc rester verrouillée, mais rien d'autre ne casse. |

opencodex joint le vrai `chatgpt.com` via son propre réglage `proxy`, comme tout son autre trafic
sortant.

## Garder l'application utilisable quand opencodex s'arrête

En mode par défaut, une application routée dépend de l'écouteur : tant qu'opencodex est arrêté, ses
requêtes vers `chatgpt.com` échouent. Le repli PAC lance plutôt l'application avec un fichier PAC
généré, pour qu'elle se replie d'elle-même :

```json
{ "chatgptDesktop": { "unblockSend": true, "pacFallback": true } }
```

`pacFallback` n'a d'effet qu'avec `unblockSend`. opencodex écoute alors aussi sur le port de
l'écouteur plus un (`10301` par défaut) et réécrit `chatgpt-unblock.pac` dans son répertoire à chaque
démarrage. Le PAC envoie `chatgpt.com` d'abord vers opencodex, et tous les autres hôtes selon le
routage du système :

| Configuration | Autres hôtes, et `chatgpt.com` tant qu'opencodex est arrêté |
|---|---|
| Aucun proxy, ou VPN en mode TUN | Direct. |
| VPN en mode proxy système | Le proxy système, puis direct. |
| Fichier PAC | Le PAC système, intégré au fichier généré. |

Quand opencodex s'arrête, l'application continue de fonctionner par ce chemin, sans redémarrage ;
seul le déblocage de l'envoi est suspendu jusqu'au retour d'opencodex. Le routage est capturé au
démarrage d'opencodex : après un changement de mode du VPN, redémarrez opencodex et lancez
`ocx chatgpt launch`. Si un PAC système est configuré mais illisible à ce moment, les autres hôtes
passent en direct et opencodex affiche un avertissement.

Après avoir activé ou désactivé `pacFallback`, redémarrez opencodex, lancez `ocx chatgpt launch`, et
relancez `ocx chatgpt install-watcher` si vous utilisez le surveillant.

## Vérifier l'état

```bash
ocx chatgpt status
```

La commande indique si la fonctionnalité est active, si l'écouteur du port est celui d'opencodex, si
le certificat est de confiance, l'état du surveillant, si l'application en cours porte la route, et
les verrous d'envoi conservés volontairement.

## Désactiver

```bash
ocx chatgpt uninstall-watcher
ocx chatgpt restore
```

`restore` rouvre une application routée avec le réseau natif. Réglez ensuite
`chatgptDesktop.unblockSend` sur `false` et redémarrez opencodex. L'autorité de certification est
partagée avec les intégrations Claude d'opencodex ; ne retirez sa confiance que si vous n'utilisez
ni l'une ni l'autre.

## Dépannage

- **Les pages de compte, d'utilisation ou de réglages ne se chargent pas :** le certificat n'est pas
de confiance. Refaites l'étape 2 ; `ocx chatgpt status` affiche l'état de confiance.
- **Le bouton d'envoi reste grisé :** consultez `ocx chatgpt status`. L'application tourne peut-être
sans la route (lancez `ocx chatgpt launch`), ou le verrou a une raison autre que le quota
d'utilisation, listée sous « send blocks kept ».
- **L'application ne charge plus rien après l'arrêt d'opencodex :** en mode par défaut, une
application routée dépend de l'écouteur. Redémarrez opencodex ou lancez `ocx chatgpt restore`, ou
activez le repli PAC pour que l'application se replie d'elle-même.
141 changes: 141 additions & 0 deletions docs-site/src/content/docs/guides/chatgpt-desktop.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,141 @@
---
title: ChatGPT Desktop Send Unblock
description: Keep the ChatGPT desktop app's composer usable when the account's usage quota runs out (macOS, opt-in).
---

When the logged-in ChatGPT account runs out of usage quota, the ChatGPT desktop app greys out
its send button, even for conversations whose model calls opencodex routes to other providers.
This opt-in macOS integration keeps the composer usable. It is off by default.

## What it changes

opencodex runs a local TLS listener for `chatgpt.com`. The app is launched with a Chromium
switch that sends `chatgpt.com` to that listener; every other host, including its subdomains,
keeps its normal route. Requests are relayed to the real `chatgpt.com` with the app's own
credentials, and WebSockets (such as voice dictation) are relayed as well. Nothing is logged or
stored.

Responses are passed through unchanged except for two endpoints:

- conversation metadata (`/backend-api/conversation/init` and the conversation stream): send
locks caused by usage quota are removed;
- the usage snapshot (`/backend-api/wham/usage`): the "limit reached" gate is opened.

Send locks with any other reason, such as a subscription requirement, are kept, and
`ocx chatgpt status` lists them. Displayed usage (percentages, reset times, banners) is never
changed, and OpenAI's servers still enforce every limit on their own requests.

## Setup

1. Enable the feature in `~/.opencodex/config.json` and restart opencodex:

```json
{ "chatgptDesktop": { "unblockSend": true } }
```

The listener uses the proxy port plus 200 (`10300` by default). Set
`chatgptDesktop.port` to choose another port.

2. Trust the local certificate authority once. The command asks for your login password, so
run it yourself:

```bash
security add-trusted-cert -r trustRoot -p ssl \
-k ~/Library/Keychains/login.keychain-db ~/.opencodex/claude-intercept/ca.pem
```

Without this trust the app cannot load account, usage or settings pages. If you use a
custom opencodex home, `ocx chatgpt status` prints the exact command for your setup.

3. Launch the app through opencodex:

```bash
ocx chatgpt launch
```

4. Optional: make normal Dock and Spotlight launches use the route too:

```bash
ocx chatgpt install-watcher
```

The watcher runs each time the app starts. If the app was opened normally while opencodex
is running, it quits the app right after launch and reopens it with the route. It never acts
on an app that is already in use, and does nothing while opencodex is not running. The
command asks for confirmation; `--yes` confirms non-interactively.

## Network setups

No VPN or proxy rules are needed. In the default mode the launch arguments are chosen from the
system proxy each time the app starts:

| Setup | What the app is launched with |
|---|---|
| No proxy | The `chatgpt.com` route only. |
| VPN in system-proxy mode | The route, the system proxy with a direct fallback, and a bypass for `chatgpt.com` only. |
| VPN in TUN mode | The route only; loopback traffic never enters the tunnel. |
| PAC file | The route only. The PAC file may keep `chatgpt.com` on the proxy, so the composer can stay locked, but nothing else breaks. |

opencodex reaches the real `chatgpt.com` through its own `proxy` setting, like all its other
outbound traffic.

## Keep the app working when opencodex stops

In the default mode a routed app depends on the listener: while opencodex is stopped, its
`chatgpt.com` requests fail. PAC fallback launches the app with a generated PAC file instead, so
the app falls back on its own:

```json
{ "chatgptDesktop": { "unblockSend": true, "pacFallback": true } }
```

`pacFallback` only takes effect together with `unblockSend`. opencodex then also listens on the
listener port plus one (`10301` by default) and rewrites `chatgpt-unblock.pac` in its home
directory at every start. The PAC sends `chatgpt.com` to opencodex first, and every other host
the way the system routes it:

| Setup | Other hosts, and `chatgpt.com` while opencodex is stopped |
|---|---|
| No proxy, or VPN in TUN mode | Direct. |
| VPN in system-proxy mode | The system proxy, then direct. |
| PAC file | The system PAC, embedded in the generated file. |

When opencodex stops, the app keeps working on that route without a restart; only the send
unblock pauses until opencodex is back. The route is captured when opencodex starts: after
changing the VPN mode, restart opencodex and run `ocx chatgpt launch`. If a system PAC is set but
cannot be read at that moment, other hosts go direct and opencodex prints a warning.

After turning `pacFallback` on or off, restart opencodex, run `ocx chatgpt launch`, and run
`ocx chatgpt install-watcher` again if you use the watcher.

## Check the state

```bash
ocx chatgpt status
```

It reports whether the feature is on, whether the listener on the port is opencodex's, whether
the certificate is trusted, the watcher state, whether the running app carries the route, and
any send locks that were kept on purpose.

## Turn it off

```bash
ocx chatgpt uninstall-watcher
ocx chatgpt restore
```

`restore` reopens a routed app with native networking. Then set
`chatgptDesktop.unblockSend` to `false` and restart opencodex. The certificate authority is
shared with opencodex's Claude integrations; remove its trust only if you use neither.

## Troubleshooting

- **Account, usage or settings pages do not load:** the certificate is not trusted. Run
step 2 again; `ocx chatgpt status` shows the trust state.
- **The send button is still grey:** check `ocx chatgpt status`. The app may be running
without the route (run `ocx chatgpt launch`), or the lock may have a reason other than usage
quota, which is listed under "send blocks kept".
- **The app cannot load anything after opencodex stops:** in the default mode a routed app
depends on the listener. Start opencodex again or run `ocx chatgpt restore`, or turn on
PAC fallback so the app falls back on its own.
Loading
Loading