The Agentic Layer
Custom Commands & Skills
Commands are what humans type. Skills are what agents call. Together they make your agentic layer interactive and composable.
Commands vs skills
Commands
Human-invoked
A human types a command, and an agent executes it. Commands are the interface between your team and the agentic layer. Named, parameterized entry points.
/plan
/build
/commit
/security-audit
/explain
When to use: When a human wants to trigger a specific agent behavior on demand, outside the full workflow.
Skills
Agent-invoked
One agent calls another agent's capability programmatically. Skills let agents delegate sub-tasks. The calling agent gets structured output it can parse and act on.
run-tests
lint-check
dependency-check
generate-commit-message
When to use: When a workflow phase needs to delegate a sub-task to a specialized capability.
The key difference: commands output human-readable text because humans read the result. Skills output structured JSON because agents parse the result.
Anatomy of a command
Here is a complete /commit command. YAML frontmatter declares metadata; the prompt body follows the 4-section anatomy.
---
name: commit
description: Stage changes, generate a conventional commit message, and commit.
parameters:
- name: scope
type: string
required: false
description: "Conventional commit scope (e.g., auth, api, ui)"
tools:
- file_system.read
- file_system.search
- code_execution.shell
---
# /commit Command
## Role
You are a Release Engineer. Your job is to create a clean,
conventional commit from the current staged changes.
## Context
Current diff:
${git_diff_staged}
Recent commit history:
${recent_commits}
Scope (if provided): ${scope}
## Constraints
- Use Conventional Commits format: type(scope): description
- Types: feat, fix, refactor, test, docs, chore, perf, ci
- Subject line max 72 characters
- Body should explain WHY, not WHAT (the diff shows what)
- Do NOT amend previous commits
- Do NOT force push
- If no files are staged, tell the user and stop
## Output
1. Show the generated commit message to the user
2. Ask for confirmation (y/n)
3. If confirmed, execute: git commit -m "<message>"
4. Show the commit hash and summary
Anatomy of a skill
Skills declare a trigger and output_format instead of parameters. Their output is JSON, always structured, always parseable.
---
name: run-tests
description: Execute the test suite and return structured results.
trigger: called by build, test, or review phases
output_format: json
tools:
- code_execution.shell
- file_system.read
---
# run-tests Skill
## Role
You are a Test Runner. Execute the project's test suite and
return structured results that the calling agent can parse.
## Context
Test commands:
${test_commands}
Project type: ${project_type} # node | python | go | rust | java
## Constraints
- Run ALL test suites, not just unit tests
- Do NOT modify test files or source code
- Do NOT skip failing tests
- If a test command fails to execute (not test failure,
but command error), report it separately
- Timeout per test suite: 120 seconds
## Output Format
Return a JSON object:
{
"status": "pass | fail | error",
"suites": [
{
"name": "unit",
"command": "npm test",
"passed": 42,
"failed": 1,
"skipped": 0,
"duration_ms": 3200,
"failures": [
{
"test": "UserService.create should validate email",
"file": "src/services/__tests__/user.test.ts",
"line": 28,
"error": "Expected 'invalid' to throw ValidationError",
"type": "assertion"
}
]
}
],
"coverage": { "lines": 84.2, "branches": 71.5, "functions": 89.1 },
"total_passed": 42,
"total_failed": 1,
"total_skipped": 0
}
Example commands
---
name: security-audit
description: Scan the codebase for OWASP Top 10 vulnerabilities.
parameters:
- name: target
type: string
required: false
description: "Specific directory or file to audit (default: entire project)"
tools:
- file_system.read
- file_system.search
- code_execution.shell
---
# /security-audit Command
## Role
You are a Security Engineer specializing in application security.
Scan the codebase for vulnerabilities from the OWASP Top 10.
## Context
Project: ${project_name}
Target: ${target}
Language: ${primary_language}
### Codebase Summary
${codebase_summary}
## Constraints
- READ-ONLY. Do not modify any files.
- Focus on the OWASP Top 10 2021 categories:
1. Broken Access Control
2. Cryptographic Failures
3. Injection (SQL, NoSQL, OS command, LDAP)
4. Insecure Design
5. Security Misconfiguration
6. Vulnerable and Outdated Components
7. Identification and Authentication Failures
8. Software and Data Integrity Failures
9. Security Logging and Monitoring Failures
10. Server-Side Request Forgery (SSRF)
- Prioritize findings by severity: critical, high, medium, low
- Do NOT report false positives -- if unsure, mark as "needs review"
## Output Format
### Security Audit Report
**Overall Risk Level:** CRITICAL | HIGH | MEDIUM | LOW | CLEAN
| # | Category | Severity | File | Line | Finding | Remediation |
|---|----------|----------|------|------|---------|-------------|
### Summary
- Critical: (count)
- High: (count)
- Medium: (count)
- Low: (count)
- Needs Review: (count)
### Recommended Next Steps
(Prioritized list of remediations)
Example skills
---
name: lint-check
description: Run linter and categorize issues by severity.
trigger: called by build or review phases
output_format: json
tools:
- code_execution.shell
- file_system.read
---
# lint-check Skill
## Role
You are a Code Quality Analyst. Run the project's linter
and return categorized results.
## Context
Lint command: ${lint_command}
Project type: ${project_type}
Files changed: ${changed_files}
## Constraints
- Run the linter ONLY on changed files (if supported)
- Do NOT auto-fix issues -- report only
- Do NOT modify any files
- Categorize: error (must fix), warning (should fix), info (optional)
## Output Format
{
"status": "clean | warnings | errors",
"issues": [
{
"file": "src/services/user.ts",
"line": 15,
"column": 8,
"severity": "error",
"rule": "no-unused-vars",
"message": "'tempData' is defined but never used"
}
],
"summary": { "errors": 1, "warnings": 3, "info": 0 }
}
Composability: commands use skills
Commands and skills compose. A command invokes skills internally, chaining structured outputs.
The /build command's template can reference skills by name. When the build agent reaches the testing step, it invokes the run-tests skill, receives structured JSON back, and uses that data to decide whether to continue or report failures. The lint-check skill runs separately. The command orchestrates; the skills execute.
How to create your own
agentic-layer/
├── commands/
│ ├── commit.md
│ ├── security-audit.md
│ ├── explain.md
│ └── your-command.md # add here
├── skills/
│ ├── run-tests.md
│ ├── lint-check.md
│ ├── dependency-check.md
│ └── your-skill.md # add here
Choose command or skill
If a human triggers it, it is a command. If an agent triggers it, it is a skill.
Create the file
Markdown with YAML frontmatter. The filename becomes the invocation name.
Define the frontmatter
Name, description, parameters (commands) or trigger (skills), tool access, output format.
Write the prompt
Follow the 4-section anatomy: Role, Context, Constraints, Output Format.
Test it
Run against 2-3 representative inputs. Verify the output structure matches your spec.
Commit and share
The command/skill is now available to your entire team.
Naming conventions
- Commands: lowercase, hyphenated.
security-audit, notSecurityAudit. - Skills: lowercase, hyphenated.
run-tests, notrunTests. - Filenames: match invocation names.
security-audit.mdis invoked as/security-audit.