Skip to content

dist-town/cli 0.7.0

Graham
Sep 3, 20262 min read

The command is now just disttown publish.

disttown.jsonc

A repo can commit a manifest describing what it publishes: the project, the artifact globs, the storage choice, and the account expected to do the publishing. It's JSON with comments (the .jsonc extension is the honest label — editors just work), it resolves by walking up from wherever you are (monorepo sub-projects get their own), and a published JSON Schema at dist.town/disttown.schema.json gives you completion and validation as you write it.

disttown init writes a commented scaffold, proposing the project name and detecting dist/.

Inference, shown

With a manifest committed and an annotated tag at HEAD, publish infers everything: the tag proposes the version (a leading v before a digit is stripped), the manifest supplies the files, the storage choice routes the bytes. Nothing inferred is ever silent — interactive publish renders the whole plan first (every value with its source, every file with its digest and destination, every pointer move) and asks. --yes skips the question; non-interactive runs behave exactly as before, so no CI pipeline changes.

Explicit arguments override the manifest everywhere. No manifest means the CLI you already know, unchanged.

Storage profiles

The machine defines buckets, repos pick them by name: disttown storage setup --profile cdn records the definition, a manifest says "storage": "cdn", and per-entry overrides route individual globs elsewhere. "blobs" is reserved for bytes-on-your-own-PDS. Upload commands and credentials never live in the repo, so a cloned manifest carries no secrets. DISTTOWN_STORAGE_BASE_URL / _UPLOAD_CMD serve CI without any files.

The publisher guard

The manifest records which DID it expects to publish. Logged in as someone else, publish stops before a byte moves and says so — the multi-account save. The other resolution is adoption: the manifest is rewritten to expect you, and the original project reference moves into derivedFrom — fork lineage, captured at the only moment the CLI can know it, preserved comment-for-comment. The claim reaches the project record and renders on the fork's page as exactly what it is: a claim.

Also

  • Every command that takes a project now infers it from the manifest when you don't say — release list bare, inside a governed repo, means that repo's project, and the output says so.
  • Manifest globs are containment-checked: never absolute, never escaping the repo, symlinks resolved — a hostile manifest can't publish your dotfiles.
  • storage doctor --profile <name> checks a named profile.
  • Nix builds of the CLI now stamp their version (0.7.0+nix) and update source instead of reporting dev.

Did you enjoy this article?

Recommend it — Standard Reader surfaces well-loved writing to more readers across the network.

Across the AtmosphereDiscussions