| name | metadata |
| description | Fetch repository metadata (description, default branch, languages, license, stars, archived, icon) from repos.ecosyste.ms and save it on the repository row. |
| license | MIT |
| compatibility | Prefers the scrutineer API's cached ecosyste.ms payload; needs network access to repos.ecosyste.ms only when nothing is cached. |
| metadata | {"scrutineer.version":1,"scrutineer.output_file":"report.json","scrutineer.output_kind":"repo_metadata","scrutineer.requires_remote":true,"scrutineer.model":"mid"} |
metadata
Populate repository metadata from repos.ecosyste.ms. One API call, one flat JSON document.
Workspace
./context.json — has repository.url (the git URL of the target repo), plus scrutineer.api_base, scrutineer.token and scrutineer.repository_id
./report.json — write the flat metadata here
./schema.json — output shape
What to do
- Read
./context.json and extract repository.url, scrutineer.api_base, scrutineer.token and scrutineer.repository_id.
- Ask scrutineer for the cached payload first:
GET {api_base}/repositories/{repository_id}/ecosystems/repo/raw with the bearer token. A 200 is the verbatim upstream lookup response — use it and go to step 4. This is the only path that works under --hardened, where ecosyste.ms is not in the egress allowlist, and it avoids a redundant external fetch otherwise.
- On 404 nothing is cached — the steady state under
ecosystems_enrichment: false — so fetch https://repos.ecosyste.ms/api/v1/repositories/lookup?url={URL-ENCODED_URL} directly. Follow redirects.
- Keep the raw upstream response available for the
metadata blob (the parser stores it as Repository.Metadata).
- Map the fields below into
./report.json exactly as ./schema.json describes:
full_name from upstream full_name
owner from upstream owner
description from upstream description
default_branch from upstream default_branch
languages as a plain array of names (upstream returns an object like {"Go": 90, "JavaScript": 10}; take the keys)
license from upstream license (string, not object)
stars from upstream stargazers_count
forks from upstream forks_count
archived from upstream archived
pushed_at from upstream pushed_at (RFC3339 string)
html_url from upstream html_url
icon_url from upstream icon_url if present
Omit any field upstream did not provide rather than making one up. If the lookup genuinely returns nothing, write {} and exit 0 — the parser handles an empty map cleanly.
If neither source is reachable — the cached endpoint returned 404 and the direct fetch failed, which is what --hardened looks like on an uncached repository — do not write ./report.json at all. Exit non-zero instead. An empty document here is a claim that upstream knows nothing about this repository, and it blanks the stored metadata blob and zeroes stars/forks on the row.