npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

adlc-agents-cli

v0.3.0

Published

Generic CLI that wraps npx skills add and converts installed skills to slash commands + lifecycle event hooks for any coding agent.

Readme

adlc-agents-cli

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.

Why?

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.

Quickstart

# 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 cursor

How it works

adlc-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

Commands

| 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 |

Flags

| 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 |

Supported agents

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.

Command generation: two modes

Inline (default)

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...]

$ARGUMENTS

Wrapper

Thin 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.

$ARGUMENTS

User-invoked skills: wrapper vs execution mode

User-invoked skills (disable-model-invocation: true in frontmatter) are meant to be triggered explicitly, not auto-invoked by the model. On wrapper-default agents (those with a skill tool), the command body strategy is chosen per agent via user_invoked_mode:

| user_invoked_mode | Used by | Command body | Why | |---------------------|---------|--------------|-----| | "wrapper" | opencode | Invoke the \team-setup` skill.+ summary | opencode **ignores**disable-model-invocation— the skill stays in<available_skills>and loads via theskilltool. The wrapper command tells the model to invoke it, and it can. | |"execution"(default) |claude-code, cursor, copilot, codex | Full body inlined, framed as imperative steps | These agents **respect** disable-model-invocation— the skill is hidden from the model, soskill({name})` would fail. Inlining the body is the only working path. |

For opencode, /team-setup expands to the wrapper text, the model sees team-setup in <available_skills>, and calls skill({ name: "team-setup" }) — the skill loads via the tool with full progressive disclosure (base dir + sampled files, invocation visible in traces).

Install

# One-off (no install needed)
npx adlc-agents-cli add tikalk/adlc-team-skills -a opencode

# Install as global binary → adlc-agents-cli available everywhere
npm install -g adlc-agents-cli
adlc-agents-cli add tikalk/adlc-team-skills -a opencode

Events: lifecycle hooks

For 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:

  1. The agent supports events (9 agents above)
  2. The source repo declares a .events.json manifest
  3. --no-events is not set

.events.json manifest

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.

The dispatcher: two execution paths

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
---

6 canonical events

| 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 |

Per-agent native hook configuration

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 |

Context injection: what reaches the model

Not every agent injects a hook's plain-text stdout as model context. The dispatcher wraps its stdout in the JSON envelope each agent's hook protocol requires (passed as a 5th argv arg), per this matrix:

| Agent | session_start injection | user_prompt_submit injection | Mechanism | |-------|--------------------------|-------------------------------|-----------| | claude-code | ✅ plain stdout | ✅ plain stdout | none needed | | codex | ✅ plain stdout | ✅ plain stdout | none needed | | gemini-cli | ✅ JSON envelope | ✅ JSON envelope | {"hookSpecificOutput":{"additionalContext":...}} | | tabnine-cli | ✅ JSON envelope | ✅ JSON envelope | same | | qwen-code | ✅ JSON envelope | ✅ JSON envelope | same | | devin | ✅ JSON envelope | ✅ JSON envelope | same | | github-copilot | ✅ JSON envelope | ⛔ impossible | {"additionalContext":...} (top-level); userPromptSubmitted output is not processed | | cursor | ✅ JSON envelope | ⛔ impossible | {"additional_context":...} (snake_case); beforeSubmitPrompt has no context field | | opencode | ✅ system.transform | ✅ chat.message | plugin pushes into hook outputs (no stdout) |

For strict-JSON agents (gemini-cli, tabnine-cli, qwen-code, devin), plain stdout on non-injectable events would become user-facing noise or a hook parse error — there the dispatcher is invoked with suppress and emits nothing. On cursor, everything except sessionStart is suppressed for the same reason.

Codex trust review: Codex skips non-managed hooks until you review and trust them. After installing, run /hooks in Codex once and trust the generated entries (trust is recorded against the hook hash, so upgrades that change the entries need re-trusting). The repo's .codex/ layer must also be trusted. Hooks are enabled by default otherwise — [features] hooks = false in config.toml is the kill switch.

opencode compatibility: the generated TS plugin is verified against opencode ≥ 1.18. opencode's Part.id must start with prt (its Identifier brand) and hooks must never throw — a schema error or rethrown exception in a plugin crashes the whole session. The plugin derives the injected part's id from the last existing part at runtime (so it inherits opencode's brand even if the prefix changes), falling back to prt_, and wraps every hook body in try/catch that logs instead of rethrowing. If you upgrade opencode, re-run adlc-agents-cli upgrade -a opencode to regenerate the plugin.

Safety patterns (ported from spec-kit)

  • Idempotent merge: re-install never duplicates hook entries (marker-based dedup)
  • Surgical teardown: remove strips 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: execFileSync with argv arrays, no shell injection
  • stdin payload forwarding: user_prompt_submit receives the user's prompt

Self-describing files

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:

  • remove to safely delete only our files (user-created commands/hooks are never touched)
  • upgrade to overwrite our files while skipping user-modified ones (header removed = user-owned)

No manifest database or state file needed.

Development

# 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 opencode

Zero runtime dependencies. Requires Node.js >= 18.

License

MIT