Ship agent plugins that actually board. HookHound sniffs broken hooks, missing manifests, unshipped dist/ files, and package payload mistakes before users discover them.
HookHound is a CI-friendly release gate for Claude, ZCode, Codex, GJC, and OmO-style agent plugin repositories. It checks plugin manifests, hook commands, skill/agent references, and npm package payloads before a broken plugin reaches release.
Mascot: Hookie, the airport beagle for agent plugins. If a hook script is missing from the suitcase, Hookie barks before release day.
npm install
npm run build
node dist/cli.js sniff --root .Use the published package without installing it globally:
npm exec --package hookhound@0.1.2 -- hookhound sniff --root .
npm exec --package hookhound@0.1.2 -- hookhound sniff --root . --strict
npm exec --package hookhound@0.1.2 -- hookhound sniff --root . --json
npm exec --package hookhound@0.1.2 -- hookhound sniff --root . --format githubOr install the CLI globally:
npm install -g hookhound
hookhound sniff --root .Exit code is non-zero when any error finding exists. Warnings and info findings are reported without failing the run.
name: HookHound
on:
pull_request:
push:
branches: [main]
jobs:
sniff:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: YoungsPlace/hookhound@v0.1.2
with:
root: .
strict: "true"Inputs:
| Input | Default | Description |
|---|---|---|
root |
. |
Plugin root to scan. Relative paths resolve from the GitHub workspace. |
strict |
false |
Fail when no agent plugin surface is detected. |
The Action runs the HookHound CLI JSON path, emits GitHub workflow annotations for file-scoped errors and warnings, and writes a markdown job summary. Repository-level findings stay in the summary instead of being attached to fake files or lines.
Run a clean fixture:
node dist/cli.js sniff --root test/fixtures/clean-plugin
# Verdict: PASSEDRun a broken generated hook fixture:
node dist/cli.js sniff --root test/fixtures/missing-dist --json
# exits 1 and reports: missing-generated-hook-artifactRun a hook that escapes the plugin root with GitHub-format output:
node dist/cli.js sniff --root test/fixtures/outside-root --format github
# emits ::error ... hook-target-outside-root ... and exits 1Run SARIF output locally after building:
node dist/cli.js sniff --root test/fixtures/outside-root --format sarif
# emits SARIF 2.1.0 JSON for code-scanning toolsRun the Action entrypoint locally after building:
GITHUB_WORKSPACE="$PWD" \
INPUT_ROOT="test/fixtures/outside-root" \
GITHUB_STEP_SUMMARY="/tmp/hookhound-summary.md" \
node dist/action.js
# exits 1, prints GitHub annotation commands, and writes the job summary.claude-plugin/plugin.json.claude-plugin/marketplace.json.zcode-plugin/plugin.json.zcode-plugin/marketplace.json.codex/hooks.jsonhooks/hooks.jsonskills/*/SKILL.mdand.codex/skills/*/SKILL.mdagents/*.mdand.claude-plugin/agents/*.mdpackage.jsonfor npm payload modeling
- Invalid JSON and non-object manifests
- Missing plugin metadata:
name,version,description,license - Version drift across plugin manifests
- License drift and missing root
LICENSE - Marketplace plugin entries that are not objects
- Missing or unresolved marketplace
sourcepaths
- Supported root template interpolation, including
${PLUGIN_ROOT},${ZCODE_PLUGIN_ROOT},${CLAUDE_PLUGIN_ROOT},${CODEX_PLUGIN_ROOT},${GJC_PLUGIN_ROOT}, and${OMO_PLUGIN_ROOT} - Interpreter/wrapper hook commands such as
python3 "${PLUGIN_ROOT}/scripts/check.py"and/usr/bin/env node ./hooks/check.js - Missing hook command targets
- Missing generated
dist/hook artifacts - Hook targets that escape the plugin root
- Node hook script syntax errors via
node --check - Process hooks without timeouts
- Markdown references to missing
agents/*.mdfiles
npm pack --dry-run --json --ignore-scriptspayload modeling- Hook targets that exist locally but are omitted from the npm package payload
- Generated hook artifacts that appear likely to be excluded by
package.json.files - Configurable suppressions for known accepted findings
- Generated path mappings for release pipelines that copy files from source trees into plugin payload paths
hookhound sniff --root . # human text report
hookhound sniff --root . --json # machine-readable ScanSummary
hookhound sniff --root . --format github # GitHub annotations + markdown summary
hookhound sniff --root . --format sarif # SARIF 2.1.0 for code scanning toolsThe JSON shape is the stable integration surface for wrappers:
interface Finding {
id: string
level: "error" | "warning" | "info"
title: string
message: string
file?: string
evidence?: string
hint?: string
line?: number
column?: number
}--format sarif emits SARIF 2.1.0 with HookHound findings mapped to SARIF rules/results for adoption in code-scanning dashboards.
HookHound automatically reads hookhound.yml or hookhound.yaml from the scan root. Use it to adapt the release gate to real repository layouts without weakening default checks for every project:
ignore:
- id: referenced-agent-file-missing
file: "skills/*/SKILL.md"
evidence: "agents/*.md"
reason: "agents are generated into the release payload"
generated:
- from: src/ouroboros/agents
to: agentsignore suppresses findings by id and optional file / evidence glob-like patterns. generated tells HookHound that a release pipeline copies source files into payload paths, so Markdown references such as agents/reviewer.md can be satisfied by src/ouroboros/agents/reviewer.md.
You can also point at an explicit config file:
hookhound sniff --root . --config ./hookhound.ymlConfig parsing is dependency-free and intentionally narrow: top-level ignore: / generated: lists with object items and scalar string values. Invalid config is an error finding because a release gate should not silently ignore a typoed suppression or mapping.
HookHound currently provides local text output, machine-readable ScanSummary JSON, GitHub annotations/job summaries, and SARIF for code-scanning consumers. It does not provide:
- hosted dashboards
- telemetry or report uploads
- broad marketplace schema coverage
- a broad adapter framework
- package-manager payload simulations beyond npm
Those are intentionally deferred until real CI usage shows demand. The current goal is boring and useful: catch broken agent plugin releases in local and GitHub CI workflows without uploading project data.
HookHound has been tested against real external agent/tooling repositories. See docs/dogfood.md for true positives, false-positive notes, and the next scanner UX backlog.
The launch positioning and README conversion review lives in docs/marketing-review.md. It records the applied copy, mascot, multilingual, and scope-boundary improvements.
- Harden GitHub Action usage against real plugin repositories.
- Expand config-driven adapter hints when repeated implementation pressure appears.
- Improve first-run adoption with
hookhound initandhookhound doctor. - Expand SARIF/code-scanning polish from real adopter feedback.
npm install
npm run build
npm test
npm run checkUseful fixture commands:
node dist/cli.js sniff --root test/fixtures/clean-plugin
node dist/cli.js sniff --root test/fixtures/missing-dist --json
node dist/cli.js sniff --root test/fixtures/unshipped-target --json
node dist/cli.js sniff --root test/fixtures/package-only --strict --jsonMIT
