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
Original file line number Diff line number Diff line change
Expand Up @@ -164,6 +164,15 @@ et la colonne plan/label recouvre le plan, l'e-mail masqué, l'étiquette et la

### `ocx account list [provider] [--json] [--all]`

Les comptes ChatGPT enregistrés dans le pool restent consultables sur les hôtes sans répertoire
Codex natif, y compris dans le tableau de bord et lors de l'actualisation des comptes. Cette consultation
ne crée pas de répertoire Codex et ne déconnecte pas le compte principal natif. Désactiver l'intégration
du client Codex ne désactive pas l'observation du quota d'une connexion native existante. Un chemin
`CODEX_HOME` explicite invalide continue de produire une erreur de configuration. Un stockage
`OPENCODEX_HOME` non sûr produit une erreur même si le répertoire Codex natif est absent. La résolution
du chemin Codex par défaut renvoie également une erreur s'il désigne un fichier, un lien symbolique
dont la cible n'existe pas, ou si son répertoire parent ne peut pas être traversé.

Sans fournisseur, répertorie le groupe de comptes Codex, les comptes OAuth et les groupes de clés API configurés. Les fournisseurs vides
sont ignorés à moins que `--all` soit présent. Avec un fournisseur, répertorie uniquement cette famille d’informations d’identification.
La sortie destinée aux utilisateurs utilise `PROVIDER TYPE ID PLAN/LABEL PRIORITY STATUS` ; une ligne Codex sélectionnée manuellement porte la mention
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -131,6 +131,14 @@ Codex pool selection applies to the next request after clearing existing affinit

### `ocx account list [provider] [--json] [--all] [--quota [--refresh]]`

保存済みの ChatGPT プールアカウントは、ネイティブ Codex ホームがないホストでも、
ダッシュボードやアカウント更新時を含めて一覧表示できます。一覧表示によって Codex ホームが
作成されたり、ネイティブのメインアカウントからサインアウトしたりすることはありません。
Codex クライアント連携を無効にしても、既存のネイティブログインのクォータ観測は無効になりません。
明示的に指定した `CODEX_HOME` のパスが無効な場合は、引き続き設定エラーを返します。
`OPENCODEX_HOME` のストレージが安全でない場合は、ネイティブ Codex ホームがなくてもエラーを返します。
既定の Codex ホームのパス解決では、ファイル、リンク先が存在しないシンボリックリンク、辿れない親ディレクトリもエラーになります。

プロバイダーを使用しない場合、Codex プール、OAuth アカウント、および設定された API キー プールが一覧表示されます。 `--all` が存在しない限り、空のプロバイダーはスキップされます。プロバイダーを使用すると、その資格情報ファミリーのみがリストされます。人間の出力では `PROVIDER TYPE ID PLAN/LABEL PRIORITY STATUS` を使用します。手動で選択した Codex 行には `selected` というマークが付けられます。利用可能な Kiro アカウントが 2 つ以上保存されている場合、既定では 429 を受けると別のアカウントへ自動的に切り替え、既知の残り利用枠が最も多いアカウントを優先します。この切り替えはアカウントの存在によって有効になり、無効にはできません。`oauthAccountFailover.enabled: false` が断るのは 429 復旧ではなく、送信前にアカウントを選ぶ動作だけです。`ocx account login kiro` はアカウントを 1 件ずつプールへ追加します。結果が空であっても成功です。 `--json` は次を返します:

```text
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -241,6 +241,14 @@ Codex pool selection applies to the next request after clearing existing affinit

### `ocx account list [provider] [--json] [--all] [--quota [--refresh]]`

저장된 ChatGPT 풀 계정은 네이티브 Codex 홈이 없는 호스트에서도 대시보드와 계정 새로 고침을
포함해 계속 나열할 수 있습니다. 목록 조회는 Codex 홈을 만들거나 네이티브 메인 계정에서
로그아웃하지 않습니다. Codex 클라이언트 통합을 비활성화해도 기존 네이티브 로그인의 할당량
관측은 비활성화되지 않습니다. 명시적으로 지정한 `CODEX_HOME` 경로가 유효하지 않으면 계속
설정 오류를 반환합니다. `OPENCODEX_HOME` 저장소가 안전하지 않으면 네이티브 Codex 홈이
없어도 오류를 반환합니다.
기본 Codex 홈의 경로를 확인할 때도 파일, 대상이 없는 심볼릭 링크, 탐색할 수 없는 상위 디렉터리는 오류를 발생시킵니다.

제공자를 지정하지 않으면 Codex 풀, OAuth 계정, 설정된 API 키 풀을 나열합니다. `--all`이 없으면 비어 있는 제공자는 건너뜁니다. 제공자를 지정하면 해당 자격 증명 계열만 나열합니다. 사람이 보는 출력은 `PROVIDER TYPE ID PLAN/LABEL PRIORITY STATUS` 형식을 사용하며, 수동으로 선택한 Codex 행에는 `selected`가 표시됩니다. 사용 가능한 Kiro 계정이 두 개 이상 저장되어 있으면 기본적으로 429 응답 시 다른 계정으로 자동 전환하며, 알려진 잔여 할당량이 가장 많은 계정을 우선합니다. 이 전환은 계정 존재만으로 활성화되며 끌 수 없습니다. `oauthAccountFailover.enabled: false`는 429 복구가 아니라 요청을 보내기 전 계정을 고르는 동작만 거부합니다. `ocx account login kiro`는 계정을 한 번에 하나씩 풀에 추가합니다. 빈 결과도 성공입니다. `--json`은 다음을 반환합니다:

```text
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -667,6 +667,13 @@ changes Orca files, or changes the active pool account.

