Loading pkgs/by-name/co/codex-acp/hashes.jsondeleted 100644 → 0 +0 −8 Original line number Diff line number Diff line { "version": "0.9.4", "hash": "sha256-sVmy7t1+z88WmYuupVmUA3GYA2kkv3nY7Z3Ic99f5UY=", "cargoHash": "sha256-Ik6pewc6f+cmVKiqVj1g0h7cIxLhE6xOd9p/ySo/EPg=", "codexRev": "c34b30a3c128bb75fcec27ef838c93c99b92fc61", "codexSrcHash": "sha256-SnJHiecKNCHhkiMpbsEwpUarpKLpxn1JOHLHy2vgRog=", "nodeVersionHash": "sha256-q/bOpgF6/0K3MDKXAC+bi1Rb/vCHNhKZpNDbhyYH+oc=" } pkgs/by-name/co/codex-acp/package.nix +35 −34 Original line number Diff line number Diff line Loading @@ -7,53 +7,56 @@ pkg-config, openssl, libcap, librusty_v8 ? fetchurl { name = "librusty_v8-146.4.0"; url = "https://github.com/denoland/rusty_v8/releases/download/v146.4.0/librusty_v8_release_${stdenv.hostPlatform.rust.rustcTarget}.a.gz"; hash = { x86_64-linux = "sha256-5ktNmeSuKTouhGJEqJuAF4uhA4LBP7WRwfppaPUpEVM="; aarch64-linux = "sha256-2/FlsHyBvbBUvARrQ9I+afz3vMGkwbW0d2mDpxBi7Ng="; x86_64-darwin = "sha256-YwzSQPG77NsHFBfcGDh6uBz2fFScHFFaC0/Pnrpke7c="; aarch64-darwin = "sha256-v+LJvjKlbChUbw+WWCXuaPv2BkBfMQzE4XtEilaM+Yo="; } .${stdenv.hostPlatform.system}; meta = { version = "146.4.0"; sourceProvenance = with lib.sourceTypes; [ binaryNativeCode ]; }; }, }: let versionData = builtins.fromJSON (builtins.readFile ./hashes.json); inherit (versionData) version hash cargoHash codexRev codexSrcHash nodeVersionHash ; # codex-core uses include_str!("../../../../node-version.txt"), so we need # to place node-version.txt at the vendored workspace root. nodeVersionFile = fetchurl { url = "https://raw.githubusercontent.com/zed-industries/codex/${codexRev}/codex-rs/node-version.txt"; hash = nodeVersionHash; }; # codex-linux-sandbox compiles a patched bubblewrap source tree from # codex-rs/vendor/bubblewrap. Cargo vendoring flattens workspace layout, # so this directory must be provided explicitly. # codex-acp 0.12.0 pins openai/codex rust-v0.124.0 in Cargo.lock. codexRev = "e9fb49366c93a1478ec71cc41ecee415a197d036"; codexSrc = fetchFromGitHub { owner = "zed-industries"; owner = "openai"; repo = "codex"; rev = codexRev; hash = codexSrcHash; hash = "sha256-YFnzzwCm9/b30qLDMbkf/rEizuTjeqdCgoBZeS0wNBo="; }; in rustPlatform.buildRustPackage { rustPlatform.buildRustPackage (finalAttrs: { pname = "codex-acp"; inherit version; version = "0.12.0"; src = fetchFromGitHub { owner = "zed-industries"; repo = "codex-acp"; rev = "v${version}"; inherit hash; tag = "v${finalAttrs.version}"; hash = "sha256-qPqg95FpXHBtyHBJtrfJUwu9GokfmOJgKgqLKQ48u+8="; }; inherit cargoHash; cargoHash = "sha256-/BZ82qiTy/mPwhf5v5CFrNSB6AxCRFdmHB72L0+KjJw="; preBuild = '' cp ${nodeVersionFile} "$NIX_BUILD_TOP/codex-acp-${version}-vendor/node-version.txt" # fetchCargoVendor only keeps the individual git crate subtrees, so restore # the workspace-root file that codex-core includes via ../../../../node-version.txt. postPatch = '' cp ${codexSrc}/codex-rs/node-version.txt "$cargoDepsCopy/source-git-0/node-version.txt" ''; env = lib.optionalAttrs stdenv.hostPlatform.isLinux { env = { RUSTY_V8_ARCHIVE = librusty_v8; } // lib.optionalAttrs stdenv.hostPlatform.isLinux { CODEX_BWRAP_SOURCE_DIR = "${codexSrc}/codex-rs/vendor/bubblewrap"; }; Loading @@ -70,16 +73,14 @@ rustPlatform.buildRustPackage { doCheck = false; passthru.updateScript = ./update.py; meta = { description = "An ACP-compatible coding agent powered by Codex"; homepage = "https://github.com/zed-industries/codex-acp"; changelog = "https://github.com/zed-industries/codex-acp/releases/tag/v${version}"; changelog = "https://github.com/zed-industries/codex-acp/releases/tag/v${finalAttrs.version}"; license = lib.licenses.asl20; maintainers = with lib.maintainers; [ tlvince ]; platforms = lib.platforms.unix; sourceProvenance = with lib.sourceTypes; [ fromSource ]; mainProgram = "codex-acp"; }; } }) pkgs/by-name/co/codex-acp/update.pydeleted 100755 → 0 +0 −216 Original line number Diff line number Diff line #!/usr/bin/env nix-shell #!nix-shell -I nixpkgs=./. -i python3 -p python3 nix cacert """Update script for codex-acp package. codex-acp depends on crates from zed-industries/codex via a git dependency. To keep the Nix expression up to date, we need to: - update codex-acp source hash, - extract the pinned codex git revision from Cargo.lock, - refresh node-version.txt hash for that codex revision, - refresh codex source hash for vendored bubblewrap on Linux, - recompute cargoHash. """ from __future__ import annotations import json import os import re import subprocess import tarfile import tempfile import urllib.request from pathlib import Path SCRIPT_DIR = Path(__file__).resolve().parent NIXPKGS_ROOT = SCRIPT_DIR.parents[4] HASHES_FILE = SCRIPT_DIR / "hashes.json" OWNER = "zed-industries" REPO = "codex-acp" DUMMY_CARGO_HASH = "sha256-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=" ANSI_ESCAPE_RE = re.compile(r"\x1b\[[0-9;]*m") def run(cmd: list[str], cwd: Path | None = None) -> str: result = subprocess.run( cmd, cwd=str(cwd) if cwd else None, check=False, capture_output=True, text=True, ) if result.returncode != 0: output = result.stderr.strip() or result.stdout.strip() msg = f"Command failed ({result.returncode}): {' '.join(cmd)}" if output: msg = f"{msg}\n{output}" raise RuntimeError(msg) return result.stdout.strip() def github_request(url: str) -> dict: headers = { "Accept": "application/vnd.github+json", } token = os.environ.get("GITHUB_TOKEN") if token: headers["Authorization"] = f"Bearer {token}" req = urllib.request.Request(url, headers=headers) with urllib.request.urlopen(req) as response: return json.loads(response.read().decode("utf-8")) def fetch_latest_release(owner: str, repo: str) -> str: data = github_request(f"https://api.github.com/repos/{owner}/{repo}/releases/latest") tag_name = data["tag_name"] return tag_name[1:] if tag_name.startswith("v") else tag_name def version_key(version: str) -> tuple[int, ...]: parts = re.findall(r"\d+", version) return tuple(int(part) for part in parts) def should_update(current: str, latest: str) -> bool: return version_key(latest) > version_key(current) def load_hashes(path: Path) -> dict[str, str]: with path.open() as f: return json.load(f) def save_hashes(path: Path, data: dict[str, str]) -> None: with path.open("w") as f: json.dump(data, f, indent=2) f.write("\n") def prefetch_sri(url: str, *, unpack: bool = False) -> str: cmd = ["nix-prefetch-url", "--type", "sha256"] if unpack: cmd.append("--unpack") cmd.append(url) raw_hash = run(cmd, cwd=NIXPKGS_ROOT) return run( [ "nix", "--extra-experimental-features", "nix-command", "hash", "to-sri", "--type", "sha256", raw_hash, ], cwd=NIXPKGS_ROOT, ) def extract_codex_rev_from_tarball(tag: str) -> str: """Extract zed-industries/codex git revision from codex-acp Cargo.lock.""" url = f"https://github.com/{OWNER}/{REPO}/archive/refs/tags/{tag}.tar.gz" with tempfile.TemporaryDirectory() as tmpdir: tarball_path = Path(tmpdir) / "source.tar.gz" urllib.request.urlretrieve(url, tarball_path) with tarfile.open(tarball_path, "r:gz") as tar: for member in tar.getmembers(): if not member.name.endswith("Cargo.lock"): continue cargo_lock = tar.extractfile(member) if cargo_lock is None: continue content = cargo_lock.read().decode("utf-8") match = re.search(r"zed-industries/codex\?branch=acp#([a-f0-9]+)", content) if match: return match.group(1) raise RuntimeError("Could not extract codex git revision from Cargo.lock") def calculate_dependency_hash(attr_path: str) -> str: result = subprocess.run( ["nix-build", "--no-out-link", "-A", attr_path], cwd=str(NIXPKGS_ROOT), check=False, capture_output=True, text=True, ) output = ANSI_ESCAPE_RE.sub("", f"{result.stdout}\n{result.stderr}") match = re.search(r"got:\s*(sha256-[A-Za-z0-9+/=]+)", output) if match: return match.group(1) if result.returncode == 0: raise RuntimeError("nix-build unexpectedly succeeded with placeholder cargoHash") raise RuntimeError("Failed to parse cargoHash from nix-build output") def main() -> None: data = load_hashes(HASHES_FILE) current = data["version"] latest = fetch_latest_release(OWNER, REPO) print(f"Current: {current}, Latest: {latest}") if not should_update(current, latest): print("Already up to date") return tag = f"v{latest}" print(f"Updating codex-acp to {latest}...") source_url = f"https://github.com/{OWNER}/{REPO}/archive/refs/tags/{tag}.tar.gz" print("Calculating source hash...") source_hash = prefetch_sri(source_url, unpack=True) print(f" hash: {source_hash}") print("Extracting codex git revision from Cargo.lock...") codex_rev = extract_codex_rev_from_tarball(tag) print(f" codexRev: {codex_rev}") codex_src_url = f"https://github.com/zed-industries/codex/archive/{codex_rev}.tar.gz" print("Calculating codex source hash...") codex_src_hash = prefetch_sri(codex_src_url, unpack=True) print(f" codexSrcHash: {codex_src_hash}") node_version_url = ( f"https://raw.githubusercontent.com/zed-industries/codex/{codex_rev}/" "codex-rs/node-version.txt" ) print("Calculating node-version.txt hash...") node_version_hash = prefetch_sri(node_version_url, unpack=False) print(f" nodeVersionHash: {node_version_hash}") data = { "version": latest, "hash": source_hash, "cargoHash": DUMMY_CARGO_HASH, "codexRev": codex_rev, "codexSrcHash": codex_src_hash, "nodeVersionHash": node_version_hash, } save_hashes(HASHES_FILE, data) print("Calculating cargoHash...") attr_path = os.environ.get("UPDATE_NIX_ATTR_PATH", "codex-acp") cargo_hash = calculate_dependency_hash(attr_path) print(f" cargoHash: {cargo_hash}") data["cargoHash"] = cargo_hash save_hashes(HASHES_FILE, data) print(f"Updated to {latest}") if __name__ == "__main__": main() Loading
pkgs/by-name/co/codex-acp/hashes.jsondeleted 100644 → 0 +0 −8 Original line number Diff line number Diff line { "version": "0.9.4", "hash": "sha256-sVmy7t1+z88WmYuupVmUA3GYA2kkv3nY7Z3Ic99f5UY=", "cargoHash": "sha256-Ik6pewc6f+cmVKiqVj1g0h7cIxLhE6xOd9p/ySo/EPg=", "codexRev": "c34b30a3c128bb75fcec27ef838c93c99b92fc61", "codexSrcHash": "sha256-SnJHiecKNCHhkiMpbsEwpUarpKLpxn1JOHLHy2vgRog=", "nodeVersionHash": "sha256-q/bOpgF6/0K3MDKXAC+bi1Rb/vCHNhKZpNDbhyYH+oc=" }
pkgs/by-name/co/codex-acp/package.nix +35 −34 Original line number Diff line number Diff line Loading @@ -7,53 +7,56 @@ pkg-config, openssl, libcap, librusty_v8 ? fetchurl { name = "librusty_v8-146.4.0"; url = "https://github.com/denoland/rusty_v8/releases/download/v146.4.0/librusty_v8_release_${stdenv.hostPlatform.rust.rustcTarget}.a.gz"; hash = { x86_64-linux = "sha256-5ktNmeSuKTouhGJEqJuAF4uhA4LBP7WRwfppaPUpEVM="; aarch64-linux = "sha256-2/FlsHyBvbBUvARrQ9I+afz3vMGkwbW0d2mDpxBi7Ng="; x86_64-darwin = "sha256-YwzSQPG77NsHFBfcGDh6uBz2fFScHFFaC0/Pnrpke7c="; aarch64-darwin = "sha256-v+LJvjKlbChUbw+WWCXuaPv2BkBfMQzE4XtEilaM+Yo="; } .${stdenv.hostPlatform.system}; meta = { version = "146.4.0"; sourceProvenance = with lib.sourceTypes; [ binaryNativeCode ]; }; }, }: let versionData = builtins.fromJSON (builtins.readFile ./hashes.json); inherit (versionData) version hash cargoHash codexRev codexSrcHash nodeVersionHash ; # codex-core uses include_str!("../../../../node-version.txt"), so we need # to place node-version.txt at the vendored workspace root. nodeVersionFile = fetchurl { url = "https://raw.githubusercontent.com/zed-industries/codex/${codexRev}/codex-rs/node-version.txt"; hash = nodeVersionHash; }; # codex-linux-sandbox compiles a patched bubblewrap source tree from # codex-rs/vendor/bubblewrap. Cargo vendoring flattens workspace layout, # so this directory must be provided explicitly. # codex-acp 0.12.0 pins openai/codex rust-v0.124.0 in Cargo.lock. codexRev = "e9fb49366c93a1478ec71cc41ecee415a197d036"; codexSrc = fetchFromGitHub { owner = "zed-industries"; owner = "openai"; repo = "codex"; rev = codexRev; hash = codexSrcHash; hash = "sha256-YFnzzwCm9/b30qLDMbkf/rEizuTjeqdCgoBZeS0wNBo="; }; in rustPlatform.buildRustPackage { rustPlatform.buildRustPackage (finalAttrs: { pname = "codex-acp"; inherit version; version = "0.12.0"; src = fetchFromGitHub { owner = "zed-industries"; repo = "codex-acp"; rev = "v${version}"; inherit hash; tag = "v${finalAttrs.version}"; hash = "sha256-qPqg95FpXHBtyHBJtrfJUwu9GokfmOJgKgqLKQ48u+8="; }; inherit cargoHash; cargoHash = "sha256-/BZ82qiTy/mPwhf5v5CFrNSB6AxCRFdmHB72L0+KjJw="; preBuild = '' cp ${nodeVersionFile} "$NIX_BUILD_TOP/codex-acp-${version}-vendor/node-version.txt" # fetchCargoVendor only keeps the individual git crate subtrees, so restore # the workspace-root file that codex-core includes via ../../../../node-version.txt. postPatch = '' cp ${codexSrc}/codex-rs/node-version.txt "$cargoDepsCopy/source-git-0/node-version.txt" ''; env = lib.optionalAttrs stdenv.hostPlatform.isLinux { env = { RUSTY_V8_ARCHIVE = librusty_v8; } // lib.optionalAttrs stdenv.hostPlatform.isLinux { CODEX_BWRAP_SOURCE_DIR = "${codexSrc}/codex-rs/vendor/bubblewrap"; }; Loading @@ -70,16 +73,14 @@ rustPlatform.buildRustPackage { doCheck = false; passthru.updateScript = ./update.py; meta = { description = "An ACP-compatible coding agent powered by Codex"; homepage = "https://github.com/zed-industries/codex-acp"; changelog = "https://github.com/zed-industries/codex-acp/releases/tag/v${version}"; changelog = "https://github.com/zed-industries/codex-acp/releases/tag/v${finalAttrs.version}"; license = lib.licenses.asl20; maintainers = with lib.maintainers; [ tlvince ]; platforms = lib.platforms.unix; sourceProvenance = with lib.sourceTypes; [ fromSource ]; mainProgram = "codex-acp"; }; } })
pkgs/by-name/co/codex-acp/update.pydeleted 100755 → 0 +0 −216 Original line number Diff line number Diff line #!/usr/bin/env nix-shell #!nix-shell -I nixpkgs=./. -i python3 -p python3 nix cacert """Update script for codex-acp package. codex-acp depends on crates from zed-industries/codex via a git dependency. To keep the Nix expression up to date, we need to: - update codex-acp source hash, - extract the pinned codex git revision from Cargo.lock, - refresh node-version.txt hash for that codex revision, - refresh codex source hash for vendored bubblewrap on Linux, - recompute cargoHash. """ from __future__ import annotations import json import os import re import subprocess import tarfile import tempfile import urllib.request from pathlib import Path SCRIPT_DIR = Path(__file__).resolve().parent NIXPKGS_ROOT = SCRIPT_DIR.parents[4] HASHES_FILE = SCRIPT_DIR / "hashes.json" OWNER = "zed-industries" REPO = "codex-acp" DUMMY_CARGO_HASH = "sha256-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=" ANSI_ESCAPE_RE = re.compile(r"\x1b\[[0-9;]*m") def run(cmd: list[str], cwd: Path | None = None) -> str: result = subprocess.run( cmd, cwd=str(cwd) if cwd else None, check=False, capture_output=True, text=True, ) if result.returncode != 0: output = result.stderr.strip() or result.stdout.strip() msg = f"Command failed ({result.returncode}): {' '.join(cmd)}" if output: msg = f"{msg}\n{output}" raise RuntimeError(msg) return result.stdout.strip() def github_request(url: str) -> dict: headers = { "Accept": "application/vnd.github+json", } token = os.environ.get("GITHUB_TOKEN") if token: headers["Authorization"] = f"Bearer {token}" req = urllib.request.Request(url, headers=headers) with urllib.request.urlopen(req) as response: return json.loads(response.read().decode("utf-8")) def fetch_latest_release(owner: str, repo: str) -> str: data = github_request(f"https://api.github.com/repos/{owner}/{repo}/releases/latest") tag_name = data["tag_name"] return tag_name[1:] if tag_name.startswith("v") else tag_name def version_key(version: str) -> tuple[int, ...]: parts = re.findall(r"\d+", version) return tuple(int(part) for part in parts) def should_update(current: str, latest: str) -> bool: return version_key(latest) > version_key(current) def load_hashes(path: Path) -> dict[str, str]: with path.open() as f: return json.load(f) def save_hashes(path: Path, data: dict[str, str]) -> None: with path.open("w") as f: json.dump(data, f, indent=2) f.write("\n") def prefetch_sri(url: str, *, unpack: bool = False) -> str: cmd = ["nix-prefetch-url", "--type", "sha256"] if unpack: cmd.append("--unpack") cmd.append(url) raw_hash = run(cmd, cwd=NIXPKGS_ROOT) return run( [ "nix", "--extra-experimental-features", "nix-command", "hash", "to-sri", "--type", "sha256", raw_hash, ], cwd=NIXPKGS_ROOT, ) def extract_codex_rev_from_tarball(tag: str) -> str: """Extract zed-industries/codex git revision from codex-acp Cargo.lock.""" url = f"https://github.com/{OWNER}/{REPO}/archive/refs/tags/{tag}.tar.gz" with tempfile.TemporaryDirectory() as tmpdir: tarball_path = Path(tmpdir) / "source.tar.gz" urllib.request.urlretrieve(url, tarball_path) with tarfile.open(tarball_path, "r:gz") as tar: for member in tar.getmembers(): if not member.name.endswith("Cargo.lock"): continue cargo_lock = tar.extractfile(member) if cargo_lock is None: continue content = cargo_lock.read().decode("utf-8") match = re.search(r"zed-industries/codex\?branch=acp#([a-f0-9]+)", content) if match: return match.group(1) raise RuntimeError("Could not extract codex git revision from Cargo.lock") def calculate_dependency_hash(attr_path: str) -> str: result = subprocess.run( ["nix-build", "--no-out-link", "-A", attr_path], cwd=str(NIXPKGS_ROOT), check=False, capture_output=True, text=True, ) output = ANSI_ESCAPE_RE.sub("", f"{result.stdout}\n{result.stderr}") match = re.search(r"got:\s*(sha256-[A-Za-z0-9+/=]+)", output) if match: return match.group(1) if result.returncode == 0: raise RuntimeError("nix-build unexpectedly succeeded with placeholder cargoHash") raise RuntimeError("Failed to parse cargoHash from nix-build output") def main() -> None: data = load_hashes(HASHES_FILE) current = data["version"] latest = fetch_latest_release(OWNER, REPO) print(f"Current: {current}, Latest: {latest}") if not should_update(current, latest): print("Already up to date") return tag = f"v{latest}" print(f"Updating codex-acp to {latest}...") source_url = f"https://github.com/{OWNER}/{REPO}/archive/refs/tags/{tag}.tar.gz" print("Calculating source hash...") source_hash = prefetch_sri(source_url, unpack=True) print(f" hash: {source_hash}") print("Extracting codex git revision from Cargo.lock...") codex_rev = extract_codex_rev_from_tarball(tag) print(f" codexRev: {codex_rev}") codex_src_url = f"https://github.com/zed-industries/codex/archive/{codex_rev}.tar.gz" print("Calculating codex source hash...") codex_src_hash = prefetch_sri(codex_src_url, unpack=True) print(f" codexSrcHash: {codex_src_hash}") node_version_url = ( f"https://raw.githubusercontent.com/zed-industries/codex/{codex_rev}/" "codex-rs/node-version.txt" ) print("Calculating node-version.txt hash...") node_version_hash = prefetch_sri(node_version_url, unpack=False) print(f" nodeVersionHash: {node_version_hash}") data = { "version": latest, "hash": source_hash, "cargoHash": DUMMY_CARGO_HASH, "codexRev": codex_rev, "codexSrcHash": codex_src_hash, "nodeVersionHash": node_version_hash, } save_hashes(HASHES_FILE, data) print("Calculating cargoHash...") attr_path = os.environ.get("UPDATE_NIX_ATTR_PATH", "codex-acp") cargo_hash = calculate_dependency_hash(attr_path) print(f" cargoHash: {cargo_hash}") data["cargoHash"] = cargo_hash save_hashes(HASHES_FILE, data) print(f"Updated to {latest}") if __name__ == "__main__": main()