npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

artifact-contracts-analyzer

v0.3.4

Published

Artifact traceability analyzer — trace elements, resolve links, and validate coverage across artifact boundaries

Readme

artifact-contracts-analyzer

Analyze project source code through the lens of agent contracts.

artifact-contracts-analyzer bridges the gap between design-time contract definitions (agent-contracts) and runtime execution (agent-contracts-runtime) by analyzing actual project source code against the contract graph.

It answers the questions that neither the DSL compiler nor the runtime can answer alone:

  • What code is actually affected when an artifact changes?
  • What context should an agent receive for a given task?
  • How do source-level dependencies map to contract-level relationships?

Why artifact-contracts-analyzer?

agent-contracts knows the contract graph — which agents own which artifacts, which tools produce or consume them, and what routes a change should follow. But it operates on DSL definitions only. It cannot look inside project source files.

agent-contracts-runtime knows how to execute agent workflows — task scheduling, SDK adaptation, guardrail enforcement. But it treats context as an opaque input provided by the caller.

The missing layer is source-aware analysis: reading actual project files, parsing their structure, and connecting code-level dependencies to contract-level relationships.

agent-contracts            artifact-contracts-analyzer       agent-contracts-runtime
(contract graph)           (source analysis)              (execution)

"api-schema's producer     "src/generated/client.ts       "Run implementer with
 is generate-api-client     imports from openapi.yaml.     this context pack and
 tool, and its source       src/handlers/*.ts imports      validate the result."
 is openapi-spec."          from client.ts."

DSL YAML only              DSL + project source files     contracts + context

Without this layer, agents either receive too much context (entire repository) or too little (manually curated file lists). Neither scales.


What it does

1. AST Graph (low-level)

Parse project source files into a language-aware code structure graph.

Input:
  Project source tree + artifact path_patterns from DSL

Output:
  Code structure graph
  ├── file nodes (kind: "file")
  ├── symbol nodes (kind: "symbol", with symbolId = "filePath#name")
  ├── imports / exports / re_exports edges
  ├── calls edges (caller symbol → callee symbol)
  ├── type_reference edges
  └── contains edges (file → symbol it defines)

The AST Graph captures intra-file structure and inter-file references at the symbol level. Beyond file nodes, it materializes a node per declared symbol (functions, classes, types, etc.), each identified by a stable symbolId of the form filePath#name and carrying its 1-based source line range. contains edges link a file to the symbols it defines, and calls edges connect a calling symbol to the symbol it invokes. It is a raw, deterministic representation of what the code says — no interpretation, no inference.

This is the lowest-level graph in the system. It does not know about artifacts, packages, or contract boundaries. Higher-level graphs consume it.

2. Dependency Graph (high-level)

Build a project-wide dependency graph by integrating the AST Graph with package manifests and contract artifact boundaries.

Input:
  AST Graph (code-level edges)
  + package manifests (package.json)
  + artifact path_patterns (from DSL)

Output:
  Unified Dependency Graph
  ├── symbol nodes + symbol-to-symbol edges (calls, type_reference, contains)
  ├── file-to-file edges (from AST Graph)
  ├── external package dependencies (from manifests)
  └── artifact boundary crossings (file → artifact mapping)

The Dependency Graph preserves the AST Graph's symbol nodes and symbol-to-symbol edges (such as calls and type_reference) alongside the file and package layers, so a query can drill from artifacts down to individual functions. It is the integration layer that connects code structure to contract structure. It answers: "when file A — or the symbol file#fn — changes, which other files, symbols, and artifacts are downstream?"

AST Graph                          Dependency Graph
(code structure, symbol-level)     (project structure, artifact-aware)
         │                                  │
         └──────── consumed by ────────────→│
                                            │← package manifests
                                            │← artifact path_patterns

3. Impact Analysis

Given a changed artifact or set of changed files, compute the downstream impact — what is affected by the change.

Input:
  Navigation Index (from agent-contracts)
  + Dependency Graph
  + change seeds: changed files, changed symbols, an artifact ID,
    or a git diff ref

Output:
  Impact Report
  ├── affected entries (AffectedEntry: path, plus symbolId and line/endLine
  │     when the affected node is a symbol)
  ├── directly affected files (immediate dependents)
  ├── transitively affected files (downstream closure)
  ├── affected artifacts (mapped back to DSL)
  ├── affected validations (from artifact required_validations)
  ├── affected agents and workflows
  └── confidence annotations per edge

Change seeds can be specified at multiple granularities:

  • Files (--files) — whole-file change seeds, as before.
  • Symbols (--symbols) — symbol-level seeds of the form src/server.ts#handleRequest, so impact starts from a single function rather than the whole file.
  • Git diff (--diff <ref>) — derives changed symbols automatically by diffing against a ref (e.g. HEAD~1, main), mapping each changed line range back to the symbol whose source range contains it.

Each result is an AffectedEntry carrying the file path; when the affected node is a symbol it also carries its symbolId and line/endLine range, so consumers know exactly which declarations are in scope.

Impact Analysis traces reverse dependencies from the change point outward:

changed file/artifact
  → reverse references (who imports/calls this?)
  → affected callers (downstream transitive closure)
  → affected artifacts (mapped via path_patterns)
  → affected validations (from artifact required_validations)
  → affected agents/workflows (from Navigation Index routes)

The default direction is downstream impact — what breaks or needs updating when this changes. Upstream analysis (what does this depend on?) is available as a separate query mode but is not the primary use case.

The Navigation Index provides contract-level relationships (tool operations, artifact relations, action routes). The Dependency Graph provides code-level relationships. Impact Analysis overlays both to determine the full scope of a change.

4. Context Pack Generator

Produce a minimal, relevant context pack for an agent task — the right files, the right sections, the right metadata.

Input:
  Impact Report (or task + artifact scope)
  + Dependency Graph
  + project source files

Output:
  Context Pack
  ├── relevant source files (ranked by relevance)
  ├── relevant artifact definitions
  ├── dependency context (what depends on what)
  └── size budget enforcement

Instead of passing an entire repository or relying on manual file lists, the Context Pack Generator uses graph analysis to select the minimal set of files an agent needs to complete a task effectively.

Two extraction granularities are supported (--granularity):

  • symbol (default) — only the line ranges of the affected symbols are extracted.
  • file — each selected file is included in full. extractSymbolSections turns the impact report's affected symbols into one section per symbol (spanning its lineendLine), sorted and de-overlapped, so the pack carries the relevant functions and types rather than whole files. This packs far more relevant context into the same token budget.

5. Provenance and Evidence Model

Every edge in the graph carries provenance metadata: an edge classification and an array of evidence recording why the edge exists.

The graph build produces deterministic edges from static AST analysis, manifests, and path pattern matching. Each edge carries structured evidence:

edge:
  from: src/routes/api.ts
  to: src/services/user-service.ts
  type: deterministic
  source: ast_import
  confidence: 1.0
  evidence:
    - type: static_import
      detail: "import { UserService } from '../services/user-service'"
      line: 3

computeRelevanceScore assigns each edge a relevance score from the kinds of evidence backing it (e.g. static_import outweighs heuristic links), with a bonus when several distinct evidence kinds corroborate the same edge.

artifact-analyzer semantic detects gaps in the deterministic graph and proposes candidate edges via LLM inference. Candidate edges are persisted to the store and automatically merged into the graph on subsequent impact and context-pack runs. Use --edge-types deterministic to exclude them.

6. Call Graph

Walk the calls edges from an entry symbol to build a bounded call tree. The traversal runs in either direction:

  • Forward (default) — follow calls edges caller → callee: "what does this function call, transitively?" Useful for understanding a function's full call chain before changing it.
  • Reverse — follow calls edges callee → caller: "who calls this function, up to the entry points?" Callers surface at the leaves. Useful for verifying test coverage (which tests reach this symbol?) and assessing blast radius.

Cycles (recursion, mutual recursion) are detected per root-to-node path and truncated, so the tree is always finite, and traversal is bounded by a maximum depth.

# Forward: what does handleGet call, up to 3 levels deep?
artifact-analyzer callgraph --entry 'src/api.ts#handleGet' --depth 3

# Reverse: who calls parse() — including which tests reach it?
artifact-analyzer callgraph --entry 'src/utils.ts#parse' --direction reverse

The global --format selects the rendering: an indented tree (text), a Graphviz digraph (dot), or the raw tree structure (json).


Architecture

Inputs and outputs

┌─────────────────────────┐     ┌──────────────────────────┐
│ agent-contracts          │     │ Project Source Tree       │
│                          │     │                          │
│ resolve() ───────────────┼──┐  │ src/, lib/, tests/, ...  │
│ buildNavigationIndex() ──┼──┤  │ package.json             │
│                          │  │  │ config files             │
└─────────────────────────┘  │  └──────────┬───────────────┘
                             │             │
                             ▼             ▼
                    ┌──────────────────────────────┐
                    │ artifact-contracts-analyzer      │
                    │                              │
                    │ buildAstGraph()       (low)  │
                    │     ↓                        │
                    │ buildDependencyGraph() (high) │
                    │     ↓                        │
                    │ analyzeImpact()              │
                    │     ↓                        │
                    │ generateContextPack()        │
                    └──────────────┬───────────────┘
                                   │
                    ┌──────────────┼───────────────┐
                    ▼              ▼               ▼
              Impact Report   Context Pack   Dependency Graph
                    │              │
                    ▼              ▼
            ┌─────────────────────────────┐
            │ agent-contracts-runtime      │
            │                             │
            │ runWorkflow(invocation, {   │
            │   contextPack: pack         │
            │ })                          │
            └─────────────────────────────┘

Internal data flow

Source files ──→ AST Graph (symbol-level, deterministic)
                    │
                    ├── + package manifests
                    ├── + artifact path_patterns
                    ▼
               Dependency Graph (project-level, artifact-aware)
                    │
                    ├── + Navigation Index (contract-level)
                    ├── + changed files
                    ▼
               Impact Report (downstream closure + evidence)
                    │
                    ├── + source file contents
                    ├── + token budget
                    ▼
               Context Pack (optimized agent input)

Package dependencies

artifact-contracts-analyzer
  dependencies:
    agent-contracts         — resolve(), buildNavigationIndex(), DSL types
  peerDependencies:
    better-sqlite3          — optional: persistent index store (in-memory fallback)

artifact-contracts-analyzer depends on agent-contracts for DSL resolution and the Navigation Index API. It does not depend on agent-contracts-runtime — runtime integration lives in a separate package (artifact-contracts-analyzer-plugin), so the analyzer can be used standalone for impact analysis and dependency visualization.

Boundary with agent-contracts

| Concern | agent-contracts | artifact-contracts-analyzer | |---------|----------------|--------------------------| | Input | DSL YAML (+ cli-contract YAML) | DSL + project source files | | Contract Graph | Builds from DSL | Consumes as input | | Navigation Index | Builds from DSL | Consumes as input | | AST analysis | None | Core capability | | File system scanning | artifact-coverage (pattern matching only) | Deep source analysis | | Impact analysis | None | Core capability | | Context generation | Template rendering (Handlebars) | Graph-based context selection |

Boundary with agent-contracts-runtime

| Concern | agent-contracts-runtime | artifact-contracts-analyzer | |---------|------------------------|--------------------------| | Agent execution | Core capability | None | | SDK adaptation | Core capability | None | | Workflow DAG scheduling | Core capability | None | | Context pack consumption | Receives and passes to agents | Produces | | Plugin system | Provides AgentPlugin interface | Bridged by separate artifact-contracts-analyzer-plugin package | | Guardrail enforcement | Core capability | None |

Runtime plugin integration

Runtime integration is provided by a separate package, artifact-contracts-analyzer-plugin, which depends on both the analyzer and agent-contracts-runtime. The analyzer core stays free of runtime knowledge:

import { createAnalyzerPlugin } from 'artifact-contracts-analyzer-plugin';
import { pluginRegistry } from 'agent-contracts-runtime';

const plugin = createAnalyzerPlugin({
  projectRoot: '.',
  index: prebuiltIndex,
});

pluginRegistry.register(plugin);

The plugin implements the AgentPlugin.contextEnhancer interface — no changes to agent-contracts-runtime are required.


Deterministic-first principle

The graph build produces deterministic edges from code structure:

| Priority | Method | Confidence | Example | |----------|--------|------------|---------| | 1 | Static AST analysis | 1.0 | import { foo } from './bar' | | 2 | Manifest resolution | 1.0 | dependencies in package.json | | 3 | Path pattern matching | 1.0 | path_patterns: ["src/generated/**"] |

artifact-analyzer semantic can propose candidate edges via LLM inference for gap detection. Candidate edges are persisted and merged into subsequent pipeline runs. Use --edge-types deterministic to restrict to confirmed relationships only.


Capabilities

CLI

# Build and display the AST dependency graph
artifact-analyzer graph --project-root .

# Analyze impact of changes to a specific artifact
artifact-analyzer impact --artifact api-schema

# Analyze impact of specific file changes
artifact-analyzer impact --files src/api/schema.ts src/api/types.ts

# Analyze impact starting from a single symbol
artifact-analyzer impact --symbols 'src/server.ts#handleRequest'

# Derive changed symbols from a git diff and analyze their impact
artifact-analyzer impact --diff HEAD~1

# Build a forward call graph rooted at a symbol
artifact-analyzer callgraph --entry 'src/api.ts#handleGet' --depth 3

# Build a reverse call graph (who calls this symbol?)
artifact-analyzer callgraph --entry 'src/utils.ts#parse' --direction reverse

# Generate a context pack (symbol-scoped by default)
artifact-analyzer context-pack --files src/api.ts --task implement-feature --budget 50000

# Generate a file-granularity context pack
artifact-analyzer context-pack --files src/api.ts --granularity file

# List dependencies of a file
artifact-analyzer dependencies --file src/api.ts --format json

Library API

import {
  buildAstGraph,
  buildDependencyGraph,
  createDefaultRegistry,
  analyzeImpact,
  buildCallGraph,
  generateContextPack,
} from 'artifact-contracts-analyzer';

// Artifact patterns: artifactId → glob patterns (from DSL path_patterns).
const artifactPatterns = new Map([
  ['api-schema', ['src/generated/**']],
  ['handlers', ['src/handlers/**']],
]);

const registry = createDefaultRegistry();

const { graph: ast, fileContents } = await buildAstGraph({
  projectRoot: '.',
  artifactPatterns,
  registry,
});

const graph = await buildDependencyGraph({
  ast,
  projectRoot: '.',
  artifactPatterns,
  manifests: ['package.json'],
});

// Symbol-level impact: seeds may be files OR symbolIds ("filePath#name").
const impact = await analyzeImpact({
  graph,
  changed: ['src/server.ts#handleRequest'],
  direction: 'downstream',
});

for (const entry of impact.directlyAffected) {
  if (entry.symbolId) {
    console.log(`${entry.symbolId} (lines ${entry.line}-${entry.endLine})`);
  }
}

// Call graph: who calls this symbol, up to the entry points?
const callGraph = buildCallGraph({
  graph,
  entry: 'src/utils.ts#parse',
  direction: 'reverse',
  maxDepth: 3,
});

// Context pack: symbol-scoped by default.
const contextPack = await generateContextPack({
  graph,
  changed: ['src/server.ts#handleRequest'],
  taskId: 'implement-feature',
  budgetTokens: 50_000,
  projectRoot: '.',
  fileContents,
});

Who this is for

artifact-contracts-analyzer is a fit for teams that:

  • use agent-contracts to define multi-agent workflows
  • want agents to receive optimized, relevant context instead of entire repositories
  • need impact analysis to understand what a change affects before delegating to agents
  • operate at scale where manual context curation is not sustainable
  • want to integrate source analysis into existing agent-contracts-runtime workflows

Who this is not for

  • Teams not using agent-contracts — the analyzer requires a contract graph as input
  • Single-file or trivial projects — the overhead of graph analysis exceeds the benefit
  • Teams that need only runtime orchestration — use agent-contracts-runtime directly

Relationship to the ecosystem

┌────────────────────────────────────────────────────────────────┐
│                    agent-contracts ecosystem                    │
│                                                                │
│  ┌──────────────┐  ┌─────────────────┐  ┌──────────────────┐  │
│  │              │  │                 │  │                  │  │
│  │   agent-     │  │    agent-       │  │    agent-        │  │
│  │  contracts   │──│  contracts-     │──│  contracts-      │  │
│  │              │  │   analyzer      │  │   runtime        │  │
│  │  (design)    │  │  (analysis)     │  │  (execution)     │  │
│  │              │  │                 │  │                  │  │
│  └──────────────┘  └─────────────────┘  └──────────────────┘  │
│                                                                │
│  DSL → Contract    Contract Graph →    Contracts + Context →  │
│  Graph             Source Analysis →   SDK Execution →         │
│                    Context Pack        Validated Results       │
└────────────────────────────────────────────────────────────────┘

The three packages form a pipeline:

  1. agent-contracts — define what the system looks like (contracts)
  2. artifact-contracts-analyzer — understand what the code looks like (analysis)
  3. agent-contracts-runtime — execute agent tasks with optimal context (execution)

Each package is independently useful, but the combination enables contract-aware, source-optimized agent execution.


AST cache

The analyzer caches per-file AST parse results keyed by content hash (SHA-256). On subsequent invocations, only files whose content has changed are re-parsed. The cache is stored locally (SQLite with in-memory fallback) and can be inspected or cleared via artifact-analyzer cache status / cache clear.


Evidence model

Every edge in the graph carries structured evidence explaining why the relationship exists:

edge:
  from: src/routes/api.ts
  to: src/services/user-service.ts
  type: deterministic
  source: ast_import
  confidence: 1.0
  evidence:
    - type: static_import
      detail: "import { UserService } from '../services/user-service'"
      line: 3

Evidence types include static_import, manifest_dependency, path_pattern_match, and others. This makes every edge auditable (reviewers can inspect why two files are linked) and debuggable (unexpected impact results can be traced to their evidence).


Tech stack

| Category | Choice | |----------|--------| | Language | TypeScript (ESM, strict mode) | | AST parsing | TypeScript Compiler API (built-in) | | Cross-file resolution | TypeScript Compiler API via ProjectAnalyzer (resolves calls/type_reference targets to cross-file symbolIds) | | Graph | In-memory adjacency graph with serialization | | Schema | Zod | | CLI | commander | | Testing | Vitest | | Build | tsup |


Status

This project is implemented and usable for TypeScript/JavaScript projects. The full pipeline — AST graph, dependency graph, impact analysis, call graph, and context pack generation — is available through both the artifact-analyzer CLI and the library API, including symbol-level analysis (symbol nodes, calls edges, symbol-level impact seeds, git-diff-derived seeds, and symbol-scoped context packs). A runtime plugin bridge (artifact-contracts-analyzer-plugin) is provided as a separate package. As a pre-1.0 release, the API surface may still evolve.


License

MIT