openplain/filament-shadcn-theme
Shadcn UI theme for Filament - Beautiful color themes with the iconic Shadcn design system
Scanned 7 hours ago
Check details
Security
Tag-pinned Actions can be silently re-pointed to malicious code by a compromised maintainer. The tj-actions/changed-files incident (March 2025) demonstrated this: attackers re-pointed a widely-used tag mid-run and exfiltrated CI secrets from thousands of repositories. Pinning every third-party action reference to a full 40-character commit SHA is the only way to guarantee the code that ran yesterday runs again today.
First-party references (./path actions and same-repository reusable workflows) are exempt because they are protected by the repository's own branch-protection rules.
.github/workflows directory found
An active, unfixed security advisory against the version users actually install is the most concrete threat we can detect. We cross-reference two independent advisory feeds — GitHub Security Advisories (GHSA) and Packagist's aggregated advisories — and dedupe by CVE id so that lag or downtime in one feed cannot hide a known vulnerability.
An advisory counts against a package when the latest released version falls inside the advisory's affected-version range and either no fix has been published or the published fix is no newer than the latest release. Any such advisory fails the check and lowers the Security category score to a maximum of 30.
The check is skipped (Not Applicable) when the package has no resolved stable release — there is nothing yet to evaluate. A feed that does not apply to the package is skipped (for example, Packagist advisories for a package that is not registered on Packagist). If every applicable feed is unreachable the check reports an error; if at least one feed responds it still produces a verdict and any failed feed is recorded in the evidence.
This is a veto check: if it fails, the Security score is capped at 30/100 no matter how other checks score. The veto is not currently affecting this package's score. Learn how scoring works.
- Sources Seen
- ghsa, packagist
- Latest Version
- v1.1.0
- Sources Failed
- Advisories Total
- 0
A maintainer who leaves Dependabot pull requests open for months is signalling either inattention or an unwillingness to engage with automated dependency management -- both compound into real exposure as vulnerabilities accumulate unpatched.
All open Dependabot PRs are scored across two buckets with different urgency thresholds. Security PRs -- identified by a CVE or GHSA identifier in the PR body -- are scored strictly: pass requires no open security PR older than 14 days, with partial credit at 14-30 days (0.7) and 30-90 days (0.3), and failure beyond 90 days. General dependency PRs are scored more leniently: pass within 30 days, partial credit at 30-60 days (0.7) and 60-180 days (0.3), and failure beyond 180 days. The final score is the worse of the two buckets.
- General Prs
- Security Prs
- General Pr Count
- 0
- Security Pr Count
- 0
- Oldest General Age Days
- —
- Oldest Security Age Days
- —
Automated dependency updates are how transitive vulnerability exposure is kept in check at scale. This check confirms that Dependabot or Renovate is configured and covers every ecosystem the repository actually maintains: Composer when a composer.lock is committed, GitHub Actions when workflow files exist, and JavaScript when an npm, yarn, pnpm, or bun lockfile is committed. Repositories with none of these — libraries that deliberately commit no lockfile and run no workflows — have nothing for an updater to maintain and are not penalized. For Renovate, coverage follows the declared enabledManagers list; when absent, all managers are enabled by default. The OpenSSF Scorecard calls this the Dependency-Update-Tool check.
- Searched
- renovate.json, renovate.json5, .github/renovate.json, .github/dependabot.yml, package.json
- Tool Found
- —
- Js Relevant
- false
- Js Lockfiles
- Actions Relevant
- false
- Composer Relevant
- false
Updating instantly on release is exactly when malicious releases get pulled into projects -- the xz-utils supply chain attack targeted this window. A cooldown of several days lets the community identify and report obvious issues before they propagate. This check verifies that the configured dependency updater (Dependabot or Renovate) enforces a minimum age before merging updates.
Without a documented disclosure process, consumers who find a vulnerability have no clear place to reach out — so many never report it at all, and those who do often fall back to public issues or discussions, disclosing the problem in the open and accelerating exploitation while maintainers scramble to triage. A security policy tells researchers where to send vulnerability reports privately.
A package satisfies this check either with a SECURITY.md at one of GitHub's recognized locations (repo root, .github/, or docs/), or with a security policy the maintainer provided when registering the package with Plumb — the equivalent signal for private packages. This is a presence-only check. We do not grade the prose or verify the contact path actually works; the reasoning is mechanical: a published policy is the difference between "I have a clear place to report this" and "I have to guess."
- Searched
- SECURITY.md, .github/SECURITY.md, docs/SECURITY.md
Maintenance
A maintainer can explicitly tell the ecosystem a package will not be patched on two surfaces: Packagist's abandoned flag (optionally pointing consumers at a suggested replacement) and archiving the repository on GitHub. Both are the same statement — the strongest non-malware signal we can receive — and maintainers frequently set one without the other, so either alone fails the check. For packages not registered on public Packagist, the archive state is the only abandonment signal that exists.
The check is binary. A failure caps the Maintenance category at 20 regardless of how the package scores on every other Maintenance signal, because no amount of recent activity or hygiene offsets the maintainer's own statement that future fixes will not land.
When the maintainer provided a replacement package name on Packagist, we surface it in the check evidence so downstream consumers (the API, the website, the Composer plugin) can present the redirect alongside the failure. The replacement suggestion is the actionable next step that helps consumers migrate rather than merely warning them off.
This is a veto check: if it fails, the Maintenance score is capped at 20/100 no matter how other checks score. The veto is not currently affecting this package's score. Learn how scoring works.
No consulted source marks the package abandoned (packagist, github).- Archived At
- —
- Is Archived
- false
- Is Abandoned
- false
- Sources Consulted
- packagist, github
- Abandoned Replacement
- —
Recency is a noisy signal — some mature packages legitimately do not need frequent commits — but combined with other maintenance signals it correlates strongly with abandonment risk. We measure two independent signals: the date of the most recent commit on the default branch and the date of the most recent stable release on Packagist. A package passes if either signal is sufficiently recent; it fails only when both signals have been silent for an extended period.
Commit threshold (90 days) mirrors the OpenSSF Scorecard "Maintained" check, which uses 90 days as the boundary between active and inactive. Release threshold (180 days active / 365 days stale) is Plumb-specific: releases have a slower natural cadence than commits, so the window is wider. A package that passes on releases alone has published a stable version in the last 6 months; one in the warn zone released between 6 and 12 months ago; one that fails has had no release in over a year and no commit in over a year.
- Last Commit Date
- 2026-01-19T14:22:59Z
- Last Release Date
- 2026-01-19T14:22:59+00:00
- Last Commit Age Days
- 174
- Last Release Age Days
- 174
Composer ignores nested lockfiles found inside vendor/, so a library committing composer.lock does not change how its consumers resolve dependencies. The real harm is that downstream security scanners (AWS Inspector, dependency-audit tooling) walk installed vendor/ directories and parse any composer.lock they find, flagging the package versions pinned inside — versions that drift from what the consumer is actually using, adding false-positive noise to audits.
The check inspects only the released dist archive — the artifact consumers actually receive via composer require. If the lock is absent from the dist, the package passes regardless of how that exclusion was achieved (.gitattributes export-ignore, never committed, composer.json archive.exclude, etc.). The check is mechanism-agnostic: we trust the ground truth rather than modelling every way a maintainer might exclude a file.
NotApplicable when no stable release exists on Packagist, or when the package's composer.json declares type: project (Symfony skeletons, Laravel applications legitimately commit a lockfile).
Low-weight hygiene signal — a slip means downstream audit noise, not a security failure.
composer.lock is absent from the released dist archive.
- Package Type
- library
- Release Version
- v1.1.0
- Lock Present In Dist
- false
Dev files shipped in the dist archive bloat every install, expand the attack surface, and signal that the maintainer has not configured archive exclusions. Smaller dists mean faster composer require, less noise in security scanners walking vendor/, and a clear signal of care.
Files are grouped into four categories: test infrastructure, CI/CD configs, AI assistant configs, and dev tooling/environment. The check passes when all groups are clean, warns (0.5) when exactly one group has flagged files, and fails when two or more groups do.
The check inspects the dist archive only — we trust the released bytes regardless of how the maintainer excluded files (.gitattributes export-ignore, composer.json archive.exclude, never committed, etc.).
NotApplicable when no stable release exists on Packagist.
- Hits
- 4 items
- Release Version
- v1.1.0
Ecosystem
A Laravel-ecosystem package that cannot be installed alongside the current stable Laravel forces its users to stay on an older framework — one that may no longer receive active bug fixes or, worse, security patches. Packages stuck below the current version put downstream projects on end-of-life infrastructure.
The check runs a real Composer resolution of the released dependencies together with the current Laravel line — the same answer composer require would give. This honors replace and conflict semantics that reading constraint strings cannot, and covers constraints hidden inside intermediate dependencies. If the current line resolves, the package passes; otherwise the newest line that does resolve determines the verdict: still in active support earns a partial score, security-only earns a lower partial score, end-of-life (or no resolvable line at all) fails. The solver's own conflict explanation is recorded as evidence for every non-pass verdict. Wildcard or unbounded constraints pass naturally.
A package counts as Laravel-related when its own require names laravel/framework or any illuminate/* component, or when its resolved dependency graph reaches one of those through packages that are themselves Laravel-ecosystem packages. NotApplicable when no such signal exists, when the package's own dependencies do not currently resolve at all (the conflict explanation is surfaced as evidence), when no stable release artifact is available, or when composer.json is absent from the dist archive.
13.0.
- Detected Via
- transitive
- Probed Lines
- Constraint Key
- illuminate/contracts
- Detection Path
- filament/filament, filament/support, illuminate/contracts
- Unproven Lines
- Lifecycle Source
- endoflife.date
- Probe Constraint
- laravel/framework 13.*
- Supports Current
- true
- Laravel Constraint
- —
- Constraint Declared
- false
- Max Supported Version
- 13.0
- Skipped Meta Lag Lines
- Current Laravel Version
- 13.0
A package that does not support the current stable PHP version forces its users to stay on an older runtime — one that may no longer receive active bug fixes or, worse, security patches. Packages stuck below the current version put downstream projects on end-of-life infrastructure.
The check reads the require.php constraint from the released composer.json. If the constraint allows the current stable PHP, the package passes. If the constraint's maximum allowed version is still receiving active maintenance, a partial score is awarded. If the maximum allowed version is security-only, a lower partial score is awarded. If it is fully end-of-life, the check fails.
Packages that declare no PHP constraint (or use *) impose no restriction and pass — they can be installed on any PHP version including the current one.
NotApplicable when no stable release artifact is available or when composer.json is absent from the dist archive.
^8.2|^8.3|^8.4 supports current PHP 8.5.
- Php Constraint
- ^8.2|^8.3|^8.4
- Lifecycle Source
- phpwatch
- Supports Current
- true
- Constraint Declared
- true
- Current Php Version
- 8.5
A Symfony-ecosystem package that cannot be installed alongside the current stable Symfony forces its users to stay on an older framework — one that may no longer receive active bug fixes or, worse, security patches. Packages stuck below the current version put downstream projects on end-of-life infrastructure.
The check runs a real Composer resolution of the released dependencies together with the current Symfony line, pinning every framework component to that line the way Symfony applications are locked — the same answer composer require would give. This honors replace and conflict semantics that reading constraint strings cannot, and covers constraints hidden inside intermediate dependencies. If the current line resolves, the package passes; otherwise the newest line that does resolve determines the verdict: still in active support earns a partial score, security-only (LTS lines only — standard Symfony releases have no security-only phase) earns a lower partial score, end-of-life (or no resolvable line at all) fails. The solver's own conflict explanation is recorded as evidence for every non-pass verdict. Wildcard or unbounded constraints pass naturally.
A package counts as Symfony-related when its own require names symfony/framework-bundle or a framework-versioned component (such as http-kernel, console, yaml, validator), or when its resolved dependency graph reaches symfony/framework-bundle or symfony/http-kernel through packages that are themselves Symfony-ecosystem packages. Independently versioned packages (symfony/polyfill-*, contracts, symfony/ux-*, Flex, MakerBundle, MonologBundle) never count, and packages are not misclassified just because a framework they build on reuses Symfony components internally. NotApplicable when no such signal exists, when the package's own dependencies do not currently resolve at all (the conflict explanation is surfaced as evidence), when no stable release artifact is available, or when composer.json is absent from the dist archive.
Add a Plumb badge to your README.
[](https://plumbphp.dev/openplain/filament-shadcn-theme)
[](https://plumbphp.dev/openplain/filament-shadcn-theme)
[](https://plumbphp.dev/openplain/filament-shadcn-theme)
[](https://plumbphp.dev/openplain/filament-shadcn-theme)
[](https://plumbphp.dev/openplain/filament-shadcn-theme)