-
Notifications
You must be signed in to change notification settings - Fork 916
Description
Prerequisites
- I have searched existing issues to avoid duplicates
- I am using the latest version of oh-my-opencode
- I have read the documentation
Bug Description
When a skill from ~/.config/opencode/skill/ is invoked as a slash command without arguments (e.g., /my-skill), the $ARGUMENTS placeholder in the skill template is never substituted. It remains as the literal string $ARGUMENTS, and the agent receives no actual user request, causing it to ignore the skill instructions entirely.
Why This Is a Problem
Broken user mental model:
- User creates a skill with clear instructions
- Skill appears in slash command autocomplete (suggesting it's usable)
- User types
/my-skilland presses Enter (natural, expected behavior) - Agent ignores the skill entirely and responds generically
Silent failure with no feedback:
- No error message indicating something went wrong
- Agent responds as if no command was invoked
- User has no way to know the skill content was ignored
- Debugging is nearly impossible without reading source code
Violates principle of least surprise:
- If skills weren't meant to be invoked without arguments, they shouldn't appear in autocomplete
- If they appear in autocomplete, invoking them should work
- Current behavior: looks like it works, silently does nothing
Steps to Reproduce
- Create a skill:
mkdir -p ~/.config/opencode/skill/test-skill
cat > ~/.config/opencode/skill/test-skill/SKILL.md << 'EOF'
---
name: test-skill
description: A test skill
---
# Test Skill
When invoked, respond with: "Hello! Test skill loaded successfully!"
If no user request is provided, introduce yourself.
EOF-
Start a fresh opencode session
-
Type
/test-skill(no arguments) and press Enter
Expected Behavior
Agent follows the skill instructions and responds with "Hello! Test skill loaded successfully!" or introduces itself.
Actual Behavior
Agent responds with generic fallback like "I'm ready to help. What would you like to work on?" - completely ignoring the skill content.
The agent receives this prompt (note the literal $ARGUMENTS):
# /test-skill Command
**Description**: (opencode - Skill) A test skill
**Scope**: skill
---
## Command Instructions
<skill-instruction>
Base directory for this skill: /Users/chili/.config/opencode/skill/test-skill/
File references (@path) in this skill are relative to this directory.
# Test Skill
When invoked, respond with: "Hello! Test skill loaded successfully!"
If no user request is provided, introduce yourself.
</skill-instruction>
<user-request>
$ARGUMENTS
</user-request>Observations:
**User Arguments**line is missing (becauseargsis empty)## User Requestsection is missing (becauseargsis empty)$ARGUMENTSremains as literal text - never substituted
Tested by running executeSlashCommand({ command: "test-skill", args: "" }) directly against the source.
Doctor Output
oMoMoMoMo... Doctor
Installation
────────────────────────────────────────
✓ OpenCode Installation → 1.1.8
✓ Plugin Registration → Registered (pinned: beta)
Configuration
────────────────────────────────────────
✓ Configuration Validity → Valid JSON config
Authentication
────────────────────────────────────────
✓ Anthropic (Claude) Auth → Auth plugin available
○ OpenAI (ChatGPT) Auth → Auth plugin not installed
○ Google (Gemini) Auth → Auth plugin not installed
Dependencies
────────────────────────────────────────
⚠ AST-Grep CLI → Not installed (optional)
⚠ AST-Grep NAPI → Not installed (optional)
⚠ Comment Checker → Not installed (optional)
Tools & Servers
────────────────────────────────────────
⚠ GitHub CLI → Not installed (optional)
⚠ LSP Servers → No LSP servers detected
✓ Built-in MCP Servers → 3 built-in servers enabled
○ User MCP Configuration → No user MCP configuration found
Updates
────────────────────────────────────────
✓ Version Status → Pinned to version beta
Summary
────────────────────────────────────────
6 passed, 0 failed, 5 warnings, 3 skippedError Logs
Configuration
Additional Context
Root Cause
In src/features/opencode-skill-loader/loader.ts (lines 83-92), skills are wrapped with a literal $ARGUMENTS:
lazyContent.content = `<skill-instruction>
Base directory for this skill: ${resolvedPath}/
File references (@path) in this skill are relative to this directory.
${body.trim()}
</skill-instruction>
<user-request>
$ARGUMENTS
</user-request>`In src/hooks/auto-slash-command/executor.ts (lines 158-172), formatCommandTemplate() never substitutes $ARGUMENTS:
let content = cmd.content || ""
if (!content && cmd.lazyContentLoader) {
content = await cmd.lazyContentLoader.load()
}
const commandDir = cmd.path ? dirname(cmd.path) : process.cwd()
const withFileRefs = await resolveFileReferencesInText(content, commandDir)
const resolvedContent = await resolveCommandsInText(withFileRefs)
sections.push(resolvedContent.trim())
if (args) {
sections.push("\n\n---\n")
sections.push("## User Request\n")
sections.push(args)
}When args is empty:
$ARGUMENTSremains as literal text- No "User Request" section is added
- Agent sees
<user-request>$ARGUMENTS</user-request>and has no actual request to act on
Suggested Fix
In formatCommandTemplate(), substitute $ARGUMENTS before pushing content:
const resolvedContent = await resolveCommandsInText(withFileRefs)
const withArgs = resolvedContent.replace(/\$ARGUMENTS/g, args || '')
sections.push(withArgs.trim())Operating System
macOS
OpenCode Version
1.1.8