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

@stackbilt/adf

v0.7.0

Published

ADF (Attention-Directed Format) — AST-backed context format for AI agents

Readme

@stackbilt/adf

ADF (Attention-Directed Format) parser, formatter, patcher, and bundler for Charter Kit -- a local-first governance toolkit for software repos. ADF is an attention-optimized microformat that replaces monolithic context files (.cursorrules, claude.md) with a modular, AST-backed system designed for LLM context windows.

ADF Architecture

Want the full toolkit? Just install the CLI -- it includes everything:

npm install -g @stackbilt/cli

Only install this package directly if you need ADF parsing/formatting without the CLI.

Install

npm install @stackbilt/adf

What is ADF?

ADF treats LLM context as a compiled language. Key properties:

  • Emoji-decorated semantic keys act as high-contrast attention boundaries for transformer models
  • Strict AST with four content types: text, list, map, and metric
  • Patch protocol for safe delta updates (agents issue typed ops, not full rewrites)
  • Module system with manifest-based routing, progressive disclosure, and token budgets
  • Weight annotations distinguish load-bearing constraints from advisory preferences
  • Sync protocol detects drift between source .adf files and their compressed targets
  • Constraint validation checks metric ceilings and produces structured pass/fail evidence reports
  • Cadence scheduling declares check frequency expectations per metric
  • Auto-measurement via manifest METRICS section mapping metric keys to source files

Example ADF document:

ADF: 0.1
TASK: Implement Redis cache layer
CONTEXT:
  - High-traffic /api/users endpoint
  - Cloudflare Workers environment
OUTPUT: Patch diff + brief explanation
CONSTRAINTS [load-bearing]:
  - No new dependencies
  - P99 latency must improve
STATE:
  CURRENT: Baseline endpoint works but slow under load
  NEXT: Add cache + invalidation logic
  METRICS:
    entry_loc: 142 / 200 [lines]
    total_loc: 312 / 400 [lines]

Usage

Parse an ADF document

import { parseAdf } from '@stackbilt/adf';

const doc = parseAdf(`
ADF: 0.1
TASK: Build feature
CONSTRAINTS:
  - No new deps
  - Stay fast
STATE:
  CURRENT: Starting
  NEXT: Continue
`);

console.log(doc.version);                // '0.1'
console.log(doc.sections[0].key);        // 'TASK'
console.log(doc.sections[0].content);    // { type: 'text', value: 'Build feature' }
console.log(doc.sections[1].content);    // { type: 'list', items: ['No new deps', 'Stay fast'] }
console.log(doc.sections[2].content);    // { type: 'map', entries: [{key:'CURRENT',value:'Starting'}, ...] }

Parse metric content

const doc = parseAdf(`
STATE:
  entry_loc: 142 / 200 [lines]
  total_loc: 312 / 400 [lines]
`);

// doc.sections[0].content =>
// { type: 'metric', entries: [
//   { key: 'entry_loc', value: 142, ceiling: 200, unit: 'lines' },
//   { key: 'total_loc', value: 312, ceiling: 400, unit: 'lines' },
// ]}

Metric entries use lowercase_key: value / ceiling [unit] syntax. Map entries use UPPERCASE_KEY: value. This is the disambiguation.

Parse weight annotations

const doc = parseAdf(`
CONSTRAINTS [load-bearing]:
  - Max 400 LOC
`);

console.log(doc.sections[0].weight);  // 'load-bearing'

Sections can carry [load-bearing] or [advisory] annotations. Weight defaults to undefined when no annotation is present.

Format to canonical ADF

import { parseAdf, formatAdf } from '@stackbilt/adf';

const doc = parseAdf(messyInput);
const canonical = formatAdf(doc);
// Sections sorted by canonical key order, standard emoji auto-injected, 2-space indent
// Metric entries formatted as: key: value / ceiling [unit]
// Weight annotations preserved in headers

Apply patches (safe delta updates)

import { parseAdf, applyPatches, formatAdf } from '@stackbilt/adf';

const doc = parseAdf(input);
const patched = applyPatches(doc, [
  { op: 'ADD_BULLET', section: 'CONSTRAINTS', value: 'Must pass CI' },
  { op: 'REPLACE_BULLET', section: 'STATE', index: 1, value: 'NEXT: Deploy to prod' },
  { op: 'REMOVE_BULLET', section: 'STATE', index: 0 },
  { op: 'ADD_SECTION', key: 'RISKS', content: { type: 'list', items: ['Data loss'] } },
  { op: 'UPDATE_METRIC', section: 'METRICS', key: 'entry_loc', value: 156 },
]);
console.log(formatAdf(patched));

