npm.io
0.1.12 • Published 3d agoCLI

@kylebegeman/ledger

Licence
MIT
Version
0.1.12
Deps
3
Size
462 kB
Vulns
0
Weekly
0

Ledger notebook icon

Ledger

Repo-native change memory for humans and coding agents.

Agents sign in, do the work, and leave a durable record for the next person or agent who touches the codebase.

CI Version License Node TypeScript Markdown source


Ledger is an agent-first CLI and TypeScript library for keeping implementation history, backlog, durable decisions, release notes, verification records, invariants, docs impact, and merge-conflict guidance inside your repository.

The primary design target is coding agents: compact retrieval, MCP tools, conflict guidance, docs impact checks, and durable handoff records that survive between sessions. Human use is fully supported through the CLI and generated reader, but the structure is intentionally optimized so agents can read, query, and act on the history without guessing from Git alone.

The source of truth is plain Markdown under .ledger/. Generated indexes, reports, release notes, and a static reader make those records useful for automation without making the project dependent on a hosted service.

At A Glance

Question Answer
What is it? A structured change memory layer for software repos.
Primary audience Coding agents that need durable implementation memory.
Human workflow Fully available through the CLI, Markdown records, reports, and static reader.
Source format Markdown with YAML frontmatter.
Default root .ledger/
Runtime Node >=20
Outputs JSON indexes, validation reports, docs reports, release records, static HTML.
Product boundary Ledger stands alone. It can later export into Dossier or other renderers.

Why Ledger Exists

Traditional changelogs answer what shipped. Ledger answers what future maintainers and agents need before changing the code again:

  • what changed
  • why the change exists
  • which files, symbols, docs, decisions, and backlog items are related
  • what invariants must survive future refactors
  • what verification proved the behavior
  • what to preserve if the same area conflicts during a merge
  • which release carried the work

Git history tells you what happened. Ledger tells you what matters.

Five Minute Start

Work From This Repo Today
git clone https://github.com/kylebegeman/ledger.git
cd ledger
npm ci
npm run build
npm link

ledger version

You can also run the CLI without linking:

node dist/cli.js version
Initialize Ledger In A Project
cd /path/to/your-project
ledger init --with-docs

This creates:

.ledger/
  config.yaml
  entries/
  backlog/
  decisions/
  releases/
  templates/
  policies/

docs/
  README.md
  llm/
Record A Change
git status --short
ledger new "Add provider reconnect guard" --from-diff --area runtime

Ledger drafts a Markdown entry with changed files, detected TypeScript or Markdown symbols, inferred areas, docs impact prompts, and a per-file conflict checklist.

Open the generated file, finish the narrative, then run:

ledger validate
ledger ci
Build The Local Reader
ledger index
ledger render
open .ledger/dist/index.html

The static reader is a single offline HTML file. It gives humans and agents a searchable, faceted view of entries, decisions, backlog, releases, invariants, verification checks, relationships, and raw Markdown source.

Published Package Shape

Ledger is intended to publish as the scoped public package @kylebegeman/ledger. The scoped name avoids collisions with unrelated unscoped ledger packages and supports direct one-off CLI usage:

pnpm dlx @kylebegeman/ledger init --with-docs
pnpm dlx @kylebegeman/ledger ci
npm exec --package @kylebegeman/ledger -- ledger init --with-docs
npx --package @kylebegeman/ledger -- ledger ci

For a project-local install:

npm install --save-dev @kylebegeman/ledger
npx ledger init --with-docs
npx ledger ci

The package builds from source during prepare; release checks use npm run release:build.

After the Homebrew tap is published, macOS users can install with:

brew tap kylebegeman/tap
brew install ledger

What Ledger Creates

Path Purpose
.ledger/entries/ Landed change records.
.ledger/backlog/ Accepted or proposed future work.
.ledger/decisions/ Durable project decisions.
.ledger/releases/ Release records generated from entries or maintained by hand.
.ledger/templates/ Project-local templates for new records.
.ledger/policies/ Policy files such as git coverage requirements.
.ledger/indexes/ Generated JSON indexes.
.ledger/reports/ Validation, docs, coverage, and impact reports.
.ledger/dist/ Generated static reader output.
docs/ Optional durable project docs scaffold managed alongside Ledger records.

