#!/usr/bin/env bash set -euo pipefail # Build a Debian package (.deb) for Agent Joule from a bundle-linux tarball. # # script/build-deb [deb-arch] # # Lays the tarball's zed.app under /usr/lib/agent-joule, symlinks the launcher to # /usr/bin/agent-joule, and installs the desktop entry + icons for system menus. # Works on Linux (dpkg-deb) and macOS (falls back to ar + tar). tarball="${1:?usage: build-deb [arch]}" version="${2:?usage: build-deb [arch]}" deb_arch="${3:-amd64}" workdir="$(mktemp -d)" trap 'rm -rf "$workdir"' EXIT pkgroot="$workdir/pkg" # Extract the bundle and locate the zed*.app directory inside it. mkdir -p "$workdir/extract" tar -xzf "$tarball" -C "$workdir/extract" app_src="$(find "$workdir/extract" -maxdepth 1 -type d -name '*.app' | head -1)" [ -n "$app_src" ] || { echo "no .app dir found in $tarball" >&2; exit 1; } # /usr/lib/agent-joule holds the self-contained app (bin/, libexec/, lib/, share/). install_dir="$pkgroot/usr/lib/agent-joule" mkdir -p "$install_dir" "$pkgroot/usr/bin" \ "$pkgroot/usr/share/applications" \ "$pkgroot/usr/share/icons/hicolor/512x512/apps" \ "$pkgroot/usr/share/icons/hicolor/1024x1024/apps" cp -a "$app_src/." "$install_dir/" # Launcher on PATH. bin/zed (the cli) resolves libexec/zed-editor by its real # path, so a symlink into /usr/bin keeps the app self-locating. ln -sf /usr/lib/agent-joule/bin/zed "$pkgroot/usr/bin/agent-joule" # Desktop entry + icons for the application menu (rename zed -> agent-joule, and # point Exec/Icon at the installed paths). desktop_src="$(find "$install_dir/share/applications" -name '*.desktop' | head -1 || true)" if [ -n "${desktop_src:-}" ]; then sed -e 's%^Exec=.*%Exec=/usr/bin/agent-joule %' \ -e 's%^Icon=.*%Icon=agent-joule%' \ -e 's%^Name=.*%Name=Agent Joule%' \ "$desktop_src" > "$pkgroot/usr/share/applications/agent-joule.desktop" fi for size in 512x512 1024x1024; do icon="$install_dir/share/icons/hicolor/$size/apps/zed.png" [ -f "$icon" ] && cp "$icon" "$pkgroot/usr/share/icons/hicolor/$size/apps/agent-joule.png" done installed_kb="$(du -sk "$pkgroot" | cut -f1)" # Debian control metadata. mkdir -p "$pkgroot/DEBIAN" cat > "$pkgroot/DEBIAN/control" < Installed-Size: ${installed_kb} Depends: libc6, libstdc++6, zlib1g, libfontconfig1, libxkbcommon0, libxkbcommon-x11-0, libwayland-client0, libvulkan1, libgl1, libasound2 Homepage: https://az.transaction.science Description: Deterministic-first, energy-metered AI coding editor (a fork of Zed) Agent Joule resolves code deterministic-first (lookup, search, templates) and reaches for a model only as a last resort, with energy tracking and code traceability built in. CONTROL cat > "$pkgroot/DEBIAN/postinst" <<'POSTINST' #!/bin/sh set -e if command -v gtk-update-icon-cache >/dev/null 2>&1; then gtk-update-icon-cache -q /usr/share/icons/hicolor || true fi if command -v update-desktop-database >/dev/null 2>&1; then update-desktop-database -q /usr/share/applications || true fi exit 0 POSTINST chmod 0755 "$pkgroot/DEBIAN/postinst" out="agent-joule_${version}_${deb_arch}.deb" if command -v dpkg-deb >/dev/null 2>&1; then dpkg-deb --root-owner-group --build "$pkgroot" "$out" else # Portable fallback (macOS): assemble the ar archive by hand. echo "dpkg-deb not found; building .deb with ar + tar" ( cd "$pkgroot" && tar --numeric-owner --owner=0 --group=0 -czf "$workdir/data.tar.gz" \ --exclude=./DEBIAN -C "$pkgroot" . ) ( cd "$pkgroot/DEBIAN" && tar --numeric-owner --owner=0 --group=0 -czf "$workdir/control.tar.gz" . ) echo "2.0" > "$workdir/debian-binary" ( cd "$workdir" && ar rc "$OLDPWD/$out" debian-binary control.tar.gz data.tar.gz ) fi echo "Built ${out}"