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

@phoenixaihub/agent-contracts

v0.1.0

Published

Design by Contract for AI Agent Steps — runtime preconditions, postconditions, and invariants for agent execution

Readme

Agent Contracts

npm version CI License: MIT TypeScript

Design by Contract for AI Agent Steps.

Runtime preconditions, postconditions, and invariants for agent execution. Catch silent corruption the moment it happens — not after the full run.

import { contract, fileExists, testsPass, projectCompiles } from '@phoenixaihub/agent-contracts';

const editContract = contract('edit-function', {
  pre: [fileExists('src/utils.ts'), fileContains('src/utils.ts', 'calculateTotal')],
  post: [testsPass('npm test')],
  invariant: [projectCompiles('npx tsc --noEmit')],
});

const result = await editContract.execute(async () => {
  return await agent.edit('src/utils.ts', instructions);
});
// If ANY check fails → ContractViolationError with structured diagnostics

Why

AI agents execute multi-step workflows. Each step can silently corrupt state: modify the wrong file, introduce syntax errors, break something unrelated. Current tools don't catch this:

| Tool | What It Does | The Gap | |------|-------------|---------| | Guardrails AI | Input/output validation | Validates format, not execution correctness | | Ouroboros | Spec-first agents | Post-hoc evaluation — checks at the end | | NeMo Guardrails | Conversational rails | Dialog safety, not code verification | | LangSmith | Observability | Sees what happened, doesn't prevent bad steps | | Pydantic AI | Type-safe agents | Validates data shapes, not side-effects | | Agent Contracts | Step-level contracts | Verifies correctness DURING execution |

Agent Contracts brings Bertrand Meyer's Design by Contract (1986) to AI agents. Contracts are deterministic, programmatic checks — no LLM in the verification loop.

Install

npm install @phoenixaihub/agent-contracts

Quick Start

1. Define a Contract

import {
  contract,
  fileExists,
  fileContains,
  commandSucceeds,
  consoleReporter,
} from '@phoenixaihub/agent-contracts';

const editContract = contract('edit-function', {
  // Must be true BEFORE the step runs
  pre: [
    fileExists('src/utils.ts'),
    fileContains('src/utils.ts', 'calculateTotal'),
  ],
  // Must be true AFTER the step runs
  post: [
    fileContains('src/utils.ts', 'calculateTotal'),  // function still exists
    commandSucceeds('npm test'),                       // tests still pass
  ],
  // Must be true BEFORE and AFTER
  invariant: [
    commandSucceeds('npx tsc --noEmit'),  // always compiles
  ],
}, {
  reporters: [consoleReporter({ verbose: true })],
  onViolation: 'throw',
});

2. Execute Under Contract

const result = await editContract.execute(async () => {
  // Your agent step here
  return await agent.edit('src/utils.ts', 'Add error handling');
});

console.log(result.success);      // true if all checks passed
console.log(result.violations);   // [] if clean
console.log(result.durationMs);   // total time including checks

3. Handle Violations

import { ContractViolationError } from '@phoenixaihub/agent-contracts';

try {
  await editContract.execute(async () => { /* ... */ });
} catch (err) {
  if (err instanceof ContractViolationError) {
    for (const v of err.violations) {
      console.error(`[${v.phase}] ${v.checkName}: ${v.message}`);
    }
  }
}

Built-in Checks

File Checks

| Check | Description | |-------|-------------| | fileExists(path) | File exists | | fileNotExists(path) | File does not exist | | fileContains(path, pattern) | File contains string or regex | | fileNotContains(path, pattern) | File does NOT contain string or regex | | fileParseable(path, language) | File parses as json or typescript | | fileSizeWithin(path, min, max) | File size within byte range | | fileUnchanged(path) | File unchanged between invariant checks |

Process Checks

| Check | Description | |-------|-------------| | commandSucceeds(cmd) | Command exits 0 | | commandOutputContains(cmd, pattern) | Command output contains string/regex | | testsPass(cmd) | Test suite passes (semantic alias) | | projectCompiles(cmd) | Compilation succeeds (semantic alias) | | noNewLintErrors(cmd) | No new lint violations |

Git Checks

| Check | Description | |-------|-------------| | noUnstagedChanges() | Working tree clean | | onlyFilesChanged(patterns) | Only specific files modified | | noOtherFilesChanged(patterns) | Protected files NOT modified | | commitMessageMatches(pattern) | Commit message matches format |

Custom Checks

import { createCheck, check, allOf, anyOf, not } from '@phoenixaihub/agent-contracts';

// Simple boolean check
const isReady = check('is-ready', () => database.isConnected());

