Skip to content
Closed
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
18 changes: 16 additions & 2 deletions bin/ocx.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ import { fileURLToPath } from "node:url";
import { isRealBunBinary } from "../src/lib/bun-binary-validator.mjs";
import { npmInvocation } from "../src/update/npm-invocation.mjs";
import { pnpmInvocationForPath, resolvePnpmCommands } from "../src/update/pnpm-invocation.mjs";
import { detectInstallFromPath } from "../src/update/install-detection.mjs";
import { detectInstallOwnershipFromPath } from "../src/update/install-detection.mjs";
import {
pnpmOwnerInvocation,
resolvePnpmGlobalOwner,
Expand Down Expand Up @@ -70,7 +70,8 @@ try {
}
const require = createRequire(import.meta.url);
const here = dirname(fileURLToPath(import.meta.url));
const installMethod = detectInstallFromPath(here, { exists: existsSync });
const installOwnership = detectInstallOwnershipFromPath(here, { exists: existsSync });
const installMethod = installOwnership.installer;
const cliPath = join(here, "..", "src", "cli", "index.ts");
const NODE_LAUNCH_CONTEXT_ENV = "OCX_NODE_LAUNCH_CONTEXT";
const NODE_LAUNCH_PROOF_PREFIX = "--ocx-internal-launch-proof=";
Expand Down Expand Up @@ -916,6 +917,19 @@ if (codexCliUpdateInspection && typeof process.versions.bun === "string") {
process.exit(1);
}

if (process.argv[2] === "update" && installMethod === "mise") {
if (installOwnership.owner) {
console.error(
`opencodex: this installation is externally managed by mise; update it with: mise upgrade ${installOwnership.owner.tool}`,
);
} else {
console.error(
"opencodex: this installation appears to be managed by mise, but its ownership metadata is unreadable or inconsistent; repair the mise installation metadata before updating.",
);
}
process.exit(1);
}

if (process.argv[2] === "update" && isNodeModulesInstall() && !isBunGlobalInstall()) {
if (installMethod === "npm") runNpmSelfUpdate();
if (installMethod === "pnpm") runPnpmSelfUpdate();
Expand Down
2 changes: 2 additions & 0 deletions docs-site/src/content/docs/fr/reference/cli/lifecycle.md
Original file line number Diff line number Diff line change
Expand Up @@ -317,6 +317,8 @@ Ouvre le [tableau de bord Web](/fr/guides/web-dashboard/) à l’adresse `http:/

### `ocx update [--tag latest|preview]`

Lorsque OpenCodex est installé avec mise, cette commande échoue avant d'arrêter le proxy ou de modifier les fichiers du paquet et affiche `mise upgrade <outil>` avec l'alias mise local vérifié. La vérification des mises à jour reste disponible et signale une gestion externe. Des métadonnées de propriété mise illisibles ou incohérentes bloquent aussi toute modification sans deviner le nom de l'outil, et `--tag preview` ne change jamais la sélection configurée dans mise.

Met à jour opencodex depuis npm. Les installations stables utilisent `@latest` ; les préversions restent sur `@preview`, sauf si vous indiquez `--tag latest|preview`. La commande détecte un dépôt de sources et vous invite alors à exécuter `git pull && bun install`. Elle ne fait rien si la version la plus récente correspondant à cette balise est déjà installée.

Avant tout arrêt, les installations npm effectuent sous Unix un contrôle borné de la propriété et de l’accès au cache. Les liens symboliques imbriqués sont examinés avec `lstat`, sans être suivis ; Windows ignore explicitement ce contrôle propre à Unix. En cas d’échec, l’opération s’interrompt tandis que l’icône et le proxy fonctionnent encore. Le proxy actif est ensuite arrêté avant le remplacement des fichiers. Un service installé est reconstruit et redémarré automatiquement ; pour une installation au premier plan, la commande indique `ocx start` comme étape suivante. Avant leur conservation, les enregistrements de mise à jour du tableau de bord masquent les chemins de profil et de cache ainsi que les valeurs UID/GID.
Expand Down
2 changes: 2 additions & 0 deletions docs-site/src/content/docs/ja/reference/cli/lifecycle.md
Original file line number Diff line number Diff line change
Expand Up @@ -286,6 +286,8 @@ Windows ステータス トレイ アイコンをインストールして制御

### `ocx update [--tag latest|preview]`

OpenCodex が mise 経由でインストールされている場合、このコマンドはプロキシの停止やパッケージファイルの変更前に失敗終了し、検証済みのローカル mise エイリアスを使った `mise upgrade <tool>` を表示します。更新確認は引き続き利用でき、外部管理として報告されます。mise の所有権メタデータを読み取れない場合や整合しない場合もツール名を推測せずに変更を拒否し、`--tag preview` は mise の設定済み選択を変更しません。

npm から opencodex を自己更新します。安定したインストールでは `@latest` を使用します。 `--tag latest|preview` を渡さない限り、プレビュー インストールは `@preview` に残ります。ソース チェックアウトを検出し、代わりに `git pull && bun install` を使用するように指示しますが、そのタグの最新バージョンをすでに使用している場合は何もしません。npm インストールでは、何かを停止する前に Unix キャッシュの所有権とアクセスを上限付きで検査します。ネストされたシンボリックリンクは `lstat` で確認しますが追跡しません。Windows では、この Unix 専用検査を明示的にスキップします。検査に失敗した場合、トレイとプロキシを実行したまま更新を中止します。その後、実行中のプロキシはファイルが置き換えられる前に停止されます。インストールされたサービスは再構築されて自動的に開始されますが、フォアグラウンド インストールでは次のステップとして `ocx start` が出力されます。ダッシュボードの更新記録では、保存前にプロファイル/キャッシュのパスと UID/GID 値が秘匿されます。

```bash
Expand Down
2 changes: 2 additions & 0 deletions docs-site/src/content/docs/ko/reference/cli/lifecycle.md
Original file line number Diff line number Diff line change
Expand Up @@ -406,6 +406,8 @@ Windows 상태 트레이 아이콘을 설치하고 제어합니다. Windows 로

### `ocx update [--tag latest|preview]`

OpenCodex가 mise를 통해 설치된 경우 이 명령은 프록시를 중지하거나 패키지 파일을 변경하기 전에 실패하며 검증된 로컬 mise 별칭을 사용한 `mise upgrade <tool>`을 표시합니다. 업데이트 확인은 계속 사용할 수 있고 외부 관리 설치로 보고합니다. mise 소유권 메타데이터를 읽을 수 없거나 일관되지 않아도 도구 이름을 추측하지 않고 변경을 거부하며, `--tag preview`는 mise에 구성된 선택을 변경하지 않습니다.

npm에서 opencodex를 자체 업데이트합니다. 안정판 설치는 `@latest`를 사용하고, 미리보기 설치는
`--tag latest|preview`를 주지 않으면 `@preview`를 유지합니다. 소스 체크아웃을 감지하면 대신
`git pull && bun install`을 실행하라고 안내하고, 해당 태그에서 이미 최신 버전이면 아무 동작도 하지
Expand Down
2 changes: 2 additions & 0 deletions docs-site/src/content/docs/reference/cli/lifecycle.md
Original file line number Diff line number Diff line change
Expand Up @@ -700,6 +700,8 @@ package registry or install an update.

### `ocx update [--tag latest|preview]`

When OpenCodex is installed through mise, this command exits unsuccessfully before stopping the proxy or changing package files and shows `mise upgrade <tool>`, using the verified local mise alias. Update checks remain available and report the installation as externally managed. An unreadable or inconsistent mise ownership record fails closed without guessing a tool name, and `--tag preview` never changes mise's configured selection.

Self-update opencodex from npm. Stable installs use `@latest`; preview installs stay on `@preview`
unless you pass `--tag latest|preview`. It detects a source checkout and tells you to
`git pull && bun install` instead, and is a no-op if you are already on the newest version for that
Expand Down
2 changes: 2 additions & 0 deletions docs-site/src/content/docs/ru/reference/cli/lifecycle.md
Original file line number Diff line number Diff line change
Expand Up @@ -411,6 +411,8 @@ one-click управление прокси. `start` и `stop` управляю

### `ocx update [--tag latest|preview]`

Если OpenCodex установлен через mise, команда завершается с ошибкой до остановки прокси или изменения файлов пакета и показывает `mise upgrade <tool>` с проверенным локальным псевдонимом mise. Проверка обновлений остаётся доступной и сообщает о внешнем управлении. Нечитаемые или противоречивые метаданные владельца mise также запрещают изменения без угадывания имени инструмента, а `--tag preview` никогда не меняет выбранную в mise версию.

Самообновить opencodex из npm. Стабильные установки используют `@latest`; preview-установки
остаются на `@preview`, если только вы не передадите `--tag latest|preview`. Команда распознаёт
source checkout и предлагает вместо этого `git pull && bun install`, а если у вас уже новейшая
Expand Down
2 changes: 2 additions & 0 deletions docs-site/src/content/docs/tr/reference/cli/lifecycle.md
Original file line number Diff line number Diff line change
Expand Up @@ -486,6 +486,8 @@ adresindeki [web kontrol panelini](/tr/guides/web-dashboard/) açın; hub'da yö

### `ocx update [--tag latest|preview]`

OpenCodex mise üzerinden kurulduğunda bu komut proxy'yi durdurmadan veya paket dosyalarını değiştirmeden önce başarısız olur ve doğrulanmış yerel mise diğer adını kullanarak `mise upgrade <tool>` komutunu gösterir. Güncelleme denetimi kullanılabilir kalır ve kurulumun harici olarak yönetildiğini bildirir. Okunamayan veya tutarsız mise sahiplik meta verileri de araç adını tahmin etmeden değişikliği reddeder; `--tag preview` mise içinde yapılandırılmış seçimi değiştirmez.

opencodex'i npm'den kendi kendine güncelleyin. Kararlı kurulumlar `@latest`
kullanır; önizleme kurulumları `--tag latest|preview` iletmediğiniz sürece
`@preview` üzerinde kalır. Bir kaynak kod kopyasını algılar ve bunun yerine `git
Expand Down
2 changes: 2 additions & 0 deletions docs-site/src/content/docs/zh-cn/reference/cli/lifecycle.md
Original file line number Diff line number Diff line change
Expand Up @@ -273,6 +273,8 @@ ocx codex-shim uninstall

### `ocx update [--tag latest|preview]`

当 OpenCodex 由 mise 安装时,此命令会在停止代理或修改软件包文件之前以失败状态退出,并使用经过验证的本地 mise 别名显示 `mise upgrade <tool>`。更新检查仍然可用,并会报告该安装由外部管理。无法读取或不一致的 mise 所有权元数据也会阻止修改,且不会猜测工具名称;`--tag preview` 绝不会更改 mise 中配置的选择。

从 npm 自更新 opencodex。稳定版安装使用 `@latest`;预览版安装保持在 `@preview`,除非你传入 `--tag latest|preview`。它会检测源码检出,并提示你改为运行 `git pull && bun install`;如果你已经是该标签的最新版本,则不会执行任何操作。对于 npm 安装,它会在停止任何进程之前,对 Unix 缓存的所有权和访问权限执行有界检查。嵌套符号链接会通过 `lstat` 检查但不会跟随;Windows 会明确跳过这项仅适用于 Unix 的检查。检查失败时,更新会在托盘和代理仍运行的情况下中止。随后才会在替换文件之前停止正在运行的代理;已安装的服务会自动重建并启动,而前台安装则会打印 `ocx start` 作为下一步。持久化前,仪表板更新记录会隐去用户配置文件/缓存路径以及 UID/GID 值。

```bash
Expand Down
2 changes: 2 additions & 0 deletions docs-site/src/content/docs/zh-tw/reference/cli/lifecycle.md
Original file line number Diff line number Diff line change
Expand Up @@ -258,6 +258,8 @@ ocx codex-shim uninstall

### `ocx update [--tag latest|preview]`

當 OpenCodex 由 mise 安裝時,此命令會在停止代理或修改套件檔案之前以失敗狀態結束,並使用經過驗證的本機 mise 別名顯示 `mise upgrade <tool>`。更新檢查仍可使用,並會回報該安裝由外部管理。無法讀取或不一致的 mise 擁有權中繼資料也會阻止修改,且不會猜測工具名稱;`--tag preview` 絕不會變更 mise 中設定的選擇。

從 npm 自我更新 opencodex。穩定安裝使用 `@latest`;預覽安裝停留在 `@preview`,除非你傳入 `--tag latest|preview`。它偵測原始碼 checkout 並告訴你改用
`git pull && bun install`,且若你已是該 tag 的最新版本則為 no-op。執行中的代理會在檔案被替換前停止;已安裝的服務會自動重建並啟動,而前景安裝會印出 `ocx start` 作為下一步。

Expand Down
1 change: 1 addition & 0 deletions gui/src/components/sidebar-github-row.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ interface StarStatus {
interface UpdateBadge {
updateAvailable?: boolean;
latestVersion?: string | null;
installer?: "bun" | "mise" | "npm" | "pnpm" | "source";
/** True when no cached registry answer exists, so "no update" is unproven. */
unknown?: boolean;
}
Expand Down
2 changes: 2 additions & 0 deletions gui/src/i18n/de.ts
Original file line number Diff line number Diff line change
Expand Up @@ -435,6 +435,8 @@ export const de: Record<TKey, string> = {
"dash.updateReason.source_checkout": "Quellcode-Checkout",
"dash.updateReason.latest_unavailable": "npm-Registry nicht erreichbar",
"dash.updateReason.already_latest": "bereits auf dem neuesten Stand",
"dash.updateReason.externally_managed": "extern von mise verwaltet; führe den angezeigten Befehl aus",
"dash.updateReason.external_ownership_invalid": "mise-Eigentümerdaten sind nicht lesbar oder widersprüchlich",
"dash.updateReason.unknown": "Update nicht verfügbar",
"dash.updateRestart": "Nach Update neu starten",
"dash.updateRestartHint": "Empfohlen. Die aktuelle GUI läuft weiter mit altem Code, bis der Proxy neu startet.",
Expand Down
2 changes: 2 additions & 0 deletions gui/src/i18n/en.ts
Original file line number Diff line number Diff line change
Expand Up @@ -456,6 +456,8 @@ export const en = {
"dash.updateReason.source_checkout": "source checkout",
"dash.updateReason.latest_unavailable": "npm registry unreachable",
"dash.updateReason.already_latest": "already on latest",
"dash.updateReason.externally_managed": "managed externally by mise; run the shown command",
"dash.updateReason.external_ownership_invalid": "mise ownership metadata is unreadable or inconsistent",
"dash.updateReason.unknown": "update unavailable",
"dash.updateRestart": "Restart after update",
"dash.updateRestartHint": "Recommended. The current GUI keeps running the old code until the proxy restarts.",
Expand Down
2 changes: 2 additions & 0 deletions gui/src/i18n/fr.ts
Original file line number Diff line number Diff line change
Expand Up @@ -446,6 +446,8 @@ export const fr: Record<TKey, string> = {
"dash.updateReason.source_checkout": "extraction du code source",
"dash.updateReason.latest_unavailable": "registre npm inaccessible",
"dash.updateReason.already_latest": "dernière version déjà installée",
"dash.updateReason.externally_managed": "géré par mise ; exécutez la commande affichée",
"dash.updateReason.external_ownership_invalid": "les métadonnées de propriété mise sont illisibles ou incohérentes",
"dash.updateReason.unknown": "mise à jour indisponible",
"dash.updateRestart": "Redémarrer après la mise à jour",
"dash.updateRestartHint": "Recommandé. L’interface graphique actuelle continue d’exécuter l’ancien code jusqu’au redémarrage du proxy.",
Expand Down
2 changes: 2 additions & 0 deletions gui/src/i18n/ja.ts
Original file line number Diff line number Diff line change
Expand Up @@ -444,6 +444,8 @@ export const ja: Record<TKey, string> = {
"dash.updateReason.source_checkout": "ソースチェックアウト",
"dash.updateReason.latest_unavailable": "npm レジストリに到達できません",
"dash.updateReason.already_latest": "最新です",
"dash.updateReason.externally_managed": "mise によって外部管理されています。表示されたコマンドを実行してください",
"dash.updateReason.external_ownership_invalid": "mise の所有権メタデータを読み取れないか、整合していません",
"dash.updateReason.unknown": "更新は利用できません",
"dash.updateRestart": "更新後に再起動",
"dash.updateRestartHint": "推奨。プロキシが再起動されるまで現在の GUI は古いコードを実行し続けます。",
Expand Down
2 changes: 2 additions & 0 deletions gui/src/i18n/ko.ts
Original file line number Diff line number Diff line change
Expand Up @@ -442,6 +442,8 @@ export const ko: Record<TKey, string> = {
"dash.updateReason.source_checkout": "소스 체크아웃",
"dash.updateReason.latest_unavailable": "npm 레지스트리에 연결할 수 없음",
"dash.updateReason.already_latest": "이미 최신 버전",
"dash.updateReason.externally_managed": "mise에서 외부 관리 중입니다. 표시된 명령을 실행하세요",
"dash.updateReason.external_ownership_invalid": "mise 소유권 메타데이터를 읽을 수 없거나 일관되지 않습니다",
"dash.updateReason.unknown": "업데이트 불가",
"dash.updateRestart": "업데이트 후 재시작",
"dash.updateRestartHint": "권장. 프록시를 재시작하기 전까지 현재 GUI는 이전 코드로 계속 실행됩니다.",
Expand Down
2 changes: 2 additions & 0 deletions gui/src/i18n/ru.ts
Original file line number Diff line number Diff line change
Expand Up @@ -444,6 +444,8 @@ export const ru: Record<TKey, string> = {
"dash.updateReason.source_checkout": "установка из исходного кода",
"dash.updateReason.latest_unavailable": "реестр npm недоступен",
"dash.updateReason.already_latest": "уже установлена последняя версия",
"dash.updateReason.externally_managed": "управляется mise; выполните показанную команду",
"dash.updateReason.external_ownership_invalid": "метаданные владельца mise недоступны или противоречивы",
"dash.updateReason.unknown": "обновление недоступно",
"dash.updateRestart": "Перезапустить после обновления",
"dash.updateRestartHint": "Рекомендуется. Текущий GUI продолжает работать на старом коде, пока прокси не перезапустится.",
Expand Down
2 changes: 2 additions & 0 deletions gui/src/i18n/tr.ts
Original file line number Diff line number Diff line change
Expand Up @@ -448,6 +448,8 @@ export const tr: Record<TKey, string> = {
"dash.updateReason.source_checkout": "kaynak kod kopyası",
"dash.updateReason.latest_unavailable": "npm sunucusuna ulaşılamıyor",
"dash.updateReason.already_latest": "zaten en son sürümde",
"dash.updateReason.externally_managed": "mise tarafından harici olarak yönetiliyor; gösterilen komutu çalıştırın",
"dash.updateReason.external_ownership_invalid": "mise sahiplik meta verileri okunamıyor veya tutarsız",
"dash.updateReason.unknown": "güncelleme kullanılamıyor",
"dash.updateRestart": "Güncellemeden sonra yeniden başlat",
"dash.updateRestartHint": "Önerilir. Proxy yeniden başlayana kadar mevcut GUI eski kodu çalıştırmaya devam eder.",
Expand Down
2 changes: 2 additions & 0 deletions gui/src/i18n/vi.ts
Original file line number Diff line number Diff line change
Expand Up @@ -440,6 +440,8 @@ export const vi: Record<TKey, string> = {
"dash.updateReason.source_checkout": "checkout mã nguồn",
"dash.updateReason.latest_unavailable": "không thể kết nối với registry npm",
"dash.updateReason.already_latest": "đã ở phiên bản mới nhất",
"dash.updateReason.externally_managed": "được mise quản lý bên ngoài; hãy chạy lệnh được hiển thị",
"dash.updateReason.external_ownership_invalid": "siêu dữ liệu quyền sở hữu của mise không đọc được hoặc không nhất quán",
"dash.updateReason.unknown": "cập nhật không khả dụng",
"dash.updateRestart": "Khởi động lại sau khi cập nhật",
"dash.updateRestartHint": "Khuyên dùng. GUI hiện tại vẫn tiếp tục chạy mã nguồn cũ cho đến khi proxy khởi động lại.",
Expand Down
2 changes: 2 additions & 0 deletions gui/src/i18n/zh-TW.ts
Original file line number Diff line number Diff line change
Expand Up @@ -334,6 +334,8 @@ export const zhTW: Record<TKey, string> = {
"dash.updateReason.source_checkout": "原始碼檢出",
"dash.updateReason.latest_unavailable": "無法連線 npm 登入檔",
"dash.updateReason.already_latest": "已是最新版本",
"dash.updateReason.externally_managed": "由 mise 外部管理;請執行顯示的命令",
"dash.updateReason.external_ownership_invalid": "mise 擁有權中繼資料無法讀取或不一致",
"dash.updateReason.unknown": "無法更新",
"dash.updateRestart": "更新後重新啟動",
"dash.updateRestartHint": "推薦開啟。代理重新啟動前,當前 GUI 仍執行舊程式碼。",
Expand Down
2 changes: 2 additions & 0 deletions gui/src/i18n/zh.ts
Original file line number Diff line number Diff line change
Expand Up @@ -439,6 +439,8 @@ export const zh: Record<TKey, string> = {
"dash.updateReason.source_checkout": "源码检出",
"dash.updateReason.latest_unavailable": "无法连接 npm 注册表",
"dash.updateReason.already_latest": "已是最新版本",
"dash.updateReason.externally_managed": "由 mise 外部管理;请运行显示的命令",
"dash.updateReason.external_ownership_invalid": "mise 所有权元数据无法读取或不一致",
"dash.updateReason.unknown": "无法更新",
"dash.updateRestart": "更新后重启",
"dash.updateRestartHint": "推荐开启。代理重启前,当前 GUI 仍运行旧代码。",
Expand Down
Loading
Loading