### `ocx account list [provider] [--json] [--all] [--quota [--refresh]]`

Stored ChatGPT pool accounts remain listable on hosts without a native Codex home, including in the
dashboard and on account refresh. Listing does not create a Codex home or sign out the native main
account. Disabling the Codex client integration does not disable an existing native login's quota
observation; invalid explicit `CODEX_HOME` paths still report a configuration error. Unsafe
`OPENCODEX_HOME` storage reports an error even when the native Codex home is missing.
Comment thread
coderabbitai[bot] marked this conversation as resolved.
Default-home resolution also reports errors for files, dangling links, and parent directories that cannot be traversed.

Without a provider, lists the Codex pool, OAuth accounts, and configured API-key pools. Empty
providers are skipped unless `--all` is present. With a provider, lists only that credential family.
Human output uses `PROVIDER TYPE ID PLAN/LABEL PRIORITY STATUS`; a manually chosen Codex row is marked
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -154,6 +154,14 @@ label и masked key.

### `ocx account list [provider] [--json] [--all]`

Сохранённые аккаунты пула ChatGPT доступны для просмотра даже на хостах без нативного каталога
Codex, в том числе в dashboard и при обновлении аккаунтов. Просмотр списка не создаёт каталог
Codex и не выполняет выход из нативного основного аккаунта. Отключение интеграции клиента Codex
не отключает наблюдение за квотой существующего нативного входа. Некорректный явно заданный
путь `CODEX_HOME` по-прежнему вызывает ошибку конфигурации. Небезопасное хранилище
`OPENCODEX_HOME` вызывает ошибку даже при отсутствии нативного каталога Codex.
При разрешении пути к каталогу Codex по умолчанию также возвращается ошибка, если он является файлом, ссылкой на отсутствующий объект или его родительский каталог не позволяет пройти по пути.

Без провайдера команда показывает пул Codex, OAuth-аккаунты и настроенные API-key pool'ы.
Пустые провайдеры пропускаются, если не задан `--all`. С провайдером выводится только это
семейство credential'ов. Human-output использует формат
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -175,6 +175,14 @@ kullanılamadığında atlanır):

### `ocx account list [provider] [--json] [--all]`

Kayıtlı ChatGPT havuz hesapları, yerel Codex ana dizini olmayan makinelerde de listelenebilir;
buna pano ve hesap yenileme işlemleri dahildir. Listeleme, Codex ana dizini oluşturmaz ve yerel ana
hesabın oturumunu kapatmaz. Codex istemci entegrasyonunu devre dışı bırakmak, mevcut bir yerel oturumun
kota gözlemini devre dışı bırakmaz. Açıkça belirtilmiş geçersiz `CODEX_HOME` yolları yine yapılandırma
hatası döndürür. Güvenli olmayan `OPENCODEX_HOME` depolaması, yerel Codex ana dizini eksik olsa bile
hata döndürür. Varsayılan Codex ana dizini yolu çözümlenirken dosyalar, hedefi bulunmayan sembolik
bağlantılar ve geçiş yapılamayan üst dizinler de hataya neden olur.

Bir sağlayıcı olmadan Codex havuzunu, OAuth hesaplarını ve yapılandırılmış API
anahtarı havuzlarını listeler. `--all` bulunmadıkça boş sağlayıcılar atlanır.
Bir sağlayıcı ile yalnızca bu kimlik bilgisi ailesini listeler. İnsan çıktısı
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -149,6 +149,12 @@ OAuth 账号会显示为 `Account N`,而 plan/label 列会在 plan、屏蔽后

### `ocx account list [provider] [--json] [--all] [--quota [--refresh]]`

