Merge pull request 'aish: package v0.1.0 for arch + debian' (#95) from claude-noether/marfrit-packages:noether/aish-v0.1.0-package into main
build and publish packages / distcc-avahi-aarch64 (push) Successful in 6s
build and publish packages / mesa-panvk-bifrost-aarch64 (push) Successful in 5s
build and publish packages / mesa-panvk-bifrost-video-aarch64 (push) Successful in 3s
build and publish packages / lmcp-any (push) Successful in 4s
build and publish packages / lmcp-debian (push) Successful in 3s
build and publish packages / claude-his-any (push) Successful in 3s
build and publish packages / aish-any (push) Successful in 12s
build and publish packages / ffmpeg-v4l2-request-aarch64 (push) Successful in 3s
build and publish packages / claude-his-debian (push) Successful in 3s
build and publish packages / ffmpeg-v4l2-request-debian (push) Successful in 5s
build and publish packages / daedalus-v4l2-debian (push) Successful in 4s
build and publish packages / aish-debian (push) Successful in 9s
build and publish packages / daedalus-v4l2-dkms-debian (push) Successful in 5s
build and publish packages / libva-v4l2-request-fourier-aarch64 (push) Successful in 7s
build and publish packages / libva-v4l2-request-fourier-debian (push) Successful in 4s
build and publish packages / mpv-fourier-aarch64 (push) Successful in 3s
build and publish packages / mpv-fourier-debian (push) Successful in 3s

Reviewed-on: #95
This commit was merged in pull request #95.
This commit is contained in:
2026-05-24 22:40:53 +00:00
6 changed files with 378 additions and 0 deletions
+176
View File
@@ -1556,3 +1556,179 @@ jobs:
if: always() if: always()
run: rm -f /root/repo_pass /root/.ssh/id_ed25519 run: rm -f /root/repo_pass /root/.ssh/id_ed25519
# -------------------------------------------------------------------------
# aish (arch=any) — pure LuaJIT, one .pkg.tar valid on every pacman target.
# Same dual-arch publish pattern as lmcp / claude-his.
# -------------------------------------------------------------------------
aish-any:
needs: lmcp-debian # parallel with claude-his-any (pure-Lua sibling),
# serialized via the shared arch-aarch64 runner.
# Avoids needless wait through the fourier stack.
runs-on: arch-aarch64
steps:
- uses: actions/checkout@v4
- name: skip if already published
id: skip-check
run: |
set -e
result=$(./.gitea/scripts/check-already-published.sh arch/aish)
echo "$result" >> "$GITHUB_OUTPUT"
echo "decision: $result"
- name: bootstrap runner (idempotent)
if: steps.skip-check.outputs.skip != '1'
run: |
set -e
retry() { for i in 1 2 3; do "$@" && return 0; rc=$?; echo "retry $i (exit=$rc)" >&2; sleep $((i*5)); done; return 1; }
retry pacman -Syu --noconfirm --needed base-devel git rsync gnupg openssh sudo luajit readline curl
- name: import signing key
if: steps.skip-check.outputs.skip != '1'
env:
PRIV: ${{ secrets.MARFRIT_REPO_PRIVATE_KEY }}
PASS: ${{ secrets.MARFRIT_REPO_PASSPHRASE }}
run: |
set -e
gpgconf --homedir /root/.gnupg --kill all 2>/dev/null || true
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
if: steps.skip-check.outputs.skip != '1'
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 aish
if: steps.skip-check.outputs.skip != '1'
run: |
set -e
rm -rf /tmp/build-aish
cp -r arch/aish /tmp/build-aish
chown -R builder:builder /tmp/build-aish
cd /tmp/build-aish
sudo -u builder -H makepkg --nocheck --noconfirm --syncdeps --cleanbuild
ls -la *.pkg.tar.* | grep -v "\.sig$"
- name: sign aish
if: steps.skip-check.outputs.skip != '1'
run: |
set -e
cd /tmp/build-aish
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 aish to both arches
if: steps.skip-check.outputs.skip != '1'
run: |
set -e
retry() { for i in 1 2 3; do "$@" && return 0; rc=$?; echo "retry $i (exit=$rc)" >&2; sleep $((i*5)); done; return 1; }
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-$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-aish/*.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
retry 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
aish-debian:
needs: aish-any # serialize after the Arch build to share the runner
runs-on: arch-aarch64
steps:
- uses: actions/checkout@v4
- name: skip if already published
id: skip-check
run: |
set -e
result=$(./.gitea/scripts/check-already-published.sh debian/aish)
echo "$result" >> "$GITHUB_OUTPUT"
echo "decision: $result"
- name: install dpkg
if: steps.skip-check.outputs.skip != '1'
run: |
set -e
retry() { for i in 1 2 3; do "$@" && return 0; rc=$?; echo "retry $i (exit=$rc)" >&2; sleep $((i*5)); done; return 1; }
retry pacman -Syu --noconfirm --needed dpkg openssh rsync curl
- name: install hertz deploy ssh key
if: steps.skip-check.outputs.skip != '1'
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 aish .deb
if: steps.skip-check.outputs.skip != '1'
run: |
set -e
cd debian/aish
./build-deb.sh
ls -la *.deb
- name: upload + publish to suites
if: steps.skip-check.outputs.skip != '1'
run: |
set -e
retry() { for i in 1 2 3; do "$@" && return 0; rc=$?; echo "retry $i (exit=$rc)" >&2; sleep $((i*5)); done; return 1; }
cd debian/aish
DEB=$(ls aish_*.deb | head -1)
# Push the .deb into hertz's incoming dir via rrsync.
retry rsync -av -e 'ssh -i /root/.ssh/id_ed25519_hertz' "$DEB" \
marfritrepo@hertz.fritz.box:
# Trigger reprepro for each suite.
for suite in bookworm trixie; do
retry 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
+53
View File
@@ -0,0 +1,53 @@
# Maintainer: Markus Fritsche <mfritsche@reauktion.de>
# aish — AI-augmented conversational shell in LuaJIT.
# Source of truth: git.reauktion.de/marfrit/aish
pkgname=aish
pkgver=0.1.0
pkgrel=1
pkgdesc="AI-augmented conversational shell (LuaJIT, FFI-only)"
arch=('any')
url="https://git.reauktion.de/marfrit/aish"
license=('MIT')
depends=('luajit' 'readline' 'curl')
# The _tag back-translation handles both clean releases (no '_') and
# pre-release pkgvers (e.g. 0.1.0_rc1 → v0.1.0-rc1).
_tag="v${pkgver//_/-}"
source=("${pkgname}-${pkgver}.tar.gz::https://git.reauktion.de/marfrit/aish/archive/${_tag}.tar.gz")
sha256sums=('9ebc3939e028832e39391ae33efacb5ec9bcd99d123cbc8ca1cd6ca9a640b5b5')
package() {
cd "${pkgname}"
local libdir="${pkgdir}/usr/share/lua/5.1/aish"
# Top-level modules
install -Dm644 main.lua "${libdir}/main.lua"
install -Dm644 broker.lua "${libdir}/broker.lua"
install -Dm644 context.lua "${libdir}/context.lua"
install -Dm644 executor.lua "${libdir}/executor.lua"
install -Dm644 history.lua "${libdir}/history.lua"
install -Dm644 mcp.lua "${libdir}/mcp.lua"
install -Dm644 renderer.lua "${libdir}/renderer.lua"
install -Dm644 repl.lua "${libdir}/repl.lua"
install -Dm644 router.lua "${libdir}/router.lua"
install -Dm644 safety.lua "${libdir}/safety.lua"
install -Dm644 secrets.lua "${libdir}/secrets.lua"
# FFI bindings
install -Dm644 ffi/curl.lua "${libdir}/ffi/curl.lua"
install -Dm644 ffi/libc.lua "${libdir}/ffi/libc.lua"
install -Dm644 ffi/pty.lua "${libdir}/ffi/pty.lua"
install -Dm644 ffi/readline.lua "${libdir}/ffi/readline.lua"
# Vendored dependencies
install -Dm644 vendor/dkjson.lua "${libdir}/vendor/dkjson.lua"
# Launch wrapper
install -Dm755 bin/aish "${pkgdir}/usr/bin/aish"
# Documentation + example config
install -Dm644 README.md "${pkgdir}/usr/share/doc/${pkgname}/README.md"
install -Dm644 LICENSE "${pkgdir}/usr/share/doc/${pkgname}/LICENSE"
install -Dm644 examples/config.lua \
"${pkgdir}/usr/share/doc/${pkgname}/examples/config.lua"
}
Vendored Executable
+85
View File
@@ -0,0 +1,85 @@
#!/bin/bash
# Build aish_<ver>_all.deb from this directory using dpkg-deb directly.
# Run from inside the runner container, which has dpkg installed.
#
# Matches the lmcp build-deb.sh pattern: no dh/debhelper, no Build-Depends
# beyond `dpkg`, structurally a normal apt package (Architecture: all).
set -euo pipefail
PKGVER=0.1.0
UPSTREAM_TAG=v0.1.0
PKGREL=1
AISH_TARBALL_SHA256=9ebc3939e028832e39391ae33efacb5ec9bcd99d123cbc8ca1cd6ca9a640b5b5
HERE=$(dirname "$(readlink -f "$0")")
# Reproducible build: pin all file mtimes + ar member timestamps to a fixed
# epoch tied to this packaging release (aish v0.1.0 — 2026-05-25 00:00 UTC).
# Without this, repeat builds produce different byte streams and reprepro
# refuses re-includes with "size expected: X, got: Y".
export SOURCE_DATE_EPOCH=1779667200
work=$(mktemp -d)
trap "rm -rf $work" EXIT
cd "$work"
curl --connect-timeout 10 --max-time 600 --retry 3 --retry-delay 5 -sSLfo aish.tar.gz \
"https://git.reauktion.de/marfrit/aish/archive/${UPSTREAM_TAG}.tar.gz"
echo "$AISH_TARBALL_SHA256 aish.tar.gz" | sha256sum -c
tar xzf aish.tar.gz
ROOT="$work/pkgroot"
LIBDIR="$ROOT/usr/share/lua/5.1/aish"
mkdir -p "$ROOT/DEBIAN" \
"$LIBDIR/ffi" \
"$LIBDIR/vendor" \
"$ROOT/usr/bin" \
"$ROOT/usr/share/doc/aish/examples"
# Top-level modules
for m in main broker context executor history mcp renderer repl router safety secrets; do
cp "aish/${m}.lua" "$LIBDIR/${m}.lua"
done
# FFI bindings
for m in curl libc pty readline; do
cp "aish/ffi/${m}.lua" "$LIBDIR/ffi/${m}.lua"
done
# Vendored dependencies
cp aish/vendor/dkjson.lua "$LIBDIR/vendor/dkjson.lua"
# Launch wrapper
install -m 755 aish/bin/aish "$ROOT/usr/bin/aish"
# Documentation + example config
cp aish/README.md "$ROOT/usr/share/doc/aish/"
cp aish/LICENSE "$ROOT/usr/share/doc/aish/"
cp aish/examples/config.lua "$ROOT/usr/share/doc/aish/examples/"
cp "$HERE/debian/copyright" "$ROOT/usr/share/doc/aish/copyright"
cp "$HERE/debian/changelog" "$ROOT/usr/share/doc/aish/changelog.Debian"
gzip -9 -n "$ROOT/usr/share/doc/aish/changelog.Debian"
cat > "$ROOT/DEBIAN/control" <<EOF
Package: aish
Version: ${PKGVER}-${PKGREL}
Section: shells
Priority: optional
Architecture: all
Depends: luajit, libreadline8t64 | libreadline8, libcurl4t64 | libcurl4
Maintainer: Markus Fritsche <mfritsche@reauktion.de>
Homepage: https://git.reauktion.de/marfrit/aish
Description: AI-augmented conversational shell (LuaJIT, FFI-only)
aish is an interactive REPL that interleaves shell execution and
language-model conversation against llama.cpp HTTP brokers. Pure
LuaJIT 2.x with FFI bindings to libcurl, GNU readline, and libc.
.
Modules install under /usr/share/lua/5.1/aish/. The launcher is
/usr/bin/aish. Example configuration is at
/usr/share/doc/aish/examples/config.lua (copy to
~/.config/aish/config.lua and adapt).
EOF
# Build the .deb. Output to current dir of the caller.
DEB_OUT=aish_${PKGVER}-${PKGREL}_all.deb
dpkg-deb --root-owner-group --build "$ROOT" "$HERE/$DEB_OUT"
echo "built: $HERE/$DEB_OUT"
+14
View File
@@ -0,0 +1,14 @@
aish (0.1.0-1) bookworm trixie; urgency=medium
* Initial release packaged for marfrit overlay repo. Phases 0-10
complete (102 closed issues): local llama.cpp + cloud broker
routing via hossenfelder, MCP tool calls with confirm-gate and
per-tool auto_approve, Chuck Norris autonomous mode with
destructive-op heuristic, cross-session memory.jsonl, multi-model
routing + GBNF grammar passthrough, project file-tree context,
cost/usage observability, /tokenize endpoint integration, project
overlay (.aish.lua + sha256-pinned trust ledger), cloud preplanner
→ local executor split.
* Source-of-truth: git.reauktion.de/marfrit/aish, tagged v0.1.0.
-- Markus Fritsche <mfritsche@reauktion.de> Mon, 25 May 2026 00:00:00 +0000
+20
View File
@@ -0,0 +1,20 @@
Source: aish
Section: shells
Priority: optional
Maintainer: Markus Fritsche <mfritsche@reauktion.de>
Standards-Version: 4.6.2
Homepage: https://git.reauktion.de/marfrit/aish
Package: aish
Architecture: all
Depends: ${misc:Depends}, luajit, libreadline8t64 | libreadline8, libcurl4t64 | libcurl4
Description: AI-augmented conversational shell (LuaJIT, FFI-only)
aish is an interactive REPL that interleaves shell execution and language-
model conversation against llama.cpp HTTP brokers. Implementation is pure
LuaJIT 2.x with FFI bindings to libcurl, GNU readline, and libc — no C
extensions, no build step.
.
Modules install under /usr/share/lua/5.1/aish/. The launcher is
/usr/bin/aish. Example configuration is at
/usr/share/doc/aish/examples/config.lua (copy to ~/.config/aish/config.lua
and adapt).
+30
View File
@@ -0,0 +1,30 @@
Format: https://www.debian.org/doc/packaging-manuals/copyright-format/1.0/
Upstream-Name: aish
Source: https://git.reauktion.de/marfrit/aish
Files: *
Copyright: 2026 Markus Fritsche <mfritsche@reauktion.de>
License: MIT
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
.
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND.
Files: vendor/dkjson.lua
Copyright: 2010-2014 David Heiko Kolf
License: MIT
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including the rights to use, copy,
modify, merge, publish, distribute, sublicense, and/or sell copies of the
Software, and to permit persons to whom the Software is furnished to do so,
subject to the following conditions: the above copyright notice and this
permission notice shall be included in all copies or substantial portions of
the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND.