feat: add README and flesh out all plugins

README.md:
- GitHub-friendly documentation
- Installation instructions
- Plugin overview with commands

review plugin:
- /review:security - Security-focused review
- /review:pr - PR review
- hooks.json - Post PR create suggestion
- scripts/post-pr-create.sh

verify plugin:
- /verify:ready - Quick readiness check
- /verify:tests - Test verification
- hooks.json - Pre-push warning
- scripts/pre-push-check.sh

qa plugin:
- /qa:check - Report only, no fixes
- /qa:lint - Lint with fix option
- hooks.json - QA output filtering

ci plugin:
- /ci:status - CI status display
- /ci:run - Trigger workflows
- /ci:fix - Analyse and fix failures
- hooks.json - Post-push CI hint
- scripts/post-push-ci.sh

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
Snider 2026-02-01 19:48:51 +00:00
parent 9942ab8081
commit b633ae81f6
17 changed files with 954 additions and 0 deletions

119
README.md Normal file
View file

@ -0,0 +1,119 @@
# core-agent
A monorepo of [Claude Code](https://claude.ai/code) plugins for the Host UK federated monorepo.
## Plugins
| Plugin | Description | Commands |
|--------|-------------|----------|
| **[code](./claude/code)** | Core development - hooks, scripts, data collection | `/code:remember`, `/code:yes` |
| **[review](./claude/review)** | Code review automation | `/review:review`, `/review:security`, `/review:pr` |
| **[verify](./claude/verify)** | Work verification before commit/push | `/verify:verify`, `/verify:ready` |
| **[qa](./claude/qa)** | Quality assurance fix loops | `/qa:qa`, `/qa:fix`, `/qa:check` |
| **[ci](./claude/ci)** | CI/CD integration | `/ci:ci`, `/ci:workflow`, `/ci:fix` |
## Installation
```bash
# Install all plugins via marketplace
claude plugin add host-uk/core-agent
# Or install individual plugins
claude plugin add host-uk/core-agent/claude/code
claude plugin add host-uk/core-agent/claude/review
claude plugin add host-uk/core-agent/claude/qa
```
## Quick Start
```bash
# Code review staged changes
/review:review
# Run QA and fix all issues
/qa:qa
# Verify work is ready to commit
/verify:verify
# Check CI status
/ci:ci
```
## Core CLI Integration
These plugins enforce the `core` CLI for development commands:
| Instead of... | Use... |
|---------------|--------|
| `go test` | `core go test` |
| `go build` | `core build` |
| `golangci-lint` | `core go lint` |
| `composer test` | `core php test` |
| `./vendor/bin/pint` | `core php fmt` |
## Plugin Details
### code
The core plugin with hooks and data collection skills:
- **Hooks**: Auto-format, debug detection, dangerous command blocking
- **Skills**: Data collection for archiving OSS projects (whitepapers, forums, market data)
- **Commands**: `/code:remember` (persist facts), `/code:yes` (auto-approve mode)
### review
Code review automation:
- `/review:review` - Review staged changes or commit range
- `/review:security` - Security-focused review
- `/review:pr [number]` - Review a pull request
### verify
Work verification:
- `/verify:verify` - Full verification (tests, lint, format, debug check)
- `/verify:ready` - Quick check if ready to commit
### qa
Quality assurance:
- `/qa:qa` - Run QA pipeline, fix all issues iteratively
- `/qa:fix <issue>` - Fix a specific issue
- `/qa:check` - Check without fixing
### ci
CI/CD integration:
- `/ci:ci` - Check CI status
- `/ci:workflow <type>` - Generate GitHub Actions workflow
- `/ci:fix` - Analyse and fix failing CI
## Development
### Adding a new plugin
1. Create `claude/<name>/.claude-plugin/plugin.json`
2. Add commands to `claude/<name>/commands/`
3. Add hooks to `claude/<name>/hooks.json` (optional)
4. Register in `.claude-plugin/marketplace.json`
### Testing locally
```bash
claude plugin add /path/to/core-agent
```
## License
EUPL-1.2
## Links
- [Host UK](https://host.uk.com)
- [Claude Code Documentation](https://docs.anthropic.com/claude-code)
- [Issues](https://github.com/host-uk/core-agent/issues)

97
claude/ci/commands/fix.md Normal file
View file

@ -0,0 +1,97 @@
---
name: fix
description: Analyse and fix failing CI
---
# Fix CI
Analyse failing CI runs and suggest/apply fixes.
## Process
1. **Get failing run**
```bash
gh run list --status failure --limit 1
gh run view <id> --log-failed
```
2. **Analyse failure**
- Parse error messages
- Identify root cause
- Check if local issue or CI-specific
3. **Suggest fix**
- Code changes if needed
- CI config changes if needed
4. **Apply fix** (if approved)
## Common CI Failures
### Test Failures
```
Error: go test failed
--- FAIL: TestFoo
```
→ Fix the failing test locally, then push
### Lint Failures
```
Error: golangci-lint failed
file.go:42: undefined: X
```
→ Fix lint issue locally
### Build Failures
```
Error: go build failed
cannot find package
```
→ Run `go mod tidy`, check imports
### Dependency Issues
```
Error: go mod download failed
```
→ Check go.mod, clear cache, retry
### Timeout
```
Error: Job exceeded time limit
```
→ Optimise tests or increase timeout in workflow
## Output
```markdown
## CI Failure Analysis
**Run**: #12345
**Workflow**: Tests
**Failed at**: 2024-01-15 14:30
### Error
```
--- FAIL: TestCreateUser (0.02s)
handler_test.go:45: expected 200, got 500
```
### Analysis
The test expects a 200 response but gets 500. This indicates the handler is returning an error.
### Root Cause
Looking at recent changes, `ErrNotFound` was removed but still referenced.
### Fix
Add the missing error definition:
```go
var ErrNotFound = errors.New("not found")
```
### Commands
```bash
# Apply fix and push
git add . && git commit -m "fix: add missing ErrNotFound"
git push
```
```

76
claude/ci/commands/run.md Normal file
View file

@ -0,0 +1,76 @@
---
name: run
description: Trigger a CI workflow run
args: [workflow-name]
---
# Run Workflow
Manually trigger a GitHub Actions workflow.
## Usage
```
/ci:run # Run default workflow
/ci:run tests # Run specific workflow
/ci:run release # Trigger release workflow
```
## Process
1. **List available workflows**
```bash
gh workflow list
```
2. **Trigger workflow**
```bash
gh workflow run tests.yml
gh workflow run tests.yml --ref feature-branch
```
3. **Watch progress**
```bash
gh run watch
```
## Common Workflows
| Workflow | Trigger | Purpose |
|----------|---------|---------|
| `tests.yml` | Push, PR | Run test suite |
| `lint.yml` | Push, PR | Run linters |
| `build.yml` | Push | Build artifacts |
| `release.yml` | Tag | Create release |
| `deploy.yml` | Manual | Deploy to environment |
## Output
```markdown
## Workflow Triggered
**Workflow**: tests.yml
**Branch**: feature/add-auth
**Run ID**: 12345
Watching progress...
```
⠋ Tests running...
✓ Setup (12s)
✓ Install dependencies (45s)
⠋ Run tests (running)
```
**Run completed in 2m 34s** ✓
```
## Options
```bash
# Run with inputs (for workflows that accept them)
gh workflow run deploy.yml -f environment=staging
# Run on specific ref
gh workflow run tests.yml --ref main
```

View file

@ -0,0 +1,63 @@
---
name: status
description: Show CI status for current branch
---
# CI Status
Show GitHub Actions status for the current branch.
## Usage
```
/ci:status
/ci:status --all # All recent runs
/ci:status --branch X # Specific branch
```
## Commands
```bash
# Current branch status
gh run list --branch $(git branch --show-current) --limit 5
# Get details of latest run
gh run view --log-failed
# Watch running workflow
gh run watch
```
## Output
```markdown
## CI Status: feature/add-auth
| Workflow | Status | Duration | Commit | When |
|----------|--------|----------|--------|------|
| Tests | ✓ pass | 2m 34s | abc123 | 5m ago |
| Lint | ✓ pass | 45s | abc123 | 5m ago |
| Build | ✓ pass | 1m 12s | abc123 | 5m ago |
**All checks passing** ✓
---
Or if failing:
| Workflow | Status | Duration | Commit | When |
|----------|--------|----------|--------|------|
| Tests | ✗ fail | 1m 45s | abc123 | 5m ago |
| Lint | ✓ pass | 45s | abc123 | 5m ago |
| Build | - skip | - | abc123 | 5m ago |
**1 workflow failing**
### Tests Failure
```
--- FAIL: TestCreateUser
expected 200, got 500
```
Run `/ci:fix` to analyse and fix.
```

17
claude/ci/hooks.json Normal file
View file

@ -0,0 +1,17 @@
{
"$schema": "https://claude.ai/schemas/hooks.json",
"hooks": {
"PostToolUse": [
{
"matcher": "tool == \"Bash\" && tool_input.command matches \"^git push\"",
"hooks": [
{
"type": "command",
"command": "${CLAUDE_PLUGIN_ROOT}/scripts/post-push-ci.sh"
}
],
"description": "Show CI status after push"
}
]
}
}

View file

@ -0,0 +1,23 @@
#!/bin/bash
# Show CI status hint after push
read -r input
EXIT_CODE=$(echo "$input" | jq -r '.tool_response.exit_code // 0')
if [ "$EXIT_CODE" = "0" ]; then
# Check if repo has workflows
if [ -d ".github/workflows" ]; then
cat << 'EOF'
{
"hookSpecificOutput": {
"hookEventName": "PostToolUse",
"additionalContext": "Push successful. CI workflows will run shortly.\n\nRun `/ci:status` to check progress or `gh run watch` to follow live."
}
}
EOF
else
echo "$input"
fi
else
echo "$input"
fi

View file

@ -0,0 +1,74 @@
---
name: check
description: Run QA checks without fixing (report only)
args: [--go|--php|--all]
---
# QA Check
Run QA pipeline and report issues without fixing them.
## Usage
```
/qa:check # Auto-detect project type
/qa:check --go # Force Go checks
/qa:check --php # Force PHP checks
/qa:check --all # Run both if applicable
```
## Process
1. **Detect project type**
2. **Run QA pipeline**
3. **Parse and report issues**
4. **Do NOT fix anything**
## Go Checks
```bash
core go qa
```
Runs:
- `go fmt` - Formatting
- `go vet` - Static analysis
- `golangci-lint` - Linting
- `go test` - Tests
## PHP Checks
```bash
core php qa
```
Runs:
- `pint` - Formatting
- `phpstan` - Static analysis
- `pest` - Tests
## Output
```markdown
## QA Report
**Project**: Go (go.mod detected)
**Status**: 3 issues found
### Formatting
✗ 2 files need formatting
- pkg/api/handler.go
- pkg/auth/token.go
### Linting
✗ 1 issue
- pkg/api/handler.go:42 - undefined: ErrNotFound
### Tests
✓ All passing (47/47)
---
**Summary**: fmt: FAIL | lint: FAIL | test: PASS
Run `/qa:qa` to fix these issues automatically.
```

View file

@ -0,0 +1,78 @@
---
name: lint
description: Run linter and fix issues
args: [--check|--fix]
---
# Lint
Run linter and optionally fix issues.
## Usage
```
/qa:lint # Run lint, report issues
/qa:lint --check # Check only, no fixes
/qa:lint --fix # Auto-fix where possible
```
## Process
### Go
```bash
# Check
core go lint
# Some issues can be auto-fixed
golangci-lint run --fix
```
### PHP
```bash
# Check
core php stan
# PHPStan doesn't auto-fix, but can suggest fixes
```
## Common Issues
### Go
| Issue | Fix |
|-------|-----|
| `undefined: X` | Add import or define variable |
| `ineffectual assignment` | Use variable or remove |
| `unused parameter` | Use `_` prefix or remove |
| `error return value not checked` | Handle the error |
### PHP
| Issue | Fix |
|-------|-----|
| `Undefined variable` | Define or check existence |
| `Parameter $x has no type` | Add type hint |
| `Method has no return type` | Add return type |
## Output
```markdown
## Lint Results
**Linter**: golangci-lint
**Issues**: 3
### Errors
1. **pkg/api/handler.go:42** - undefined: ErrNotFound
→ Add `var ErrNotFound = errors.New("not found")`
2. **pkg/api/handler.go:87** - error return value not checked
→ Handle error: `if err != nil { return err }`
### Warnings
1. **pkg/api/handler.go:15** - unused parameter ctx
→ Rename to `_` or use it
---
Run `/qa:lint --fix` to auto-fix where possible.
```

17
claude/qa/hooks.json Normal file
View file

@ -0,0 +1,17 @@
{
"$schema": "https://claude.ai/schemas/hooks.json",
"hooks": {
"PostToolUse": [
{
"matcher": "tool == \"Bash\" && tool_input.command matches \"^core (go|php) (qa|test|lint|stan)\"",
"hooks": [
{
"type": "command",
"command": "${CLAUDE_PLUGIN_ROOT}/scripts/qa-filter.sh"
}
],
"description": "Filter QA output to show only actionable issues"
}
]
}
}

View file

@ -0,0 +1,87 @@
---
name: pr
description: Review a pull request
args: <pr-number>
---
# PR Review
Review a GitHub pull request.
## Usage
```
/review:pr 123
/review:pr 123 --security
/review:pr 123 --quick
```
## Process
1. **Fetch PR details**
```bash
gh pr view 123 --json title,body,author,files,additions,deletions
```
2. **Get PR diff**
```bash
gh pr diff 123
```
3. **Check CI status**
```bash
gh pr checks 123
```
4. **Review changes**
- Correctness
- Security (if --security)
- Tests coverage
- Documentation
5. **Provide feedback**
## Output Format
```markdown
## PR Review: #123 - Add user authentication
**Author**: @username
**Files**: 5 changed (+120, -30)
**CI**: ✓ All checks passing
### Summary
Brief description of what this PR does.
### Review
#### Approved ✓
- Clean implementation
- Good test coverage
- Documentation updated
#### Changes Requested ✗
- **src/auth.go:42** - Missing input validation
- **src/auth.go:87** - Error not handled
#### Comments
- Consider adding rate limiting
- Nice use of middleware pattern
---
**Recommendation**: Approve with minor changes
```
## Actions
After review, you can:
```bash
# Approve
gh pr review 123 --approve
# Request changes
gh pr review 123 --request-changes --body "See comments"
# Comment only
gh pr review 123 --comment --body "Looks good overall"
```

View file

@ -0,0 +1,93 @@
---
name: security
description: Security-focused code review
args: [commit-range|--pr=N]
---
# Security Review
Perform a security-focused code review.
## Focus Areas
### 1. Injection Vulnerabilities
- SQL injection
- Command injection
- XSS (Cross-Site Scripting)
- LDAP injection
- XML injection
### 2. Authentication & Authorisation
- Hardcoded credentials
- Weak password handling
- Missing auth checks
- Privilege escalation paths
### 3. Data Exposure
- Sensitive data in logs
- PII in error messages
- Secrets in version control
- Insecure data transmission
### 4. Cryptography
- Weak algorithms (MD5, SHA1 for security)
- Hardcoded keys/IVs
- Insecure random number generation
### 5. Dependencies
- Known vulnerable packages
- Outdated dependencies
## Process
1. Get diff for specified range
2. Scan for security patterns
3. Check for common vulnerabilities
4. Report findings with severity
## Patterns to Check
### Go
```go
// SQL injection
db.Query("SELECT * FROM users WHERE id = " + id)
// Command injection
exec.Command("bash", "-c", userInput)
// Hardcoded secrets
apiKey := "sk_live_..."
```
### PHP
```php
// SQL injection
$db->query("SELECT * FROM users WHERE id = $id");
// XSS
echo $request->input('name');
// Command injection
shell_exec($userInput);
```
## Output Format
```markdown
## Security Review
### Critical
- **file:line** - SQL Injection: User input directly in query
### High
- **file:line** - Hardcoded API key detected
### Medium
- **file:line** - Missing CSRF protection
### Low
- **file:line** - Debug endpoint exposed
---
**Summary**: X critical, Y high, Z medium, W low
```

17
claude/review/hooks.json Normal file
View file

@ -0,0 +1,17 @@
{
"$schema": "https://claude.ai/schemas/hooks.json",
"hooks": {
"PostToolUse": [
{
"matcher": "tool == \"Bash\" && tool_input.command matches \"^gh pr create\"",
"hooks": [
{
"type": "command",
"command": "${CLAUDE_PLUGIN_ROOT}/scripts/post-pr-create.sh"
}
],
"description": "Suggest review after PR creation"
}
]
}
}

View file

@ -0,0 +1,22 @@
#!/bin/bash
# Suggest review after PR creation
read -r input
OUTPUT=$(echo "$input" | jq -r '.tool_response.stdout // .tool_response.output // empty')
# Extract PR URL from output
PR_URL=$(echo "$OUTPUT" | grep -oE 'https://github.com/[^/]+/[^/]+/pull/[0-9]+' | head -1)
if [ -n "$PR_URL" ]; then
PR_NUM=$(echo "$PR_URL" | grep -oE '[0-9]+$')
cat << EOF
{
"hookSpecificOutput": {
"hookEventName": "PostToolUse",
"additionalContext": "PR created: $PR_URL\n\nRun \`/review:pr $PR_NUM\` to review before requesting reviewers."
}
}
EOF
else
echo "$input"
fi

View file

@ -0,0 +1,53 @@
---
name: ready
description: Quick check if work is ready to commit
---
# Ready Check
Quick verification that work is ready to commit.
## Checks
1. **No uncommitted changes left behind**
2. **No debug statements**
3. **Code is formatted**
## Process
```bash
# Check for changes
git status --porcelain
# Quick format check
core go fmt --check 2>/dev/null || core php fmt --test 2>/dev/null
```
## Output
```
## Ready Check
✓ All changes staged
✓ No debug statements
✓ Code formatted
**Ready to commit!**
```
Or:
```
## Ready Check
✗ Unstaged changes: 2 files
✓ No debug statements
✗ Formatting needed: 1 file
**Not ready** - run `/verify:verify` for details
```
## When to Use
Use `/verify:ready` for a quick check before committing.
Use `/verify:verify` for full verification including tests.

View file

@ -0,0 +1,80 @@
---
name: tests
description: Verify tests pass for changed files
---
# Test Verification
Run tests related to changed files.
## Process
1. **Identify changed files**
```bash
git diff --name-only HEAD
```
2. **Find related tests**
- Go: `*_test.go` files in same package
- PHP: `*Test.php` files in tests/ directory
3. **Run targeted tests**
```bash
# Go - run package tests
core go test ./pkg/changed/...
# PHP - run filtered tests
core php test --filter=ChangedTest
```
4. **Report results**
## Smart Test Detection
### Go
```
Changed: pkg/api/handler.go
Related: pkg/api/handler_test.go
Run: core go test ./pkg/api/...
```
### PHP
```
Changed: src/Http/UserController.php
Related: tests/Http/UserControllerTest.php
Run: core php test tests/Http/UserControllerTest.php
```
## Output
```
## Test Verification
**Changed files**: 3
**Related tests**: 2 packages
### Results
✓ pkg/api: 12 tests passed
✓ pkg/auth: 8 tests passed
**All tests passing!**
```
Or:
```
## Test Verification
**Changed files**: 3
**Related tests**: 2 packages
### Results
✓ pkg/api: 12 tests passed
✗ pkg/auth: 1 failed
### Failures
- TestValidateToken: expected true, got false
auth_test.go:45
**Fix failing tests before committing.**
```

17
claude/verify/hooks.json Normal file
View file

@ -0,0 +1,17 @@
{
"$schema": "https://claude.ai/schemas/hooks.json",
"hooks": {
"PreToolUse": [
{
"matcher": "tool == \"Bash\" && tool_input.command matches \"^git push\"",
"hooks": [
{
"type": "command",
"command": "${CLAUDE_PLUGIN_ROOT}/scripts/pre-push-check.sh"
}
],
"description": "Warn about unpushed verification before git push"
}
]
}
}

View file

@ -0,0 +1,21 @@
#!/bin/bash
# Remind about verification before push
read -r input
# Check if tests were run recently (within last 5 minutes)
LAST_TEST=$(find . -name "*.test" -mmin -5 2>/dev/null | head -1)
LAST_COVERAGE=$(find . -name "coverage.*" -mmin -5 2>/dev/null | head -1)
if [ -z "$LAST_TEST" ] && [ -z "$LAST_COVERAGE" ]; then
cat << 'EOF'
{
"hookSpecificOutput": {
"hookEventName": "PreToolUse",
"additionalContext": "⚠️ No recent test run detected. Consider running `/verify:verify` before pushing."
}
}
EOF
else
echo "$input"
fi