chore: import upstream snapshot with attribution

This commit is contained in:
wehub-resource-sync
2026-07-13 12:36:35 +08:00
commit d389869988
1095 changed files with 222202 additions and 0 deletions
+147
View File
@@ -0,0 +1,147 @@
name: Claude Code Review
on:
pull_request:
types: [opened, synchronize, ready_for_review, reopened]
jobs:
claude-review:
if: |
github.event.pull_request.draft == false &&
github.actor != 'dependabot[bot]' &&
github.event.pull_request.user.login != 'dependabot[bot]' &&
github.event.pull_request.head.repo.full_name == github.repository
runs-on: ubuntu-latest
permissions:
contents: read
pull-requests: write
issues: read
id-token: write
steps:
- name: Checkout repository
uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4
with:
fetch-depth: 1
persist-credentials: false
- name: Run Claude Code Review
id: claude-review
uses: anthropics/claude-code-action@4481e6d3c7bbb88db2a928ca3444c536f589c7c1 # v1
with:
claude_code_oauth_token: ${{ secrets.CLAUDE_CODE_OAUTH_TOKEN }}
track_progress: true
prompt: |
REPO: ${{ github.repository }}
PR NUMBER: ${{ github.event.pull_request.number }}
You are reviewing a PR for claude-agents — a multi-harness
agentic plugin marketplace (Claude Code, Codex CLI, Cursor,
OpenCode, Gemini CLI) with 82+ plugins, 191+ agents, 155+
skills, and 102+ commands. The source of truth is Markdown
under `plugins/`; per-harness artifacts under `.codex/`,
`.cursor-plugin/`, `.cursor/rules/`, `.opencode/`, and the
top-level `skills/`/`agents/`/`commands/` directories are
generated by `make generate HARNESS=<name>` and are
gitignored.
Read `AGENTS.md` at the repo root (canonical context) before
starting. Consult `docs/authoring.md` for plugin / agent /
skill frontmatter shapes, `docs/harnesses.md` for per-harness
capability deltas, and `docs/plugins.md` for the catalog.
## Review checklist
1. **Source-of-truth invariant** — Only `plugins/`,
`.claude-plugin/marketplace.json`, `docs/`, `tools/`, and
top-level Markdown (`AGENTS.md`, `CLAUDE.md`, `GEMINI.md`,
`README.md`, `ARCHITECTURE.md`, `CONTRIBUTING.md`) should
be hand-edited. Flag any change under `.codex/`,
`.cursor-plugin/`, `.cursor/rules/`, `.opencode/`, or
top-level `skills/`/`agents/`/`commands/` at the extension
root — those are generated artifacts and must not be
committed by hand.
2. **Plugin / agent / skill frontmatter** — Every agent under
`plugins/*/agents/*.md` needs `name:`, `description:`, and
a `model:` tier. Every skill under
`plugins/*/skills/*/SKILL.md` needs `name:` and
`description:`. Plugin directory names must be lowercase,
hyphen-separated, and must NOT contain `__` (that is the
adapter namespace separator — see `docs/authoring.md`).
3. **Cross-harness portability** — Content should work across
all five harnesses unless explicitly marked Claude-Code-
only in `CLAUDE.md`. Watch for hard dependencies on
Claude-Code-only primitives (`TodoWrite`, the `Task` /
`Agent` spawn tool, per-agent `tools:` frontmatter) without
a documented fallback. Locked agents (`tools: []`) get
special-cased by the OpenCode adapter — preserve that
contract.
4. **Codex 8 KB skill body cap** — Skill bodies in
`plugins/*/skills/*/SKILL.md` should fit under ~8 KB after
adapter transpilation; overflow belongs in
`references/details.md`. `make garden` flags oversize
skills; if a new or edited skill is borderline, suggest
splitting before merge.
5. **Canonical context sync** — `AGENTS.md` is the single
source of truth; `CLAUDE.md` imports it via `@AGENTS.md`
and `GEMINI.md` mirrors it. If any of the three diverge in
this PR, call it out. Per OpenAI's harness-engineering
practice, `AGENTS.md` must stay under ~150 lines — detail
belongs in `docs/`.
6. **Quality gates** — Will this break
`make validate STRICT=1`, `make garden`, `make test`, or
`make smoke-test`? Reference the relevant gate by name in
your finding so the author knows what to run.
7. **Catalog drift** — New, removed, or renamed plugins,
agents, skills, or commands should be reflected in
`docs/plugins.md`, `docs/agents.md`, and
`docs/agent-skills.md` counts and lists. The plugin total
in `AGENTS.md` and `README.md` should also stay in sync.
8. **Python tooling correctness** — Code under `tools/` uses
uv + ruff + ty (NOT pip / mypy / black). Flag any
reintroduction of `pip`, `requirements.txt`, `mypy`, or
`black`. Watch for unhandled errors in adapter code,
broken JSON in `plugin.json` or `marketplace.json`, and
missing tests under `tools/tests/`.
9. **Security** — No secrets in code or workflow files; no
destructive git in scripts (`push --force`,
`reset --hard`, `branch -D`); no shell injection in
`Bash(...)` allowlists or hook scripts; pinned action SHAs
and `persist-credentials: false` on any new GitHub
workflow (match the style in
`.github/workflows/validate.yml`).
## Output rules
- Use inline comments
(`mcp__github_inline_comment__create_inline_comment`) for
specific issues tied to a line of code.
- Use `gh pr comment` for a short summary (≤ 10 lines) at
the end.
- If no critical issues are found, post a single one-line
✅ summary via `gh pr comment` and stop — do NOT attempt to
submit a formal review approval (no review-submission tool
is exposed).
- Do NOT comment on formatting, import order, or naming
style — `ruff` and `ty` handle that.
- Do NOT suggest documentation or comment additions unless a
public-facing doc count or catalog entry is wrong.
- Do NOT re-raise issues already flagged by `coderabbitai`
or `chatgpt-codex-connector` in this PR's existing
comments — read them first via
`gh api repos/${{ github.repository }}/pulls/${{ github.event.pull_request.number }}/comments`.
- Be concise: one sentence per finding is enough. Prefer
actionable suggestions (diff blocks) over prose.
claude_args: |
--model claude-opus-4-7
--allowedTools "mcp__github_inline_comment__create_inline_comment,Bash(gh pr comment:*),Bash(gh pr diff:*),Bash(gh pr view:*),Bash(gh api repos/*/pulls/*/comments:*)"
+79
View File
@@ -0,0 +1,79 @@
name: Claude Code
on:
issue_comment:
types: [created]
pull_request_review_comment:
types: [created]
issues:
# `edited` (not `assigned`) is the actionable event here: the `if:`
# block below checks `github.event.issue.body` / `.title` for
# `@claude`, which only changes on edit. Reassignment would fire
# the workflow without any matching body/title change.
types: [opened, edited]
pull_request_review:
types: [submitted]
jobs:
claude:
# Gate on author_association so only repo owners / members /
# collaborators (who already have write access) can trigger this
# workflow — required because the job is granted write scopes below.
if: |
(
github.event_name == 'issue_comment' &&
contains(github.event.comment.body, '@claude') &&
contains(fromJSON('["OWNER","MEMBER","COLLABORATOR"]'), github.event.comment.author_association)
) ||
(
github.event_name == 'pull_request_review_comment' &&
contains(github.event.comment.body, '@claude') &&
contains(fromJSON('["OWNER","MEMBER","COLLABORATOR"]'), github.event.comment.author_association)
) ||
(
github.event_name == 'pull_request_review' &&
contains(github.event.review.body, '@claude') &&
contains(fromJSON('["OWNER","MEMBER","COLLABORATOR"]'), github.event.review.author_association)
) ||
(
github.event_name == 'issues' &&
(contains(github.event.issue.body, '@claude') || contains(github.event.issue.title, '@claude')) &&
contains(fromJSON('["OWNER","MEMBER","COLLABORATOR"]'), github.event.issue.author_association)
)
runs-on: ubuntu-latest
permissions:
contents: write
pull-requests: write
issues: write
id-token: write
actions: read # Required for Claude to read CI results on PRs
steps:
- name: Checkout repository
uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4
with:
fetch-depth: 1
persist-credentials: false
- name: Run Claude Code
id: claude
uses: anthropics/claude-code-action@4481e6d3c7bbb88db2a928ca3444c536f589c7c1 # v1
with:
claude_code_oauth_token: ${{ secrets.CLAUDE_CODE_OAUTH_TOKEN }}
# This is an optional setting that allows Claude to read CI results on PRs
additional_permissions: |
actions: read
# Tools tailored to this repo's uv-native Python toolchain.
# See AGENTS.md for the canonical command reference.
#
# Both `gh` and `git` are enumerated to safe subcommands only.
# Writes that need a commit/branch are handled by the action
# itself via the GitHub API (see action.yml `branch_prefix` /
# `branch_name_template` inputs) — local `git add/commit/push`
# is not in the allowlist, so destructive variants
# (`push --force`, `reset --hard`, `branch -D`, `tag -d`,
# `checkout -- .`, `clean -fd`) are unreachable.
claude_args: |
--model claude-opus-4-7
--allowedTools "Edit,Write,Read,Bash(uv:*),Bash(make:*),Bash(python:*),Bash(python3:*),Bash(ruff:*),Bash(ty:*),Bash(pytest:*),Bash(gh pr view:*),Bash(gh pr diff:*),Bash(gh pr list:*),Bash(gh pr comment:*),Bash(gh pr edit:*),Bash(gh pr checks:*),Bash(gh issue view:*),Bash(gh issue list:*),Bash(gh issue comment:*),Bash(gh issue edit:*),Bash(gh api repos/*/pulls/*/comments:*),Bash(gh api repos/*/issues/*/comments:*),Bash(gh api repos/*/issues/*/timeline:*),Bash(gh run view:*),Bash(gh workflow view:*),Bash(gh search:*),Bash(git status:*),Bash(git diff:*),Bash(git log:*),Bash(git show:*),Bash(git rev-parse:*),Bash(git ls-files:*),mcp__github_inline_comment__create_inline_comment"
+162
View File
@@ -0,0 +1,162 @@
name: Code Quality
on:
pull_request:
branches: [main]
push:
branches: [main]
workflow_dispatch:
# Read-only lint workflow — no writes back to the repo, no deployments.
permissions:
contents: read
jobs:
python-lint:
name: Python (ruff + ty)
runs-on: ubuntu-latest
defaults:
run:
working-directory: plugins/plugin-eval
steps:
- uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4
with:
persist-credentials: false
- name: Install uv
uses: astral-sh/setup-uv@e58605a9b6da7c637471fab8847a5e5a6b8df081 # v5
with:
enable-cache: true
- name: Set up Python
run: uv python install
- name: Sync plugin-eval dev dependencies
run: uv sync --all-extras
- name: ruff check (lint)
# Scope: adapter framework + plugin-eval. yt-design-extractor.py is legacy
# and out of scope for the multi-harness work; not gated.
run: |
uv run ruff check \
../../tools/adapters/ \
../../tools/generate.py \
../../tools/validate_generated.py \
../../tools/doc_gardener.py \
../../tools/tests/ \
src/plugin_eval/
- name: ruff format --check
run: |
uv run ruff format --check \
../../tools/adapters/ \
../../tools/generate.py \
../../tools/validate_generated.py \
../../tools/doc_gardener.py \
../../tools/tests/ \
src/plugin_eval/
- name: ty type-check
run: |
uv run ty check \
../../tools/adapters/ \
../../tools/generate.py \
../../tools/validate_generated.py \
../../tools/doc_gardener.py \
../../tools/tests/ \
src/plugin_eval/
markdown-lint:
name: Markdown (markdownlint-cli2)
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4
with:
persist-credentials: false
- name: Set up Node.js
uses: actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020 # v4
with:
node-version: '20'
- name: markdownlint
# Lints top-level guides (README, AGENTS, ARCHITECTURE, CLAUDE, per-harness
# setup, CONTRIBUTING) and our authored docs/. Per-plugin READMEs are owned
# by their plugin authors and not lint-gated here — they should be authored
# to spec, but lint enforcement happens at the plugin-author layer, not at
# the framework PR layer.
# Config in .markdownlint.json keeps the ruleset narrow and pragmatic.
uses: DavidAnson/markdownlint-cli2-action@eb5ca3ab411449c66620fe7f1b3c9e10547144b0 # v18
with:
globs: |
*.md
docs/*.md
config: .markdownlint.json
json-lint:
name: JSON / TOML / YAML syntax
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4
with:
persist-credentials: false
- name: Install uv
uses: astral-sh/setup-uv@e58605a9b6da7c637471fab8847a5e5a6b8df081 # v5
with:
enable-cache: true
- name: Set up Python
run: uv python install 3.12
- name: Validate every JSON file
run: |
set -e
shopt -s globstar nullglob
failed=0
for f in **/*.json; do
# Skip generated trees and node_modules
case "$f" in
.codex/*|.cursor/*|.cursor-plugin/*|.opencode/*|node_modules/*|skills/*|agents/*|commands/*) continue ;;
esac
if ! uv run python -m json.tool "$f" > /dev/null 2>&1; then
echo "::error file=$f::invalid JSON"
failed=1
fi
done
exit $failed
- name: Validate every TOML file
run: |
set -e
shopt -s globstar nullglob
failed=0
for f in **/*.toml; do
case "$f" in
.codex/*|.cursor/*|.cursor-plugin/*|.opencode/*|node_modules/*|commands/*) continue ;;
esac
if ! uv run python -c "import tomllib, sys; tomllib.loads(open(sys.argv[1]).read())" "$f" 2>/dev/null; then
echo "::error file=$f::invalid TOML"
failed=1
fi
done
exit $failed
- name: Validate every YAML file
run: |
set -e
shopt -s globstar nullglob
failed=0
for f in **/*.yml **/*.yaml; do
case "$f" in
.codex/*|.cursor/*|.cursor-plugin/*|.opencode/*|node_modules/*) continue ;;
esac
# Use safe_load_all to handle multi-document YAML (e.g. Kubernetes manifests
# with `---` document separators — valid YAML, but safe_load only reads the
# first doc and would mis-flag the file as invalid).
if ! uv run --with pyyaml python -c "import yaml, sys; list(yaml.safe_load_all(open(sys.argv[1]).read()))" "$f" 2>/dev/null; then
echo "::error file=$f::invalid YAML"
failed=1
fi
done
exit $failed
+73
View File
@@ -0,0 +1,73 @@
name: Plugin Eval Report
on:
workflow_dispatch:
inputs:
depth:
description: 'Evaluation depth (quick = static only, standard = +LLM judge, deep = +Monte Carlo)'
required: true
default: 'quick'
type: choice
options:
- quick
- standard
- deep
only_changed:
description: 'Comma-separated plugin names to evaluate (blank = all)'
required: false
default: ''
type: string
schedule:
# Weekly full static sweep, Mondays at 06:00 UTC
- cron: '0 6 * * 1'
permissions:
contents: read
jobs:
eval:
name: Evaluate plugins (${{ inputs.depth || 'quick' }})
runs-on: ubuntu-latest
timeout-minutes: 180
env:
DEPTH: ${{ inputs.depth || 'quick' }}
ONLY_CHANGED: ${{ inputs.only_changed || '' }}
steps:
- uses: actions/checkout@v4
- name: Install uv
uses: astral-sh/setup-uv@v5
with:
enable-cache: true
- name: Sync plugin-eval dependencies
working-directory: plugins/plugin-eval
run: uv sync --all-extras
- name: Run eval sweep
working-directory: plugins/plugin-eval
env:
ANTHROPIC_API_KEY: ${{ secrets.ANTHROPIC_API_KEY }}
run: |
args=( --depth "$DEPTH" --output-dir "$GITHUB_WORKSPACE/eval-reports" --concurrency 4 )
if [ -n "$ONLY_CHANGED" ]; then
args+=( --only-changed "$ONLY_CHANGED" )
fi
uv run python scripts/eval_all.py "${args[@]}"
- name: Post report to job summary
if: always()
run: |
if [ -f eval-reports/summary.md ]; then
cat eval-reports/summary.md >> "$GITHUB_STEP_SUMMARY"
else
echo "No summary produced." >> "$GITHUB_STEP_SUMMARY"
fi
- name: Upload reports artifact
if: always()
uses: actions/upload-artifact@v4
with:
name: eval-reports-${{ env.DEPTH }}-${{ github.run_id }}
path: eval-reports/
retention-days: 30
+272
View File
@@ -0,0 +1,272 @@
name: Validate
on:
pull_request:
branches: [main]
push:
branches: [main]
workflow_dispatch:
permissions:
contents: read
jobs:
validate-json:
name: Validate JSON files
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4
with:
persist-credentials: false
- name: Validate marketplace.json
run: python3 -m json.tool .claude-plugin/marketplace.json > /dev/null
- name: Validate every plugin.json
run: |
set -e
shopt -s globstar nullglob
failed=0
for f in plugins/*/.claude-plugin/plugin.json; do
if ! python3 -m json.tool "$f" > /dev/null 2>&1; then
echo "::error file=$f::invalid JSON"
failed=1
fi
done
exit $failed
- name: Validate hooks.json files
run: |
set -e
shopt -s globstar nullglob
failed=0
for f in plugins/*/hooks/*.json; do
if ! python3 -m json.tool "$f" > /dev/null 2>&1; then
echo "::error file=$f::invalid JSON"
failed=1
fi
done
exit $failed
- name: Validate marketplace entries resolve to plugin dirs
run: |
python3 - <<'PY'
import json, os, posixpath, sys
from urllib.parse import urlparse
with open('.claude-plugin/marketplace.json') as f:
mp = json.load(f)
errors = []
for p in mp.get('plugins', []):
src = p.get('source')
if isinstance(src, str) and src.startswith('./plugins/'):
path = src.lstrip('./')
if not os.path.isdir(path):
errors.append(f"{p['name']}: source {src} does not exist")
elif not os.path.isfile(os.path.join(path, '.claude-plugin', 'plugin.json')):
errors.append(f"{p['name']}: missing .claude-plugin/plugin.json in {src}")
elif isinstance(src, dict):
if src.get('source') != 'git-subdir':
errors.append(f"{p['name']}: unsupported source object {src.get('source')!r}")
continue
extra_keys = set(src) - {'source', 'url', 'path'}
if extra_keys:
errors.append(f"{p['name']}: git-subdir entry has unsupported keys: {sorted(extra_keys)}")
url = src.get('url')
path = src.get('path')
if not url:
errors.append(f"{p['name']}: git-subdir entry missing url")
else:
parsed = urlparse(url)
if parsed.scheme != 'https' or parsed.netloc != 'github.com' or not parsed.path.endswith('.git'):
errors.append(f"{p['name']}: git-subdir url must be an https://github.com/*.git URL")
if not path:
errors.append(f"{p['name']}: git-subdir entry missing path")
elif path != '.':
normalized = posixpath.normpath(path)
if (
path.startswith('/')
or '\\' in path
or normalized != path
or normalized == '..'
or normalized.startswith('../')
):
errors.append(f"{p['name']}: git-subdir path must be a normalized relative path")
if errors:
for e in errors:
print(f"::error::{e}")
sys.exit(1)
print(f"OK: {len(mp.get('plugins', []))} marketplace entries validated")
PY
- name: Check agent name uniqueness
run: python3 tools/check_agent_name_collisions.py --fail-on-duplicates
plugin-eval-tests:
name: plugin-eval pytest
runs-on: ubuntu-latest
defaults:
run:
working-directory: plugins/plugin-eval
steps:
- uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4
with:
persist-credentials: false
- name: Install uv
uses: astral-sh/setup-uv@e58605a9b6da7c637471fab8847a5e5a6b8df081 # v5
with:
enable-cache: true
- name: Set up Python
run: uv python install
- name: Sync dependencies
run: uv sync --all-extras
- name: Run tests
run: uv run pytest
tools-tests:
name: tools pytest (adapters + validators + gardener)
runs-on: ubuntu-latest
defaults:
run:
working-directory: plugins/plugin-eval
steps:
- uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4
with:
persist-credentials: false
- name: Install uv
uses: astral-sh/setup-uv@e58605a9b6da7c637471fab8847a5e5a6b8df081 # v5
with:
enable-cache: true
- name: Set up Python
run: uv python install
- name: Sync dependencies
run: uv sync --all-extras
- name: Run tools test suite
run: uv run pytest -q ../../tools/tests/
multi-harness-generate:
name: Cross-harness generation + validation
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4
with:
persist-credentials: false
- name: Install uv
uses: astral-sh/setup-uv@e58605a9b6da7c637471fab8847a5e5a6b8df081 # v5
with:
enable-cache: true
- name: Set up Python
run: uv python install 3.12
- name: Sync plugin-eval venv (provides pyyaml + adapter imports)
working-directory: plugins/plugin-eval
run: uv sync --all-extras
- name: Generate all harness artifacts
run: make generate-all
- name: Verify committed artifacts are in sync with sources
# Native-install artifacts are committed so the repo installs from a clone.
# Regeneration must produce no diff — if it does, a source change was committed
# without running `make generate-all`. Run it locally and commit the result.
run: |
if [ -n "$(git status --porcelain)" ]; then
echo "::error::Generated artifacts drifted from the committed tree. Run 'make generate-all' and commit the result."
git status --short
git --no-pager diff --stat
exit 1
fi
echo "OK: committed harness artifacts match a fresh 'make generate-all'."
- name: Structural validation (strict)
run: make validate STRICT=1
- name: Doc-gardener (no errors allowed)
# Errors fail this step; warnings (e.g. oversized source skills with no
# references/) are surfaced but don't block. Use STRICT=1 to gate on warnings too.
run: make garden
- name: Upload generated artifacts for inspection
if: always()
uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4
with:
name: multi-harness-output
path: |
.codex/
.cursor/
.cursor-plugin/
.opencode/
opencode.json
commands/
agents/
skills/
AGENTS.md
retention-days: 7
cli-smoke-test:
name: Real-CLI smoke test (OpenCode + Gemini)
runs-on: ubuntu-latest
# Real-CLI subprocess tests: invokes the actual harness binaries against our
# generated artifacts to catch issues that pure-Python parsing misses (CLI
# version drift, schema-loader surprises, plugin discovery bugs).
steps:
- uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4
with:
persist-credentials: false
- name: Set up Node.js (for Gemini CLI)
uses: actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020 # v4
with:
node-version: '20'
- name: Set up Bun (for OpenCode CLI)
uses: oven-sh/setup-bun@0c5077e51419868618aeaa5fe8019c62421857d6 # v2
with:
bun-version: latest
- name: Install OpenCode CLI
run: |
curl -fsSL https://opencode.ai/install | bash
echo "$HOME/.opencode/bin" >> "$GITHUB_PATH"
- name: Install Gemini CLI
# Pinned to the released line we developed against; bump alongside any
# gemini-extension.json schema changes.
run: npm install -g @google/gemini-cli@latest
- name: Verify CLI versions
run: |
opencode --version
gemini --version
- name: Install uv
uses: astral-sh/setup-uv@e58605a9b6da7c637471fab8847a5e5a6b8df081 # v5
with:
enable-cache: true
- name: Set up Python
run: uv python install 3.12
- name: Sync plugin-eval dependencies
working-directory: plugins/plugin-eval
run: uv sync --all-extras
- name: Generate all harness artifacts
run: make generate-all
- name: Run real-CLI smoke tests
working-directory: plugins/plugin-eval
run: uv run pytest -v ../../tools/tests/test_cli_smoke.py