|
|
2 months ago | |
|---|---|---|
| .. | ||
| docs | 3 months ago | |
| examples | 3 months ago | |
| src | 3 months ago | |
| tests | 3 months ago | |
| ARCHITECTURE.md | 3 months ago | |
| MINIMAL_TEST.md | 3 months ago | |
| QUICK_REFERENCE.md | 3 months ago | |
| README.md | 2 months ago | |
| SIMPLIFICATION_SUMMARY.md | 3 months ago | |
| bun.lock | 3 months ago | |
| package.json | 2 months ago | |
| test-minimal.ts | 3 months ago | |
| test-plugin.ts | 2 months ago | |
| test-run-ability.ts | 3 months ago | |
| tsconfig.json | 3 months ago | |
Enforced, validated workflows for OpenCode agents.
Abilities solve the fundamental problem with Skills: LLMs ignore them. With Abilities:
Add to your opencode.json:
{
"plugin": [
"file://./packages/plugin-abilities/src/opencode-plugin.ts"
],
"abilities": {
"enabled": true,
"auto_trigger": true,
"enforcement": "strict"
}
}
bun add @openagents/plugin-abilities
# .opencode/abilities/deploy/ability.yaml
name: deploy
description: Deploy with safety checks
triggers:
keywords:
- "deploy"
- "ship it"
inputs:
version:
type: string
required: true
pattern: '^v\d+\.\d+\.\d+$'
steps:
- id: test
type: script
run: npm test
validation:
exit_code: 0
- id: build
type: script
run: npm run build
needs: [test]
- id: deploy
type: script
run: ./deploy.sh {{inputs.version}}
needs: [build]
/ability run deploy --version=v1.2.3
Or let it auto-detect from natural language:
User: "Deploy v1.2.3 to production"
→ Ability detected: deploy
Runs a shell command deterministically.
- id: test
type: script
run: npm test
cwd: ./packages/api
env:
NODE_ENV: test
validation:
exit_code: 0
stdout_contains: "passed"
timeout: 5m
on_failure: stop
Calls an OpenAgents Control agent.
- id: review
type: agent
agent: reviewer
prompt: "Review the code changes"
needs: [test]
Loads an existing skill.
- id: docs
type: skill
skill: generate-docs
Human approval gate.
- id: approve
type: approval
prompt: "Deploy to production?"
when: inputs.environment == "production"
Nested workflow (calls another ability).
- id: setup
type: workflow
workflow: setup-environment
inputs:
env: {{inputs.environment}}
inputs:
version:
type: string
required: true
pattern: '^v\d+\.\d+\.\d+$'
count:
type: number
min: 1
max: 100
default: 10
env:
type: string
enum: [dev, staging, prod]
Steps can depend on other steps:
steps:
- id: test
type: script
run: npm test
- id: build
needs: [test] # Runs after test completes
type: script
run: npm run build
- id: deploy
needs: [build] # Runs after build completes
type: script
run: ./deploy.sh
- id: deploy-prod
type: script
run: ./deploy.sh prod
when: inputs.environment == "production"
Abilities enforce execution order via hooks:
settings:
enforcement: strict
tool.execute.before - Blocks tools based on current step type:
chat.message - Injects ability context into every message:
session.idle - Prevents session exit while ability running:
These tools are never blocked (read-only/status):
ability.list, ability.status, ability.cancel,
todoread, read, glob, grep,
lsp_hover, lsp_diagnostics, lsp_document_symbols
Abilities can be attached to specific agents:
# Restrict to specific agents
compatible_agents:
- deploy-agent
- devops-agent
# Or exclusive to one agent
exclusive_agent: deploy-agent
---
name: deploy-agent
abilities:
- deploy/production
- deploy/staging
- rollback
---
Use the ability.agent tool:
ability.agent({ agent: "deploy-agent" })
→ Lists all abilities available to that agent
ability.list - List available abilitiesability.validate <name> - Validate an abilityability.run <name> [inputs] - Execute an abilityability.status - Get active execution statusimport { createAbilitiesSDK } from '@openagents/plugin-abilities/sdk'
// Create SDK instance
const sdk = createAbilitiesSDK({
projectDir: '.opencode/abilities',
includeGlobal: true
})
// List all abilities
const abilities = await sdk.list()
// => [{ name, description, source, triggers, inputCount, stepCount }]
// Get specific ability
const ability = await sdk.get('deploy')
// Validate
const { valid, errors } = await sdk.validate('deploy')
// Execute with inputs
const result = await sdk.execute('deploy', { version: 'v1.2.3' })
// => { id, status, ability, duration, steps, formatted }
// Check status
const status = await sdk.status()
// => { active, ability, currentStep, progress, status }
// Cancel active execution
await sdk.cancel()
// Wait for completion (async)
const final = await sdk.waitFor(result.id, 60000)
// Cleanup when done
sdk.cleanup()
import { loadAbilities, executeAbility, validateAbility } from '@openagents/plugin-abilities'
// Load all abilities
const abilities = await loadAbilities({
projectDir: '.opencode/abilities',
})
// Validate
const result = validateAbility(ability)
// Execute
const execution = await executeAbility(ability, inputs, context)
.opencode/
└── abilities/
├── deploy/
│ └── ability.yaml
├── test-suite/
│ └── ability.yaml
└── simple.yaml
cd packages/plugin-abilities
bun test
Test Results: 87 tests passing across 7 test files
executor.test.ts - Script execution, step ordering, validationvalidator.test.ts - Ability validation, input validationenforcement.test.ts - Hook enforcement, agent attachmentintegration.test.ts - Full lifecycle, ExecutionManager, error handlingtrigger.test.ts - Keyword/pattern matching, auto-detectionbun run build
bun test-plugin.ts
All phases complete! 87 tests passing.
MIT