feat(agent/plugins): create plugins/{core-go,core-php,infra} tree (RFC.plugin-restructure §1+§2)
plugins/ subtree created from scratch (no dappcore-go/dappcore-php
existed to rename). Per docs/RFC-AGENT-PLUGIN-RESTRUCTURE.md:
plugins/core-go/:
- .claude-plugin/plugin.json (name: core-go)
- README.md, marketplace.yaml, .mcp.json (calls core mcp serve)
- commands/{commit,qa,review,verify}.md
- skills/{core,core-go,go-agent}/SKILL.md (seeded from existing repo material)
- skills/api-endpoints/SKILL.md (NEW per ticket)
- agents/go-developer.md
- hook scripts referenced by commands
plugins/core-php/: same structure, php-developer agent + php-specific
api-endpoints skill.
plugins/infra/: plugin.json, README.md, marketplace.yaml, agents/infra-ops.md.
Manifests use core-* not dappcore-*. .mcp.json files call core mcp serve.
No dappcore-* names left.
Note: seed skills copied from existing repo material per ticket spec —
some upstream Host UK examples remain in copied skill docs. Future PR
can purge those if Host UK references are out of scope for the public
plugin marketplace.
Co-authored-by: Codex <noreply@openai.com>
Closes tasks.lthn.sh/view.php?id=234
This commit is contained in:
parent
fbee790859
commit
55bc34c885
36 changed files with 2468 additions and 0 deletions
18
plugins/core-go/.claude-plugin/plugin.json
Normal file
18
plugins/core-go/.claude-plugin/plugin.json
Normal file
|
|
@ -0,0 +1,18 @@
|
|||
{
|
||||
"name": "core-go",
|
||||
"version": "0.1.0",
|
||||
"description": "Claude plugin family for Core Go services, libraries, and tooling.",
|
||||
"author": {
|
||||
"name": "Lethean Community",
|
||||
"email": "hello@lethean.io"
|
||||
},
|
||||
"homepage": "https://lthn.ai",
|
||||
"repository": "https://forge.lthn.ai/core/agent.git",
|
||||
"license": "EUPL-1.2",
|
||||
"keywords": [
|
||||
"claude",
|
||||
"core",
|
||||
"go",
|
||||
"agent"
|
||||
]
|
||||
}
|
||||
9
plugins/core-go/.mcp.json
Normal file
9
plugins/core-go/.mcp.json
Normal file
|
|
@ -0,0 +1,9 @@
|
|||
{
|
||||
"mcpServers": {
|
||||
"core": {
|
||||
"type": "stdio",
|
||||
"command": "core",
|
||||
"args": ["mcp", "serve"]
|
||||
}
|
||||
}
|
||||
}
|
||||
6
plugins/core-go/README.md
Normal file
6
plugins/core-go/README.md
Normal file
|
|
@ -0,0 +1,6 @@
|
|||
# core-go
|
||||
This plugin family covers Claude workflows for Core Go services and shared libraries.
|
||||
It is the canonical home for Go-focused commands, agents, and skills in the Core ecosystem.
|
||||
The scope includes service scaffolding, package conventions, QA, verification, and release support.
|
||||
Marketplace metadata for this family is defined in `marketplace.yaml`.
|
||||
Commands, agents, and skills here are seeded from the existing Claude and Codex plugin material in this repository.
|
||||
24
plugins/core-go/agents/go-developer.md
Normal file
24
plugins/core-go/agents/go-developer.md
Normal file
|
|
@ -0,0 +1,24 @@
|
|||
---
|
||||
name: go-developer
|
||||
description: Go development agent for Core services and libraries. Derived from the existing core-go and go-agent skills.
|
||||
tools: Bash, Read, Edit, MultiEdit, Grep, Glob, LS
|
||||
model: sonnet
|
||||
color: green
|
||||
---
|
||||
|
||||
You are a Go developer working in the Core ecosystem.
|
||||
|
||||
## Working rules
|
||||
|
||||
- Follow the package and CLI conventions in `skills/core/SKILL.md` and `skills/core-go/SKILL.md`.
|
||||
- Use the delivery loop in `skills/go-agent/SKILL.md` when the task requires autonomous implementation.
|
||||
- Prefer `core go test`, `core go lint`, `core go fmt`, and `core build` over raw toolchain commands when the wrapper exists.
|
||||
- Keep user-facing strings in UK English.
|
||||
- Use the Good/Bad/Ugly test naming pattern described by the existing Go skill.
|
||||
|
||||
## Delivery standard
|
||||
|
||||
1. Read the package structure before adding new code.
|
||||
2. Keep changes small, typed, and test-backed.
|
||||
3. Fix the root cause, not just the failing symptom.
|
||||
4. Run QA and verification before stopping.
|
||||
52
plugins/core-go/commands/commit.md
Normal file
52
plugins/core-go/commands/commit.md
Normal file
|
|
@ -0,0 +1,52 @@
|
|||
---
|
||||
name: commit
|
||||
description: Generate a conventional commit message for staged changes
|
||||
args: "[message]"
|
||||
flags:
|
||||
- --amend
|
||||
hooks:
|
||||
Before:
|
||||
- hooks:
|
||||
- type: command
|
||||
command: "${CLAUDE_PLUGIN_ROOT}/scripts/smart-commit.sh"
|
||||
---
|
||||
|
||||
# Smart Commit
|
||||
|
||||
Generate a conventional commit message for staged changes.
|
||||
|
||||
## Usage
|
||||
|
||||
Generate message automatically:
|
||||
`/core-go:commit`
|
||||
|
||||
Provide a custom message:
|
||||
`/core-go:commit "feat(auth): add token validation"`
|
||||
|
||||
Amend the previous commit:
|
||||
`/core-go:commit --amend`
|
||||
|
||||
## Behavior
|
||||
|
||||
1. **Analyze Staged Changes**: Examines the `git diff --staged` to understand the nature of the changes.
|
||||
2. **Generate Conventional Commit Message**:
|
||||
- `feat`: For new files, functions, or features.
|
||||
- `fix`: For bug fixes.
|
||||
- `refactor`: For code restructuring without changing external behavior.
|
||||
- `docs`: For changes to documentation.
|
||||
- `test`: For adding or modifying tests.
|
||||
- `chore`: For routine maintenance tasks.
|
||||
3. **Determine Scope**: Infers the scope from the affected module's file paths (e.g., `auth`, `payment`, `ui`).
|
||||
4. **Add Co-Authored-By Trailer**: Appends `Co-Authored-By: Claude <noreply@anthropic.com>` to the commit message.
|
||||
|
||||
## Message Generation Example
|
||||
|
||||
```
|
||||
feat(auth): add JWT token validation
|
||||
|
||||
- Add validateToken() function
|
||||
- Add token expiry check
|
||||
- Add unit tests for validation
|
||||
|
||||
Co-Authored-By: Claude <noreply@anthropic.com>
|
||||
```
|
||||
128
plugins/core-go/commands/qa.md
Normal file
128
plugins/core-go/commands/qa.md
Normal file
|
|
@ -0,0 +1,128 @@
|
|||
---
|
||||
name: qa
|
||||
description: Run Go QA checks and fix all issues iteratively
|
||||
hooks:
|
||||
PostToolUse:
|
||||
- matcher: "Bash"
|
||||
hooks:
|
||||
- type: command
|
||||
command: "${CLAUDE_PLUGIN_ROOT}/scripts/qa-filter.sh"
|
||||
Stop:
|
||||
- hooks:
|
||||
- type: command
|
||||
command: "${CLAUDE_PLUGIN_ROOT}/scripts/qa-verify.sh"
|
||||
once: true
|
||||
---
|
||||
|
||||
# QA Fix Loop
|
||||
|
||||
Run the full Go QA pipeline and fix all issues.
|
||||
|
||||
## Process
|
||||
|
||||
1. **Run QA**: Execute `core go qa`
|
||||
2. **Parse issues**: Extract failures from output (see format below)
|
||||
3. **Fix each issue**: Address one at a time, simplest first
|
||||
4. **Re-verify**: After fixes, re-run QA
|
||||
5. **Repeat**: Until all checks pass
|
||||
6. **Report**: Summary of what was fixed
|
||||
|
||||
## Issue Priority
|
||||
|
||||
Fix in this order (fastest feedback first):
|
||||
1. **fmt** - formatting issues (auto-fix with `core go fmt`)
|
||||
2. **lint** - static analysis (usually quick fixes)
|
||||
3. **test** - failing tests (may need more investigation)
|
||||
4. **build** - compilation errors (fix before tests can run)
|
||||
|
||||
## Output Parsing
|
||||
|
||||
### Go QA Output
|
||||
```
|
||||
=== FMT ===
|
||||
FAIL: pkg/api/handler.go needs formatting
|
||||
|
||||
=== LINT ===
|
||||
pkg/api/handler.go:42:15: undefined: ErrNotFound (typecheck)
|
||||
pkg/api/handler.go:87:2: ineffectual assignment to err (ineffassign)
|
||||
|
||||
=== TEST ===
|
||||
--- FAIL: TestCreateUser (0.02s)
|
||||
handler_test.go:45: expected 200, got 500
|
||||
FAIL
|
||||
|
||||
=== RESULT ===
|
||||
fmt: FAIL
|
||||
lint: FAIL (2 issues)
|
||||
test: FAIL (1 failed)
|
||||
```
|
||||
|
||||
## Fixing Strategy
|
||||
|
||||
**Formatting (fmt):**
|
||||
- Just run `core go fmt`
|
||||
- No code reading needed
|
||||
|
||||
**Lint errors:**
|
||||
- Read the specific file:line
|
||||
- Understand the error type
|
||||
- Make minimal fix
|
||||
|
||||
**Test failures:**
|
||||
- Read the test file to understand expectation
|
||||
- Read the implementation
|
||||
- Fix the root cause (not just the symptom)
|
||||
|
||||
**Build errors:**
|
||||
- Usually missing imports or typos
|
||||
- Fix before attempting other checks
|
||||
|
||||
## Stop Condition
|
||||
|
||||
Only stop when:
|
||||
- All QA checks pass, OR
|
||||
- User explicitly cancels, OR
|
||||
- Same error repeats 3 times (stuck - ask for help)
|
||||
|
||||
## Example Session
|
||||
|
||||
```
|
||||
Running: core go qa
|
||||
|
||||
## QA Issues
|
||||
|
||||
pkg/api/handler.go:42:15: undefined: ErrNotFound
|
||||
--- FAIL: TestCreateUser (0.02s)
|
||||
|
||||
**Summary:** lint: FAIL (1) | test: FAIL (1)
|
||||
|
||||
---
|
||||
|
||||
Fixing lint issue: undefined ErrNotFound
|
||||
Reading pkg/api/handler.go...
|
||||
Adding error variable definition.
|
||||
|
||||
Running: core go qa
|
||||
|
||||
## QA Issues
|
||||
|
||||
--- FAIL: TestCreateUser (0.02s)
|
||||
expected 200, got 404
|
||||
|
||||
**Summary:** lint: PASS | test: FAIL (1)
|
||||
|
||||
---
|
||||
|
||||
Fixing test issue: expected 200, got 404
|
||||
Reading test setup...
|
||||
Correcting test data.
|
||||
|
||||
Running: core go qa
|
||||
|
||||
✓ All checks passed!
|
||||
|
||||
**Summary:**
|
||||
- Fixed: undefined ErrNotFound (added error variable)
|
||||
- Fixed: TestCreateUser (corrected test setup)
|
||||
- 2 issues resolved, all checks passing
|
||||
```
|
||||
63
plugins/core-go/commands/review.md
Normal file
63
plugins/core-go/commands/review.md
Normal file
|
|
@ -0,0 +1,63 @@
|
|||
---
|
||||
name: review
|
||||
description: Perform code review on staged changes or PRs
|
||||
args: [commit-range|--pr=N|--security]
|
||||
---
|
||||
|
||||
# Code Review
|
||||
|
||||
Perform a thorough code review of the specified changes.
|
||||
|
||||
## Arguments
|
||||
|
||||
- No args: Review staged changes
|
||||
- `HEAD~3..HEAD`: Review last 3 commits
|
||||
- `--pr=123`: Review PR #123
|
||||
- `--security`: Focus on security issues
|
||||
|
||||
## Process
|
||||
|
||||
1. **Gather changes**: Get diff for the specified range
|
||||
2. **Analyse each file**: Review for issues by category
|
||||
3. **Report findings**: Output structured review
|
||||
|
||||
## Review Checklist
|
||||
|
||||
| Category | Checks |
|
||||
|----------|--------|
|
||||
| **Correctness** | Logic errors, edge cases, error handling |
|
||||
| **Security** | SQL injection, XSS, hardcoded secrets, CSRF |
|
||||
| **Performance** | N+1 queries, unnecessary loops, large allocations |
|
||||
| **Maintainability** | Naming, structure, complexity |
|
||||
| **Tests** | Coverage gaps, missing assertions |
|
||||
|
||||
## Output Format
|
||||
|
||||
```markdown
|
||||
## Code Review: [title]
|
||||
|
||||
### Critical
|
||||
- **file:line** - Issue description
|
||||
|
||||
### Warning
|
||||
- **file:line** - Issue description
|
||||
|
||||
### Suggestions
|
||||
- **file:line** - Improvement idea
|
||||
|
||||
---
|
||||
**Summary**: X critical, Y warnings, Z suggestions
|
||||
```
|
||||
|
||||
## Commands
|
||||
|
||||
```bash
|
||||
# Get staged diff
|
||||
git diff --cached
|
||||
|
||||
# Get PR diff
|
||||
gh pr diff 123
|
||||
|
||||
# Get commit range diff
|
||||
git diff HEAD~3..HEAD
|
||||
```
|
||||
75
plugins/core-go/commands/verify.md
Normal file
75
plugins/core-go/commands/verify.md
Normal file
|
|
@ -0,0 +1,75 @@
|
|||
---
|
||||
name: verify
|
||||
description: Verify work is complete before stopping
|
||||
args: [--quick|--full]
|
||||
---
|
||||
|
||||
# Work Verification
|
||||
|
||||
Verify that Go work is complete and ready to commit/push.
|
||||
|
||||
## Arguments
|
||||
|
||||
- No args: Standard verification
|
||||
- `--quick`: Fast checks only (format, lint)
|
||||
- `--full`: All checks including slow tests
|
||||
|
||||
## Verification Steps
|
||||
|
||||
### 1. Check for uncommitted changes
|
||||
```bash
|
||||
git status --porcelain
|
||||
```
|
||||
|
||||
### 2. Check for debug statements
|
||||
Look for:
|
||||
- Go: `fmt.Println`, `log.Println`, `spew.Dump`
|
||||
- PHP: `dd(`, `dump(`, `var_dump(`, `ray(`
|
||||
- JS/TS: `console.log`, `debugger`
|
||||
|
||||
### 3. Run tests
|
||||
```bash
|
||||
core go test
|
||||
```
|
||||
|
||||
### 4. Run linter
|
||||
```bash
|
||||
core go lint
|
||||
```
|
||||
|
||||
### 5. Check formatting
|
||||
```bash
|
||||
core go fmt --check
|
||||
```
|
||||
|
||||
## Output
|
||||
|
||||
Report verification status:
|
||||
|
||||
```
|
||||
## Verification Results
|
||||
|
||||
✓ No uncommitted changes
|
||||
✓ No debug statements found
|
||||
✓ Tests passing (47/47)
|
||||
✓ Lint clean
|
||||
✓ Formatting correct
|
||||
|
||||
**Status: READY**
|
||||
```
|
||||
|
||||
Or if issues found:
|
||||
|
||||
```
|
||||
## Verification Results
|
||||
|
||||
✓ No uncommitted changes
|
||||
✗ Debug statement found: src/handler.go:42
|
||||
✗ Tests failing (45/47)
|
||||
✓ Lint clean
|
||||
✓ Formatting correct
|
||||
|
||||
**Status: NOT READY**
|
||||
|
||||
Fix these issues before proceeding.
|
||||
```
|
||||
6
plugins/core-go/marketplace.yaml
Normal file
6
plugins/core-go/marketplace.yaml
Normal file
|
|
@ -0,0 +1,6 @@
|
|||
marketplace:
|
||||
registry: forge.lthn.ai
|
||||
organization: core
|
||||
repository: core-go
|
||||
auto_update: true
|
||||
check_interval: 24h
|
||||
62
plugins/core-go/scripts/qa-filter.sh
Executable file
62
plugins/core-go/scripts/qa-filter.sh
Executable file
|
|
@ -0,0 +1,62 @@
|
|||
#!/bin/bash
|
||||
# Filter QA output to show only actionable issues during /core:qa mode
|
||||
#
|
||||
# PostToolUse hook that processes QA command output and extracts
|
||||
# only the failures, hiding verbose success output.
|
||||
|
||||
read -r input
|
||||
COMMAND=$(echo "$input" | jq -r '.tool_input.command // empty')
|
||||
OUTPUT=$(echo "$input" | jq -r '.tool_response.stdout // .tool_response.output // empty')
|
||||
EXIT_CODE=$(echo "$input" | jq -r '.tool_response.exit_code // 0')
|
||||
|
||||
# Only process QA-related commands
|
||||
case "$COMMAND" in
|
||||
"core go qa"*|"core php qa"*|"core go test"*|"core php test"*|"core go lint"*|"core php stan"*)
|
||||
;;
|
||||
*)
|
||||
# Not a QA command, pass through unchanged
|
||||
echo "$input"
|
||||
exit 0
|
||||
;;
|
||||
esac
|
||||
|
||||
# Extract failures from output
|
||||
FAILURES=$(echo "$OUTPUT" | grep -E "^(FAIL|---\s*FAIL|✗|ERROR|undefined:|error:|panic:)" | head -20)
|
||||
SUMMARY=$(echo "$OUTPUT" | grep -E "^(fmt:|lint:|test:|pint:|stan:|=== RESULT ===)" | tail -5)
|
||||
|
||||
# Also grab specific error lines with file:line references
|
||||
FILE_ERRORS=$(echo "$OUTPUT" | grep -E "^[a-zA-Z0-9_/.-]+\.(go|php):[0-9]+:" | head -10)
|
||||
|
||||
if [ -z "$FAILURES" ] && [ "$EXIT_CODE" = "0" ]; then
|
||||
# All passed - show brief confirmation
|
||||
cat << 'EOF'
|
||||
{
|
||||
"suppressOutput": true,
|
||||
"hookSpecificOutput": {
|
||||
"hookEventName": "PostToolUse",
|
||||
"additionalContext": "✓ QA passed"
|
||||
}
|
||||
}
|
||||
EOF
|
||||
else
|
||||
# Combine failures and file errors
|
||||
ISSUES="$FAILURES"
|
||||
if [ -n "$FILE_ERRORS" ]; then
|
||||
ISSUES="$ISSUES
|
||||
$FILE_ERRORS"
|
||||
fi
|
||||
|
||||
# Escape for JSON
|
||||
ISSUES_ESCAPED=$(echo "$ISSUES" | sed 's/\\/\\\\/g' | sed 's/"/\\"/g' | sed ':a;N;$!ba;s/\n/\\n/g')
|
||||
SUMMARY_ESCAPED=$(echo "$SUMMARY" | sed 's/\\/\\\\/g' | sed 's/"/\\"/g' | sed ':a;N;$!ba;s/\n/ | /g')
|
||||
|
||||
cat << EOF
|
||||
{
|
||||
"suppressOutput": true,
|
||||
"hookSpecificOutput": {
|
||||
"hookEventName": "PostToolUse",
|
||||
"additionalContext": "## QA Issues\n\n\`\`\`\n$ISSUES_ESCAPED\n\`\`\`\n\n**Summary:** $SUMMARY_ESCAPED"
|
||||
}
|
||||
}
|
||||
EOF
|
||||
fi
|
||||
28
plugins/core-go/scripts/qa-verify.sh
Executable file
28
plugins/core-go/scripts/qa-verify.sh
Executable file
|
|
@ -0,0 +1,28 @@
|
|||
#!/bin/bash
|
||||
# Verify QA passes before stopping during /core-go:qa mode.
|
||||
|
||||
read -r input
|
||||
STOP_ACTIVE=$(echo "$input" | jq -r '.stop_hook_active // false')
|
||||
|
||||
# Prevent infinite loop
|
||||
if [ "$STOP_ACTIVE" = "true" ]; then
|
||||
exit 0
|
||||
fi
|
||||
|
||||
# Run Go QA for this plugin family.
|
||||
RESULT=$(core go qa 2>&1) || true
|
||||
|
||||
# Check if QA passed
|
||||
if echo "$RESULT" | grep -qE "FAIL|ERROR|✗|panic:|undefined:"; then
|
||||
ISSUES=$(echo "$RESULT" | grep -E "^(FAIL|ERROR|✗|undefined:|panic:)|^[a-zA-Z0-9_/.-]+\.go:[0-9]+:" | head -5)
|
||||
ISSUES_ESCAPED=$(echo "$ISSUES" | sed 's/\\/\\\\/g' | sed 's/"/\\"/g' | sed ':a;N;$!ba;s/\n/\\n/g')
|
||||
|
||||
cat << EOF
|
||||
{
|
||||
"decision": "block",
|
||||
"reason": "QA still has issues:\n\n$ISSUES_ESCAPED\n\nPlease fix these before stopping."
|
||||
}
|
||||
EOF
|
||||
else
|
||||
exit 0
|
||||
fi
|
||||
108
plugins/core-go/scripts/smart-commit.sh
Executable file
108
plugins/core-go/scripts/smart-commit.sh
Executable file
|
|
@ -0,0 +1,108 @@
|
|||
#!/bin/bash
|
||||
# Smart commit script for /core:commit command
|
||||
|
||||
CUSTOM_MESSAGE=""
|
||||
AMEND_FLAG=""
|
||||
|
||||
# Parse arguments
|
||||
while (( "$#" )); do
|
||||
case "$1" in
|
||||
--amend)
|
||||
AMEND_FLAG="--amend"
|
||||
shift
|
||||
;;
|
||||
-*)
|
||||
echo "Unsupported flag $1" >&2
|
||||
exit 1
|
||||
;;
|
||||
*)
|
||||
# The rest of the arguments are treated as the commit message
|
||||
CUSTOM_MESSAGE="$@"
|
||||
break
|
||||
;;
|
||||
esac
|
||||
done
|
||||
|
||||
# Get staged changes
|
||||
STAGED_FILES=$(git diff --staged --name-status)
|
||||
|
||||
if [ -z "$STAGED_FILES" ]; then
|
||||
echo "No staged changes to commit."
|
||||
exit 0
|
||||
fi
|
||||
|
||||
# Determine commit type and scope
|
||||
COMMIT_TYPE="chore" # Default to chore
|
||||
SCOPE=""
|
||||
|
||||
# Get just the file paths
|
||||
STAGED_FILE_PATHS=$(git diff --staged --name-only)
|
||||
|
||||
# Determine type from file paths/status
|
||||
# Order is important here: test and docs are more specific than feat.
|
||||
if echo "$STAGED_FILE_PATHS" | grep -q -E "(_test\.go|\.test\.js|/tests/|/spec/)"; then
|
||||
COMMIT_TYPE="test"
|
||||
elif echo "$STAGED_FILE_PATHS" | grep -q -E "(\.md|/docs/|README)"; then
|
||||
COMMIT_TYPE="docs"
|
||||
elif echo "$STAGED_FILES" | grep -q "^A"; then
|
||||
COMMIT_TYPE="feat"
|
||||
elif git diff --staged | grep -q -E "^\+.*(fix|bug|issue)"; then
|
||||
COMMIT_TYPE="fix"
|
||||
elif git diff --staged | grep -q -E "^\+.*(refactor|restructure)"; then
|
||||
COMMIT_TYPE="refactor"
|
||||
fi
|
||||
|
||||
# Determine scope from the most common path component
|
||||
if [ -n "$STAGED_FILE_PATHS" ]; then
|
||||
# Extract the second component of each path (e.g., 'code' from 'claude/code/file.md')
|
||||
# This is a decent heuristic for module name.
|
||||
# We filter for lines that have a second component.
|
||||
POSSIBLE_SCOPES=$(echo "$STAGED_FILE_PATHS" | grep '/' | cut -d/ -f2)
|
||||
|
||||
if [ -n "$POSSIBLE_SCOPES" ]; then
|
||||
SCOPE=$(echo "$POSSIBLE_SCOPES" | sort | uniq -c | sort -nr | head -n 1 | awk '{print $2}')
|
||||
fi
|
||||
# If no scope is found (e.g., all files are in root), SCOPE remains empty, which is valid.
|
||||
fi
|
||||
|
||||
# Construct the commit message
|
||||
if [ -n "$CUSTOM_MESSAGE" ]; then
|
||||
COMMIT_MESSAGE="$CUSTOM_MESSAGE"
|
||||
else
|
||||
# Auto-generate a descriptive summary
|
||||
DIFF_CONTENT=$(git diff --staged)
|
||||
# Try to find a function or class name from the diff
|
||||
# This is a simple heuristic that can be greatly expanded.
|
||||
SUMMARY=$(echo "$DIFF_CONTENT" | grep -E -o "(function|class|def) \w+" | head -n 1 | sed -e 's/function //g' -e 's/class //g' -e 's/def //g')
|
||||
|
||||
if [ -z "$SUMMARY" ]; then
|
||||
if [ $(echo "$STAGED_FILE_PATHS" | wc -l) -eq 1 ]; then
|
||||
FIRST_FILE=$(echo "$STAGED_FILE_PATHS" | head -n 1)
|
||||
SUMMARY="update $(basename "$FIRST_FILE")"
|
||||
else
|
||||
SUMMARY="update multiple files"
|
||||
fi
|
||||
else
|
||||
SUMMARY="update $SUMMARY"
|
||||
fi
|
||||
|
||||
SUBJECT="$COMMIT_TYPE($SCOPE): $SUMMARY"
|
||||
BODY=$(echo "$DIFF_CONTENT" | grep -E "^\+" | sed -e 's/^+//' | head -n 5 | sed 's/^/ - /')
|
||||
COMMIT_MESSAGE="$SUBJECT\n\n$BODY"
|
||||
fi
|
||||
|
||||
# Add Co-Authored-By trailer
|
||||
CO_AUTHOR="Co-Authored-By: Claude <noreply@anthropic.com>"
|
||||
if ! echo "$COMMIT_MESSAGE" | grep -q "$CO_AUTHOR"; then
|
||||
COMMIT_MESSAGE="$COMMIT_MESSAGE\n\n$CO_AUTHOR"
|
||||
fi
|
||||
|
||||
# Execute the commit
|
||||
git commit $AMEND_FLAG -m "$(echo -e "$COMMIT_MESSAGE")"
|
||||
|
||||
if [ $? -eq 0 ]; then
|
||||
echo "Commit successful."
|
||||
else
|
||||
echo "Commit failed."
|
||||
exit 1
|
||||
fi
|
||||
63
plugins/core-go/skills/api-endpoints/SKILL.md
Normal file
63
plugins/core-go/skills/api-endpoints/SKILL.md
Normal file
|
|
@ -0,0 +1,63 @@
|
|||
---
|
||||
name: api-endpoints
|
||||
description: Use when a Core plugin needs to call api.lthn.sh or mcp.lthn.sh. Documents the JSON headers, auth, and endpoint conventions required by the plugin restructure RFC.
|
||||
---
|
||||
|
||||
# API and MCP Endpoints
|
||||
|
||||
Use this skill when a command, script, or tool talks to the shared Core endpoints.
|
||||
|
||||
## Canonical endpoints
|
||||
|
||||
- `https://api.lthn.sh` — REST API
|
||||
- `https://mcp.lthn.sh` — MCP bridge endpoint
|
||||
|
||||
These conventions apply to both production and self-hosted `lthn.sh` installs.
|
||||
|
||||
## Required headers
|
||||
|
||||
- Send `Accept: application/json` on every API request. The default response may be HTML if this header is missing.
|
||||
- Send `Content-Type: application/json` for JSON request bodies.
|
||||
- Send `Authorization: Bearer <token>` for authenticated requests.
|
||||
|
||||
## REST shape
|
||||
|
||||
- Use `/v1/{resource}` paths.
|
||||
- Expect JSON request and response bodies.
|
||||
- Keep request payloads explicit and small.
|
||||
|
||||
Example:
|
||||
|
||||
```bash
|
||||
curl -s https://api.lthn.sh/v1/issues \
|
||||
-H 'Accept: application/json' \
|
||||
-H "Authorization: Bearer ${TOKEN}"
|
||||
```
|
||||
|
||||
```bash
|
||||
curl -s https://api.lthn.sh/v1/brain/recall \
|
||||
-X POST \
|
||||
-H 'Accept: application/json' \
|
||||
-H 'Content-Type: application/json' \
|
||||
-H "Authorization: Bearer ${TOKEN}" \
|
||||
-d '{"query":"dispatch status","top_k":3}'
|
||||
```
|
||||
|
||||
## MCP usage
|
||||
|
||||
- Remote MCP can be reached at `https://mcp.lthn.sh`.
|
||||
- Local plugin configs in this repository use `core mcp serve` through `.mcp.json`.
|
||||
|
||||
Local `.mcp.json` pattern:
|
||||
|
||||
```json
|
||||
{
|
||||
"mcpServers": {
|
||||
"core": {
|
||||
"type": "stdio",
|
||||
"command": "core",
|
||||
"args": ["mcp", "serve"]
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
107
plugins/core-go/skills/core-go/SKILL.md
Normal file
107
plugins/core-go/skills/core-go/SKILL.md
Normal file
|
|
@ -0,0 +1,107 @@
|
|||
---
|
||||
name: core-go
|
||||
description: Use when creating Go packages or extending the core CLI.
|
||||
---
|
||||
|
||||
# Go Framework Patterns
|
||||
|
||||
Core CLI uses `pkg/` for reusable packages. Use `core go` commands.
|
||||
|
||||
## Package Structure
|
||||
|
||||
```
|
||||
core/
|
||||
├── main.go # CLI entry point
|
||||
├── pkg/
|
||||
│ ├── cli/ # CLI framework, output, errors
|
||||
│ ├── {domain}/ # Domain package
|
||||
│ │ ├── cmd_{name}.go # Cobra command definitions
|
||||
│ │ ├── service.go # Business logic
|
||||
│ │ └── *_test.go # Tests
|
||||
│ └── ...
|
||||
└── internal/ # Private packages
|
||||
```
|
||||
|
||||
## Adding a CLI Command
|
||||
|
||||
1. Create `pkg/{domain}/cmd_{name}.go`:
|
||||
|
||||
```go
|
||||
package domain
|
||||
|
||||
import (
|
||||
"github.com/host-uk/core/pkg/cli"
|
||||
"github.com/spf13/cobra"
|
||||
)
|
||||
|
||||
func NewNameCmd() *cobra.Command {
|
||||
cmd := &cobra.Command{
|
||||
Use: "name",
|
||||
Short: cli.T("domain.name.short"),
|
||||
RunE: func(cmd *cobra.Command, args []string) error {
|
||||
// Implementation
|
||||
cli.Success("Done")
|
||||
return nil
|
||||
},
|
||||
}
|
||||
return cmd
|
||||
}
|
||||
```
|
||||
|
||||
2. Register in parent command.
|
||||
|
||||
## CLI Output Helpers
|
||||
|
||||
```go
|
||||
import "github.com/host-uk/core/pkg/cli"
|
||||
|
||||
cli.Success("Operation completed") // Green check
|
||||
cli.Warning("Something to note") // Yellow warning
|
||||
cli.Error("Something failed") // Red error
|
||||
cli.Info("Informational message") // Blue info
|
||||
cli.Fatal(err) // Print error and exit 1
|
||||
|
||||
// Structured output
|
||||
cli.Table(headers, rows)
|
||||
cli.JSON(data)
|
||||
```
|
||||
|
||||
## i18n Pattern
|
||||
|
||||
```go
|
||||
// Use cli.T() for translatable strings
|
||||
cli.T("domain.action.success")
|
||||
cli.T("domain.action.error", "details", value)
|
||||
|
||||
// Define in pkg/i18n/locales/en.yaml:
|
||||
domain:
|
||||
action:
|
||||
success: "Operation completed successfully"
|
||||
error: "Failed: {{.details}}"
|
||||
```
|
||||
|
||||
## Test Naming
|
||||
|
||||
```go
|
||||
func TestFeature_Good(t *testing.T) { /* happy path */ }
|
||||
func TestFeature_Bad(t *testing.T) { /* expected errors */ }
|
||||
func TestFeature_Ugly(t *testing.T) { /* panics, edge cases */ }
|
||||
```
|
||||
|
||||
## Commands
|
||||
|
||||
| Task | Command |
|
||||
|------|---------|
|
||||
| Run tests | `core go test` |
|
||||
| Coverage | `core go cov` |
|
||||
| Format | `core go fmt --fix` |
|
||||
| Lint | `core go lint` |
|
||||
| Build | `core build` |
|
||||
| Install | `core go install` |
|
||||
|
||||
## Rules
|
||||
|
||||
- `CGO_ENABLED=0` for all builds
|
||||
- UK English in user-facing strings
|
||||
- All errors via `cli.E("context", "message", err)`
|
||||
- Table-driven tests preferred
|
||||
73
plugins/core-go/skills/core/SKILL.md
Normal file
73
plugins/core-go/skills/core/SKILL.md
Normal file
|
|
@ -0,0 +1,73 @@
|
|||
---
|
||||
name: core
|
||||
description: Use when working in host-uk repositories, running tests, building, releasing, or managing multi-repo workflows. Provides the core CLI command reference.
|
||||
---
|
||||
|
||||
# Core CLI
|
||||
|
||||
The `core` command provides a unified interface for Go/PHP development and multi-repo management.
|
||||
|
||||
**Rule:** Always prefer `core <command>` over raw commands.
|
||||
|
||||
## Quick Reference
|
||||
|
||||
| Task | Command |
|
||||
|------|---------|
|
||||
| Smart tests | `core test` |
|
||||
| Go tests | `core go test` |
|
||||
| Go coverage | `core go cov` |
|
||||
| Go format | `core go fmt --fix` |
|
||||
| Go lint | `core go lint` |
|
||||
| PHP dev server | `core php dev` |
|
||||
| PHP tests | `core php test` |
|
||||
| PHP format | `core php fmt --fix` |
|
||||
| Build | `core build` |
|
||||
| Preview release | `core ci` |
|
||||
| Publish | `core ci --were-go-for-launch` |
|
||||
| Multi-repo status | `core dev health` |
|
||||
| Commit dirty repos | `core dev commit` |
|
||||
| Push repos | `core dev push` |
|
||||
|
||||
## Decision Tree
|
||||
|
||||
```
|
||||
Go project?
|
||||
tests: core go test
|
||||
format: core go fmt --fix
|
||||
build: core build
|
||||
|
||||
PHP project?
|
||||
dev: core php dev
|
||||
tests: core php test
|
||||
format: core php fmt --fix
|
||||
deploy: core php deploy
|
||||
|
||||
Multiple repos?
|
||||
status: core dev health
|
||||
commit: core dev commit
|
||||
push: core dev push
|
||||
```
|
||||
|
||||
## Common Mistakes
|
||||
|
||||
| Wrong | Right |
|
||||
|-------|-------|
|
||||
| `go test ./...` | `core go test` |
|
||||
| `go build` | `core build` |
|
||||
| `php artisan serve` | `core php dev` |
|
||||
| `./vendor/bin/pest` | `core php test` |
|
||||
| `git status` per repo | `core dev health` |
|
||||
|
||||
Run `core --help` or `core <cmd> --help` for full options.
|
||||
|
||||
## Smart Test Runner: `core test`
|
||||
|
||||
The `core test` command provides an intelligent way to run only the tests relevant to your recent changes.
|
||||
|
||||
- **`core test`**: Automatically detects changed files since the last commit and runs only the corresponding tests.
|
||||
- **`core test --all`**: Runs the entire test suite for the project.
|
||||
- **`core test --filter <TestName>`**: Runs a specific test by name.
|
||||
- **`core test --coverage`**: Generates a test coverage report.
|
||||
- **`core test <path/to/file>`**: Runs tests for a specific file or directory.
|
||||
|
||||
The runner automatically detects whether the project is Go or PHP and executes the appropriate testing tool. If it cannot map changed files to test files, it will fall back to running the full test suite.
|
||||
420
plugins/core-go/skills/go-agent/SKILL.md
Normal file
420
plugins/core-go/skills/go-agent/SKILL.md
Normal file
|
|
@ -0,0 +1,420 @@
|
|||
---
|
||||
name: go-agent
|
||||
description: Autonomous Go development agent - picks up issues, implements, handles reviews, merges
|
||||
---
|
||||
|
||||
# Go Agent Skill
|
||||
|
||||
You are an autonomous Go development agent working on the Host UK Go projects (primarily the `core` CLI). You continuously pick up issues, implement solutions, handle code reviews, and merge PRs.
|
||||
|
||||
## Workflow Loop
|
||||
|
||||
This skill runs as a continuous loop:
|
||||
|
||||
```
|
||||
1. CHECK PENDING PRs → Fix reviews if CodeRabbit commented
|
||||
2. FIND ISSUE → Pick a Go issue from host-uk org
|
||||
3. IMPLEMENT → Create branch, code, test, push
|
||||
4. HANDLE REVIEW → Wait for/fix CodeRabbit feedback
|
||||
5. MERGE → Merge when approved
|
||||
6. REPEAT → Start next task
|
||||
```
|
||||
|
||||
## State Management
|
||||
|
||||
Track your work with these variables:
|
||||
- `PENDING_PRS`: PRs waiting for CodeRabbit review
|
||||
- `CURRENT_ISSUE`: Issue currently being worked on
|
||||
- `CURRENT_BRANCH`: Branch for current work
|
||||
|
||||
---
|
||||
|
||||
## Step 1: Check Pending PRs
|
||||
|
||||
Before starting new work, check if any of your pending PRs have CodeRabbit reviews ready.
|
||||
|
||||
```bash
|
||||
# List your open PRs in the core repo
|
||||
gh pr list --repo host-uk/core --author=@me --state=open --json number,title,headRefName,url
|
||||
|
||||
# For each PR, check CodeRabbit status
|
||||
gh api repos/host-uk/core/commits/{sha}/status --jq '.statuses[] | select(.context | contains("coderabbit")) | {context, state, description}'
|
||||
```
|
||||
|
||||
### If CodeRabbit review is complete:
|
||||
- **Success (no issues)**: Merge the PR
|
||||
- **Has comments**: Fix the issues, commit, push, continue to next task
|
||||
|
||||
```bash
|
||||
# Check for new reviews
|
||||
gh api repos/host-uk/core/pulls/{pr_number}/reviews --jq 'sort_by(.submitted_at) | .[-1] | {author: .user.login, state: .state, body: .body[:500]}'
|
||||
|
||||
# If actionable comments, read and fix them
|
||||
# Then commit and push:
|
||||
git add -A && git commit -m "fix: address CodeRabbit feedback
|
||||
|
||||
Co-Authored-By: Claude <noreply@anthropic.com>"
|
||||
git push
|
||||
```
|
||||
|
||||
### Merging PRs
|
||||
```bash
|
||||
# When CodeRabbit approves (status: success), merge without admin
|
||||
gh pr merge {pr_number} --squash --repo host-uk/core
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Step 2: Find an Issue
|
||||
|
||||
Search for Go issues in the Host UK organization.
|
||||
|
||||
```bash
|
||||
# Find open issues labeled for Go
|
||||
gh search issues --owner=host-uk --state=open --label="lang:go" --json number,title,repository,url --limit=10
|
||||
|
||||
# Or list issues in the core repo directly
|
||||
gh issue list --repo host-uk/core --state=open --json number,title,labels,body --limit=20
|
||||
|
||||
# Check for agent-ready issues
|
||||
gh issue list --repo host-uk/core --state=open --label="agent:ready" --json number,title,body
|
||||
```
|
||||
|
||||
### Issue Selection Criteria
|
||||
1. **Priority**: Issues with `priority:high` or `good-first-issue` labels
|
||||
2. **Dependencies**: Check if issue depends on other incomplete work
|
||||
3. **Scope**: Prefer issues that can be completed in one session
|
||||
4. **Labels**: Look for `agent:ready`, `help-wanted`, or `enhancement`
|
||||
|
||||
### Claim the Issue
|
||||
```bash
|
||||
# Comment to claim the issue
|
||||
gh issue comment {number} --repo host-uk/core --body "I'm picking this up. Starting work now."
|
||||
|
||||
# Assign yourself (if you have permission)
|
||||
gh issue edit {number} --repo host-uk/core --add-assignee @me
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Step 3: Implement the Solution
|
||||
|
||||
### Setup Branch
|
||||
```bash
|
||||
# Navigate to the core package
|
||||
cd packages/core
|
||||
|
||||
# Ensure you're on dev and up to date
|
||||
git checkout dev && git pull
|
||||
|
||||
# Create feature branch
|
||||
git checkout -b feature/issue-{number}-{short-description}
|
||||
```
|
||||
|
||||
### Development Workflow
|
||||
1. **Read the code** - Understand the package structure
|
||||
2. **Write tests first** - TDD approach when possible
|
||||
3. **Implement the solution** - Follow Go best practices
|
||||
4. **Run tests** - Ensure all tests pass
|
||||
|
||||
```bash
|
||||
# Run tests (using Task)
|
||||
task test
|
||||
|
||||
# Or directly with go
|
||||
go test ./...
|
||||
|
||||
# Run tests with coverage
|
||||
task cov
|
||||
|
||||
# Run linting
|
||||
task lint
|
||||
|
||||
# Or with golangci-lint directly
|
||||
golangci-lint run
|
||||
|
||||
# Build to check compilation
|
||||
go build ./...
|
||||
```
|
||||
|
||||
### Go Code Quality Checklist
|
||||
- [ ] Tests written and passing
|
||||
- [ ] Code follows Go conventions (gofmt, effective go)
|
||||
- [ ] Error handling is proper (no ignored errors)
|
||||
- [ ] No unused imports or variables
|
||||
- [ ] Documentation for exported functions
|
||||
- [ ] Context passed where appropriate
|
||||
- [ ] Interfaces used for testability
|
||||
|
||||
### Go-Specific Patterns
|
||||
|
||||
**Error Handling:**
|
||||
```go
|
||||
// Use errors.E for contextual errors
|
||||
return errors.E("service.method", "what failed", err)
|
||||
|
||||
// Or errors.Wrap for wrapping
|
||||
return errors.Wrap(err, "service.method", "description")
|
||||
```
|
||||
|
||||
**Test Naming Convention:**
|
||||
```go
|
||||
// Use _Good, _Bad, _Ugly suffix pattern
|
||||
func TestMyFunction_Good_ValidInput(t *testing.T) { ... }
|
||||
func TestMyFunction_Bad_InvalidInput(t *testing.T) { ... }
|
||||
func TestMyFunction_Ugly_PanicCase(t *testing.T) { ... }
|
||||
```
|
||||
|
||||
**i18n Strings:**
|
||||
```go
|
||||
// Use i18n package for user-facing strings
|
||||
i18n.T("cmd.mycommand.description")
|
||||
i18n.Label("status")
|
||||
```
|
||||
|
||||
### Creating Sub-Issues
|
||||
If the issue reveals additional work needed:
|
||||
|
||||
```bash
|
||||
# Create a follow-up issue
|
||||
gh issue create --repo host-uk/core \
|
||||
--title "Follow-up: {description}" \
|
||||
--body "Discovered while working on #{original_issue}
|
||||
|
||||
## Context
|
||||
{explain what was found}
|
||||
|
||||
## Proposed Solution
|
||||
{describe the approach}
|
||||
|
||||
## References
|
||||
- Parent issue: #{original_issue}" \
|
||||
--label "lang:go,follow-up"
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Step 4: Push and Create PR
|
||||
|
||||
```bash
|
||||
# Stage and commit
|
||||
git add -A
|
||||
git commit -m "feat({pkg}): {description}
|
||||
|
||||
{longer description if needed}
|
||||
|
||||
Closes #{issue_number}
|
||||
|
||||
Co-Authored-By: Claude <noreply@anthropic.com>"
|
||||
|
||||
# Push
|
||||
git push -u origin feature/issue-{number}-{short-description}
|
||||
|
||||
# Create PR
|
||||
gh pr create --repo host-uk/core \
|
||||
--title "feat({pkg}): {description}" \
|
||||
--body "$(cat <<'EOF'
|
||||
## Summary
|
||||
{Brief description of changes}
|
||||
|
||||
## Changes
|
||||
- {Change 1}
|
||||
- {Change 2}
|
||||
|
||||
## Test Plan
|
||||
- [ ] Unit tests added/updated
|
||||
- [ ] `task test` passes
|
||||
- [ ] `task lint` passes
|
||||
- [ ] Manual testing completed
|
||||
|
||||
Closes #{issue_number}
|
||||
|
||||
---
|
||||
Generated with Claude Code
|
||||
EOF
|
||||
)"
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Step 5: Handle CodeRabbit Review
|
||||
|
||||
After pushing, CodeRabbit will automatically review. Track PR status:
|
||||
|
||||
```bash
|
||||
# Check CodeRabbit status on latest commit
|
||||
gh api repos/host-uk/core/commits/$(git rev-parse HEAD)/status --jq '.statuses[] | select(.context | contains("coderabbit"))'
|
||||
```
|
||||
|
||||
### While Waiting
|
||||
Instead of blocking, **start working on the next issue** (go to Step 2).
|
||||
|
||||
### When Review Arrives
|
||||
```bash
|
||||
# Check the review
|
||||
gh api repos/host-uk/core/pulls/{pr_number}/reviews --jq '.[-1]'
|
||||
|
||||
# If "Actionable comments posted: N", fix them:
|
||||
# 1. Read each comment
|
||||
# 2. Make the fix
|
||||
# 3. Commit with clear message
|
||||
# 4. Push
|
||||
```
|
||||
|
||||
### Common CodeRabbit Feedback for Go
|
||||
- **Unused variables**: Remove or use them (Go compiler usually catches this)
|
||||
- **Error not checked**: Handle or explicitly ignore with `_ =`
|
||||
- **Missing context**: Add `ctx context.Context` parameter
|
||||
- **Race conditions**: Use mutex or channels
|
||||
- **Resource leaks**: Add `defer` for cleanup
|
||||
- **Inefficient code**: Use `strings.Builder`, avoid allocations in loops
|
||||
- **Missing documentation**: Add doc comments for exported symbols
|
||||
|
||||
---
|
||||
|
||||
## Step 6: Merge and Close
|
||||
|
||||
When CodeRabbit status shows "Review completed" with state "success":
|
||||
|
||||
```bash
|
||||
# Merge the PR (squash merge)
|
||||
gh pr merge {pr_number} --squash --repo host-uk/core
|
||||
|
||||
# The issue will auto-close if "Closes #N" was in PR body
|
||||
# Otherwise, close manually:
|
||||
gh issue close {number} --repo host-uk/core
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Step 7: Restart Loop
|
||||
|
||||
After merging:
|
||||
|
||||
1. Remove PR from `PENDING_PRS`
|
||||
2. Check remaining pending PRs for reviews
|
||||
3. Pick up next issue
|
||||
4. **Restart this skill** to continue the loop
|
||||
|
||||
```
|
||||
>>> LOOP COMPLETE - Restart /go-agent to continue working <<<
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Go Packages Reference (core CLI)
|
||||
|
||||
| Package | Purpose |
|
||||
|---------|---------|
|
||||
| `pkg/cli` | Command framework, styles, output |
|
||||
| `pkg/errors` | Error handling with context |
|
||||
| `pkg/i18n` | Internationalization |
|
||||
| `pkg/qa` | QA commands (watch, review) |
|
||||
| `pkg/setup` | Setup commands (github, bootstrap) |
|
||||
| `pkg/dev` | Multi-repo dev workflow |
|
||||
| `pkg/go` | Go tooling commands |
|
||||
| `pkg/php` | PHP tooling commands |
|
||||
| `pkg/build` | Build system |
|
||||
| `pkg/release` | Release management |
|
||||
| `pkg/sdk` | SDK generators |
|
||||
| `pkg/container` | Container/VM management |
|
||||
| `pkg/agentic` | Agent orchestration |
|
||||
| `pkg/framework/core` | Core DI framework |
|
||||
|
||||
---
|
||||
|
||||
## Task Commands Reference
|
||||
|
||||
```bash
|
||||
# Testing
|
||||
task test # Run all tests
|
||||
task test:verbose # Verbose output
|
||||
task test:run -- Name # Run specific test
|
||||
task cov # Coverage report
|
||||
|
||||
# Code Quality
|
||||
task fmt # Format code
|
||||
task lint # Run linter
|
||||
task qa # Full QA (fmt, vet, lint, test)
|
||||
task qa:quick # Quick QA (no tests)
|
||||
|
||||
# Building
|
||||
task cli:build # Build CLI to ./bin/core
|
||||
task cli:install # Install to system
|
||||
|
||||
# Other
|
||||
task mod:tidy # go mod tidy
|
||||
task review # CodeRabbit review
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Troubleshooting
|
||||
|
||||
### CodeRabbit Not Reviewing
|
||||
```bash
|
||||
# Check commit status
|
||||
gh api repos/host-uk/core/commits/$(git rev-parse HEAD)/status
|
||||
|
||||
# Check if webhooks are configured
|
||||
gh api repos/host-uk/core/hooks
|
||||
```
|
||||
|
||||
### Tests Failing
|
||||
```bash
|
||||
# Run with verbose output
|
||||
go test -v ./...
|
||||
|
||||
# Run specific test
|
||||
go test -run TestName ./pkg/...
|
||||
|
||||
# Run with race detector
|
||||
go test -race ./...
|
||||
```
|
||||
|
||||
### Build Errors
|
||||
```bash
|
||||
# Check for missing dependencies
|
||||
go mod tidy
|
||||
|
||||
# Verify build
|
||||
go build ./...
|
||||
|
||||
# Check for vet issues
|
||||
go vet ./...
|
||||
```
|
||||
|
||||
### Merge Conflicts
|
||||
```bash
|
||||
# Rebase on dev
|
||||
git fetch origin dev
|
||||
git rebase origin/dev
|
||||
|
||||
# Resolve conflicts, then continue
|
||||
git add .
|
||||
git rebase --continue
|
||||
git push --force-with-lease
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Best Practices
|
||||
|
||||
1. **One issue per PR** - Keep changes focused
|
||||
2. **Small commits** - Easier to review and revert
|
||||
3. **Descriptive messages** - Help future maintainers
|
||||
4. **Test coverage** - Don't decrease coverage
|
||||
5. **Documentation** - Update if behavior changes
|
||||
6. **Error context** - Use errors.E with service.method prefix
|
||||
7. **i18n strings** - Add to en_GB.json for user-facing text
|
||||
|
||||
## Labels Reference
|
||||
|
||||
- `lang:go` - Go code changes
|
||||
- `agent:ready` - Ready for AI agent pickup
|
||||
- `good-first-issue` - Simple, well-defined tasks
|
||||
- `priority:high` - Should be addressed soon
|
||||
- `follow-up` - Created from another issue
|
||||
- `needs:review` - Awaiting human review
|
||||
- `bug` - Something isn't working
|
||||
- `enhancement` - New feature or improvement
|
||||
18
plugins/core-php/.claude-plugin/plugin.json
Normal file
18
plugins/core-php/.claude-plugin/plugin.json
Normal file
|
|
@ -0,0 +1,18 @@
|
|||
{
|
||||
"name": "core-php",
|
||||
"version": "0.1.0",
|
||||
"description": "Claude plugin family for Core PHP services, modules, and tooling.",
|
||||
"author": {
|
||||
"name": "Lethean Community",
|
||||
"email": "hello@lethean.io"
|
||||
},
|
||||
"homepage": "https://lthn.ai",
|
||||
"repository": "https://forge.lthn.ai/core/agent.git",
|
||||
"license": "EUPL-1.2",
|
||||
"keywords": [
|
||||
"claude",
|
||||
"core",
|
||||
"php",
|
||||
"agent"
|
||||
]
|
||||
}
|
||||
9
plugins/core-php/.mcp.json
Normal file
9
plugins/core-php/.mcp.json
Normal file
|
|
@ -0,0 +1,9 @@
|
|||
{
|
||||
"mcpServers": {
|
||||
"core": {
|
||||
"type": "stdio",
|
||||
"command": "core",
|
||||
"args": ["mcp", "serve"]
|
||||
}
|
||||
}
|
||||
}
|
||||
6
plugins/core-php/README.md
Normal file
6
plugins/core-php/README.md
Normal file
|
|
@ -0,0 +1,6 @@
|
|||
# core-php
|
||||
This plugin family covers Claude workflows for Core PHP services and application modules.
|
||||
It is the canonical home for PHP-focused commands, agents, and skills in the Core ecosystem.
|
||||
The scope includes framework conventions, module structure, QA, verification, and delivery support.
|
||||
Marketplace metadata for this family is defined in `marketplace.yaml`.
|
||||
Commands, agents, and skills here are seeded from the existing Claude and Codex plugin material in this repository.
|
||||
24
plugins/core-php/agents/php-developer.md
Normal file
24
plugins/core-php/agents/php-developer.md
Normal file
|
|
@ -0,0 +1,24 @@
|
|||
---
|
||||
name: php-developer
|
||||
description: PHP development agent for Core services and modules. Derived from the existing core-php, php-agent, and senior-developer material.
|
||||
tools: Bash, Read, Edit, MultiEdit, Grep, Glob, LS
|
||||
model: sonnet
|
||||
color: purple
|
||||
---
|
||||
|
||||
You are a PHP developer working in the Core ecosystem.
|
||||
|
||||
## Working rules
|
||||
|
||||
- Follow the module conventions in `skills/core/SKILL.md` and `skills/core-php/SKILL.md`.
|
||||
- Use the delivery loop in `skills/php-agent/SKILL.md` when the task requires autonomous implementation.
|
||||
- Prefer `core php test`, `core php fmt`, and `core php stan` over raw commands when the wrapper exists.
|
||||
- Keep `declare(strict_types=1);` on PHP files and keep user-facing strings in UK English.
|
||||
- Use Actions for business logic, thin controllers, and Pest for tests.
|
||||
|
||||
## Delivery standard
|
||||
|
||||
1. Read the module structure before making changes.
|
||||
2. Keep business logic in Actions and keep multi-tenant boundaries explicit.
|
||||
3. Fix the failing behaviour and add or update tests.
|
||||
4. Run QA and verification before stopping.
|
||||
52
plugins/core-php/commands/commit.md
Normal file
52
plugins/core-php/commands/commit.md
Normal file
|
|
@ -0,0 +1,52 @@
|
|||
---
|
||||
name: commit
|
||||
description: Generate a conventional commit message for staged changes
|
||||
args: "[message]"
|
||||
flags:
|
||||
- --amend
|
||||
hooks:
|
||||
Before:
|
||||
- hooks:
|
||||
- type: command
|
||||
command: "${CLAUDE_PLUGIN_ROOT}/scripts/smart-commit.sh"
|
||||
---
|
||||
|
||||
# Smart Commit
|
||||
|
||||
Generate a conventional commit message for staged changes.
|
||||
|
||||
## Usage
|
||||
|
||||
Generate message automatically:
|
||||
`/core-php:commit`
|
||||
|
||||
Provide a custom message:
|
||||
`/core-php:commit "feat(module): add action validation"`
|
||||
|
||||
Amend the previous commit:
|
||||
`/core-php:commit --amend`
|
||||
|
||||
## Behavior
|
||||
|
||||
1. **Analyze Staged Changes**: Examines the `git diff --staged` to understand the nature of the changes.
|
||||
2. **Generate Conventional Commit Message**:
|
||||
- `feat`: For new files, functions, or features.
|
||||
- `fix`: For bug fixes.
|
||||
- `refactor`: For code restructuring without changing external behavior.
|
||||
- `docs`: For changes to documentation.
|
||||
- `test`: For adding or modifying tests.
|
||||
- `chore`: For routine maintenance tasks.
|
||||
3. **Determine Scope**: Infers the scope from the affected module's file paths (e.g., `auth`, `payment`, `ui`).
|
||||
4. **Add Co-Authored-By Trailer**: Appends `Co-Authored-By: Claude <noreply@anthropic.com>` to the commit message.
|
||||
|
||||
## Message Generation Example
|
||||
|
||||
```
|
||||
feat(auth): add JWT token validation
|
||||
|
||||
- Add validateToken() function
|
||||
- Add token expiry check
|
||||
- Add unit tests for validation
|
||||
|
||||
Co-Authored-By: Claude <noreply@anthropic.com>
|
||||
```
|
||||
126
plugins/core-php/commands/qa.md
Normal file
126
plugins/core-php/commands/qa.md
Normal file
|
|
@ -0,0 +1,126 @@
|
|||
---
|
||||
name: qa
|
||||
description: Run PHP QA checks and fix all issues iteratively
|
||||
hooks:
|
||||
PostToolUse:
|
||||
- matcher: "Bash"
|
||||
hooks:
|
||||
- type: command
|
||||
command: "${CLAUDE_PLUGIN_ROOT}/scripts/qa-filter.sh"
|
||||
Stop:
|
||||
- hooks:
|
||||
- type: command
|
||||
command: "${CLAUDE_PLUGIN_ROOT}/scripts/qa-verify.sh"
|
||||
once: true
|
||||
---
|
||||
|
||||
# QA Fix Loop
|
||||
|
||||
Run the full PHP QA pipeline and fix all issues.
|
||||
|
||||
## Process
|
||||
|
||||
1. **Run QA**: Execute `core php qa`
|
||||
2. **Parse issues**: Extract failures from output (see format below)
|
||||
3. **Fix each issue**: Address one at a time, simplest first
|
||||
4. **Re-verify**: After fixes, re-run QA
|
||||
5. **Repeat**: Until all checks pass
|
||||
6. **Report**: Summary of what was fixed
|
||||
|
||||
## Issue Priority
|
||||
|
||||
Fix in this order (fastest feedback first):
|
||||
1. **pint** - formatting issues (auto-fix with `core php fmt`)
|
||||
2. **stan** - static analysis (usually quick fixes)
|
||||
3. **test** - failing tests (may need more investigation)
|
||||
4. **build** - runtime bootstrap or syntax errors (fix before tests can run)
|
||||
|
||||
## Output Parsing
|
||||
|
||||
### PHP QA Output
|
||||
```
|
||||
=== PINT ===
|
||||
FAIL: 2 files need formatting
|
||||
|
||||
=== STAN ===
|
||||
src/Http/Controller.php:42 - Undefined variable $user
|
||||
|
||||
=== TEST ===
|
||||
✗ CreateUserTest::testSuccess
|
||||
Expected status 200, got 500
|
||||
|
||||
=== RESULT ===
|
||||
pint: FAIL
|
||||
stan: FAIL (1 error)
|
||||
test: FAIL (1 failed)
|
||||
```
|
||||
|
||||
## Fixing Strategy
|
||||
|
||||
**Formatting (pint):**
|
||||
- Just run `core php fmt`
|
||||
- No code reading needed
|
||||
|
||||
**Static analysis errors:**
|
||||
- Read the specific file:line
|
||||
- Understand the error type
|
||||
- Make minimal fix
|
||||
|
||||
**Test failures:**
|
||||
- Read the test file to understand expectation
|
||||
- Read the implementation
|
||||
- Fix the root cause (not just the symptom)
|
||||
|
||||
**Build errors:**
|
||||
- Usually bootstrap, syntax, or autoload issues
|
||||
- Fix before attempting other checks
|
||||
|
||||
## Stop Condition
|
||||
|
||||
Only stop when:
|
||||
- All QA checks pass, OR
|
||||
- User explicitly cancels, OR
|
||||
- Same error repeats 3 times (stuck - ask for help)
|
||||
|
||||
## Example Session
|
||||
|
||||
```
|
||||
Running: core php qa
|
||||
|
||||
## QA Issues
|
||||
|
||||
src/Http/Controller.php:42 - Undefined variable $user
|
||||
✗ CreateUserTest::testSuccess
|
||||
|
||||
**Summary:** stan: FAIL (1) | test: FAIL (1)
|
||||
|
||||
---
|
||||
|
||||
Fixing static analysis issue: undefined variable
|
||||
Reading src/Http/Controller.php...
|
||||
Adding the missing variable assignment.
|
||||
|
||||
Running: core php qa
|
||||
|
||||
## QA Issues
|
||||
|
||||
✗ CreateUserTest::testSuccess
|
||||
Expected status 200, got 500
|
||||
|
||||
**Summary:** stan: PASS | test: FAIL (1)
|
||||
|
||||
---
|
||||
|
||||
Fixing test issue: expected 200, got 500
|
||||
Reading test setup...
|
||||
Correcting test data.
|
||||
|
||||
Running: core php qa
|
||||
|
||||
✓ All checks passed!
|
||||
|
||||
**Summary:**
|
||||
- Fixed: undefined variable (added assignment)
|
||||
- Fixed: TestCreateUser (corrected test setup)
|
||||
- 2 issues resolved, all checks passing
|
||||
```
|
||||
63
plugins/core-php/commands/review.md
Normal file
63
plugins/core-php/commands/review.md
Normal file
|
|
@ -0,0 +1,63 @@
|
|||
---
|
||||
name: review
|
||||
description: Perform code review on staged changes or PRs
|
||||
args: [commit-range|--pr=N|--security]
|
||||
---
|
||||
|
||||
# Code Review
|
||||
|
||||
Perform a thorough code review of the specified changes.
|
||||
|
||||
## Arguments
|
||||
|
||||
- No args: Review staged changes
|
||||
- `HEAD~3..HEAD`: Review last 3 commits
|
||||
- `--pr=123`: Review PR #123
|
||||
- `--security`: Focus on security issues
|
||||
|
||||
## Process
|
||||
|
||||
1. **Gather changes**: Get diff for the specified range
|
||||
2. **Analyse each file**: Review for issues by category
|
||||
3. **Report findings**: Output structured review
|
||||
|
||||
## Review Checklist
|
||||
|
||||
| Category | Checks |
|
||||
|----------|--------|
|
||||
| **Correctness** | Logic errors, edge cases, error handling |
|
||||
| **Security** | SQL injection, XSS, hardcoded secrets, CSRF |
|
||||
| **Performance** | N+1 queries, unnecessary loops, large allocations |
|
||||
| **Maintainability** | Naming, structure, complexity |
|
||||
| **Tests** | Coverage gaps, missing assertions |
|
||||
|
||||
## Output Format
|
||||
|
||||
```markdown
|
||||
## Code Review: [title]
|
||||
|
||||
### Critical
|
||||
- **file:line** - Issue description
|
||||
|
||||
### Warning
|
||||
- **file:line** - Issue description
|
||||
|
||||
### Suggestions
|
||||
- **file:line** - Improvement idea
|
||||
|
||||
---
|
||||
**Summary**: X critical, Y warnings, Z suggestions
|
||||
```
|
||||
|
||||
## Commands
|
||||
|
||||
```bash
|
||||
# Get staged diff
|
||||
git diff --cached
|
||||
|
||||
# Get PR diff
|
||||
gh pr diff 123
|
||||
|
||||
# Get commit range diff
|
||||
git diff HEAD~3..HEAD
|
||||
```
|
||||
75
plugins/core-php/commands/verify.md
Normal file
75
plugins/core-php/commands/verify.md
Normal file
|
|
@ -0,0 +1,75 @@
|
|||
---
|
||||
name: verify
|
||||
description: Verify work is complete before stopping
|
||||
args: [--quick|--full]
|
||||
---
|
||||
|
||||
# Work Verification
|
||||
|
||||
Verify that PHP work is complete and ready to commit/push.
|
||||
|
||||
## Arguments
|
||||
|
||||
- No args: Standard verification
|
||||
- `--quick`: Fast checks only (format, lint)
|
||||
- `--full`: All checks including slow tests
|
||||
|
||||
## Verification Steps
|
||||
|
||||
### 1. Check for uncommitted changes
|
||||
```bash
|
||||
git status --porcelain
|
||||
```
|
||||
|
||||
### 2. Check for debug statements
|
||||
Look for:
|
||||
- Go: `fmt.Println`, `log.Println`, `spew.Dump`
|
||||
- PHP: `dd(`, `dump(`, `var_dump(`, `ray(`
|
||||
- JS/TS: `console.log`, `debugger`
|
||||
|
||||
### 3. Run tests
|
||||
```bash
|
||||
core php test
|
||||
```
|
||||
|
||||
### 4. Run linter
|
||||
```bash
|
||||
core php stan
|
||||
```
|
||||
|
||||
### 5. Check formatting
|
||||
```bash
|
||||
core php fmt --test
|
||||
```
|
||||
|
||||
## Output
|
||||
|
||||
Report verification status:
|
||||
|
||||
```
|
||||
## Verification Results
|
||||
|
||||
✓ No uncommitted changes
|
||||
✓ No debug statements found
|
||||
✓ Tests passing (47/47)
|
||||
✓ Lint clean
|
||||
✓ Formatting correct
|
||||
|
||||
**Status: READY**
|
||||
```
|
||||
|
||||
Or if issues found:
|
||||
|
||||
```
|
||||
## Verification Results
|
||||
|
||||
✓ No uncommitted changes
|
||||
✗ Debug statement found: src/handler.go:42
|
||||
✗ Tests failing (45/47)
|
||||
✓ Lint clean
|
||||
✓ Formatting correct
|
||||
|
||||
**Status: NOT READY**
|
||||
|
||||
Fix these issues before proceeding.
|
||||
```
|
||||
6
plugins/core-php/marketplace.yaml
Normal file
6
plugins/core-php/marketplace.yaml
Normal file
|
|
@ -0,0 +1,6 @@
|
|||
marketplace:
|
||||
registry: forge.lthn.ai
|
||||
organization: core
|
||||
repository: core-php
|
||||
auto_update: true
|
||||
check_interval: 24h
|
||||
62
plugins/core-php/scripts/qa-filter.sh
Executable file
62
plugins/core-php/scripts/qa-filter.sh
Executable file
|
|
@ -0,0 +1,62 @@
|
|||
#!/bin/bash
|
||||
# Filter QA output to show only actionable issues during /core:qa mode
|
||||
#
|
||||
# PostToolUse hook that processes QA command output and extracts
|
||||
# only the failures, hiding verbose success output.
|
||||
|
||||
read -r input
|
||||
COMMAND=$(echo "$input" | jq -r '.tool_input.command // empty')
|
||||
OUTPUT=$(echo "$input" | jq -r '.tool_response.stdout // .tool_response.output // empty')
|
||||
EXIT_CODE=$(echo "$input" | jq -r '.tool_response.exit_code // 0')
|
||||
|
||||
# Only process QA-related commands
|
||||
case "$COMMAND" in
|
||||
"core go qa"*|"core php qa"*|"core go test"*|"core php test"*|"core go lint"*|"core php stan"*)
|
||||
;;
|
||||
*)
|
||||
# Not a QA command, pass through unchanged
|
||||
echo "$input"
|
||||
exit 0
|
||||
;;
|
||||
esac
|
||||
|
||||
# Extract failures from output
|
||||
FAILURES=$(echo "$OUTPUT" | grep -E "^(FAIL|---\s*FAIL|✗|ERROR|undefined:|error:|panic:)" | head -20)
|
||||
SUMMARY=$(echo "$OUTPUT" | grep -E "^(fmt:|lint:|test:|pint:|stan:|=== RESULT ===)" | tail -5)
|
||||
|
||||
# Also grab specific error lines with file:line references
|
||||
FILE_ERRORS=$(echo "$OUTPUT" | grep -E "^[a-zA-Z0-9_/.-]+\.(go|php):[0-9]+:" | head -10)
|
||||
|
||||
if [ -z "$FAILURES" ] && [ "$EXIT_CODE" = "0" ]; then
|
||||
# All passed - show brief confirmation
|
||||
cat << 'EOF'
|
||||
{
|
||||
"suppressOutput": true,
|
||||
"hookSpecificOutput": {
|
||||
"hookEventName": "PostToolUse",
|
||||
"additionalContext": "✓ QA passed"
|
||||
}
|
||||
}
|
||||
EOF
|
||||
else
|
||||
# Combine failures and file errors
|
||||
ISSUES="$FAILURES"
|
||||
if [ -n "$FILE_ERRORS" ]; then
|
||||
ISSUES="$ISSUES
|
||||
$FILE_ERRORS"
|
||||
fi
|
||||
|
||||
# Escape for JSON
|
||||
ISSUES_ESCAPED=$(echo "$ISSUES" | sed 's/\\/\\\\/g' | sed 's/"/\\"/g' | sed ':a;N;$!ba;s/\n/\\n/g')
|
||||
SUMMARY_ESCAPED=$(echo "$SUMMARY" | sed 's/\\/\\\\/g' | sed 's/"/\\"/g' | sed ':a;N;$!ba;s/\n/ | /g')
|
||||
|
||||
cat << EOF
|
||||
{
|
||||
"suppressOutput": true,
|
||||
"hookSpecificOutput": {
|
||||
"hookEventName": "PostToolUse",
|
||||
"additionalContext": "## QA Issues\n\n\`\`\`\n$ISSUES_ESCAPED\n\`\`\`\n\n**Summary:** $SUMMARY_ESCAPED"
|
||||
}
|
||||
}
|
||||
EOF
|
||||
fi
|
||||
28
plugins/core-php/scripts/qa-verify.sh
Executable file
28
plugins/core-php/scripts/qa-verify.sh
Executable file
|
|
@ -0,0 +1,28 @@
|
|||
#!/bin/bash
|
||||
# Verify QA passes before stopping during /core-php:qa mode.
|
||||
|
||||
read -r input
|
||||
STOP_ACTIVE=$(echo "$input" | jq -r '.stop_hook_active // false')
|
||||
|
||||
# Prevent infinite loop
|
||||
if [ "$STOP_ACTIVE" = "true" ]; then
|
||||
exit 0
|
||||
fi
|
||||
|
||||
# Run PHP QA for this plugin family.
|
||||
RESULT=$(core php qa 2>&1) || true
|
||||
|
||||
# Check if QA passed
|
||||
if echo "$RESULT" | grep -qE "FAIL|ERROR|✗|panic:|undefined:"; then
|
||||
ISSUES=$(echo "$RESULT" | grep -E "^(FAIL|ERROR|✗|undefined:|panic:)|^[a-zA-Z0-9_/.-]+\.php:[0-9]+:" | head -5)
|
||||
ISSUES_ESCAPED=$(echo "$ISSUES" | sed 's/\\/\\\\/g' | sed 's/"/\\"/g' | sed ':a;N;$!ba;s/\n/\\n/g')
|
||||
|
||||
cat << EOF
|
||||
{
|
||||
"decision": "block",
|
||||
"reason": "QA still has issues:\n\n$ISSUES_ESCAPED\n\nPlease fix these before stopping."
|
||||
}
|
||||
EOF
|
||||
else
|
||||
exit 0
|
||||
fi
|
||||
108
plugins/core-php/scripts/smart-commit.sh
Executable file
108
plugins/core-php/scripts/smart-commit.sh
Executable file
|
|
@ -0,0 +1,108 @@
|
|||
#!/bin/bash
|
||||
# Smart commit script for /core:commit command
|
||||
|
||||
CUSTOM_MESSAGE=""
|
||||
AMEND_FLAG=""
|
||||
|
||||
# Parse arguments
|
||||
while (( "$#" )); do
|
||||
case "$1" in
|
||||
--amend)
|
||||
AMEND_FLAG="--amend"
|
||||
shift
|
||||
;;
|
||||
-*)
|
||||
echo "Unsupported flag $1" >&2
|
||||
exit 1
|
||||
;;
|
||||
*)
|
||||
# The rest of the arguments are treated as the commit message
|
||||
CUSTOM_MESSAGE="$@"
|
||||
break
|
||||
;;
|
||||
esac
|
||||
done
|
||||
|
||||
# Get staged changes
|
||||
STAGED_FILES=$(git diff --staged --name-status)
|
||||
|
||||
if [ -z "$STAGED_FILES" ]; then
|
||||
echo "No staged changes to commit."
|
||||
exit 0
|
||||
fi
|
||||
|
||||
# Determine commit type and scope
|
||||
COMMIT_TYPE="chore" # Default to chore
|
||||
SCOPE=""
|
||||
|
||||
# Get just the file paths
|
||||
STAGED_FILE_PATHS=$(git diff --staged --name-only)
|
||||
|
||||
# Determine type from file paths/status
|
||||
# Order is important here: test and docs are more specific than feat.
|
||||
if echo "$STAGED_FILE_PATHS" | grep -q -E "(_test\.go|\.test\.js|/tests/|/spec/)"; then
|
||||
COMMIT_TYPE="test"
|
||||
elif echo "$STAGED_FILE_PATHS" | grep -q -E "(\.md|/docs/|README)"; then
|
||||
COMMIT_TYPE="docs"
|
||||
elif echo "$STAGED_FILES" | grep -q "^A"; then
|
||||
COMMIT_TYPE="feat"
|
||||
elif git diff --staged | grep -q -E "^\+.*(fix|bug|issue)"; then
|
||||
COMMIT_TYPE="fix"
|
||||
elif git diff --staged | grep -q -E "^\+.*(refactor|restructure)"; then
|
||||
COMMIT_TYPE="refactor"
|
||||
fi
|
||||
|
||||
# Determine scope from the most common path component
|
||||
if [ -n "$STAGED_FILE_PATHS" ]; then
|
||||
# Extract the second component of each path (e.g., 'code' from 'claude/code/file.md')
|
||||
# This is a decent heuristic for module name.
|
||||
# We filter for lines that have a second component.
|
||||
POSSIBLE_SCOPES=$(echo "$STAGED_FILE_PATHS" | grep '/' | cut -d/ -f2)
|
||||
|
||||
if [ -n "$POSSIBLE_SCOPES" ]; then
|
||||
SCOPE=$(echo "$POSSIBLE_SCOPES" | sort | uniq -c | sort -nr | head -n 1 | awk '{print $2}')
|
||||
fi
|
||||
# If no scope is found (e.g., all files are in root), SCOPE remains empty, which is valid.
|
||||
fi
|
||||
|
||||
# Construct the commit message
|
||||
if [ -n "$CUSTOM_MESSAGE" ]; then
|
||||
COMMIT_MESSAGE="$CUSTOM_MESSAGE"
|
||||
else
|
||||
# Auto-generate a descriptive summary
|
||||
DIFF_CONTENT=$(git diff --staged)
|
||||
# Try to find a function or class name from the diff
|
||||
# This is a simple heuristic that can be greatly expanded.
|
||||
SUMMARY=$(echo "$DIFF_CONTENT" | grep -E -o "(function|class|def) \w+" | head -n 1 | sed -e 's/function //g' -e 's/class //g' -e 's/def //g')
|
||||
|
||||
if [ -z "$SUMMARY" ]; then
|
||||
if [ $(echo "$STAGED_FILE_PATHS" | wc -l) -eq 1 ]; then
|
||||
FIRST_FILE=$(echo "$STAGED_FILE_PATHS" | head -n 1)
|
||||
SUMMARY="update $(basename "$FIRST_FILE")"
|
||||
else
|
||||
SUMMARY="update multiple files"
|
||||
fi
|
||||
else
|
||||
SUMMARY="update $SUMMARY"
|
||||
fi
|
||||
|
||||
SUBJECT="$COMMIT_TYPE($SCOPE): $SUMMARY"
|
||||
BODY=$(echo "$DIFF_CONTENT" | grep -E "^\+" | sed -e 's/^+//' | head -n 5 | sed 's/^/ - /')
|
||||
COMMIT_MESSAGE="$SUBJECT\n\n$BODY"
|
||||
fi
|
||||
|
||||
# Add Co-Authored-By trailer
|
||||
CO_AUTHOR="Co-Authored-By: Claude <noreply@anthropic.com>"
|
||||
if ! echo "$COMMIT_MESSAGE" | grep -q "$CO_AUTHOR"; then
|
||||
COMMIT_MESSAGE="$COMMIT_MESSAGE\n\n$CO_AUTHOR"
|
||||
fi
|
||||
|
||||
# Execute the commit
|
||||
git commit $AMEND_FLAG -m "$(echo -e "$COMMIT_MESSAGE")"
|
||||
|
||||
if [ $? -eq 0 ]; then
|
||||
echo "Commit successful."
|
||||
else
|
||||
echo "Commit failed."
|
||||
exit 1
|
||||
fi
|
||||
63
plugins/core-php/skills/api-endpoints/SKILL.md
Normal file
63
plugins/core-php/skills/api-endpoints/SKILL.md
Normal file
|
|
@ -0,0 +1,63 @@
|
|||
---
|
||||
name: api-endpoints
|
||||
description: Use when a Core plugin needs to call api.lthn.sh or mcp.lthn.sh. Documents the JSON headers, auth, and endpoint conventions required by the plugin restructure RFC.
|
||||
---
|
||||
|
||||
# API and MCP Endpoints
|
||||
|
||||
Use this skill when a command, script, or tool talks to the shared Core endpoints.
|
||||
|
||||
## Canonical endpoints
|
||||
|
||||
- `https://api.lthn.sh` — REST API
|
||||
- `https://mcp.lthn.sh` — MCP bridge endpoint
|
||||
|
||||
These conventions apply to both production and self-hosted `lthn.sh` installs.
|
||||
|
||||
## Required headers
|
||||
|
||||
- Send `Accept: application/json` on every API request. The default response may be HTML if this header is missing.
|
||||
- Send `Content-Type: application/json` for JSON request bodies.
|
||||
- Send `Authorization: Bearer <token>` for authenticated requests.
|
||||
|
||||
## REST shape
|
||||
|
||||
- Use `/v1/{resource}` paths.
|
||||
- Expect JSON request and response bodies.
|
||||
- Keep request payloads explicit and small.
|
||||
|
||||
Example:
|
||||
|
||||
```bash
|
||||
curl -s https://api.lthn.sh/v1/issues \
|
||||
-H 'Accept: application/json' \
|
||||
-H "Authorization: Bearer ${TOKEN}"
|
||||
```
|
||||
|
||||
```bash
|
||||
curl -s https://api.lthn.sh/v1/brain/recall \
|
||||
-X POST \
|
||||
-H 'Accept: application/json' \
|
||||
-H 'Content-Type: application/json' \
|
||||
-H "Authorization: Bearer ${TOKEN}" \
|
||||
-d '{"query":"dispatch status","top_k":3}'
|
||||
```
|
||||
|
||||
## MCP usage
|
||||
|
||||
- Remote MCP can be reached at `https://mcp.lthn.sh`.
|
||||
- Local plugin configs in this repository use `core mcp serve` through `.mcp.json`.
|
||||
|
||||
Local `.mcp.json` pattern:
|
||||
|
||||
```json
|
||||
{
|
||||
"mcpServers": {
|
||||
"core": {
|
||||
"type": "stdio",
|
||||
"command": "core",
|
||||
"args": ["mcp", "serve"]
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
126
plugins/core-php/skills/core-php/SKILL.md
Normal file
126
plugins/core-php/skills/core-php/SKILL.md
Normal file
|
|
@ -0,0 +1,126 @@
|
|||
---
|
||||
name: core-php
|
||||
description: Use when creating PHP modules, services, or actions in core-* packages.
|
||||
---
|
||||
|
||||
# PHP Framework Patterns
|
||||
|
||||
Host UK PHP modules follow strict conventions. Use `core php` commands.
|
||||
|
||||
## Module Structure
|
||||
|
||||
```
|
||||
core-{name}/
|
||||
├── src/
|
||||
│ ├── Core/ # Namespace: Core\{Name}
|
||||
│ │ ├── Boot.php # Module bootstrap (listens to lifecycle events)
|
||||
│ │ ├── Actions/ # Single-purpose business logic
|
||||
│ │ └── Models/ # Eloquent models
|
||||
│ └── Mod/ # Namespace: Core\Mod\{Name} (optional extensions)
|
||||
├── resources/views/ # Blade templates
|
||||
├── routes/ # Route definitions
|
||||
├── database/migrations/ # Migrations
|
||||
├── tests/ # Pest tests
|
||||
└── composer.json
|
||||
```
|
||||
|
||||
## Boot Class Pattern
|
||||
|
||||
```php
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Core\{Name};
|
||||
|
||||
use Core\Php\Events\WebRoutesRegistering;
|
||||
use Core\Php\Events\AdminPanelBooting;
|
||||
|
||||
class Boot
|
||||
{
|
||||
public static array $listens = [
|
||||
WebRoutesRegistering::class => 'onWebRoutes',
|
||||
AdminPanelBooting::class => ['onAdmin', 10], // With priority
|
||||
];
|
||||
|
||||
public function onWebRoutes(WebRoutesRegistering $event): void
|
||||
{
|
||||
$event->router->middleware('web')->group(__DIR__ . '/../routes/web.php');
|
||||
}
|
||||
|
||||
public function onAdmin(AdminPanelBooting $event): void
|
||||
{
|
||||
$event->panel->resources([...]);
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## Action Pattern
|
||||
|
||||
```php
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Core\{Name}\Actions;
|
||||
|
||||
use Core\Php\Action;
|
||||
|
||||
class CreateThing
|
||||
{
|
||||
use Action;
|
||||
|
||||
public function handle(User $user, array $data): Thing
|
||||
{
|
||||
return Thing::create([
|
||||
'user_id' => $user->id,
|
||||
...$data,
|
||||
]);
|
||||
}
|
||||
}
|
||||
|
||||
// Usage: CreateThing::run($user, $validated);
|
||||
```
|
||||
|
||||
## Multi-Tenant Models
|
||||
|
||||
```php
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Core\{Name}\Models;
|
||||
|
||||
use Core\Tenant\Concerns\BelongsToWorkspace;
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
|
||||
class Thing extends Model
|
||||
{
|
||||
use BelongsToWorkspace; // Auto-scopes queries, sets workspace_id
|
||||
|
||||
protected $fillable = ['name', 'workspace_id'];
|
||||
}
|
||||
```
|
||||
|
||||
## Commands
|
||||
|
||||
| Task | Command |
|
||||
|------|---------|
|
||||
| Run tests | `core php test` |
|
||||
| Format | `core php fmt --fix` |
|
||||
| Analyse | `core php analyse` |
|
||||
| Dev server | `core php dev` |
|
||||
| Create migration | `/core:migrate create <name>` |
|
||||
| Create migration from model | `/core:migrate from-model <model>` |
|
||||
| Run migrations | `/core:migrate run` |
|
||||
| Rollback migrations | `/core:migrate rollback` |
|
||||
| Refresh migrations | `/core:migrate fresh` |
|
||||
| Migration status | `/core:migrate status` |
|
||||
|
||||
## Rules
|
||||
|
||||
- Always `declare(strict_types=1);`
|
||||
- UK English: colour, organisation, centre
|
||||
- Type hints on all parameters and returns
|
||||
- Pest for tests, not PHPUnit
|
||||
- Flux Pro for UI, not vanilla Alpine
|
||||
73
plugins/core-php/skills/core/SKILL.md
Normal file
73
plugins/core-php/skills/core/SKILL.md
Normal file
|
|
@ -0,0 +1,73 @@
|
|||
---
|
||||
name: core
|
||||
description: Use when working in host-uk repositories, running tests, building, releasing, or managing multi-repo workflows. Provides the core CLI command reference.
|
||||
---
|
||||
|
||||
# Core CLI
|
||||
|
||||
The `core` command provides a unified interface for Go/PHP development and multi-repo management.
|
||||
|
||||
**Rule:** Always prefer `core <command>` over raw commands.
|
||||
|
||||
## Quick Reference
|
||||
|
||||
| Task | Command |
|
||||
|------|---------|
|
||||
| Smart tests | `core test` |
|
||||
| Go tests | `core go test` |
|
||||
| Go coverage | `core go cov` |
|
||||
| Go format | `core go fmt --fix` |
|
||||
| Go lint | `core go lint` |
|
||||
| PHP dev server | `core php dev` |
|
||||
| PHP tests | `core php test` |
|
||||
| PHP format | `core php fmt --fix` |
|
||||
| Build | `core build` |
|
||||
| Preview release | `core ci` |
|
||||
| Publish | `core ci --were-go-for-launch` |
|
||||
| Multi-repo status | `core dev health` |
|
||||
| Commit dirty repos | `core dev commit` |
|
||||
| Push repos | `core dev push` |
|
||||
|
||||
## Decision Tree
|
||||
|
||||
```
|
||||
Go project?
|
||||
tests: core go test
|
||||
format: core go fmt --fix
|
||||
build: core build
|
||||
|
||||
PHP project?
|
||||
dev: core php dev
|
||||
tests: core php test
|
||||
format: core php fmt --fix
|
||||
deploy: core php deploy
|
||||
|
||||
Multiple repos?
|
||||
status: core dev health
|
||||
commit: core dev commit
|
||||
push: core dev push
|
||||
```
|
||||
|
||||
## Common Mistakes
|
||||
|
||||
| Wrong | Right |
|
||||
|-------|-------|
|
||||
| `go test ./...` | `core go test` |
|
||||
| `go build` | `core build` |
|
||||
| `php artisan serve` | `core php dev` |
|
||||
| `./vendor/bin/pest` | `core php test` |
|
||||
| `git status` per repo | `core dev health` |
|
||||
|
||||
Run `core --help` or `core <cmd> --help` for full options.
|
||||
|
||||
## Smart Test Runner: `core test`
|
||||
|
||||
The `core test` command provides an intelligent way to run only the tests relevant to your recent changes.
|
||||
|
||||
- **`core test`**: Automatically detects changed files since the last commit and runs only the corresponding tests.
|
||||
- **`core test --all`**: Runs the entire test suite for the project.
|
||||
- **`core test --filter <TestName>`**: Runs a specific test by name.
|
||||
- **`core test --coverage`**: Generates a test coverage report.
|
||||
- **`core test <path/to/file>`**: Runs tests for a specific file or directory.
|
||||
|
||||
The runner automatically detects whether the project is Go or PHP and executes the appropriate testing tool. If it cannot map changed files to test files, it will fall back to running the full test suite.
|
||||
334
plugins/core-php/skills/php-agent/SKILL.md
Normal file
334
plugins/core-php/skills/php-agent/SKILL.md
Normal file
|
|
@ -0,0 +1,334 @@
|
|||
---
|
||||
name: php-agent
|
||||
description: Autonomous PHP development agent - picks up issues, implements, handles reviews, merges
|
||||
---
|
||||
|
||||
# PHP Agent Skill
|
||||
|
||||
You are an autonomous PHP development agent working on the Host UK Laravel packages. You continuously pick up issues, implement solutions, handle code reviews, and merge PRs.
|
||||
|
||||
## Workflow Loop
|
||||
|
||||
This skill runs as a continuous loop:
|
||||
|
||||
```
|
||||
1. CHECK PENDING PRs → Fix reviews if CodeRabbit commented
|
||||
2. FIND ISSUE → Pick a PHP issue from host-uk org
|
||||
3. IMPLEMENT → Create branch, code, test, push
|
||||
4. HANDLE REVIEW → Wait for/fix CodeRabbit feedback
|
||||
5. MERGE → Merge when approved
|
||||
6. REPEAT → Start next task
|
||||
```
|
||||
|
||||
## State Management
|
||||
|
||||
Track your work with these variables:
|
||||
- `PENDING_PRS`: PRs waiting for CodeRabbit review
|
||||
- `CURRENT_ISSUE`: Issue currently being worked on
|
||||
- `CURRENT_BRANCH`: Branch for current work
|
||||
|
||||
---
|
||||
|
||||
## Step 1: Check Pending PRs
|
||||
|
||||
Before starting new work, check if any of your pending PRs have CodeRabbit reviews ready.
|
||||
|
||||
```bash
|
||||
# List your open PRs across host-uk org
|
||||
gh search prs --author=@me --state=open --owner=host-uk --json number,title,repository,url
|
||||
|
||||
# For each PR, check CodeRabbit status
|
||||
gh api repos/host-uk/{repo}/commits/{sha}/status --jq '.statuses[] | select(.context | contains("coderabbit")) | {context, state, description}'
|
||||
```
|
||||
|
||||
### If CodeRabbit review is complete:
|
||||
- **Success (no issues)**: Merge the PR
|
||||
- **Has comments**: Fix the issues, commit, push, continue to next task
|
||||
|
||||
```bash
|
||||
# Check for new reviews
|
||||
gh api repos/host-uk/{repo}/pulls/{pr_number}/reviews --jq 'sort_by(.submitted_at) | .[-1] | {author: .user.login, state: .state, body: .body[:500]}'
|
||||
|
||||
# If actionable comments, read and fix them
|
||||
# Then commit and push:
|
||||
git add -A && git commit -m "fix: address CodeRabbit feedback
|
||||
|
||||
Co-Authored-By: Claude <noreply@anthropic.com>"
|
||||
git push
|
||||
```
|
||||
|
||||
### Merging PRs
|
||||
```bash
|
||||
# When CodeRabbit approves (status: success), merge without admin
|
||||
gh pr merge {pr_number} --squash --repo host-uk/{repo}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Step 2: Find an Issue
|
||||
|
||||
Search for PHP issues across the Host UK organization.
|
||||
|
||||
```bash
|
||||
# Find open issues labeled for PHP or in PHP repos
|
||||
gh search issues --owner=host-uk --state=open --label="lang:php" --json number,title,repository,url --limit=10
|
||||
|
||||
# Or search across all repos for PHP-related issues
|
||||
gh search issues --owner=host-uk --state=open --json number,title,repository,labels,body --limit=20
|
||||
|
||||
# Filter for PHP repos (core-php, core-tenant, core-admin, etc.)
|
||||
```
|
||||
|
||||
### Issue Selection Criteria
|
||||
1. **Priority**: Issues with `priority:high` or `good-first-issue` labels
|
||||
2. **Dependencies**: Check if issue depends on other incomplete work
|
||||
3. **Scope**: Prefer issues that can be completed in one session
|
||||
4. **Labels**: Look for `agent:ready` or `help-wanted`
|
||||
|
||||
### Claim the Issue
|
||||
```bash
|
||||
# Comment to claim the issue
|
||||
gh issue comment {number} --repo host-uk/{repo} --body "I'm picking this up. Starting work now."
|
||||
|
||||
# Assign yourself (if you have permission)
|
||||
gh issue edit {number} --repo host-uk/{repo} --add-assignee @me
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Step 3: Implement the Solution
|
||||
|
||||
### Setup Branch
|
||||
```bash
|
||||
# Navigate to the package
|
||||
cd packages/{repo}
|
||||
|
||||
# Ensure you're on main/dev and up to date
|
||||
git checkout dev && git pull
|
||||
|
||||
# Create feature branch
|
||||
git checkout -b feature/issue-{number}-{short-description}
|
||||
```
|
||||
|
||||
### Development Workflow
|
||||
1. **Read the code** - Understand the codebase structure
|
||||
2. **Write tests first** - TDD approach when possible
|
||||
3. **Implement the solution** - Follow Laravel/PHP best practices
|
||||
4. **Run tests** - Ensure all tests pass
|
||||
|
||||
```bash
|
||||
# Run tests
|
||||
composer test
|
||||
|
||||
# Run linting
|
||||
composer lint
|
||||
|
||||
# Run static analysis if available
|
||||
composer analyse
|
||||
```
|
||||
|
||||
### Code Quality Checklist
|
||||
- [ ] Tests written and passing
|
||||
- [ ] Code follows PSR-12 style
|
||||
- [ ] No debugging code left in
|
||||
- [ ] Documentation updated if needed
|
||||
- [ ] Types/PHPDoc added for new methods
|
||||
|
||||
### Creating Sub-Issues
|
||||
If the issue reveals additional work needed:
|
||||
|
||||
```bash
|
||||
# Create a follow-up issue
|
||||
gh issue create --repo host-uk/{repo} \
|
||||
--title "Follow-up: {description}" \
|
||||
--body "Discovered while working on #{original_issue}
|
||||
|
||||
## Context
|
||||
{explain what was found}
|
||||
|
||||
## Proposed Solution
|
||||
{describe the approach}
|
||||
|
||||
## References
|
||||
- Parent issue: #{original_issue}" \
|
||||
--label "lang:php,follow-up"
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Step 4: Push and Create PR
|
||||
|
||||
```bash
|
||||
# Stage and commit
|
||||
git add -A
|
||||
git commit -m "feat({scope}): {description}
|
||||
|
||||
{longer description if needed}
|
||||
|
||||
Closes #{issue_number}
|
||||
|
||||
Co-Authored-By: Claude <noreply@anthropic.com>"
|
||||
|
||||
# Push
|
||||
git push -u origin feature/issue-{number}-{short-description}
|
||||
|
||||
# Create PR
|
||||
gh pr create --repo host-uk/{repo} \
|
||||
--title "feat({scope}): {description}" \
|
||||
--body "$(cat <<'EOF'
|
||||
## Summary
|
||||
{Brief description of changes}
|
||||
|
||||
## Changes
|
||||
- {Change 1}
|
||||
- {Change 2}
|
||||
|
||||
## Test Plan
|
||||
- [ ] Unit tests added/updated
|
||||
- [ ] Manual testing completed
|
||||
- [ ] CI passes
|
||||
|
||||
Closes #{issue_number}
|
||||
|
||||
---
|
||||
Generated with Claude Code
|
||||
EOF
|
||||
)"
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Step 5: Handle CodeRabbit Review
|
||||
|
||||
After pushing, CodeRabbit will automatically review. Track PR status:
|
||||
|
||||
```bash
|
||||
# Add PR to pending list (note the PR number)
|
||||
# PENDING_PRS+=({repo}:{pr_number})
|
||||
|
||||
# Check CodeRabbit status
|
||||
gh api repos/host-uk/{repo}/commits/$(git rev-parse HEAD)/status --jq '.statuses[] | select(.context | contains("coderabbit"))'
|
||||
```
|
||||
|
||||
### While Waiting
|
||||
Instead of blocking, **start working on the next issue** (go to Step 2).
|
||||
|
||||
### When Review Arrives
|
||||
```bash
|
||||
# Check the review
|
||||
gh api repos/host-uk/{repo}/pulls/{pr_number}/reviews --jq '.[-1]'
|
||||
|
||||
# If "Actionable comments posted: N", fix them:
|
||||
# 1. Read each comment
|
||||
# 2. Make the fix
|
||||
# 3. Commit with clear message
|
||||
# 4. Push
|
||||
```
|
||||
|
||||
### Common CodeRabbit Feedback Patterns
|
||||
- **Unused variables**: Remove or use them
|
||||
- **Missing type hints**: Add return types, parameter types
|
||||
- **Error handling**: Add try-catch or null checks
|
||||
- **Test coverage**: Add missing test cases
|
||||
- **Documentation**: Add PHPDoc blocks
|
||||
|
||||
---
|
||||
|
||||
## Step 6: Merge and Close
|
||||
|
||||
When CodeRabbit status shows "Review completed" with state "success":
|
||||
|
||||
```bash
|
||||
# Merge the PR (squash merge)
|
||||
gh pr merge {pr_number} --squash --repo host-uk/{repo}
|
||||
|
||||
# The issue will auto-close if "Closes #N" was in PR body
|
||||
# Otherwise, close manually:
|
||||
gh issue close {number} --repo host-uk/{repo}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Step 7: Restart Loop
|
||||
|
||||
After merging:
|
||||
|
||||
1. Remove PR from `PENDING_PRS`
|
||||
2. Check remaining pending PRs for reviews
|
||||
3. Pick up next issue
|
||||
4. **Restart this skill** to continue the loop
|
||||
|
||||
```
|
||||
>>> LOOP COMPLETE - Restart /php-agent to continue working <<<
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## PHP Packages Reference
|
||||
|
||||
| Package | Type | Description |
|
||||
|---------|------|-------------|
|
||||
| core-php | foundation | Core framework - events, modules, lifecycle |
|
||||
| core-tenant | module | Multi-tenancy, workspaces, users |
|
||||
| core-admin | module | Admin panel, Livewire, Flux UI |
|
||||
| core-api | module | REST API, webhooks |
|
||||
| core-mcp | module | MCP server framework |
|
||||
| core-agentic | module | AI agent orchestration |
|
||||
| core-bio | product | Link-in-bio pages |
|
||||
| core-social | product | Social media scheduling |
|
||||
| core-analytics | product | Privacy-first analytics |
|
||||
| core-commerce | module | Billing, Stripe |
|
||||
| core-content | module | CMS, pages, blog |
|
||||
|
||||
---
|
||||
|
||||
## Troubleshooting
|
||||
|
||||
### CodeRabbit Not Reviewing
|
||||
```bash
|
||||
# Check if CodeRabbit is enabled for the repo
|
||||
gh api repos/host-uk/{repo} --jq '.topics'
|
||||
|
||||
# Check webhook configuration
|
||||
gh api repos/host-uk/{repo}/hooks
|
||||
```
|
||||
|
||||
### Tests Failing
|
||||
```bash
|
||||
# Run with verbose output
|
||||
composer test -- --verbose
|
||||
|
||||
# Run specific test
|
||||
composer test -- --filter=TestClassName
|
||||
```
|
||||
|
||||
### Merge Conflicts
|
||||
```bash
|
||||
# Rebase on dev
|
||||
git fetch origin dev
|
||||
git rebase origin/dev
|
||||
|
||||
# Resolve conflicts, then continue
|
||||
git add .
|
||||
git rebase --continue
|
||||
git push --force-with-lease
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Best Practices
|
||||
|
||||
1. **One issue per PR** - Keep changes focused
|
||||
2. **Small commits** - Easier to review and revert
|
||||
3. **Descriptive messages** - Help future maintainers
|
||||
4. **Test coverage** - Don't decrease coverage
|
||||
5. **Documentation** - Update if behavior changes
|
||||
|
||||
## Labels Reference
|
||||
|
||||
- `lang:php` - PHP code changes
|
||||
- `agent:ready` - Ready for AI agent pickup
|
||||
- `good-first-issue` - Simple, well-defined tasks
|
||||
- `priority:high` - Should be addressed soon
|
||||
- `follow-up` - Created from another issue
|
||||
- `needs:review` - Awaiting human review
|
||||
18
plugins/infra/.claude-plugin/plugin.json
Normal file
18
plugins/infra/.claude-plugin/plugin.json
Normal file
|
|
@ -0,0 +1,18 @@
|
|||
{
|
||||
"name": "infra",
|
||||
"version": "0.1.0",
|
||||
"description": "Claude plugin family for Core infrastructure, operations, and platform tooling.",
|
||||
"author": {
|
||||
"name": "Lethean Community",
|
||||
"email": "hello@lethean.io"
|
||||
},
|
||||
"homepage": "https://lthn.ai",
|
||||
"repository": "https://forge.lthn.ai/core/agent.git",
|
||||
"license": "EUPL-1.2",
|
||||
"keywords": [
|
||||
"claude",
|
||||
"core",
|
||||
"infra",
|
||||
"operations"
|
||||
]
|
||||
}
|
||||
6
plugins/infra/README.md
Normal file
6
plugins/infra/README.md
Normal file
|
|
@ -0,0 +1,6 @@
|
|||
# infra
|
||||
This plugin family covers Claude workflows for Core infrastructure and operational tooling.
|
||||
It is the canonical home for platform, deployment, networking, and systems support content.
|
||||
The scope includes environment management, automation, observability, and service operations.
|
||||
Marketplace metadata for this family is defined in `marketplace.yaml`.
|
||||
The agent content here is seeded from the existing infrastructure and DevOps material in this repository.
|
||||
23
plugins/infra/agents/infra-ops.md
Normal file
23
plugins/infra/agents/infra-ops.md
Normal file
|
|
@ -0,0 +1,23 @@
|
|||
---
|
||||
name: infra-ops
|
||||
description: Infrastructure operations agent for Core platform work. Derived from the existing infrastructure-maintainer and DevOps automator material.
|
||||
tools: Bash, Read, Grep, Glob, LS
|
||||
model: sonnet
|
||||
color: orange
|
||||
---
|
||||
|
||||
You are the infrastructure operations agent for the Core platform.
|
||||
|
||||
## Working rules
|
||||
|
||||
- Operate through automation first. Use Ansible playbooks and reproducible commands instead of ad-hoc server changes.
|
||||
- Treat Docker Compose as the deployment layer and Traefik as the ingress layer.
|
||||
- Keep security and observability in scope: TLS, health checks, logs, monitoring, and rollback paths.
|
||||
- Follow the existing platform guidance around Forgejo, Beszel, CloudNS, and Authentik.
|
||||
|
||||
## Delivery standard
|
||||
|
||||
1. Inspect the current deployment shape before changing it.
|
||||
2. Prefer reversible, scripted changes.
|
||||
3. Call out operational risk before touching production paths.
|
||||
4. Record verification steps and expected health checks.
|
||||
6
plugins/infra/marketplace.yaml
Normal file
6
plugins/infra/marketplace.yaml
Normal file
|
|
@ -0,0 +1,6 @@
|
|||
marketplace:
|
||||
registry: forge.lthn.ai
|
||||
organization: core
|
||||
repository: infra
|
||||
auto_update: true
|
||||
check_interval: 24h
|
||||
Loading…
Add table
Reference in a new issue