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:
co-authored by
Claude Opus 4.8
parent
63dbd2727f
commit
0f8893330f
+11
-13
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user