A generic CLI that wraps npx skills add and converts installed skills to slash commands — plus event hooks (session_start, user_prompt_submit, and more) that auto-trigger skills on any coding agent.
Works with any skills repo: adlc-team-skills, mattpocock/skills, addyosmani/agent-skills, obra/superpowers, or your own.
npx skills add installs SKILL.md files to an agent's skills directory, but does not generate slash command files or wire event hooks. Many coding agents only support commands (not skills), and auto-triggering skills at lifecycle points (session start, prompt submit) requires per-agent native hook configuration. This CLI fills both gaps.
# Install skills + generate commands + wire events (if .events.json present)
npx adlc-agents-cli add tikalk/adlc-team-skills -a opencode
# Works with any skills repo — events auto-skip if no .events.json
npx adlc-agents-cli add mattpocock/skills -a claude-code --no-events
npx adlc-agents-cli add addyosmani/agent-skills -a opencode -a cursoradlc-agents-cli add <source> -a <agent>
│
├─ 1. npx skills add <source> -a <npx_agent> ← installs SKILL.md files
│
├─ 2. Discover installed skills ← reads SKILL.md frontmatter
│
├─ 3. Generate command files ← slash commands (/name)
│ .opencode/commands/<name>.md inline: embeds skill body
│ wrapper: references skill
│
└─ 4. Wire events (if .events.json in source) ← lifecycle hooks
.agents/dispatcher.mjs generic dispatcher (shipped)
.opencode/plugin/adlc-agents-events.ts agent-native hook config
| Command | Description |
|---|---|
add <source> -a <agent> |
Install skills via npx skills add + generate commands + wire events |
upgrade [-a <agent>] |
Re-generate commands from currently-installed skills (header-matched overwrite) |
remove [-a <agent>] |
Remove generated commands + event configs (marker-matched only) |
status [-a <agent>] |
Show what's installed per agent + dispatcher + event status |
agents |
List supported agents, directories, formats, event support |
| Flag | Description |
|---|---|
-a <agent> |
Target agent (repeatable). Run agents to list. |
-g, --global |
Install to user directory instead of project |
--no-events |
Skip event config generation |
--prefix <str> |
Namespace command filenames (e.g., adlc.team-setup.md) |
--mode <mode> |
inline (default, embeds full skill body) or wrapper (references skill by name) |
--skill <name> |
Install/generate for one skill only (use '*' for all) |
--copy |
Copy files instead of symlinking (passthrough to npx skills) |
-y, --yes |
Skip confirmation prompts |
23 agents across 3 command formats. 9 agents support event hooks.
| Agent | Commands dir | Format | Events |
|---|---|---|---|
| opencode | .opencode/commands/ |
markdown | yes |
| claude-code | .claude/commands/ |
markdown | yes |
| cursor | .cursor/commands/ |
markdown | yes |
| github-copilot | .github/prompts/ |
markdown | yes |
| codex | ~/.codex/prompts/ |
markdown | yes |
| devin | .devin/commands/ |
markdown | yes |
| qwen-code | .qwen/commands/ |
markdown | yes |
| gemini-cli | .gemini/commands/ |
toml | yes |
| tabnine-cli | .tabnine/agent/commands/ |
toml | yes |
| amp | .agents/commands/ |
markdown | no |
| goose | .goose/recipes/ |
yaml | no |
| ...and 12 more |
Run adlc-agents-cli agents for the full list.
Embeds the full SKILL.md body in the command file — self-contained, works on any agent even without skill support:
---
description: Clone, scaffold, or configure a team AI directives repository
---
<!-- generated by adlc-agents-cli; source: tikalk/adlc-team-skills — do not edit -->
Base directory for this skill: /project/.agents/skills/team-setup
Relative paths in this skill are relative to this base directory.
---
# Team Setup
[full skill body...]
$ARGUMENTSThin command that references the installed skill — requires the agent to have skill support:
---
description: Clone, scaffold, or configure a team AI directives repository
---
<!-- generated by adlc-agents-cli; source: tikalk/adlc-team-skills — do not edit -->
Invoke the `team-setup` skill.
$ARGUMENTSFor agents with native hook support (9 agents), the CLI wires event hooks that auto-trigger skills at lifecycle points — replacing the "model must invoke the skill" soft directive with deterministic, runtime-enforced context injection.
Events are auto-enabled when:
- The agent supports events (9 agents above)
- The source repo declares a
.events.jsonmanifest --no-eventsis not set
Skills repos declare events at the repo root:
{
"events": {
"session_start": [
{ "skill": "team-boot", "description": "Bootstrap session with team context", "timeout": 60 }
],
"user_prompt_submit": [
{ "skill": "team-discover", "description": "Fetch relevant context for the current prompt", "timeout": 30 }
]
}
}Repos without .events.json (e.g., mattpocock/skills) simply get commands only — events are skipped silently.
A generic dispatcher (.agents/dispatcher.mjs) is shipped to the project. When a native hook fires, it calls the dispatcher with (event, skill, skills_dir, timeout). The dispatcher resolves the skill and executes it via one of two paths:
| Path | When | How | Best for |
|---|---|---|---|
| Script (spec-kit model) | Skill has scripts: in frontmatter |
Runs the script (sh/ps/py variant) → stdout | Deterministic logic (file assembly, keyword matching) |
| Body (superpowers model) | No scripts: block |
Outputs the skill's markdown body → stdout | Orientation/instruction skills (pure LLM prompts) |
Both paths share the stdout → context injection pipeline: whatever the dispatcher outputs to stdout is captured by the agent's native hook and injected as session context.
# Skill with a script (deterministic path)
---
name: team-boot
scripts:
sh: scripts/boot.sh
---# Skill without a script (body path — default)
---
name: using-superpowers
description: Orientation skill injected at session start
---| Event | Fires when | Body path? | Script path? |
|---|---|---|---|
session_start |
Agent session begins | yes | yes |
user_prompt_submit |
User sends a prompt (payload via stdin) | yes | yes |
pre_tool_use |
Before a tool call | no | yes |
post_tool_use |
After a tool call | no | yes |
session_end |
Session ends | no | yes |
stop |
Agent stops | no | yes |
The CLI generates agent-native hook configs that call the dispatcher. Each agent's native event names and config format are handled automatically:
| Agent | Config file | Format | Timeout unit |
|---|---|---|---|
| opencode | .opencode/plugin/adlc-agents-events.ts |
TS plugin | seconds |
| claude-code | .claude/settings.json (merged) |
JSON nested | seconds |
| cursor | .cursor/hooks.json (merged) |
JSON nested | seconds |
| github-copilot | .github/hooks/adlc-agents.json |
JSON (bash+powershell) | seconds |
| codex | .codex/config.toml (merged) |
TOML | seconds |
| gemini-cli | .gemini/settings.json (merged) |
JSON nested | milliseconds |
| qwen-code | .qwen/settings.json (merged) |
JSON nested | milliseconds |
| devin | .devin/hooks.v1.json (merged) |
JSON root-nested | seconds |
| tabnine-cli | .tabnine/agent/settings.json (merged) |
JSON nested | milliseconds |
- Idempotent merge: re-install never duplicates hook entries (marker-based dedup)
- Surgical teardown:
removestrips only our entries, preserves user hooks - JSONC preservation: malformed JSON aborts, never resets user content
- Safe-destination validation: rejects symlink redirects outside project root
- Shell-safe argv:
execFileSyncwith argv arrays, no shell injection - stdin payload forwarding:
user_prompt_submitreceives the user's prompt
Every generated file includes a <!-- generated by adlc-agents-cli --> header. Event hook entries carry a _adlc_agents_cli: true marker (JSON) or adlc_marker = true (TOML). This enables:
removeto safely delete only our files (user-created commands/hooks are never touched)upgradeto overwrite our files while skipping user-modified ones (header removed = user-owned)
No manifest database or state file needed.
# Run tests
npm test
# Run the CLI locally
node bin/adlc-agents-cli.mjs agents
node bin/adlc-agents-cli.mjs help
node bin/adlc-agents-cli.mjs status -a opencodeZero runtime dependencies. Requires Node.js >= 18.
MIT