From 71c57ea647fbc376d1207f11d851c09504c9c02d Mon Sep 17 00:00:00 2001 From: bitkyc08-arch Date: Tue, 25 Aug 2026 10:37:05 +0900 Subject: [PATCH 1/4] release: v2.32.1 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index f73ed2d0e5..063ecfe73e 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@bitkyc08/opencodex", - "version": "2.32.0", + "version": "2.32.1", "description": "Universal provider proxy for OpenAI Codex & Claude Code — use any LLM with Codex CLI/App/SDK and Claude Code", "type": "module", "main": "./bin/package-main.mjs", From ec51e42d745d2645bcb22cb67855fa053ba1778e Mon Sep 17 00:00:00 2001 From: bitkyc08-arch Date: Tue, 25 Aug 2026 20:25:22 +0900 Subject: [PATCH 2/4] release: v2.33.0 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 063ecfe73e..6f8499ffbf 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@bitkyc08/opencodex", - "version": "2.32.1", + "version": "2.33.0", "description": "Universal provider proxy for OpenAI Codex & Claude Code — use any LLM with Codex CLI/App/SDK and Claude Code", "type": "module", "main": "./bin/package-main.mjs", From aaa9eaf37058965373dc42d1ca344e987950b6b6 Mon Sep 17 00:00:00 2001 From: JUN Date: Wed, 2 Sep 2026 18:43:29 +0900 Subject: [PATCH 3/4] fix(release): pass the bump job's permissions through the reusable-workflow call (#3262) Both v2.40.0 release dispatches (33615174183 preview, 33615177849 main) died at startup_failure: a workflow_call cannot grant its callee more than the calling job holds, and dev-version-bump.yml's job declares contents+pull- requests write. #3129 wired the call but never dispatched a release, so this is its first live run. The caller job now declares exactly the callee's two permissions; no other job in release.yml gains anything. Co-authored-by: jun (cherry picked from commit 7ce0ba51834740d7b4d5ec4793f6572d84624409) --- .github/workflows/release.yml | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 458bb67e0a..261aece1d1 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -67,6 +67,14 @@ jobs: bump-dev-version: needs: publish if: ${{ inputs.dry-run != true }} + # A reusable-workflow CALL cannot grant the callee more than the calling job holds, + # and GitHub refuses the whole run at startup when the called workflow's own job + # declares permissions the caller did not pass down ("startup_failure", runs + # 33615174183 / 33615177849 — the first dispatches since #3129 wired this call). + # The callee's job declares exactly these two; nothing else in this file gains them. + permissions: + contents: write + pull-requests: write uses: ./.github/workflows/dev-version-bump.yml with: released-version: v${{ inputs.version }} From 26480931faa6c4ad0330378efe22cba523de80f6 Mon Sep 17 00:00:00 2001 From: luvs01 Date: Thu, 3 Sep 2026 15:18:59 +0900 Subject: [PATCH 4/4] fix(gui): hide unavailable key rotation controls --- .../components/apikeys-workspace/ApiKeysWorkspace.tsx | 5 +++-- gui/tests/apikeys-actions.test.tsx | 10 ++++++++++ 2 files changed, 13 insertions(+), 2 deletions(-) diff --git a/gui/src/components/apikeys-workspace/ApiKeysWorkspace.tsx b/gui/src/components/apikeys-workspace/ApiKeysWorkspace.tsx index dba0e23591..76a2835d9f 100644 --- a/gui/src/components/apikeys-workspace/ApiKeysWorkspace.tsx +++ b/gui/src/components/apikeys-workspace/ApiKeysWorkspace.tsx @@ -140,6 +140,7 @@ export default function ApiKeysWorkspace({ const selectedRotationId = selected ? (rotationSecret?.id === selected.id ? rotationSecret.rotationId : selected.pendingRotation?.id) : undefined; + const rotationEnabled = Boolean(onRotationStart || onRotationCommit || onRotationAbort); const mutationPending = deleting || renamePending || rotationPending; const runRotation = async (operation: "start" | "commit" | "abort") => { @@ -356,7 +357,7 @@ export default function ApiKeysWorkspace({ -
+ {rotationEnabled &&

{t("api.rotation.title")}

{selectedRotationId ? ( <> @@ -394,7 +395,7 @@ export default function ApiKeysWorkspace({ )} {rotationFailed &&

{t("api.rotation.failed")}

} -
+
}

{t("api.attribution.title")}

{/* Branch on the DATASET field, not on `usage`: a key with zero diff --git a/gui/tests/apikeys-actions.test.tsx b/gui/tests/apikeys-actions.test.tsx index ae3bffecef..f7db49c10f 100644 --- a/gui/tests/apikeys-actions.test.tsx +++ b/gui/tests/apikeys-actions.test.tsx @@ -284,6 +284,16 @@ test("rotation start, one-time secret, commit, and abort stay explicit", async ( expect(calls).toContain("abort:k1:rotation-1"); }); +test("rotation controls stay hidden when the runtime supplies no rotation handlers", async () => { + const container = await mount({}); + await openKey(container); + + expect(container.textContent).not.toContain("Key rotation"); + expect(container.textContent).not.toContain("Start rotation"); + expect(container.textContent).not.toContain("Commit rotation"); + expect(container.textContent).not.toContain("Abort rotation"); +}); + test("a protocol result belongs to its own chip", async () => { const container = await mount({ filteredModels: [{ id: "gpt-5.4", displayName: "gpt-5.4", provider: "openai", native: true }],