📚 Reference

Generated, not hand-copied.


Everything below is read from the real source at request time — the AI vocabulary contract and GRAIN's token slots. Change the source, this page changes with it.

Actions

Generated from grain/ai/contract.ts's ACTIONS registry — the single source of truth. Payload fields marked * are required; hints are MCP-style behaviour flags.

verbpayloadaccepts (surface kinds)depthhintswhat it does
item.archiveno argsitemlightidempotentArchive an item (stands in for task.complete on the optimistic light path).
say.settext*:stringreflectionlightidempotentWrite a noted line back into a reflection surface.
say.streamno argssay-streamlightidempotentStream a reflection line out token by token.
demo.runno argsscreenheavyidempotentPlay a scripted AI-acting demo on the current screen.
desk.stopno argsscreenlightreadOnly, idempotentAsk the AI to halt the current run (mediated — never a force-kill).
chat.sendtext*:stringchat-loglightSend a chat message; the AI's reply streams back over SSE.
note.appendtext*:string (markdown)notepadlightAppend one markdown entry to the notepad.
note.replacetext*:string (markdown)notepadlightdestructive, idempotentRewrite the whole notepad from one markdown body.
navigatehref*:string (root-relative path, e.g. /notes)screenlightreadOnly, idempotentChange screens — same-origin, root-relative href only (validated at the door).
field.setvalue*:string (plain text; replaces the field's current value)fieldlightdestructive, idempotentPrefill a registered form field with drafted text — the human reviews and submits; the AI never submits.
check.setchecked*:boolean (true ticks the box, false clears it)checklightdestructive, idempotentTick or clear a registered tick box (checkbox or radio) — the human reviews and submits; the AI never submits.
block.removeno argsblocklightdestructive, idempotentDrop one block from the composed page. The page keeps every other block's id, so a later verb still names what it means.
block.spanspan*:string (one of: full, half, third)blocklightidempotentSet how wide one block sits: full, half or third. The whole layout vocabulary, and there is no fourth word.
block.movedirection*:string (one of: up, down)blocklightMove one block one place earlier or later in the page. Clamped at the ends rather than wrapped.
Surface kinds

Every kind at least one verb above accepts.

kind
block
chat-log
check
field
item
notepad
reflection
say-stream
screen
Render ops

The effect kinds the client dispatcher applies (see AI-INTERFACE.md).

opmeans
replaceswap the target's HTML — the confirmed/committed fragment
appendadd HTML to the end of the target (a chat log, a plan list, the console)
removedelete the target element
flasha transient note; also rolls back an optimistic pending state
typestream one text token into the target, or (done) settle it
spotlightshow the AI as actor — dim everything, light (and optionally pulse) the target
logappend one provenance-tagged entry to the interaction timeline (the unified human+AI log)
navigatechange the browser's location (href) — same-origin, root-relative only
choicesthe AI asks the human to pick — a chat bubble with a row of choice buttons (each a chat.send)
fillprefill a registered form field's value — persists for human review (the AI never submits)
tickset a registered tick box's checked state — persists for human review (a radio may only be ticked, never cleared)
spanset one block's width word on a composed page — full, half or third, and there is no fourth
moveshift one block one place on a composed page — up or down, clamped at the ends rather than wrapped
The one door

The HTTP surface every human/AI interaction enters through.

endpointmeans
POST /intentthe one door — every human/AI interaction enters here
GET /streamthe per-session SSE channel render ops are pushed back over
GET /ai/manifestthe machine-readable index of what's operable right now
Token slots

Every custom property GRAIN's default theme sets on :root — override these to re-skin (see RE-SKIN-VIA-TOKENS.md), never a component's own CSS.

tokendefault value
--paper#E2E0D8
--paper-2#E8E6DF
--panel#E8E6DF
--ink#1C1B17
--ink-muted#65635B
--ink-faint#ABA89F
--hairline#1C1B17
--line-softrgba(28, 27, 23, .14)
--scrimrgba(20, 19, 15, .72)
--on-scrim#F4F2EA
--font-smooth"Redaction", "Times New Roman", Georgia, serif
--font-grain"Redaction 50", "Redaction 35", "Times New Roman", Georgia, serif
--font-accent"Redaction 70", "Times New Roman", Georgia, serif
--font-grain-fine"Redaction 35", "Times New Roman", Georgia, serif
--font-monoui-monospace, "SF Mono", "SFMono-Regular", Menlo, Consolas, "Liberation Mono", monospace
--font-weight-regular400
--font-weight-medium500
--font-weight-semibold600
--font-weight-bold700
--text-xs0.8125rem
--text-sm0.875rem
--text-base0.9375rem
--text-lg1.05rem
--text-xl1.3rem
--text-2xl1.6rem
--text-3xl2.25rem
--displayclamp(2rem, 6vw, 2.75rem)
--leading-tight1.02
--leading-normal1.5
--leading-relaxed1.55
--space-10.25rem
--space-20.5rem
--space-30.75rem
--space-41rem
--space-51.25rem
--space-61.5rem
--space-82rem
--radius-sm4px
--radius-md4px
--radius-pill2px
--rule1.5px solid var(--hairline)
--border1px solid var(--hairline)
--content-max768px
--page-padclamp(1.25rem, 5vw, 2.5rem)
--color-bgvar(--paper)
--color-surfacevar(--panel)
--color-fgvar(--ink)
--color-mutedvar(--ink-muted)
--color-linevar(--line-soft)
--color-accentvar(--ink)
--color-accent-hovervar(--ink)
--color-accent-contrastvar(--paper)
--color-accent-softvar(--paper-2)
--color-primaryvar(--color-accent)
--color-primary-hovervar(--color-accent-hover)
--color-primary-contrastvar(--color-accent-contrast)
--color-primary-softvar(--color-accent-soft)
--color-successvar(--ink)
--color-success-hovervar(--ink)
--color-success-contrastvar(--paper)
--color-success-softvar(--paper-2)
--color-dangervar(--ink)
--color-danger-hovervar(--ink)
--color-danger-contrastvar(--paper)
--color-danger-softvar(--paper-2)
--color-ok-bgtransparent
--color-ok-fgvar(--ink)
--color-archived-bgtransparent
--color-archived-fgvar(--ink-muted)
--type-fontvar(--font-smooth)
--font-basevar(--text-base)/var(--leading-relaxed) var(--type-font)
--ai-veil-alpha22%
--ai-veilcolor-mix(in srgb, var(--ink) var(--ai-veil-alpha), transparent)
--ai-veilcolor-mix(in srgb, var(--paper) 70%, transparent)
--ai-veiltransparent
--ai-focus-move0.65s
--ai-focus-easeease-in-out
--editor-header-h2.9rem
--z-presentation8000
--z-ai-veil9000
--z-ai-spot9001
--z-ai-surface9002
--paper-grain-opacity0.09