From 787c058c71f9fb30363697b19820a266a1ce8f2a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?m=C3=BCde?= Date: Sat, 16 May 2026 23:35:28 +0200 Subject: [PATCH] harness: install tea + auto-login from /state/forge-token agents get `pkgs.tea` (gitea/forgejo CLI) and a tea-login oneshot that runs `tea login add --url --token $(cat /state/forge-token)` before the harness starts. idempotent: exits 0 when the token file is absent (hive-forge not on) or when ~/.config/tea/config.yml already exists. new `hyperhive.forge.url` option (default http://localhost:3000) so operators can point at a non-default forge port. claude can now shell out to `tea repos create`, `tea pulls create`, etc. --- nix/templates/harness-base.nix | 53 ++++++++++++++++++++++++++++++++++ 1 file changed, 53 insertions(+) diff --git a/nix/templates/harness-base.nix b/nix/templates/harness-base.nix index c9b4b26..e6cf7aa 100644 --- a/nix/templates/harness-base.nix +++ b/nix/templates/harness-base.nix @@ -82,6 +82,20 @@ ''; }; + options.hyperhive.forge.url = lib.mkOption { + type = lib.types.str; + default = "http://localhost:3000"; + example = "http://forge.internal:3000"; + description = '' + Base URL of the hyperhive-managed Forgejo. Used at container + boot by a oneshot systemd unit that calls + `tea login add --url --token "$(cat /state/forge-token)"` + so the agent's claude can shell out to `tea` without an extra + auth dance. No-op when `/state/forge-token` is missing (i.e. + hive-forge isn't running on the host). + ''; + }; + options.hyperhive.claudePlugins = lib.mkOption { type = lib.types.listOf lib.types.str; default = [ ]; @@ -124,8 +138,47 @@ # procps for pkill — used by the web UI's /api/cancel to SIGINT the # in-flight claude turn. procps + # tea: gitea/forgejo CLI client. Configured at boot by the + # tea-login oneshot below if /state/forge-token is present, so + # claude can `tea repos create`, `tea pulls create`, etc. + tea ]; + # One-shot: configure tea with the agent's forge token if + # hive-c0re seeded one and tea hasn't been configured yet. + # Runs before the harness service so the first turn can already + # `tea repos create`. Idempotent — exits 0 if config already + # exists, exits 0 if no token file (hive-forge not enabled). + systemd.services.tea-login = { + description = "configure tea CLI from /state/forge-token"; + wantedBy = [ "multi-user.target" ]; + after = [ "local-fs.target" ]; + serviceConfig = { + Type = "oneshot"; + RemainAfterExit = true; + }; + path = [ pkgs.tea pkgs.coreutils ]; + script = '' + set -eu + TOKEN_FILE=/state/forge-token + CONFIG=/root/.config/tea/config.yml + if [ ! -f "$TOKEN_FILE" ]; then + echo "tea-login: no $TOKEN_FILE (hive-forge not seeded); skipping" + exit 0 + fi + if [ -f "$CONFIG" ]; then + echo "tea-login: $CONFIG already present; skipping" + exit 0 + fi + mkdir -p "$(dirname "$CONFIG")" + tea login add \ + --name forge \ + --url ${lib.escapeShellArg config.hyperhive.forge.url} \ + --token "$(cat "$TOKEN_FILE")" + echo "tea-login: configured for ${config.hyperhive.forge.url}" + ''; + }; + # 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//flake.nix` overrides `user.name` and