Create guided, multi-step workflows that walk users through complex tasks with variable collection, conditional logic, and automated script execution. Extends regular opencode commands.
Resources
15Install
npx skillscat add apiad/opencode-literate-commands Install via the SkillsCat registry.
Literate Commands Skill
Use this skill when you need to create guided, multi-step workflows that walk users through complex tasks with variable collection, conditional logic, and automated script execution.
When to Use Literate Commands
Use literate commands when you want to:
- Guide users through multi-step processes (setup wizards, onboarding flows)
- Collect structured data from users before executing commands
- Create reusable command templates with customizable parameters
- Build conditional workflows that branch based on user input
- Automate script execution with variable interpolation
Don't use them for: Simple one-off commands that just run a single script or tool.
Creating a Literate Command
- Create a markdown file in
.opencode/commands/ - Add
literate: truein the frontmatter - Define steps separated by
---
---
description: My guided workflow
literate: true
---
First step content...
---
Second step content...Step Configuration
Each step can have a YAML config block to control behavior:
step: unique-step-name
parse:
variable: type
next:
"condition": target-step
stop: trueConfig Options
| Option | Type | Description |
|---|---|---|
step |
string | Unique name for routing (use kebab-case) |
parse |
object | Variables to extract from user response |
next |
string | object |
stop |
boolean | End command after this step |
exec |
object | Script execution settings |
Step Examples
Collect data:
parse:
username: string
age: number
newsletter: boolRoute conditionally:
next:
"role === 'admin'": admin-panel
"confirmed": proceed
_: fallbackEnd command:
stop: trueVariable Collection (parse)
Ask the model to respond with JSON containing specific variables:
parse:
name: string
count: number
active: boolThe model will be prompted to respond with:
{"name": "...", "count": 0, "active": true}Type Coercion
| Type | Description |
|---|---|
string |
Convert to text |
number |
Convert to numeric |
bool |
Convert to true/false |
Variable Substitution
Use $variable in your prompts to inject collected data:
| Syntax | Example | Result |
|---|---|---|
$name |
$name |
Alice |
$obj.prop |
$user.email |
alice@example.com |
$arr.0 |
$items.0 |
first item |
$$ |
$$ |
Full metadata JSON |
Example
Hello **$name**! You selected $count items.If name=Alice and count=42:
Hello **Alice**! You selected 42 items.Routing (next)
Control which step executes next based on variables:
Simple Redirect
next: other-stepConditional Routing
next:
"role === 'admin'": admin-panel
"role === 'user'": user-panel
_: default-panelThe _ key is the fallback when no condition matches.
Condition Syntax
Use JavaScript-style expressions:
"confirmed === true""count > 10""role !== 'guest'""name.includes('admin')"
Script Execution (exec)
Run scripts within steps. The agent sees the result, or you can store variables.
Basic Execution
echo "Hello $name"Store Output as Variables
import json
print(json.dumps({"result": len("$name")}))Exec Modes
| Mode | Description |
|---|---|
stdout |
Show output to user (default) |
store |
Parse JSON output and store as variables |
none |
Execute silently (no output) |
Interpreters
Specify the interpreter explicitly if its not the default:
print("Python!")echo "Bash!"console.log("Node!");Complete Example
---
description: Project setup wizard
literate: true
---
```yaml {config}
step: project-name
parse:
name: string
type: string
```
What would you like to name your project, and what type is it?
---
```yaml {config}
step: confirm
next:
"confirmed === true": create
_: cancel
```
Ready to create **$name** ($type)? Type `true` or `false`.
---
```yaml {config}
step: create
parse:
confirmed: bool
```
Let me set that up for you:
```bash {exec mode=store}
mkdir -p "$name"
echo '{"created": true, "path": "'$name'"}'
```
---
```yaml {config}
step: success
stop: true
```
✓ Project **$name** created successfully!
---
```yaml {config}
step: cancel
stop: true
```Project creation cancelled. Let me know if you need anything else!
Tips
- Keep steps focused - One clear action per step
- Use meaningful step names - Makes routing easier to debug
- Validate early - Collect and validate data before expensive operations
- Store, don't echo - Use
mode=storefor script results you want to keep - Test routing - Use
stop: trueon branches to verify they work
Testing Your Command
opencode run --print-logs --log-level DEBUG --command your-command-nameThe command will run through steps sequentially. Check logs for:
- Step parsing
- Variable substitution
- Routing decisions
- Script execution