Agento-patronum patronum-dev-validate
Validate the agento-patronum plugin structure. Run before opening a PR.
install
source · Clone the upstream repo
git clone https://github.com/emaarco/agento-patronum
Claude Code · Install into ~/.claude/skills/
T=$(mktemp -d) && git clone --depth=1 https://github.com/emaarco/agento-patronum "$T" && mkdir -p ~/.claude/skills && cp -r "$T/.claude/skills/patronum-dev-validate" ~/.claude/skills/emaarco-agento-patronum-patronum-dev-validate && rm -rf "$T"
manifest:
.claude/skills/patronum-dev-validate/SKILL.mdsource content
Skill: patronum-dev-validate
Run all plugin validation checks locally.
Steps
1. JSON validity
node -e "JSON.parse(require('fs').readFileSync('.claude-plugin/plugin.json','utf8'))" && echo "plugin.json OK" node -e "JSON.parse(require('fs').readFileSync('.claude-plugin/marketplace.json','utf8'))" && echo "marketplace.json OK" node -e "JSON.parse(require('fs').readFileSync('hooks/hooks.json','utf8'))" && echo "hooks.json OK" node -e "JSON.parse(require('fs').readFileSync('defaults/patronum.json','utf8'))" && echo "patronum.json OK"
1b. marketplace.json schema
Verify the
source field starts with ./ and metadata.description is present (both required by Claude Code validation):
node -e " const m = JSON.parse(require('fs').readFileSync('.claude-plugin/marketplace.json','utf8')); const p = m.plugins[0]; if (typeof p.source === 'string' && p.source.startsWith('./')) console.log('marketplace source OK'); else { console.error('marketplace source FAIL'); process.exit(1); } " node -e " const m = JSON.parse(require('fs').readFileSync('.claude-plugin/marketplace.json','utf8')); const d = m.metadata && m.metadata.description; if (typeof d === 'string' && d.length > 0) console.log('marketplace description OK'); else { console.error('marketplace description FAIL'); process.exit(1); } "
2. Default patterns check
Verify
defaults/patronum.json has at least one entry:
node -e " const d = JSON.parse(require('fs').readFileSync('defaults/patronum.json','utf8')); const count = d.entries.length; if (count > 0) console.log('Default patterns: ' + count + ' entries OK'); else { console.error('No default patterns found'); process.exit(1); } "
3. Script syntax
node -e " const fs = require('fs'); const glob = require('path'); ['hooks', 'management', 'setup'].forEach(dir => { fs.readdirSync('scripts/' + dir).filter(f => f.startsWith('patronum-') && f.endsWith('.js')).forEach(f => { const p = 'scripts/' + dir + '/' + f; try { require('child_process').execSync('node -c ' + p, {stdio:'pipe'}); console.log(p + ' OK'); } catch(e) { console.error(p + ' FAIL'); process.exit(1); } }); }); "
4. Script permissions
for f in scripts/hooks/patronum-*.js scripts/management/patronum-*.js scripts/setup/patronum-*.js; do test -x "$f" && echo "$f executable OK" done
5. SKILL.md frontmatter
Check each SKILL.md has a
name: and description: in its frontmatter:
for f in skills/*/SKILL.md; do head -10 "$f" | grep -q "^name:" && echo "$f: name OK" head -10 "$f" | grep -q "^description:" && echo "$f: description OK" done
6. Report
Summarize all results. Use before opening a PR.