Go-first workflows for managing, installing, and mounting AI agent skills across projects. Supports Claude Code, Codex, and Gemini CLI with local-only execution, containerised security audits, and symlink-based project mounting.
- Overview
- Prerequisites
- Quick Start
- Installation
- CLI Reference
- Make Targets
- Skill Management
- Security
- Configuration
- Development
- License
- Contributing
This project provides a Go CLI and Make-based workflow for:
- Local-only skill install/add inside this repository
- External project linking via
.agentsmount-style symlinks - Containerised security audit scanning with behavioural and YARA-based analysis
Skills are sourced from Vercel's skill.sh registry (vercel-labs/agent-skills) and stored under
.agents/skills/. They work with Claude Code, Codex, and Gemini CLI agents. All operations run locally — your code and
prompts are never sent to third-party services for skill management.
What is skill.sh? skill.sh is Vercel's open registry of agent skills. This project uses it as the default source for
make skillsandmake add-skill. The registry provides curated, community-contributed skills that enhance AI coding agents with domain-specific capabilities. Skills are downloaded once and stored locally — no ongoing connection to the registry is required.
| Dependency | Required for | Notes |
|---|---|---|
| Go 1.26+ | Development only | Not needed if using Docker or prebuilt binary |
| Docker | skills, add-skill, audit |
Required for containerised workflows |
| Make | Make targets | Optional but recommended for day-to-day use |
# 1. Configure environment
cp .env.example .env
# 2. Install skills into this repository
make skills
# 3. Mount skills to your project
make mount-skills TARGET_PROJECT=/absolute/path/to/your/project
# 4. Validate symlinks
make skills-validate TARGET_PROJECT=/absolute/path/to/your/projectClone the repository and build the Go CLI binary:
git clone https://github.com/gocanto/skills.git
cd skills
make build # outputs binary to dist/skillsDownload the prebuilt binary package from GHCR without cloning this repository.
# Optional for private packages
docker login ghcr.io
# Choose one tag: vX.Y.Z-linux-amd64, vX.Y.Z-linux-arm64, vX.Y.Z-darwin-amd64, vX.Y.Z-darwin-arm64
# Or use latest: latest-linux-amd64, latest-linux-arm64, latest-darwin-amd64, latest-darwin-arm64
docker pull ghcr.io/gocanto/skills-bin:latest-darwin-arm64
container_id="$(docker create ghcr.io/gocanto/skills-bin:latest-darwin-arm64)"
docker cp "${container_id}:/skills" ./skills
docker rm "${container_id}"
chmod +x ./skills
./skills helpStandalone command equivalents for Make workflows:
# make skills
./skills skills --repo-root /absolute/path/to/repo
# make add-skill SKILLS='skill-a,skill-b'
./skills add-skill --repo-root /absolute/path/to/repo --skills 'skill-a,skill-b'
# make mount-skills TARGET_PROJECT=/absolute/path/to/project
./skills mount-skills --project /absolute/path/to/project --source-root /absolute/path/to/repo --agents-source /absolute/path/to/repo/.agents
# make audit ROOT_PATH=/absolute/path/to/repo
./skills audit --root /absolute/path/to/repoNotes:
skillsandadd-skillrequire Docker at runtime and use a runner image (SKILLS_RUNNER_IMAGEor--runner-image).mount-skillslinks.agentsand.claudeinto the target project.mount-skillsuses--source-root(env:SKILLS_ROOT, default: current working directory absolute path) and--agents-source(env:AGENTS_DIR, default:<skills-root>/.agents).- If the provided source paths contain neither
.agentsnor.agents/skills,mount-skillsextracts embedded content to cache and uses that location as the source for the links.
Build and run the CLI entirely inside Docker (no host Go required):
docker build -f docker/Dockerfile.manager -t skills-cli:local .
docker run --rm -it \
-v /var/run/docker.sock:/var/run/docker.sock \
-v "$PWD":/workspace/skills \
-w /workspace/skills \
skills-cli:local helpGo CLI (development mode):
go run ./manager/cmd/skills <command> [flags]
--repo-root,--source-root,--agents-source, and--rootrequire absolute paths. Use$(pwd)as a shortcut during development.
Install all skills into this repository from the skill.sh registry.
go run ./manager/cmd/skills skills --repo-root /absolute/path/to/repo --runner-image ghcr.io/gocanto/skills-runner:latest| Flag | Default | Description |
|---|---|---|
--repo-root |
— | Absolute path to the repository root (required) |
--runner-image |
SKILLS_RUNNER_IMAGE env |
Docker image used for skill installation |
Add one or more specific skills to this repository from the skill.sh registry.
go run ./manager/cmd/skills add-skill --repo-root /absolute/path/to/repo --skills 'skill-a,skill-b'| Flag | Default | Description |
|---|---|---|
--repo-root |
— | Absolute path to the repository root (required) |
--skills |
* |
Comma-separated skill names or * for all |
--runner-image |
SKILLS_RUNNER_IMAGE env |
Docker image used for skill installation |
Link skills into an external project via symlinks.
go run ./manager/cmd/skills mount-skills --project /absolute/path/to/project --source-root /absolute/path/to/repo --agents-source /absolute/path/to/repo/.agents| Flag | Default | Description |
|---|---|---|
--project |
— | Absolute path to the target project (required) |
--source-root |
SKILLS_ROOT env |
Absolute path to the source repository root |
--agents-source |
AGENTS_DIR env |
Absolute path to the .agents directory |
Creates two symlinks in the target project:
<project>/.agents -> <source-root>/.agents(or embedded fallback)<project>/.claude -> <source-root>/.agents/skills(or embedded fallback)
If either target path already exists, it is moved to a timestamped backup before replacement.
Run containerised security scanning on installed skills.
go run ./manager/cmd/skills audit --root /absolute/path/to/repo| Flag | Default | Description |
|---|---|---|
--root |
— | Absolute path to the repository root (required) |
Default scan profile: --severity low --use-behavioral --yara-mode strict --fail-on-findings
| Target | Description |
|---|---|
make skills |
Install/update all skills in this repository |
make add-skill |
Add specific skills to this repository |
make mount-skills |
Mount skills into an external project |
make skills-validate |
Verify symlinks in an external project |
make audit |
Run security scanner on installed skills |
make build |
Build the Go CLI binary to dist/skills |
make format |
Run gofmt; with imports arg also runs goimports via Docker |
make lint |
Run gofmt check and go vet |
make test |
Run all tests (unit, functional, e2e) and check coverage |
make test-unit |
Run unit tests only |
make test-functional |
Run functional tests only |
make test-e2e |
Run end-to-end tests only |
make test-coverage |
Merge coverage reports and check threshold |
make turbo-build |
Run turbo run build via Docker |
make turbo-test |
Run turbo run test via Docker |
make turbo-lint |
Run turbo run lint via Docker |
| Variable | Used by | Default | Description |
|---|---|---|---|
TARGET_PROJECT |
mount-skills,skills-validate |
— | Required absolute path to target project |
SOURCE |
skills |
vercel-labs/agent-skills |
Source repository for skills |
SKILLS |
skills, add-skill |
* |
Comma-separated skill names or * |
SKILLS_ROOT |
mount-skills |
Host workspace path | Absolute path to the skills repository root |
AGENTS_DIR |
mount-skills |
— | Absolute path to the .agents directory |
ROOT_PATH |
audit |
Current directory | Absolute path to repo root to scan |
SKILL_SCANNER_PATH |
audit |
.agents/skills |
Path under ROOT_PATH to scan |
SKILL_SCANNER_ARGS |
audit |
See Security scanning | Extra args forwarded to skill-scanner |
SKILLS_RUNNER_IMAGE |
skills, add-skill |
ghcr.io/gocanto/skills-runner:latest |
Image override for runtime |
DISABLE_TELEMETRY |
skills |
1 |
Set to 1 to disable skills.sh telemetry |
COLOR |
All | always |
Output color mode: always, auto, never |
ALLOW_DOCKER_SOCK |
Tests, turbo | false |
Set to true for docker.sock mounted workflows |
USE_DOCKER |
Tests | true |
Set to false to run tests on host |
Populate or refresh the .agents/skills directory with all available skills from the skill.sh
registry:
make skillsOptional overrides:
make skills \
SOURCE=vercel-labs/agent-skills \
SKILLS='*' \
DISABLE_TELEMETRY=1 \
COLOR=alwaysmake skills and make add-skill are local-only for this repository. make skills TARGET_PROJECT=... is rejected —
use make mount-skills TARGET_PROJECT=... for external projects.
make add-skill SKILLS='skill-a'
make add-skill SKILLS='skill-a,skill-b'
make add-skill SKILLS='*'
make add-skillis locked tovercel-labs/agent-skills(skill.sh) and does not support other sources.
Remove a skill from this repository:
git rm -r .agents/skills/skill-aRemove mounted links from an external project:
rm -f /absolute/path/to/project/.agents
rm -f /absolute/path/to/project/.claudeExpose skills in another project without cloning this repository there:
make mount-skills TARGET_PROJECT=/absolute/path/to/your/projectThis always enforces:
<project>/.agents -> <source-root>/.agents(or embedded fallback)<project>/.claude -> <source-root>/.agents/skills(or embedded fallback)
If either target path already exists (file/dir/symlink), it is moved to a timestamped backup and replaced.
Verify that symlinks were correctly created in the target project:
make skills-validate TARGET_PROJECT=/absolute/path/to/your/projectThis checks that both .agents and .claude symlinks exist and point to valid targets. Broken or missing symlinks are
reported as errors.
- Local-Only Execution: All skills are stored and executed locally within your environment. Your code and prompts are never sent to third-party services for skill management.
- Containerised Audits: The
make auditcommand runs a containerised security scanner that performs behavioural and static analysis (via YARA) on all skills to detect malicious patterns, prompt injections, or unauthorised data exfiltration risks. - Docker Socket Isolation: Docker-based workflows that require host Docker daemon control are explicitly protected by the
ALLOW_DOCKER_SOCKopt-in mechanism. - Immutability: When mounting skills, existing paths are backed up rather than overwritten, ensuring you never lose local configurations.
make auditDefault profile:
--severity low --use-behavioral --yara-mode strict --fail-on-findingsOptional overrides:
make audit \
ROOT_PATH=/absolute/path/to/repo \
SKILL_SCANNER_PATH=.agents/skills \
SKILL_SCANNER_ARGS='--severity critical' \
COLOR=autodocker/compose.turbo.yml and docker/compose.tests.yml mount /var/run/docker.sock, which gives containers host Docker daemon control.
- Treat these workflows as host-root equivalent.
- Use only in trusted local/CI environments.
- Explicitly opt in with
ALLOW_DOCKER_SOCK=true.
ALLOW_DOCKER_SOCK=true make turbo-build
ALLOW_DOCKER_SOCK=true make turbo-test
ALLOW_DOCKER_SOCK=true make testCopy the example file and edit for your local environment:
cp .env.example .env
.envcan include secrets locally; never commit your real.env.
| Variable | Default | Description |
|---|---|---|
SOURCE |
vercel-labs/agent-skills |
Source repository for skills |
SKILLS |
* |
Comma-separated skill names or * |
DISABLE_TELEMETRY |
1 |
Disable skills.sh telemetry |
MANAGE_CLAUDE_LINK |
1 |
Manage .claude symlink |
SKILLS_RUNNER_IMAGE |
ghcr.io/gocanto/skills-runner:latest |
Docker image for skill installation |
TARGET_PROJECT |
— | Absolute path for mount-skills |
SKILLS_ROOT |
— | Absolute skills repository root |
AGENTS_DIR |
— | Absolute .agents directory path |
SKILL_SCANNER_PATH |
.agents/skills |
Path to scan for security audit |
SKILL_SCANNER_ARGS |
--severity low --use-behavioral --yara-mode strict --fail-on-findings |
Scanner arguments |
COLOR |
always |
Output color mode |
TEST_TIMEOUT |
20m |
Test execution timeout |
COVERAGE_MIN |
80 |
Minimum coverage threshold |
COVERAGE_DIR |
.cache/coverage |
Coverage output directory |
USE_DOCKER |
true |
Run tests inside Docker (false in CI) |
ALLOW_DOCKER_SOCK |
false |
Opt-in for docker.sock mounted workflows |
Go commands support Docker-style file inputs via *_FILE variables. The *_FILE variant takes precedence over the direct value.
SKILLS_ROOT_FILE=/run/secrets/skills_root
AGENTS_DIR_FILE=/run/secrets/agents_dir
SKILLS_RUNNER_IMAGE_FILE=/run/secrets/skills_runner_image
SKILL_SCANNER_ARGS_FILE=/run/secrets/skill_scanner_argsAll _FILE variants available: SOURCE_FILE, SKILLS_FILE, DISABLE_TELEMETRY_FILE, MANAGE_CLAUDE_LINK_FILE, SKILLS_RUNNER_IMAGE_FILE, SKILLS_ROOT_FILE, AGENTS_DIR_FILE, SKILL_SCANNER_PATH_FILE, SKILL_SCANNER_ARGS_FILE.
.
├── .agents/skills/ # Installed agent skills
├── .github/workflows/ # CI/CD pipelines
├── docker/ # Dockerfiles and Compose configs
│ ├── Dockerfile.binary # Standalone binary build
│ ├── Dockerfile.manager # Manager CLI image
│ ├── Dockerfile.skills # Skills runner image
│ ├── Dockerfile.tests # Test runner
│ ├── Dockerfile.tools # Development tools (goimports)
│ ├── Dockerfile.turbo # Turborepo runner
│ ├── compose.skills.yml # Skills workflows
│ ├── compose.tests.yml # Test execution
│ ├── compose.tools.yml # Formatting tools
│ └── compose.turbo.yml # Turbo-based tasks
├── manager/ # Go CLI source
│ └── cmd/skills/ # CLI entrypoint
├── scripts/ # Build and CI scripts
│ └── mk/ # Makefile includes
├── .env.example # Environment template
├── Makefile # Primary task runner
├── go.work # Go workspace (1.26)
└── turbo.json # Turborepo configuration
make build # outputs dist/skills# Format with gofmt
make format
# Format with gofmt + goimports via Docker (with -local skills)
make format imports
# Lint: gofmt check + go vet
make lintAll tests are Go-based and include Testcontainers-driven functional/e2e coverage. By default, tests run inside Docker using turbo run .... Set USE_DOCKER=false to run directly on your host.
# Run all tests (unit, functional, e2e) and check coverage
make test
# Individual test suites
make test-unit
make test-functional
make test-e2e
# Check coverage threshold (requires previous test runs)
make test-coverage
# Run all tests with host Go (bypassing Docker)
make test USE_DOCKER=falseTest configuration (from scripts/mk/tests.mk):
| Setting | Default | Description |
|---|---|---|
COVERAGE_MIN |
80 |
Minimum coverage percentage |
TEST_TIMEOUT |
20m |
Per-test timeout |
COVERAGE_DIR |
.cache/coverage |
Coverage output directory |
USE_DOCKER |
true |
Docker-based execution (auto false in CI) |
ALLOW_DOCKER_SOCK |
false |
Enable docker.sock for mounted runs |
Coverage outputs:
- Unit:
.cache/coverage/unit-*.out - Functional:
.cache/coverage/functional.out - E2E:
.cache/coverage/e2e.out
Tests workflow (tests.yml) — runs on pull requests:
- Lint (
make lint) - Unit tests (
make test-unit) - Functional tests (
make test-functional) - E2E tests (
make test-e2e) - Coverage gate (
make test-coverage) — merges all profiles and checks a threshold
Release workflow (release.yml) — runs on version tags (v*):
- Validates embedded
.agentsarchive - Builds and pushes manager image to GHCR (multi-arch:
linux/amd64,linux/arm64) - Builds and pushes runner image to GHCR (multi-arch)
- Builds and pushes standalone binary packages for
linux/amd64,linux/arm64,darwin/amd64,darwin/arm64
This project is licensed under the MIT Licence – see the LICENCE file for details.
Contributions are welcome! Please feel free to submit a Pull Request.
Thanks, Gus.