fix(ai-cli): install current upstream Codex and Claude releases

- Pin official Codex 0.161.0 and Claude Code 2.1.292 binaries
- Preserve Codex helpers and Claude's NixOS compatibility wrapper
- Add an updater for stable upstream versions and checksums
- Document CLI updates independently of stable NixOS inputs
This commit is contained in:
clw committed 2026-10-07 18:14:21 +01:00
1 parent 2759278aff
commit 0aac36b7de
6 files changed
+155 -5

No files matched your search

+57
View File
@@ -0,0 +1,57 @@
#!/usr/bin/env python3
"""Pin the latest stable upstream CLI releases without updating NixOS."""
import json
import re
import urllib.request
from pathlib import Path
def fetch_json(url):
request = urllib.request.Request(
url, headers={"User-Agent": "nixos-config-ai-cli-updater"}
)
with urllib.request.urlopen(request, timeout=60) as response:
return json.load(response)
def latest_release(repository):
release = fetch_json(f"https://api.github.com/repos/{repository}/releases/latest")
if release["prerelease"] or release["draft"]:
raise ValueError(f"Expected a stable release from {repository}")
return release
codex = latest_release("openai/codex")
codex_version = codex["tag_name"].removeprefix("rust-v")
claude = latest_release("anthropics/claude-code")
claude_version = claude["tag_name"].removeprefix("v")
for version in (codex_version, claude_version):
if not re.fullmatch(r"\d+\.\d+\.\d+", version):
raise ValueError(f"Unexpected release version: {version}")
asset = next(
item for item in codex["assets"]
if item["name"] == "codex-package-x86_64-unknown-linux-musl.tar.gz"
)
digest = asset["digest"]
if not re.fullmatch(r"sha256:[0-9a-f]{64}", digest):
raise ValueError("Codex release asset has no valid SHA-256 digest")
manifest = fetch_json(
f"https://downloads.claude.ai/claude-code-releases/{claude_version}/manifest.json"
)
if manifest["version"] != claude_version:
raise ValueError("Claude release and download manifest versions differ")
claude_hash = manifest["platforms"]["linux-x64"]["checksum"]
if not re.fullmatch(r"[0-9a-f]{64}", claude_hash):
raise ValueError("Claude manifest has no valid SHA-256 checksum")
versions = {
"codex": {"version": codex_version, "sha256": digest.removeprefix("sha256:")},
"claude-code": {"version": claude_version, "sha256": claude_hash},
}
destination = Path(__file__).resolve().parent.parent / "packages" / "ai-cli-versions.json"
destination.write_text(json.dumps(versions, indent=2) + "\n")
print(f"Pinned Codex {codex_version} and Claude Code {claude_version}.")
print("Review the diff, build the packages, rebuild your host and commit the pins.")