From e0a1a8836e447ece3010ba98813e6feb3161eefd Mon Sep 17 00:00:00 2001 From: t Date: Mon, 7 Sep 2026 19:33:29 +0900 Subject: [PATCH 1/3] docs: complete Raycast status and model-name recovery guidance [skip ci] --- .../content/docs/fr/guides/integrations.md | 2 +- .../fr/reference/configuration/providers.md | 18 +++++++++ .../src/content/docs/guides/integrations.md | 24 ++++++++---- .../ja/reference/configuration/providers.md | 16 ++++++++ .../ko/reference/configuration/providers.md | 14 +++++++ .../ru/reference/configuration/providers.md | 18 +++++++++ .../tr/reference/configuration/providers.md | 17 ++++++++ .../reference/configuration/providers.md | 12 ++++++ .../reference/configuration/providers.md | 12 ++++++ src/cli/integrations.ts | 2 +- tests/cli/cli-headless-parity.test.ts | 39 +++++++++++++++++++ 11 files changed, 164 insertions(+), 10 deletions(-) diff --git a/docs-site/src/content/docs/fr/guides/integrations.md b/docs-site/src/content/docs/fr/guides/integrations.md index c718801ddc8..97babedd183 100644 --- a/docs-site/src/content/docs/fr/guides/integrations.md +++ b/docs-site/src/content/docs/fr/guides/integrations.md @@ -128,7 +128,7 @@ niveaux. Dans ces cas, le commutateur est verrouillé afin que rien ne soit modi **OMP** n'est pas affecté non plus par les modifications voisines, mais pour une autre raison : son outil d'écriture ne modifie, octet par octet, que sa propre plage `providers.opencodex` ; le reste du fichier n'est jamais réécrit. Pour les autres formats susceptibles de contenir des commentaires (Hermes, OpenClaw, -Kimi Code, Gajae Code, MiniMax Code, ZCode, Prime Agent, Aside et Raycast — documents YAML, JSON5 et TOML réécrits en entier), ou lorsque les propres entrées +Kimi Code, Gajae Code, MiniMax Code et Raycast — documents YAML, JSON5 et TOML réécrits en entier), ou lorsque les propres entrées 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. diff --git a/docs-site/src/content/docs/fr/reference/configuration/providers.md b/docs-site/src/content/docs/fr/reference/configuration/providers.md index 96d00e5668c..9686bb24708 100644 --- a/docs-site/src/content/docs/fr/reference/configuration/providers.md +++ b/docs-site/src/content/docs/fr/reference/configuration/providers.md @@ -473,6 +473,24 @@ avec un contexte de `922000` et une entrée maximale de `922000` ; OpenRouter i } ``` +## Éditeur de noms d'affichage des modèles + +Dans le tableau de bord, **Models** permet d'enregistrer durablement des noms lisibles pour les modèles découverts. Développez le fournisseur, +repérez un modèle découvert et choisissez **Name**. La boîte de dialogue garde le sélecteur exact +`provider/model` visible pendant que vous enregistrez un libellé lisible. Choisissez **Reset name** +pour revenir aux métadonnées du fournisseur ou au sélecteur utilisé par défaut. **Name** ne change +que l'affichage ; le crayon distinct consacré à l'alias modifie l'alias court de routage et n'est +pas un éditeur de nom d'affichage. Les lignes OpenAI natives et celles des modèles personnalisés +conservent leurs commandes existantes. + +Si la modification est enregistrée mais que l'actualisation échoue, la boîte de dialogue reflète +la valeur enregistrée et garde **Retry** disponible. Retry relance la convergence du catalogue +si le serveur a signalé son échec, ou recharge la liste si seule la requête de liste a échoué. +La reprise d'une réinitialisation conserve cette opération ; elle ne rétablit pas l'ancien nom. +Les requêtes ont un délai maximal de 60 secondes couvrant l'écriture et l'actualisation de la liste +qui suit. Un dépassement de délai n'annule pas une écriture : utilisez **Retry** pour vérifier +le nom actuel avant d'effectuer une autre modification. + ## Exemple complet ```json diff --git a/docs-site/src/content/docs/guides/integrations.md b/docs-site/src/content/docs/guides/integrations.md index ea3c93f2dda..b475b71e201 100644 --- a/docs-site/src/content/docs/guides/integrations.md +++ b/docs-site/src/content/docs/guides/integrations.md @@ -62,14 +62,22 @@ One caveat specific to Aside: the running app rewrites `models.json` itself, so fully quit and reopen Aside after applying, the same way Claude Desktop needs a restart. Aside's block is loopback-only and never carries a real credential. -Raycast has two prerequisites. Custom Providers is a **Raycast Pro** feature: on a -free plan the file is still written, but `ocx integration client status --client -raycast` and the Integrations page report a warning, because Raycast will not -read it. And Raycast only creates its `ai` folder when you open Raycast → -Settings → AI → **Reveal Providers Config** once; opencodex uses that folder as -the install signal and reports the client as not installed until then. Raycast -reads `~/.config/raycast/ai/providers.yaml` on macOS and Windows alike and does -not honor `XDG_CONFIG_HOME`, so that path is not relocatable. +The managed Raycast integration supports **macOS and Windows**. Custom Providers +is a **Raycast Pro** feature: on a free plan the file is still written, but +`ocx integration client status --client raycast` and the Integrations page report +a warning, because Raycast will not read it. On macOS or Windows, open Raycast → +Settings → AI → **Reveal Providers Config** once so the `ai` folder exists. +On these supported platforms, opencodex uses that folder as its install signal +and reports the client as not installed until it exists. Linux is unsupported, +even if the folder exists. + +The status field `aiDirPresent` reports only whether `~/.config/raycast/ai` exists, +independently of whether the Raycast app is installed or the platform is supported. +It does not prove that Raycast is installed or usable. The CLI prints `plan` on a +separate line and adds the macOS/Windows setup instruction when `aiDirPresent` is +false; `--json` preserves the raw status, including the nested `raycast` block. +Raycast reads `~/.config/raycast/ai/providers.yaml` on macOS and Windows alike and +does not honor `XDG_CONFIG_HOME`, so that path is not relocatable. The managed block is one element, `id: opencodex`, in the file's `providers` sequence: `name: OpenCodex`, `base_url: http://:/v1`, and every diff --git a/docs-site/src/content/docs/ja/reference/configuration/providers.md b/docs-site/src/content/docs/ja/reference/configuration/providers.md index 8938073e6c5..dc7929d26e5 100644 --- a/docs-site/src/content/docs/ja/reference/configuration/providers.md +++ b/docs-site/src/content/docs/ja/reference/configuration/providers.md @@ -394,6 +394,22 @@ Vercel AI Gateway は、1 つのモデルを複数の基盤となる推論プロ } ``` +## モデルの表示名エディター + +ダッシュボードの **Models** では、検出されたモデルに読みやすい名前を付けて永続的に保存できます。プロバイダーを展開し、検出された +モデルを見つけて **Name** を選択します。読みやすい名前を保存する間も、ダイアログには正確な +`provider/model` セレクターが表示されます。**Reset name** を選ぶと、プロバイダーのメタデータ、 +または通常のセレクター表示に戻ります。**Name** が変更するのは表示だけです。別のエイリアス用 +鉛筆アイコンは短いルーティングエイリアスを変更するもので、表示名エディターではありません。 +ネイティブ OpenAI とカスタムモデルの行では、既存の操作方法が維持されます。 + +変更は保存されたものの更新に失敗した場合、ダイアログは保存済みの上書き設定を反映し、**Retry** を +引き続き利用できます。サーバーがカタログの収束処理の失敗を報告した場合、Retry はその処理を再実行し、 +一覧取得のリクエストだけが失敗した場合は一覧を再読み込みします。リセット後の復旧でもリセット操作を +維持し、以前の名前には戻しません。リクエストには、書き込みとその後の一覧更新を合わせて 60 秒の +期限があります。タイムアウトしても書き込みは取り消されません。次の変更を行う前に **Retry** で +現在の名前を確認してください。 + ## 完全な例 ```json diff --git a/docs-site/src/content/docs/ko/reference/configuration/providers.md b/docs-site/src/content/docs/ko/reference/configuration/providers.md index 2dda27e7bfe..75ae5055b65 100644 --- a/docs-site/src/content/docs/ko/reference/configuration/providers.md +++ b/docs-site/src/content/docs/ko/reference/configuration/providers.md @@ -401,6 +401,20 @@ Vercel AI Gateway는 하나의 모델을 여러 기반 추론 공급자에 걸 } ``` +## 모델 표시 이름 편집기 + +대시보드의 **Models**에서 발견된 모델의 읽기 쉬운 이름을 저장해 유지할 수 있습니다. 공급자를 펼치고 발견된 모델을 +찾아 **Name**을 선택하세요. 읽기 쉬운 이름을 저장하는 동안에도 대화 상자는 정확한 `provider/model` +선택자를 표시합니다. **Reset name**을 선택하면 공급자 메타데이터 또는 기본 선택자 표시로 돌아갑니다. +**Name**은 표시만 바꿉니다. 별도의 별칭 연필 아이콘은 짧은 라우팅 별칭을 바꾸며, 표시 이름 편집기가 +아닙니다. 네이티브 OpenAI와 사용자 지정 모델 행은 기존 조작 방식을 유지합니다. + +변경은 저장됐지만 새로고침에 실패하면 대화 상자는 저장된 재정의를 반영하고 **Retry**를 계속 제공합니다. +서버가 카탈로그 수렴 실패를 보고했다면 Retry는 수렴을 다시 실행하고, 목록 요청만 실패했다면 목록을 +다시 불러옵니다. 초기화 후 복구는 초기화 작업을 유지하며 이전 이름을 복원하지 않습니다. 요청에는 +쓰기와 후속 목록 새로고침을 모두 포함하는 60초 제한이 있습니다. 시간 초과가 쓰기를 취소하지는 않습니다. +다른 변경을 하기 전에 **Retry**로 현재 이름을 확인하세요. + ## 전체 예시 ```json diff --git a/docs-site/src/content/docs/ru/reference/configuration/providers.md b/docs-site/src/content/docs/ru/reference/configuration/providers.md index 14a8b0a3ceb..3ddb29c806e 100644 --- a/docs-site/src/content/docs/ru/reference/configuration/providers.md +++ b/docs-site/src/content/docs/ru/reference/configuration/providers.md @@ -488,6 +488,24 @@ Pool/Direct рекламирует `922000`; синхронизированны } ``` +## Редактор отображаемых имён моделей + +На странице **Models** в дашборде можно задать понятные имена для обнаруженных моделей и сохранить их для дальнейшего использования. Разверните провайдера, +найдите обнаруженную модель и выберите **Name**. При сохранении понятной подписи диалог оставляет +видимым точный селектор `provider/model`. Выберите **Reset name**, чтобы вернуться к metadata +провайдера или обычному селектору, используемому по умолчанию. **Name** меняет только отображение; +отдельный значок карандаша для alias меняет короткий routing alias и не является редактором +отображаемого имени. Нативные строки OpenAI и строки пользовательских моделей сохраняют +существующие элементы управления. + +Если изменение сохранено, но обновление не удалось, диалог отражает сохранённое переопределение +и оставляет **Retry** доступным. Retry повторяет приведение каталога к согласованному состоянию, +если сервер сообщил о сбое этого процесса, или перезагружает список, если не удался только запрос +списка. Восстановление после сброса сохраняет операцию сброса и не возвращает старое имя. +Для запросов действует общий срок в 60 секунд, включающий запись и последующее обновление списка. +Тайм-аут не отменяет запись: используйте **Retry**, чтобы проверить текущее имя перед следующим +изменением. + ## Полный пример ```json diff --git a/docs-site/src/content/docs/tr/reference/configuration/providers.md b/docs-site/src/content/docs/tr/reference/configuration/providers.md index 3e01051010c..daffcd2120f 100644 --- a/docs-site/src/content/docs/tr/reference/configuration/providers.md +++ b/docs-site/src/content/docs/tr/reference/configuration/providers.md @@ -518,6 +518,23 @@ bildirir; senkronize edilen katalog `xhigh`'ı ayrı tutarken `max` bildirir. } ``` +## Model görünen adı düzenleyicisi + +Kontrol panelindeki **Models**, keşfedilen modeller için okunabilir adları kalıcı olarak kaydetmenizi sağlar. Sağlayıcıyı genişletin, keşfedilen +bir modeli bulun ve **Name** seçeneğini seçin. Okunabilir bir etiket kaydederken iletişim kutusu +tam `provider/model` seçicisini görünür tutar. Sağlayıcı meta verilerine veya varsayılan seçici +gösterimine dönmek için **Reset name** seçeneğini seçin. **Name** yalnızca görünümü değiştirir; +ayrı takma ad kalemi kısa yönlendirme takma adını değiştirir ve bir görünen ad düzenleyicisi +değildir. Yerel OpenAI ve özel model satırları mevcut kontrollerini korur. + +Değişiklik kaydedildiği halde yenileme başarısız olursa iletişim kutusu kaydedilen geçersiz kılma +değerini yansıtır ve **Retry** kullanılabilir kalır. Sunucu katalog yakınsamasının başarısız +olduğunu bildirdiyse Retry bu işlemi tekrarlar; yalnızca liste isteği başarısız olduysa listeyi +yeniden yükler. Sıfırlama sonrası kurtarma, sıfırlama işlemini korur ve eski adı geri getirmez. +İsteklerin, yazma işlemini ve ardından gelen liste yenilemesini kapsayan 60 saniyelik bir süresi +vardır. Zaman aşımı yazma işlemini geri almaz: başka bir değişiklik yapmadan önce **Retry** ile +geçerli adı kontrol edin. + ## Tam örnek ```json diff --git a/docs-site/src/content/docs/zh-cn/reference/configuration/providers.md b/docs-site/src/content/docs/zh-cn/reference/configuration/providers.md index 32f2b52a694..313663f346b 100644 --- a/docs-site/src/content/docs/zh-cn/reference/configuration/providers.md +++ b/docs-site/src/content/docs/zh-cn/reference/configuration/providers.md @@ -395,6 +395,18 @@ Vercel AI Gateway 可以在多个底层推理提供者之间路由一个模型 } ``` +## 模型显示名称编辑器 + +仪表板的 **Models** 可让你为已发现的模型持久保存易读名称。展开提供者,找到一个已发现的模型,然后选择 **Name**。 +保存易读名称时,对话框会一直显示精确的 `provider/model` 选择器。选择 **Reset name** 可恢复为 +提供者元数据中的名称,或默认的选择器显示。**Name** 只改变显示;单独的别名铅笔图标用于修改 +短路由别名,并不是显示名称编辑器。原生 OpenAI 和自定义模型条目保留现有控件。 + +如果更改已保存但刷新失败,对话框会反映已保存的覆盖值,并继续提供 **Retry**。如果服务器报告 +目录收敛失败,Retry 会重新执行目录收敛;如果只是列表请求失败,则重新加载列表。重置后的恢复 +会保留重置操作,不会恢复旧名称。请求的总时限为 60 秒,涵盖写入及后续的列表刷新。超时不会撤销 +写入:进行其他更改前,请使用 **Retry** 检查当前名称。 + ## 完整示例 ```json diff --git a/docs-site/src/content/docs/zh-tw/reference/configuration/providers.md b/docs-site/src/content/docs/zh-tw/reference/configuration/providers.md index 2a53c4d33ad..74ee860ff14 100644 --- a/docs-site/src/content/docs/zh-tw/reference/configuration/providers.md +++ b/docs-site/src/content/docs/zh-tw/reference/configuration/providers.md @@ -352,6 +352,18 @@ Vercel AI Gateway 可在多個底層推論供應商之間路由一個模型。`v } ``` +## 模型顯示名稱編輯器 + +儀表板的 **Models** 可讓你為已探索到的模型持久儲存易讀名稱。展開供應商,找到已探索到的模型,然後選擇 **Name**。 +儲存易讀名稱時,對話方塊會持續顯示精確的 `provider/model` 選擇器。選擇 **Reset name** 可回到 +供應商中繼資料中的名稱,或預設的選擇器顯示。**Name** 只改變顯示;獨立的別名鉛筆圖示用來修改 +短路由別名,並不是顯示名稱編輯器。原生 OpenAI 與自訂模型列保留既有控制項。 + +若變更已儲存但重新整理失敗,對話方塊會反映已儲存的覆寫值,並繼續提供 **Retry**。若伺服器回報 +目錄收斂失敗,Retry 會重新執行目錄收斂;若只有清單請求失敗,則重新載入清單。重設後的復原 +會保留重設操作,不會還原舊名稱。請求的總期限為 60 秒,涵蓋寫入及後續的清單重新整理。逾時不會 +撤銷寫入:進行其他變更前,請使用 **Retry** 檢查目前名稱。 + ## 完整範例 ```json diff --git a/src/cli/integrations.ts b/src/cli/integrations.ts index 89ab3ee0466..5b690a6c8b5 100644 --- a/src/cli/integrations.ts +++ b/src/cli/integrations.ts @@ -189,7 +189,7 @@ function singleClientStatusLines(result: unknown): string[] { const rest = Object.fromEntries(Object.entries(result as Record).filter(([key]) => key !== "raycast")); const lines = [...summaryLines(rest), `plan: ${raycast.plan}`]; if (!raycast.aiDirPresent) { - lines.push('Open Raycast → Settings → AI → "Reveal Providers Config" once so the ai folder exists.'); + lines.push('On macOS or Windows, open Raycast → Settings → AI → "Reveal Providers Config" once so the ai folder exists.'); } return lines; } diff --git a/tests/cli/cli-headless-parity.test.ts b/tests/cli/cli-headless-parity.test.ts index dab85a132ca..78f0cc04a1f 100644 --- a/tests/cli/cli-headless-parity.test.ts +++ b/tests/cli/cli-headless-parity.test.ts @@ -609,6 +609,45 @@ describe("headless GUI parity CLI", () => { expect(runtime.requests[1]).toEqual({ path: "/api/grok/selection", method: "PUT", body: { excluded: ["b"] } }); }); + for (const plan of ["pro", "free", "unknown"] as const) { + for (const aiDirPresent of [true, false]) { + test(`Raycast status keeps plan ${plan} separate with aiDirPresent=${aiDirPresent}`, async () => { + const payload = { + clientId: "raycast", + installed: aiDirPresent, + raycast: { plan, aiDirPresent }, + }; + const runtime = fakeRuntime(() => payload); + const logSpy = spyOn(console, "log").mockImplementation(() => {}); + try { + expect(await handleClientIntegrationCommand(["status", "--client", "raycast"], runtime.deps)).toBe(0); + const out = logSpy.mock.calls.map(call => String(call[0])).join("\n"); + const lines = out.split("\n"); + expect(lines.filter(line => line.startsWith("plan:"))).toEqual([`plan: ${plan}`]); + expect(out).not.toContain("raycast."); + if (aiDirPresent) { + expect(out).not.toContain("Reveal Providers Config"); + } else { + expect(lines).toContain('On macOS or Windows, open Raycast → Settings → AI → "Reveal Providers Config" once so the ai folder exists.'); + } + + logSpy.mockClear(); + expect(await handleClientIntegrationCommand(["status", "--client", "raycast", "--json"], runtime.deps)).toBe(0); + expect(logSpy.mock.calls).toHaveLength(1); + const jsonOut = String(logSpy.mock.calls[0]![0]); + expect(JSON.parse(jsonOut)).toEqual(payload); + expect(jsonOut).not.toContain("Reveal Providers Config"); + expect(runtime.requests).toEqual([ + { path: "/api/client-integrations/raycast", method: "GET", body: null }, + { path: "/api/client-integrations/raycast", method: "GET", body: null }, + ]); + } finally { + logSpy.mockRestore(); + } + }); + } + } + test("client integration toggles hit the exact management routes", async () => { const runtime = fakeRuntime(); expect(await handleClientIntegrationCommand(["enable", "--client", "hermes", "--json"], runtime.deps)).toBe(0); From 568a3e89cb4bc67987d86acbf5e9d63fb3015c9b Mon Sep 17 00:00:00 2001 From: t Date: Mon, 7 Sep 2026 19:36:04 +0900 Subject: [PATCH 2/3] docs: record code-mode delivery and qualify Desktop model switching [skip ci] --- .../040_delivery_record.md | 100 ++++++++++++++++++ .../src/content/docs/guides/claude-code.md | 12 ++- 2 files changed, 110 insertions(+), 2 deletions(-) create mode 100644 devlog/_plan/260907_code_mode_host_contract/040_delivery_record.md diff --git a/devlog/_plan/260907_code_mode_host_contract/040_delivery_record.md b/devlog/_plan/260907_code_mode_host_contract/040_delivery_record.md new file mode 100644 index 00000000000..3c2b28e23d8 --- /dev/null +++ b/devlog/_plan/260907_code_mode_host_contract/040_delivery_record.md @@ -0,0 +1,100 @@ +# 040 — Delivery record: code-mode host contract + +Recorded 2026-09-07 from GitHub PR and Actions API responses. This records the delivery requested +by [030_docs_and_delivery.md](030_docs_and_delivery.md#d-record). + +## Delivered revision and CI identity + +- [PR #3854](https://github.com/lidge-jun/opencodex/pull/3854) is merged into `dev`; + GitHub records `merged_at: 2026-09-07T06:41:03Z`. +- Final PR head: `6bdcba5bff4196debf3cd159c7af3d34e35a24e0`. +- Merge commit: `ece556a6ed32dc811bd660ddd8ef9e829512457a`. +- [Pre-merge CI run 34090946313](https://github.com/lidge-jun/opencodex/actions/runs/34090946313), + attempt 1: `event: pull_request`, `head_sha: 6bdcba5bff4196debf3cd159c7af3d34e35a24e0`, + `status: completed`, `conclusion: success`; updated `2026-09-07T06:39:04Z`. +- [Merge-head CI run 34091933836](https://github.com/lidge-jun/opencodex/actions/runs/34091933836), attempt 1: + `event: push`, `head_sha: ece556a6ed32dc811bd660ddd8ef9e829512457a`, + `status: completed`, `conclusion: success`; updated `2026-09-07T06:50:18Z`. + +The pre-merge run matches the final PR head; the later push run matches the merge commit. +These are distinct CI records. This API check does not attest that the separate local receipt +required by 030 was recorded. + +## Per-job results + +Each run has 21 completed jobs: 19 success, 2 skipped. Every job has the same conclusion in both +runs. Names below are the literal Actions job names; each evidence link identifies its own run. + +| Job | Conclusion in both runs | Pre-merge evidence | Merge-head evidence | +|---|---|---|---| +| `select windows runner` | success | [job 101644191502](https://github.com/lidge-jun/opencodex/actions/runs/34090946313/job/101644191502) | [job 101647069433](https://github.com/lidge-jun/opencodex/actions/runs/34091933836/job/101647069433) | +| `changes` | success | [job 101644191303](https://github.com/lidge-jun/opencodex/actions/runs/34090946313/job/101644191303) | [job 101647069779](https://github.com/lidge-jun/opencodex/actions/runs/34091933836/job/101647069779) | +| `windows ${{ matrix.shard }}/6` | skipped | [job 101644212182](https://github.com/lidge-jun/opencodex/actions/runs/34090946313/job/101644212182) | [job 101647096144](https://github.com/lidge-jun/opencodex/actions/runs/34091933836/job/101647096144) | +| `macos 1/2` | success | [job 101644233998](https://github.com/lidge-jun/opencodex/actions/runs/34090946313/job/101644233998) | [job 101647111898](https://github.com/lidge-jun/opencodex/actions/runs/34091933836/job/101647111898) | +| `api usage` | success | [job 101644234038](https://github.com/lidge-jun/opencodex/actions/runs/34090946313/job/101644234038) | [job 101647111914](https://github.com/lidge-jun/opencodex/actions/runs/34091933836/job/101647111914) | +| `storage policy` | success | [job 101644234034](https://github.com/lidge-jun/opencodex/actions/runs/34090946313/job/101644234034) | [job 101647111922](https://github.com/lidge-jun/opencodex/actions/runs/34091933836/job/101647111922) | +| `docker smoke` | success | [job 101644234277](https://github.com/lidge-jun/opencodex/actions/runs/34090946313/job/101644234277) | [job 101647111928](https://github.com/lidge-jun/opencodex/actions/runs/34091933836/job/101647111928) | +| `keyring ubuntu` | success | [job 101644234063](https://github.com/lidge-jun/opencodex/actions/runs/34090946313/job/101644234063) | [job 101647111929](https://github.com/lidge-jun/opencodex/actions/runs/34091933836/job/101647111929) | +| `test 3/4` | success | [job 101644234103](https://github.com/lidge-jun/opencodex/actions/runs/34090946313/job/101644234103) | [job 101647111932](https://github.com/lidge-jun/opencodex/actions/runs/34091933836/job/101647111932) | +| `test 4/4` | success | [job 101644234047](https://github.com/lidge-jun/opencodex/actions/runs/34090946313/job/101644234047) | [job 101647111936](https://github.com/lidge-jun/opencodex/actions/runs/34091933836/job/101647111936) | +| `keyring macos` | success | [job 101644233982](https://github.com/lidge-jun/opencodex/actions/runs/34090946313/job/101644233982) | [job 101647111942](https://github.com/lidge-jun/opencodex/actions/runs/34091933836/job/101647111942) | +| `test 1/4` | success | [job 101644234139](https://github.com/lidge-jun/opencodex/actions/runs/34090946313/job/101644234139) | [job 101647111951](https://github.com/lidge-jun/opencodex/actions/runs/34091933836/job/101647111951) | +| `gates` | success | [job 101644233985](https://github.com/lidge-jun/opencodex/actions/runs/34090946313/job/101644233985) | [job 101647111970](https://github.com/lidge-jun/opencodex/actions/runs/34091933836/job/101647111970) | +| `keyring windows` | success | [job 101644234037](https://github.com/lidge-jun/opencodex/actions/runs/34090946313/job/101644234037) | [job 101647111972](https://github.com/lidge-jun/opencodex/actions/runs/34091933836/job/101647111972) | +| `macos 2/2` | success | [job 101644234066](https://github.com/lidge-jun/opencodex/actions/runs/34090946313/job/101644234066) | [job 101647111974](https://github.com/lidge-jun/opencodex/actions/runs/34091933836/job/101647111974) | +| `npm-global ubuntu-latest` | success | [job 101644234059](https://github.com/lidge-jun/opencodex/actions/runs/34090946313/job/101644234059) | [job 101647111980](https://github.com/lidge-jun/opencodex/actions/runs/34091933836/job/101647111980) | +| `npm-global windows-latest` | success | [job 101644234098](https://github.com/lidge-jun/opencodex/actions/runs/34090946313/job/101644234098) | [job 101647111990](https://github.com/lidge-jun/opencodex/actions/runs/34091933836/job/101647111990) | +| `test 2/4` | success | [job 101644234167](https://github.com/lidge-jun/opencodex/actions/runs/34090946313/job/101644234167) | [job 101647112003](https://github.com/lidge-jun/opencodex/actions/runs/34091933836/job/101647112003) | +| `npm-global macos-latest` | success | [job 101644234033](https://github.com/lidge-jun/opencodex/actions/runs/34090946313/job/101644234033) | [job 101647112012](https://github.com/lidge-jun/opencodex/actions/runs/34091933836/job/101647112012) | +| `macos control` | skipped | [job 101644235362](https://github.com/lidge-jun/opencodex/actions/runs/34090946313/job/101644235362) | [job 101647112696](https://github.com/lidge-jun/opencodex/actions/runs/34091933836/job/101647112696) | +| `ci` | success | [job 101646588871](https://github.com/lidge-jun/opencodex/actions/runs/34090946313/job/101646588871) | [job 101649082610](https://github.com/lidge-jun/opencodex/actions/runs/34091933836/job/101649082610) | + +The Windows full-suite matrix was **SKIPPED in both runs**. Windows keyring create/read/delete smoke and +npm-global packaging/install/help smoke passed; those focused passes do not establish Windows +full-suite coverage. The `ci` aggregate accepts successful or skipped prerequisites, so its green +result does not turn skipped jobs into passes. On the merge-head run, `gates` includes successful Typecheck, GUI tests, +Privacy scan, skill-surface check, release-helper syntax check, and CLI help smoke; its GUI lint, +GUI build, and dashboard-preview steps were skipped. + +Evidence retrieval (read-only): + +```sh +gh api repos/lidge-jun/opencodex/pulls/3854 +gh api repos/lidge-jun/opencodex/actions/runs/34090946313 +gh api 'repos/lidge-jun/opencodex/actions/runs/34090946313/jobs?per_page=100' +gh api repos/lidge-jun/opencodex/actions/runs/34091933836 +gh api 'repos/lidge-jun/opencodex/actions/runs/34091933836/jobs?per_page=100' +``` + +## Limits and residuals + +The delivered scope is the pre-call guidance and post-hoc recovery annotations described in +[030](030_docs_and_delivery.md). Guidance cannot force model compliance, repair the model's +JavaScript or patch payload, or replace the host's validation. The effect on the live Grok defect +rate remains **unmeasured** until a live re-probe; CI success is not a defect-rate measurement. + +Anthropic, Google, OpenAI-chat, and command-code tool-result paths still lack exec-result +annotation seams and do not annotate these host failures. Existing coverage is limited to native +routed Responses, Kiro, and Cursor. + +Two public review threads were **OPEN / UNRESOLVED in the recorded 2026-09-07 audit snapshot**: GitHub's review-thread API returned +`isResolved: false` for both on 2026-09-07. The merge and green CI do not resolve these findings. +Source inspected for that snapshot was read at worktree HEAD `0fd3408b99994f74bd509975df7ee89823ddfecd`: + +- [discussion_r3947178410](https://github.com/lidge-jun/opencodex/pull/3854#discussion_r3947178410): + `src/adapters/exec-tool-result-normalize.ts:196` searches arbitrary output for a marker substring. + Successful output from a command such as `rg` or `cat` can therefore receive a misleading + recovery hint when it quotes that phrase, even though the command did not fail. The requested + host-error status/envelope or exact diagnostic check remains unimplemented at this anchor. +- [discussion_r3947178418](https://github.com/lidge-jun/opencodex/pull/3854#discussion_r3947178418): + `src/adapters/cursor/tool-result-normalize.ts:114` gates annotation on tool name/namespace + without request-catalog or freeform provenance. A structured tool named `exec` can receive + unrelated host guidance. The requested code-mode provenance check remains unimplemented at + this anchor. + +These limitations were also recorded in [000](000_plan.md). Recording them here is not a fix, +review resolution, or claim that successful output is left byte-identical. + +Local runtime, tests, typecheck, build, and install: **NOT RUN** by instruction. No live model +re-probe was performed for this record. The remote results above belong to the recorded PR head +and merge commit and do not validate later candidate documentation or test patches. diff --git a/docs-site/src/content/docs/guides/claude-code.md b/docs-site/src/content/docs/guides/claude-code.md index 0b1c0e9db46..0c3cb326972 100644 --- a/docs-site/src/content/docs/guides/claude-code.md +++ b/docs-site/src/content/docs/guides/claude-code.md @@ -309,8 +309,16 @@ canonical ids. The synthetic 2026 date is an internal slot, not a release date. and `claude-ocx---` ids from older configs still resolve. If Claude Desktop's footer picker does not change the model for an already-running 3P -conversation, use `/model ` in that conversation. OpenCodex cannot observe picker state; it -routes the model id carried by each request. Confirm the result under **Logs → requestedModel**. +conversation, you can try `/model `, but this workaround may also fail on affected Desktop +builds. [Issue #3782](https://github.com/lidge-jun/opencodex/issues/3782) reports that on Windows +with Claude Desktop 1.46388.4, the conversation continues using its initial model after both +footer-picker and `/model` changes. The report does not establish which client or routing +component causes the behavior. + +You can also try selecting the intended default model in the OpenCodex Claude Desktop profile, +reapplying the profile, and starting a new conversation. This is a troubleshooting step, not a +guaranteed fix. OpenCodex cannot observe picker state; it routes the model id carried by each +request. Confirm what the client sends under **Logs → requestedModel**. Models with an authoritative 1M context window get an extra `…[1m]` picker row: selecting it makes Claude Code account a full 1M context for that model (auto-compaction stays on) — the proxy strips From f8c8f6dd15b1518f25a3b1cd7b15c9b6c8b24f62 Mon Sep 17 00:00:00 2001 From: t Date: Mon, 7 Sep 2026 20:29:56 +0900 Subject: [PATCH 3/3] docs: qualify Desktop model switching in translated guides [skip ci] --- .../src/content/docs/fr/guides/claude-code.md | 12 ++++++++++-- .../src/content/docs/ja/guides/claude-code.md | 15 ++++++++++++--- .../src/content/docs/ko/guides/claude-code.md | 14 +++++++++++--- .../src/content/docs/ru/guides/claude-code.md | 12 ++++++++++-- .../src/content/docs/tr/guides/claude-code.md | 16 +++++++++++++--- .../src/content/docs/zh-cn/guides/claude-code.md | 12 +++++++++--- 6 files changed, 65 insertions(+), 16 deletions(-) diff --git a/docs-site/src/content/docs/fr/guides/claude-code.md b/docs-site/src/content/docs/fr/guides/claude-code.md index 2ae39402547..e11e6a06d89 100644 --- a/docs-site/src/content/docs/fr/guides/claude-code.md +++ b/docs-site/src/content/docs/fr/guides/claude-code.md @@ -290,8 +290,16 @@ anciens alias hachés et les identifiants `claude-ocx---` des c toujours résolus. Si le sélecteur situé au bas de Claude Desktop ne modifie pas le modèle d'une conversation 3P déjà en cours, -utilisez `/model ` dans cette conversation. OpenCodex ne peut pas observer l'état du sélecteur ; il -achemine l’identifiant du modèle porté par chaque requête. Confirmez le résultat sous **Journaux → requestModel**. +vous pouvez essayer `/model `, mais ce contournement peut également échouer sur les versions de Desktop +concernées. Le [ticket #3782](https://github.com/lidge-jun/opencodex/issues/3782) rapporte que sous Windows, +avec Claude Desktop 1.46388.4, la conversation continue d'utiliser son modèle initial après des changements +via le sélecteur du bas comme via `/model`. Ce signalement ne permet pas d'établir quel composant du client +ou du routage est à l'origine de ce comportement. + +Vous pouvez aussi essayer de sélectionner le modèle par défaut souhaité dans le profil Claude Desktop +d'OpenCodex, de réappliquer ce profil et de démarrer une nouvelle conversation. Il s'agit d'une étape de +dépannage, sans garantie de résolution. OpenCodex ne peut pas observer l'état du sélecteur ; il achemine +l'identifiant du modèle porté par chaque requête. Vérifiez ce que le client envoie sous **Logs → requestedModel**. Les modèles dont la fenêtre de contexte de référence atteint 1M obtiennent une ligne supplémentaire `…[1m]` dans le sélecteur. Sa sélection indique à Claude Code la fenêtre complète de 1M pour ce modèle, tout en maintenant le compactage automatique ; le proxy retire diff --git a/docs-site/src/content/docs/ja/guides/claude-code.md b/docs-site/src/content/docs/ja/guides/claude-code.md index 384c3f50df9..adc87033400 100644 --- a/docs-site/src/content/docs/ja/guides/claude-code.md +++ b/docs-site/src/content/docs/ja/guides/claude-code.md @@ -163,9 +163,18 @@ Claude Code 2.1.129 以降は `GET /v1/models?limit=1000` でゲートウェイ 提供します。両系列は継続してデコードできるため、どちらの形式でも `settings.json` に保存したモデルは 引き続き動作します。 -Claude Desktop のフッターピッカーで実行中の 3P 会話のモデルが切り替わらない場合は、その会話で -`/model ` を使用してください。OpenCodex はピッカーの状態を直接参照できず、各リクエストに -含まれるモデル ID をルーティングします。結果は **Logs → requestedModel** で確認できます。 +Claude Desktop のフッターピッカーで実行中の 3P 会話のモデルが切り替わらない場合は、 +`/model ` を試せますが、影響を受ける Desktop ビルドではこの回避策も失敗することがあります。 +[Issue #3782](https://github.com/lidge-jun/opencodex/issues/3782) では、Windows 上の +Claude Desktop 1.46388.4 で、フッターピッカーと `/model` のどちらで変更しても、会話が最初の +モデルを使い続けると報告されています。この報告だけでは、クライアントやルーティングのどの +コンポーネントがこの動作の原因なのかは確定できません。 + +OpenCodex の Claude Desktop プロファイルで希望するデフォルトモデルを選択し、プロファイルを +再適用して、新しい会話を開始することも試せます。これはトラブルシューティングの手順であり、 +解決を保証するものではありません。OpenCodex はピッカーの状態を参照できず、各リクエストに +含まれるモデル ID をルーティングします。クライアントが何を送信しているかは +**Logs → requestedModel** で確認してください。 **エイリアス構文ルール:** provider には `/` や `--` を含められず `native` と同じでもいけません。 `/` も `~` も含まない plain な model ID は v1 接頭辞 `claude-ocx-…` のままです。`/` または `~` を含む diff --git a/docs-site/src/content/docs/ko/guides/claude-code.md b/docs-site/src/content/docs/ko/guides/claude-code.md index 676800d1e6c..90857854f01 100644 --- a/docs-site/src/content/docs/ko/guides/claude-code.md +++ b/docs-site/src/content/docs/ko/guides/claude-code.md @@ -199,9 +199,17 @@ Claude Code 2.1.129 이상은 `GET /v1/models?limit=1000`에서 게이트웨이 제공해요. 두 계열은 계속 디코딩할 수 있으므로 어느 형식이든 `settings.json`에 저장한 모델이 계속 작동해요. -Claude Desktop의 하단 선택기로 이미 실행 중인 3P 대화의 모델이 바뀌지 않는다면, 그 대화에서 -`/model `를 사용하세요. OpenCodex는 선택기 상태를 따로 볼 수 없고 각 요청에 실린 모델 ID를 -라우팅해요. 적용 결과는 **Logs → requestedModel**에서 확인할 수 있어요. +Claude Desktop의 하단 선택기로 이미 실행 중인 3P 대화의 모델이 바뀌지 않는다면, +`/model `를 시도할 수 있지만, 문제가 있는 Desktop 빌드에서는 이 우회 방법도 실패할 수 있어요. +[이슈 #3782](https://github.com/lidge-jun/opencodex/issues/3782)에는 Windows의 +Claude Desktop 1.46388.4에서 하단 선택기와 `/model`로 각각 변경해도 대화가 처음 모델을 계속 +사용한다는 보고가 있어요. 이 보고만으로는 클라이언트나 라우팅의 어느 구성 요소가 이 동작을 +일으키는지 확정할 수 없어요. + +OpenCodex의 Claude Desktop 프로필에서 원하는 기본 모델을 선택하고, 프로필을 다시 적용한 뒤 +새 대화를 시작하는 방법도 시도할 수 있어요. 이는 문제 해결을 위한 시도이며 해결을 보장하지는 +않아요. OpenCodex는 선택기 상태를 볼 수 없고 각 요청에 실린 모델 ID를 라우팅해요. +클라이언트가 실제로 무엇을 보내는지는 **Logs → requestedModel**에서 확인하세요. **별칭 문법 규칙:** provider에는 `/`나 `--`를 넣을 수 없고 `native`와 같아도 안 돼요. `/`와 `~`가 없는 plain model ID는 v1 접두사 `claude-ocx-…`를 유지해요. `/` 또는 `~`가 있는 model ID는 v2 diff --git a/docs-site/src/content/docs/ru/guides/claude-code.md b/docs-site/src/content/docs/ru/guides/claude-code.md index 60464bfb90e..f5504c9dc25 100644 --- a/docs-site/src/content/docs/ru/guides/claude-code.md +++ b/docs-site/src/content/docs/ru/guides/claude-code.md @@ -176,8 +176,16 @@ user-agent `claude-code/*` получает читаемую CLI-форму, а продолжает работать. Если нижний селектор Claude Desktop не переключает модель в уже запущенном 3P-диалоге, -используйте `/model ` внутри этого диалога. OpenCodex не видит состояние селектора и -маршрутизирует id модели из каждого запроса. Результат можно проверить в **Logs → requestedModel**. +можно попробовать `/model `, но в затронутых сборках Desktop этот обходной способ тоже может +не сработать. В [issue #3782](https://github.com/lidge-jun/opencodex/issues/3782) сообщается, что +в Windows с Claude Desktop 1.46388.4 диалог продолжает использовать исходную модель после изменений +как через нижний селектор, так и через `/model`. Это сообщение не устанавливает, какой компонент +клиента или маршрутизации вызывает такое поведение. + +Можно также попробовать выбрать нужную модель по умолчанию в профиле Claude Desktop в OpenCodex, +повторно применить профиль и начать новый диалог. Это шаг по устранению неполадки, а не гарантированное +решение. OpenCodex не видит состояние селектора; он маршрутизирует id модели, переданный в каждом +запросе. Проверьте, что отправляет клиент, в **Logs → requestedModel**. **Правила грамматики алиасов:** provider не может содержать `/` или `--` и не может быть равен `native`. Обычные id моделей (без `/` и `~`) остаются с префиксом v1 `claude-ocx-…`. Id с `/` diff --git a/docs-site/src/content/docs/tr/guides/claude-code.md b/docs-site/src/content/docs/tr/guides/claude-code.md index 4be81a4de8f..497f5e635bb 100644 --- a/docs-site/src/content/docs/tr/guides/claude-code.md +++ b/docs-site/src/content/docs/tr/guides/claude-code.md @@ -332,9 +332,19 @@ takma adlar ve eski yapılandırmalardan gelen `claude-ocx---` kimlikleri hala çözümlenir. Claude Desktop'ın altbilgi seçicisi zaten çalışan bir 3P görüşmesi için modeli -değiştirmezse, o görüşmede `/model ` komutunu kullanın. OpenCodex seçici -durumunu gözlemleyemez; her isteğin taşıdığı model kimliğini yönlendirir. Sonucu -**Logs → requestedModel** altında onaylayın. +değiştirmezse, `/model ` komutunu deneyebilirsiniz; ancak bu geçici çözüm de +etkilenen Desktop derlemelerinde başarısız olabilir. +[Sorun #3782](https://github.com/lidge-jun/opencodex/issues/3782), Windows üzerinde +Claude Desktop 1.46388.4 ile hem altbilgi seçicisi hem de `/model` üzerinden yapılan +değişikliklerden sonra görüşmenin ilk modelini kullanmaya devam ettiğini bildiriyor. +Bu bildirim, davranışa hangi istemci veya yönlendirme bileşeninin neden olduğunu +ortaya koymuyor. + +OpenCodex Claude Desktop profilinde istediğiniz varsayılan modeli seçmeyi, profili +yeniden uygulamayı ve yeni bir görüşme başlatmayı da deneyebilirsiniz. Bu bir sorun +giderme adımıdır; kesin çözüm değildir. OpenCodex seçici durumunu gözlemleyemez; +her isteğin taşıdığı model kimliğini yönlendirir. İstemcinin ne gönderdiğini +**Logs → requestedModel** altında kontrol edin. Yetkili 1M bağlam penceresine sahip modeller fazladan bir `…[1m]` seçici satırı alır: bunu seçmek Claude Code'un bu model için tam 1M bağlam hesabı yapmasını diff --git a/docs-site/src/content/docs/zh-cn/guides/claude-code.md b/docs-site/src/content/docs/zh-cn/guides/claude-code.md index dd8bc740b83..216766f70ce 100644 --- a/docs-site/src/content/docs/zh-cn/guides/claude-code.md +++ b/docs-site/src/content/docs/zh-cn/guides/claude-code.md @@ -157,9 +157,15 @@ opencodex 会将已路由模型公开为稳定且可逆的别名: user-agent 会获得易读的 CLI 形式,其他客户端会获得 Desktop 哈希形式。两种别名族都会永久 保持可解码——以任一形式保存在 `settings.json` 中的模型都能继续工作。 -如果 Claude Desktop 底部的选择器没有切换已运行 3P 对话的模型,请在该对话中使用 -`/model `。OpenCodex 无法读取选择器状态,只会路由每个请求实际携带的模型 ID;可在 -**Logs → requestedModel** 中确认结果。 +如果 Claude Desktop 底部的选择器没有切换正在进行的 3P 对话的模型,可以尝试 +`/model `,但在受影响的 Desktop 版本中,这种变通方法也可能失败。 +[Issue #3782](https://github.com/lidge-jun/opencodex/issues/3782) 报告称,在 Windows 上使用 +Claude Desktop 1.46388.4 时,无论通过底部选择器还是 `/model` 更改模型,对话都会继续使用 +最初的模型。该报告并未确定是哪个客户端组件或路由组件导致了这一行为。 + +也可以尝试在 OpenCodex 的 Claude Desktop 配置档案中选择所需的默认模型,重新应用配置档案, +然后开始新对话。这是一项排查步骤,不保证能解决问题。OpenCodex 无法读取选择器状态, +而是根据每个请求携带的模型 ID 进行路由。请在 **Logs → requestedModel** 中确认客户端实际发送的内容。 **别名语法规则:**provider 不得包含 `/` 或 `--`,也不得等于 `native`。 不含 `/` 或 `~` 的普通 model ID 继续使用 v1 前缀 `claude-ocx-…`。包含 `/` 或 `~` 的 model ID