diff --git a/.gitea/workflows/build.yml b/.gitea/workflows/build.yml index dc90ce386..91e85f38e 100644 --- a/.gitea/workflows/build.yml +++ b/.gitea/workflows/build.yml @@ -257,3 +257,144 @@ jobs: - name: wipe secrets if: always() run: rm -f /root/repo_pass /root/.ssh/id_ed25519 + + # ------------------------------------------------------------------------- + # claude-his-agent (arch=any) — pure markdown + shell, one pkg valid on all + # pacman targets. Same dual-arch publish trick as lmcp. + # ------------------------------------------------------------------------- + claude-his-any: + needs: lmcp-debian + runs-on: arch-aarch64 + steps: + - uses: actions/checkout@v4 + + - name: bootstrap runner (idempotent) + run: pacman -Syu --noconfirm --needed base-devel git rsync gnupg openssh sudo + + - name: import signing key + env: + PRIV: ${{ secrets.MARFRIT_REPO_PRIVATE_KEY }} + PASS: ${{ secrets.MARFRIT_REPO_PASSPHRASE }} + run: | + set -e + rm -rf /root/.gnupg /root/repo_pass + mkdir -m700 -p /root/.gnupg + printf '%s' "$PASS" > /root/repo_pass + chmod 600 /root/repo_pass + printf '%s\n' "$PRIV" | gpg --batch --import + echo "92D5E96D8F63C75E4116AA1FF5C8C4603D0D250C:6:" | gpg --import-ownertrust + + - name: install deploy ssh key + env: + KEY: ${{ secrets.MARFRIT_REPO_DEPLOY_KEY }} + run: | + mkdir -m700 -p /root/.ssh + printf '%s\n' "$KEY" > /root/.ssh/id_ed25519 + chmod 600 /root/.ssh/id_ed25519 + ssh-keyscan -t ed25519 nc.reauktion.de > /root/.ssh/known_hosts 2>/dev/null + + - name: makepkg claude-his-agent + run: | + set -e + rm -rf /tmp/build-his + cp -r arch/claude-his-agent /tmp/build-his + chown -R builder:builder /tmp/build-his + cd /tmp/build-his + sudo -u builder -H makepkg --nocheck --noconfirm --syncdeps --cleanbuild + ls -la *.pkg.tar.* | grep -v "\.sig$" + + - name: sign claude-his-agent + run: | + set -e + cd /tmp/build-his + for f in *.pkg.tar.xz *.pkg.tar.zst *.pkg.tar.gz; do + [ -f "$f" ] || continue + gpg --batch --pinentry-mode loopback --passphrase-file /root/repo_pass \ + --detach-sign --yes -u 92D5E96D8F63C75E4116AA1FF5C8C4603D0D250C "$f" + done + + - name: publish claude-his-agent to both arches + run: | + set -e + export GNUPGHOME=/root/.gnupg + printf 'pinentry-mode loopback\npassphrase-file /root/repo_pass\n' > /root/.gnupg/gpg.conf + printf 'allow-loopback-pinentry\n' > /root/.gnupg/gpg-agent.conf + gpg-connect-agent reloadagent /bye + + for target in aarch64 x86_64; do + stage="/tmp/arch-stage-his-$target" + rm -rf "$stage"; mkdir -p "$stage"; cd "$stage" + for f in marfrit.db.tar.gz marfrit.db.tar.gz.sig marfrit.files.tar.gz marfrit.files.tar.gz.sig; do + curl -sSLf "https://packages.reauktion.de/arch/$target/$f" -o "$f" || rm -f "$f" + done + cp /tmp/build-his/*.pkg.tar.* . + pkgs=() + for ext in xz zst gz; do + for f in *.pkg.tar.$ext; do [ -f "$f" ] && pkgs+=("$f"); done + done + if [ -f marfrit.db.tar.gz ]; then + for f in "${pkgs[@]}"; do + name=$(echo "$f" | sed -E 's/-[0-9].*//') + repo-remove --sign --key 92D5E96D8F63C75E4116AA1FF5C8C4603D0D250C \ + marfrit.db.tar.gz "$name" 2>/dev/null || true + done + fi + repo-add --new --sign --key 92D5E96D8F63C75E4116AA1FF5C8C4603D0D250C \ + --verify marfrit.db.tar.gz "${pkgs[@]}" + ln -sf marfrit.db.tar.gz marfrit.db + ln -sf marfrit.files.tar.gz marfrit.files + ln -sf marfrit.db.tar.gz.sig marfrit.db.sig + ln -sf marfrit.files.tar.gz.sig marfrit.files.sig + rsync -avL --copy-unsafe-links \ + -e 'ssh -i /root/.ssh/id_ed25519' \ + ./ "mfritsche@nc.reauktion.de:arch/$target/" + done + + - name: wipe secrets + if: always() + run: rm -f /root/repo_pass /root/.ssh/id_ed25519 + + # ------------------------------------------------------------------------- + # claude-his-agent Debian (Architecture: all) — same dpkg-deb pattern as + # lmcp-debian; publishes to bookworm + trixie via hertz reprepro. + # ------------------------------------------------------------------------- + claude-his-debian: + needs: claude-his-any + runs-on: arch-aarch64 + steps: + - uses: actions/checkout@v4 + + - name: install dpkg + run: pacman -Syu --noconfirm --needed dpkg openssh rsync curl + + - name: install hertz deploy ssh key + env: + KEY: ${{ secrets.MARFRIT_REPO_HERTZ_KEY }} + run: | + mkdir -m700 -p /root/.ssh + printf '%s\n' "$KEY" > /root/.ssh/id_ed25519_hertz + chmod 600 /root/.ssh/id_ed25519_hertz + ssh-keyscan -t ed25519 hertz.fritz.box >> /root/.ssh/known_hosts 2>/dev/null + + - name: build claude-his-agent .deb + run: | + set -e + cd debian/claude-his-agent + ./build-deb.sh + ls -la *.deb + + - name: upload + publish to suites + run: | + set -e + cd debian/claude-his-agent + DEB=$(ls claude-his-agent_*.deb | head -1) + rsync -av -e 'ssh -i /root/.ssh/id_ed25519_hertz' "$DEB" \ + marfritrepo@hertz.fritz.box: + for suite in bookworm trixie; do + ssh -i /root/.ssh/id_ed25519_hertz marfritrepo@hertz.fritz.box \ + "publish-deb $suite $DEB" + done + + - name: wipe secrets + if: always() + run: rm -f /root/.ssh/id_ed25519_hertz diff --git a/arch/claude-his-agent/PKGBUILD b/arch/claude-his-agent/PKGBUILD new file mode 100644 index 000000000..da7ce32a2 --- /dev/null +++ b/arch/claude-his-agent/PKGBUILD @@ -0,0 +1,22 @@ +# Maintainer: Markus Fritsche +# Home Infrastructure Specialist subagent + skill for Claude Code. +# Source of truth: git.reauktion.de/marfrit/claude-his-agent + +pkgname=claude-his-agent +pkgver=0.1.0 +pkgrel=1 +pkgdesc="Home Infrastructure Specialist subagent + skill for Claude Code (mfritsche home infra)" +arch=('any') +url="https://git.reauktion.de/marfrit/claude-his-agent" +license=('custom') +depends=('bash') +source=("${pkgname}-${pkgver}.tar.gz::https://git.reauktion.de/marfrit/claude-his-agent/archive/v${pkgver}.tar.gz") +sha256sums=('d1e953632c3cf52ef9cd6ab51d2878808f99fb031931bbc99f6a554501dfc14e') + +package() { + cd "${pkgname}" + install -Dm644 agents/his.md "${pkgdir}/usr/share/claude-agents/his.md" + install -Dm644 skills/his/SKILL.md "${pkgdir}/usr/share/claude-skills/his/SKILL.md" + install -Dm755 scripts/claude-his-install "${pkgdir}/usr/bin/claude-his-install" + install -Dm644 README.md "${pkgdir}/usr/share/doc/${pkgname}/README.md" +} diff --git a/debian/claude-his-agent/build-deb.sh b/debian/claude-his-agent/build-deb.sh new file mode 100755 index 000000000..145225f6f --- /dev/null +++ b/debian/claude-his-agent/build-deb.sh @@ -0,0 +1,57 @@ +#!/bin/bash +# Build claude-his-agent__all.deb from this directory using dpkg-deb. +# Mirrors the lmcp/build-deb.sh pattern. +set -euo pipefail + +PKGVER=0.1.0 +PKGREL=1 +HIS_TARBALL_SHA256=d1e953632c3cf52ef9cd6ab51d2878808f99fb031931bbc99f6a554501dfc14e +HERE=$(dirname "$(readlink -f "$0")") + +# Reproducible build: pin mtimes + ar member timestamps to a fixed epoch +# tied to this release (v0.1.0, 2026-04-17 11:30 UTC). +export SOURCE_DATE_EPOCH=1776698400 + +work=$(mktemp -d) +trap "rm -rf $work" EXIT + +cd "$work" +curl -sSLfo his.tar.gz \ + "https://git.reauktion.de/marfrit/claude-his-agent/archive/v${PKGVER}.tar.gz" +echo "$HIS_TARBALL_SHA256 his.tar.gz" | sha256sum -c +tar xzf his.tar.gz + +ROOT="$work/pkgroot" +mkdir -p "$ROOT/DEBIAN" \ + "$ROOT/usr/share/claude-agents" \ + "$ROOT/usr/share/claude-skills/his" \ + "$ROOT/usr/bin" \ + "$ROOT/usr/share/doc/claude-his-agent" + +install -m 644 claude-his-agent/agents/his.md "$ROOT/usr/share/claude-agents/his.md" +install -m 644 claude-his-agent/skills/his/SKILL.md "$ROOT/usr/share/claude-skills/his/SKILL.md" +install -m 755 claude-his-agent/scripts/claude-his-install "$ROOT/usr/bin/claude-his-install" +install -m 644 claude-his-agent/README.md "$ROOT/usr/share/doc/claude-his-agent/README.md" +install -m 644 "$HERE/debian/copyright" "$ROOT/usr/share/doc/claude-his-agent/copyright" + +# Render control from the source debian/control, filling in version +CONTROL_SRC="$HERE/debian/control" +{ + echo "Package: claude-his-agent" + echo "Version: ${PKGVER}-${PKGREL}" + echo "Architecture: all" + echo "Maintainer: Markus Fritsche " + echo "Homepage: https://git.reauktion.de/marfrit/claude-his-agent" + echo "Section: utils" + echo "Priority: optional" + echo "Depends: bash" + # Trailing description from the source control (indented multi-line block) + awk '/^Description:/{p=1} p' "$CONTROL_SRC" +} > "$ROOT/DEBIAN/control" + +# Normalize mtimes for reproducibility +find "$ROOT" -exec touch -d "@$SOURCE_DATE_EPOCH" {} + + +OUT_DEB="$HERE/claude-his-agent_${PKGVER}-${PKGREL}_all.deb" +dpkg-deb --build --root-owner-group "$ROOT" "$OUT_DEB" +ls -la "$OUT_DEB" diff --git a/debian/claude-his-agent/debian/changelog b/debian/claude-his-agent/debian/changelog new file mode 100644 index 000000000..35059a659 --- /dev/null +++ b/debian/claude-his-agent/debian/changelog @@ -0,0 +1,6 @@ +claude-his-agent (0.1.0-1) trixie; urgency=low + + * Initial release — subagent + skill for summoning His across sibling Claude + Code instances, encoding distcc + /opt/herding/ + lmcp + wake procedures. + + -- Markus Fritsche Fri, 17 Apr 2026 12:00:00 +0200 diff --git a/debian/claude-his-agent/debian/control b/debian/claude-his-agent/debian/control new file mode 100644 index 000000000..02310d18a --- /dev/null +++ b/debian/claude-his-agent/debian/control @@ -0,0 +1,18 @@ +Source: claude-his-agent +Section: utils +Priority: optional +Maintainer: Markus Fritsche +Standards-Version: 4.6.2 +Homepage: https://git.reauktion.de/marfrit/claude-his-agent + +Package: claude-his-agent +Architecture: all +Depends: bash +Description: Home Infrastructure Specialist subagent + skill for Claude Code + Ships the His subagent (agents/his.md) and skill (skills/his/SKILL.md) that + encode operational knowledge of mfritsche's home network — distcc hosts, + wake procedures, /opt/herding/ tooling, lmcp endpoints — so sibling Claude + Code instances can summon it instead of re-learning the infra every session. + . + Files install to /usr/share/claude-agents/ and /usr/share/claude-skills/his/. + Run 'claude-his-install' as a user to symlink them into ~/.claude/. diff --git a/debian/claude-his-agent/debian/copyright b/debian/claude-his-agent/debian/copyright new file mode 100644 index 000000000..ff0b86b6a --- /dev/null +++ b/debian/claude-his-agent/debian/copyright @@ -0,0 +1,9 @@ +Format: https://www.debian.org/doc/packaging-manuals/copyright-format/1.0/ +Upstream-Name: claude-his-agent +Upstream-Contact: Markus Fritsche +Source: https://git.reauktion.de/marfrit/claude-his-agent + +Files: * +Copyright: 2026 Markus Fritsche +License: custom + Personal infra tooling. All rights reserved unless negotiated.