Run build, test, and lint verification for changed files, auto-detecting affected ecosystems (.NET, Python, TypeScript, Bash, PowerShell, Markdown) from git status, with the consuming project's own documented commands overriding portable defaults. Use when: 'does it compile', 'run tests', 'build it', 'run the tests', 'does this still build', 'check it', or after any code edit; for lint-only use /toolchain:lint, for full outcome verification use /verification:confirm.
Scanned 9/2/2026
Install to Claude Code
npx -y skills add melodic-software/claude-code-plugins --skill check --agent claude-codeInstalls into .claude/skills of the current project.
Are you the author of Check?
Add the live security badge to your README — it updates automatically with every re-scan.
[](https://www.skillsdirectory.com/skills/melodic-software-check-a6f0cc79)More formats (shields.io, HTML) on the badges page.
---
description: "Run build, test, and lint verification for changed files, auto-detecting affected ecosystems (.NET, Python, TypeScript, Bash, PowerShell, Markdown) from git status, with the consuming project's own documented commands overriding portable defaults. Use when: 'does it compile', 'run tests', 'build it', 'run the tests', 'does this still build', 'check it', or after any code edit; for lint-only use /toolchain:lint, for full outcome verification use /verification:confirm."
user-invocable: true
disable-model-invocation: false
argument-hint: "[ecosystem] (e.g., /toolchain:check dotnet, /toolchain:check python, /toolchain:check all. Default: auto-detect from git status)"
shell: bash
metadata:
workflow-stage: verify
summary: Build, test, and lint changed files across detected ecosystems
---
## Pre-computed context
Working tree status (empty = clean): !`{ git status --porcelain 2>/dev/null || echo "(git status unavailable)"; } | head -20`
Current branch: !`git branch --show-current 2>/dev/null || echo "unknown"`
## Purpose
Detects affected ecosystems from changed files and runs each one's build → test → lint. Serves two roles:
1. **Task skill**. `/toolchain:check` runs build verification for changed files. `/toolchain:check dotnet` targets one ecosystem
2. **Reference skill**. Its sibling `/toolchain:lint`, the `verification` plugin's `/verification:confirm` (when installed), and verification agents compose this for detection and command resolution instead of baking their own tables
**The command surface is resolved, not hardcoded.** Both `/toolchain:check` and `/toolchain:lint` resolve each ecosystem's build/test/lint commands through the shared four-rung ladder in [`${CLAUDE_PLUGIN_ROOT}/reference/resolution-ladder.md`](${CLAUDE_PLUGIN_ROOT}/reference/resolution-ladder.md): the consuming repo's tracked `.claude/ecosystems/<ecosystem>.yaml` is authoritative when present; the plugin's bundled portable defaults at `${CLAUDE_PLUGIN_ROOT}/reference/ecosystems/` are the rung-4 fallback. The consumer's file always wins.
## Arguments
`$ARGUMENTS`, optional ecosystem filter. If provided, run only that ecosystem. If omitted, auto-detect from changed files.
Available ecosystem filters are the ecosystems `/toolchain:check` covers: `dotnet`, `python`, `typescript`, `bash`, `powershell`, `markdown`, `go` (resolved per the ladder). Common aliases: `ts`/`node` → `typescript`, `shell` → `bash`, `ps`/`pwsh` → `powershell`, `md` → `markdown`, `golang` → `go`. Literal `all` runs every covered ecosystem. The lint-only `yaml` and `cross-cutting` surfaces are **not** run by `/toolchain:check`. Use `/toolchain:lint` for those.
## Ecosystem detection
Each ecosystem declares a list of `globs` that classify changed files into that ecosystem (resolved per the ladder. Consumer `.claude/ecosystems/<ecosystem>.yaml` when present, else the bundled default). The skill matches `git status --porcelain` output against each covered ecosystem's `globs` to determine which ecosystems are affected. `/toolchain:check` covers `dotnet`, `python`, `typescript`, `bash`, `powershell`, `markdown`, `go`; the lint-only `yaml` and `cross-cutting` surfaces are `/toolchain:lint`'s (in particular `cross-cutting`'s `**` glob is never matched here).
For ecosystem-specific gotchas, reference files, and primary-source detail, read the corresponding context file:
- [context/dotnet.md](context/dotnet.md). .NET build, test, format
- [context/sarif.md](context/sarif.md). Roslyn SARIF output, jq parser patterns, AI consumption
- [context/python.md](context/python.md). Python lint, format, test
- [context/typescript.md](context/typescript.md). TypeScript compile, test, lint
- [context/bash.md](context/bash.md). ShellCheck, shfmt
- [context/powershell.md](context/powershell.md). PSScriptAnalyzer
- [context/go.md](context/go.md). Go build, test, lint, module discovery
When invoked as a task (`/toolchain:check`), detect from `git status --porcelain`. When referenced by another skill, use the file list that skill provides.
## Workflow (when invoked as /toolchain:check)
### 0. Resolve repo root
```bash
REPO_ROOT=$(git rev-parse --show-toplevel)
```
All commands use absolute paths. Never `cd` and lose context.
### 1. Detect ecosystems
If `$ARGUMENTS` specifies an ecosystem, use it. If `all`, run every covered ecosystem. Otherwise, classify changed files from `git status --porcelain` against each covered ecosystem's `globs` (resolved per the ladder; `/toolchain:check` covers `dotnet`, `python`, `typescript`, `bash`, `powershell`, `markdown`, `go`). Skip any ecosystem whose resolved `enabled` is `false` (a consumer opt-out). Excluded even under `all`.
If the working tree is clean, fall back to the branch diff so checkpoint-committed work still gets classified (the common pre-PR case: every green block was already committed). Resolve the default branch by **detection, not assumption**, never a hardcoded `main`/`master`, and assign it before use:
```bash
REMOTE="" DEFAULT_BRANCH=""
TRACKED=$(git config "branch.$(git branch --show-current | tr -d '\r').remote" 2>/dev/null | tr -d '\r')
[[ "$TRACKED" == "." ]] && TRACKED=""
CANDIDATES=$( { [[ -n "$TRACKED" ]] && echo "$TRACKED"; git remote | grep -qx origin && echo origin; git remote; } | awk 'NF && !seen[\$0]++' )
while IFS= read -r CANDIDATE; do
BRANCH=$(git symbolic-ref --short "refs/remotes/$CANDIDATE/HEAD" 2>/dev/null)
BRANCH=${BRANCH#"$CANDIDATE/"}
BRANCH=${BRANCH:-$(git ls-remote --symref --end-of-options "$CANDIDATE" HEAD 2>/dev/null | awk '/^ref:/{sub(/refs\/heads\//,"",\$2); print \$2; exit}')}
if [[ -n "$BRANCH" ]] && git rev-parse --verify --quiet "refs/remotes/$CANDIDATE/$BRANCH" >/dev/null; then
REMOTE=$CANDIDATE DEFAULT_BRANCH=$BRANCH
break
fi
done <<< "$CANDIDATES"
if [[ -n "$REMOTE" ]]; then
git diff --name-only "$(git merge-base "refs/remotes/$REMOTE/$DEFAULT_BRANCH" HEAD)..HEAD"
else
echo "branch diff unavailable (could not detect default branch)"
fi
```
The loop probes candidate remotes in priority order, the remote the current branch tracks (`branch.<name>.remote`) first, then `origin` if present, then the rest, and selects the first one whose default branch resolves to a locally available tracking ref, never a hardcoded remote name. This handles an unpushed feature branch (no tracking remote) in a repo cloned with a different remote name (e.g. `git clone -o vendor`), and skips a remote that was added but never fetched (its default branch has no local `refs/remotes/<remote>/<branch>` to diff against) in favor of a later remote that does, the candidate is accepted only when `git rev-parse` confirms the tracking ref exists locally. Each candidate's default branch comes from that remote's own `HEAD` (not the current branch's upstream, which on a pushed feature branch points at the feature branch itself and would make `merge-base` equal `HEAD`, yielding an empty diff), falling back to a `git ls-remote --symref` query when the local `HEAD` symref is absent. `merge-base` is taken against the fully-qualified remote-tracking ref `refs/remotes/$REMOTE/$DEFAULT_BRANCH`, which resolves without a local branch of that name and, like the `rev-parse` verify. Cannot be misparsed as an option when the remote name begins with a dash (`git clone --origin=-x`); the `git ls-remote` probe terminates option parsing with `--end-of-options` for the same reason. If no candidate yields a locally available default branch, skip the branch-diff path rather than guessing. A caller passing an explicit changed-file list (e.g. `/verification:confirm`) overrides both detection paths.
If neither path yields changes and no `$ARGUMENTS`: report "No changes found (working tree clean, no branch diff vs the default branch). Use `/toolchain:check all` to verify the full repo, or `/toolchain:check <ecosystem>` for a specific ecosystem." and exit.
**Conversation-aware targeting**: when the conversation has been working with specific files/projects, scope the build to what was touched. Don't rebuild the whole scope for a single-project change. The ecosystem config's `anchor` field provides the default scoping anchor for ecosystems with a canonical entry point; substitute a narrower project file when changes are confined to one project. For .NET specifically: use the specific `.csproj` when changes are in one project, use the solution file when changes span multiple projects or touch shared files (`.props`, `.targets`, solution file).
### 1.5 Resolve each ecosystem's command surface
For each affected ecosystem, resolve its command surface (`globs`, `build-cmd`, `test-cmd`, `check-cmd`, `fix-cmd`, `code-fix-cmd`, `anchor`, `project-discovery`, `install-hint`, `gates`, `notes`) through the four-rung ladder in [`${CLAUDE_PLUGIN_ROOT}/reference/resolution-ladder.md`](${CLAUDE_PLUGIN_ROOT}/reference/resolution-ladder.md):
1. Consumer `.claude/ecosystems/<ecosystem>.yaml` (+ `.local.yaml` overlay, `~/.claude/ecosystems/` user-global, additive per key) → authoritative.
2. Absent → infer from the repo's build files and offer to persist via `/toolchain:setup`.
3. Cannot infer → ask; offer to persist.
4. Otherwise → the bundled default at `${CLAUDE_PLUGIN_ROOT}/reference/ecosystems/<ecosystem>.yaml`.
A malformed consumer file warns and degrades to rung 2, never a hard stop.
### 2. Run checks
For each affected ecosystem, use the resolved `build-cmd`, `test-cmd`, and `check-cmd`. Null commands are skipped (no build step / no test framework / no lint).
Substitute placeholders from the ecosystem config:
- `<solution-or-project-file>` ← resolved per the ecosystem's `anchor` description
- `<project-dir>` ← walked per-project root (driven by `project-discovery` patterns)
- `<files>` ← the changed-files list for that ecosystem
Run build → test → lint in order per ecosystem. Stop that ecosystem on first failure but continue to next ecosystem.
Tool presence: before each ecosystem runs, verify the tool is on `PATH`. If missing, report `skip` with the ecosystem's `install-hint` from the ecosystem config, never report `FAIL` for a missing tool. **What "the tool" means here is the one the ecosystem's commands are invoked through** (python's `uv`, not the `ruff` and `pyright` behind it), the probe is per ecosystem, not per sub-tool. A sub-tool bundled inside an opaque compound `check-cmd` is not probed and cannot be: its absence is discoverable only at execution time, where it surfaces as a real non-zero exit and the ecosystem reports `FAIL`. Do not extend this rule into a per-sub-tool probe to convert that into a `skip`. That contradicts the atomicity rule below, and each affected ecosystem documents the consequence in its own `context/<ecosystem>.md`.
**Opt-in gate (lint phase only)**: before running an ecosystem's `check-cmd`, evaluate its resolved `opt-in` condition (if present) against the repo. Build and test always run regardless of `opt-in`. Only the lint phase is gated, since compiling and testing don't depend on style configuration.
This binary gate applies cleanly when `opt-in` describes ONE condition governing the whole `check-cmd` (e.g. dotnet, python, go): unmet → report the ecosystem's Lint column as `skip (opt-in unmet: <condition, ≤10 words>)`, visible, not silently omitted, and do not run `check-cmd`. Met → run `check-cmd` normally.
When `opt-in` instead describes MULTIPLE independent per-tool conditions bundled into one opaque command string (e.g. bash's `"shellcheck always applies to shell files; shfmt only when .editorconfig declares shell style"`, where `check-cmd` is `shellcheck ... && shfmt -d <files>`), this gate does NOT apply. `check-cmd` is a single opaque string (per the ecosystem-commands contract) with no way to run one sub-tool's portion without the other. Run `check-cmd` as before (unchanged from prior behavior) and report its real output; do not attempt a partial skip. The known atomicity limitation this leaves open is in Gotchas below.
An opt-in-unmet skip (single-condition case) counts toward the table's total ecosystem count but never toward the FAIL count, the same precedent as a missing-tool skip. This is ecosystem-generic (reads the resolved `opt-in` key), not dotnet-specific. It applies to every current and future single-condition opt-in-bearing ecosystem `/toolchain:check` covers. CI-parity gates (below) are unaffected. They run independent of `check-cmd`.
**CI-parity gates (resolved `gates` array).** After an affected ecosystem's build → test → lint, iterate its resolved `gates` array (§1.5. Bundled default or consumer file, per the ladder). Gates cover the CI-parity checks plain build / test / lint don't catch: lockfile drift, generated-artifact freshness, schema regeneration. For each gate:
- **Fire condition**. `trigger-globs` narrows a *change-driven* run. Under auto-detection (§1), run the gate only when ≥1 changed file matches, matched against the **full** changed-files set (not the ecosystem-scoped subset, a gate's trigger files need not classify into the ecosystem's own `globs`); no match → the gate does not fire. If `trigger-globs` is omitted, run whenever the ecosystem runs.
- **Explicit scope overrides the narrowing**, when `$ARGUMENTS` names a scope (`/toolchain:check all` or `/toolchain:check <ecosystem>`), every gate of a selected ecosystem fires regardless of `trigger-globs`. The user asked to verify that scope, not to narrow by what changed, and the ecosystem's own `build-cmd`/`test-cmd`/`check-cmd` already run in full there. Leaving gates change-narrowed would make `check all` on a clean tree, the exact command §1 tells the user to run for full-repo verification, pass a committed-but-untidy `go.mod`. This is also the only way to force a gate without manufacturing a matching change.
- **Reachability**, a gate is subordinate to its ecosystem's run (per the ecosystem-commands schema: `trigger-globs` "run the gate only when a changed file matches (matched against the full changed-file set); omit to run whenever the ecosystem runs"), so `trigger-globs` narrows *within* a run and never selects an ecosystem. Under auto-targeting the ecosystem must first be affected by its own `globs` (§1); a gate whose `trigger-globs` alone match a changed file is reached via `/toolchain:check <ecosystem>` or `/toolchain:check all`. This is settled, not a parked default: to make a cross-ecosystem trigger select its ecosystem under auto-targeting, add the trigger pattern to that ecosystem's own `globs`.
- **Independent of the build/test/lint short-circuit**, a fired gate runs even when this ecosystem's build, test, or lint already failed and stopped (line above). Gates mirror CI checks that are independent of build success (a lockfile or `go mod tidy` gate is meaningful whether or not the build compiled), so a failed earlier phase never suppresses them.
- **Run** `gate.cmd` (an opaque shell string. Substitute the same placeholders as other commands: `<files>`, resolved anchor, etc.) with absolute paths. Execution location is governed by the resolved `run-from` (default `"ecosystem"` when the key is omitted): `"ecosystem"` runs from the **same execution location the ecosystem's own build/test/lint use** (§2 placeholders, and Gotchas' "Multiple projects in same ecosystem"), once per resolved `<project-dir>` for a `project-discovery` ecosystem, from the `anchor`'s directory for an `anchor` ecosystem, and from `$REPO_ROOT` only when neither is defined; `"repo-root"` forces a single run from `$REPO_ROOT` regardless of the ecosystem's `project-discovery` or `anchor`. The `"ecosystem"` default matters for the bundled `go.yaml` `go-mod-tidy-drift` gate: `go mod tidy -diff` is inherently per-module, so a `project-discovery: ["go.mod"]` monorepo must run it from each `go.mod` root, a `$REPO_ROOT`-only run falsely fails when the sole module is nested (`go.mod file not found`) and never checks drift in nested modules when a root module also exists. `run-from: repo-root` exists for the opposite shape: a repo-wide gate (protobuf generation, schema freshness) declared under a `project-discovery` ecosystem, which would otherwise inherit the per-project scope and run redundantly or fail in project roots lacking its config. Declare `run-from: repo-root` on that gate instead of moving it to an ecosystem without `project-discovery`. The **fire condition** above stays repo-wide (`trigger-globs` vs the full changed-files set decides *whether* the gate runs) regardless of `run-from`; only the execution location changes. When a gate `cmd` uses `<files>` under `"ecosystem"` scope, it expands to that project's scoped changed-files subset, exactly as for the ecosystem's other commands (§2); under `"repo-root"` scope it expands to the full changed-files set for that ecosystem, since there is no single project root to scope to. `<project-dir>` is **not defined** under `"repo-root"` scope, a single run has no one project root to bind it to, and picking one arbitrarily or iterating them would defeat the single-run guarantee this key exists to provide. A gate `cmd` that uses `<project-dir>` while declaring `run-from: repo-root` is a configuration error: report it as a `FAIL` naming the gate and the unresolvable placeholder rather than guessing an expansion. Such a gate is per-project by construction and belongs on the `"ecosystem"` default.
- **Tool presence**, as with `check-cmd`, if the gate's tool is missing from `PATH`, report `skip` (reuse the ecosystem's `install-hint`), never `FAIL`.
- **Version floor**, a tool that is present but too old for the gate's invocation is an environment capability gap, not project drift, so it reports `skip (unsupported: <tool + capability, ≤10 words>)` with the `install-hint` rather than a false `FAIL`. The bundled `go.yaml` `go-mod-tidy-drift` gate has one: `go mod tidy -diff` needs Go 1.23+, so a Go 1.22 toolchain must skip rather than fail every `*.go`/`go.mod`/`go.sum` change. **A rejected invocation is not by itself evidence of a version floor**, a typo in a consumer's `gate.cmd` (misspelled flag, wrong subcommand) is rejected identically, and skipping it would leave a malformed gate silently unenforced. So the skip requires the mismatch to be **positively established**, either by the tool naming its own minimum in the error, or by a minimum documented for that gate (the gate's `remediation`, the ecosystem's `notes`, or `context/<ecosystem>.md`) that the tool's reported version, queried directly, e.g. `go version`, falls below. Unexplained rejection → `FAIL`, with the rejection text shown so the typo is visible. Every other non-zero exit (a malformed manifest, a network failure, real drift) is likewise a `FAIL`.
- **Outcome**. Report `pass`/`FAIL` by name. On `FAIL`, surface `gate.remediation`. A fired gate that fails is a real failure and **counts toward the run's FAIL verdict** (unlike opt-in/missing-tool skips). A gate that runs more than once (`"ecosystem"` scope under `project-discovery`, once per project root) reports **one aggregated outcome line per gate name**, not one line per root: `FAIL` if any invocation failed, `pass` only if every invocation passed. On an aggregated `FAIL`, show each failing invocation's output below the table labeled by its execution root, so a multi-root failure is traceable to the specific root that failed. `run-from: repo-root` runs exactly once, so this aggregation never applies to it.
Gates resolve through the ladder like every other key: a bundled default may ship one (e.g. `go.yaml`'s `go-mod-tidy-drift`), and a consumer declares its own in its tracked `.claude/ecosystems/<ecosystem>.yaml` `gates` array (e.g. the `nuget-lockfile-drift` shape in `docs/conventions/ecosystem-commands/examples/dotnet.yaml`).
**Convention-documented gates still run.** The `gates` array is the declaration form this skill can resolve, report by name, and layer per the ladder, but it is not the only place a consuming project states its CI-parity checks. When the project documents extra local checks in its own conventions (its `CLAUDE.md`, `.claude/rules/`, or a commands reference) rather than in a `gates` array, run those too, by the same rules above: fire on their stated trigger files, run after build → test → lint and independent of that short-circuit, report by name with the project's own remediation, and count a failure toward the verdict. A project that documented its gates in prose keeps them; declaring them in `.claude/ecosystems/<ecosystem>.yaml` is the preferred form because it makes them structured, layerable, and machine-checkable, not a precondition for running them.
For ecosystem-specific gotchas (xUnit `--nologo` trap, `dotnet test --project`, etc.), read the corresponding `context/<ecosystem>.md` file.
### 3. Report results
```text
## Build Results
| Ecosystem | Build | Test | Lint | Status |
|------------|-------|------|------|--------|
| dotnet | pass | pass | pass | PASS |
| python | — | pass | FAIL | FAIL |
Gates: go-mod-tidy-drift — FAIL (run go mod tidy and commit the updated go.mod/go.sum)
Overall: FAIL (1 of 2 ecosystems failed, 1 gate failed)
```
Use `pass`, `FAIL`, `skip` (tool missing), `skip (opt-in unmet: ...)` (config condition not met), `skip (unsupported: ...)` (gates only, the installed tool's version is below the gate's documented floor), or `—` (not applicable. For ecosystems where the corresponding command is null in the ecosystem config). Show failing command output below the table.
If any CI-parity gates fired, summarize each by name + outcome below the per-ecosystem block, with the remediation pointer on failure. A fired gate that failed flips Overall to `FAIL` and is counted in it, including when every ecosystem's build/test/lint cell passed (e.g. `Overall: FAIL (0 of 2 ecosystems failed, 1 gate failed)`). The Overall line names both counts whenever a gate fires, pass or fail, a fired-and-passed gate still reports its count (e.g. `Overall: PASS (2 of 2 ecosystems passed, 1 gate passed)`), so the report is unambiguous about whether a gate ran.
A gate declared under a `project-discovery` ecosystem without `run-from: repo-root` runs once per discovered project root (§2 "Run"); per the aggregation rule (§2 "Outcome"), that still reports **one** `Gates:` line per gate name, with each failing root's output shown underneath, labeled by its execution root:
```text
Gates: go-mod-tidy-drift — FAIL (run go mod tidy and commit the updated go.mod/go.sum)
[services/auth] go: updates to go.sum needed, disabled by -mod=readonly
[services/billing] go.mod: missing go.sum entry for module golang.org/x/text v0.14.0
```
Only the roots that actually failed are listed, a root whose invocation passed contributes nothing below the line. A gate declaring `run-from: repo-root` never produces this per-root breakdown (it runs exactly once), so its `FAIL` line stands alone as in the first example above.
## For other skills referencing /toolchain:check
When composing `/toolchain:check` from another skill (like `/verification:confirm` or `/toolchain:lint`):
- **To get command tables**: resolve per [`${CLAUDE_PLUGIN_ROOT}/reference/resolution-ladder.md`](${CLAUDE_PLUGIN_ROOT}/reference/resolution-ladder.md). Consumer `.claude/ecosystems/<ecosystem>.yaml` wins, bundled defaults at `${CLAUDE_PLUGIN_ROOT}/reference/ecosystems/` are the fallback, or the relevant `context/<ecosystem>.md` for gotchas and prose detail
- **To run full verification**: invoke `/toolchain:check` or `/toolchain:check <ecosystem>` via the Skill tool
- **To run lint-only checks**: invoke `/toolchain:lint` or `/toolchain:lint <ecosystem>` via the Skill tool (it resolves through the same ladder and additionally owns the `yaml` and `cross-cutting` surfaces)
- **To embed commands in agent prompts**: resolve per the ladder AND read the corresponding `context/<ecosystem>.md` for gotchas
## Gotchas (cross-ecosystem)
- **CWD drift**, the #1 source of false failures. Always use absolute paths
- **Missing tools**. Report as `skip` with reason, not as failure (e.g., `uv` not installed). The probe is per ecosystem: it covers the tool the ecosystem's commands are invoked through, not every sub-tool a compound command reaches (see the atomicity bullet below)
- **Opt-in unmet**. Report as `skip (opt-in unmet: ...)` with the condition, not as failure and not silently omitted (e.g., dotnet with no C#-relevant `.editorconfig`)
- **Multi-tool `check-cmd` atomicity**, when a multi-tool ecosystem's `check-cmd` bundles a gated sub-tool and an unconditional sub-tool in one shell string (e.g. bash's `shellcheck ... && shfmt -d <files>`), the opt-in gate cannot suppress just the gated sub-tool's contribution. Both run whenever the unconditional sub-tool's condition holds, per the ecosystem-commands contract's own "opaque shell string" rule. The same opacity reaches the missing-tool rule above: a sub-tool the ecosystem's own probe never covers (python's `pyright` behind `uv`) is absent only at execution time, so its absence surfaces as a real non-zero exit and the Lint cell reports `FAIL`, not `skip`. Document that consequence per ecosystem (`context/python.md`) rather than inferring a skip the runner does not perform. Splitting a multi-tool `check-cmd` into separately gateable ecosystem keys, or probing each sub-tool independently, would need a schema change; not addressed here
- **Multiple projects in same ecosystem**. Ecosystems with an `anchor` use that as the scoping anchor; ecosystems with `project-discovery` patterns walk each discovered project root
Is this your skill, or is something wrong with this listing? Request removal or report an issue. Author removals are honored within 72 hours.
No comments yet. Be the first to comment!