Scribe

Changelog

Release notes for scribe-cms — each version is a content doc, all rendered here.

v0.0.23

Added

  • Create and edit entries from the studio: forms are generated from each content type's schema, with widgets for every field kind, inline validation errors, and slug auto-derivation. Every save is a plain file write, so a studio session reads like a hand edit in git
  • Image uploads in entry forms: files land exactly where the config says (templated {slug} destinations or the field's directory), with format and size limits enforced. Nothing is ever converted behind your back
  • Multiple asset fields: field.asset({ multiple: true }) attaches an ordered gallery of images to one entry, validated per element and covered by deletion planning and orphan detection
  • Field help text: Zod's .describe("...") on any field shows up as help text in the studio inspector and entry forms
  • Searchable relation pickers: long relation lists get a filter box with a live match count

Changed

  • The studio is now content-first: the home page shows your content types with entry counts, validation badges, and New buttons; translation dashboards live under a single Translations section, and per-entry translation status moved to a tab on the entry inspector. Old URLs redirect
  • New entries are always created as .mdx; existing .md files stay fully readable and editable

Fixed

  • .describe() on asset and relation fields no longer strips their field metadata
  • The studio's YAML editor uses js-yaml's safe schema, so YAML type tags cannot execute code

v0.0.22

Covers releases 0.0.19 to 0.0.22.

Added

  • Inline body tokens: embed localized links to other documents, asset URLs, frontmatter variables, and strings that must never be translated directly in MDX prose. Editing a token updates every locale instantly, with no retranslation
  • Templated asset fields with field.asset(): constrained web paths, existence validation, and resolution to public URLs at read time
  • Bodyless content types: a type can omit the MDX body entirely, and translatability is derived from the schema
  • scribe delete: removes an entry together with its assets, translations, and snapshots, with a reference cascade, --dry-run, and --yes
  • Studio content browser: per-type document lists, global search, inline validation tooltips, a body preview with clickable relation links and rendered assets, and arrow-key navigation

Changed

  • Breaking: relation tokens now require an explicit :href or :slug mode suffix
  • The built-in translation prompt was rewritten around transcreation: the model writes as a native-speaker copywriter, recreating idioms and wordplay instead of rendering them literally, with native typographic conventions

Fixed

  • scribe translate --dry-run now reports real estimated tokens and cost, with the batch discount applied, instead of $0

v0.0.18

Covers releases 0.0.13 to 0.0.18.

Added

  • scribe translate now runs through the Gemini Batch API by default, cutting token costs by 50%. Runs are resumable: quit during polling and run scribe translate again to pick pending jobs back up. Use --batch or --direct to choose the mode explicitly
  • Automatic locale fallback chains: a regional locale with no translation is served its base language before English (fr-CA falls back to fr). On by default; disable with localeFallbacks: false
  • Failed translations are retried once automatically at the end of the run, with the validation errors fed back to the model so it can fix them
  • scribe translate --type accepts comma-separated content type ids

Changed

  • Translation prompts share an identical English prefix across all target locales, so Gemini context caching discounts repeated input tokens. Thinking tokens are now counted in the reported cost

Fixed

  • Transient Gemini errors are retried automatically with backoff
  • Hallucinated nested fields in model output are pruned instead of failing the run
  • The target locale is always appended to prompts, even with a custom translate.prompt
  • scribe translate --force now retranslates fresh content too

v0.0.12

Fixed

  • Translating content whose body contains a Markdown code fence no longer fails JSON parsing; fenced code in translated bodies is preserved

Changed

  • scribe validate now MDX-validates EN source bodies in addition to stored translations, so invalid MDX is caught at the source

v0.0.11

Covers releases 0.0.8 to 0.0.11.

Added

  • Per-content-type _redirects.json files replace frontmatter aliases and redirect_to: same-type, cross-type, and external redirects, with automatic translated-slug expansion
  • localeRouting config and createUrlBuilder() for config-driven locale URL generation
  • listRoutableTypes() and isRoutableType to find content types with public routes
  • MDX validation at translation time and in scribe validate, catching bodies that would fail prerender

Fixed

  • Cross-type redirects with the same EN slug in from and toSlug are no longer rejected as self-redirects

Removed

  • Frontmatter aliases and redirect_to (use _redirects.json) and slugPreserveTerms (use translate.context / translate.rules)

v0.0.7

Fixed

  • Localized slugs that accidentally ended with a locale code (e.g. -fr, -he, -ar) are now stripped automatically during scribe translate, so URLs stay clean
  • scribe validate no longer fails the build when an existing translation slug ends with a locale code; it now reports a warning instead of an error

Improved

  • Localized slugs are now genuinely translated into the target language instead of staying in English: the translator is told the target language by name and to base the slug on the translated title, transliterating non-Latin scripts into Latin

Added

  • Translator prompt now instructs the model not to append locale codes to slugs, since locale routing is handled by the URL prefix

v0.0.6

Changed

  • Replace per-locale revisions table with deduplicated en_snapshots linked via translations.snapshot_id
  • Snapshots store EN source at translate time; many locales share one snapshot per en_hash
  • scribe history and Studio show EN snapshot metadata instead of revision timeline

Removed

  • revisions table (auto-dropped on migrate to schema v4)
Changelog · Scribe