- Add 48 new MCP/AI-assistant tools covering guest lifecycle, node
operations, firewall/security, and backup/replication/HA/storage/SDN
management. Every mutating tool is admin-gated the same way
guest_power_action already is; migrate/resize/move-disk, node
reboot/shutdown, disk wipe, cert revocation, and cluster-node removal are
deliberately left out as being as destructive as a delete.
- ai_chat.go: when a provider (chiefly Needle, a pure tool-router with no
narrative output of its own) finishes calling tools but returns nothing to
say, render the tool results themselves as the answer instead of the
misleading "ran out of tool calls" message.
- needle.go: serialize every request against the shared Needle subprocess
(it handles one request at a time) to stop concurrent callers from racing
it, and surface the subprocess's captured output when a request fails
because it died mid-response, instead of a bare network error.
- Dockerfile: switch the final stage from distroless "static" to "base" —
the bundled Needle CLI is a dynamically-linked glibc binary and cannot run
in an image with no libc at all.
- .github/workflows/release.yml: build and push a multi-arch (amd64/arm64)
Docker image to ghcr.io on every version tag, tagged with the version and
"latest".
- Dockerfile/README: add OCI image labels and document the published GHCR
image as the primary Docker install path.
scripts/build.sh, get.sh, and scripts/linux/*.sh had lost their executable
bit in git (core.fileMode=false on this Windows checkout meant a local
chmod +x never made it into the index) — release.yml invokes
scripts/build.sh directly rather than via `bash`, so the CI job failed
immediately with exit code 126 (permission denied). Also invoke it via
`bash` explicitly as a second line of defense, and fix the zip-install
step's `||`/`&&` operator precedence (it always ran apt-get regardless of
whether zip was already present, harmless but not what it looked like).
Verified locally end-to-end: scripts/build.sh all now builds and packages
all 6 platform targets and every checksum verifies.
- ci.yml: build the frontend before go vet/build/test — web/embed.go's
//go:embed all:dist has no dist/ to embed otherwise (dist/ is gitignored,
not committed), which was failing every CI run with "pattern all:dist:
no matching files found".
- Untrack Claude-Account-1.cmd (personal local launcher script, already
gitignored — file stays on disk, just stops being pushed).
- README: rework the Screenshots section into a proper 2-column HTML
table gallery with clickable thumbnails, instead of ten full-width
images stacked one after another.
- .gitignore/.dockerignore: cover Go build artifacts, env files, logs,
editor/OS cruft, and local runtime data (sqlite db/secret, config.yaml).
- README: add a Screenshots section (captured against a mock Proxmox
cluster) and a Deploying a release build section.
- LICENSE: MIT.
Deployable binaries:
- cmd/ferrum: -version flag with build-time version/commit/date via
-ldflags; -log-file flag (Windows services don't capture stdout/stderr
the way systemd does); native Windows Service Control Manager support
(service_windows.go) so ferrum.exe manages its own start/stop lifecycle
under a Windows service, same graceful-shutdown path SIGTERM already used
on Linux.
- packaging/systemd/ferrum.service: hardened systemd unit.
- scripts/build.sh, build.ps1: cross-compile linux/windows/darwin x
amd64/arm64, package as .tar.gz/.zip with an install script and
checksums.txt.
- scripts/linux/install.sh, uninstall.sh: create a dedicated system user,
install the binary, seed /etc/ferrum/config.yaml, enable + start the
systemd service.
- scripts/get.sh: one-line curl-pipeable installer (get.docker.com style)
that resolves the latest release, verifies its checksum, and hands off
to install.sh.
- scripts/windows/install-service.ps1, uninstall-service.ps1: register/
remove the self-managing Windows service.
- .github/workflows/release.yml: publish all platform archives + checksums
as GitHub Release assets on a vX.Y.Z tag push.
- .github/workflows/ci.yml: go vet/build/test, frontend lint/test/build,
and shell-script syntax checks on push/PR.