即使主机上没有原生 Codex 主目录,保存的 ChatGPT 池账号仍可列出,包括在仪表盘中和刷新账号时。
查询列表不会创建 Codex 主目录,也不会退出原生主账号。禁用 Codex 客户端集成不会停止
观测已有原生登录的配额;显式设置的 `CODEX_HOME` 路径无效时,仍会报告配置错误。
如果 `OPENCODEX_HOME` 存储不安全,即使没有原生 Codex 主目录,也会报告错误。
解析默认 Codex 主目录路径时,如果该路径是文件、目标不存在的符号链接,或父目录无法遍历,也会报告错误。

不指定提供方时,会列出 Codex 池、OAuth 账号和已配置的 API 密钥池。除非提供
`--all`,否则会跳过空的提供方。指定提供方时,只列出该凭据家族。人类可读输出
使用 `PROVIDER TYPE ID PLAN/LABEL PRIORITY STATUS`;手动选中的 Codex 行会标记为 `selected`。
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -113,6 +113,11 @@ Codex 池選擇套用於清除既有親和性後的下一個請求;進行中

### `ocx account list [provider] [--json] [--all] [--quota [--refresh]]`

即使主機沒有原生 Codex 主目錄,仍可列出已儲存的 ChatGPT 池帳號,包括在儀表板中及重新整理帳號時。
列出帳號不會建立 Codex 主目錄,也不會將原生主帳號登出。停用 Codex 用戶端整合不會停用對既有原生登入的額度觀測;
明確設定但無效的 `CODEX_HOME` 路徑仍會回報設定錯誤。若 `OPENCODEX_HOME` 儲存空間不安全,即使原生 Codex 主目錄不存在,也會回報錯誤。
解析預設 Codex 主目錄路徑時,若該路徑是檔案、目標不存在的符號連結,或父目錄無法遍歷,也會回報錯誤。

未指定供應商時,列出 Codex 池、OAuth 帳號與已設定的 API-key 池。除非存在 `--all`,否則空的供應商會被跳過。指定供應商時,僅列出該憑證家族。人類輸出使用 `PROVIDER TYPE ID PLAN/LABEL STATUS`;手動選擇的 Codex 列標記為 `selected`。當儲存了兩個以上符合資格的 Kiro 帳號時,預設情況下 429 會自動輪換至另一個帳號,並優先選擇已知剩餘額度最多的帳號;輪換由帳號存在與否驅動,且無法關閉;`oauthAccountFailover.enabled: false` 拒絕的是送出前的帳號優選,而非 429 復原。`ocx account login kiro` 每次將一個帳號加入池中。空結果仍為成功。`--json` 回傳:

