agents: caller-provided skills hook — repos can ship their own opencode skills

A consuming repo can now add repo-specific skills under .gitea/agent-skills/<name>/
(SKILL.md + skill.json + optional setup.sh); the framework installs the ones
allowed for the running agent. This keeps deploy-target / infra specifics in the
repo they belong to instead of hardcoded in the shared workflow.

- install-caller-skills.sh: scans the caller workspace, installs each skill whose
  skill.json `agents` list includes the running agent, runs its optional setup.sh
  with all inherited secrets available as $SECRETS_JSON (toJSON(secrets) — so a
  caller's setup can read repo-specific secret names the framework can't know),
  and merges the allowed skills into the permission.skill allow-list.
- agent.yml: replace the hardcoded node1-ssh step with the generic caller-skills
  step (passes NAME, WORKSPACE, SECRETS_JSON).
- Remove the built-in node1-ssh skill: delete skill-node1-ssh.sh, drop "node1-ssh"
  from agents.json (senior/lead). The homelab repo now owns that skill.
- run-agent.sh: note caller-provided skills aren't in the roster (route them via
  the caller's AGENTS.md).

toJSON(secrets) verified supported on this Gitea (1.27) via an isolated probe.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
Felix Faerber
2026-07-05 17:35:45 +03:00
co-authored by Claude Opus 4.8
parent 63dbd2727f
commit 0f8893330f
5 changed files with 127 additions and 106 deletions
+11 -13
View File
@@ -112,21 +112,19 @@ jobs:
SKILLS: ${{ steps.prep.outputs.skills }} # JSON array of skills this agent may load
run: bash "$SCRIPTS/install-opencode.sh"
- name: Set up read-only SSH alias `node1` (+ opencode skill so the agent actually knows about it)
# 1) Writes the deploy key + an SSH config alias so the agent can run
# `ssh node1 <read-only cmd>` (matches the homelab opencode.json allowlist).
# 2) Emits a `node1-ssh` opencode Skill file under ~/.config/opencode/skills/ so any
# downstream repo's dev agent discovers this capability via OpenCode's skill registry
# rather than having to trial against the permission allowlist. Only emitted when the
# swarm plumbing is actually wired for that caller (SWARM_HOST/SWARM_USER/SSH_PRIV_KEY).
# All three secrets are passed via env and never inlined into shell — this shared workflow
# runs in repos that don't have them and must not fail there.
- name: Install caller-provided skills (from the caller repo's .gitea/agent-skills/)
# Framework skill-plugin hook. A consuming repo can ship its OWN opencode skills under
# `.gitea/agent-skills/<name>/` (SKILL.md + skill.json + optional setup.sh) — e.g. homelab's
# "ssh into the deploy host" skill. This installs the ones allowed for the running agent, so
# deploy-target / infra specifics live in the repo they belong to, not in this framework.
# SECRETS_JSON = toJSON(secrets): a caller's setup.sh reads the repo-specific secrets it needs
# (whose names this framework can't know) via jq; it never touches disk here in the clear.
env:
SCRIPTS: ${{ runner.temp }}/agents-scripts
SWARM_HOST: ${{ secrets.SWARM_HOST }}
SWARM_USER: ${{ secrets.SWARM_USER }}
SSH_PRIV_KEY: ${{ secrets.SSH_PRIV_KEY }}
run: bash "$SCRIPTS/skill-node1-ssh.sh"
NAME: ${{ steps.prep.outputs.name }}
WORKSPACE: ${{ github.workspace }}
SECRETS_JSON: ${{ toJSON(secrets) }}
run: bash "$SCRIPTS/install-caller-skills.sh"
- name: Set up `gitea-api` skill (let agents read/write issues, PRs, Actions across repos)
# Emits an opencode Skill file. The skill uses SELF_TOKEN — the running agent's OWN token