Patch operations throw AdfPatchError with context on invalid ops (missing section, out-of-bounds index, duplicate section). UPDATE_METRIC only changes the value; ceiling and unit are immutable through patches.

Manifest-based module bundling

import { parseAdf, parseManifest, resolveModules, bundleModules } from '@stackbilt/adf';
import * as fs from 'node:fs';

const manifestDoc = parseAdf(fs.readFileSync('.ai/manifest.adf', 'utf-8'));
const manifest = parseManifest(manifestDoc);

// Resolve modules for a given task
const keywords = ['React', 'component', 'fix'];
const modules = resolveModules(manifest, keywords);
// => ['core.adf', 'state.adf', 'frontend.adf']

// Bundle into single merged document (pass keywords for trigger observability)
const result = bundleModules('.ai', modules, (p) => fs.readFileSync(p, 'utf-8'), keywords);
console.log(result.tokenEstimate);        // rough token count
console.log(result.tokenBudget);          // from manifest BUDGET section (or null)
console.log(result.tokenUtilization);     // estimate / budget (or null)
console.log(result.perModuleTokens);      // { 'core.adf': 45, 'state.adf': 22, ... }
console.log(result.resolvedModules);      // which modules were loaded
console.log(result.triggerMatches);       // per-trigger detail with matchedKeywords + loadReason
console.log(result.unmatchedModules);     // on-demand modules not resolved
console.log(result.advisoryOnlyModules);  // loaded modules with no load-bearing sections
console.log(result.moduleBudgetOverruns); // modules exceeding their per-module budget

API Reference

parseAdf(input: string): AdfDocument

Tolerant parser that handles messy LLM output. Strips emoji decorations, normalizes line endings, auto-detects content types (text, list, map, metric). Defaults to version 0.1 if version line is missing. Parses [load-bearing] and [advisory] weight annotations on section headers.

formatAdf(doc: AdfDocument): string

Strict emitter producing canonical ADF. Sorts sections by canonical key order, auto-injects standard emoji decorations when missing, uses 2-space indent for body content. Emits weight annotations and metric entries in canonical form.

applyPatches(doc: AdfDocument, ops: PatchOperation[]): AdfDocument

Immutable patcher. Returns a new document; the original is never mutated. Supports seven operation types:

| Op | Target | Description | |---|---|---| | ADD_BULLET | list/map section | Append an item or entry | | REPLACE_BULLET | list/map section | Replace item at index | | REMOVE_BULLET | list/map section | Remove item at index | | ADD_SECTION | document | Add new section (throws if duplicate) | | REPLACE_SECTION | document | Replace entire section content | | REMOVE_SECTION | document | Remove section by key | | UPDATE_METRIC | metric section | Update value by key (ceiling/unit immutable) |

parseManifest(doc: AdfDocument): Manifest

Extract routing manifest from a parsed ADF document. Reads DEFAULT_LOAD, ON_DEMAND (with trigger parsing and optional [budget: N] suffix), BUDGET (global MAX_TOKENS), SYNC, CADENCE, METRICS (source file mappings), ROLE, and RULES sections.

resolveModules(manifest: Manifest, taskKeywords: string[]): string[]

Resolve which modules to load. Always includes defaultLoad; adds ON_DEMAND modules whose triggers match any keyword (case-insensitive).

bundleModules(basePath: string, modulePaths: string[], readFile: (p: string) => string, taskKeywords?: string[]): BundleResult

Parse, merge, and bundle resolved modules into a single ADF document. Duplicate sections are merged (lists concatenated, texts joined, maps concatenated, metrics concatenated). Returns token estimate, budget utilization, per-module token counts, trigger match report with keyword-level detail, unmatched modules, and advisory-only module warnings. Optional taskKeywords enables richer trigger observability in the report.

validateConstraints(doc: AdfDocument, context?: Record<string, number>): EvidenceResult

Validate all metric entries against their ceilings. Returns a structured evidence report with pass/fail/warn per metric, weight summary, and aggregate counts. Optional context parameter injects external measurements (e.g., actual LOC count) that override the document's own values. Status semantics: value < ceiling = pass, value === ceiling = warn, value > ceiling = fail.

computeWeightSummary(doc: AdfDocument): WeightSummary

Count sections by weight category (load-bearing, advisory, unweighted). Useful independently from constraint validation.

parseMarkdownSections(input: string): MarkdownSection[]

Parse a markdown string into structured sections. Splits on ## (H2) headings; content before the first H2 becomes a preamble section. Within each section, sub-elements are classified as rules (with imperative/advisory/neutral strength detection), code blocks (with language tag), table rows, or prose.

