RegistriesLast updated on
Last updated on
Consuming and creating Asterdoc artifact registries
A registry is a hosted collection of Asterdoc artifacts. Registries can be public or private. You find an artifact in a registry, install it into your project, and fill and render it there. The CLI and the AI tools both read registries; the examples on this page use the CLI.
Using registries
Namespaces
Every artifact reference names a registry namespace, as in @acme/residential-lease.
- There is no default registry. The CLI resolves a namespace only through your configuration. An unconfigured namespace fails with a message that names it and tells you to run
asterdoc registry add @<ns> <url>. @asterdocis reserved. It is kept for the Asterdoc registry, which is not available yet. Using it fails withThe Asterdoc registry is not available yet.asterdoc registry add @asterdoc <url>is refused, and a global or project config that sets a URL for@asterdocis an error.- Every other namespace is yours to add. Anyone can host a registry and give it any other namespace.
Adding a registry
Add a registry to your project by editing asterdoc.json:
{
"registries": {
"@acme": "https://registry.acme.com"
}
}Or add one globally so it's available across all projects:
asterdoc registry add @acme https://registry.acme.com --globalFor registries that require authentication, use the extended format:
{
"registries": {
"@private": {
"url": "https://registry.example.com",
"headers": {
"Authorization": "Bearer ${REGISTRY_TOKEN}"
}
}
}
}| Field | Description |
|---|---|
url | Registry base URL |
headers | Custom headers (supports ${ENV_VAR} expansion) |
cache.ttl | Per-registry cache TTL override in seconds |
Searching for artifacts
Use asterdoc search to query a registry. Without --registry it searches your one configured registry; with none or several configured, pass --registry:
asterdoc search lease
asterdoc search --kind form --tags legal
asterdoc search --registry @acme "tax"The query matches against artifact names, titles, and descriptions. Filter by --kind or --tags to narrow results.
Installing artifacts
Use asterdoc add to install an artifact. The CLI resolves the namespace to a registry, downloads the definition, writes it to your artifacts directory, and updates the lock file:
asterdoc add @acme/residential-leaseDownload layers alongside the definition:
asterdoc add @acme/residential-lease --layers allA reference is @namespace/name, with an optional edition and an optional version. See Editions and versions for the difference.
| Reference | Meaning |
|---|---|
@acme/w-9 | The current edition, latest version |
@acme/w-9/2024-03 | The latest version of edition 2024-03 |
@acme/w-9@1.0.0 | Version 1.0.0 of the current edition, or of an artifact that has no editions |
@acme/w-9/2024-03@1.0.0 | One edition and one version |
current names the current edition and latest names the latest version, so @acme/w-9/current@latest is the same as @acme/w-9. A reference to an edition or version that the registry does not list fails, and the error says which ones it does list.
The CLI checks the downloaded file against the checksum in the registry manifest and refuses a file that does not match. The lock file records the installed version and, when the artifact has editions, the edition.
Viewing artifact details
View metadata for an installed artifact:
asterdoc registry view @acme/residential-leaseDirect URL installs
Install from a URL directly, bypassing namespace resolution:
asterdoc add https://example.com/artifacts/my-form.yamlPrivate registries
For private registries, configure authentication headers with environment variable tokens:
{
"registries": {
"@private": {
"url": "https://registry.example.com",
"headers": {
"Authorization": "Bearer ${REGISTRY_TOKEN}"
}
}
}
}export REGISTRY_TOKEN="your-token-here"
asterdoc add @private/internal-formLocal development registries may use HTTP:
{
"registries": {
"@local": {
"url": "http://localhost:4567"
}
}
}Managing registries
List all configured registries (project and global). The built-in @asterdoc is not listed, because it is never configured:
asterdoc registry listRemove a registry. Without a namespace, the command lets you pick from a list. --global or --project limits the list to that config:
asterdoc registry remove @acme --global
asterdoc registry remove --projectSee the registry command reference for all subcommands.
Creating registries
Registry structure
You write two things: the artifact files, and registry.config.json, which lists them. asterdoc registry compile builds the registry from them: one manifest file, registry.json, and a folder for each release.
my-registry/
├── registry.config.json # You write this
├── forms/ # Your artifact files, one for each release
│ ├── w-9-2024-03-1.0.0.json
│ ├── w-9-2024-03-1.1.0.json
│ ├── w-9.pdf
│ ├── pet-addendum.json
│ └── pet-addendum.pdf
└── dist/ # Compile writes this. You host it.
├── registry.json # The manifest
├── w-9/
│ └── 2024-03/ # An edition
│ ├── 1.0.0/ # A version
│ │ ├── w-9.json
│ │ └── w-9.pdf
│ └── 1.1.0/
│ ├── w-9.json
│ └── w-9.pdf
└── pet-addendum/
└── 1.1.0/
├── pet-addendum.json
└── pet-addendum.pdfEach artifact file is one release: one version of one edition, or one version of an artifact that has no editions. Files with the same name become the editions and versions of one artifact. Name and place your source files as you like.
Editions and versions
An artifact can change in two ways, and the manifest keeps them apart.
- An edition is the issuer's revision of a form. The IRS issued the W-9 as Rev. October 2018 and later as Rev. March 2024. Those are two editions.
- A version is the publisher's own revision of the artifact for one edition. If you fix a field label in your encoding of the March 2024 W-9, you publish version
1.1.0of that edition. The form the IRS printed did not change.
A form that you wrote yourself, such as a pet addendum, has no issuer and no editions. It has versions only.
The manifest names the default for each: currentEdition on an artifact that has editions, and latestVersion on each edition or on an artifact that has none. Both are your statements as the publisher. A reader uses them as written and does not compare dates or version numbers. This lets you list a future edition before it takes effect and keep the edition in force as the current one until that day. Compile fills in both from your files, and you can state either one yourself. See Default edition and version.
An artifact has an edition in every release or in none. When an artifact that has only versions gets its first edition, publish it again in the edition shape: give every source file of that artifact an edition, and compile. currentEdition and editions then replace latestVersion and versions on the item.
Registry config
registry.config.json is the publisher's source file. asterdoc registry make creates it, and asterdoc registry catalog adds and removes source files.
{
"name": "acme",
"description": "Official forms and documents for Acme Corp",
"homepage": "https://acme.com/forms",
"sources": [
"forms/w-9-2024-03-1.0.0.json",
"forms/w-9-2024-03-1.1.0.json",
"forms/pet-addendum.json"
],
"tags": { "w-9": ["irs", "tax"] }
}| Field | Type | Required | Description |
|---|---|---|---|
name | string | Yes | Registry name, a lowercase slug (e.g., acme) |
description | string | No | Registry description |
homepage | string | No | Registry homepage URL |
enableTelemetry | boolean | No | Set false to turn off install telemetry for this registry |
enableDirectory | boolean | No | Set false to keep this registry out of the Asterdoc Hub |
sources | array | Yes | Paths of the artifact files, relative to this file. Each file is in this folder or below it |
tags | object | No | Search tags, keyed by artifact name |
defaults | object | No | The default edition and version of an artifact, keyed by artifact name. See below |
Default edition and version
Compile chooses each default, and you state one in defaults when the choice is not what you mean.
latestVersionis the highest version that is not a pre-release.currentEditionis the only edition when there is one. With more, it is the edition that started last and not after today. An edition starts on itseffectiveFrom, or on itsdatewhen it has noeffectiveFrom.
When the files cannot decide, compile fails and names the defaults entry to set. This happens when every version is a pre-release, an edition has no date, every edition starts after today, or two dates do not say which is later.
{
"defaults": {
"w-9": {
"currentEdition": "2018-10",
"editions": { "2024-03": { "latestVersion": "1.0.0" } }
},
"pet-addendum": { "latestVersion": "2.0.0-beta.1" }
}
}Manifest
registry.json is the one file that lists every artifact in the registry, with every edition and version of each. Compile writes it. Do not edit it by hand:
{
"$schema": "https://schema.asterdoc.com/registry.json",
"name": "acme",
"description": "Official forms and documents for Acme Corp",
"homepage": "https://acme.com/forms",
"items": [
{
"name": "w-9",
"kind": "form",
"title": "Request for Taxpayer Identification Number and Certification",
"tags": ["irs", "tax"],
"currentEdition": "2024-03",
"editions": {
"2024-03": {
"label": "Rev. March 2024",
"date": "2024-03",
"latestVersion": "1.1.0",
"versions": {
"1.0.0": {
"path": "w-9/2024-03/1.0.0/w-9.json",
"sha256": "5f2b7c1e9a4d38e06b1f0c7d2a9e4b6c8d0f1a3b5c7e9d2f4a6b8c0e1d3f5a79"
},
"1.1.0": {
"path": "w-9/2024-03/1.1.0/w-9.json",
"sha256": "0c9e8d7b6a5f4e3d2c1b0a9f8e7d6c5b4a3f2e1d0c9b8a7f6e5d4c3b2a1f0e9d"
}
}
}
}
},
{
"name": "pet-addendum",
"kind": "form",
"title": "Pet Addendum to Lease Agreement",
"latestVersion": "1.1.0",
"versions": {
"1.1.0": {
"path": "pet-addendum/1.1.0/pet-addendum.json",
"sha256": "a1b2c3d4e5f60718293a4b5c6d7e8f90a1b2c3d4e5f60718293a4b5c6d7e8f90"
}
}
}
]
}Manifest fields
| Field | Type | Required | Description |
|---|---|---|---|
$schema | string | No | JSON schema URL |
name | string | Yes | Registry name, a lowercase slug (e.g., acme) |
description | string | No | Registry description |
homepage | string | No | Registry homepage URL |
items | array | Yes | One entry for each artifact name. No two entries have the same name |
Artifact entry fields
An entry has currentEdition and editions, or latestVersion and versions. It never has both pairs.
| Field | Type | Required | Description |
|---|---|---|---|
name | string | Yes | Artifact name: lowercase letters and digits with single hyphens, such as w-9. It is the name in a reference such as @acme/w-9 |
kind | string | Yes | Artifact type: form, checklist, document, bundle |
title | string | No | Human-readable name |
description | string | No | Artifact description |
currentEdition | string | With editions | The edition to use when a reference names none. A key of editions |
editions | object | For an artifact with editions | Editions, keyed by edition key |
latestVersion | string | With versions | The version to use when a reference names none. A key of versions |
versions | object | For an artifact without editions | Versions, keyed by version |
layers | array | No | Layer keys the artifact provides |
tags | array | No | Searchable tags, from tags in the config |
Edition fields
The key of an edition is lowercase letters and digits with single hyphens, such as 2024-03. It cannot be current, latest, editions, tags or diff.
| Field | Type | Required | Description |
|---|---|---|---|
label | string | Yes | The edition text as the issuer prints it, such as Rev. March 2024 |
date | string | No | When the issuer released the edition: YYYY, YYYY-MM or YYYY-MM-DD |
effectiveFrom | string | No | The date the edition takes effect, when the issuer prints one |
latestVersion | string | Yes | The version to use when a reference names none. A key of versions |
versions | object | Yes | Versions of this edition, keyed by version |
Version fields
The key of a version is a semantic version with no build metadata, such as 1.2.0 or 1.3.0-beta.1.
| Field | Type | Required | Description |
|---|---|---|---|
path | string | Yes | Path to the artifact file, relative to the folder that holds registry.json. Forward slashes, no leading slash, no . or .. segment, and a .json, .yaml or .yml file. No two versions have the same path |
sha256 | string | Yes | SHA-256 of the bytes of the file, as 64 lowercase hex digits. A reader refuses a file that does not match |
Publishing rules
- A published version does not change. To fix an artifact, add a source file with a new version and compile. The checksum makes a changed file fail for everyone who reads it.
- To withdraw a version, remove its source file from the config and compile. The manifest then no longer lists it.
Workflow
-
Create the config —
asterdoc registry makewritesregistry.config.jsonwith your registry name and metadata. -
Add source files —
asterdoc registry catalog addadds one artifact file, which is one release. -
Compile —
asterdoc registry compilevalidates every source file, computes checksums, and writesregistry.jsonand the release folders. One error stops the build, and nothing is written.
asterdoc registry make --name acme --description "Official forms and documents for Acme Corp"
asterdoc registry catalog add forms/w-9-2024-03-1.0.0.json
asterdoc registry compile --output distHosting
A registry is just static files served over HTTPS. Host the folder that compile writes. Any hosting provider or web server works:
- GitHub Pages — free for public repositories
- Netlify / Vercel — deploy from a Git repository
- AWS S3 + CloudFront — scalable, cost-effective
- nginx / Apache — self-hosted
For local development, serve the directory with a static file server:
npx serve my-registry/dist -l 4567Then configure the local registry:
{
"registries": {
"@local": {
"url": "http://localhost:4567"
}
}
}Example: GitHub Pages
- Create a repository with your compiled registry (
registry.jsonand the release folders) - Enable GitHub Pages in repository settings (serve from the root or
docs/folder) - Configure the registry in your project:
{
"registries": {
"@myorg": "https://myorg.github.io/asterdoc-registry"
}
}The CLI fetches https://myorg.github.io/asterdoc-registry/registry.json to discover available artifacts.
Best practices
- Version your artifacts — use semantic versioning, and publish a new version for every change
- Add descriptive tags — help users discover artifacts through search
- Include descriptions — add descriptions to the registry, artifacts, and fields
- Validate before publishing — run
asterdoc validateon your artifacts. Compile validates them again - Use HTTPS — always use HTTPS in production (HTTP only for local development)