Skip to content
Merged
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
52 changes: 52 additions & 0 deletions bin/ocx.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ import { existsSync, readFileSync, readdirSync, statSync } from "node:fs";
import { homedir } from "node:os";
import { dirname, join, resolve } from "node:path";
import { fileURLToPath } from "node:url";
import { handoffWindowsTrayForUpdate, planWindowsTrayUpdate } from "../src/update/tray-update-plan.mjs";

const PKG = "@bitkyc08/opencodex";
const require = createRequire(import.meta.url);
Expand Down Expand Up @@ -90,6 +91,27 @@ function repairCodexShimIfNeeded() {
}
}

function trayInstallState() {
const statePath = join(configDir(), "tray-state.json");
if (!existsSync(statePath)) return { installed: false, running: false };
let running = false;
try {
const heartbeat = JSON.parse(readFileSync(join(configDir(), "tray-heartbeat.json"), "utf8"));
if (Number.isSafeInteger(heartbeat.pid) && Date.now() - Number(heartbeat.timestamp) < 15_000) {
process.kill(heartbeat.pid, 0);
running = true;
}
} catch { /* installed but not running */ }
return { installed: true, running };
}

function runTrayLifecycle(launcher, action) {
return spawnSync(process.execPath, [launcher, "tray", action], {
stdio: "inherit",
windowsHide: true,
});
}

