Node.js API
rolecraft exposes a programmatic API for use in your own Node.js scripts, tools, and CI pipelines. All API functions return plain objects with no side-effects.
Usage
import { install, list, search, doctor } from 'rolecraft'
// install a skill
const result = await install('./my-skill', { global: true })
// list installed skills
const skills = await list()
// search GitHub for skills
const results = await search('code-review')
// run health check
const health = await doctor()Available Functions
install(source, options?)
Install a skill with security scan.
| Option | Type | Default | Description |
|---|---|---|---|
global | boolean | false | Install to ~/.agents/skills/ |
project | boolean | true | Install to ./.agents/skills/ |
scope | object | { project: true } | Target scope object ({ project, global, [agentFlag]: true, ... }); overrides global/project |
yes | boolean | false | Bypass security prompts |
dryRun | boolean | false | Preview only |
symlink | boolean | false | Symlink instead of copy |
frozenLockfile | boolean | false | Fail if already installed |
noMcp | boolean | false | Skip MCP server installation |
skill | string|string[] | — | Specific skill slug(s) |
Returns { results: [{ name, slug, owner, security, install }], mcpResults?: [...] }.
rollback(slug, options?)
Restore a skill to its previous version from backup history. History is created automatically on update or re-install.
| Option | Type | Default | Description |
|---|---|---|---|
list | boolean | false | Show history without restoring |
dryRun | boolean | false | Preview without restoring |
Returns { slug, files, targets, prevContentSha }.
Or with list: true: { slug, currentVersion, history: [{ version, contentSha, installedAt }] }.
list(cwd?, options?)
List installed skills.
| Option | Type | Default | Description |
|---|---|---|---|
json | boolean | false | Return structured data |
agent | string | — | Filter skills by agent name (case-insensitive) |
Returns { skills: { [slug]: { name, slug, owner, description, source, sourceType, scope, installedAt, contentSha, ... } }, total: number, globals: number, projects: number, agent?: string }.
remove(slug, options?)
Uninstall a skill.
| Option | Type | Default | Description |
|---|---|---|---|
dryRun | boolean | false | Preview only |
Returns { removed: [...], targets: [...] }.
update(slug, options?)
Re-install a skill from its original source.
| Option | Type | Default | Description |
|---|---|---|---|
dryRun | boolean | false | Preview only |
Returns { slug, source, updated: boolean }.
check(options?)
Check installed skills for available updates.
Returns { skills: [{ slug, status: 'update_available'|'up_to_date'|'error', current?, latest?, source?, fromRegistry?, oldHash?, newHash?, hash?, reason? }], updatesAvailable: number, total: number }.
verify(options?)
Verify SHA256 content hashes of installed skills.
Returns { verified: [...], failed: [...] }.
ci(options?)
Re-install all skills and MCP servers from lockfile.
Takes no options. Non-interactive by design — installs everything from the lockfile.
Returns { installed: [{ slug, name, scope }], failed: [{ slug, reason }], skillCount, mcpCount, total, allPassed, mcpInstalled: [{ name, agents }], mcpFailed: [{ name, reason }] }.
search(query, options?)
Search for skills on GitHub or skills.sh.
| Option | Type | Default | Description |
|---|---|---|---|
skillsSh | boolean | false | Search skills.sh instead of GitHub |
interactive | boolean | false | Enable TUI picker |
Returns { results: [{ full_name, description, stargazers_count, language }], source: 'github'|'skills.sh' }.
doctor(options?)
Run system health check.
| Option | Type | Default | Description |
|---|---|---|---|
json | boolean | false | Return structured data |
network | boolean | false | Include GitHub connectivity test |
deep | boolean | false | Run conflict detection across all installed skills |
Returns { status, checks: [...], summary: { passed, warnings, errors, total }, agents, mcp, skills, conflicts }.
When deep: true, the conflicts array contains objects shaped as { a, b, sections: [{ heading, a, b }] } where a and b are conflicting skill slugs and each section lists up to 3 differing lines from each skill.
use(source, options?)
Preview a skill's files without installing.
Returns { name, slug, files: [...], targets: [...] }.
resolve(source)
Resolve a source string to its metadata. Returns { slug, name, files, contentSha, ... }.
resolveSkills(source)
Resolve a source string and discover all skills within it (including multi-skill repos). Used internally by install, use, and setup.
Returns [{ slug, name, description, owner, files, sourcePath, sourceType, content }].
diff(skillA, skillB, options?)
Section-aware comparison of two SKILL.md files.
| Option | Type | Default | Description |
|---|---|---|---|
json | boolean | false | Return structured JSON |
brief | boolean | false | Show only summary of changes |
noColor | boolean | false | Disable colored output |
Returns { a, b, frontmatter, sections: [{ heading, status, added, removed }], stats }.
compose(sources, options?)
Merge or chain multiple SKILL.md files into one.
| Option | Type | Default | Description |
|---|---|---|---|
mode | string | 'merge' | 'merge' (dedup lines) or 'chain' (override) |
name | string | — | Output skill name |
json | boolean | false | Return structured JSON |
noColor | boolean | false | Disable colored output |
Returns { content, stats: { sources, totalInputSections, totalOutputSections, mergedSections, frontmatterFields } }.
test(skillPath, options?)
Run quality assertions against a SKILL.md file.
| Option | Type | Default | Description |
|---|---|---|---|
all | boolean | false | Test all installed skills |
json | boolean | false | Return structured JSON |
verbose | boolean | false | Show detailed results |
noColor | boolean | false | Disable colored output |
noEmoji | boolean | false | Use ASCII fallback for emojis |
minScore | number | 0 | Fail if score is below threshold |
only | string|string[] | — | Run specific checks by name |
Returns { skill, score, grade, label, assertions: [...], suggestions: [...] }. With --all, returns { results: [...], summary: { total, passed, failed, skipped } }.
mcpInstall(source, options?)
Install an MCP server.
| Option | Type | Default | Description |
|---|---|---|---|
name | string | — | Override the server name |
yes | boolean | false | Skip confirmation and security blocks |
dryRun | boolean | false | Preview without making changes |
Returns { name, source, resolved: { command, args }, results: [{ agent, name, success }], scanResult }.
mcpList(options?)
List all installed MCP servers.
Returns { servers: [{ agent, name, command, args }], total: number }.
mcpUpdate(name, options?)
Update an MCP server.
| Option | Type | Default | Description |
|---|---|---|---|
name | string | — | Server name override |
yes | boolean | false | Skip confirmation |
dryRun | boolean | false | Preview without making changes |
Returns { name, source, resolved: { command, args }, results: [{ agent, name, success }] }.
mcpRemove(name, options?)
Remove an MCP server.
| Option | Type | Default | Description |
|---|---|---|---|
dryRun | boolean | false | Preview only |
Returns { name, results: [{ agent, name, success }] }.
mcpCheck(options?)
Check MCP server health.
Returns { servers: [{ agent, name, currentVersion, latestVersion, hasUpdate }], updatesAvailable: number, total: number }.
mcpSearch(query, options?)
Search for MCP servers on npm or GitHub.
| Option | Type | Default | Description |
|---|---|---|---|
npm | boolean | false | Search npm registry instead of GitHub |
interactive | boolean | false | Enable TUI picker |
Returns { results: [{ name, description, source, stars }], source: 'npm'|'github', total: number }.
profileSave(name, options?)
Save current agent configuration as a profile. Returns { name, agents: number, profile: { name, description, agents } }.
profileApply(name, options?)
Apply a saved profile.
| Option | Type | Default | Description |
|---|---|---|---|
dryRun | boolean | false | Preview only |
skipMcp | boolean | false | Skip MCP configuration |
skipSkills | boolean | false | Skip skill installation |
yes | boolean | false | Non-interactive mode |
Returns { agents: [...], mcp: [...], skills: [...] }.
profileDiff(name)
Compare current config against a saved profile. Returns { added: [...], removed: [...], changed: [...] }.
profileList()
List all saved profiles. Returns { profiles: [...] }.
profileShow(name)
Show profile details. Returns { name, agents: {...}, createdAt, updatedAt }.
profileDelete(name)
Delete a saved profile. Returns { deleted: true }.
profileImport(source)
Import a profile from file or URL. Returns { name, agents: number }.
setup(source, options?)
Detect agents and optionally install a skill to all detected agents.
| Option | Type | Default | Description |
|---|---|---|---|
yes | boolean | false | Install all skills without prompt |
dryRun | boolean | false | Preview only |
list | boolean | false | List available skills without installing |
skill | string|string[] | — | Install specific skills by name |
candidates | boolean | false | Return the resolved skills without selecting or installing |
Returns { agents: [{ flag, label }], installed?: [{ name, slug, owner, files, results, mcpServers }] }. With list: true, returns { agents, skills: [{ name, slug, owner, description, files }] }. With candidates: true, returns { agents, candidates: [{ name, slug, description }] } and writes nothing — read the list, then call again with skill to install a choice.
bundle(sources, options?)
Install multiple skills from inline sources or a bundle file.
| Option | Type | Default | Description |
|---|---|---|---|
dryRun | boolean | false | Preview only |
noMcp | boolean | false | Skip MCP server installation |
Returns { installed: number, failed: number, results: [{ source, status, error? }] }.
watch(slug?, cwd?, options?)
Watch installed local skills for file changes and auto-sync.
| Option | Type | Default | Description |
|---|---|---|---|
dryRun | boolean | false | Preview only |
onEvent | (event) => void | none | Called for setup and sync events (see below) |
Returns { watchers: FSWatcher[], skills: string[], installedCount: number, close: () => void }. Call close() to cancel pending syncs and close every watcher; it is safe to call more than once. With dryRun, returns { dryRun: true, skills: [{ slug, source, path }] } instead.
Throws a UserError with code WATCH_SKILL_NOT_FOUND when slug is not installed.
onEvent receives objects with a type field:
type | Extra fields | When |
|---|---|---|
start | slugs | Before watchers are set up |
skip | slug, sourceType | A non-local skill was requested |
watching | slug, path | A watcher started |
error | slug, path, error | A watcher could not start, or reported an error later |
syncing | slug, filename, startedAt | A change triggered a re-install |
synced | slug, ok, startedAt | The re-install finished (ok: false on failure) |
convert(source, options?)
Convert skills bidirectionally between rolecraft's SKILL.md format and Cursor/Claude Code's .mdc rule format. Programmatic implementation is in src/api/convert.js.
| Option | Type | Default | Description |
|---|---|---|---|
dryRun | boolean | false | Preview conversion plan without writing files or creating directories |
output | string | process.cwd() | Target output directory (created recursively if missing in write mode) |
Return Value
convert() always returns an array of result objects (one per converted file), even when passed a single file path:
- Write mode (
dryRun: false): Returns[{ from: string, to: string, format: 'skill-to-mdc' | 'mdc-to-skill' }]. Files are written to disk. - Dry-run mode (
dryRun: true): Returns[{ dryRun: true, from: string, to: string }]. Returns the planned destination paths without creating directories or writing any files to disk (formatis omitted in dry-run mode).
Destination Path Resolution
The destination filename is determined by the input format:
- SKILL.md → .mdc (
skill-to-mdc): Destination filename is derived from the skill's frontmatter slug or name (${slug}.mdc, falling back toskill.mdc). Slashes in slugs are normalized to dashes. - .mdc → SKILL.md (
mdc-to-skill): Destination filename is alwaysSKILL.mdinside the specifiedoutputdirectory (path.join(outDir, 'SKILL.md')).
Source Resolution and Format Detection
- Directories:
convert()checks forSKILL.mdfirst. If found, only that skill file is converted to.mdc. If noSKILL.mdexists, it scans for all*.mdcfiles in the directory and converts each one toSKILL.md. If neither is found, it throwsNo SKILL.md or .mdc files found in <dir>. - Single Files: If a file does not use the standard name
SKILL.mdor.mdcextension (e.g.rules.txt),convert()sniffs frontmatter keys:slug:detects a skill file, whilealwaysApply:orglobs:detects an MDC rule. If neither is found, it throwsCannot detect format. - Empty Files: Throws
Source is empty: <path>.
Example
import { convert } from 'rolecraft'
// Preview conversion plan without writing files
const plan = await convert('./rules/cursor-rule.mdc', {
dryRun: true,
output: './converted',
})
console.log(plan)
// [
// {
// dryRun: true,
// from: '/path/to/rules/cursor-rule.mdc',
// to: '/path/to/converted/SKILL.md',
// }
// ]
// Execute the actual conversion
const results = await convert('./rules/cursor-rule.mdc', {
output: './converted',
})
console.log(results)
// [
// {
// from: '/path/to/rules/cursor-rule.mdc',
// to: '/path/to/converted/SKILL.md',
// format: 'mdc-to-skill',
// }
// ]init(name?)
Scaffold a new SKILL.md file.
| Param | Type | Description |
|---|---|---|
name | string | Skill name or owner/name (default: my-skill) |
Returns { path: string, slug: string, name: string, owner: string }.
upgrade(options?)
Check for rolecraft updates and upgrade.
| Option | Type | Default | Description |
|---|---|---|---|
dryRun | boolean | false | Check without upgrading |
Returns { current: string, latest: string|null, isUpToDate: boolean|null, upgraded?: boolean, version?: string }.
completions(shell)
Generate shell completion script.
| Param | Type | Description |
|---|---|---|
shell | string | 'bash', 'zsh', or 'fish' |
Returns the completion script as a string.
agentsXml(writeToFile?)
Generate a <skills_system> XML block listing installed skills.
| Param | Type | Default | Description |
|---|---|---|---|
writeToFile | boolean | false | Write or replace XML section in ./AGENTS.md |
Returns { xml: string, written: boolean, path?: string }.
compareVersions(a, b)
Compare two semver version strings. Returns negative, zero, or positive number.
See also
- CLI Reference — every command with all flags on one page.
- Commands — each command grouped by what you are trying to do.
- Architecture — how rolecraft is put together under the hood.