classifyElement(element: MarkdownElement, heading: string): ClassificationResult

Classify a single markdown element into an ADF routing decision. Returns STAY (environment/runtime content that should remain in the vendor file) or MIGRATE (with target section, module, and weight). Uses deterministic heuristics based on NEVER/ALWAYS/MUST patterns, heading context, and element type.

buildMigrationPlan(sections: MarkdownSection[], existingAdf?: AdfDocument): MigrationPlan

Build a complete migration plan from parsed markdown sections. If existingAdf is provided, uses Jaccard similarity deduplication to skip items already present in the ADF document. Returns classified items, STAY/MIGRATE split, target modules, and summary counts.

isDuplicateItem(existing: string, candidate: string): boolean

Check if two text items are duplicates using Jaccard word similarity with a 0.8 (80%) threshold.

AST Types

// --- Document Model ---
interface AdfDocument { version: '0.1'; sections: AdfSection[]; }
interface AdfSection  {
  key: string;
  decoration: string | null;
  content: AdfContent;
  weight?: 'load-bearing' | 'advisory';
}

type AdfContent =
  | { type: 'text'; value: string }
  | { type: 'list'; items: string[] }
  | { type: 'map';  entries: AdfMapEntry[] }
  | { type: 'metric'; entries: AdfMetricEntry[] };

interface AdfMapEntry    { key: string; value: string; }
interface AdfMetricEntry { key: string; value: number; ceiling: number; unit: string; }

// --- Manifest ---
interface Manifest {
  version: '0.1'; role?: string; defaultLoad: string[];
  onDemand: ManifestModule[]; rules: string[]; tokenBudget?: number;
  sync: SyncEntry[]; cadence: CadenceEntry[]; metrics: MetricSource[];
}
interface ManifestModule { path: string; triggers: string[]; loadPolicy: 'DEFAULT' | 'ON_DEMAND'; tokenBudget?: number; }
interface SyncEntry      { source: string; target: string; }
interface CadenceEntry   { check: string; frequency: string; }
interface MetricSource   { key: string; path: string; }

// --- Bundle Result ---
interface BundleResult {
  manifest: Manifest; resolvedModules: string[]; mergedDocument: AdfDocument;
  tokenEstimate: number; tokenBudget: number | null; tokenUtilization: number | null;
  perModuleTokens: Record<string, number>;
  moduleBudgetOverruns: Array<{ module: string; tokens: number; budget: number }>;
  triggerMatches: Array<{
    module: string; trigger: string; matched: boolean;
    matchedKeywords: string[]; loadReason: 'default' | 'trigger';
  }>;
  unmatchedModules: string[];
  advisoryOnlyModules: string[];
}

// --- Constraint Validation ---
type ConstraintStatus = 'pass' | 'fail' | 'warn';
interface ConstraintResult {
  section: string; metric: string; value: number; ceiling: number;
  unit: string; status: ConstraintStatus; message: string; source: 'metric' | 'context';
}
interface WeightSummary  { loadBearing: number; advisory: number; unweighted: number; total: number; }
interface EvidenceResult {
  constraints: ConstraintResult[]; weightSummary: WeightSummary;
  allPassing: boolean; failCount: number; warnCount: number;
}

.adf.lock Format

The sync protocol uses a lockfile (.adf.lock) to detect drift between source .adf files and their last-known state. The format is a flat JSON object mapping source filenames to truncated SHA-256 hashes:

{
  "core.adf": "54d5c9a146d6da3c",
  "state.adf": "a1b2c3d4e5f67890"
}
  • Key: ADF source filename (relative to .ai/ directory)
  • Value: First 16 hex characters of SHA-256(file_content)
  • Generated by: charter adf sync --write
  • Checked by: charter adf sync --check (exits 1 if any hash differs)

The hash algorithm: crypto.createHash('sha256').update(content).digest('hex').slice(0, 16).

Error Types

  • AdfParseError -- invalid document structure (with optional line number)
  • AdfPatchError -- invalid patch operation (with op name, section, index context)
  • AdfBundleError -- module resolution failure (with optional module path)

Self-Governance

Charter uses @stackbilt/adf to govern its own codebase. The .ai/manifest.adf maps metric keys to source files, and validateConstraints() with auto-measured line counts enforces LOC ceilings on every key module. When adf_commands_loc approaches its 900-line ceiling, the evidence report signals that a refactor is needed -- the same mechanism available to any project using ADF.

Requirements

  • Node >= 18
  • Zero runtime dependencies

License

Apache-2.0

Links