Command Map

Command What It Does
ledger init --with-docs Creates .ledger/ and optional docs/ scaffolding.
ledger init --migrate Creates a partial-adoption scaffold for replacing an existing changelog or docs workflow.
ledger adopt Initializes Ledger for an established repo without claiming ownership of the whole docs tree.
ledger new "Title" --from-diff Drafts a change entry from git status.
ledger feedback "Title" Captures dogfood or product feedback as a first-class product note.
ledger validate Parses and validates Ledger source documents. Supports --current-only, --update-baseline, and --no-baseline.
ledger index Writes JSON indexes under .ledger/indexes/.
ledger verify-integrity Writes record and catalog hashes for provenance checks.
ledger render Builds the static HTML reader.
ledger coverage --explain Checks that changed source paths have Ledger coverage and explains required, ignored, covered, and missing paths.
ledger docs audit Finds missing and unreferenced durable docs links.
ledger docs classify <path> Classifies docs as durable, routing, scratch, generated, or unknown.
ledger docs impact --check Fails when source changes lack docs impact.
ledger docs reconcile Regenerates the docs routing manifest and START_HERE.md from the docs audit.
ledger docs migrate Writes a docs migration report with cleanup guidance.
ledger explain <path> Shows records related to a file.
ledger explain <path> --agent Emits compact agent context for a file.
ledger packet <path> --write-report Builds a compact agent handoff packet, optionally writing .ledger/reports/packet.md.
ledger mcp Starts a stdio MCP server for agent tools.
ledger conflict <path> --write-report Extracts conflict rules, invariants, and verification, optionally writing .ledger/reports/conflict.md.
ledger query --kind change --area cli --symbol run --text retry Filters records by kind, area, status, release, relationship, symbol, file, doc, id, or metadata text.
ledger unreleased Lists landed or shipped changes not assigned to a release.
ledger release v0.1.1 --include-unreleased --assign --status released --write Assigns selected entries and writes a release record.
ledger migrate changelog <dir> --rewrite-docs Migrates legacy Markdown changelog records into .ledger/entries and writes a receipt.
ledger agents Prints ready-to-paste AGENTS.md instructions for the configured workflow.
ledger ci Runs validation, docs audit, coverage, and docs impact together.

Every command has focused help:

ledger help
ledger help new
ledger docs impact --help
ledger release --help

Adoption And Migration

Established repos can use partial docs adoption:

ledger adopt
ledger migrate changelog docs/changelog --rewrite-docs
ledger validate --current-only

ledger migrate changelog <dir> reads Markdown records, preserves IDs when possible, writes duplicate-ID suggestions in a migration receipt, and maps frontmatter plus body sections into Ledger change entries. --rewrite-docs updates docs references from old changelog paths to the new .ledger/entries paths.

For long-lived histories, mark migrated records with status: "historical" or acknowledge stale paths with staleRefs. Historical records stay queryable but do not flood validation with missing file warnings. Projects can also use ledger validate --update-baseline to baseline known warnings and ledger validate --current-only while actively changing current records.

