Feature: strukturerade verktygsgodkännanden
- shared: protokoll för approval (daemon:approval, server:approval[-resolved],
web:approval-decision, server:approval-decision)
- daemon: hook-läge ('agent-helm hook' — samma binär), lokal 127.0.0.1-endpoint
som hooken POST:ar till, long-poll tills beslut; graceful default (allow) när
ingen UI; timeout-fallback; skickar AGENT_HELM_HOOK_PORT till agentens env
- server: routar daemon:approval -> prenumeranter, beslut -> daemon + döljer kort
- web: reaktiv approvals-lista + kort-overlay (Tillåt/Neka), mobilanpassad
CI:
- release.yaml triggar nu även på master-push -> rullande 'latest'-release
(versionerade releaser kvar på v*-taggar); install.sh hämtar 'latest'
Docs: hook-konfig (gemini settings.json) + hook-env i .env.example + DEPLOY.md.
Säkerhet: hook-endpoint binder endast 127.0.0.1; inga hemligheter i repot.
Verifierat lokalt: hook->daemon->server->kort->beslut->hook ger {"decision":"allow"};
alla paket typecheckar; web bygger.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
8.9 KiB
Deploy: agent-helm på Pi5 via Gitea Actions → registry → Dockge → NPM
Flödet: git push master → Gitea Actions-runnern på Pi5 bygger arm64-image:n
→ pushar till localhost:5000/agent-helm-server:latest → Dockge kör stacken →
NPM exponerar https://rcai.brasse-pc.eu. Uppdatering = push + klicka Update i Dockge.
push master ──► gitea-act-runner (bygg arm64) ──► localhost:5000/agent-helm-server:latest
│
Dockge: Update (pull + up -d)
▼
container "agent-helm" :8787 (srv_default)
▲
NPM: rcai.brasse-pc.eu ─┘ (Websockets ON, TLS)
Förutsättningar som redan är på plats: DNS rcai.brasse-pc.eu → 155.4.72.51 (✓),
srv_default-nätet, docker-registry och npm körs (✓). Gitea 1.24 har Actions
påslaget som default.
Kataloger & ägarskap (gör FÖRE deploy)
Bind-mountade kataloger måste finnas och ägas av uid 1000 innan containern
startar. Startar containern först skapar Docker katalogen som root, och appen
(kör som uid 1000 node) kan då inte läsa/skriva den. Skapa som brasse (= uid 1000):
# data/config för appen (måste vara uid 1000-ägd — appen skriver hit)
mkdir -p /srv/docker/agent-helm
# runner-state
mkdir -p /srv/docker/act-runner
# stack-mappar för Dockge
mkdir -p /srv/dockge-staks/act-runner /srv/dockge-staks/agent-helm
# verifiera ägarskap (ska visa uid 1000 i andra kolumnen)
ls -ln /srv/docker | grep -E 'agent-helm|act-runner'
Om någon katalog råkat bli root-ägd (t.ex. för att en container startade först):
sudo chown -R 1000:1000 /srv/docker/agent-helm
# starta sedan om stacken så mounten läses om
Steg 1 — Registrera Gitea Actions-runnern (engång)
-
Hämta registrerings-token i Gitea:
Site Administration → Actions → Runners → Create new runner→ kopiera token. (Eller repo-nivå:brasse/agent-helm → Settings → Actions → Runners.) -
Skapa stacken i Dockge (
dockge.brasse-pc.eu):- Ny stack, namn
act-runner. - Klistra in
deploy/act-runner.compose.yaml. - Lägg
deploy/act-runner.config.yamlsom filenconfig.yamli stacken (Dockge låter dig skapa extra filer i stack-mappen, dvs/srv/dockge-staks/act-runner/config.yaml). - I stackens env:
GITEA_RUNNER_REGISTRATION_TOKEN=<din-token>. - Deploy.
- Ny stack, namn
-
Verifiera: i Gitea
Site Administration → Actions → Runnersskapi5-docker-runnerdyka upp som Idle. Loggen:docker logs gitea-act-runner.
Runnern monterar värdens
docker.sockoch bygger med Pi5:ans egen Docker → arm64 nativt, ochlocalhost:5000(registryn) trustas automatiskt.
Steg 2 — Första bygget
.gitea/workflows/build.yaml triggas på push till master/main. Trigga det:
- Pusha en commit till
master, eller - Gitea repo →
Actions→ välj workflowen →Run workflow(manuell dispatch).
Följ körningen under repo:ts Actions-flik. När den är grön finns
localhost:5000/agent-helm-server:latest i registryn.
Snabbkoll (på Pi5, eller via claude-docker):
curl -s http://localhost:5000/v2/agent-helm-server/tags/list
# -> {"name":"agent-helm-server","tags":["latest","<sha>"]}
Steg 3 — Kör stacken i Dockge
- Skapa host-katalogen för config/data (som
brasse, uid 1000):mkdir -p /srv/docker/agent-helmDen bind-mountas till/app/datai containern (där framtida db/auth hamnar); containern kör som uid 1000 =brasseså filerna blir korrekt ägda. - Ny stack i Dockge, namn
agent-helm. - Klistra in
deploy/agent-helm.compose.yaml. - I stackens env:
AGENT_HELM_TOKEN=<lång slumpad hemlighet>— en stark slumpad sträng (≥ 32 byte). Förvaras bara i stackens.envpå Pi5, aldrig i git. Det är denna token som skyddar åtkomsten till dina sessioner, så håll den hemlig. - Deploy. Kolla i Dockge att containern
agent-helmär running.
Steg 4 — NPM proxy host (manuellt i NPM-UI:t)
I Proxy.brasse-pc.eu → Proxy Hosts → Add Proxy Host:
| Fält | Värde |
|---|---|
| Domain Names | rcai.brasse-pc.eu |
| Scheme | http |
| Forward Hostname | agent-helm |
| Forward Port | 8787 |
| Websockets Support | PÅ (viktigt — WS-kanalen) |
| Block Common Exploits | valfritt |
Under SSL: Request a new SSL Certificate (Let's Encrypt) + Force SSL + HTTP/2.
Spara. Öppna https://rcai.brasse-pc.eu → logga in med AGENT_HELM_TOKEN.
Steg 5 — Anslut en daemon (annars finns inga sessioner)
Servern är bara control-plane. En daemon kör agenten och ansluter till servern. Kör den var du vill (workstation, eller som egen container senare):
# på workstationen, i agent-helm-repot
AGENT_HELM_TOKEN=<samma-token> \
SERVER_URL=wss://rcai.brasse-pc.eu \
AGENT_CMD=gemini \
pnpm dev:daemon
Daemonen dyker upp som en session i web-UI:t. (Kräver att NPM:s Websockets är på.)
Klienten (daemon) — installera på en Linux-maskin
Klienten distribueras som självständiga binärer (Node + node-pty inbäddat, inga
beroenden på målet) för linux-x64 och linux-arm64, byggda av
.gitea/workflows/release.yaml och publicerade som Release-assets på Gitea.
Skapa en release (bygger båda arkitekturerna på Pi-runnern):
git tag v0.1.0 && git push origin v0.1.0
# eller: Gitea -> Actions -> release-client -> Run workflow (ange tag)
Installera på valfri Linux-maskin (Arch, Ubuntu, …) — ett kommando:
curl -fsSL https://gitea.brasse-pc.eu/brasse/agent-helm/raw/branch/main/install.sh | sh
Installern detekterar arch, hämtar rätt binär från senaste releasen, lägger
agent-helm i /usr/local/bin (eller ~/.local/bin), skapar
~/.config/agent-helm/config.env och en (valfri) systemd-user-service.
Sätt token + kör:
${EDITOR:-nano} ~/.config/agent-helm/config.env # AGENT_HELM_TOKEN, SERVER_URL, AGENT_CMD
systemctl --user daemon-reload && systemctl --user enable --now agent-helm
# eller direkt: set -a; . ~/.config/agent-helm/config.env; agent-helm
Klienten ansluter till wss://rcai.brasse-pc.eu och dyker upp som en session i UI:t.
Strukturerade godkännanden (BeforeTool-hook + kort-vy)
Utöver fallback-tangentbordet kan agentens verktygsanrop visas som godkännande-kort
i UI:t (Tillåt/Neka). Det sker via en BeforeTool-hook i Gemini som anropar
agent-helm hook — samma binär, så inget extra beroende.
Aktivera genom att lägga till hooken i ~/.gemini/settings.json på maskinen där
klienten kör (justera vid behov efter din Gemini-versions hook-schema):
{
"hooks": {
"BeforeTool": [
{ "hooks": [{ "type": "command", "command": "agent-helm hook" }] }
]
}
}
Daemonen skickar automatiskt AGENT_HELM_HOOK_PORT till agentens miljö, så
agent-helm hook hittar den lokala endpointen själv.
Beteende:
- UI anslutet → verktygsanropet visas som kort, agenten väntar på ditt beslut.
- Ingen UI / servern onåbar →
AGENT_HELM_HOOK_DEFAULT(defaultallow— agenten fungerar som utan hook). SättAGENT_HELM_HOOK_DEFAULT=denyför strikt läge. - Inget svar inom
AGENT_HELM_HOOK_TIMEOUT(ms) → default-beslutet används.
Den lokala hook-endpointen binder endast 127.0.0.1 och är aldrig nåbar utifrån.
Uppdatera till senaste
git push master→ runnern bygger + pushar:latest.- Dockge → stacken
agent-helm→ Update (kördocker compose pull && up -d).
Det var det — senaste image:n körs.
Felsökning
| Symptom | Trolig orsak / åtgärd |
|---|---|
| Runnern syns inte i Gitea | Fel/förbrukad token. Skapa ny, uppdatera env, redeploy act-runner. |
Workflow fastnar på actions/checkout |
Runnern når inte github för att hämta action:en, eller inte gitea-d:3000. Kolla att runnern är på srv_default. |
docker: command not found i jobbet |
Fel job-image. Labeln ska peka på catthehacker/ubuntu:act-latest. |
push nekas / http: server gave HTTP response to HTTPS client |
Pusha till localhost:5000 (inte 192.168.0.19:5000) från Pi-runnern — localhost trustas som insecure automatiskt. |
rcai ger 502 |
agent-helm-containern nere, eller fel forward-namn/port i NPM. |
| WS ansluter inte (UI loggar in men sessioner laddar ej) | Websockets Support av i NPM-hosten. Slå på. |
| Bygget kompilerar node-pty och failar | Ska inte hända — Dockerfilen filtrerar bort daemon. Om det sker: kontrollera --filter-raderna. |