3 minutes read

90-second demo

This repository includes a deliberately outdated project at examples/demo. Its manifest is stored as package.json.fixture; the example helper restores the real name in a temporary copy. It declares an unsupported Node.js range, uses the deprecated request package, and runs an old checkout action.

git clone https://github.com/velella-sh/offing.git
cd offing
npm ci
npm run build
demo="$(node dist/tools/examples.js demo)"
node dist/src/cli.js scan "$demo"

Offing reports four evidence-backed lifecycle findings: Node.js 18 and 20, request, and actions/checkout@v4. Each result includes the exact declaration, severity, replacement, and authoritative sources.

Pick the request finding ID from the scan and inspect it:

node dist/src/cli.js explain '<finding-id>' "$demo"
node dist/src/cli.js context '<finding-id>' "$demo" --json

The context packet identifies package.json and src/client.js, preserves HTTP behavior as a migration constraint, proposes ordered changes, and suggests checks. Offing does not modify files or execute suggested commands.

For an agent-driven version of the same flow, start offing mcp and use scan_repository, explain_deprecation, create_migration_context, and verify_migration in one local session.

examples/gallery holds one minimal repository per detector, each with the exact findings a scan must return in expected.json. They exist to show each detector working in thirty seconds; they are deliberately outdated, so do not copy them into a real project.

Files a dependency scanner reads by name are committed under the neutral names from decision 0027, such as Gemfile.lock.fixture, so an example never appears as the repository's own dependency. The command below copies an example to a temporary directory, restores the real names there, and runs Offing inside it; nothing is written to the repository.

Ecosystem Directory What it declares
Android examples/gallery/android Play Billing 5 in a Groovy and a Kotlin build script
CI images examples/gallery/ci-images Ubuntu 20.04 and Windows 2019 agents in Azure Pipelines
Containers examples/gallery/container Old Node, Python, Debian, Ubuntu, Alpine, Redis, and PostgreSQL base images across Dockerfiles, Compose, and a devcontainer
C++ examples/gallery/cpp cmake_minimum_required below the policy floor
Dart examples/gallery/dart A pubspec.yaml SDK constraint on an unsupported Dart release
Databases examples/gallery/database MySQL 5.7 and PostgreSQL 12 in Compose and Terraform
Deno examples/gallery/deno A Deno 1.x project and a Bun 1.0 pin
.NET examples/gallery/dotnet .NET 3.1, 5.0, 6.0, and 8.0 targets, + global.json, Directory.Build.props, central package versions, and a deprecated Azure storage package
Elixir examples/gallery/elixir Elixir 1.14 and Erlang 25, plus a retired package in mix.exs and mix.lock
GitHub Actions examples/gallery/github-actions actions/checkout on the retired Node 20 runtime
Go examples/gallery/go Go 1.22 and 1.23 in go.mod and go.work
Java examples/gallery/java JDK pins in Maven, Gradle, the version catalog, .sdkmanrc, .tool-versions, and .java-version; Spring Boot 2.x and 3.x plus a relocated Hibernate artifact
Kubernetes examples/gallery/kubernetes Removed extensions/v1beta1, networking.k8s.io/v1beta1, policy/v1beta1, and batch/v1beta1 APIs, a pod security policy, and the retired Helm stable repository
Node.js examples/gallery/nodejs .nvmrc on Node.js 20
npm examples/gallery/npm A dependency on the deprecated request package
PHP examples/gallery/php PHP 7.4 in composer.json, composer.lock, .php-version, and .tool-versions
Python examples/gallery/python .python-version on Python 3.9
Ruby examples/gallery/ruby Ruby 3.2 in .ruby-version, .tool-versions, the Gemfile, and Gemfile.lock
Rust examples/gallery/rust Unmaintained crates (failure, ansi-term, atty, tempdir) and a toolchain pin on Rust 1.98
Scala examples/gallery/scala Scala 2.11 and sbt 0.13
Serverless examples/gallery/serverless Retired Lambda and Cloud Functions runtimes in a SAM template, a Serverless Framework service, and Terraform
Shell examples/gallery/shell PowerShell 7.0 in a module manifest and script, plus actions/checkout on Node 20
Swift examples/gallery/swift An Xcode version in the App Store removal window
Terraform examples/gallery/terraform .terraform-version on an unsupported CLI release

Scan any example the same way as the demo:

npm run build
node dist/tools/examples.js gallery/kubernetes scan

Use npm run --silent example -- <example> <command> for the same thing. With no command the tool prints the temporary directory and leaves it in place:

node dist/tools/examples.js gallery/php

Any other command accepts a whole example directory the same way:

node dist/tools/examples.js gallery countdown --as-of 2026-10-25

The gallery is part of npm run check. To run only its test:

npm run build
node --test dist/tests/examples-gallery.test.js

The test scans every example twice and compares the result to expected.json as a whole, so a rule or detector change that alters an example fails CI until the example and its expected output are reviewed together.

Recordings

The recordings in the README are generated from demos/*.tape by the Demos workflow. This one looks up a runtime without scanning anything:

Terminal recording: offing lookup node 18 reports Node.js 18 as end-of-life with the replacement and source

View Markdown

Use with an agent
View Markdown

Open in