AgentWorks documentation
Skills System
Skills are reusable instruction sets that guide workflow agents on how to handle specific tasks. They provide domain expertise and methodology that agents can apply during step execution.
Overview
- Storage: Skills are stored in
workspace-docs/skills/.- Standard Skills: Imported skills are stored in
skills/<skill-name>/. - Custom Skills: Skills created via Skill Builder are stored in
skills/custom/<skill-name>/.
- Standard Skills: Imported skills are stored in
- Main File: Each skill must have a
SKILL.mdfile with YAML frontmatter. - Read-Only: Skills are read-only during workflow execution (but writable in Skill Builder mode).
- Selection: Skills can be selected at preset level or overridden per-step.
Skill Builder Mode
The Skill Builder is a specialized agent mode designed to help you create, test, and refine skills.
- Access: Select "Skill Builder" from the mode switcher or use
Ctrl+5. - Theme: Identified by the Emerald (Green) theme.
- Capabilities:
- Automatically creates skills in the
skills/custom/directory. - Can read all existing skills for reference.
- Restricted to writing only within
skills/custom/. - Optimized for creating API wrappers and automation scripts (Python/Bash).
- Automatically creates skills in the
Skill File Format
A valid skill folder must contain SKILL.md:
---
name: code-review
description: Performs a comprehensive code review
argument-hint: <file-path>
allowed-tools: ["execute_shell_command", "diff_patch_workspace_file"]
model: openrouter/anthropic/claude-sonnet-4
---
Review the code at `$ARGUMENTS` focusing on:
1. Code quality
2. Potential bugs
3. Security issues
Frontmatter Fields
| Field | Required | Description |
|---|---|---|
name |
Yes | Display name of the skill |
description |
Yes | Brief description of what the skill does |
argument-hint |
No | Hint for arguments the skill accepts |
allowed-tools |
No | List of tools the skill is allowed to use. For current workflow agents, prefer exposed tools such as execute_shell_command and diff_patch_workspace_file; legacy workspace-basic names like read_workspace_file, update_workspace_file, and delete_workspace_file are internal/API wrappers unless explicitly exposed by the session. |
model |
No | Preferred LLM model for this skill |
disable-model-invocation |
No | When true, the model is not offered this skill for automatic invocation |
user-invocable |
No | Whether the skill appears as user-invocable (e.g. as a slash command); auto-generated learnings skills set this to false |
effort |
No | Effort hint for the skill's execution |
context |
No | Context hint for skill matching |
agent |
No | Agent hint for skill routing |
Configuration Hierarchy
Skills follow a priority hierarchy:
PresetQuery.selected_skills (workflow-wide default)
└── Step.AgentConfigs.enabled_skills (per-step override)
- Preset Level: Default skills for all steps in the workflow
- Step Level: Override in
step_config.jsonfor specific steps
Example step_config.json
{
"steps": [
{
"id": "research-step",
"agent_configs": {
"selected_servers": ["playwright"],
"enabled_skills": ["lead-research-assistant"]
}
},
{
"id": "mcp-building-step",
"agent_configs": {
"selected_servers": ["github"],
"enabled_skills": ["mcp-builder"]
}
}
]
}
Backend Implementation
Package Structure
agent_go/pkg/skills/
├── types.go # Skill, SkillFrontmatter structs
├── parser.go # Parse YAML frontmatter + markdown
├── validator.go # Validate skill folder against spec
├── discovery.go # Discover skills from workspace-docs/skills/ (incl. custom/)
├── github.go # Download skill folders from GitHub URLs
├── workspace_api.go # Workspace file operations
├── runtime_loader.go # LoadAttachable / LoadGlobalSkill — build attachable skills for agents
├── builtin_browser_skills.go # Builtin agent-browser / playwright skills (served from code, never on disk)
├── cli.go # skills CLI integration (npx skills), lock-file update detection
└── zip.go # Zip import/export of skill folders
Key Types
type SkillFrontmatter struct {
Name string `yaml:"name,omitempty"`
Description string `yaml:"description"`
ArgumentHint string `yaml:"argument-hint,omitempty"`
AllowedTools []string `yaml:"allowed-tools,omitempty"`
Model string `yaml:"model,omitempty"`
DisableModelInvocation bool `yaml:"disable-model-invocation,omitempty"`
UserInvocable *bool `yaml:"user-invocable,omitempty"`
Effort string `yaml:"effort,omitempty"`
Context string `yaml:"context,omitempty"`
Agent string `yaml:"agent,omitempty"`
}
type Skill struct {
Frontmatter SkillFrontmatter `json:"frontmatter"`
Content string `json:"content"` // Markdown after frontmatter
FolderName string `json:"folder_name"` // Skill folder name
FilePath string `json:"file_path"` // Relative path in workspace
SourceURL string `json:"source_url,omitempty"` // Source URL (from lock file)
LockInfo *CLILockEntry `json:"lock_info,omitempty"` // Version tracking from skills-lock.json
}
API Endpoints
| Method | Endpoint | Description |
|---|---|---|
| GET | /api/skills |
List all skills in workspace-docs/skills/ |
| GET | /api/skills/{name} |
Get skill details and content |
| POST | /api/skills/import |
Import skill from GitHub folder URL |
| POST | /api/skills/validate |
Validate a GitHub URL before import |
| DELETE | /api/skills/{name} |
Delete a skill folder |
| PUT | /api/skills/{name} |
Update skill content |
Workflow Integration
Skills are integrated into workflow execution in skills_integration.go:
// Get effective skills for a step (step override > preset default)
func GetEffectiveSkills(stepConfig *AgentConfigs, orchestrator *BaseOrchestrator) []string
// Build folder guard paths (skills are read-only)
func BuildSkillFolderGuardPaths(selectedSkills []string) (readPaths, writePaths []string)
How Skills Reach the Agent
There is no hand-assembled "Active Skills" prompt section any more. Skill surfacing lives in the transport layer:
- Builders call
skills.LoadAttachable(workspaceAPIURL, selectedSkills)(pkg/skills/runtime_loader.go), which parses each SKILL.md into an attachable skill — full markdown body plusSupportingFiles(everything under the skill folder except SKILL.md, e.g.references/,scripts/). - Each skill is registered with
agent.AttachSkill(skill). The mcpagent library injects a progressive-disclosure skill listing into the outgoing system prompt atensureSystemPrompt()time; CLI transports additionally project the skill folder to disk via the SkillProjector contract. - Builtin skills:
agent-browserandplaywrightare served from code (builtin_browser_skills.go), not from the skills/ folder. The loader checks builtins first, so a disk folder with the same name would be silently shadowed — never create one. - Global learnings pointer:
LoadGlobalSkill()attaches a tiny "workflow-learnings" pointer skill that directs the agent to readlearnings/_global/from the workflow folder on demand, instead of copying the (large, growing) learnings bundle into every session.
Folder Guard
Skills folders are added to the read-only paths in the folder guard:
// In controller_agent_factory.go
effectiveSkills := GetEffectiveSkills(stepConfig, orchestrator)
if len(effectiveSkills) > 0 {
skillReadPaths, _ := BuildSkillFolderGuardPaths(effectiveSkills)
readPaths = append(readPaths, skillReadPaths...)
}
This ensures agents can read skill files but cannot modify them.
Frontend Implementation
Components
frontend/src/components/skills/
├── SkillsManager.tsx # Main panel (sidebar)
├── SkillsList.tsx # List of installed skills
├── SkillCard.tsx # Individual skill display
├── SkillImportDialog.tsx # Dialog to paste GitHub URL
├── SkillEditor.tsx # View/edit skill content
└── SkillSelectionSection.tsx # Multi-select for preset editor
API Client
// frontend/src/api/skills.ts
export const skillsApi = {
listSkills(): Promise<{ skills: Skill[] }>
getSkill(folderName: string): Promise<Skill>
importSkill(githubUrl: string): Promise<ImportSkillResponse>
validateSkill(githubUrl: string): Promise<ValidateSkillResponse>
deleteSkill(folderName: string): Promise<void>
updateSkill(folderName: string, content: string): Promise<Skill>
}
Preset Integration
Skills are stored in presets via selected_skills field:
interface CustomPreset {
// ... other fields
selectedSkills?: string[]; // Array of skill folder names
}
The SkillSelectionSection component allows selecting skills when creating/editing workflow presets.
GitHub Import
Skills can be imported from GitHub folder URLs:
- User provides URL like
https://github.com/user/repo/tree/main/skills/my-skill - Backend parses URL to extract owner, repo, branch, path
- Fetches folder contents via GitHub API
- Validates: checks for SKILL.md, parses frontmatter, validates required fields
- Downloads files to
workspace-docs/skills/{skill-name}/ - Returns success/error to frontend
Storage Structure
workspace-docs/
├── skills/
│ ├── code-review/ # Standard/Imported Skill
│ │ └── SKILL.md
│ ├── custom/ # User-created Skills
│ │ └── my-new-skill/
│ │ └── SKILL.md
│ └── lead-research-assistant/
│ ├── SKILL.md
│ └── templates/
│ └── research-template.md
└── ... other workspace files
Usage Flow
- Import Skills: Use Skills Manager to import from GitHub or create manually
- Create Preset: Select skills in the preset editor for workflow-wide defaults
- Configure Steps: Optionally override skills per-step in step_config.json
- Execution: Agent reads skill instructions and applies methodology to step