From 03337bc545f574b04dbc18b7f499bd42feeb8198 Mon Sep 17 00:00:00 2001 From: Alexander Miroshnichenko Date: Tue, 6 Oct 2026 21:45:16 +0300 Subject: [PATCH] feat(codeaf): add CodeAF coding agent package CodeAF (Agent-Field/CodeAF) is a Go coding harness that ships one binary. Pinned to v0.7.1; the flake's nixpkgs already carries go 1.26.7 and go.mod asks for 1.26.5, so no extra nixpkgs input is needed. Two things about this build are not obvious from the derivation: - `make build` runs two host-side steps before compiling: `go generate ./internal/manual` packs the built-in manual into the pages.pack.gz and chat.pack.gz that the codeaf_packed_manual tag embeds, and internal/furrowbin/cmd/fetch stages the pinned Agent-Field/furrow release into internal/furrowbin/cache for go:embed. Both are run in preBuild with GOOS/GOARCH unset, the way the Makefile does it, so a cross build does not try to run a target binary on the build machine. buildGoModule runs preBuild in the vendoring derivation as well, before vendor/ exists and before the dependencies are in reach, so the two steps are gated on vendor/. - The furrow step gets its bytes from fetchurl and `-from`, the offline road upstream documents. The fetcher still checks the sha256 in internal/furrowbin/pin.json, so the hashes here duplicate a pin that is already in the source; drop the furrow entirely and codeaf still builds and falls back to looking for the binary on PATH. Tests are off: the upstream suite is a make/CI matrix with network and timing assumptions, not a `go test ./...` that fits buildGoModule. Verified with nix build .#codeaf, `codeaf --version` reporting 0.7.1 and `codeaf manual` listing the packed manual pages. Refs nix-overlay-m5y --- README.md | 2 + packages/codeaf/default.nix | 5 ++ packages/codeaf/package.nix | 118 ++++++++++++++++++++++++++++++++++++ 3 files changed, 125 insertions(+) create mode 100644 packages/codeaf/default.nix create mode 100644 packages/codeaf/package.nix diff --git a/README.md b/README.md index 3bb1823..8511f50 100644 --- a/README.md +++ b/README.md @@ -14,6 +14,7 @@ A custom Nix overlay and flake providing additional packages not found in upstre |---------|-------------|----------| | `awg-tool` | CLI for AmneziaWG self-hosting — generates 1.0/1.5/2.0/3.0 obfuscation parameters, exports .conf and vpn:// configs, installs servers over SSH | Networking | | `aionui` | Free, open-source, Cowork app with AI Agents | AI Coding Agents | +| `codeaf` | Coding harness and software factory for open models: hand work off, then watch every project from one terminal | AI Coding Agents | | `container-use` | Containerized environments for coding agents | AI Coding Agents | | `desloppify` | Multi-language codebase health scanner and technical debt tracker for AI agents | AI Coding Agents | | `ds4` | DeepSeek 4 Flash and PRO local inference engine for ROCm (Strix Halo) | AI Inference | @@ -185,6 +186,7 @@ nix-overlay/ ├── packages/ # Package definitions │ ├── awg-tool/ # AmneziaWG parameter generation and SSH deployment CLI │ ├── aionui/ # AionUi - AI Cowork desktop app +│ ├── codeaf/ # Coding harness and software factory for open models │ ├── container-use/ # Containerized environments for coding agents │ ├── default/ # Meta-package listing all packages │ ├── desloppify/ # Codebase health scanner for AI agents diff --git a/packages/codeaf/default.nix b/packages/codeaf/default.nix new file mode 100644 index 0000000..291b4f4 --- /dev/null +++ b/packages/codeaf/default.nix @@ -0,0 +1,5 @@ +{ + pkgs, + ... +}: +pkgs.callPackage ./package.nix { } diff --git a/packages/codeaf/package.nix b/packages/codeaf/package.nix new file mode 100644 index 0000000..6cd0d56 --- /dev/null +++ b/packages/codeaf/package.nix @@ -0,0 +1,118 @@ +{ + lib, + buildGoModule, + fetchFromGitHub, + fetchurl, + stdenv, +}: + +# Every codeaf ships a furrow inside it: internal/furrowbin embeds a pinned +# Agent-Field/furrow release, and `make build` stages it with +# `fetch -from ` instead of downloading, which is the road this build +# takes. The fetcher re-checks the sha256 named in internal/furrowbin/pin.json, +# so the hashes below are a second copy of a pin already in the source. Without +# a staged furrow codeaf still builds, and looks for the binary on PATH instead. +let + furrow = ( + { + x86_64-linux = { + goos = "linux"; + goarch = "amd64"; + source = fetchurl { + url = "https://github.com/Agent-Field/furrow/releases/download/v0.1.0/furrow-linux-amd64"; + hash = "sha256-x/h+3m81Kq0F066kJRfqychmCa3rYlGHKGQRSSZj4rQ="; + }; + }; + aarch64-linux = { + goos = "linux"; + goarch = "arm64"; + source = fetchurl { + url = "https://github.com/Agent-Field/furrow/releases/download/v0.1.0/furrow-linux-arm64"; + hash = "sha256-ifE9UG8vf1TSyJIMU7V4TwsBiK5w91jpErcb/v3x0dY="; + }; + }; + x86_64-darwin = { + goos = "darwin"; + goarch = "amd64"; + source = fetchurl { + url = "https://github.com/Agent-Field/furrow/releases/download/v0.1.0/furrow-darwin-amd64"; + hash = "sha256-B5mP5JoqoZ9O0IdVud6mWkiwjR/WgLWFKMVbNXnLaFI="; + }; + }; + aarch64-darwin = { + goos = "darwin"; + goarch = "arm64"; + source = fetchurl { + url = "https://github.com/Agent-Field/furrow/releases/download/v0.1.0/furrow-darwin-arm64"; + hash = "sha256-EJN1Fmnla1dqK2WPvZxFKcqvNWfqoJyfduDV2wL4+hY="; + }; + }; + } + .${stdenv.hostPlatform.system} or null + ); +in +buildGoModule rec { + pname = "codeaf"; + version = "0.7.1"; + + src = fetchFromGitHub { + owner = "Agent-Field"; + repo = "CodeAF"; + rev = "v${version}"; + hash = "sha256-F4rRDNrTCF8/cj6g0KM41+gNdzvTWw5Vj2N0OJp+vCc="; + }; + + vendorHash = "sha256-eIocnhp3uGk+wG0kprRie0Csms+Deqxy3K3HuI1vJyM="; + + env.CGO_ENABLED = 0; + + # The shipped binary carries the packed manual rather than the raw Markdown. + tags = [ "codeaf_packed_manual" ]; + + subPackages = [ "cmd/codeaf" ]; + + # Upstream's own suite is a CI matrix (make test / make check) with network + # and timing assumptions; it is not buildGoModule-shaped. + doCheck = false; + + # `make build` runs two host-side steps before compiling. Both are built for + # the build machine even when codeaf targets another platform, hence the + # unset GOOS/GOARCH; the fetcher is told the target platform by hand. The + # vendoring derivation runs preBuild too, before vendor/ exists, and these two + # need the vendored dependencies, so they wait for it. + preBuild = '' + if [ -d vendor ]; then + env -u GOOS -u GOARCH go generate ./internal/manual + ${lib.optionalString (furrow != null) + "env -u GOOS -u GOARCH go run ./internal/furrowbin/cmd/fetch -goos=${furrow.goos} -goarch=${furrow.goarch} -from ${furrow.source}" + } + fi + ''; + + ldflags = [ + "-s" + "-w" + "-X github.com/Agent-Field/codeaf/internal/buildinfo.rev=${version}" + "-X github.com/Agent-Field/codeaf/internal/buildinfo.dirty=false" + ]; + + passthru = { + category = "AI Coding Agents"; + updateScript = [ + "nix-update" + "--flake" + ".#codeaf" + ]; + }; + + meta = with lib; { + description = "Coding harness and software factory for open models: hand off work and watch every project from one terminal"; + homepage = "https://github.com/Agent-Field/CodeAF"; + changelog = "https://github.com/Agent-Field/CodeAF/blob/v${version}/CHANGELOG.md"; + license = licenses.asl20; + # Not fromSource all the way down: the binary embeds the prebuilt furrow + # release named in internal/furrowbin/pin.json. + mainProgram = "codeaf"; + platforms = platforms.linux ++ platforms.darwin; + }; +}