evergreen-deprecation 0.1.0 → 0.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +107 -7
- package/data/README.md +11 -0
- package/data/sigstore-trusted-root.json +126 -0
- package/dist/src/action.js +27 -7
- package/dist/src/action.js.map +1 -1
- package/dist/src/agent-instructions.d.ts +20 -0
- package/dist/src/agent-instructions.js +76 -0
- package/dist/src/agent-instructions.js.map +1 -0
- package/dist/src/agent-tools.d.ts +14 -2
- package/dist/src/agent-tools.js +19 -3
- package/dist/src/agent-tools.js.map +1 -1
- package/dist/src/baseline.d.ts +65 -3
- package/dist/src/baseline.js +123 -11
- package/dist/src/baseline.js.map +1 -1
- package/dist/src/capabilities.d.ts +68 -0
- package/dist/src/capabilities.js +222 -0
- package/dist/src/capabilities.js.map +1 -0
- package/dist/src/check-dependency.d.ts +58 -0
- package/dist/src/check-dependency.js +135 -0
- package/dist/src/check-dependency.js.map +1 -0
- package/dist/src/cli.js +241 -9
- package/dist/src/cli.js.map +1 -1
- package/dist/src/conformance/checks/bounds.d.ts +4 -0
- package/dist/src/conformance/checks/bounds.js +43 -0
- package/dist/src/conformance/checks/bounds.js.map +1 -0
- package/dist/src/conformance/checks/determinism.d.ts +2 -0
- package/dist/src/conformance/checks/determinism.js +11 -0
- package/dist/src/conformance/checks/determinism.js.map +1 -0
- package/dist/src/conformance/checks/evidence.d.ts +2 -0
- package/dist/src/conformance/checks/evidence.js +13 -0
- package/dist/src/conformance/checks/evidence.js.map +1 -0
- package/dist/src/conformance/checks/locations.d.ts +2 -0
- package/dist/src/conformance/checks/locations.js +44 -0
- package/dist/src/conformance/checks/locations.js.map +1 -0
- package/dist/src/conformance/checks/malformed.d.ts +2 -0
- package/dist/src/conformance/checks/malformed.js +13 -0
- package/dist/src/conformance/checks/malformed.js.map +1 -0
- package/dist/src/conformance/checks/zero.d.ts +2 -0
- package/dist/src/conformance/checks/zero.js +13 -0
- package/dist/src/conformance/checks/zero.js.map +1 -0
- package/dist/src/conformance/index.d.ts +27 -0
- package/dist/src/conformance/index.js +44 -0
- package/dist/src/conformance/index.js.map +1 -0
- package/dist/src/data-bundle.d.ts +75 -0
- package/dist/src/data-bundle.js +205 -0
- package/dist/src/data-bundle.js.map +1 -0
- package/dist/src/data-signature.d.ts +21 -0
- package/dist/src/data-signature.js +54 -0
- package/dist/src/data-signature.js.map +1 -0
- package/dist/src/data-source.d.ts +74 -0
- package/dist/src/data-source.js +233 -0
- package/dist/src/data-source.js.map +1 -0
- package/dist/src/data-status.d.ts +35 -0
- package/dist/src/data-status.js +60 -0
- package/dist/src/data-status.js.map +1 -0
- package/dist/src/data-update.d.ts +69 -0
- package/dist/src/data-update.js +211 -0
- package/dist/src/data-update.js.map +1 -0
- package/dist/src/detectors/ci-images/parse-gitlab-ci.d.ts +22 -0
- package/dist/src/detectors/ci-images/parse-gitlab-ci.js +90 -0
- package/dist/src/detectors/ci-images/parse-gitlab-ci.js.map +1 -0
- package/dist/src/detectors/container/index.d.ts +8 -0
- package/dist/src/detectors/container/index.js +168 -0
- package/dist/src/detectors/container/index.js.map +1 -0
- package/dist/src/detectors/container/parse-compose.d.ts +23 -0
- package/dist/src/detectors/container/parse-compose.js +50 -0
- package/dist/src/detectors/container/parse-compose.js.map +1 -0
- package/dist/src/detectors/container/parse-dockerfile.d.ts +25 -0
- package/dist/src/detectors/container/parse-dockerfile.js +68 -0
- package/dist/src/detectors/container/parse-dockerfile.js.map +1 -0
- package/dist/src/detectors/container/parse-image.d.ts +16 -0
- package/dist/src/detectors/container/parse-image.js +56 -0
- package/dist/src/detectors/container/parse-image.js.map +1 -0
- package/dist/src/detectors/dotnet/index.d.ts +24 -0
- package/dist/src/detectors/dotnet/index.js +215 -0
- package/dist/src/detectors/dotnet/index.js.map +1 -0
- package/dist/src/detectors/dotnet/json-lines.d.ts +31 -0
- package/dist/src/detectors/dotnet/json-lines.js +167 -0
- package/dist/src/detectors/dotnet/json-lines.js.map +1 -0
- package/dist/src/detectors/dotnet/msbuild-xml.d.ts +24 -0
- package/dist/src/detectors/dotnet/msbuild-xml.js +146 -0
- package/dist/src/detectors/dotnet/msbuild-xml.js.map +1 -0
- package/dist/src/detectors/dotnet/parse-global-json.d.ts +15 -0
- package/dist/src/detectors/dotnet/parse-global-json.js +6 -0
- package/dist/src/detectors/dotnet/parse-global-json.js.map +1 -0
- package/dist/src/detectors/dotnet/parse-msbuild.d.ts +34 -0
- package/dist/src/detectors/dotnet/parse-msbuild.js +48 -0
- package/dist/src/detectors/dotnet/parse-msbuild.js.map +1 -0
- package/dist/src/detectors/dotnet/parse-packages-lock.d.ts +18 -0
- package/dist/src/detectors/dotnet/parse-packages-lock.js +20 -0
- package/dist/src/detectors/dotnet/parse-packages-lock.js.map +1 -0
- package/dist/src/detectors/github-actions.d.ts +3 -2
- package/dist/src/detectors/github-actions.js +111 -14
- package/dist/src/detectors/github-actions.js.map +1 -1
- package/dist/src/detectors/go/index.d.ts +14 -0
- package/dist/src/detectors/go/index.js +142 -0
- package/dist/src/detectors/go/index.js.map +1 -0
- package/dist/src/detectors/go/parse-go-mod.d.ts +30 -0
- package/dist/src/detectors/go/parse-go-mod.js +71 -0
- package/dist/src/detectors/go/parse-go-mod.js.map +1 -0
- package/dist/src/detectors/go/parse-go-work.d.ts +12 -0
- package/dist/src/detectors/go/parse-go-work.js +51 -0
- package/dist/src/detectors/go/parse-go-work.js.map +1 -0
- package/dist/src/detectors/index.js +12 -0
- package/dist/src/detectors/index.js.map +1 -1
- package/dist/src/detectors/java/index.d.ts +8 -0
- package/dist/src/detectors/java/index.js +173 -0
- package/dist/src/detectors/java/index.js.map +1 -0
- package/dist/src/detectors/java/jdk-version.d.ts +58 -0
- package/dist/src/detectors/java/jdk-version.js +45 -0
- package/dist/src/detectors/java/jdk-version.js.map +1 -0
- package/dist/src/detectors/java/parse-gradle.d.ts +22 -0
- package/dist/src/detectors/java/parse-gradle.js +174 -0
- package/dist/src/detectors/java/parse-gradle.js.map +1 -0
- package/dist/src/detectors/java/parse-pins.d.ts +18 -0
- package/dist/src/detectors/java/parse-pins.js +49 -0
- package/dist/src/detectors/java/parse-pins.js.map +1 -0
- package/dist/src/detectors/java/parse-pom.d.ts +15 -0
- package/dist/src/detectors/java/parse-pom.js +87 -0
- package/dist/src/detectors/java/parse-pom.js.map +1 -0
- package/dist/src/detectors/java/parse-wrapper.d.ts +13 -0
- package/dist/src/detectors/java/parse-wrapper.js +42 -0
- package/dist/src/detectors/java/parse-wrapper.js.map +1 -0
- package/dist/src/detectors/java/xml.d.ts +23 -0
- package/dist/src/detectors/java/xml.js +140 -0
- package/dist/src/detectors/java/xml.js.map +1 -0
- package/dist/src/detectors/kubernetes/api-version.d.ts +21 -0
- package/dist/src/detectors/kubernetes/api-version.js +39 -0
- package/dist/src/detectors/kubernetes/api-version.js.map +1 -0
- package/dist/src/detectors/kubernetes/index.d.ts +8 -0
- package/dist/src/detectors/kubernetes/index.js +156 -0
- package/dist/src/detectors/kubernetes/index.js.map +1 -0
- package/dist/src/detectors/kubernetes/parse-helm.d.ts +32 -0
- package/dist/src/detectors/kubernetes/parse-helm.js +229 -0
- package/dist/src/detectors/kubernetes/parse-helm.js.map +1 -0
- package/dist/src/detectors/kubernetes/parse-kustomize.d.ts +30 -0
- package/dist/src/detectors/kubernetes/parse-kustomize.js +144 -0
- package/dist/src/detectors/kubernetes/parse-kustomize.js.map +1 -0
- package/dist/src/detectors/kubernetes/parse-manifest.d.ts +33 -0
- package/dist/src/detectors/kubernetes/parse-manifest.js +80 -0
- package/dist/src/detectors/kubernetes/parse-manifest.js.map +1 -0
- package/dist/src/detectors/npm.js +115 -57
- package/dist/src/detectors/npm.js.map +1 -1
- package/dist/src/detectors/python.js +82 -54
- package/dist/src/detectors/python.js.map +1 -1
- package/dist/src/detectors/rust/index.d.ts +12 -0
- package/dist/src/detectors/rust/index.js +171 -0
- package/dist/src/detectors/rust/index.js.map +1 -0
- package/dist/src/detectors/rust/parse-cargo-lock.d.ts +19 -0
- package/dist/src/detectors/rust/parse-cargo-lock.js +48 -0
- package/dist/src/detectors/rust/parse-cargo-lock.js.map +1 -0
- package/dist/src/detectors/rust/parse-cargo-toml.d.ts +31 -0
- package/dist/src/detectors/rust/parse-cargo-toml.js +102 -0
- package/dist/src/detectors/rust/parse-cargo-toml.js.map +1 -0
- package/dist/src/detectors/rust/parse-rust-toolchain.d.ts +18 -0
- package/dist/src/detectors/rust/parse-rust-toolchain.js +36 -0
- package/dist/src/detectors/rust/parse-rust-toolchain.js.map +1 -0
- package/dist/src/detectors/rust/toml-lines.d.ts +31 -0
- package/dist/src/detectors/rust/toml-lines.js +118 -0
- package/dist/src/detectors/rust/toml-lines.js.map +1 -0
- package/dist/src/doctor.d.ts +40 -0
- package/dist/src/doctor.js +234 -0
- package/dist/src/doctor.js.map +1 -0
- package/dist/src/domain.d.ts +56 -3
- package/dist/src/domain.js +5 -0
- package/dist/src/domain.js.map +1 -1
- package/dist/src/engine.js +30 -10
- package/dist/src/engine.js.map +1 -1
- package/dist/src/github-action.d.ts +30 -1
- package/dist/src/github-action.js +94 -4
- package/dist/src/github-action.js.map +1 -1
- package/dist/src/index.d.ts +4 -0
- package/dist/src/index.js +2 -0
- package/dist/src/index.js.map +1 -1
- package/dist/src/init-agents.d.ts +17 -0
- package/dist/src/init-agents.js +57 -0
- package/dist/src/init-agents.js.map +1 -0
- package/dist/src/mcp-cli.js +2 -7
- package/dist/src/mcp-cli.js.map +1 -1
- package/dist/src/mcp-server.d.ts +2 -0
- package/dist/src/mcp-server.js +11 -0
- package/dist/src/mcp-server.js.map +1 -0
- package/dist/src/mcp.d.ts +27 -1
- package/dist/src/mcp.js +178 -14
- package/dist/src/mcp.js.map +1 -1
- package/dist/src/migration-prompt.d.ts +8 -0
- package/dist/src/migration-prompt.js +28 -0
- package/dist/src/migration-prompt.js.map +1 -0
- package/dist/src/package-files.d.ts +2 -0
- package/dist/src/package-files.js +20 -0
- package/dist/src/package-files.js.map +1 -1
- package/dist/src/paths.d.ts +7 -0
- package/dist/src/paths.js +13 -0
- package/dist/src/paths.js.map +1 -0
- package/dist/src/purl.d.ts +23 -0
- package/dist/src/purl.js +174 -0
- package/dist/src/purl.js.map +1 -0
- package/dist/src/registry.d.ts +70 -0
- package/dist/src/registry.js +262 -0
- package/dist/src/registry.js.map +1 -0
- package/dist/src/reporters.d.ts +11 -1
- package/dist/src/reporters.js +133 -0
- package/dist/src/reporters.js.map +1 -1
- package/dist/src/rule-resources.d.ts +30 -0
- package/dist/src/rule-resources.js +26 -0
- package/dist/src/rule-resources.js.map +1 -0
- package/dist/src/sdk.d.ts +9 -2
- package/dist/src/sdk.js +2 -2
- package/dist/src/sdk.js.map +1 -1
- package/dist/src/source-usage.d.ts +2 -1
- package/dist/src/source-usage.js +281 -12
- package/dist/src/source-usage.js.map +1 -1
- package/dist/src/vers/gem.d.ts +3 -0
- package/dist/src/vers/gem.js +50 -0
- package/dist/src/vers/gem.js.map +1 -0
- package/dist/src/vers/index.d.ts +6 -0
- package/dist/src/vers/index.js +8 -0
- package/dist/src/vers/index.js.map +1 -0
- package/dist/src/vers/maven.d.ts +3 -0
- package/dist/src/vers/maven.js +230 -0
- package/dist/src/vers/maven.js.map +1 -0
- package/dist/src/vers/nuget.d.ts +3 -0
- package/dist/src/vers/nuget.js +55 -0
- package/dist/src/vers/nuget.js.map +1 -0
- package/dist/src/vers/pep440.d.ts +3 -0
- package/dist/src/vers/pep440.js +108 -0
- package/dist/src/vers/pep440.js.map +1 -0
- package/dist/src/vers/semver.d.ts +3 -0
- package/dist/src/vers/semver.js +22 -0
- package/dist/src/vers/semver.js.map +1 -0
- package/dist/src/vers.d.ts +44 -0
- package/dist/src/vers.js +191 -0
- package/dist/src/vers.js.map +1 -0
- package/dist/src/version.d.ts +1 -1
- package/dist/src/version.js +1 -1
- package/dist/src/workspaces.d.ts +25 -0
- package/dist/src/workspaces.js +165 -0
- package/dist/src/workspaces.js.map +1 -0
- package/examples/agents/README.md +14 -0
- package/examples/agents/copilot/.github/copilot-instructions.md +8 -0
- package/examples/agents/copilot/.vscode/mcp.json +14 -0
- package/examples/agents/copilot/README.md +18 -0
- package/examples/agents/copilot/coding-agent-mcp.json +22 -0
- package/examples/agents/cursor/.cursor/mcp.json +14 -0
- package/examples/agents/cursor/.cursor/rules/evergreen.mdc +13 -0
- package/examples/agents/cursor/README.md +18 -0
- package/examples/agents/dependency-check.md +8 -0
- package/examples/agents/gemini/GEMINI.md +8 -0
- package/examples/agents/gemini/README.md +24 -0
- package/examples/agents/gemini/gemini-extension.json +17 -0
- package/examples/agents/gemini/settings.json +14 -0
- package/examples/agents/kilo/.kilo/rules/evergreen.md +8 -0
- package/examples/agents/kilo/README.md +20 -0
- package/examples/agents/kilo/kilo.jsonc +18 -0
- package/examples/capabilities.json +49 -0
- package/examples/registry.v2.example.json +87 -0
- package/package.json +56 -9
- package/registry/container.json +281 -0
- package/registry/dotnet.json +484 -0
- package/registry/github-actions-shas.json +1247 -0
- package/registry/github-actions.json +1307 -61
- package/registry/go.json +351 -0
- package/registry/java.json +430 -0
- package/registry/kubernetes.json +324 -0
- package/registry/nodejs.json +385 -39
- package/registry/npm.json +2997 -46
- package/registry/python.json +1892 -63
- package/registry/rust.json +290 -0
- package/schemas/baseline.v1.schema.json +5 -1
- package/schemas/capabilities.v1.schema.json +89 -0
- package/schemas/check.v1.schema.json +50 -0
- package/schemas/data-bundle.v1.schema.json +61 -0
- package/schemas/data-status.v1.schema.json +29 -0
- package/schemas/deprecations.v1.schema.json +1 -0
- package/schemas/doctor.v1.schema.json +58 -0
- package/schemas/finding.v1.schema.json +259 -0
- package/schemas/migration-review-log.v1.schema.json +47 -0
- package/schemas/public-validation.v1.schema.json +56 -0
- package/schemas/registry.v2.schema.json +164 -0
- package/schemas/rule.v1.schema.json +42 -0
- package/schemas/scan.v1.schema.json +420 -45
- package/skills/evergreen-deprecation/README.md +52 -0
- package/skills/evergreen-deprecation/SKILL.md +7 -2
- package/skills/evergreen-deprecation/evals/cases.json +63 -49
- package/skills/evergreen-deprecation/evals/dependency-cases.json +389 -0
package/README.md
CHANGED
|
@@ -1,12 +1,42 @@
|
|
|
1
1
|
# Evergreen
|
|
2
2
|
|
|
3
|
+
<p align="center">
|
|
4
|
+
<picture>
|
|
5
|
+
<source media="(prefers-color-scheme: dark)" srcset="https://raw.githubusercontent.com/arminazimi/evergreen/main/brand/exports/banner-dark.png">
|
|
6
|
+
<source media="(prefers-color-scheme: light)" srcset="https://raw.githubusercontent.com/arminazimi/evergreen/main/brand/exports/banner-light.png">
|
|
7
|
+
<img alt="Evergreen — Know what breaks next." src="https://raw.githubusercontent.com/arminazimi/evergreen/main/brand/exports/banner-light.png" width="100%">
|
|
8
|
+
</picture>
|
|
9
|
+
</p>
|
|
10
|
+
|
|
3
11
|
[](https://github.com/arminazimi/evergreen/actions/workflows/ci.yml)
|
|
12
|
+
[](https://github.com/arminazimi/evergreen/actions/workflows/ci.yml)
|
|
4
13
|
[](https://www.npmjs.com/package/evergreen-deprecation)
|
|
14
|
+
[](https://skills.sh/arminazimi/evergreen/evergreen-deprecation)
|
|
15
|
+
[](docs/COMPATIBILITY.md)
|
|
16
|
+
[](docs/GITHUB_ACTION.md#code-scanning)
|
|
17
|
+
[](docs/MCP.md)
|
|
5
18
|
[](LICENSE)
|
|
6
19
|
|
|
7
|
-
Evergreen
|
|
20
|
+
Evergreen finds **end-of-life and deprecated** runtimes, packages, and GitHub Actions in your repository, shows the exact file and line, and backs every finding with an authoritative source, a replacement, and migration steps. It runs on your machine as a CLI, a local MCP server, a GitHub Action (with SARIF for code scanning), and an Agent Skill, so people and coding agents can find lifecycle risk before it breaks a build, and check a dependency before adding it. Scans are deterministic and offline, and need no account.
|
|
21
|
+
|
|
22
|
+
Read the [public documentation](https://arminazimi.github.io/evergreen/), run the [90-second demo](docs/DEMO.md), or inspect the [validation report](docs/VALIDATION.md). For AI tools, the docs are also published as [`llms.txt`](https://arminazimi.github.io/evergreen/llms.txt) and [`llms-full.txt`](https://arminazimi.github.io/evergreen/llms-full.txt).
|
|
23
|
+
|
|
24
|
+
## What it covers
|
|
8
25
|
|
|
9
|
-
|
|
26
|
+
| Ecosystem | What Evergreen reads | What it reports |
|
|
27
|
+
| --- | --- | --- |
|
|
28
|
+
| **Container base images** *(experimental)* | `Dockerfile`, `*.Dockerfile`, `Containerfile`, `compose.yaml`, `docker-compose.yml`: base images of official `node`, `python`, `postgres`, `mysql`, and `ruby` | Image release lines that are end of life. Variables, `latest`, and floating tags are listed as unclassified, never guessed. See [Container base images](docs/detectors/container.md) |
|
|
29
|
+
| **.NET** *(experimental)* | `global.json`, `*.csproj`/`*.fsproj`/`*.vbproj`, `Directory.Build.props`, `Directory.Packages.props`, `packages.lock.json`: the pinned SDK, target frameworks, and direct NuGet packages | .NET release lines past end of support, and direct packages their publisher deprecated, with the C# files that use them. .NET Framework, `netstandard`, MSBuild properties, floating versions, and ranges are not judged. See [.NET](docs/detectors/dotnet.md) |
|
|
30
|
+
| **Go** *(experimental)* | `go.mod` and `go.work`: `go` and `toolchain` directives, and direct `require` entries | Go release lines that no longer receive fixes, and direct modules with a lifecycle rule. Versions Evergreen cannot read are listed as unclassified. See [Go](docs/detectors/go.md) |
|
|
31
|
+
| **GitHub Actions** | `.github/workflows/*.yml`: `uses:` references to actions, including full-SHA pins resolved through a trailing version comment or a bundled release map | Actions on retired runtimes (such as Node.js 20) and retired or deprecated majors, at the exact line |
|
|
32
|
+
| **Java and Kotlin (JVM)** *(experimental)* | `pom.xml`, `build.gradle`, `build.gradle.kts`, `.java-version`, `.sdkmanrc`, `.tool-versions`: the JDK a project pins or targets, and direct Maven dependencies. See [Java and Kotlin](docs/detectors/java.md) | JDK feature releases that are out of support, and dependencies whose POM says they moved. Property references and expressions are listed as unclassified |
|
|
33
|
+
| **Kubernetes APIs** *(experimental)* | `*.yaml`, `*.yml` manifests, Helm chart `templates/`, and `kustomization.yaml`: the literal `apiVersion` and `kind`, and kustomize patches. See [Kubernetes APIs](docs/detectors/kubernetes.md) | API versions the Kubernetes project says are no longer served. Helm values, cluster-guarded templates, and anything it cannot read literally are skipped |
|
|
34
|
+
| **Node.js** | `engines.node`, `volta`, `.nvmrc`, `.node-version` | Runtime versions that are end of life or out of support |
|
|
35
|
+
| **npm** | `package.json` dependencies, `package-lock.json`, `npm-shrinkwrap.json`, `yarn.lock`, `pnpm-lock.yaml`, and the imports and calls that use each package | Deprecated or unmaintained packages, with the replacement and where the package is used |
|
|
36
|
+
| **Python** | `pyproject.toml`, `requirements*.txt`, `.python-version`, `runtime.txt`, `.tool-versions`, `poetry.lock`, `uv.lock`, `Pipfile.lock` | Python versions that are end of life, and deprecated or obsolete packages |
|
|
37
|
+
| **Rust** *(experimental)* | `Cargo.toml`, `Cargo.lock`, `rust-toolchain(.toml)`: the pinned toolchain and direct crate dependencies | Toolchains older than the newest stable release, and direct dependencies on unmaintained crates with the files that use them. `edition`, `rust-version`, `stable`, and anything it cannot read literally are not judged. See [Rust](docs/detectors/rust.md) |
|
|
38
|
+
|
|
39
|
+
Each finding carries its rule's sources, review date, and migration steps; see [Lifecycle rules](docs/RULES.md). Other ecosystems are not guessed at: Evergreen reports a package it has no rule for as `no-data`, never as safe, and new ecosystems start from a [generated detector skeleton](docs/DETECTORS.md#start-a-new-detector-in-this-repository). The [compatibility matrix](docs/COMPATIBILITY.md) lists supported environments and hosts.
|
|
10
40
|
|
|
11
41
|
## Product principles
|
|
12
42
|
|
|
@@ -24,6 +54,26 @@ Requirements: Node.js 22 or newer.
|
|
|
24
54
|
npx evergreen-deprecation scan .
|
|
25
55
|
```
|
|
26
56
|
|
|
57
|
+
Verify that the CLI, local MCP server, Agent Skill, plugin foundations, and CI
|
|
58
|
+
workspace are ready without changing configuration or uploading repository data:
|
|
59
|
+
|
|
60
|
+
```bash
|
|
61
|
+
npx evergreen-deprecation doctor .
|
|
62
|
+
npx evergreen-deprecation doctor . --json
|
|
63
|
+
```
|
|
64
|
+
|
|
65
|
+
See the [public compatibility matrix](docs/COMPATIBILITY.md) for supported,
|
|
66
|
+
experimental, and unsupported combinations.
|
|
67
|
+
|
|
68
|
+
Discover Evergreen's versioned capabilities and entry points programmatically:
|
|
69
|
+
|
|
70
|
+
```bash
|
|
71
|
+
npx evergreen-deprecation capabilities --json
|
|
72
|
+
```
|
|
73
|
+
|
|
74
|
+
The [auto-discovery contract](docs/CAPABILITIES.md) defines the shared identifiers
|
|
75
|
+
used by the CLI, MCP server, Agent Skill, plugins, and CI integrations.
|
|
76
|
+
|
|
27
77
|
Create a baseline for accepted existing findings, then report only new lifecycle regressions:
|
|
28
78
|
|
|
29
79
|
```bash
|
|
@@ -31,6 +81,24 @@ npx evergreen-deprecation baseline .
|
|
|
31
81
|
npx evergreen-deprecation scan . --baseline .evergreen-baseline.json
|
|
32
82
|
```
|
|
33
83
|
|
|
84
|
+
Check a single dependency before adding it, without scanning a repository:
|
|
85
|
+
|
|
86
|
+
```bash
|
|
87
|
+
npx evergreen-deprecation check pkg:npm/request@2.88.2
|
|
88
|
+
npx evergreen-deprecation check pkg:github/actions/checkout@v4 --json
|
|
89
|
+
```
|
|
90
|
+
|
|
91
|
+
The command prints the lifecycle problem, replacement, and evidence, and exits `1` when a rule at or above `--fail-on` (default `high`) applies, `0` otherwise, and `2` for invalid input. A package Evergreen has no rule for reports `no-data`, which is not a claim that it is safe. Without a version, a package whose rules only cover some versions reports `version-dependent`; add a version to get a definite answer.
|
|
92
|
+
|
|
93
|
+
Lifecycle rules can be refreshed between releases from signed bundles, and scans stay offline unless you ask:
|
|
94
|
+
|
|
95
|
+
```bash
|
|
96
|
+
npx evergreen-deprecation data status
|
|
97
|
+
npx evergreen-deprecation data update
|
|
98
|
+
```
|
|
99
|
+
|
|
100
|
+
See [Lifecycle data](docs/DATA.md) for the signing and trust model, pinning, and what happens when a download cannot be verified.
|
|
101
|
+
|
|
34
102
|
Inspect the evidence and migration direction for one result:
|
|
35
103
|
|
|
36
104
|
```bash
|
|
@@ -45,17 +113,39 @@ npx evergreen-deprecation context '<finding-id>' . --json
|
|
|
45
113
|
|
|
46
114
|
Migration packets contain rule-specific constraints and steps, exact affected files and usages, authoritative sources, and suggested verification commands. Evergreen never executes those commands automatically. See the [migration packet guide](docs/MIGRATION_PACKETS.md).
|
|
47
115
|
|
|
116
|
+
Tell the coding agents working in a repository to check dependencies before adding them. This adds (or refreshes) a clearly marked section in `AGENTS.md`, or `CLAUDE.md` if that is the file you have; running it again changes nothing, and nothing outside the markers is touched:
|
|
117
|
+
|
|
118
|
+
```bash
|
|
119
|
+
npx evergreen-deprecation init --agents --dry-run # show the change
|
|
120
|
+
npx evergreen-deprecation init --agents
|
|
121
|
+
```
|
|
122
|
+
|
|
48
123
|
Connect a coding agent through the local MCP server:
|
|
49
124
|
|
|
50
125
|
```bash
|
|
51
126
|
npx --yes --package evergreen-deprecation evergreen-mcp
|
|
52
127
|
```
|
|
53
128
|
|
|
54
|
-
The stdio server exposes `scan_repository`, `list_deprecations`, `explain_deprecation`, `create_migration_context`, and `
|
|
129
|
+
The stdio server exposes `scan_repository`, `list_deprecations`, `explain_deprecation`, `create_migration_context`, `verify_migration`, and `check_dependency` (check one package before adding it). See the [local MCP guide](docs/MCP.md) for host configuration, the intended workflow, and privacy guarantees.
|
|
55
130
|
|
|
56
131
|
## Agent Skill
|
|
57
132
|
|
|
58
|
-
|
|
133
|
+
Install the vendor-neutral Agent Skill from the monorepo:
|
|
134
|
+
|
|
135
|
+
```bash
|
|
136
|
+
npx skills add arminazimi/evergreen
|
|
137
|
+
```
|
|
138
|
+
|
|
139
|
+
Pull future revisions with:
|
|
140
|
+
|
|
141
|
+
```bash
|
|
142
|
+
npx skills update evergreen-deprecation
|
|
143
|
+
```
|
|
144
|
+
|
|
145
|
+
The [`evergreen-deprecation` Skill](skills/evergreen-deprecation/README.md) teaches discovery, explanation, migration, and verification while leaving detection and migration logic inside Evergreen. It is discoverable on [skills.sh](https://skills.sh/arminazimi/evergreen/evergreen-deprecation) and has been install-validated for Codex, Claude Code, Cursor, GitHub Copilot, and Gemini CLI. See the [Agent Skill guide](docs/AGENT_SKILLS.md) for evaluation, compatibility, limits, and security assumptions.
|
|
146
|
+
|
|
147
|
+
Codex and Claude plugin packages are generated from that same Skill and MCP workflow. Their [packaging architecture](docs/PLUGIN_PACKAGING.md) keeps host manifests thin and fails CI when either package drifts from the canonical sources.
|
|
148
|
+
The [cross-host evaluation](docs/PLUGIN_EVALS.md) publishes shared-corpus results, context budgets, permission behavior, and security limitations; the same checks block release regressions in `npm run check`.
|
|
59
149
|
|
|
60
150
|
Evergreen runs locally and does not upload repository contents.
|
|
61
151
|
|
|
@@ -102,7 +192,7 @@ permissions:
|
|
|
102
192
|
|
|
103
193
|
steps:
|
|
104
194
|
- uses: actions/checkout@v7
|
|
105
|
-
- uses: arminazimi/evergreen@v0.
|
|
195
|
+
- uses: arminazimi/evergreen@v0.3.0
|
|
106
196
|
with:
|
|
107
197
|
baseline: .evergreen-baseline.json
|
|
108
198
|
fail-on-severity: high
|
|
@@ -118,6 +208,16 @@ See the [detector authoring guide](docs/DETECTORS.md) and the [minimal detector
|
|
|
118
208
|
|
|
119
209
|
## Initial product shape
|
|
120
210
|
|
|
121
|
-
The CLI is the product. Detectors extend it, GitHub Actions automate it, and the local MCP server exposes it to agents. A hosted backend is intentionally outside the
|
|
211
|
+
The CLI is the product. Detectors extend it, GitHub Actions automate it, and the local MCP server exposes it to agents. A hosted backend is intentionally outside the roadmap; lifecycle data updates through a signed, offline-verifiable data channel instead.
|
|
212
|
+
|
|
213
|
+
See [the roadmap](docs/ROADMAP.md), [architecture](docs/ARCHITECTURE.md), [brand guide](brand/BRAND_GUIDE.md), and [contribution guide](CONTRIBUTING.md).
|
|
214
|
+
|
|
215
|
+
## Community
|
|
216
|
+
|
|
217
|
+
Questions, ideas, and things you built with Evergreen belong in [GitHub Discussions](https://github.com/arminazimi/evergreen/discussions): use **Q&A** to ask, **Ideas** to propose, and **Show and tell** to share. Use issues for bugs, lifecycle rule requests, and ecosystem requests.
|
|
218
|
+
|
|
219
|
+
## License and brand
|
|
122
220
|
|
|
123
|
-
|
|
221
|
+
Evergreen source code is licensed under the [Apache License 2.0](LICENSE). The
|
|
222
|
+
Evergreen name, logo, and files in [`brand/`](brand/) are proprietary brand assets
|
|
223
|
+
and are covered by separate [brand asset terms](brand/LICENSE.md).
|
package/data/README.md
ADDED
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
# Bundled trust material
|
|
2
|
+
|
|
3
|
+
`sigstore-trusted-root.json` is the Sigstore public-good trusted root: the keys and validity periods of the Fulcio certificate authority, the Rekor transparency log, and the certificate transparency log. Evergreen uses it to verify a lifecycle data bundle's signature offline. It ships in the npm package.
|
|
4
|
+
|
|
5
|
+
| | |
|
|
6
|
+
| --- | --- |
|
|
7
|
+
| Source | https://github.com/sigstore/root-signing/blob/main/targets/trusted_root.json |
|
|
8
|
+
| Fetched | 2026-10-16 |
|
|
9
|
+
| SHA-256 | `6494e21ea73fa7ee769f85f57d5a3e6a08725eae1e38c755fc3517c9e6bc0b66` |
|
|
10
|
+
|
|
11
|
+
Trust in this file is trust in the Evergreen release that contains it, the same as trust in the registries bundled with that release. Sigstore rotates these keys occasionally; when a signing key in the file expires, signatures made after that time no longer verify and Evergreen falls back to its bundled data with a warning. Refresh the file when Sigstore publishes a new root, update the hash above, and release. A test checks the hash.
|
|
@@ -0,0 +1,126 @@
|
|
|
1
|
+
{
|
|
2
|
+
"mediaType": "application/vnd.dev.sigstore.trustedroot+json;version=0.1",
|
|
3
|
+
"tlogs": [
|
|
4
|
+
{
|
|
5
|
+
"baseUrl": "https://rekor.sigstore.dev",
|
|
6
|
+
"hashAlgorithm": "SHA2_256",
|
|
7
|
+
"publicKey": {
|
|
8
|
+
"rawBytes": "MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAE2G2Y+2tabdTV5BcGiBIx0a9fAFwrkBbmLSGtks4L3qX6yYY0zufBnhC8Ur/iy55GhWP/9A/bY2LhC30M9+RYtw==",
|
|
9
|
+
"keyDetails": "PKIX_ECDSA_P256_SHA_256",
|
|
10
|
+
"validFor": {
|
|
11
|
+
"start": "2021-01-12T11:53:27Z"
|
|
12
|
+
}
|
|
13
|
+
},
|
|
14
|
+
"logId": {
|
|
15
|
+
"keyId": "wNI9atQGlz+VWfO6LRygH4QUfY/8W4RFwiT5i5WRgB0="
|
|
16
|
+
}
|
|
17
|
+
},
|
|
18
|
+
{
|
|
19
|
+
"baseUrl": "https://log2025-1.rekor.sigstore.dev",
|
|
20
|
+
"hashAlgorithm": "SHA2_256",
|
|
21
|
+
"publicKey": {
|
|
22
|
+
"rawBytes": "MCowBQYDK2VwAyEAt8rlp1knGwjfbcXAYPYAkn0XiLz1x8O4t0YkEhie244=",
|
|
23
|
+
"keyDetails": "PKIX_ED25519",
|
|
24
|
+
"validFor": {
|
|
25
|
+
"start": "2025-09-23T00:00:00Z"
|
|
26
|
+
}
|
|
27
|
+
},
|
|
28
|
+
"logId": {
|
|
29
|
+
"keyId": "zxGZFVvd0FEmjR8WrFwMdcAJ9vtaY/QXf44Y1wUeP6A="
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
],
|
|
33
|
+
"certificateAuthorities": [
|
|
34
|
+
{
|
|
35
|
+
"subject": {
|
|
36
|
+
"organization": "sigstore.dev",
|
|
37
|
+
"commonName": "sigstore"
|
|
38
|
+
},
|
|
39
|
+
"uri": "https://fulcio.sigstore.dev",
|
|
40
|
+
"certChain": {
|
|
41
|
+
"certificates": [
|
|
42
|
+
{
|
|
43
|
+
"rawBytes": "MIIB+DCCAX6gAwIBAgITNVkDZoCiofPDsy7dfm6geLbuhzAKBggqhkjOPQQDAzAqMRUwEwYDVQQKEwxzaWdzdG9yZS5kZXYxETAPBgNVBAMTCHNpZ3N0b3JlMB4XDTIxMDMwNzAzMjAyOVoXDTMxMDIyMzAzMjAyOVowKjEVMBMGA1UEChMMc2lnc3RvcmUuZGV2MREwDwYDVQQDEwhzaWdzdG9yZTB2MBAGByqGSM49AgEGBSuBBAAiA2IABLSyA7Ii5k+pNO8ZEWY0ylemWDowOkNa3kL+GZE5Z5GWehL9/A9bRNA3RbrsZ5i0JcastaRL7Sp5fp/jD5dxqc/UdTVnlvS16an+2Yfswe/QuLolRUCrcOE2+2iA5+tzd6NmMGQwDgYDVR0PAQH/BAQDAgEGMBIGA1UdEwEB/wQIMAYBAf8CAQEwHQYDVR0OBBYEFMjFHQBBmiQpMlEk6w2uSu1KBtPsMB8GA1UdIwQYMBaAFMjFHQBBmiQpMlEk6w2uSu1KBtPsMAoGCCqGSM49BAMDA2gAMGUCMH8liWJfMui6vXXBhjDgY4MwslmN/TJxVe/83WrFomwmNf056y1X48F9c4m3a3ozXAIxAKjRay5/aj/jsKKGIkmQatjI8uupHr/+CxFvaJWmpYqNkLDGRU+9orzh5hI2RrcuaQ=="
|
|
44
|
+
}
|
|
45
|
+
]
|
|
46
|
+
},
|
|
47
|
+
"validFor": {
|
|
48
|
+
"start": "2021-03-07T03:20:29Z",
|
|
49
|
+
"end": "2022-12-31T23:59:59.999Z"
|
|
50
|
+
}
|
|
51
|
+
},
|
|
52
|
+
{
|
|
53
|
+
"subject": {
|
|
54
|
+
"organization": "sigstore.dev",
|
|
55
|
+
"commonName": "sigstore"
|
|
56
|
+
},
|
|
57
|
+
"uri": "https://fulcio.sigstore.dev",
|
|
58
|
+
"certChain": {
|
|
59
|
+
"certificates": [
|
|
60
|
+
{
|
|
61
|
+
"rawBytes": "MIICGjCCAaGgAwIBAgIUALnViVfnU0brJasmRkHrn/UnfaQwCgYIKoZIzj0EAwMwKjEVMBMGA1UEChMMc2lnc3RvcmUuZGV2MREwDwYDVQQDEwhzaWdzdG9yZTAeFw0yMjA0MTMyMDA2MTVaFw0zMTEwMDUxMzU2NThaMDcxFTATBgNVBAoTDHNpZ3N0b3JlLmRldjEeMBwGA1UEAxMVc2lnc3RvcmUtaW50ZXJtZWRpYXRlMHYwEAYHKoZIzj0CAQYFK4EEACIDYgAE8RVS/ysH+NOvuDZyPIZtilgUF9NlarYpAd9HP1vBBH1U5CV77LSS7s0ZiH4nE7Hv7ptS6LvvR/STk798LVgMzLlJ4HeIfF3tHSaexLcYpSASr1kS0N/RgBJz/9jWCiXno3sweTAOBgNVHQ8BAf8EBAMCAQYwEwYDVR0lBAwwCgYIKwYBBQUHAwMwEgYDVR0TAQH/BAgwBgEB/wIBADAdBgNVHQ4EFgQU39Ppz1YkEZb5qNjpKFWixi4YZD8wHwYDVR0jBBgwFoAUWMAeX5FFpWapesyQoZMi0CrFxfowCgYIKoZIzj0EAwMDZwAwZAIwPCsQK4DYiZYDPIaDi5HFKnfxXx6ASSVmERfsynYBiX2X6SJRnZU84/9DZdnFvvxmAjBOt6QpBlc4J/0DxvkTCqpclvziL6BCCPnjdlIB3Pu3BxsPmygUY7Ii2zbdCdliiow="
|
|
62
|
+
},
|
|
63
|
+
{
|
|
64
|
+
"rawBytes": "MIIB9zCCAXygAwIBAgIUALZNAPFdxHPwjeDloDwyYChAO/4wCgYIKoZIzj0EAwMwKjEVMBMGA1UEChMMc2lnc3RvcmUuZGV2MREwDwYDVQQDEwhzaWdzdG9yZTAeFw0yMTEwMDcxMzU2NTlaFw0zMTEwMDUxMzU2NThaMCoxFTATBgNVBAoTDHNpZ3N0b3JlLmRldjERMA8GA1UEAxMIc2lnc3RvcmUwdjAQBgcqhkjOPQIBBgUrgQQAIgNiAAT7XeFT4rb3PQGwS4IajtLk3/OlnpgangaBclYpsYBr5i+4ynB07ceb3LP0OIOZdxexX69c5iVuyJRQ+Hz05yi+UF3uBWAlHpiS5sh0+H2GHE7SXrk1EC5m1Tr19L9gg92jYzBhMA4GA1UdDwEB/wQEAwIBBjAPBgNVHRMBAf8EBTADAQH/MB0GA1UdDgQWBBRYwB5fkUWlZql6zJChkyLQKsXF+jAfBgNVHSMEGDAWgBRYwB5fkUWlZql6zJChkyLQKsXF+jAKBggqhkjOPQQDAwNpADBmAjEAj1nHeXZp+13NWBNa+EDsDP8G1WWg1tCMWP/WHPqpaVo0jhsweNFZgSs0eE7wYI4qAjEA2WB9ot98sIkoF3vZYdd3/VtWB5b9TNMea7Ix/stJ5TfcLLeABLE4BNJOsQ4vnBHJ"
|
|
65
|
+
}
|
|
66
|
+
]
|
|
67
|
+
},
|
|
68
|
+
"validFor": {
|
|
69
|
+
"start": "2022-04-13T20:06:15Z"
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
],
|
|
73
|
+
"ctlogs": [
|
|
74
|
+
{
|
|
75
|
+
"baseUrl": "https://ctfe.sigstore.dev/test",
|
|
76
|
+
"hashAlgorithm": "SHA2_256",
|
|
77
|
+
"publicKey": {
|
|
78
|
+
"rawBytes": "MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEbfwR+RJudXscgRBRpKX1XFDy3PyudDxz/SfnRi1fT8ekpfBd2O1uoz7jr3Z8nKzxA69EUQ+eFCFI3zeubPWU7w==",
|
|
79
|
+
"keyDetails": "PKIX_ECDSA_P256_SHA_256",
|
|
80
|
+
"validFor": {
|
|
81
|
+
"start": "2021-03-14T00:00:00Z",
|
|
82
|
+
"end": "2022-10-31T23:59:59.999Z"
|
|
83
|
+
}
|
|
84
|
+
},
|
|
85
|
+
"logId": {
|
|
86
|
+
"keyId": "CGCS8ChS/2hF0dFrJ4ScRWcYrBY9wzjSbea8IgY2b3I="
|
|
87
|
+
}
|
|
88
|
+
},
|
|
89
|
+
{
|
|
90
|
+
"baseUrl": "https://ctfe.sigstore.dev/2022",
|
|
91
|
+
"hashAlgorithm": "SHA2_256",
|
|
92
|
+
"publicKey": {
|
|
93
|
+
"rawBytes": "MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEiPSlFi0CmFTfEjCUqF9HuCEcYXNKAaYalIJmBZ8yyezPjTqhxrKBpMnaocVtLJBI1eM3uXnQzQGAJdJ4gs9Fyw==",
|
|
94
|
+
"keyDetails": "PKIX_ECDSA_P256_SHA_256",
|
|
95
|
+
"validFor": {
|
|
96
|
+
"start": "2022-10-20T00:00:00Z"
|
|
97
|
+
}
|
|
98
|
+
},
|
|
99
|
+
"logId": {
|
|
100
|
+
"keyId": "3T0wasbHETJjGR4cmWc3AqJKXrjePK3/h4pygC8p7o4="
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
],
|
|
104
|
+
"timestampAuthorities": [
|
|
105
|
+
{
|
|
106
|
+
"subject": {
|
|
107
|
+
"organization": "sigstore.dev",
|
|
108
|
+
"commonName": "sigstore-tsa-selfsigned"
|
|
109
|
+
},
|
|
110
|
+
"uri": "https://timestamp.sigstore.dev/api/v1/timestamp",
|
|
111
|
+
"certChain": {
|
|
112
|
+
"certificates": [
|
|
113
|
+
{
|
|
114
|
+
"rawBytes": "MIICEDCCAZagAwIBAgIUOhNULwyQYe68wUMvy4qOiyojiwwwCgYIKoZIzj0EAwMwOTEVMBMGA1UEChMMc2lnc3RvcmUuZGV2MSAwHgYDVQQDExdzaWdzdG9yZS10c2Etc2VsZnNpZ25lZDAeFw0yNTA0MDgwNjU5NDNaFw0zNTA0MDYwNjU5NDNaMC4xFTATBgNVBAoTDHNpZ3N0b3JlLmRldjEVMBMGA1UEAxMMc2lnc3RvcmUtdHNhMHYwEAYHKoZIzj0CAQYFK4EEACIDYgAE4ra2Z8hKNig2T9kFjCAToGG30jky+WQv3BzL+mKvh1SKNR/UwuwsfNCg4sryoYAd8E6isovVA3M4aoNdm9QDi50Z8nTEyvqgfDPtTIwXItfiW/AFf1V7uwkbkAoj0xxco2owaDAOBgNVHQ8BAf8EBAMCB4AwHQYDVR0OBBYEFIn9eUOHz9BlRsMCRscsc1t9tOsDMB8GA1UdIwQYMBaAFJjsAe9/u1H/1JUeb4qImFMHic6/MBYGA1UdJQEB/wQMMAoGCCsGAQUFBwMIMAoGCCqGSM49BAMDA2gAMGUCMDtpsV/6KaO0qyF/UMsX2aSUXKQFdoGTptQGc0ftq1csulHPGG6dsmyMNd3JB+G3EQIxAOajvBcjpJmKb4Nv+2Taoj8Uc5+b6ih6FXCCKraSqupe07zqswMcXJTe1cExvHvvlw=="
|
|
115
|
+
},
|
|
116
|
+
{
|
|
117
|
+
"rawBytes": "MIIB9zCCAXygAwIBAgIUV7f0GLDOoEzIh8LXSW80OJiUp14wCgYIKoZIzj0EAwMwOTEVMBMGA1UEChMMc2lnc3RvcmUuZGV2MSAwHgYDVQQDExdzaWdzdG9yZS10c2Etc2VsZnNpZ25lZDAeFw0yNTA0MDgwNjU5NDNaFw0zNTA0MDYwNjU5NDNaMDkxFTATBgNVBAoTDHNpZ3N0b3JlLmRldjEgMB4GA1UEAxMXc2lnc3RvcmUtdHNhLXNlbGZzaWduZWQwdjAQBgcqhkjOPQIBBgUrgQQAIgNiAAQUQNtfRT/ou3YATa6wB/kKTe70cfJwyRIBovMnt8RcJph/COE82uyS6FmppLLL1VBPGcPfpQPYJNXzWwi8icwhKQ6W/Qe2h3oebBb2FHpwNJDqo+TMaC/tdfkv/ElJB72jRTBDMA4GA1UdDwEB/wQEAwIBBjASBgNVHRMBAf8ECDAGAQH/AgEAMB0GA1UdDgQWBBSY7AHvf7tR/9SVHm+KiJhTB4nOvzAKBggqhkjOPQQDAwNpADBmAjEAwGEGrfGZR1cen1R8/DTVMI943LssZmJRtDp/i7SfGHmGRP6gRbuj9vOK3b67Z0QQAjEAuT2H673LQEaHTcyQSZrkp4mX7WwkmF+sVbkYY5mXN+RMH13KUEHHOqASaemYWK/E"
|
|
118
|
+
}
|
|
119
|
+
]
|
|
120
|
+
},
|
|
121
|
+
"validFor": {
|
|
122
|
+
"start": "2025-07-04T00:00:00Z"
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
]
|
|
126
|
+
}
|
package/dist/src/action.js
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
import { appendFile } from "node:fs/promises";
|
|
3
3
|
import process from "node:process";
|
|
4
4
|
import { resolve } from "node:path";
|
|
5
|
-
import { runGitHubAction } from "./github-action.js";
|
|
5
|
+
import { renderFailure, renderSummary, runGitHubAction } from "./github-action.js";
|
|
6
6
|
function commandValue(value) {
|
|
7
7
|
return value.replaceAll("%", "%25").replaceAll("\r", "%0D").replaceAll("\n", "%0A");
|
|
8
8
|
}
|
|
@@ -23,32 +23,52 @@ async function setOutput(name, value) {
|
|
|
23
23
|
if (output)
|
|
24
24
|
await appendFile(output, `${name}=${value}\n`, "utf8");
|
|
25
25
|
}
|
|
26
|
-
async function writeSummary(findings, failed, gate) {
|
|
26
|
+
async function writeSummary(findings, failed, gate, data, expiredFailure = false, suppressions) {
|
|
27
27
|
const summary = process.env.GITHUB_STEP_SUMMARY;
|
|
28
28
|
if (!summary)
|
|
29
29
|
return;
|
|
30
|
-
|
|
31
|
-
|
|
30
|
+
// On by default; `attribution: "false"` turns the line off.
|
|
31
|
+
const attribution = process.env.INPUT_ATTRIBUTION !== "false";
|
|
32
|
+
const note = expiredFailure ? "\n> **Failed:** a baseline suppression has expired and `on-expired` is set to `fail`.\n" : "";
|
|
33
|
+
await appendFile(summary, `${renderSummary(findings, failed, gate, data, attribution, suppressions)}${note}`, "utf8");
|
|
32
34
|
}
|
|
33
35
|
async function main() {
|
|
34
36
|
try {
|
|
35
37
|
const workspace = process.env.GITHUB_WORKSPACE ?? process.cwd();
|
|
36
38
|
const root = process.env.INPUT_PATH || workspace;
|
|
37
39
|
const reportPath = resolve(process.env.RUNNER_TEMP ?? workspace, "evergreen-report.json");
|
|
40
|
+
const sarifPath = process.env["INPUT_UPLOAD-SARIF"] === "true"
|
|
41
|
+
? resolve(process.env.RUNNER_TEMP ?? workspace, "evergreen-results.sarif")
|
|
42
|
+
: undefined;
|
|
38
43
|
const outcome = await runGitHubAction({
|
|
39
44
|
root,
|
|
40
45
|
reportPath,
|
|
46
|
+
...(sarifPath ? { sarifPath } : {}),
|
|
41
47
|
...(process.env.INPUT_BASELINE ? { baselinePath: process.env.INPUT_BASELINE } : {}),
|
|
48
|
+
...(process.env["INPUT_BASELINE-WARN-DAYS"] ? { baselineWarnDays: Number(process.env["INPUT_BASELINE-WARN-DAYS"]) } : {}),
|
|
49
|
+
...(process.env["INPUT_ON-EXPIRED"] ? { onExpired: process.env["INPUT_ON-EXPIRED"] } : {}),
|
|
42
50
|
failOnSeverity: (process.env["INPUT_FAIL-ON-SEVERITY"] || "high"),
|
|
43
51
|
});
|
|
44
52
|
for (const annotation of outcome.annotations)
|
|
45
53
|
console.log(annotationCommand(annotation));
|
|
54
|
+
// A suppression about to expire is a warning on the run, not a finding.
|
|
55
|
+
for (const diagnostic of outcome.result.diagnostics) {
|
|
56
|
+
if (diagnostic.startsWith("Baseline suppression expired"))
|
|
57
|
+
console.log(`::warning title=Evergreen baseline suppression expired::${commandValue(diagnostic)}`);
|
|
58
|
+
if (diagnostic.startsWith("Baseline suppression expires"))
|
|
59
|
+
console.log(`::warning title=Evergreen baseline suppression expires soon::${commandValue(diagnostic)}`);
|
|
60
|
+
}
|
|
46
61
|
await setOutput("report-path", outcome.reportPath);
|
|
62
|
+
if (outcome.sarifPath)
|
|
63
|
+
await setOutput("sarif-path", outcome.sarifPath);
|
|
47
64
|
await setOutput("finding-count", String(outcome.result.findings.length));
|
|
48
|
-
await writeSummary(outcome.result.findings.
|
|
65
|
+
await writeSummary(outcome.result.findings, outcome.gateFailed, outcome.gate, outcome.result.data, outcome.expiredFailure, outcome.result.suppressions);
|
|
66
|
+
if (outcome.result.data?.stale)
|
|
67
|
+
console.log(`::warning title=Evergreen lifecycle data is stale::The data is ${outcome.result.data.ageDays} days old, so findings may miss recent changes.`);
|
|
49
68
|
console.log(`Evergreen found ${outcome.result.findings.length} new lifecycle finding${outcome.result.findings.length === 1 ? "" : "s"}.`);
|
|
50
|
-
|
|
51
|
-
|
|
69
|
+
const failure = renderFailure(outcome);
|
|
70
|
+
if (failure) {
|
|
71
|
+
console.log(`::error title=Evergreen policy gate failed::${commandValue(failure)}`);
|
|
52
72
|
process.exitCode = 1;
|
|
53
73
|
}
|
|
54
74
|
}
|
package/dist/src/action.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"action.js","sourceRoot":"","sources":["../../src/action.ts"],"names":[],"mappings":";AAEA,OAAO,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AAC9C,OAAO,OAAO,MAAM,cAAc,CAAC;AACnC,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;
|
|
1
|
+
{"version":3,"file":"action.js","sourceRoot":"","sources":["../../src/action.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
/** The section `evergreen init --agents` keeps in a repository's AGENTS.md or CLAUDE.md. */
|
|
2
|
+
export declare const SECTION_BEGIN = "<!-- evergreen:begin -->";
|
|
3
|
+
export declare const SECTION_END = "<!-- evergreen:end -->";
|
|
4
|
+
/** The instructions themselves; `examples/agents/dependency-check.md` carries the same text for hosts configured by hand. */
|
|
5
|
+
export declare const DEPENDENCY_CHECK_INSTRUCTIONS = "Before you add a new package, runtime, or GitHub Action to this project, or pick one to replace another, check it with Evergreen.\n\n- Call the `check_dependency` tool with a Package URL, for example `pkg:npm/request@2.88.2`, `pkg:pypi/nose`, or `pkg:github/actions/checkout@v4`. Without MCP, run `npx evergreen-deprecation check <purl>`.\n- If the status is `affected`, prefer the replacement it names and tell the user why, citing the evidence links it returns.\n- `version-dependent` means rules exist only for some versions: call again with the version you intend to use. `no-data` means Evergreen has no rule for that package; it is not a claim that the package is safe.\n- Do not use Evergreen for security vulnerability audits or for routine upgrades of dependencies the project already uses.\n";
|
|
6
|
+
export declare const AGENT_SECTION = "<!-- evergreen:begin -->\n<!-- This section is maintained by `evergreen init --agents`. Edit around it, not inside it. -->\n## Evergreen dependency check\n\nBefore you add a new package, runtime, or GitHub Action to this project, or pick one to replace another, check it with Evergreen.\n\n- Call the `check_dependency` tool with a Package URL, for example `pkg:npm/request@2.88.2`, `pkg:pypi/nose`, or `pkg:github/actions/checkout@v4`. Without MCP, run `npx evergreen-deprecation check <purl>`.\n- If the status is `affected`, prefer the replacement it names and tell the user why, citing the evidence links it returns.\n- `version-dependent` means rules exist only for some versions: call again with the version you intend to use. `no-data` means Evergreen has no rule for that package; it is not a claim that the package is safe.\n- Do not use Evergreen for security vulnerability audits or for routine upgrades of dependencies the project already uses.\n<!-- evergreen:end -->";
|
|
7
|
+
export declare class AgentFileError extends Error {
|
|
8
|
+
constructor(message: string);
|
|
9
|
+
}
|
|
10
|
+
export interface SectionUpdate {
|
|
11
|
+
text: string;
|
|
12
|
+
change: "created" | "added" | "updated" | "unchanged";
|
|
13
|
+
}
|
|
14
|
+
/**
|
|
15
|
+
* Returns `existing` with the Evergreen section added or refreshed. Everything outside the markers is preserved
|
|
16
|
+
* byte for byte, including the file's line endings; a file with damaged markers is refused rather than guessed at.
|
|
17
|
+
*/
|
|
18
|
+
export declare function withAgentSection(existing: string | undefined): SectionUpdate;
|
|
19
|
+
/** A small unified diff of the one region that changes, with two lines of context. */
|
|
20
|
+
export declare function renderDiff(file: string, before: string, after: string): string;
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
/** The section `evergreen init --agents` keeps in a repository's AGENTS.md or CLAUDE.md. */
|
|
2
|
+
export const SECTION_BEGIN = "<!-- evergreen:begin -->";
|
|
3
|
+
export const SECTION_END = "<!-- evergreen:end -->";
|
|
4
|
+
/** The instructions themselves; `examples/agents/dependency-check.md` carries the same text for hosts configured by hand. */
|
|
5
|
+
export const DEPENDENCY_CHECK_INSTRUCTIONS = `Before you add a new package, runtime, or GitHub Action to this project, or pick one to replace another, check it with Evergreen.
|
|
6
|
+
|
|
7
|
+
- Call the \`check_dependency\` tool with a Package URL, for example \`pkg:npm/request@2.88.2\`, \`pkg:pypi/nose\`, or \`pkg:github/actions/checkout@v4\`. Without MCP, run \`npx evergreen-deprecation check <purl>\`.
|
|
8
|
+
- If the status is \`affected\`, prefer the replacement it names and tell the user why, citing the evidence links it returns.
|
|
9
|
+
- \`version-dependent\` means rules exist only for some versions: call again with the version you intend to use. \`no-data\` means Evergreen has no rule for that package; it is not a claim that the package is safe.
|
|
10
|
+
- Do not use Evergreen for security vulnerability audits or for routine upgrades of dependencies the project already uses.
|
|
11
|
+
`;
|
|
12
|
+
export const AGENT_SECTION = `${SECTION_BEGIN}
|
|
13
|
+
<!-- This section is maintained by \`evergreen init --agents\`. Edit around it, not inside it. -->
|
|
14
|
+
## Evergreen dependency check
|
|
15
|
+
|
|
16
|
+
${DEPENDENCY_CHECK_INSTRUCTIONS}${SECTION_END}`;
|
|
17
|
+
export class AgentFileError extends Error {
|
|
18
|
+
constructor(message) {
|
|
19
|
+
super(message);
|
|
20
|
+
this.name = "AgentFileError";
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
/**
|
|
24
|
+
* Returns `existing` with the Evergreen section added or refreshed. Everything outside the markers is preserved
|
|
25
|
+
* byte for byte, including the file's line endings; a file with damaged markers is refused rather than guessed at.
|
|
26
|
+
*/
|
|
27
|
+
export function withAgentSection(existing) {
|
|
28
|
+
if (existing === undefined || existing.length === 0)
|
|
29
|
+
return { text: `${AGENT_SECTION}\n`, change: "created" };
|
|
30
|
+
const newline = existing.includes("\r\n") ? "\r\n" : "\n";
|
|
31
|
+
const section = AGENT_SECTION.replaceAll("\n", newline);
|
|
32
|
+
const begins = existing.split(SECTION_BEGIN).length - 1;
|
|
33
|
+
const ends = existing.split(SECTION_END).length - 1;
|
|
34
|
+
if (begins === 0 && ends === 0) {
|
|
35
|
+
const separator = existing.endsWith(newline) ? newline : `${newline}${newline}`;
|
|
36
|
+
return { text: `${existing}${separator}${section}${newline}`, change: "added" };
|
|
37
|
+
}
|
|
38
|
+
if (begins !== 1 || ends !== 1) {
|
|
39
|
+
throw new AgentFileError(`The file has ${begins} "${SECTION_BEGIN}" and ${ends} "${SECTION_END}" markers; there must be exactly one of each. Fix them by hand and run the command again. Nothing was changed.`);
|
|
40
|
+
}
|
|
41
|
+
const start = existing.indexOf(SECTION_BEGIN);
|
|
42
|
+
const end = existing.indexOf(SECTION_END);
|
|
43
|
+
if (end < start)
|
|
44
|
+
throw new AgentFileError(`The "${SECTION_END}" marker comes before "${SECTION_BEGIN}". Fix them by hand and run the command again. Nothing was changed.`);
|
|
45
|
+
const text = `${existing.slice(0, start)}${section}${existing.slice(end + SECTION_END.length)}`;
|
|
46
|
+
return { text, change: text === existing ? "unchanged" : "updated" };
|
|
47
|
+
}
|
|
48
|
+
/** A small unified diff of the one region that changes, with two lines of context. */
|
|
49
|
+
export function renderDiff(file, before, after) {
|
|
50
|
+
const old = before.split("\n");
|
|
51
|
+
const next = after.split("\n");
|
|
52
|
+
let prefix = 0;
|
|
53
|
+
while (prefix < old.length && prefix < next.length && old[prefix] === next[prefix])
|
|
54
|
+
prefix++;
|
|
55
|
+
let suffix = 0;
|
|
56
|
+
while (suffix < old.length - prefix && suffix < next.length - prefix && old[old.length - 1 - suffix] === next[next.length - 1 - suffix])
|
|
57
|
+
suffix++;
|
|
58
|
+
const contextStart = Math.max(0, prefix - 2);
|
|
59
|
+
const contextEnd = Math.min(suffix, 2);
|
|
60
|
+
const removed = old.slice(prefix, old.length - suffix);
|
|
61
|
+
const added = next.slice(prefix, next.length - suffix);
|
|
62
|
+
const head = old.slice(contextStart, prefix);
|
|
63
|
+
const tail = old.slice(old.length - suffix, old.length - suffix + contextEnd);
|
|
64
|
+
const oldCount = head.length + removed.length + tail.length;
|
|
65
|
+
const newCount = head.length + added.length + tail.length;
|
|
66
|
+
return [
|
|
67
|
+
`--- a/${file}`,
|
|
68
|
+
`+++ b/${file}`,
|
|
69
|
+
`@@ -${contextStart + 1},${oldCount} +${contextStart + 1},${newCount} @@`,
|
|
70
|
+
...head.map((line) => ` ${line}`),
|
|
71
|
+
...removed.map((line) => `-${line}`),
|
|
72
|
+
...added.map((line) => `+${line}`),
|
|
73
|
+
...tail.map((line) => ` ${line}`),
|
|
74
|
+
].join("\n");
|
|
75
|
+
}
|
|
76
|
+
//# sourceMappingURL=agent-instructions.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"agent-instructions.js","sourceRoot":"","sources":["../../src/agent-instructions.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { Finding, ScanResult, Severity, SourceLocation, VerificationCommand } from "./domain.js";
|
|
1
|
+
import type { DataInfo, Finding, ScanResult, Severity, SourceLocation, VerificationCommand } from "./domain.js";
|
|
2
2
|
import type { MigrationPacket } from "./migration-packet.js";
|
|
3
3
|
export interface DeprecationSummary {
|
|
4
4
|
id: string;
|
|
@@ -15,6 +15,7 @@ export interface DeprecationList {
|
|
|
15
15
|
scannedAt: string;
|
|
16
16
|
count: number;
|
|
17
17
|
deprecations: DeprecationSummary[];
|
|
18
|
+
data?: DataInfo;
|
|
18
19
|
}
|
|
19
20
|
export interface MigrationVerification {
|
|
20
21
|
schemaVersion: "evergreen.verification.v1";
|
|
@@ -27,6 +28,14 @@ export interface MigrationVerification {
|
|
|
27
28
|
remainingFindings: Finding[];
|
|
28
29
|
suggestedCommands: VerificationCommand[];
|
|
29
30
|
}
|
|
31
|
+
/** A finding observed in this session, with the repository it came from. */
|
|
32
|
+
export interface ObservedFinding {
|
|
33
|
+
/** Short stable key of the repository root, used in the finding's resource URI. */
|
|
34
|
+
repositoryKey: string;
|
|
35
|
+
repositoryRoot: string;
|
|
36
|
+
finding: Finding;
|
|
37
|
+
}
|
|
38
|
+
export declare const repositoryKey: (root: string) => string;
|
|
30
39
|
export declare class FindingNotObservedError extends Error {
|
|
31
40
|
constructor(findingId: string);
|
|
32
41
|
}
|
|
@@ -36,10 +45,13 @@ export declare class FindingNotObservedError extends Error {
|
|
|
36
45
|
*/
|
|
37
46
|
export declare class EvergreenAgentTools {
|
|
38
47
|
private readonly observed;
|
|
39
|
-
scan(repositoryPath?: string): Promise<ScanResult>;
|
|
48
|
+
scan(repositoryPath?: string, baselinePath?: string): Promise<ScanResult>;
|
|
40
49
|
list(repositoryPath?: string): Promise<DeprecationList>;
|
|
41
50
|
explain(findingId: string, repositoryPath?: string): Promise<Finding>;
|
|
42
51
|
context(findingId: string, repositoryPath?: string): Promise<MigrationPacket>;
|
|
43
52
|
verify(findingId: string, repositoryPath?: string): Promise<MigrationVerification>;
|
|
53
|
+
/** Every finding observed by this session so far, ordered by repository, then finding id. */
|
|
54
|
+
observedFindings(): ObservedFinding[];
|
|
55
|
+
observedFinding(key: string, findingId: string): ObservedFinding | undefined;
|
|
44
56
|
private remember;
|
|
45
57
|
}
|
package/dist/src/agent-tools.js
CHANGED
|
@@ -1,8 +1,10 @@
|
|
|
1
|
+
import { createHash } from "node:crypto";
|
|
1
2
|
import { resolve } from "node:path";
|
|
2
|
-
import { findingFingerprint } from "./baseline.js";
|
|
3
|
+
import { applyBaseline, findingFingerprint, readBaseline } from "./baseline.js";
|
|
3
4
|
import { builtInDetectors } from "./detectors/index.js";
|
|
4
5
|
import { scanRepository } from "./engine.js";
|
|
5
6
|
import { createMigrationPacket } from "./migration-packet.js";
|
|
7
|
+
export const repositoryKey = (root) => createHash("sha256").update(root).digest("hex").slice(0, 8);
|
|
6
8
|
export class FindingNotObservedError extends Error {
|
|
7
9
|
constructor(findingId) {
|
|
8
10
|
super(`Finding was not observed in this MCP session: ${findingId}. Call scan_repository, explain_deprecation, or create_migration_context before editing the repository.`);
|
|
@@ -15,8 +17,12 @@ export class FindingNotObservedError extends Error {
|
|
|
15
17
|
*/
|
|
16
18
|
export class EvergreenAgentTools {
|
|
17
19
|
observed = new Map();
|
|
18
|
-
async scan(repositoryPath = ".") {
|
|
19
|
-
|
|
20
|
+
async scan(repositoryPath = ".", baselinePath) {
|
|
21
|
+
let result = await scanRepository(repositoryPath, builtInDetectors);
|
|
22
|
+
if (baselinePath) {
|
|
23
|
+
// A baseline path is relative to the repository, as in the Action. The reference day is today in UTC.
|
|
24
|
+
result = applyBaseline(result, await readBaseline(resolve(repositoryPath, baselinePath)), { today: new Date().toISOString().slice(0, 10) });
|
|
25
|
+
}
|
|
20
26
|
this.remember(result);
|
|
21
27
|
return result;
|
|
22
28
|
}
|
|
@@ -27,6 +33,7 @@ export class EvergreenAgentTools {
|
|
|
27
33
|
repositoryRoot: result.root,
|
|
28
34
|
scannedAt: result.scannedAt,
|
|
29
35
|
count: result.findings.length,
|
|
36
|
+
...(result.data ? { data: result.data } : {}),
|
|
30
37
|
deprecations: result.findings.map((finding) => ({
|
|
31
38
|
id: finding.id,
|
|
32
39
|
ruleId: finding.ruleId,
|
|
@@ -80,6 +87,15 @@ export class EvergreenAgentTools {
|
|
|
80
87
|
suggestedCommands,
|
|
81
88
|
};
|
|
82
89
|
}
|
|
90
|
+
/** Every finding observed by this session so far, ordered by repository, then finding id. */
|
|
91
|
+
observedFindings() {
|
|
92
|
+
return [...this.observed.entries()]
|
|
93
|
+
.flatMap(([root, findings]) => [...findings.values()].map((finding) => ({ repositoryKey: repositoryKey(root), repositoryRoot: root, finding })))
|
|
94
|
+
.sort((left, right) => left.repositoryRoot.localeCompare(right.repositoryRoot) || left.finding.id.localeCompare(right.finding.id));
|
|
95
|
+
}
|
|
96
|
+
observedFinding(key, findingId) {
|
|
97
|
+
return this.observedFindings().find((entry) => entry.repositoryKey === key && entry.finding.id === findingId);
|
|
98
|
+
}
|
|
83
99
|
remember(result) {
|
|
84
100
|
const findings = this.observed.get(result.root) ?? new Map();
|
|
85
101
|
for (const finding of result.findings) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"agent-tools.js","sourceRoot":"","sources":["../../src/agent-tools.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAEpC,OAAO,EAAE,kBAAkB,EAAE,MAAM,eAAe,CAAC;
|
|
1
|
+
{"version":3,"file":"agent-tools.js","sourceRoot":"","sources":["../../src/agent-tools.ts"],"names":[],"mappings":"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"}
|