Files
Miguel Palhas 2f50a83b01
Nix / Nix Eval + Web Frontend (push) Successful in 1m27s
CI / Web (push) Failing after 4m43s
CI / Rust (push) Failing after 8m49s
feat!: remove sandbox, tool sessions, Node download, QR, log tee
Five feature removals, ~27.8k lines:

- Docker/Podman sandbox: src/containers/, container_config, acp::sandbox,
  SandboxInfo, the [sandbox] config section, container terminals, in-container
  hooks, volume_ignores, the sandbox-image banner (and [updates], which existed
  only to gate it), /api/docker/status, and docker/.
- ACP Node download: the pinned-tarball fetch and NodeSource::Bundled. Drops
  the tar and xz2 deps, and with xz2 the system liblzma requirement.
- session_tee: the per-session tracing mirror. Agent stderr still reaches
  acp-workers/<id>.log via the runner; daemon events stay in debug.log.
- qrcode: dep plus the serve dialog's QR block.
- session.tools: tool sessions, picker dialog, ViewMode::Tool, hotkeys.

Legacy tmux prefixes (aoe_tool_*, aoe_cterm_*) are kept as sweep-only
constants so sessions left by an older build are still torn down rather than
mistaken for agent panes.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-22 14:05:26 +01:00

174 lines
7.0 KiB
Nix

{
description = "Terminal session manager for AI coding agents";
inputs = {
nixpkgs.url = "github:NixOS/nixpkgs/nixos-unstable";
flake-parts.url = "github:hercules-ci/flake-parts";
crane.url = "github:ipetkov/crane";
};
outputs = inputs @ { flake-parts, ... }:
flake-parts.lib.mkFlake { inherit inputs; } {
systems = [ "x86_64-linux" "aarch64-linux" "aarch64-darwin" ];
perSystem = { config, self', inputs', pkgs, system, ... }:
let
craneLib = inputs.crane.mkLib pkgs;
# libgit2-sys falls back to vendoring libgit2 (needs cmake to build
# it) when pkg-config finds no system copy. git2 is built without
# `https`/`ssh`, so there is no OpenSSL to compile and no perl.
nativeBuildInputs = with pkgs; [
pkg-config
cmake
installShellFiles
];
buildInputs = with pkgs; [
zlib # required by vendored libgit2
];
commonArgs = {
# Cargo source filtering keeps only *.rs, *.toml and Cargo.lock, so
# every other compile-time embedded asset has to be unioned in
# explicitly: the acp-worker/adapters manifests that
# src/acp/adapters.rs reads with include_bytes! (#3204).
# `scripts/check-nix-embedded-assets.py` fails CI if a new embedded
# asset lands without being added here.
src = pkgs.lib.fileset.toSource {
root = ./.;
fileset = pkgs.lib.fileset.unions [
(craneLib.fileset.commonCargoSources ./.)
./acp-worker/adapters
];
};
strictDeps = true;
inherit nativeBuildInputs buildInputs;
};
# Build only workspace dependencies first (for caching)
cargoArtifacts = craneLib.buildDepsOnly commonArgs;
aoe = craneLib.buildPackage (commonArgs // {
inherit cargoArtifacts;
cargoExtraArgs = "--package agent-of-empires";
doCheck = false;
postInstall = ''
installShellCompletion --cmd aoe \
--bash <($out/bin/aoe completion bash) \
--fish <($out/bin/aoe completion fish) \
--zsh <($out/bin/aoe completion zsh)
'';
meta = with pkgs.lib; {
description = "Terminal session manager for AI coding agents";
longDescription = ''
Agent of Empires (AoE) is a terminal session manager for AI coding
agents on Linux and macOS. Built on tmux, it allows running multiple
AI agents in parallel across different branches of your codebase,
each in its own isolated session.
Supports Claude Code, OpenCode, Mistral Vibe, Codex CLI, and Gemini CLI.
'';
homepage = "https://github.com/agent-of-empires/agent-of-empires";
license = licenses.mit;
platforms = platforms.unix;
mainProgram = "aoe";
};
});
# Build the React frontend as a standalone derivation (Forgejo/ntfy-sh pattern).
# This separates the npm build from the Rust build cleanly.
#
# Update npmDepsHash whenever web/package-lock.json changes:
# nix-update aoe-with-web
# or manually: set npmDepsHash to lib.fakeHash, build, copy the got: hash.
webFrontend = pkgs.buildNpmPackage {
pname = "agent-of-empires-web";
version = "0";
src = ./web;
npmDepsHash = "sha256-pOHah9U4Qcv7MScyvmtYRbOscMP99kAcO78tAHJE8AA=";
# tsc -b && vite build; output goes to web/dist
installPhase = ''
mkdir $out
cp -r dist $out/
'';
};
# Base args for the web-enabled build. No npm tooling needed here since
# build.rs respects AOE_WEB_DIST to use the pre-built frontend.
# buildDepsOnly uses a dummy crate source so AOE_WEB_DIST is irrelevant there.
commonArgsWithWeb = commonArgs // {
cargoExtraArgs = "--package agent-of-empires --features serve";
};
# Rust dep cache compiled with --features serve (no npm involved).
cargoArtifactsWithWeb = craneLib.buildDepsOnly commonArgsWithWeb;
aoeWithWeb = craneLib.buildPackage (commonArgsWithWeb // {
cargoArtifacts = cargoArtifactsWithWeb;
doCheck = false;
# Point build.rs at the pre-built frontend; it will copy dist/ into
# place and skip running npm entirely (see build.rs AOE_WEB_DIST handling).
AOE_WEB_DIST = "${webFrontend}/dist";
postInstall = ''
installShellCompletion --cmd aoe \
--bash <($out/bin/aoe completion bash) \
--fish <($out/bin/aoe completion fish) \
--zsh <($out/bin/aoe completion zsh)
'';
meta = aoe.meta;
# Expose npmDeps so `nix-update` can automatically recompute the
# npmDepsHash in webFrontend when web/package-lock.json changes.
passthru.npmDeps = webFrontend.npmDeps;
});
in
{
packages.default = aoe;
packages.aoe-with-web = aoeWithWeb;
# Just the npm + vite build. Exposed so the PR-CI Nix Build
# Web job can validate npmDepsHash + frontend build in ~1-2
# min instead of rebuilding the full Rust workspace.
packages.aoe-web-frontend = webFrontend;
# Exposed so the nix-npm-hash bots and the local manual
# update procedure use the same nixpkgs revision as
# `buildNpmPackage` above.
packages.prefetch-npm-deps = pkgs.prefetch-npm-deps;
checks = {
# Build the packages as checks too
inherit aoe;
inherit aoeWithWeb;
aoe-clippy = craneLib.cargoClippy (commonArgs // {
inherit cargoArtifacts;
# e2e-tests keeps the gated e2e target inside the --all-targets
# sweep; without it the required-features gate would silently drop
# e2e from clippy's --deny warnings coverage.
cargoClippyExtraArgs = "--package agent-of-empires --all-targets --features e2e-tests -- --deny warnings";
});
aoe-fmt = craneLib.cargoFmt {
inherit (commonArgs) src;
};
aoe-test = craneLib.cargoTest (commonArgs // {
inherit cargoArtifacts;
cargoTestExtraArgs = "--package agent-of-empires";
# Some git:: unit tests invoke the git binary directly
nativeBuildInputs = commonArgs.nativeBuildInputs ++ [ pkgs.git ];
});
};
devShells.default = craneLib.devShell {
checks = self'.checks;
packages = with pkgs; [
rust-analyzer
tmux
nodejs # for web frontend development (--features serve)
];
};
};
};
}