// Async check with structured result
const hasMinRows = createCheck('min-rows', async (ctx) => {
  const count = await db.count('users');
  return {
    passed: count >= 100,
    message: `${count} rows (need ≥100)`,
    durationMs: 0,
  };
});

// Composable
const safeToMigrate = allOf('safe-to-migrate', [
  fileExists('migrations/latest.sql'),
  not(fileContains('migrations/latest.sql', 'DROP TABLE')),
]);

const hasBackup = anyOf('has-backup', [
  fileExists('backups/latest.sql.gz'),
  fileExists('backups/latest.dump'),
]);

YAML DSL

Define contracts in YAML files — no TypeScript needed for contract definitions:

# contracts/edit-function.yaml
name: edit-function
pre:
  - check: file-exists
    params:
      path: src/utils.ts
  - check: file-parseable
    params:
      path: src/utils.ts
      language: typescript
post:
  - check: tests-pass
    params:
      cmd: npm test
invariant:
  - check: project-compiles
    params:
      cmd: npx tsc --noEmit
import { loadContract } from '@phoenixaihub/agent-contracts';

const contract = await loadContract('contracts/edit-function.yaml');
const result = await contract.execute(async () => { /* ... */ });

Reporters

| Reporter | Output | |----------|--------| | consoleReporter() | Formatted stdout/stderr | | jsonReporter({ outputPath }) | Structured JSON file | | githubActionsReporter() | ::error / ::warning annotations | | callbackReporter({ onViolation }) | Custom callbacks |

const c = contract('my-step', spec, {
  reporters: [
    consoleReporter({ verbose: true }),
    jsonReporter({ outputPath: 'contract-results.json' }),
    githubActionsReporter(),
  ],
});

Violation Handling

| Mode | Behavior | |------|----------| | 'throw' | Throws ContractViolationError (default) | | 'warn' | Logs warning, continues | | 'report' | Silent — violations collected in result |

// Collect all violations without stopping
const c = contract('audit', spec, {
  onViolation: 'report',
  continueOnFailure: true,
});
const result = await c.execute(step);
console.log(`${result.violations.length} violations found`);

Standalone Verification

Verify conditions without executing a step:

const c = contract('check-state', {
  pre: [fileExists('config.json'), fileParseable('config.json', 'json')],
  invariant: [commandSucceeds('npx tsc --noEmit')],
});

// Check just preconditions
const preResult = await c.verifyPre();

// Check just invariants
const invResult = await c.verifyInvariants();

Architecture

┌─────────────────────────────────────────────┐
│              Agent Framework                 │
│  (LangChain / CrewAI / AutoGen / OpenClaw)  │
└──────────────────┬──────────────────────────┘
                   │
                   ▼
┌─────────────────────────────────────────────┐
│           Contract Runtime                   │
│  ┌─────────┐ ┌──────────┐ ┌─────────────┐  │
│  │  pre()  │ │  post()  │ │ invariant() │  │
│  └────┬────┘ └────┬─────┘ └──────┬──────┘  │
│       ▼           ▼              ▼          │
│  ┌─────────────────────────────────────┐    │
│  │        Verification Engine          │    │
│  │  1. Snapshot state                  │    │
│  │  2. Run preconditions               │    │
│  │  3. Execute agent step              │    │
│  │  4. Run postconditions              │    │
│  │  5. Verify invariants               │    │
│  │  6. Emit violation reports          │    │
│  └─────────────────────────────────────┘    │
└──────────────────┬──────────────────────────┘
                   │
                   ▼
┌─────────────────────────────────────────────┐
│  Reporters: Console | JSON | GitHub Actions │
└─────────────────────────────────────────────┘

API Reference

contract(name, spec, options?)

Create a contract for an agent step.

  • name string — contract identifier
  • spec ContractSpec{ pre?, post?, invariant? } arrays of checks
  • options ContractOptions:
    • cwd — working directory (default: process.cwd())
    • onViolation'throw' | 'warn' | 'report' (default: 'throw')
    • reporters — array of Reporter instances
    • checkTimeout — per-check timeout in ms (default: 30000)
    • continueOnFailure — check all conditions even after failure (default: false)

ContractResult<T>

{
  success: boolean;
  value?: T;                    // step return value
  stepError?: Error;            // error FROM the step
  violations: Violation[];      // all contract violations
  verification: {
    pre: VerificationResult;
    post: VerificationResult;
    invariantBefore: VerificationResult;
    invariantAfter: VerificationResult;
  };
  durationMs: number;
}

Violation

{
  contractName: string;
  phase: 'pre' | 'post' | 'invariant';
  checkName: string;
  message: string;
  details?: Record<string, unknown>;
  timestamp: string;
}

Contributing

See CONTRIBUTING.md for development setup and guidelines.

License

MIT — see LICENSE.