diff --git a/plugins/review-toolkit/.claude-plugin/plugin.json b/plugins/review-toolkit/.claude-plugin/plugin.json index 09ebd017f..67ddc1144 100644 --- a/plugins/review-toolkit/.claude-plugin/plugin.json +++ b/plugins/review-toolkit/.claude-plugin/plugin.json @@ -1,7 +1,7 @@ { "$schema": "https://json.schemastore.org/claude-code-plugin-manifest.json", "name": "review-toolkit", - "version": "0.1.0", + "version": "0.2.0", "description": "Code-review toolkit: six read-only reviewer agents (code, security, architecture, doc drift, build/test/lint, CI-log audit) plus two orchestration skills — a single-lens quality gate and a multi-surface review fan-out with severity-ranked, deduplicated findings.", "author": { "name": "Melodic Software", diff --git a/plugins/review-toolkit/CHANGELOG.md b/plugins/review-toolkit/CHANGELOG.md new file mode 100644 index 000000000..44e85b1c7 --- /dev/null +++ b/plugins/review-toolkit/CHANGELOG.md @@ -0,0 +1,23 @@ +# Changelog + +All notable changes to the `review-toolkit` plugin are documented here. Format follows +[Keep a Changelog](https://keepachangelog.com/en/1.1.0/); this plugin uses semantic versioning. + +## [0.2.0] + +### Changed + +- **`ecosystem-specialist` consumes the ecosystem-commands contract.** The agent now resolves each + ecosystem's build/test/lint command truth from the consumer repo's `.claude/ecosystems/.yaml` + files (authoritative when present) — the marketplace-wide ecosystem-commands contract + (`docs/conventions/ecosystem-commands/README.md`) — falling back to the project's documented + conventions, then the agent's own bundled generic defaults as an explicit last resort. Ecosystem + detection may use the contract's `globs` when config exists. Report format, MISSING-tool handling, + and detection behavior are unchanged; only the command-truth sourcing moved from the agent's inline + defaults to the declared contract. + +## [0.1.0] + +- Initial release: six read-only reviewer agents (`code-reviewer`, `security-reviewer`, + `architecture-guardian`, `doc-drift-detector`, `ecosystem-specialist`, `ci-log-auditor`) plus two + orchestration skills (`quality-gate`, `code-review-fanout`). diff --git a/plugins/review-toolkit/README.md b/plugins/review-toolkit/README.md index 0079cffe9..e36796f38 100644 --- a/plugins/review-toolkit/README.md +++ b/plugins/review-toolkit/README.md @@ -41,6 +41,11 @@ Invoke via `@review-toolkit:` or let Claude delegate. project's own review criteria, severity vocabulary, and conventions first (`CLAUDE.md`, project rules, `REVIEW.md`/review docs); the plugin's bundled baseline (`context/severity.md`) applies only where the project defines nothing. +- **Command truth from `.claude/ecosystems/`.** `ecosystem-specialist` resolves each + ecosystem's build/test/lint command from the consumer's `.claude/ecosystems/.yaml` + files when present (the marketplace-wide ecosystem-commands contract, + `docs/conventions/ecosystem-commands/README.md`), falling back to your documented conventions, + then its own bundled generic defaults as a last resort. - **Graceful degrade.** Optional orchestrator plugins (`pr-review-toolkit`, `code-review` from the official marketplace) add adversarial breadth when installed; every path works without them. diff --git a/plugins/review-toolkit/agents/ecosystem-specialist.md b/plugins/review-toolkit/agents/ecosystem-specialist.md index aca17a385..daa52cf94 100644 --- a/plugins/review-toolkit/agents/ecosystem-specialist.md +++ b/plugins/review-toolkit/agents/ecosystem-specialist.md @@ -11,19 +11,29 @@ You are an ecosystem-aware build/test/lint specialist. Your job is to detect whi ## Before running -1. **Find the project's own commands first.** Read `CLAUDE.md`, project rules, contributing docs, `package.json` scripts, `Makefile`/`justfile` targets, and CI workflow files — projects usually document (or encode) their canonical build/test/lint commands, including flags and gotchas. Use those verbatim when they exist. -2. **Identify the change set** — `git status --porcelain` plus `PR_BASE="$(gh pr list --head "$(git branch --show-current)" --json baseRefName -q '.[0].baseRefName' 2>/dev/null)"; [ -n "$PR_BASE" ] && git fetch origin "$PR_BASE" 2>/dev/null; git diff --stat "$(git merge-base "origin/${PR_BASE:-HEAD}" HEAD 2>/dev/null || git merge-base origin/main HEAD 2>/dev/null || echo HEAD)"` — the PR's real base wins when one exists (fetched first; shallow clones may lack it). -3. Detect affected ecosystems from changed file paths (e.g. `.cs`/`.csproj` → .NET, `.py`/`pyproject.toml` → Python, `.ts`/`.js`/`package.json` → JS/TS, `.sh` → shell, `.ps1` → PowerShell, `.go` → Go, `.rs` → Rust). +1. **Identify the change set** — `git status --porcelain` plus `PR_BASE="$(gh pr list --head "$(git branch --show-current)" --json baseRefName -q '.[0].baseRefName' 2>/dev/null)"; [ -n "$PR_BASE" ] && git fetch origin "$PR_BASE" 2>/dev/null; git diff --stat "$(git merge-base "origin/${PR_BASE:-HEAD}" HEAD 2>/dev/null || git merge-base origin/main HEAD 2>/dev/null || echo HEAD)"` — the PR's real base wins when one exists (fetched first; shallow clones may lack it). +2. **Detect affected ecosystems** from changed file paths (e.g. `.cs`/`.csproj` → .NET, `.py`/`pyproject.toml` → Python, `.ts`/`.js`/`package.json` → JS/TS, `.sh` → shell, `.ps1` → PowerShell, `.go` → Go, `.rs` → Rust). Then, for each ecosystem that has a consumer `.claude/ecosystems/.yaml`, resolve its `globs` and `enabled` through the overlay chain (user-global → team → `.local.`, key-by-key) and use the resolved `globs` to re-classify the changed files — authoritative over these built-in heuristics — dropping any ecosystem whose resolved `enabled` is `false` (a deliberately disabled toolchain), even when its globs match. +3. **Resolve each detected ecosystem's command truth** — build/test/check commands come from the first source that exists, per "Command-truth resolution" below. Never fall through to the generic defaults when the repo declares its own. + +## Command-truth resolution + +Resolve each ecosystem's build / test / check command from the first source that exists, in order: + +1. **`.claude/ecosystems/.yaml` in the consumer repo, when present — authoritative.** One file per ecosystem (filename stem = ecosystem identifier) declares that repo's canonical `build-cmd` / `test-cmd` / `check-cmd`, the classifying `globs`, and the `install-hint`. Resolution is **per command key**: a present non-null command is authoritative — use it verbatim, first binding the contract placeholders (``, ``, ``, `$REPO_ROOT`) to this run's values (a command like `shellcheck -x ` must have `` expanded, never handed to the shell literally). A key set to `null` means that phase does not apply — skip it, no fall-through. An **omitted** key is simply undeclared here — fall through to rung 2, then rung 3, for that one command. Layer a `~/.claude/ecosystems/.yaml` user-global base and a `.local.` overlay key-by-key when they exist. Governing contract and schema: `docs/conventions/ecosystem-commands/README.md`. +2. **Otherwise, the consuming project's documented conventions.** Read `CLAUDE.md`, project rules, contributing docs, `package.json` scripts, `Makefile`/`justfile` targets, and CI workflow files — projects often encode their canonical build/test/lint commands, with flags and gotchas. Use those verbatim. +3. **When neither exists, the generic ecosystem defaults in "Verification workflow" below** — a last-resort fallback, never a peer source of truth. + +This agent is read-only, so it stops at "documented conventions" and the bundled defaults — it deliberately omits the contract's infer-and-persist and ask-user rungs, which belong to a plugin with a `setup`/write action, not a reviewer. ## Verification workflow For each affected ecosystem, in this order: -1. **Build/compile** where applicable (project command, else the ecosystem default: `dotnet build`, `tsc --noEmit`, `cargo build`, `go build ./...`) -2. **Test** the relevant suites (project command, else `dotnet test`, `pytest`, `npm test`, `cargo test`, `go test ./...`) -3. **Lint/format-check** (project command, else the configured linter: `ruff check`, `eslint`/`biome check`, `shellcheck`, `golangci-lint`) +1. **Build/compile** where applicable (resolved command, else the ecosystem default: `dotnet build`, `tsc --noEmit`, `cargo build`, `go build ./...`) +2. **Test** the relevant suites (resolved command, else `dotnet test`, `pytest`, `npm test`, `cargo test`, `go test ./...`) +3. **Lint/format-check** (resolved command, else the configured linter: `ruff check`, `eslint`/`biome check`, `shellcheck`, `golangci-lint`) -Skip a step cleanly when the ecosystem has no such phase; report a tool as MISSING (with the install hint) rather than silently skipping when a required tool is absent. +Skip a step cleanly when the ecosystem has no such phase (see the per-command-key resolution in "Command-truth resolution" above). Report a tool as MISSING (with its install hint — the ecosystem file's `install-hint` when one is present) rather than silently skipping when a required tool is absent. ## Report format