harness: sync agent icon to Forgejo user avatar on rebuild (closes #141)

This commit is contained in:
damocles 2026-05-21 18:27:13 +02:00 committed by Mara
parent 32f4796a7f
commit 00281730bb

View file

@ -399,6 +399,61 @@
'';
};
# One-shot: upload the agent's configured icon to its Forgejo user avatar
# so the icon shows up on commits / PRs / issue comments in the forge.
# Only runs when `/etc/hyperhive/icon.svg` is present (set via
# `hyperhive.icon`). No-op when the forge is unreachable or the icon
# is not set. *Always* exits 0.
systemd.services.forge-avatar-sync = {
description = "sync agent icon to Forgejo user avatar (best-effort)";
wantedBy = [ "multi-user.target" ];
after = [ "tea-login.service" ];
serviceConfig = {
Type = "oneshot";
RemainAfterExit = true;
};
path = [
pkgs.curl
pkgs.coreutils
pkgs.python3
];
script = ''
ICON=/etc/hyperhive/icon.svg
if [ ! -f "$ICON" ]; then
echo "forge-avatar-sync: no icon configured; skipping"
exit 0
fi
FORGE_URL=${lib.escapeShellArg config.hyperhive.forge.url}
TOKEN_FILE=""
for f in /state/forge-token /agents/*/state/forge-token; do
if [ -f "$f" ]; then
TOKEN_FILE="$f"
break
fi
done
if [ -z "$TOKEN_FILE" ]; then
echo "forge-avatar-sync: no forge-token found; skipping"
exit 0
fi
TOKEN=$(cat "$TOKEN_FILE")
# Base64-encode the SVG and wrap in a data URI.
IMAGE=$(base64 -w 0 < "$ICON")
DATA_URI="data:image/svg+xml;base64,$IMAGE"
RESP=$(curl -sf --max-time 10 \
-X POST "$FORGE_URL/api/v1/user/avatar" \
-H "Authorization: token $TOKEN" \
-H "Content-Type: application/json" \
-d "{\"image\":\"$DATA_URI\"}" \
-w "\n%{http_code}" 2>/dev/null || true)
CODE=$(printf '%s' "$RESP" | tail -1)
if [ "$CODE" = "204" ] || [ "$CODE" = "200" ]; then
echo "forge-avatar-sync: avatar uploaded (HTTP $CODE)"
else
echo "forge-avatar-sync: upload returned HTTP $CODE skipping (non-fatal)"
fi
'';
};
# Git is needed by claude's Bash tool (for the agent <-> manager config
# request flow) and by hive-c0re's own setup_applied / setup_proposed.
# The per-agent `applied/<name>/flake.nix` overrides `user.name` and