function runNpmSelfUpdate() {
const current = currentPackageVersion();
const tag = updateTag(current);
Expand All @@ -115,6 +137,9 @@ function runNpmSelfUpdate() {
// unloads it permanently, so a successful update must reinstall it afterwards.
const serviceStatePath = join(configDir(), "service-state.json");
const serviceWasInstalled = existsSync(serviceStatePath);
const trayBeforeUpdate = planWindowsTrayUpdate(
process.platform === "win32" ? trayInstallState() : { installed: false, running: false },
);
/** Read the backend from service-state.json so the update reinstalls the same one. */
function serviceReinstallArgs() {
try {
Expand Down Expand Up @@ -160,6 +185,21 @@ function runNpmSelfUpdate() {
// and the runtime-port record too: a service-managed or orphaned proxy can be live
// while ocx.pid is stale/missing.
const launcher = fileURLToPath(import.meta.url);
if (trayBeforeUpdate.stopBeforeReplacement) {
console.log("⏹ Handing off the Windows tray before updating...");
try {
handoffWindowsTrayForUpdate(trayBeforeUpdate, {
stop: () => {
const stopped = runTrayLifecycle(launcher, "stop");
return { exitStatus: stopped.status, running: trayInstallState().running };
},
start: () => runTrayLifecycle(launcher, "start"),
});
} catch {
console.error("opencodex: could not stop the Windows tray; aborting before package replacement.");
process.exit(1);
}
}
const hasRuntimeState =
existsSync(join(configDir(), "ocx.pid")) || existsSync(join(configDir(), "runtime-port.json"));
if (serviceWasInstalled || hasRuntimeState) {
Expand All @@ -168,6 +208,7 @@ function runNpmSelfUpdate() {
const stillHasRuntimeState =
existsSync(join(configDir(), "ocx.pid")) || existsSync(join(configDir(), "runtime-port.json"));
if (stopRes.status !== 0 || stillHasRuntimeState) {
if (trayBeforeUpdate.restoreOnFailure) runTrayLifecycle(launcher, "start");
console.error("opencodex: could not stop the running proxy; aborting the update. Run 'ocx stop' and retry.");
process.exit(1);
}
Expand All @@ -190,6 +231,16 @@ function runNpmSelfUpdate() {
if (res.status === 0) {
console.log(`\nUpdated${latest ? ` to v${latest}` : ""}.`);
repairCodexShimIfNeeded();
if (trayBeforeUpdate.refreshAfterReplacement) {
const tray = spawnSync(process.execPath, [launcher, ...trayBeforeUpdate.installArgs], {
stdio: "inherit",
windowsHide: true,
});
if (tray.status !== 0) {
console.warn("opencodex: Windows tray refresh failed. Run: ocx tray install");
if (trayBeforeUpdate.restoreOnFailure) runTrayLifecycle(launcher, "start");
}
}
// The stop above unloaded any managed service; reinstall via the freshly-installed
// launcher so the new files write the baked paths and the service restarts.
if (serviceWasInstalled) {
Expand Down Expand Up @@ -226,6 +277,7 @@ function runNpmSelfUpdate() {
}
process.exit(0);
}
if (trayBeforeUpdate.restoreOnFailure) runTrayLifecycle(launcher, "start");
console.error(`\nUpdate failed (${npm} exit ${res.status ?? "?"}). Try manually: ${npm} install -g ${PKG}@${tag}`);
process.exit(1);
}
Expand Down
7 changes: 6 additions & 1 deletion docs-site/src/content/docs/guides/web-dashboard.md
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,9 @@ bun run dev:gui
| **Sub-agent delegation** | Choose a native or routed guidance model and an optional reasoning effort for v1 delegation prompts. This is not a per-spawn router; see below. |
| **Sidecars** | Choose the web-search model and effort plus the vision-description model. Changes apply on the next request. |
| **Maintenance** | Resync the Codex model catalog, inspect project-local config bypass warnings, check the latest or preview release, and run an update with optional proxy restart. |
| **Codex autostart** | Enable or disable the Codex launcher shim that runs `ocx ensure` before Codex CLI/App starts. |
| **Startup safety** | Show whether injected Codex routing survives a restart, with separate service and launcher-shim health plus exact repair commands. |
| **Windows tray** | Install a per-user login tray for one-click proxy start, stop, restart, dashboard access, and status. The tray is a controller, not a proxy restart service. |
| **Codex autostart** | Allow an already-installed Codex launcher shim to run `ocx ensure`. This toggle does not install a shim or background service. |
| **Providers** | Add, edit, enable/disable, and remove providers; manage OAuth account pools and API-key pools where supported. Provider Settings can disable live model discovery for endpoints with missing, slow, or oversized `/models` catalogs. |
| **Add provider** | Search registry-backed presets for account login, API-key services, local servers, or a custom endpoint. |
| **Codex Auth** | Add ChatGPT/Codex pool accounts, select the next-session account, refresh 5h / weekly / 30d quotas, and configure quota auto-switch and transient-failure failover. |
Expand Down Expand Up @@ -86,6 +88,9 @@ The GUI is a thin client over the proxy's JSON management API. Useful endpoints
| Endpoint | Purpose |
| --- | --- |
| `GET` / `PUT /api/settings` | Read settings or toggle Codex autostart. |
| `GET /api/startup-health` | Read secret-free routing, service, shim, and restart-safety diagnostics. |
| `POST /api/startup-action` | Install the background service or Codex launcher shim through fixed, allowlisted actions. |
| `GET` / `POST /api/windows-tray` | Read or change the Windows tray installation and visible-process state. POST accepts `install`, `start`, `stop`, or `uninstall`. |
| `POST /api/sync` | Rebuild the shared model catalog and stale the Codex model cache. |
| `GET /api/update/check` · `POST /api/update/run` · `GET /api/update/status` | Check, run, and monitor self-update jobs. |
| `GET` / `PUT /api/sidecar-settings` | Read or set search/vision sidecar model settings. |
Expand Down
6 changes: 5 additions & 1 deletion docs-site/src/content/docs/ja/guides/web-dashboard.md
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,9 @@ bun run dev:gui
| **サブエージェント委任** | v1 委任プロンプトに入れるネイティブまたはルーティングモデルとオプションの推論強度を選びます。スポーンごとのルーターではありません。下記の説明を確認してください。 |
| **サイドカー** | ウェブ検索モデルと強度、画像説明モデルを選択します。次回リクエストから適用されます。 |
| **メンテナンス** | Codex モデルカタログを再同期し、プロジェクトローカル設定のバイパス警告を確認し、latest/preview 更新を照会またはオプションのプロキシ再起動と共にインストールします。 |
| **Codex 自動起動** | Codex CLI/App 実行前に `ocx ensure` を呼ぶランチャーシムをオン/オフします。 |
| **起動安全性** | 注入された Codex ルーティングが再起動後も機能するか、サービスと launcher shim の状態、正確な修復コマンドと共に表示します。 |
| **Windows トレイ** | ユーザーのログイントレイを導入し、プロキシ開始・停止・再起動・ダッシュボード・状態をクリックで操作します。トレイは再起動サービスではありません。 |
| **Codex 自動起動** | インストール済み Codex launcher shim に `ocx ensure` の実行を許可します。このトグルは shim やバックグラウンドサービスをインストールしません。 |
| **プロバイダー** | プロバイダーを追加、編集、有効化/無効化、削除し、対応する OAuth アカウントプールと API キープールを管理します。 |
| **プロバイダー追加** | レジストリベースのプリセットからアカウントログイン、API キーサービス、ローカルサーバー、custom エンドポイントを検索します。 |
| **Codex 認証** | ChatGPT/Codex プールアカウントを追加し、次回セッションアカウントを選び、5 時間 / 週間 / 30 日クォータを更新し、クォータ自動切り替えと一時的失敗フェイルオーバーを設定します。 |
Expand Down Expand Up @@ -81,6 +83,8 @@ GUI はプロキシの JSON 管理 API を使うシンクライアントです
| エンドポイント | 用途 |
--- | --- |
| `GET` / `PUT /api/settings` | 設定を読むか Codex 自動起動をオン/オフします。 |
| `GET /api/startup-health` | 秘密情報を含まないルーティング、サービス、shim、再起動安全性診断を読み取ります。 |
| `GET` / `POST /api/windows-tray` | Windows トレイの導入・表示状態を読み取り、`install`、`start`、`stop`、`uninstall` を実行します。 |
| `POST /api/sync` | 共有モデルカタログを再構築し Codex モデルキャッシュを古い状態としてマークします。 |
| `GET /api/update/check` · `POST /api/update/run` · `GET /api/update/status` | 自己更新作業を確認、実行、追跡します。 |
| `GET` / `PUT /api/sidecar-settings` | 検索/ビジョンサイドカーモデル設定を読むか変えます。 |
Expand Down
6 changes: 5 additions & 1 deletion docs-site/src/content/docs/ko/guides/web-dashboard.md
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,9 @@ bun run dev:gui
| **Sub-agent delegation** | v1 위임 프롬프트에 넣을 네이티브 또는 라우팅 모델과 선택적 reasoning 강도를 고릅니다. 스폰별 라우터는 아닙니다. 아래 설명을 확인하세요. |
| **사이드카** | 웹 검색 모델과 강도, 이미지 설명 모델을 선택합니다. 다음 요청부터 적용됩니다. |
| **Maintenance** | Codex 모델 카탈로그를 다시 동기화하고, 프로젝트 로컬 설정의 우회 경고를 확인하고, latest/preview 업데이트를 조회하거나 선택적 프록시 재시작과 함께 설치합니다. |
| **Codex 자동 시작** | Codex CLI/App 실행 전에 `ocx ensure`를 호출하는 launcher shim을 켜거나 끕니다. |
| **시작 안전성** | 주입된 Codex 라우팅이 재부팅 후에도 유지되는지 서비스와 launcher shim 상태, 정확한 복구 명령과 함께 표시합니다. |
| **Windows 트레이** | 로그인할 때 사용자 전용 트레이를 시작하고 프록시 시작·중지·재시작·대시보드·상태를 클릭으로 제어합니다. 트레이는 재시작 서비스가 아닙니다. |
| **Codex 자동 시작** | 이미 설치된 Codex launcher shim이 `ocx ensure`를 실행하도록 허용합니다. 이 토글은 shim이나 백그라운드 서비스를 설치하지 않습니다. |
| **Providers** | 프로바이더를 추가, 편집, 활성화/비활성화, 제거하고, 지원되는 OAuth 계정 풀과 API key 풀을 관리합니다. |
| **Add provider** | 레지스트리 기반 프리셋에서 계정 로그인, API key 서비스, 로컬 서버, custom endpoint를 검색합니다. |
| **Codex Auth** | ChatGPT/Codex 풀 계정을 추가하고, 다음 세션 계정을 선택하고, 5시간 / 주간 / 30일 할당량을 갱신하며, 할당량 자동 전환과 일시적 실패 failover를 설정합니다. |
Expand Down Expand Up @@ -83,6 +85,8 @@ GUI는 프록시의 JSON 관리 API를 사용하는 얇은 클라이언트입니
| 엔드포인트 | 용도 |
| --- | --- |
| `GET` / `PUT /api/settings` | 설정을 읽거나 Codex 자동 시작을 켜고 끕니다. |
| `GET /api/startup-health` | 비밀값 없이 라우팅, 서비스, shim, 재부팅 안전성 진단을 읽습니다. |
| `GET` / `POST /api/windows-tray` | Windows 트레이 설치 및 표시 상태를 읽거나 `install`, `start`, `stop`, `uninstall` 작업을 수행합니다. |
| `POST /api/sync` | 공유 모델 카탈로그를 다시 만들고 Codex 모델 캐시를 오래된 상태로 표시합니다. |
| `GET /api/update/check` · `POST /api/update/run` · `GET /api/update/status` | 자체 업데이트 작업을 확인, 실행, 추적합니다. |
| `GET` / `PUT /api/sidecar-settings` | 검색/비전 사이드카 모델 설정을 읽거나 바꿉니다. |
Expand Down
6 changes: 5 additions & 1 deletion docs-site/src/content/docs/ru/guides/web-dashboard.md
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,9 @@ bun run dev:gui
| **Sub-agent delegation** | Выбор нативной или маршрутизируемой модели для инструкции и необязательного уровня рассуждений для v1-промптов делегирования. Это не маршрутизатор для каждого порождения; см. ниже. |
| **Сайдкары** | Выбор модели и уровня рассуждений для веб-поиска, а также модели описания изображений. Изменения применяются со следующего запроса. |
| **Maintenance** | Пересинхронизация каталога моделей Codex, просмотр предупреждений об обходе через проектную локальную конфигурацию, проверка последнего или предварительного выпуска и запуск обновления с необязательным перезапуском прокси. |
| **Автозапуск Codex** | Включение и отключение launcher-шима Codex, который выполняет `ocx ensure` перед запуском Codex CLI/App. |
| **Безопасность запуска** | Показывает, сохранит ли внедрённая маршрутизация Codex работоспособность после перезагрузки, отдельно отображая службу, launcher shim и точные команды исправления. |
| **Трей Windows** | Устанавливает пользовательский значок входа для запуска, остановки, перезапуска, панели и состояния прокси одним щелчком. Трей не является службой перезапуска. |
| **Автозапуск Codex** | Разрешает уже установленному launcher shim Codex выполнять `ocx ensure`. Переключатель не устанавливает shim или фоновую службу. |
| **Providers** | Добавление, редактирование, включение/отключение и удаление провайдеров; управление пулами OAuth-аккаунтов и пулами API-ключей там, где они поддерживаются. |
| **Add provider** | Поиск по пресетам из реестра: вход по аккаунту, сервисы с API-ключом, локальные серверы или пользовательская конечная точка. |
| **Codex Auth** | Добавление аккаунтов пула ChatGPT/Codex, выбор аккаунта для следующей сессии, обновление квот 5 ч / недельных / 30-дневных, настройка автопереключения по квоте и failover при временных сбоях. |
Expand Down Expand Up @@ -86,6 +88,8 @@ GUI — это тонкий клиент поверх JSON-API управлен
| Эндпоинт | Назначение |
| --- | --- |
| `GET` / `PUT /api/settings` | Чтение настроек или переключение автозапуска Codex. |
| `GET /api/startup-health` | Чтение безопасной диагностики маршрутизации, службы, shim и устойчивости к перезагрузке. |
| `GET` / `POST /api/windows-tray` | Чтение или изменение установки и видимости трея Windows; POST поддерживает `install`, `start`, `stop`, `uninstall`. |
| `POST /api/sync` | Пересборка общего каталога моделей и инвалидация кэша моделей Codex. |
| `GET /api/update/check` · `POST /api/update/run` · `GET /api/update/status` | Проверка, запуск и мониторинг задач самообновления. |
| `GET` / `PUT /api/sidecar-settings` | Чтение или настройка моделей сайдкаров поиска/vision. |
Expand Down
6 changes: 5 additions & 1 deletion docs-site/src/content/docs/zh-cn/guides/web-dashboard.md
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,9 @@ bun run dev:gui
| **Sub-agent delegation** | 为 v1 委派 prompt 选择原生或路由模型,并可指定 reasoning 强度。它不是逐次生成的路由器,详见下文。 |
| **Sidecar** | 选择 web-search 模型及强度,以及图像描述模型;更改从下一次请求开始生效。 |
| **Maintenance** | 重新同步 Codex 模型目录,查看项目级配置绕过警告,检查 latest/preview 版本,并可在更新后重启代理。 |
| **Codex 自动启动** | 启用或禁用 Codex launcher shim;该 shim 会在 Codex CLI/App 启动前运行 `ocx ensure`。 |
| **启动安全** | 显示注入的 Codex 路由能否在重启后继续工作,并分别显示服务、launcher shim 状态和准确的修复命令。 |
| **Windows 托盘** | 安装用户登录托盘,一键控制代理启动、停止、重启、面板和状态。托盘不是代理重启服务。 |
| **Codex 自动启动** | 允许已安装的 Codex launcher shim 运行 `ocx ensure`。此开关不会安装 shim 或后台服务。 |
| **Providers** | 添加、编辑、启用/禁用、删除 provider,并在支持时管理 OAuth 账号池和 API key 池。 |
| **Add provider** | 搜索 registry preset,选择账号登录、API key 服务、本地服务器或自定义 endpoint。 |
| **Codex Auth** | 添加 ChatGPT/Codex 池账号,选择下一 session 的账号,刷新 5h / 每周 / 30d 配额,并设置配额自动切换和临时故障 failover。 |
Expand Down Expand Up @@ -78,6 +80,8 @@ GUI 是代理 JSON 管理 API 之上的轻量客户端。常用 endpoint 包括
| Endpoint | 用途 |
| --- | --- |
| `GET` / `PUT /api/settings` | 读取设置或切换 Codex 自动启动。 |
| `GET /api/startup-health` | 读取不含秘密信息的路由、服务、shim 和重启安全诊断。 |
| `GET` / `POST /api/windows-tray` | 读取或更改 Windows 托盘安装和显示状态;POST 支持 `install`、`start`、`stop`、`uninstall`。 |
| `POST /api/sync` | 重建共享模型目录,并把 Codex 模型缓存标记为过期。 |
| `GET /api/update/check` · `POST /api/update/run` · `GET /api/update/status` | 检查、运行和监控自更新任务。 |
| `GET` / `PUT /api/sidecar-settings` | 读取或设置 search/vision sidecar 模型。 |
Expand Down
Loading
Loading