Configuration-driven installer for Agent Skills. skill-ctl does not ship a catalog. You point it at a source directory, register skills, then install them into one or more agent targets.
- Node.js 18.17 or later
- pnpm (recommended for local development)
npm install -g @lion1ou/skill-ctlGlobal install provides the skill-ctl command. You can also run it without installing:
npx @lion1ou/skill-ctlFor local development:
git clone https://github.com/lion1ou/skillctl.git
cd skillctl
pnpm install
pnpm build
npm linkPaths must be absolute. Interactive init asks for the source directory first, then the cache directory. If a local config already exists, you can keep it or overwrite it.
skill-ctl init --source /absolute/path/to/catalog --cache /absolute/path/to/cache--sourceis required in non-interactive mode.--cacheis optional. The default is<skillctl>/.cache.- Machine-local mapping is stored at
~/.config/skillctl/config.json.
If the source directory has no catalog files, init creates:
skillctl-skills.json— skill registryskillctl-categories.json— category table
The generated files include two example remote skills. Existing files are not overwritten.
skill-ctl init --source /absolute/path/to/catalog
skill-ctl add --local
skill-ctl add <query|owner/repo>
skill-ctl install
skill-ctl install -G common -t cursor
skill-ctl install -s web-access -t cursor,codex --mode copy
skill-ctl manageadd only updates the catalog. It does not install skills or write the cache.
add --localregisters unlisted skills undersourceDir/skills/.add <keyword>searches skills.sh.add <owner/repo>lists sub-skills in that package.
install always runs: select → check → prepare → distribute.
- Choose scope (current directory or
~), mode (symlink or copy), targets, and skills. - Interactive skill selection is grouped by category. Child skills are indented. Selecting a category selects every skill in it.
- Skills missing from the registry are removed from the category table with a notice, not an error.
- Missing external skills are cached with a progress spinner, then copied or symlinked into each target.
- Skills with
"enabled": falsein the registry are skipped during install and listed in the result. Missingenabledis treated as enabled.
manage starts a local dashboard on 127.0.0.1. The top bar switches between Installed skills and Catalog.
skill-ctl manage
skill-ctl manage --port 4173 --no-openInstalled skills /
- Scans the user home directory by default, and can add project Workspaces through the native directory picker or an absolute path. Each Workspace is scanned using the Agent-specific subdirectories; only Agents with skills or explicitly pinned by the user are shown. Batch-adding Agents only pins them for display; it does not pre-create directories.
- The top-right Install button opens a category dialog and installs into the current Agent under the current Workspace. The enable/disable control on a card renames
SKILL.md↔SKILL.md.disable. - Click a Skill card to open its detail page, which reads the landed
SKILL.mdin that Workspace/Agent (SKILL.md.disablewhen disabled). YAML frontmatter and Markdown body are shown separately. The enable/disable control does not open detail. - Removing a Workspace only removes the management entry; it never deletes project files. The user home Workspace cannot be removed.
- Removing an Agent's skills deletes that Agent's skills directory in the current Workspace and unpins it. If the directory itself is a symlink, only the link is removed.
- The page filters by name and status, places enabled skills before disabled ones, and refreshes filesystem state every three seconds.
- Workspace paths and pinned Agents are stored in
~/.config/skillctl/config.json.
Catalog /catalog
- Visually edit
skillctl-skills.jsonandskillctl-categories.json. Change category, description, and install-timeenabled, and sync unregistered local skills from the source directory. This switch only affectsinstall, not files already installed. - Click a card to open detail for the registered skill's source
SKILL.md. Uncached external skills show as not prepared; the page does not download them automatically. - Deleting a catalog entry removes the registry record only; source files are not deleted.
Shared rules
- Detail pages show only
SKILL.md(or the disabled filename), not other files in the skill directory. Read paths must stay inside a managed Workspace, the local source directory, or the external cache root. - Toggling a symlinked installed skill modifies its real source and affects other links to that source, so the page asks for confirmation.
- The service only binds to the loopback address and protects its API with a random per-process token.
<sourceDir>/
├── skillctl-skills.json
├── skillctl-categories.json
└── skills/<skill-name>/
Each registry item has id, package, name, a Chinese description, version, source, type (local or external), and enabled. A skill belongs to exactly one category.
External skills are staged under:
<cacheDir>/<owner>/<repo>/<skillName>/
npx skills add staging leftovers (.agents/, skills-lock.json) are removed after the skill is moved into that path.
| target | skills directory |
|---|---|
| cursor | .cursor/skills |
| claude | .claude/skills |
| kiro | .kiro/skills |
| agents | .agents/skills |
| codex | .codex/skills |
| openclaw | .openclaw/skills |
| hermes | .hermes/skills |
| gemini | .gemini/skills |
| copilot | .copilot/skills |
| windsurf | .codeium/windsurf/skills |
| roo | .roo/skills |
| opencode | .config/opencode/skills |
| openhands | .openhands/skills |
| droid | .factory/skills |
| continue | .continue/skills |
| trae | .trae/skills |
| trae-cn | .trae-cn/skills |
| workbuddy | .workbuddy/skills |
| qoder | .qoder/skills |
| qoder-cn | .qoder-cn/skills |
| codebuddy | .codebuddy/skills |
| qwen | .qwen/skills |
Each target skills directory records installs in .skillctl.json. skill-ctl does not install rules or MCP configs.
npm run dev
# equivalent: pnpm run devnpm run dev temporarily points the global skill-ctl command at this repo's development entry:
- If
skill-ctlis missing, it is registered in the npm globalbin. - If
skill-ctlalready exists, it is replaced with a symlink to the development repo and the original target is remembered. - When the process exits (including Ctrl+C), a command that did not exist is removed; an existing command is restored to its previous target.
While the session is running, use skill-ctl manage from another terminal. Extra arguments are forwarded to the development CLI:
npm run dev -- manage --no-open
pnpm test
pnpm lintThe published npm package contains only bin/ and compiled dist/. Catalog sources are never bundled.
Release notes are in CHANGELOG.md. To publish @lion1ou/skill-ctl@1.2.0 yourself after committing:
pnpm test
npm publish --access public