/iblai-vibe-agent-skills
Add the agent Skills tab -- reusable playbooks a Base Agent can
discover and follow. An Agent Skill is a written instruction bundle
(plus optional reference files) for one job, like researching a topic
on the web or reviewing code. The agent reads a skill only when it's
relevant, so an agent can carry many capabilities without bloating
every conversation. The surface has two tabs — Agent Skills (the
agent's own set, with enable/disable toggles) and Available Skills
(the organization catalog, with one-click "Add to Agent") — plus New/Edit
skill dialogs (with a Resources file manager) and the chat /
skill picker that lets users invoke a skill from the composer.
Skills are managed independently of the Claw sandbox — no sandbox
instance is required. (They were previously documented as a section of
/iblai-vibe-agent-sandbox.)
Common setup (brand, conventions, env files, verification): see docs/skill-setup.md.
Prerequisites
- Auth must be set up first (
/iblai-vibe-auth)
- MCP server + skills configured (
@iblai/mcp in .mcp.json)
- Ask the user for a real
mentorId (agent UUID). Do NOT invent one.
- Agent Skills only apply to Base Agent agents (template slug
base-agent, or its legacy aliases ai-mentor / ai-agent). Use
isBaseAgentMentor() from @iblai/iblai-js/data-layer if you need
to gate the tab per agent type.
Step 1: Check Environment
Before proceeding, check for an iblai.env in the project root. Look for
PLATFORM, DOMAIN, and TOKEN variables. If the file does not exist or
is missing these variables, tell the user:
"You need an iblai.env with your platform configuration. Download the
template and fill in your values:
curl -o iblai.env https://raw.githubusercontent.com/iblai/vibe/refs/heads/main/iblai.env"
Step 2: Mount AgentSkills
AgentSkills is an independent component — it does not read from
AgentSettingsProvider. It takes platformKey and mentorUniqueId
as required props and manages everything else (fetching, dialogs,
pagination, toasts) internally.
// app/(app)/agents/[mentorId]/skills/page.tsx
"use client";
import { useEffect, useState } from "react";
import { useParams } from "next/navigation";
import { AgentSkills } from "@iblai/iblai-js/web-containers";
export default function AgentSkillsPage() {
const { mentorId } = useParams<{ mentorId: string }>();
const [platformKey, setPlatformKey] = useState("");
useEffect(() => {
try {
const resolvedTenant =
localStorage.getItem("app_tenant") ??
(() => {
try {
return JSON.parse(localStorage.getItem("current_tenant") ?? "{}").key;
} catch { return undefined; }
})() ??
localStorage.getItem("tenant") ??
"";
setPlatformKey(resolvedTenant);
} catch {}
}, []);
if (!platformKey) return null;
return (
<div className="flex h-full flex-col bg-white p-6">
<AgentSkills platformKey={platformKey} mentorUniqueId={mentorId} />
</div>
);
}
Skills work without any sandbox connection — org-level skills and the
agent's assignments both resolve on their own, so the component always
renders its full UI.
Step 3: Enable the chat / skill picker
The chat composer ships a / skill combobox (see the last screenshot):
typing / as the first word opens a popup listing the agent's skills
(name + /slug, arrow keys + Enter/Tab to select, Esc to dismiss).
Selecting inserts /slug into the composer. It is off by default
— opt in with one prop on <Chat> (from /iblai-vibe-agent-chat):
import { Chat } from "@iblai/iblai-js/web-containers/next";
<Chat
// ...existing chat config...
slashSkillsEnabled
/>;
With slashSkillsEnabled, the composer lazily fetches the agent's
skills from the per-agent skills endpoint on the first / keystroke
(20 per page, loading more as the list scrolls; errors degrade to an
inactive picker). To supply the list yourself instead, pass
slashSkills (an EffectiveAgentSkill[]) and slashSkillsLoading
while resolving it — a host-supplied list bypasses fetching entirely.
The same three props exist on ChatInputForm for custom chat
surfaces.
For a fully custom composer, the pieces are exported individually:
useSlashSkills (lazy paged fetch), useSlashSkillPicker (open/close
- keyboard state machine),
SlashSkillPicker (the listbox popup), and
isSlashCommandToken (is the composer text a / token).
Step 4: Use MCP Tools for Customization
get_component_info("AgentSkills")
get_component_info("Chat")
Component Props
<AgentSkills> (from @iblai/iblai-js/web-containers)
| Prop |
Type |
Required |
Description |
platformKey |
string |
Yes |
Organization key (org slug) |
mentorUniqueId |
string |
Yes |
Agent UUID |
<Chat> / <ChatInputForm> slash-picker props
| Prop |
Type |
Required |
Description |
slashSkillsEnabled |
boolean |
No |
Turns the / picker on (default false). Fetches the agent's skills lazily |
slashSkills |
EffectiveAgentSkill[] |
No |
Host-supplied list — overrides the internal fetch |
slashSkillsLoading |
boolean |
No |
True while the host is still resolving slashSkills — the popup shows a loading row |
What the component renders
- Header note + New Skill — "Skills added or removed here apply to
new chat sessions only. Edits to a skill's instructions apply
immediately, including in conversations already in progress." plus
the gradient New Skill button.
Agent Skills tab
The agent's effective set: its skill assignments plus its own
private skills, deduped by slug and paged 10 per row-page.
- Rows — name, version, badges (category, Native, Featured,
Private), description, enable/disable Switch, kebab menu.
- Toggle — for an assigned skill, PATCHes the assignment's
enabled; for a private skill, PATCHes the skill itself.
- Kebab menu — Remove from Agent (deletes the assignment;
only for assigned skills), Edit, Delete (edit/delete only
for skills the organization owns — featured skills from the
main
platform are read-only).
Available Skills tab
The organization's full skill catalog, paged server-side 10 at a time.
- Rows — same name/version/badges/description block.
- Add to Agent — creates a
MentorSkillAssignment (enabled) for
the agent. Rows already covered by the agent's set — attached, or
shadowed by a same-slug private skill — show a green Added chip
instead. Another agent's private skills are not attachable.
New / Edit Skill dialog
- Only This Agent toggle — "Private skills are available to this
agent only and take precedence over platform skills with the same
slug." Sets
mentor to the agent's UUID (null = platform-wide).
- Fields — Name, Slug (both required), Version (default
1.0.0),
Category (e.g. web, code, data), Description, and Instruction (a
RichTextEditor — the playbook the agent follows).
- The Edit dialog has General and Resources sub-tabs; files
can be attached after the skill is created.
Resources sub-tab (skill files)
Optional files the agent can use with the skill:
- Types —
reference and script are text files (filename +
content in a textarea); asset is a binary upload (multipart).
- Rows — filename + type chip + kebab (Download for assets,
Edit for text files, Delete with confirmation). Paged 20
per page.
Chat / skill picker
- Opens while the composer holds a single
/-prefixed word and at
least one enabled skill matches (name or slug, case-insensitive).
- ArrowUp/ArrowDown browse, Enter/Tab select (inserts
/slug ), Esc
dismisses until the token is cleared — plain text starting with /
is never blocked.
- Skills load lazily on the first
/ keystroke and page in as the
list scrolls; the popup shows spinner rows while loading.
Related Exports
From @iblai/iblai-js/web-containers:
AgentSkills — the Skills surface.
SlashSkillPicker, SlashSkillPickerProps — the / popup listbox.
useSlashSkillPicker, isSlashCommandToken — composer keyboard /
open-state machine.
useSlashSkills — lazy paged fetch of the agent's skills for the
picker.
From @iblai/iblai-js/data-layer:
useGetAgentSkillsQuery, useGetAgentSkillQuery,
useCreateAgentSkillMutation, useUpdateAgentSkillMutation,
useDeleteAgentSkillMutation — skill catalog CRUD.
useGetAgentSkillResourcesQuery,
useCreateAgentSkillResourceMutation,
useUpdateAgentSkillResourceMutation,
useUploadAgentSkillResourceAssetMutation,
useDeleteAgentSkillResourceMutation — skill file resources.
useGetMentorSkillAssignmentsQuery,
useGetMentorSkillAssignmentsInfiniteQuery (one growing cache entry
per agent — powers the / picker's lazy list),
useCreateMentorSkillAssignmentMutation,
useUpdateMentorSkillAssignmentMutation,
useDeleteMentorSkillAssignmentMutation — per-agent assignments.
resolveEffectiveAgentSkills — client-side join of catalog +
assignments into the agent's effective set (private >
organization > global/featured, deduped by slug).
filterSlashSkills — enabled-only name/slug filter used by the
picker.
isBaseAgentMentor, BASE_AGENT_TEMPLATE_SLUGS — Base Agent gate.
MENTOR_SKILL_ASSIGNMENTS_PAGE_SIZE — the picker's page size (20).
AgentSkill, AgentSkillResource, MentorSkillAssignment,
EffectiveAgentSkill — payload types.
Step 5: Verify
Run /iblai-vibe-ops-test before telling the user the work is ready:
pnpm build -- must pass with zero errors
pnpm test -- vitest must pass
- Start dev server and touch test:
pnpm dev &
npx playwright screenshot http://localhost:3000/agents/<id>/skills /tmp/agent-skills.png
Important Notes
- Redux store: Must include
mentorReducer and mentorMiddleware
initializeDataLayer(): 5 args (v1.2+)
@reduxjs/toolkit: Deduplicated via webpack aliases in next.config.ts
- Peer deps:
sonner and @iblai/iblai-web-mentor must be installed
(pnpm add sonner @iblai/iblai-web-mentor)
- Base Agent only: Agent Skills apply to Base Agent agents only.
Gate the tab with
isBaseAgentMentor({ mentorSlug, templateMentorSlug })
when your app hosts other agent types.
- Session behaviour: adding/removing a skill applies to new chat
sessions only; editing a skill's instructions applies immediately,
including to conversations already in progress. The component
surfaces this note in its header — keep it visible in custom UI.
- Skill UUID, not pk:
MentorSkillAssignment.skill is the skill's
unique_id, not the integer id. Custom UI joining skills to
assignments must key on skill.unique_id. (Skill resources key on
the integer skill.id instead.)
- Private-skill precedence: a skill created with Only This
Agent shadows platform skills with the same slug for that agent
(
resolveEffectiveAgentSkills ranks private > organization > featured).
- Featured skills are read-only: featured skills come from the
main platform; the API 404s organization writes against them, so the
component hides their Edit/Delete actions. Mirror that in custom UI.
- Enabled is an AND: an effective skill is enabled only when the
catalog skill AND its assignment are both enabled; the
/ picker
offers enabled skills only.
- Brand guidelines: BRAND.md
Agent Skills REST API
For custom UI beyond the component. All endpoints are prefixed with
${dmUrl}/api/ai-mentor/orgs/{org}/ where dmUrl is
NEXT_PUBLIC_API_BASE_URL. Auth: Authorization: Token <token>.
Skill catalog (platform-level)
| Method |
Path |
Purpose |
| GET |
agent-skills/ |
List skills — filters: enabled, search (name/slug), limit, offset |
| POST |
agent-skills/ |
Create — { name, slug, version, category, description, instruction, mentor, enabled } |
| GET |
agent-skills/{id}/ |
Retrieve |
| PATCH |
agent-skills/{id}/ |
Update |
| DELETE |
agent-skills/{id}/ |
Delete |
mentor (agent UUID) makes the skill private to that agent; null
makes it platform-wide. Featured skills (is_featured) are served
read-only to organizations.
Skill resources (files)
| Method |
Path |
Purpose |
| GET |
agent-skill-resources/ |
List — filters: skill (integer pk), file_type, limit, offset |
| POST |
agent-skill-resources/ |
Create — { skill, file_type, filename, content } for text; multipart with file for asset |
| PATCH |
agent-skill-resources/{id}/ |
Update filename/content |
| DELETE |
agent-skill-resources/{id}/ |
Delete |
file_type is reference, script (text — send content), or
asset (binary — send multipart file; the response carries a
download URL in file).
Per-agent assignments
| Method |
Path |
Purpose |
| GET |
agents/{mentor_unique_id}/skills/ |
Skills bound to this agent |
| POST |
agents/{mentor_unique_id}/skills/ |
Bind — { "skill": "<skill-uuid>", "enabled": true } |
| PATCH |
agents/{mentor_unique_id}/skills/{id}/ |
Toggle enabled |
| DELETE |
agents/{mentor_unique_id}/skills/{id}/ |
Unbind |
Uses the canonical agents/ spelling — the mentors/ route is a
deprecated alias slated for removal. The skill field is the UUID
(unique_id), not the integer primary key — keying assignments by
unique_id keeps the binding stable across skill edits.
1---2name: iblai-vibe-agent-skills3description: Add the agent Skills tab (reusable Agent Skills catalog with per-agent assignment, private skills, file resources, and the chat `/` skill picker) to your Next.js app4---56# /iblai-vibe-agent-skills78Add the agent **Skills tab** -- reusable playbooks a Base Agent can9discover and follow. An Agent Skill is a written instruction bundle10(plus optional reference files) for one job, like researching a topic11on the web or reviewing code. The agent reads a skill only when it's12relevant, so an agent can carry many capabilities without bloating13every conversation. The surface has two tabs — **Agent Skills** (the14agent's own set, with enable/disable toggles) and **Available Skills**15(the organization catalog, with one-click "Add to Agent") — plus New/Edit16skill dialogs (with a **Resources** file manager) and the chat **`/`17skill picker** that lets users invoke a skill from the composer.1819Skills are managed independently of the Claw sandbox — no sandbox20instance is required. (They were previously documented as a section of21`/iblai-vibe-agent-sandbox`.)222324252627282930313233343536373839> **Common setup (brand, conventions, env files, verification):** see [docs/skill-setup.md](https://raw.githubusercontent.com/iblai/vibe/refs/heads/main/docs/skill-setup.md).4041## Prerequisites4243- Auth must be set up first (`/iblai-vibe-auth`)44- MCP server + skills configured (`@iblai/mcp` in `.mcp.json`)45- Ask the user for a real `mentorId` (agent UUID). Do NOT invent one.46- Agent Skills only apply to **Base Agent** agents (template slug47 `base-agent`, or its legacy aliases `ai-mentor` / `ai-agent`). Use48 `isBaseAgentMentor()` from `@iblai/iblai-js/data-layer` if you need49 to gate the tab per agent type.5051## Step 1: Check Environment5253Before proceeding, check for an `iblai.env` in the project root. Look for54`PLATFORM`, `DOMAIN`, and `TOKEN` variables. If the file does not exist or55is missing these variables, tell the user:56"You need an `iblai.env` with your platform configuration. Download the57template and fill in your values:58`curl -o iblai.env https://raw.githubusercontent.com/iblai/vibe/refs/heads/main/iblai.env`"5960## Step 2: Mount `AgentSkills`6162`AgentSkills` is an independent component — it does not read from63`AgentSettingsProvider`. It takes `platformKey` and `mentorUniqueId`64as required props and manages everything else (fetching, dialogs,65pagination, toasts) internally.6667```tsx68// app/(app)/agents/[mentorId]/skills/page.tsx69"use client";7071import { useEffect, useState } from "react";72import { useParams } from "next/navigation";73import { AgentSkills } from "@iblai/iblai-js/web-containers";7475export default function AgentSkillsPage() {76 const { mentorId } = useParams<{ mentorId: string }>();77 const [platformKey, setPlatformKey] = useState("");7879 useEffect(() => {80 try {81 const resolvedTenant =82 localStorage.getItem("app_tenant") ??83 (() => {84 try {85 return JSON.parse(localStorage.getItem("current_tenant") ?? "{}").key;86 } catch { return undefined; }87 })() ??88 localStorage.getItem("tenant") ??89 "";90 setPlatformKey(resolvedTenant);91 } catch {}92 }, []);9394 if (!platformKey) return null;9596 return (97 <div className="flex h-full flex-col bg-white p-6">98 <AgentSkills platformKey={platformKey} mentorUniqueId={mentorId} />99 </div>100 );101}102```103104Skills work without any sandbox connection — org-level skills and the105agent's assignments both resolve on their own, so the component always106renders its full UI.107108## Step 3: Enable the chat `/` skill picker109110The chat composer ships a `/` skill combobox (see the last screenshot):111typing `/` as the first word opens a popup listing the agent's skills112(name + `/slug`, arrow keys + Enter/Tab to select, Esc to dismiss).113Selecting inserts `/slug ` into the composer. It is **off by default**114— opt in with one prop on `<Chat>` (from `/iblai-vibe-agent-chat`):115116```tsx117import { Chat } from "@iblai/iblai-js/web-containers/next";118119<Chat120 // ...existing chat config...121 slashSkillsEnabled122/>;123```124125With `slashSkillsEnabled`, the composer lazily fetches the agent's126skills from the per-agent skills endpoint on the first `/` keystroke127(20 per page, loading more as the list scrolls; errors degrade to an128inactive picker). To supply the list yourself instead, pass129`slashSkills` (an `EffectiveAgentSkill[]`) and `slashSkillsLoading`130while resolving it — a host-supplied list bypasses fetching entirely.131The same three props exist on `ChatInputForm` for custom chat132surfaces.133134For a fully custom composer, the pieces are exported individually:135`useSlashSkills` (lazy paged fetch), `useSlashSkillPicker` (open/close136+ keyboard state machine), `SlashSkillPicker` (the listbox popup), and137`isSlashCommandToken` (is the composer text a `/` token).138139## Step 4: Use MCP Tools for Customization140141```142get_component_info("AgentSkills")143get_component_info("Chat")144```145146## Component Props147148### `<AgentSkills>` (from `@iblai/iblai-js/web-containers`)149150| Prop | Type | Required | Description |151|------|------|----------|-------------|152| `platformKey` | `string` | Yes | Organization key (org slug) |153| `mentorUniqueId` | `string` | Yes | Agent UUID |154155### `<Chat>` / `<ChatInputForm>` slash-picker props156157| Prop | Type | Required | Description |158|------|------|----------|-------------|159| `slashSkillsEnabled` | `boolean` | No | Turns the `/` picker on (default `false`). Fetches the agent's skills lazily |160| `slashSkills` | `EffectiveAgentSkill[]` | No | Host-supplied list — overrides the internal fetch |161| `slashSkillsLoading` | `boolean` | No | True while the host is still resolving `slashSkills` — the popup shows a loading row |162163## What the component renders164165- **Header note + New Skill** — "Skills added or removed here apply to166 new chat sessions only. Edits to a skill's instructions apply167 immediately, including in conversations already in progress." plus168 the gradient **New Skill** button.169170### Agent Skills tab171172The agent's *effective* set: its skill assignments plus its own173private skills, deduped by slug and paged 10 per row-page.174175- **Rows** — name, version, badges (category, Native, Featured,176 Private), description, enable/disable **Switch**, kebab menu.177- **Toggle** — for an assigned skill, PATCHes the assignment's178 `enabled`; for a private skill, PATCHes the skill itself.179- **Kebab menu** — **Remove from Agent** (deletes the assignment;180 only for assigned skills), **Edit**, **Delete** (edit/delete only181 for skills the organization owns — featured skills from the `main`182 platform are read-only).183184### Available Skills tab185186The organization's full skill catalog, paged server-side 10 at a time.187188- **Rows** — same name/version/badges/description block.189- **Add to Agent** — creates a `MentorSkillAssignment` (enabled) for190 the agent. Rows already covered by the agent's set — attached, or191 shadowed by a same-slug private skill — show a green **Added** chip192 instead. Another agent's private skills are not attachable.193194### New / Edit Skill dialog195196- **Only This Agent** toggle — "Private skills are available to this197 agent only and take precedence over platform skills with the same198 slug." Sets `mentor` to the agent's UUID (null = platform-wide).199- **Fields** — Name, Slug (both required), Version (default `1.0.0`),200 Category (e.g. web, code, data), Description, and Instruction (a201 `RichTextEditor` — the playbook the agent follows).202- The Edit dialog has **General** and **Resources** sub-tabs; files203 can be attached after the skill is created.204205### Resources sub-tab (skill files)206207Optional files the agent can use with the skill:208209- **Types** — `reference` and `script` are text files (filename +210 content in a textarea); `asset` is a binary upload (multipart).211- **Rows** — filename + type chip + kebab (**Download** for assets,212 **Edit** for text files, **Delete** with confirmation). Paged 20213 per page.214215### Chat `/` skill picker216217- Opens while the composer holds a single `/`-prefixed word and at218 least one **enabled** skill matches (name or slug, case-insensitive).219- ArrowUp/ArrowDown browse, Enter/Tab select (inserts `/slug `), Esc220 dismisses until the token is cleared — plain text starting with `/`221 is never blocked.222- Skills load lazily on the first `/` keystroke and page in as the223 list scrolls; the popup shows spinner rows while loading.224225## Related Exports226227From `@iblai/iblai-js/web-containers`:228229- `AgentSkills` — the Skills surface.230- `SlashSkillPicker`, `SlashSkillPickerProps` — the `/` popup listbox.231- `useSlashSkillPicker`, `isSlashCommandToken` — composer keyboard /232 open-state machine.233- `useSlashSkills` — lazy paged fetch of the agent's skills for the234 picker.235236From `@iblai/iblai-js/data-layer`:237238- `useGetAgentSkillsQuery`, `useGetAgentSkillQuery`,239 `useCreateAgentSkillMutation`, `useUpdateAgentSkillMutation`,240 `useDeleteAgentSkillMutation` — skill catalog CRUD.241- `useGetAgentSkillResourcesQuery`,242 `useCreateAgentSkillResourceMutation`,243 `useUpdateAgentSkillResourceMutation`,244 `useUploadAgentSkillResourceAssetMutation`,245 `useDeleteAgentSkillResourceMutation` — skill file resources.246- `useGetMentorSkillAssignmentsQuery`,247 `useGetMentorSkillAssignmentsInfiniteQuery` (one growing cache entry248 per agent — powers the `/` picker's lazy list),249 `useCreateMentorSkillAssignmentMutation`,250 `useUpdateMentorSkillAssignmentMutation`,251 `useDeleteMentorSkillAssignmentMutation` — per-agent assignments.252- `resolveEffectiveAgentSkills` — client-side join of catalog +253 assignments into the agent's effective set (private >254 organization > global/featured, deduped by slug).255- `filterSlashSkills` — enabled-only name/slug filter used by the256 picker.257- `isBaseAgentMentor`, `BASE_AGENT_TEMPLATE_SLUGS` — Base Agent gate.258- `MENTOR_SKILL_ASSIGNMENTS_PAGE_SIZE` — the picker's page size (20).259- `AgentSkill`, `AgentSkillResource`, `MentorSkillAssignment`,260 `EffectiveAgentSkill` — payload types.261262## Step 5: Verify263264Run `/iblai-vibe-ops-test` before telling the user the work is ready:2652661. `pnpm build` -- must pass with zero errors2672. `pnpm test` -- vitest must pass2683. Start dev server and touch test:269 ```bash270 pnpm dev &271 npx playwright screenshot http://localhost:3000/agents/<id>/skills /tmp/agent-skills.png272 ```273274## Important Notes275276- **Redux store**: Must include `mentorReducer` and `mentorMiddleware`277- **`initializeDataLayer()`**: 5 args (v1.2+)278- **`@reduxjs/toolkit`**: Deduplicated via webpack aliases in `next.config.ts`279- **Peer deps**: `sonner` and `@iblai/iblai-web-mentor` must be installed280 (`pnpm add sonner @iblai/iblai-web-mentor`)281- **Base Agent only**: Agent Skills apply to Base Agent agents only.282 Gate the tab with `isBaseAgentMentor({ mentorSlug, templateMentorSlug })`283 when your app hosts other agent types.284- **Session behaviour**: adding/removing a skill applies to **new chat285 sessions only**; editing a skill's instructions applies immediately,286 including to conversations already in progress. The component287 surfaces this note in its header — keep it visible in custom UI.288- **Skill UUID, not pk**: `MentorSkillAssignment.skill` is the skill's289 `unique_id`, not the integer id. Custom UI joining skills to290 assignments must key on `skill.unique_id`. (Skill *resources* key on291 the integer `skill.id` instead.)292- **Private-skill precedence**: a skill created with **Only This293 Agent** shadows platform skills with the same slug for that agent294 (`resolveEffectiveAgentSkills` ranks private > organization > featured).295- **Featured skills are read-only**: featured skills come from the296 `main` platform; the API 404s organization writes against them, so the297 component hides their Edit/Delete actions. Mirror that in custom UI.298- **Enabled is an AND**: an effective skill is enabled only when the299 catalog skill AND its assignment are both enabled; the `/` picker300 offers enabled skills only.301- **Brand guidelines**: [BRAND.md](https://raw.githubusercontent.com/iblai/vibe/refs/heads/main/BRAND.md)302303## Agent Skills REST API304305For custom UI beyond the component. All endpoints are prefixed with306`${dmUrl}/api/ai-mentor/orgs/{org}/` where `dmUrl` is307`NEXT_PUBLIC_API_BASE_URL`. Auth: `Authorization: Token <token>`.308309### Skill catalog (platform-level)310311| Method | Path | Purpose |312|---|---|---|313| GET | `agent-skills/` | List skills — filters: `enabled`, `search` (name/slug), `limit`, `offset` |314| POST | `agent-skills/` | Create — `{ name, slug, version, category, description, instruction, mentor, enabled }` |315| GET | `agent-skills/{id}/` | Retrieve |316| PATCH | `agent-skills/{id}/` | Update |317| DELETE | `agent-skills/{id}/` | Delete |318319`mentor` (agent UUID) makes the skill private to that agent; `null`320makes it platform-wide. Featured skills (`is_featured`) are served321read-only to organizations.322323### Skill resources (files)324325| Method | Path | Purpose |326|---|---|---|327| GET | `agent-skill-resources/` | List — filters: `skill` (integer pk), `file_type`, `limit`, `offset` |328| POST | `agent-skill-resources/` | Create — `{ skill, file_type, filename, content }` for text; multipart with `file` for `asset` |329| PATCH | `agent-skill-resources/{id}/` | Update filename/content |330| DELETE | `agent-skill-resources/{id}/` | Delete |331332`file_type` is `reference`, `script` (text — send `content`), or333`asset` (binary — send multipart `file`; the response carries a334download URL in `file`).335336### Per-agent assignments337338| Method | Path | Purpose |339|---|---|---|340| GET | `agents/{mentor_unique_id}/skills/` | Skills bound to this agent |341| POST | `agents/{mentor_unique_id}/skills/` | Bind — `{ "skill": "<skill-uuid>", "enabled": true }` |342| PATCH | `agents/{mentor_unique_id}/skills/{id}/` | Toggle `enabled` |343| DELETE | `agents/{mentor_unique_id}/skills/{id}/` | Unbind |344345Uses the canonical `agents/` spelling — the `mentors/` route is a346deprecated alias slated for removal. The `skill` field is the **UUID**347(`unique_id`), not the integer primary key — keying assignments by348`unique_id` keeps the binding stable across skill edits.