Concepts

Registries

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>.
  • @asterdoc is reserved. It is kept for the Asterdoc registry, which is not available yet. Using it fails with The Asterdoc registry is not available yet. asterdoc registry add @asterdoc <url> is refused, and a global or project config that sets a URL for @asterdoc is 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 --global

For registries that require authentication, use the extended format:

{
  "registries": {
    "@private": {
      "url": "https://registry.example.com",
      "headers": {
        "Authorization": "Bearer ${REGISTRY_TOKEN}"
      }
    }
  }
}
FieldDescription
urlRegistry base URL
headersCustom headers (supports ${ENV_VAR} expansion)
cache.ttlPer-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-lease

Download layers alongside the definition:

asterdoc add @acme/residential-lease --layers all

A reference is @namespace/name, with an optional edition and an optional version. See Editions and versions for the difference.

ReferenceMeaning
@acme/w-9The current edition, latest version
@acme/w-9/2024-03The latest version of edition 2024-03
@acme/w-9@1.0.0Version 1.0.0 of the current edition, or of an artifact that has no editions
@acme/w-9/2024-03@1.0.0One 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-lease

Direct URL installs

Install from a URL directly, bypassing namespace resolution:

asterdoc add https://example.com/artifacts/my-form.yaml

Private 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-form

Local 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 list

Remove 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 --project

See 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.pdf

Each 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.0 of 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"] }
}
FieldTypeRequiredDescription
namestringYesRegistry name, a lowercase slug (e.g., acme)
descriptionstringNoRegistry description
homepagestringNoRegistry homepage URL
enableTelemetrybooleanNoSet false to turn off install telemetry for this registry
enableDirectorybooleanNoSet false to keep this registry out of the Asterdoc Hub
sourcesarrayYesPaths of the artifact files, relative to this file. Each file is in this folder or below it
tagsobjectNoSearch tags, keyed by artifact name
defaultsobjectNoThe 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.

  • latestVersion is the highest version that is not a pre-release.
  • currentEdition is the only edition when there is one. With more, it is the edition that started last and not after today. An edition starts on its effectiveFrom, or on its date when it has no effectiveFrom.

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

FieldTypeRequiredDescription
$schemastringNoJSON schema URL
namestringYesRegistry name, a lowercase slug (e.g., acme)
descriptionstringNoRegistry description
homepagestringNoRegistry homepage URL
itemsarrayYesOne 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.

FieldTypeRequiredDescription
namestringYesArtifact name: lowercase letters and digits with single hyphens, such as w-9. It is the name in a reference such as @acme/w-9
kindstringYesArtifact type: form, checklist, document, bundle
titlestringNoHuman-readable name
descriptionstringNoArtifact description
currentEditionstringWith editionsThe edition to use when a reference names none. A key of editions
editionsobjectFor an artifact with editionsEditions, keyed by edition key
latestVersionstringWith versionsThe version to use when a reference names none. A key of versions
versionsobjectFor an artifact without editionsVersions, keyed by version
layersarrayNoLayer keys the artifact provides
tagsarrayNoSearchable 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.

FieldTypeRequiredDescription
labelstringYesThe edition text as the issuer prints it, such as Rev. March 2024
datestringNoWhen the issuer released the edition: YYYY, YYYY-MM or YYYY-MM-DD
effectiveFromstringNoThe date the edition takes effect, when the issuer prints one
latestVersionstringYesThe version to use when a reference names none. A key of versions
versionsobjectYesVersions 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.

FieldTypeRequiredDescription
pathstringYesPath 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
sha256stringYesSHA-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

  1. Create the config — asterdoc registry make writes registry.config.json with your registry name and metadata.

  2. Add source files — asterdoc registry catalog add adds one artifact file, which is one release.

  3. Compile — asterdoc registry compile validates every source file, computes checksums, and writes registry.json and 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 dist

Hosting

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 4567

Then configure the local registry:

{
  "registries": {
    "@local": {
      "url": "http://localhost:4567"
    }
  }
}

Example: GitHub Pages

  1. Create a repository with your compiled registry (registry.json and the release folders)
  2. Enable GitHub Pages in repository settings (serve from the root or docs/ folder)
  3. 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

  1. Version your artifacts — use semantic versioning, and publish a new version for every change
  2. Add descriptive tags — help users discover artifacts through search
  3. Include descriptions — add descriptions to the registry, artifacts, and fields
  4. Validate before publishing — run asterdoc validate on your artifacts. Compile validates them again
  5. Use HTTPS — always use HTTPS in production (HTTP only for local development)

On this page