Entry files can use exact paths, globs such as src/features/**, or explicit prefix: and glob: patterns. ledger new --from-diff omits configured generated/vendor ignores and groups very large diffs into patterns.

Dogfood findings and product observations belong in product notes:

ledger feedback "Improve changelog migration receipt" --area cli --tag dogfood

Project-specific metadata can be made strict with schema.extensions in .ledger/config.yaml, for example phaseId: string or productAreas: string[].

Example Change Entry

---
id: "0020"
kind: "change"
title: "Overhaul README and prepare patch release"
date: "2026-06-29"
updated: "2026-06-29"
status: "landed"
areas: ["docs", "release"]
files:
  - "README.md"
  - "package.json"
symbols:
  - "ledger release"
docs:
  - "docs/PRODUCT.md"
commits: []
release: "v0.1.1"
---

# 0020: Overhaul README And Prepare Patch Release

## Summary

Explain what changed.

## Why

Explain why it changed.

## Changed Files

### README.md

- What changed: Reworked the public project landing page.
- Anchor: `Five Minute Start`
- On conflict: Keep the README accurate for the current install state.

## Behavior And UX Impact

Explain what users experience differently.

## Invariants

- Markdown remains the source of truth.
- Generated outputs remain derived artifacts.

## Verification

- `npm run check`
- `node dist/cli.js ci`

Agent Workflow

Ledger is designed to be useful to coding agents without special integration.

Before editing:

ledger explain path/to/file.ts --agent
ledger packet path/to/file.ts --write-report
ledger conflict path/to/file.ts

After editing:

ledger new "Describe the change" --from-diff
ledger ci

The entry should tell the next agent what changed, what must remain true, and how to verify the behavior.

For MCP-capable agents, run Ledger as a stdio server:

ledger mcp

The server exposes tools for validation, query, file explanation, conflict guidance, agent packets, docs impact checks, and integrity verification.

Release Workflow

Prepare a release record from entries already assigned to a version:

ledger release v0.1.1 --status released --date 2026-06-29 --write

Or preview currently unreleased work without writing:

ledger release v0.1.1 --include-unreleased --status planned

To promote currently unreleased landed work and write the release record in one step:

ledger release v0.1.1 --include-unreleased --assign --status released --write

The generated release document includes public notes, internal entry details, verification guidance, and known issues.

Docs Relationship

Ledger does not replace full project documentation. It replaces the scattered implementation memory that often grows inside docs/ without structure.

Use:

  • .ledger/ for change records, backlog, decisions, releases, invariants, verification, and conflict rules
  • docs/ for durable product, architecture, operations, API, guide, reference, and agent routing docs

Ledger can scaffold and audit docs/, but it does not try to become a docs CMS. ledger docs reconcile keeps agent routing files current, and ledger docs migrate reports scratch, generated, unknown, missing, and unreferenced docs that may need cleanup.

Integrity

Use ledger verify-integrity to generate a deterministic SHA-256 hash for every Ledger source record plus a catalog hash for the current record set. Ledger writes .ledger/indexes/integrity.json for tools and .ledger/reports/integrity.md for review.

Library Usage

The package exports the same core primitives used by the CLI:

import {
  findWorkspace,
  readLedgerDocuments,
  validateDocuments,
  buildIndexes,
  createLedgerMcpServer,
} from "@kylebegeman/ledger";

const workspace = await findWorkspace(process.cwd());
const documents = await readLedgerDocuments(workspace);
const validation = validateDocuments(workspace, documents);
const indexes = buildIndexes(workspace, documents);
const mcpServer = createLedgerMcpServer({ cwd: process.cwd() });

Use the library when you want to build custom dashboards, agent context packets, release tooling, or renderer adapters.

Project Docs

Development

Development happens on next. Stable releases are promoted to master.

npm ci
npm run ci

npm run ci runs typecheck, tests, build, Ledger's own CI checks, and an npm package dry run.

Tagged releases use .github/workflows/release.yml. When NPM_TOKEN is set in repository secrets, pushing vX.Y.Z publishes the verified package to npm with provenance.

Publishing To npm

First-time maintainers need an npm account that has permission to publish the @kylebegeman scope.

  1. Create an account at https://www.npmjs.com/signup if needed.
  2. Verify the account email address in npm.
  3. In this repo, run:
npm login --auth-type=web
npm whoami
npm run release:build
npm publish --access public

npm may open a browser authorization flow for accounts protected by passkeys or security keys. Complete the browser prompt, return to the terminal, and continue the publish. For unattended releases, prefer npm trusted publishing from GitHub Actions once the package has a trusted publisher configured.

Each publish needs a new package version. If npm reports that the version was already published, bump package.json and package-lock.json, rerun the release checks, and publish that new version.

Publishing To Homebrew

Homebrew needs a tap repository and a stable package URL. Publish npm first, then update kylebegeman/homebrew-tap with a Formula/ledger.rb formula that installs the published npm tarball for the same version.

brew tap kylebegeman/tap
brew bump-formula-pr --version <version> kylebegeman/tap/ledger

After the formula is pushed, users install with:

brew tap kylebegeman/tap
brew install ledger

See CONTRIBUTING.md and SECURITY.md.

Product Boundary

Ledger stands on its own. It does not depend on Dossier or any renderer to be useful. Later, a separate adapter can export Ledger's normalized model into Dossier or another artifact system.

License

MIT

Keywords