adr

command module
v0.3.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Jul 16, 2026 License: MIT Imports: 1 Imported by: 0

README

ADR Golang

A Golang Architectural decision records (Adrs) CLI

A simple command line written in Golang to manage Architecture Decision Records (ADRs).

Getting Started

Installation

Download the latest prebuilt binary for your platform (Linux/macOS, amd64/arm64/…):

curl -fsSL https://raw.githubusercontent.com/gwleclerc/adr/main/install.sh | sh

You can pin a version or change the install directory:

ADR_VERSION=v1.0.0 ADR_INSTALL_DIR="$HOME/.local/bin" \
  sh -c "$(curl -fsSL https://raw.githubusercontent.com/gwleclerc/adr/main/install.sh)"

Prebuilt archives for every platform (including Windows .zip) are attached to each GitHub release.

From source
go install github.com/gwleclerc/adr@latest

Check the installed version (and build metadata) with:

adr --version

Initializing

Before creating a new record, you must initialize the configuration with a folder that will contain your ADRs with the following command:

adr init docs/adrs

It will create a .adrrc.yml configuration file with the directory path inside.

Creating a new record

You can create a new record with the following command:

adr new decisive decision of architecture

You can also add flags to set record's metadata:

NAME:
   adr new - Create a new ADR

USAGE:
   adr new [options] <record title...>

OPTIONS:
   --author string, -a string     author of the record
   --status string, -s string     status of the record, allowed: "unknown", "proposed", "accepted", "deprecated", "superseded" or "observed" (default: "accepted")
   --tags string, -t string        tags of the record
   --supersedes string, -r string  record ids superseded by this one
   --template string                body template name (see `adr template list`) (default: "bare")
   --body-file string               read the record body from a file (or - for stdin) instead of the template
   --edit                           open the created record in $EDITOR
   --json                           print the created record as JSON
   --help, -h                      show help

By default new scaffolds a minimal (Nygard-style) body. Pass --template madr for a richer MADR-lite layout with Context and Problem Statement, Considered Options, Decision Outcome and Consequences sections:

adr new use urfave/cli over cobra --template madr

It will create a new numbered ADR in your ADR folder 001_decisive_decision_of_architecture.md with placeholder prose for each section, ready to edit in your preferred editor.

Templates

Templates define the body structure of a record. Inspect them with:

adr template list          # available templates (bare, madr, plus your own)
adr template show madr     # print a template's sections and guidance

Instead of editing the scaffolded file, you can supply a ready-made body — the CLI wraps it with the metadata and validates that it matches the template's sections (missing or empty section → error):

adr new "use urfave/cli over cobra" --template madr --body-file draft.md
cat draft.md | adr new "use urfave/cli over cobra" --template madr --body-file -
Custom templates

Declare a templates directory in .adrrc.yml; every *.tpl file there becomes a template named after the file (a custom name equal to a built-in overrides it):

directory: docs/adrs
templates_dir: .adr/templates   # relative to the .adrrc.yml (or absolute)

A template file is just the body skeleton — the section headings (and optional > guidance). For example .adr/templates/lightweight.tpl:

## Context
> Why is this decision needed?

## Decision
> What did we decide, and why?

Then: adr new "my decision" --template lightweight.

Record statuses

Status Meaning
unknown status is not determined
proposed proposed but not accepted yet by stakeholders
accepted accepted by stakeholders
deprecated no longer applies
superseded replaced by a newer record (set automatically via new -r)
observed documents a pre-existing decision reconstructed after the fact — e.g. while making sense of legacy code you did not write

observed is handy for retrospective ADRs: when re-appropriating an inherited codebase, record how things already are and why (adr new "..." -s observed) rather than pretending the decision is being taken now.

Updating a record

You can change the metadata of an existing record with update. Flags that are not provided are left untouched; passing an empty value (e.g. --tags=) clears the field.

adr update <record ID> -s deprecated -t design,api

Adding metadata to a record

add appends tags or superseders to a record without touching its other metadata:

adr add <record ID> -t security -r <other record ID>

Listing records

You can list all records using the following command:

adr list

By using flags, you can filter records based on their metadata:

NAME:
   adr list - List ADR files

USAGE:
   adr list [options]

OPTIONS:
   --authors string, -a string  filter records by authors
   --status string, -s string   filter records by status
   --tags string, -t string     filter records by tags
   --help, -h                   show help

This will display the records as a table. Pass --json for machine-readable output (handy for scripts and agents):

adr list --json

Inspecting and editing a record

adr show <record ID>          # print the ADR file
adr show <record ID> --json   # print its metadata as JSON
adr edit <record ID>          # open it in $EDITOR (or $VISUAL, or vi)
adr new "..." --edit          # create then open in your editor

--json is available on every command that produces machine-readable output — new, add, update, list, show, and template list / template show — for scripting and agent use (template show --json also returns the section headings).

Maintaining the records

adr toc                        # print a markdown index of all records
adr toc -o docs/adrs/README.md # or write it to a file (keep it fresh in CI/pre-commit)
adr lint                       # report inconsistencies; non-zero exit if any (great in CI)
adr lint --json

lint flags dangling superseder references, duplicate numbers, invalid statuses, superseders on a non-superseded record, and missing titles.

Lifecycle shortcuts (thin wrappers over update / add -r):

adr deprecate <record ID>              # set status to deprecated
adr supersede <old ID> <new ID>        # mark <old> superseded by an existing <new>

Configuration

.adrrc.yml supports the following keys:

directory: docs/adrs           # where records live (required)
templates_dir: .adr/templates  # optional: directory of custom *.tpl templates
default_template: madr         # optional: template used when --template is omitted
default_author: "Team Foo"     # optional: author used when --author is omitted

Shell completion

adr can generate completion scripts for your shell:

adr completion bash        # or: zsh, fish, powershell

Source the output from your shell profile (e.g. source <(adr completion bash)).

Development

Common tasks are wrapped in the Makefile:

make build          # build the binary into ./build
make test           # unit tests with the race detector
make integration    # end-to-end tests (installs and runs venom)
make lint           # golangci-lint (v2)
make vuln           # govulncheck vulnerability scan
make release VERSION=v1.2.3 RELEASE=1   # cross-compile archives into ./dist
make install-claude # symlink the Claude Code skill + /adr command into ~/.claude

CI additionally runs govulncheck on every push, and Dependabot opens weekly PRs to keep Go modules and GitHub Actions up to date (.github/dependabot.yml).

Releases are produced automatically by GitHub Actions: pushing a v* tag builds binaries for Linux, macOS and Windows across amd64/arm64/386/arm and publishes them to a GitHub release (see .github/workflows/release.yml).

Claude Code integration

This repo ships a Claude Code skill (.claude/skills/adr) and an /adr command (.claude/commands/adr.md). Run make install-claude to symlink them into ~/.claude so they're available in every repo (the source stays versioned here).

  • The skill is the single source of truth for the workflow. It triggers when a decision is made in a session (or right after a design/planning skill concludes) and drives the whole process: capturing the decision behind recent changes (from the diff, as accepted), documenting a specific decision, or retro-documenting an inherited repo as several condensed observed ADRs. It never invents rationale — it asks about the why whenever it's ambiguous — and it composes with design skills (e.g. a brainstorming/writing-plans flow hands off here to record the outcome).
  • The /adr command is a thin entry point that simply delegates to the skill, for when you want to trigger it explicitly. All the methodology lives in the skill; the command carries none of its own.

Documentation

The Go Gopher

There is no documentation for this package.

Directories

Path Synopsis

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL