Skip to content

Commit 75f649d

Browse files
TheStack-aiclaude
andcommitted
feat: add GitHub Marketplace Action for CI skill linting
Composite action that installs pulser-cli and runs diagnostics on SKILL.md files. Outputs score, errors, warnings for downstream steps. Usage: - uses: TheStack-ai/pulser@v1 with: path: '.claude/skills' strict: 'true' Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
1 parent 12938a0 commit 75f649d

1 file changed

Lines changed: 86 additions & 0 deletions

File tree

action.yml

Lines changed: 86 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,86 @@
1+
name: 'Pulser — Claude Code Skill Linter'
2+
description: 'Diagnose Claude Code SKILL.md files against Anthropic best practices. Checks 8 rules, classifies skill types, prescribes fixes.'
3+
author: 'TheStack-ai'
4+
5+
branding:
6+
icon: 'activity'
7+
color: 'green'
8+
9+
inputs:
10+
path:
11+
description: 'Path to skills directory'
12+
required: false
13+
default: '.claude/skills'
14+
strict:
15+
description: 'Treat warnings as errors (exit 1 on any issue)'
16+
required: false
17+
default: 'false'
18+
version:
19+
description: 'pulser-cli version to install (e.g. 0.4.0, latest)'
20+
required: false
21+
default: 'latest'
22+
23+
outputs:
24+
score:
25+
description: 'Overall skill health score (0-100)'
26+
value: ${{ steps.pulser.outputs.score }}
27+
errors:
28+
description: 'Number of errors found'
29+
value: ${{ steps.pulser.outputs.errors }}
30+
warnings:
31+
description: 'Number of warnings found'
32+
value: ${{ steps.pulser.outputs.warnings }}
33+
total:
34+
description: 'Total skills scanned'
35+
value: ${{ steps.pulser.outputs.total }}
36+
37+
runs:
38+
using: 'composite'
39+
steps:
40+
- name: Setup Node.js
41+
uses: actions/setup-node@v4
42+
with:
43+
node-version: '20'
44+
45+
- name: Install pulser-cli
46+
shell: bash
47+
run: npm install -g pulser-cli@${{ inputs.version }}
48+
49+
- name: Run pulser
50+
id: pulser
51+
shell: bash
52+
run: |
53+
set +e
54+
REPORT=$(pulser "${{ inputs.path }}" --format json --no-anim 2>&1)
55+
EXIT_CODE=$?
56+
set -e
57+
58+
if echo "$REPORT" | jq -e '.summary' > /dev/null 2>&1; then
59+
SCORE=$(echo "$REPORT" | jq -r '.summary.score')
60+
ERRORS=$(echo "$REPORT" | jq -r '.summary.errors')
61+
WARNINGS=$(echo "$REPORT" | jq -r '.summary.warnings')
62+
TOTAL=$(echo "$REPORT" | jq -r '.summary.total')
63+
else
64+
SCORE=0
65+
ERRORS=-1
66+
WARNINGS=-1
67+
TOTAL=0
68+
fi
69+
70+
echo "score=$SCORE" >> "$GITHUB_OUTPUT"
71+
echo "errors=$ERRORS" >> "$GITHUB_OUTPUT"
72+
echo "warnings=$WARNINGS" >> "$GITHUB_OUTPUT"
73+
echo "total=$TOTAL" >> "$GITHUB_OUTPUT"
74+
75+
echo "::group::Pulser Diagnostic Report"
76+
pulser "${{ inputs.path }}" --format text --no-anim 2>&1 || true
77+
echo "::endgroup::"
78+
79+
if [ "${{ inputs.strict }}" = "true" ]; then
80+
if [ "$ERRORS" -gt 0 ] || [ "$WARNINGS" -gt 0 ]; then
81+
echo "::error::Pulser found $ERRORS error(s) and $WARNINGS warning(s). Score: $SCORE/100"
82+
exit 1
83+
fi
84+
elif [ "$EXIT_CODE" -eq 1 ]; then
85+
echo "::warning::Pulser found issues. Score: $SCORE/100. Use strict mode to fail the build."
86+
fi

0 commit comments

Comments
 (0)