AI Assistant

A per-page chat copilot that proposes structured edits — set, delete, insert, reorder — that you review on a card and apply to the working copy with one click.

Not verified yet

The AI Assistant lives in the right rail of every page editor. You chat with it about the page you have open ("tighten the hero copy", "rewrite the SEO description", "add a CTA after the pricing table"), it streams back a short reply plus a structured proposal of changes, and you approve or reject each operation. Approved changes land in the working copy — same shape as any manual edit — and nothing commits to git until you hit Publish.

It's a copilot, not an autopilot. Every proposal goes through a card you can read, edit, and undo.

Where to find it

The right-rail "AI Assist" tab on the page editor. The tab carries a sparkles icon. Clicking it opens the chat panel; the panel state persists per-page (your conversation on pricing.md is different from your conversation on about.md).

How a conversation flows

You send a message

Type into the textarea and press Cmd/Ctrl + Enter.

The assistant streams a reply

The assistant sees what's relevant about the page you have open: the current frontmatter, the body (large bodies get truncated), and the schema for the collection the page belongs to. It also sees a short site profile when one's been generated by the AI Investigator.

You see text appear live as it's generated. The reply ends with either:

  • A proposal card listing concrete changes the assistant suggests.
  • Just text — for questions the assistant can answer without changing the page ("what's wrong with this SEO?", "explain why the title is too long").

Memory

The assistant remembers roughly the last ten back-and-forth turns of the conversation. Older messages stay visible in the panel (so you can scroll up and read them) but they fall out of the assistant's working memory. For long conversations, restate context if you want it to remember something from earlier.

Proposals — the structured part

A proposal is the assistant's structured ask: "I'd like to set hero.heading to 'Welcome', set hero.subheading to '…', insert a new CTA item at the end of blocks." Each ask is one operation. The proposal card lists them with one-line summaries plus a before/after preview.

Operation kinds

OperationWhat it doesWhat the card shows
frontmatter.setSet or replace a value at a dotted path. Auto-creates intermediate objects."Set hero.heading to 'Welcome'" + value diff
frontmatter.deleteRemove a key or array element at a dotted path. Idempotent."Remove sidebar_cta"
frontmatter.insertItemInsert a new item into an array at an optional index (defaults to append)."Add a hero-compact block at position 2"
frontmatter.removeItemRemove an array item by its stable _id. Safe across reorders."Remove block id=978…"
frontmatter.reorderItemsReorder an array's items by _id list. Items not in the list get appended."Reorder blocks: [A, C, B]"
body.replaceReplace the entire Markdown body with a new string."Rewrite body" + line-level diff

The "Add X" vs "Edit X" wording on the card depends on whether the target path already exists in the page. Missing paths render as "Add"; existing paths as "Edit".

Every operation carries a one-line summary field which is what the card actually displays — the assistant phrases each one in the user's voice rather than the raw op syntax.

How identity-safe operations work

The four frontmatter.*item ops address array items by their stable _id rather than by positional index. This means:

  • If you (or another author) reorder a block array, then later apply an AI proposal that targets one of the reordered items, the proposal lands on the right item — not whatever happens to be at the index the assistant first saw.
  • If an item was deleted between the proposal being generated and applied, the inverse op (e.g. removeItem) surfaces as a "this block is no longer in the working copy — skipping" rather than silently removing the wrong one.

This is the same identity-aware machinery the Version history tab uses for rollback. They share the sidecar _id system that stamps every block / item with a stable UUID.

Applying a proposal

The proposal card has two primary buttons:

  • Approve — applies the proposal's operations to the editor's working copy. Nothing commits to git. You can keep editing manually, undo via the same card, or hit Publish to commit whatever's in the working copy.
  • Reject — stamps the message with a rejectedAt timestamp. The card flips to show a muted "Rejected" badge. No edit happens.

You can also select a subset of operations and apply only those — useful when the assistant proposes five changes and you agree with three.

Undo

After applying, the card flips to show a green "Applied" badge and an Undo button. Clicking it restores the page to how it was before the apply. Undo survives a page reload — close the tab and come back, the Undo button is still there.

