Goal
Add first-class support for Anthropic Agent Skills so a fork of this template can drop a SKILL.md-style folder (e.g. ~/.claude/skills/astrology-skill/) and have it uploaded, registered with the Managed Agent, and visible in the mobile UI.
Skills are filesystem-based bundles: a folder with a SKILL.md (YAML frontmatter name + description) at root plus optional scripts/resources. Anthropic loads frontmatter into the system prompt at startup; the agent reads the body and bundled files on-demand inside the code-execution sandbox.
Scope
Backend (Go)
internal/skills/ — client (wraps anthropic-sdk-go Beta.Skills), service, pgx store, Fiber handler.
cmd/skills-sync/ — CLI that walks SKILLS_SOURCES env (comma-separated paths), finds dirs with SKILL.md, uploads each via the service, and persists rows.
- Migration
00005_skills.sql — table skills(id uuid pk, anthropic_skill_id text unique, name text, description text, source text, version text, created_at, updated_at).
- Provisioner updates — both
cmd/provision/main.go and internal/agent/provision.go attach the code-execution tool + installed skill IDs alongside the existing toolset.
- REST:
GET/POST/DELETE /api/skills, POST /api/skills/sync.
Mobile
services/skills.ts — typed client.
app/(app)/skills.tsx — list installed skills, upload (zip/folder), delete, trigger sync.
- Link from Settings.
Dev workflow
make skills-sync Makefile target.
.env.example adds SKILLS_SOURCES=.
docs/SKILLS.md how-to.
Constraints
- Anthropic Skills API requires beta headers: `skills-2025-10-02`, `code-execution-2025-08-25`, `files-api-2025-04-14`.
- Workspace-scoped (one per Anthropic API key); no per-team isolation in MVP.
- API sandbox has no network and no `pip install` — skills must bundle wheels (the astrology skill already does this).
- Code must be lean and idiomatic. No tests in this PR per request.
User Stories
- As a template forker, I want to point `SKILLS_SOURCES` at a directory of skill folders and run `make skills-sync`, so that all my custom Skills are uploaded to Anthropic and attached to my agent without manual API calls.
- As an end-user of a deployed app, I want to see which Skills my agent has installed and remove ones I don't need from the Settings screen, so that I can curate my agent's capabilities.
- As an end-user, I want to upload a new Skill folder/zip from the UI, so that I can add capabilities without redeploying the backend.
- As a backend operator, I want skill IDs persisted in our DB, so that I don't round-trip Anthropic on every page load and so I can tell which skills the system knows about even if Anthropic is down.
Acceptance Criteria
Sync from filesystem
- Given `SKILLS_SOURCES=/path/to/dir` is set and that dir contains `astrology-skill/SKILL.md`, when I run `make skills-sync`, then `/api/skills` lists `astrology-skill` with the Anthropic skill ID populated and a row exists in the `skills` table.
- Given I re-run `make skills-sync`, when a skill with the same `name` already exists in our DB, then the existing row is updated with the new `latest_version` (no duplicate row).
- Given a folder lacks a `SKILL.md` at its root, when the sync walks it, then it is skipped with a logged warning and the rest of the run continues.
Upload via API
- Given an authenticated user, when they POST a multipart `folder.zip` to `/api/skills`, then the server unzips, validates `SKILL.md` exists at root, uploads to Anthropic, persists a row, and returns the new skill JSON.
- Given the upload is missing `SKILL.md`, then the server returns 400 with a clear error and does not call Anthropic.
Provisioner attaches skills
- Given at least one skill is in the DB, when a new agent session is created via `agent.Service.CreateSession`, then the Anthropic Agent is configured with the code-execution tool and references those skill IDs, and the agent can invoke the skill (verified manually by chatting).
Mobile UI
- Given I open Settings → Skills, when the screen loads, then I see a list of installed skills with name, description, source (`custom` or `anthropic`), and a delete button.
- Given I tap delete, when the request succeeds, then the skill is removed from Anthropic and our DB and disappears from the list.
Negative paths
- Given `ANTHROPIC_API_KEY` is empty, when `make skills-sync` runs, then the CLI exits with a clear error before attempting any uploads.
- Given an upload to Anthropic returns a 4xx, when persisting, then no DB row is written and the error is surfaced to the caller.
Out of scope (V2)
- Skills sourced from git URLs (only local paths in V1).
- Per-team or per-user skill isolation.
- Skill version pinning UI.
- Marketplace / registry browser.
- Tests (will land in a follow-up PR).
Goal
Add first-class support for Anthropic Agent Skills so a fork of this template can drop a
SKILL.md-style folder (e.g.~/.claude/skills/astrology-skill/) and have it uploaded, registered with the Managed Agent, and visible in the mobile UI.Skills are filesystem-based bundles: a folder with a
SKILL.md(YAML frontmattername+description) at root plus optional scripts/resources. Anthropic loads frontmatter into the system prompt at startup; the agent reads the body and bundled files on-demand inside the code-execution sandbox.Scope
Backend (Go)
internal/skills/— client (wrapsanthropic-sdk-goBeta.Skills), service, pgx store, Fiber handler.cmd/skills-sync/— CLI that walksSKILLS_SOURCESenv (comma-separated paths), finds dirs withSKILL.md, uploads each via the service, and persists rows.00005_skills.sql— tableskills(id uuid pk, anthropic_skill_id text unique, name text, description text, source text, version text, created_at, updated_at).cmd/provision/main.goandinternal/agent/provision.goattach the code-execution tool + installed skill IDs alongside the existing toolset.GET/POST/DELETE /api/skills,POST /api/skills/sync.Mobile
services/skills.ts— typed client.app/(app)/skills.tsx— list installed skills, upload (zip/folder), delete, trigger sync.Dev workflow
make skills-syncMakefile target..env.exampleaddsSKILLS_SOURCES=.docs/SKILLS.mdhow-to.Constraints
User Stories
Acceptance Criteria
Sync from filesystem
Upload via API
Provisioner attaches skills
Mobile UI
Negative paths
Out of scope (V2)