@adikuma/breadcrumb
v0.7.1
Published
cli for creating and checking breadcrumb review handoffs
Readme
@adikuma/breadcrumb
CLI for creating and checking Breadcrumb review handoffs.
Breadcrumb helps reviewers understand agent-written pull requests by asking the coding agent to leave a small structured trail next to the code. The trail lives in the repo at .breadcrumb/tasks/<task-id>/review.yml.
Install
Install it once per machine, so breadcrumb works in any repository:
pnpm add -g @adikuma/breadcrumbOr run it without installing anything:
pnpm dlx @adikuma/breadcrumb@latest initWhich one to use, and why not pnpm breadcrumb
Breadcrumb runs at the repository root, because that is where .breadcrumb/ lives and where the diff is taken from. That root is often not a JavaScript project: a Python service, a Go service, or a monorepo whose JavaScript all sits under apps/.
That rules out one form:
pnpm breadcrumb check --task my-feature
# ERR_PNPM_NO_IMPORTER_MANIFEST_FOUND No package.json was found in ...pnpm refuses to run outside a package, so it fails before it ever looks for the command, even when breadcrumb is installed globally. The prefix gains nothing in a JavaScript repo and breaks the command everywhere else.
| Form | Works where | Use it when |
| --- | --- | --- |
| breadcrumb check | any repository, if installed globally | the normal case, and what the agent instructions tell agents to run |
| pnpm dlx @adikuma/breadcrumb@latest check | any repository, nothing installed | CI, a fresh machine, or a one off |
| pnpm breadcrumb check | only a repo with a root package.json | never; prefer one of the two above |
A project that would rather pin the version than install globally can add it as a dev dependency, but only if the repository root is a JavaScript project:
pnpm add -D @adikuma/breadcrumbCommands
breadcrumb init
breadcrumb init --agent claude,codex
breadcrumb init --workflow
breadcrumb task new <id>
breadcrumb check --task <id>
breadcrumb check --task <id> --json
breadcrumb check --task <id> --strict
breadcrumb check --ci
breadcrumb evidence add <file> --task <id> [--caption <text>]
breadcrumb link [--pr <number>] [--repo owner/name]Typical Flow
breadcrumb init
breadcrumb task new quote-add-ons
breadcrumb check --task quote-add-ons
gh pr create
breadcrumb linkbreadcrumb link prints the review room url for the open pull request, which is what an agent hands back instead of the GitHub link. It reads the repository from the git remote and the pull request number from gh pr view, so it takes no arguments and makes no network call of its own. Pass --pr <number> when gh cannot see the branch, and --repo owner/name when the remote is a fork. It prints a note to stderr when the pull request is a draft, since a draft opens in the room but does not appear in the inbox until it is marked ready for review.
breadcrumb init sets up the handoff and asks which agents should get the handoff skill. A developer sees an interactive picker; an agent or CI passes --agent (defaulting to claude,codex). It creates:
.breadcrumb/
config.yml
tasks/
templates/review.yml
AGENTS.md # the handoff contract
CLAUDE.md # imports AGENTS.md
.claude/skills/breadcrumb-handoff/SKILL.md # claude
.codex/skills/breadcrumb-handoff/SKILL.md # codex
.agents/skills/breadcrumb-handoff/SKILL.md # codex cross agent dirAGENTS.md holds the contract; CLAUDE.md just imports it with @AGENTS.md. The skill carries the craft of writing a good handoff and loads only when an agent is writing one. Existing instruction files are updated in place inside a managed block, never replaced. Pass --agent none to skip the skill.
What Check Does
breadcrumb check validates the handoff and compares it with the real git changed files.
It checks that:
review.ymlhas the expected schema- every described file was actually changed, which is always fatal
- every described file appears in the review sequence, a warning on a plain run and fatal under
--ci - risk values are valid
- paths are relative and safe
- generated folders like
node_modules,dist,.next, andcoverageare ignored
It counts the changed files you left undescribed and prints the total, but never fails for them. Describing only the files a reviewer needs to open is the intended shape.
CI Gate
breadcrumb check --ci runs the same validation as a pull request gate, with no arguments needed:
- finds the handoff the pull request touches (exactly one
review.ymlis expected; zero or several fail) - diffs against the pull request base branch via
GITHUB_BASE_REF - runs strict, so a described file that was never changed or never sequenced fails the check
- prints GitHub error annotations on
review.ymland writes a step summary
Add the workflow with breadcrumb init --workflow, or copy it yourself:
name: breadcrumb
on:
pull_request:
types: [opened, synchronize, reopened, labeled, unlabeled]
jobs:
check:
if: ${{ !contains(github.event.pull_request.labels.*.name, 'breadcrumb-skip') }}
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
with:
fetch-depth: 0
- uses: actions/setup-node@v4
with:
node-version: 24
- run: corepack pnpm dlx @adikuma/breadcrumb@latest check --ci
env:
COREPACK_ENABLE_STRICT: "0"fetch-depth: 0 gives the runner enough history to diff against the base branch. Label a pull request breadcrumb-skip to wave it through without a handoff, for example a dependency bump. To make the gate required, mark the check job as a required status check in branch protection.
Example Handoff
version: 1
id: quote-add-ons
title: Add optional add-ons to the quote flow
user_goal: Let sales reps add optional services to a quote.
summary: Adds add-on selection and includes add-ons in quote totals.
review_sequence:
- src/pricing/tax.ts
files:
- path: src/pricing/tax.ts
why: Start here because this file defines the pricing rule.
risk: mediumWhy This Exists
Normal pull request tools show what changed. Breadcrumb adds how to read it: the intent, risk, and recommended review order.
Releasing
Publishing happens in CI. Bump the version in package.json, merge it, then push a tag that names the package and matches that version:
git tag cli-v<version> && git push origin cli-v<version>The release workflow builds, tests, runs the packaging smoke test, checks the tag against package.json, and publishes with npm trusted publishing. There is no npm token, and a tag that disagrees with the version fails before anything ships.
protocol-v<version> releases the protocol package the same way.
To check a release locally first:
pnpm --filter @adikuma/breadcrumb check # types + unit tests
pnpm --filter @adikuma/breadcrumb smoke # packaged artifact runs end to end