-
Notifications
You must be signed in to change notification settings - Fork 483
Description
Feature Proposal: ClaudeSkill Multiplatform Support
Description
Implement Claude Skills support across all multiplatform targets (mpp-ui, mpp-vscode, CLI) to enable users to use organized folders of instructions, scripts, and resources that agents can discover and load dynamically.
Motivation
Claude Skills are currently only implemented in mpp-idea (IntelliJ IDEA plugin). To provide a consistent experience across all platforms (CLI, VSCode, Desktop Compose, Web), we need to port this functionality to the multiplatform codebase.
Claude Skills allow users to:
- Create reusable prompt templates with YAML frontmatter
- Define variables that can be resolved at runtime
- Organize skills in project directories or user home (
~/.claude/skills/) - Execute skills via
/skill.<skillname>commands
Current Implementation Analysis (mpp-idea)
Key Components
-
ClaudeSkillCommand (
mpp-idea-core/.../ClaudeSkillCommand.kt)- Data class representing a loaded skill
- Properties:
skillName,description,template,skillPath,icon - Methods:
executeWithCompiler()- UsesSpecKitTemplateCompilerfor variable resolutiontoCustomCommand()- Converts to DevIns custom command
- Companion object methods:
all(project)- Load all skills from project root and user homeloadFromProjectRoot()- Scan project directories for SKILL.mdloadFromUserSkillsDir()- Scan~/.claude/skills/fromSkillName()/fromFullName()- Find specific skill
-
SkillFrontmatter (
mpp-idea-core/.../SpecKitFrontmatter.kt)- Parses YAML frontmatter from SKILL.md files
- Extracts:
name,description,variables,additionalFields
-
SpecKitTemplateCompiler (
mpp-idea-core/.../SpecKitTemplateCompiler.kt)- Compiles templates with Velocity engine
- Resolves variables from frontmatter
- Adds project-level variables
-
ClaudeSkillInsCommand (
devins-lang/.../ClaudeSkillInsCommand.kt)- DevIns command implementation for
/skill.<name> - Parses skill name from command prop
- Executes skill with compiler
- DevIns command implementation for
-
BuiltinCommand.CLAUDE_SKILL - Enum entry for the skill command
Proposed Solution
Phase 1: Core Implementation (mpp-core)
1.1 Create ClaudeSkillCommand in mpp-core
// mpp-core/src/commonMain/kotlin/cc/unitmesh/devins/command/ClaudeSkillCommand.kt
data class ClaudeSkillCommand(
val skillName: String,
val description: String,
val template: String,
val skillPath: String // Use String instead of Path for multiplatform
) {
val fullCommandName: String get() = "skill.$skillName"
companion object {
private const val SKILL_FILE = "SKILL.md"
private const val USER_SKILLS_DIR = ".claude/skills"
fun loadAll(fileSystem: ProjectFileSystem): List<ClaudeSkillCommand>
fun loadFromProjectRoot(fileSystem: ProjectFileSystem): List<ClaudeSkillCommand>
fun loadFromUserSkillsDir(fileSystem: ProjectFileSystem): List<ClaudeSkillCommand>
fun findBySkillName(skills: List<ClaudeSkillCommand>, name: String): ClaudeSkillCommand?
fun findByFullName(skills: List<ClaudeSkillCommand>, name: String): ClaudeSkillCommand?
}
}1.2 Extend SkillFrontmatter (already exists, may need updates)
The existing SkillFrontmatter parsing in mpp-core can be reused.
1.3 Update CommandProcessor
Add skill command handling to mpp-core/.../processor/CommandProcessor.kt:
private suspend fun processSkillCommand(
commandName: String,
arguments: String,
context: CompilerContext
): ProcessResult {
// Similar to processSpecKitCommand but for Claude Skills
}1.4 Platform-specific User Home Resolution
Add expect/actual for getting user home directory:
// commonMain
expect fun getUserHomeDirectory(): String?
// jvmMain
actual fun getUserHomeDirectory(): String? = System.getProperty("user.home")
// jsMain (Node.js)
actual fun getUserHomeDirectory(): String? = js("require('os').homedir()")
// wasmJsMain
actual fun getUserHomeDirectory(): String? = null // Not supported in browser
// iosMain
actual fun getUserHomeDirectory(): String? = NSHomeDirectory()Phase 2: CLI Support (mpp-ui TypeScript)
2.1 Add SkillCommandProcessor
// mpp-ui/src/jsMain/typescript/processors/SkillCommandProcessor.ts
export class SkillCommandProcessor implements InputProcessor {
name = 'SkillCommandProcessor';
canHandle(input: string): boolean {
return input.startsWith('/skill.');
}
async process(input: string, context: ProcessorContext): Promise<ProcessorResult> {
// Parse skill name and arguments
// Load skill from filesystem
// Compile template
// Return compiled result
}
}2.2 Register in InputRouter
Update mpp-ui/src/jsMain/typescript/ui/App.tsx to register the skill processor.
2.3 Add Skill Completion Support
Update completion providers to suggest available skills.
Phase 3: VSCode Support (mpp-vscode)
3.1 Update mpp-core.ts Bridge
// mpp-vscode/src/bridge/mpp-core.ts
export class SkillManager {
private skills: ClaudeSkillCommand[] = [];
async loadSkills(projectPath: string): Promise<void>;
getSkills(): ClaudeSkillCommand[];
findSkill(name: string): ClaudeSkillCommand | null;
async executeSkill(name: string, args: string): Promise<string>;
}3.2 Add Skill Command Handler
Update mpp-vscode/src/commands/ to handle /skill.* commands.
3.3 Add Skill Completion Provider
Provide IntelliSense for skill commands in the chat input.
Phase 4: Desktop Compose Support (mpp-ui Kotlin)
4.1 Integrate with Existing Command System
The Compose desktop app uses the same mpp-core, so it should work automatically once Phase 1 is complete.
4.2 Add UI for Skill Management (Optional)
Consider adding a skill browser/manager UI component.
Implementation Tasks
mpp-core
- Create
ClaudeSkillCommand.ktinmpp-core/src/commonMain/kotlin/cc/unitmesh/devins/command/ - Add
getUserHomeDirectory()expect/actual declarations - Update
CommandProcessor.ktto handle skill commands - Add skill command to completion providers
- Export skill-related classes for JS (
@JsExport) - Write unit tests for skill loading and execution
mpp-ui (CLI/TypeScript)
- Create
SkillCommandProcessor.ts - Register processor in
InputRouter - Add skill completion support
- Update CLI help to document skill commands
- Write integration tests
mpp-vscode
- Update
mpp-core.tswithSkillManagerclass - Add skill command handling in chat provider
- Add completion provider for skills
- Update webview to display skill execution results
- Write tests
Documentation
- Document skill file format (SKILL.md)
- Document skill locations (project root, ~/.claude/skills/)
- Add examples of skill usage
Technical Considerations
File System Abstraction
The existing ProjectFileSystem interface in mpp-core provides the necessary abstraction:
readFile(path)- Read SKILL.md contentlistFiles(path, pattern)- List skill directoriesexists(path)- Check if skill existsisDirectory(path)- Verify skill directory
Platform Differences
| Platform | User Home | Project Root | Notes |
|---|---|---|---|
| JVM (Desktop) | System.getProperty("user.home") |
From workspace | Full support |
| Node.js (CLI) | os.homedir() |
process.cwd() |
Full support |
| VSCode | os.homedir() |
Workspace folder | Full support |
| WASM (Browser) | N/A | Virtual FS | Limited - no user home |
| iOS | NSHomeDirectory() |
App sandbox | Limited |
| Android | Context-based | App storage | Limited |
Template Compilation
Reuse existing SpecKitTemplateCompiler in mpp-core which already handles:
- Frontmatter parsing
- Variable resolution
- Template compilation (simple string replacement, not Velocity in mpp-core)
Alternatives Considered
-
Keep skills IDEA-only: Rejected because it limits the usefulness of skills to only IntelliJ users.
-
Use a separate skills service: Rejected because it adds unnecessary complexity. The file-based approach is simpler and works offline.
-
Different skill format per platform: Rejected to maintain consistency. SKILL.md format works everywhere.
Additional Context
Related Files
mpp-idea/mpp-idea-core/src/main/kotlin/cc/unitmesh/devti/command/dataprovider/ClaudeSkillCommand.ktmpp-idea/mpp-idea-core/src/main/kotlin/cc/unitmesh/devti/command/dataprovider/SpecKitFrontmatter.ktmpp-idea/mpp-idea-core/src/main/kotlin/cc/unitmesh/devti/command/dataprovider/SpecKitTemplateCompiler.ktmpp-idea/mpp-idea-exts/devins-lang/src/main/kotlin/cc/unitmesh/devti/language/compiler/exec/claudeskill/ClaudeSkillInsCommand.ktmpp-core/src/commonMain/kotlin/cc/unitmesh/devins/command/SpecKitCommand.kt(similar pattern)mpp-core/src/commonMain/kotlin/cc/unitmesh/devins/filesystem/ProjectFileSystem.kt
Example SKILL.md Format
---
name: pdf
description: Handle PDF document operations
variables:
DOCUMENT_PATH: "path/to/document.pdf"
---
## Instructions
Process the PDF document at $DOCUMENT_PATH with the following requirements:
$ARGUMENTSExample Usage
/skill.pdf Extract all tables from the quarterly report
/skill.code-review Review the changes in src/main.ts