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:
1 parent
2759278aff
commit
0aac36b7de
6 files changed
+155
-5
No files matched your search
@@ -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.")
|
||||
Reference in new issue
Block a user