chant vendor
Synopsis
Section titled “Synopsis”chant vendor [pull [name] | check | migrate]Description
Section titled “Description”chant vendor pulls reusable patterns — composites as source, Ops, init
templates, example skeletons — from a remote or local source into your own repo,
recorded in a vendor.json manifest with a checksum so the provenance is
verifiable. chant vendor with no subcommand runs pull.
Use it for source you copy in and own, then review in diffs and adapt. Lexicons stay npm dependencies (the typed API surface), as does anything you import and never edit.
There is no registry and no auto-update. Each source is pinned, and a pin moves
only when you bump it and review the diff. Vendored files are source in your
repo, so chant lint / chant build cover them like anything else.
The manifest — vendor.json
Section titled “The manifest — vendor.json”One entry per vendored artifact:
{ "vendored": [ { "name": "web-app", "source": { "type": "local", "path": "../shared/web-app" }, "target": "vendor/web-app", "ref": "v1.2.0" }, { "name": "alb-deploy-op", "source": { "type": "archive", "url": "https://example.com/patterns-1.4.0.tar.gz", "subpath": "ops/alb" }, "target": "vendor/alb", "ref": "1.4.0" } ]}| Field | Meaning |
|---|---|
name | Stable identity (used by pull <name>). |
source | { type: "local", path } or { type: "archive", url, subpath? }. |
target | Path in your repo to write the pulled content. |
ref | The pin — a tag/version label, recorded for provenance. |
checksum | sha256 of the pulled content. Written by pull, verified by check. |
updatePolicy | Optional; only "pin" (explicit-bump) is supported. |
v1 sources:
local(a path, e.g. a monorepo sibling) andarchive(an http.tar.gz/.zip, optionally scoped to asubpath). Both use chant’s existing fetch/extract code. Git and npm-pack sources are planned next.
The lineage lock
Section titled “The lineage lock”Each vendored target can instead be a scope of kind vendor in the project’s
lineage lock, .chant/workspace.lock.json.
The lock records the same source, pin and checksum as vendor.json, plus the
hash of every file as it was pulled. With those hashes, pull can tell your
edits from the source’s changes and keep them. chant vendor migrate moves
vendor.json into the lock.
Until you migrate, chant vendor reads vendor.json exactly as before.
chant vendor pull [name]
Section titled “chant vendor pull [name]”Resolve each source (or just name) and write it into target.
chant vendor # pull every entrychant vendor pull web-app # pull oneFor a vendor.json entry, pull replaces target with the source and records
the content checksum back into vendor.json. Local edits to the target are
lost.
For a vendor scope in the lock, pull works file by file and never overwrites
an edit:
| Your file | The source | Result |
|---|---|---|
| unedited | changed or removed | updated or removed |
| edited | unchanged | kept |
| edited | changed or removed | kept, and a manual step |
| deleted | changed | stays deleted, and a manual step |
| not in the lock | adds the same path | kept, and a manual step |
Files you added to the target are left alone. A manual step means the file needs
merging by hand. Fetch the source’s version, merge it into yours, then close the
step with chant workspace lineage resolve <path>. pull exits 0 with open
steps and lists them.
If both the lock and vendor.json have entries, pull updates both. It pulls
the vendor.json entries the old way and warns that they are not migrated yet.
chant vendor migrate
Section titled “chant vendor migrate”Move every vendor.json entry into .chant/workspace.lock.json as a vendor
scope, creating the lock if there is none, then delete vendor.json.
chant vendor migrateEach entry’s checksum becomes the scope’s digest. The per-file hashes come from
the target when it still matches the checksum. When you have edited the target,
they come from the source, which must still match the checksum. If neither
matches, the pinned files cannot be recovered and migrate stops without
writing anything: run chant vendor pull <name> first, which overwrites the
target, or restore it. An entry that was never pulled becomes an unpinned scope.
migrate refuses an entry whose name or target is already a scope in the lock.
To add a pattern later, add it to a new vendor.json and run migrate again. To
bump a pin, edit the scope’s source and ref in the lock and run pull.
chant vendor check
Section titled “chant vendor check”Verify each target’s working copy against its recorded checksum. Editing
vendored files is allowed; check reports that they diverged from the pin.
chant vendor checkDrift is a warning locally and a failure in CI (when CI is set), so a
pipeline catches unrecorded changes while local edits still pass.
For vendor scopes in the lock, edits are expected and reported as
ok, N file(s) edited locally. What fails under CI is an open manual step or a
missing target.
Updating a pin
Section titled “Updating a pin”To bump a pin, change the entry’s ref (and source.url for an archive) in
vendor.json, or the scope’s source and ref in the lock. Then re-run
chant vendor pull and review the in-repo diff. The new content and its checksum
arrive together in one reviewable change.
Coming in a later release
Section titled “Coming in a later release”A project with only vendor.json keeps today’s behaviour in this release,
including pull replacing the target. Moving those projects to the lock by
default, and warning about vendor.json until then, changes the output of an
existing command. Under the level-0 rule of
#2525, that needs a listed
exception and a release that warns first (see
Level-0 Exceptions).
Exit Codes
Section titled “Exit Codes”| Code | Meaning |
|---|---|
| 0 | Pulled or migrated successfully, or check clean (or drift, locally) |
| 1 | A source, manifest or lock error, or check drift under CI |