The trade-off to know: if you manually edit the form between applying two proposals, then undo the second one, undo restores the page to its state right before that second apply — which doesn't include your manual edits in between. The editor auto-saves your draft as you type so nothing's lost from the working copy, but the in-between manual changes will be reverted when you undo the proposal.

Auto-apply

There's an Auto-apply toggle in the panel header. When enabled, every assistant turn that ends with a proposal is applied to the working copy automatically as soon as the reply finishes — before you see the proposal card. The card still shows up; you can still Undo. Just no "Approve" click needed.

Use it when:

  • You're iterating fast and want the working copy to track the conversation live.
  • The page is short and the changes are obvious.

Don't use it when:

  • You're doing structural changes (block inserts, deletes) that you'd want to eyeball first.
  • Multiple authors are touching the same page (auto-apply is remembered per-page for you, but the changes hit the shared working copy).

The toggle is remembered per page — flip it on once for the page you're editing and it stays on next time you open it. Other pages start with it off.

Starter prompts

When a conversation has no messages, the panel shows a hero block with four clickable starter prompts:

  • "Tighten the hero copy"
  • "Improve this page's SEO meta tags"
  • "Add a call-to-action at the end"
  • "What is wrong with this page?"

Clicking one drops the text into the textarea (it doesn't auto-send). Edit it if you want, then Cmd/Ctrl + Enter to send.

These are hardcoded today. Per-site starter prompts aren't configurable yet.

Draft persistence

Your in-progress (unsent) message survives a page reload. Type something, refresh the tab, the text is still there. The draft is cleared the moment you send — so if you refresh mid-reply, the textarea is empty and the sent message is in the conversation history above.

How the assistant decides what to suggest

Every turn, the assistant sees the page you have open (frontmatter

  • body + the schema for the page's collection) plus an optional site profile — a one-paragraph summary of what your site is about, generated by the AI Investigator. When the site profile exists, every conversation shares an opinion of the site's voice and audience.

It also has a fixed set of behavioural rules baked in: keep replies short, match the schema, propose structured edits, never invent fields. Per-site customisation isn't available yet — every site's assistant follows the same rules.

History tab interaction

When you Publish after applying AI proposals, the commit is a normal publish commit — same shape as any manual edit. The Version history tab picks it up and shows the schema-aware diff like any other commit.

Today the History tab tells apart CMS publishes from direct git pushes by their commit subject (Norcube: … gets a small sparkles icon in the timeline). Distinguishing AI-Assist publishes from manual CMS publishes is a future refinement — for now they show up together.

When it fails

The assistant has a few failure modes worth knowing about.

Not configured. If your deployment doesn't have AI credentials set up, the assistant tells you so up front and asks you to contact your platform admin. The chat itself still works (no crashes), but you won't get proposals.

Conflict on apply. If you approve a proposal and another author published a change to the same page while you were thinking, the apply fails with a conflict message. Refresh the editor, ask the assistant again with the updated page in view, and re-apply.

Stream dropped mid-reply. Network blips happen. The partial reply stays in the conversation (you'll see the cut-off text), but no proposal arrives. Re-ask.

Long body. Very long page bodies get summarised for the assistant — it won't have the entire body in working memory. Point it at a specific section ("rewrite the second paragraph under the pricing block") if you want it to focus on something buried deep.

Limitations to know

  • Per-page only. Conversations are scoped to one page at a time. There's no "ask about the whole site" chat yet.
  • One proposal per turn. Each reply ends with at most one proposal. The assistant can't queue follow-up proposals across turns without you re-asking.
  • No image generation. The assistant edits text + structure; it doesn't generate images or upload media. Use the media picker for that.
  • No page create / delete. The assistant edits the page you have open. Creating new pages or deleting existing ones is always your explicit action in the editor.

What's not there yet

A few refinements that are on the list but not shipped:

  • AI-Assist commits distinguishable from manual ones in the History tab.
  • Custom prompts per site — the assistant's behavioural rules are the same on every site today. Per-site overrides would let each brand define its own voice.
  • Teaching the assistant to propose block insertions / removals / reorderings. Today it can set and delete fields but doesn't suggest structural changes to arrays.

On this page