Changelog

Search, change-set diffs, and collection-scoped keys

Productv0.5.0

Entries are searchable, change sets have a field-level diff, and API keys can be confined to specific collections. Checks can come from outside Myna and block publishing, and images are resized on delivery.

Search

Searching an entry covers every text value at any depth: titles, markdown bodies, object and list fields, block fields. Nothing to configure, no fields to nominate.

$ myna entries search "webhook signatures"

The syntax is PostgreSQL's, so bare words are ANDed, "quoted phrases" match in order, and a leading - excludes. It works on management and public reads alike, composes with filters and ordering, and covers drafts, so previewed content is searchable.

Change-set diffs

A change set reports every changed field with its before and after.

$ myna changes diff chs_01...
update posts/pricing — Clarify the annual discount
FIELD            KIND     BEFORE     AFTER
title            changed  Pricing    Pricing and plans
seo.description  added    —          Compare Myna's plans.

It is the same comparison the dashboard renders, moved into @myna-sh/sdk/schema and called by both, and myna_diff_change_set hands it to an agent.

External checks

A project can declare checks Myna does not run itself — a link checker, a staging build, a house-style review:

$ myna checks declare links --description "No broken links in the staged copy" --required
$ myna changes report-check chs_01... links --status failed --message "3 dead links in /pricing"

Whatever runs the check reports the result. A check marked required blocks publishing until it passes, whether or not the blanket "checks must pass" setting is on.

Results carry the fingerprint of the contents they were computed for, so editing the change set afterwards marks the verdict stale. A reporter cannot claim a built-in check's name, and a result for an undeclared check is refused.

Collection-scoped keys

An API key can be confined to a set of collections:

$ myna keys create --name changelog-agent \
    --scopes content:read,content:write,schema:read \
    --collections changelog

That key reads and writes changelog and nothing else. Entries, revisions, references, and schemas refuse elsewhere, and the denial names the collections the key does cover. Listing without a collection filter returns only what it covers. On public reads it sees private collections outside its scope the way an anonymous caller would.

Guidance in the schema

Collections take a guidance string, and projects take one that applies regardless of collection:

export const posts = collection({
  name: "posts",
  guidance: "Second person, present tense. Sentence-case titles under 60 characters.",
  fields: { /* … */ },
});

A field's description says what a field is for; guidance says what good looks like. It is versioned, reviewed, and deployed with the rest of the schema, and myna_get_collection_schema hands it to an agent before it writes.

Faster reads

Filtering, search, ordering, and cursor pagination on published content are one SQL query, so a collection with fifty thousand entries costs what one with fifty costs. Cursors are unchanged.

Two behaviours worth knowing: entries missing the field you ordered by sort last in both directions, and a previewed list composes at most 5000 published entries.

Image transformations

Asset URLs take a width, a format, and a quality:

<img
  src={myna.images.url(post.fields.cover, { width: 1200 })}
  srcSet={myna.images.srcSet(post.fields.cover, [640, 1200, 1920])}
  sizes="(max-width: 768px) 100vw, 1200px"
/>

Format negotiates from the browser's Accept header by default. Widths snap to a fixed ladder and quality is clamped, so an asset has a small fixed number of variants, each rendered once and cached in object storage. Images are never upscaled. Assets record their intrinsic dimensions, so a page can reserve layout space before the image loads.

Also

  • MCP covers 38 tools, up from 23: listing and closing change sets, search, diffs, bulk import, reordering, assets, and check results.
  • Localized fields are filterable and sortable in the locale you ask for. myna schema translations <collection> reports per-locale coverage and a worklist.
  • myna.entries.referencedBy(collection, slug) answers "what links here" for published content.
  • asset.* and schema.* webhook events are emitted.
  • myna entries import works on collections with a required slug field, and detects unchanged rows.

Upgrading

$ npm install @myna-sh/[email protected]
$ myna doctor

Everything here is additive: nothing removed, no client changes required, minimum supported client unchanged. New capabilities are entries.search, change-sets.diff, change-sets.checks.external, keys.collection-scope, guidance, assets.images, localization.filters, localization.coverage, and content.references — see the management API reference.

Affects sdk · cli · mcp · api · dashboard · docs

Give your agent something to work with.

Free to start, no card required. Sign in with GitHub, enable the products you want, and point your agent at them.