Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
15 commits
Select commit Hold shift + click to select a range
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
18 changes: 18 additions & 0 deletions desktop/src-tauri/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -242,6 +242,19 @@ pub fn run() {
// to the loopback dashboard by `capabilities/dashboard-zoom.json`.
.zoom_hotkeys_enabled(true)
.on_navigation(window::navigation_allowed(app.handle().clone()))
// A hidden window still loads pages: wry builds this one with WebView2
// IsVisible=false, and the bootstrap page navigates to the dashboard URL
// afterwards, so the eval that a later show or hide would rely on has nowhere
// to land during a reload. Re-sending the current state here is what keeps the
// GUI's answer correct across navigation.
.on_page_load(|window, payload| {
if matches!(payload.event(), tauri::webview::PageLoadEvent::Finished) {
window::report_visibility(
&window,
window.is_visible().unwrap_or(false),
);
}
})
.build()?;
window::configure(&window);
if startup::LaunchOrigin::detect() == startup::LaunchOrigin::User {
Expand All @@ -260,6 +273,11 @@ pub fn run() {
.build(tauri::generate_context!())
.expect("error while building OpenCodex desktop shell")
.run(|app, event| {
// Dock/Finder reopening an existing macOS app does not launch a second instance.
#[cfg(target_os = "macos")]
if let tauri::RunEvent::Reopen { .. } = event {
show_dashboard(app.clone());
}
// Window close and the platform quit gesture arrive here as an exit request, and until
// this handler existed they went straight through to a SIGKILL of the runtime. D2 makes
// them hide; only the tray's Quit, and an update's coordinated restart, get past.
Expand Down
23 changes: 23 additions & 0 deletions desktop/src-tauri/src/window.rs
Original file line number Diff line number Diff line change
Expand Up @@ -79,14 +79,37 @@ fn is_app_origin(url: &Url) -> bool {
pub fn show(window: &WebviewWindow) {
let _ = window.show();
let _ = window.set_focus();
report_visibility(window, true);
apply_tray_policy(window.app_handle(), true);
}

pub fn hide(window: &WebviewWindow) {
let _ = window.hide();
report_visibility(window, false);
apply_tray_policy(window.app_handle(), false);
}

/// Tell the main window's page whether its host window is visible.
///
/// Windows WebView2 does not flip `document.visibilityState` when the host window is hidden
/// (tauri issues #10592 and #6864), so the dashboard's pollers keep running while the app sits in
/// the tray; macOS WKWebView does flip it. Publishing the host's own answer gives the GUI one
/// signal on every platform instead of one that is correct on only some of them.
///
/// Only the `main` window publishes: `exit::hide_windows` hides every window through `hide`,
/// and the tray popup carries its own equivalent bridge, so an unguarded report would claim the
/// dashboard was hidden because a popup was. A page that has not loaded yet simply misses the eval;
/// the page-load hook re-sends the current state.
pub fn report_visibility(window: &WebviewWindow, visible: bool) {
if window.label() != "main" {
return;
}
let script = format!(
"window.__OPENCODEX_HOST_VISIBLE__ = {visible}; window.dispatchEvent(new CustomEvent('opencodex:host-visibility', {{detail: {visible}}}));"
);
let _ = window.eval(script);
}

#[cfg(target_os = "macos")]
fn apply_tray_policy(app: &AppHandle, visible: bool) {
let policy = if visible {
Expand Down
2 changes: 2 additions & 0 deletions docs-site/src/content/docs/fr/guides/desktop-app.md
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,8 @@ L’application demande à son CLI intégré d’exécuter `ocx resolve --json`

Utilisez l’action **Open dashboard** ou **Open in browser** de la zone de notification pour passer du tableau de bord intégré à votre navigateur habituel. Le menu permet aussi de rechercher les mises à jour.

Sur macOS, fermer le tableau de bord laisse l’application active dans la barre des menus. Ouvrez à nouveau OpenCodex depuis le Dock ou le Finder pour réafficher le tableau de bord sans redémarrer le proxy.

## Utilisation dans la zone de notification

Sur macOS et Windows, cliquez sur l’icône pour ouvrir un panneau compact d’utilisation. L’action **Show usage** l’ouvre également, notamment sous Linux lorsque la zone de notification ne transmet pas les clics. Sous Linux, le tableau de bord s’ouvre au démarrage, même si l’environnement de bureau n’affiche pas d’icône.
Expand Down
2 changes: 2 additions & 0 deletions docs-site/src/content/docs/fr/guides/integrations.md
Original file line number Diff line number Diff line change
Expand Up @@ -134,6 +134,8 @@ Kimi Code, gjc, MiniMax Code et Raycast — documents YAML, JSON5 et TOML rééc
d'opencodex ont été modifiées, le commutateur se verrouille et la désactivation est refusée plutôt que de
deviner quelles modifications vous appartiennent.

Exception pour Hermes : l'ajout de `session_affinity_header: session-id` seul dans un bloc déjà géré peut être adopté via **Apply** ; toute autre modification d'un champ géré reste un conflit. Jusqu'à cette application, l'actualisation automatique de la liste des modèles est également suspendue. Le réglage concerne tous les modèles du provider et nécessite une version de Hermes qui le prend en charge ; il ne garantit aucun taux de succès du cache. Voir le [guide de mise à niveau en anglais](/guides/integrations/#hermes-session-affinity).

## Prévisualiser et confirmer les modifications

Appliquer, Remplacer, Désactiver et Restaurer commencent désormais par un aperçu. La boîte de dialogue
Expand Down
10 changes: 10 additions & 0 deletions docs-site/src/content/docs/fr/guides/sidecars.md
Original file line number Diff line number Diff line change
Expand Up @@ -164,6 +164,16 @@ le délai d'attente et la limite précédemment choisis.
les clés omises inchangées. `timeoutMs` utilise les limites entières de l'environnement d'exécution
(1–2147483647 ms).

La carte du service auxiliaire de recherche web reprend la même forme de contrôle : la première
ligne du sélecteur de modèle est **Désactivé (Off)**. La désactivation arrête l'interception de
`web_search` par OpenCodex et l'intégration Codex écrit `web_search = "disabled"` dans
`~/.codex/config.toml`, car Codex continue sinon d'annoncer son propre outil hébergé
`web_search` natif, ce qu'il faut lorsqu'un serveur de recherche MCP doit être le seul chemin
de recherche. La réactivation supprime cette ligne et rétablit la ligne racine `web_search`
écrite par l'opérateur, enregistrée dans le journal Codex. L'écriture exige un
`~/.codex/config.toml` géré (`ocx sync`) ; la carte du tableau de bord vous avertit
lorsqu'elle n'a pas eu lieu et `ocx agent sidecar web --enabled off` indique si elle a réussi.

Vous pouvez toujours définir `enabled: false` dans `config.json` si vous préférez modifier le
fichier directement. La recherche et la description d'images avec OAuth Anthropic réutilisent les identifiants
Claude Code existants du magasin d'empreintes précédent. Testez néanmoins ce comportement avec le
Expand Down
19 changes: 19 additions & 0 deletions docs-site/src/content/docs/fr/guides/web-dashboard.md
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,25 @@ remplissage automatique. Le tableau de bord lui-même ne conserve le jeton qu'en
dans `localStorage` ni dans `sessionStorage` ; son enregistrement dépend entièrement du navigateur ou du
gestionnaire de mots de passe.

## Barre de résumé des quotas

Une ligne de résumé en haut de chaque page, sauf la page Sécurité au démarrage, indique
l'utilisation actuelle des quotas de chaque fournisseur, par exemple
`OpenAI 31% | Claude 54% | xAI 12% | Google 8%`. Elle lit les mêmes rapports de quotas que l'espace
fournisseur (`GET /api/provider-quotas`, toutes les 60 secondes tant que l'onglet est visible) et ne
force jamais d'actualisation en amont.

- Chaque étiquette affiche la fenêtre signalée prioritaire : d'abord hebdomadaire, puis mensuelle,
puis 5 heures, puis une fenêtre nommée par le fournisseur ou des crédits prépayés.
- Une étiquette passe en ambre à 70 % d'utilisation et en rouge à 90 %.
- Survolez une étiquette ou cliquez dessus pour voir toutes les fenêtres signalées avec leur heure de
réinitialisation et l'heure de la lecture. Appuyez sur Échap ou cliquez ailleurs pour fermer une
étiquette épinglée.
- Les fournisseurs qui ne signalent aucune fenêtre de quota sont omis. La barre est masquée quand
aucun fournisseur n'en signale.
- Le bord droit indique quand le tableau de bord a lu les rapports pour la dernière fois. Il passe en
ambre lorsque la dernière lecture a échoué et que la lecture précédente est encore affichée.

## Fonctions disponibles

| Zone | Fonction |
Expand Down
10 changes: 10 additions & 0 deletions docs-site/src/content/docs/fr/reference/cli/agents.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,18 @@ les modes de surface, la délégation, l'effort et le comportement de repli s'em

```bash
ocx agent subagents set ark/model-a,openai/gpt-5.5
ocx agent sidecar web --enabled off
```

`--enabled off` est le même interrupteur que la ligne **Désactivé (Off)** du tableau de bord :
OpenCodex cesse d'exécuter le service auxiliaire et l'intégration Codex écrit
`web_search = "disabled"` dans `~/.codex/config.toml`, ce qui permet à un serveur de
recherche MCP d'être le seul chemin de recherche. `--enabled on` supprime à nouveau cette ligne.
Lorsque l'enregistrement déplace réellement l'interrupteur, la commande signale l'écriture côté Codex
qu'elle a déclenchée (`codexWebSearch` avec `--json`, une ligne `Codex config:`
sinon) et renvoie vers `ocx sync` quand elle n'a pas pu avoir lieu. L'option fonctionne aussi
pour `vision`.

### `ocx v2 <status|on|off|mode <v1|default|v2>|threads <n>|mode-hint <text|--clear>>`

Gérez l'indicateur de fonctionnalité Codex `multi_agent_v2` et le mode surface multi-agents à trois états.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -221,7 +221,7 @@ l'API Images d'OpenAI et la forme de réponse attendue par Codex.

| Champ | Type | Par défaut | Signification |
| --- | --- | --- | --- |
| `enabled?` | `boolean` | activé lorsqu'il est utilisable | Interrupteur principal. |
| `enabled?` | `boolean` | activé lorsqu'il est utilisable | Interrupteur principal. Avec `false`, OpenCodex cesse d'intercepter `web_search` et l'intégration Codex écrit `web_search = "disabled"` dans `~/.codex/config.toml`. |
| `backend?` | `"openai" \| "anthropic" \| "xai" \| "gemini" \| "exa"` | `openai` | Une valeur explicite est prioritaire ; l'absence de valeur sélectionne toujours `openai`. `anthropic` et `xai` ne s'exécutent que s'ils sont configurés explicitement ; `gemini` et `exa` restent réservés jusqu'à la livraison de leur executor. |
| `model?` | `string` | dépendant du backend | `gpt-5.6-luna` pour OpenAI, `claude-sonnet-5` pour Anthropic ou `grok-4.6` pour xAI. L'héritage explicite `gpt-5.4-mini` migre au démarrage. |
| `exaApiKey?` | `string` | aucun | Clé opérateur pour le backend `exa`. Écriture seule : les lectures de gestion ne renvoient jamais la valeur stockée. |
Expand Down
2 changes: 2 additions & 0 deletions docs-site/src/content/docs/guides/desktop-app.md
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,8 @@ it from the tray or launch the app again.
Use the tray's **Open dashboard** or **Open in browser** action to move between the
embedded dashboard and your normal browser. The tray also provides update checks.

On macOS, closing the dashboard keeps the app running in the menu bar. Open OpenCodex again from Dock or Finder to restore the dashboard without restarting the proxy.

## Usage in the tray

On macOS and Windows, click the tray icon to open a compact usage window. The tray's
Expand Down
22 changes: 22 additions & 0 deletions docs-site/src/content/docs/guides/integrations.md
Original file line number Diff line number Diff line change
Expand Up @@ -200,6 +200,28 @@ undoable. The switch itself stays locked, because the switch cannot know which e
you meant to keep — only you can say so. Nothing else is relaxed: a file we cannot
parse, or one whose structure we cannot reason about, still refuses.

## Hermes session affinity

The generated `providers.opencodex` block includes `session_affinity_header: session-id` for all
models. This names a header; Hermes supplies its dynamic conversation identifier. OpenCodex does
not write a shared static identifier or change `api_mode` to enable affinity.

Use a Hermes version supporting [per-provider request options](https://hermes-agent.nousresearch.com/docs/user-guide/configuring-models#per-provider-request-options).
Older versions may ignore or discard the option; a valid configuration alone does not prove that
Hermes sends the header. Conversation isolation, compaction lineage and auxiliary/child requests
follow Hermes' affinity semantics. This setting does not guarantee a particular cache-hit rate.

For an existing managed integration, open **Integrations → Hermes**, review **Apply**, and confirm
the update. Until then, it shows **Update needed** and implicit catalog refresh leaves it unchanged,
including its model list. Reading the page does not upgrade the configuration. After Apply, normal
catalog refresh resumes and retains the setting; **Replace** also includes it.

If you already added exactly `session_affinity_header: session-id` inside the managed block, Apply
can adopt it when all other managed settings still match the ownership record. This is the narrow
exception to the conflict rule above: other edits, a different header name, or a block without a
matching ownership record still require conflict resolution. Unrelated YAML settings and comments
remain untouched, and the existing snapshot and Restore workflow applies to the upgrade.

## Preview and confirm changes

Apply, Replace, Disable, and Restore now begin with a preview. The dialog shows exactly which
Expand Down
23 changes: 23 additions & 0 deletions docs-site/src/content/docs/guides/sidecars.md
Original file line number Diff line number Diff line change
Expand Up @@ -207,6 +207,29 @@ timeout, and limit.
omitted keys unchanged. `timeoutMs` uses the runtime integer bounds
(1–2147483647 ms).

The web-search sidecar card carries the same control shape: the model picker's first row is
**Off**. Off does two things, and the second one is the reason the row exists. OpenCodex stops
intercepting `web_search`, and the Codex integration writes Codex's own
`web_search = "disabled"` mode into `~/.codex/config.toml` — because Codex keeps declaring its
native hosted `web_search` tool until its own mode says otherwise, and the tool a client
advertises is the one the model reaches for. An operator who wants an MCP search server to be
the only search path needs both halves; otherwise the model keeps calling the native tool.

`web_search` is Codex's key with its own value space (`disabled`, `cached`, `indexed`, `live`).
OpenCodex only ever writes `disabled` while the sidecar is off, and removes its marker-owned line
again once the sidecar is back on — a re-enabled sidecar whose client still had the native tool
switched off would have nothing to intercept. The write needs a managed `~/.codex/config.toml` (`ocx
sync`); the management response reports it as `codexWebSearch`, and both surfaces that can show it
do: the Dashboard's web-search card warns when the write did not happen, and `ocx agent sidecar web
--enabled off` prints whether it happened. Only a save that moves the switch triggers the write, so
the ordinary "nothing changed" answer reports `not_requested` and prints nothing extra. A root
`web_search` line the operator set by hand is replaced while the sidecar is off, since two root keys
of the same name are not valid TOML. Its exact text is recorded in the Codex journal and put back in
its place when the sidecar is switched on again — including for a line added after the journal
snapshot was taken, which `ocx restore` alone cannot cover. The same record is what still
recognizes our own `disabled` line when the Codex app has rewritten `config.toml` and dropped the
comment that named its owner.

You can still set `enabled: false` in `config.json` if you prefer to edit the
file directly. Anthropic-OAuth search and image description reuse the existing
Claude Code OAuth fingerprint precedent, but should be soak-tested with the
Expand Down
16 changes: 16 additions & 0 deletions docs-site/src/content/docs/guides/web-dashboard.md
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,22 @@ one column and model/effort controls share another. On narrower screens, control
labels in the same reading order. Long version labels are shortened visually; hover the version
badge or the version value to read the full value.

### Quota summary bar

A one-line summary at the top of every page except the Startup page shows each provider's current
quota usage, for example `OpenAI 31% | Claude 54% | xAI 12% | Google 8%`. It reads the same provider
quota reports as the Providers workspace (`GET /api/provider-quotas`, every 60 seconds while the tab
is visible) and never forces an upstream refresh.

- Each chip shows the preferred reported window: weekly first, then monthly, then 5-hour, then a
provider-named window or prepaid credits.
- A chip turns amber at 70% used and red at 90% used.
- Hover or click a chip to see every reported window with its reset time and the time the reading
was taken. Press Escape or click elsewhere to close a pinned chip.
- Providers that report no quota window are left out. The bar is hidden when no provider reports one.
- The right edge shows when the dashboard last read the reports. It turns amber when the latest
read failed and the previous reading is still shown.

## What you can do

| Area | What it does |
Expand Down
2 changes: 2 additions & 0 deletions docs-site/src/content/docs/ja/guides/desktop-app.md
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,8 @@ sudo apt install ./OpenCodex-<version>-linux-amd64.deb

トレイの **Open dashboard** または **Open in browser** で、埋め込みダッシュボードと通常のブラウザを切り替えられます。トレイから更新の確認もできます。

macOS では、ダッシュボードを閉じてもアプリはメニューバーで動作し続けます。Dock または Finder から OpenCodex を再度開くと、プロキシを再起動せずにダッシュボードが再表示されます。

## トレイでの使用量表示

macOS と Windows ではトレイアイコンをクリックするとコンパクトな使用量ウィンドウが開きます。トレイの **Show usage** 操作でも開けます。これはトレイのクリックイベントを転送しない Linux デスクトップでも使えます。Linux では、デスクトップ環境にトレイアイコンが表示されなくても起動時にダッシュボードが開きます。
Expand Down
2 changes: 2 additions & 0 deletions docs-site/src/content/docs/ja/guides/integrations.md
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,8 @@ Disable は opencodex が自身のものとして記録した項目だけを削

ロックされても操作不能ではありません。競合したクライアントには、概要カードとクライアントページの両方で、スイッチの横に **Replace** が表示されます。管理対象設定が置かれている内容を opencodex のブロックで置き換える操作で、先に確認を求めます。ダイアログにはファイル名、失われる内容、元に戻すためのスナップショットが示されます。スイッチ自体はロックされたままです。どの編集を維持するか判断できるのは利用者だけだからです。それ以外の制約は緩めません。解析できないファイルや、構造を安全に判断できないファイルは引き続き拒否されます。

Hermes のセッション識別設定には例外があります。管理対象の設定に `session_affinity_header: session-id` だけを追加した場合、**Apply** で取り込めます。他の管理対象フィールドの変更は引き続き競合になります。適用するまでバックグラウンドのモデル一覧更新も保留されます。この設定は provider 内の全モデルに適用され、対応する Hermes バージョンが必要です。キャッシュヒット率は保証されません。[英語のアップグレード説明](/guides/integrations/#hermes-session-affinity)を参照してください。

## 変更内容を確認して確定する

Apply、Replace、Disable、Restore はプレビューから始まります。ダイアログには、変更対象の管理設定が、範囲を限定した変更パスと値の追加・更新・削除の区別とともに表示されます。確定前に内容を確認してください。
Expand Down
Loading
Loading