```text
Expand Down
1 change: 1 addition & 0 deletions scripts/test-layout/layout.json
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,7 @@
"server-combo-plan-model-refusal.test.ts": "server",
"codex-main-token-invalidated.test.ts": "codex-integration",
"codex-main-grant-refusal.test.ts": "codex-integration",
"codex-auth-headless-accounts.test.ts": "codex-integration",
"responses-alternate-main-cancellation.test.ts": "responses",
"codex-shim-path-readiness.test.ts": "codex-integration",
"codex-shim-fnm.test.ts": "codex-integration",
Expand Down
4 changes: 2 additions & 2 deletions src/codex/auth-api/account-list.ts
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ import type { OAuthAccountHealth, OAuthHealthLabel } from "../../oauth/health";
import { isSelectableCodexPoolAccount } from "../account-id";
import type { AdmissionLease } from "../../lib/admission";
import { tryAcquireNativeMainProfileClaim } from "../native-main-admission";
import { withNativeMainCredentialClaim, isNativeMainClaimUnavailable } from "./http";
import { withNativeMainCredentialClaim, isNativeMainClaimUnavailable, isNativeMainObservationUnavailable } from "./http";
import { fetchMainAccountInfoAttempt, EMPTY_MAIN_ACCOUNT_INFO, mainResetCreditsForCurrentIdentity } from "./main-account-probe";
import { fetchPoolAccountQuota, PoolQuotaProbeBusyError, POOL_QUOTA_REFRESH_CONCURRENCY } from "./pool-quota-probe";
import type { PoolQuotaResult } from "./pool-quota-probe";
Expand Down Expand Up @@ -442,7 +442,7 @@ export async function listCodexAuthAccountsSnapshot(
try {
return await withNativeMainCredentialClaim(async () => projectSnapshot(isMainAccountRefreshGrantRejected()));
} catch (error) {
if (isNativeMainClaimUnavailable(error)) return projectSnapshot();
if (isNativeMainObservationUnavailable(error)) return projectSnapshot();
throw error;
} finally {
projectionLease.release();
Expand Down
13 changes: 13 additions & 0 deletions src/codex/auth-api/http.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
import { codexHomeIsAbsent } from "../codex-home-owner";
import { getCodexHome } from "../paths";
import { withNativeMainSharedClaim } from "../native-main-claim";
import { resolveNativeProfileContext } from "../native-profile-store";
import { NativeProfileError } from "../native-profile-types";
Expand All @@ -7,6 +9,17 @@ export function isNativeMainClaimUnavailable(error: unknown): error is NativePro
&& (error.code === "NATIVE_MAIN_CLAIM_BUSY" || error.code === "NATIVE_MAIN_CLAIM_UNAVAILABLE");
}

/** Missing native homes leave reads unobserved; credential operations still require their claim. */
export function isNativeMainObservationUnavailable(error: unknown): error is NativeProfileError {
if (isNativeMainClaimUnavailable(error)) return true;
if (!(error instanceof NativeProfileError) || error.code !== "CODEX_HOME_UNAVAILABLE") return false;
try {
return codexHomeIsAbsent(getCodexHome());
} catch {
return false;
}
}

export function withNativeMainCredentialClaim<T>(operation: () => Promise<T>): Promise<T> {
return withNativeMainSharedClaim(resolveNativeProfileContext(), operation);
}
Expand Down
4 changes: 2 additions & 2 deletions src/codex/auth-api/main-account-probe.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ import type { AdmissionLease } from "../../lib/admission";
import { nonEmptyPlan } from "./runtime-config";
import { tryAcquireNativeMainProfileClaim } from "../native-main-admission";
import { WHAM_REQUEST_TIMEOUT_MS } from "../quota-recovery-timing";
import { withNativeMainCredentialClaim, isNativeMainClaimUnavailable } from "./http";
import { withNativeMainCredentialClaim, isNativeMainObservationUnavailable } from "./http";
import { readMainAuthErrorCode, currentQuotaDispatchSequence, nextQuotaDispatchSequence, isQuotaDispatchCurrent, publishQuotaDispatch } from "./pool-quota-probe";

/**
Expand Down Expand Up @@ -198,7 +198,7 @@ export async function fetchMainAccountInfoAttempt(
try {
return await withNativeMainCredentialClaim(operation);
} catch (error) {
if (isNativeMainClaimUnavailable(error)) {
if (isNativeMainObservationUnavailable(error)) {
return {
info: EMPTY_MAIN_ACCOUNT_INFO,
credentialChecked: false,
Expand Down
3 changes: 2 additions & 1 deletion src/codex/native-profile-store.ts
Original file line number Diff line number Diff line change
Expand Up @@ -353,8 +353,9 @@ export function assertNativeProfileLockPath(context: NativeProfileContext): void
}

export function resolveNativeProfileContext(options: { codexHome?: string; configDir?: string } = {}): NativeProfileContext {
const codexHome = canonicalExistingDirectory(options.codexHome ?? getCodexHome(), "The effective CODEX_HOME");
// Read-only callers may tolerate an absent native home, but never unsafe OpenCodex storage.
const configDir = canonicalizeDirectoryPath(options.configDir ?? getConfigDir());
const codexHome = canonicalExistingDirectory(options.codexHome ?? getCodexHome(), "The effective CODEX_HOME");
const homeId = nativeProfileHomeId(codexHome);
const foldedHomeId = process.platform === "win32" ? legacyWindowsNativeProfileHomeId(codexHome) : homeId;
const instanceId = createHash("sha256").update(DOMAIN_INSTANCE).update(configDir).digest("hex");
Expand Down
6 changes: 3 additions & 3 deletions structure/providers/openai-accounts.md
Original file line number Diff line number Diff line change
Expand Up @@ -250,9 +250,9 @@ restored from the Accounts picker or Codex Auth through gated recovery: missing
from the canonical preset, disabled canonical rows are re-enabled without replacing saved mode or
model settings, and noncanonical `openai` rows never receive that recovery path.

`GET /api/codex-auth/accounts?refresh=1` treats missing main credentials, HTTP 401, and allowlisted
terminal 403 codes as `needsReauth`; generic permission failures remain non-terminal, and a
successful main usage refresh clears the runtime mark.
Account listing and explicit refresh return stored pool accounts without creating a missing native `CODEX_HOME`; an unchecked main observation leaves credential/reauth state unchanged.
When the native home is accessible, `GET /api/codex-auth/accounts?refresh=1` treats missing main credentials, HTTP 401 responses with a known terminal code, unrecognized HTTP 401 responses when the access token is not verifiably live, and allowlisted terminal 403 responses as `needsReauth`; successful refresh clears the runtime mark.
Generic quota permission failures remain non-terminal; missing-home fallback requires proven absence, so non-directory homes, dangling links, and parent directories that cannot be traversed still fail closed for both default and explicit home paths. Native-profile context resolution validates OpenCodex storage before the native home, so unsafe storage fails closed even when that home is absent; credential operations retain their strict claim requirements.

`src/codex/chatgpt-refresh-failure.ts` classifies token-endpoint failures for both stored-pool
and native-main refresh. Exact structured terminal codes apply only to authentication-error
Expand Down
Loading
Loading