Getting a file into Herald

Where the files live#

Herald keeps an app's animations in one folder per app, so every template of that app can use them. This section tells you where that folder is and what Herald puts in it, which matters when you copy a file in by hand or clean up.

text
~/Library/Application Support/Herald/assets/<app>/<asset id>.riv

<app> and <asset id> are each reduced to one safe path component:

  • A character outside A-Z a-z 0-9 . _ - becomes _ and a short hash is appended, so a/b and a_b stay different.
  • A leading dot cannot reach a parent folder.
  • For ordinary ids such as webwatcher.email and bell the folder and the file are exactly those names.

Two kinds of file live in an app's folder:

KindMade byReferenced with
A copy of a file the app's manifest declares, named <asset id>.riv.Herald, when the manifest is saved.asset
A file you or an upload put there.You, the Designer's Add... button, or an upload.path with the file name

Copies keep a banner playing after the issuing app moves or deletes its own files. Nothing else is cached on disk. Deleting a manifest removes the copies of the assets it declared and leaves the other files.

The folder holds at most 32 .riv files, whichever way they arrived.

Getting a file into Herald#

There are four ways to store an animation. Pick the one that matches who owns the file: an app ships its animation in its manifest, a person uses the Designer, and an agent or script uploads. All of them end with the file in the app's folder.

WayBest forReferenced with
UploadAgents, scripts and the CLI.path with the file name
Manifest assetAn app that ships its own animation.asset with the asset id
DesignerSomeone designing a template by hand.asset or path, chosen for you
Copy by handQuick experiments.path with the file name

Upload from a script or an agent#

Uploading copies a .riv file into the app's folder and returns the component to use. Send the path of a file on this Mac, or the file's bytes encoded as base64 (the request body is limited to 1 MB, so use a path for anything larger). Herald checks the name, the size and the 32-file limit, and it replaces a file of the same name.

shell
herald assets add --app example.bidbot --file ~/Animations/bell.riv
JSON
{"ok": true, "kind": "rive", "app": "example.bidbot", "id": "bell", "file": "bell.riv",
 "path": "/Users/you/Library/Application Support/Herald/assets/example.bidbot/bell.riv",
 "bytes": 18432, "replaced": false, "component": {"type": "rive", "path": "bell.riv"}}

The component value in the reply is ready to paste into a template cell. Storing and managing files has one command, route and tool for each job:

JobCLIHTTPMCP tool
Store a file.herald assets addPOST /v1/assetsupload_asset
List the stored files, the templates that use each and whether the manifest declares it.herald assets list --app example.bidbotGET /v1/assetslist_assets
Remove a file. The reply names the templates that still reference it.herald assets rm --app example.bidbot --file bell.rivDELETE /v1/assetsdelete_asset

Declare it in the manifest#

An app that ships its own animation lists it in its manifest as an asset. Herald copies each asset into the app's folder as <asset id>.riv when the manifest is saved, and templates refer to it by id. One bad asset is reported and never blocks the manifest: the banner shows the reason where the animation would be.

JSON
{"app": "example.bidbot", "appName": "BidBot", "version": 1,
 "fields": [{"key": "title", "type": "text", "sample": "Bid accepted"},
            {"key": "count", "type": "number", "sample": 2},
            {"key": "url", "type": "url"}],
 "assets": [{"id": "bell", "type": "rive", "path": "~/Animations/bell.riv",
             "stateMachine": "Main", "inputs": ["count", "hover"]}]}
shell
curl -s -X PUT "$HERALD/v1/manifest" \
  -H "Authorization: Bearer $TOKEN" -H "Content-Type: application/json" \
  --data @manifest.json

This is PUT /v1/manifest, also available as the MCP tool put_manifest. An asset has these rules:

PartRule
idLetters, digits, _, . and -, unique in the manifest. A component's asset names it.
typeMust be rive. Any other value is refused with asset type "x" is not supported (only rive).
pathAn absolute path, a ~/ path, a file:// URL, or a name relative to the app's folder. At most 2048 bytes. A remote URL is refused.
stateMachineOptional. The state machine a component plays when it names none.
inputsOptional. The input names the file has. The validator warns when a component binds a name that is not listed.

Saving the manifest again refreshes the copy only when the file's content changed. If the source file later disappears, the earlier valid copy keeps playing.

Add it in the Designer#

In the Designer, the Assets palette lists the app's .riv files, each with a live preview.

  • Add... opens a file panel and copies the chosen file into the app's folder, taking the id from the file name and making it unique.
  • Remove... deletes a file after asking you to confirm.
  • Drag a file onto the canvas, or click it, to place a rive component in the selected slot.
The Assets section. Each file is listed with its size. The preview square is empty in this capture because the Rive runtime does not draw offscreen.
The Assets section of the palette listing one animation, status-ring.riv, with its size, and the Add button below it

The Assets section. Each file is listed with its size. The preview square is empty in this capture because the Rive runtime does not draw offscreen.

A file the manifest declares is placed by asset, with its state machine. A file you added is placed by path, with its file name.

Select a rive cell to open its inspector, which has these controls:

ControlWhat it sets
AssetA manifest asset, or A file... to name a file.
FileThe path, with a menu of the stored files. Shown for A file....
Summary lineWhat the Rive runtime read: artboards, state machines and inputs with their kinds.
Artboard and state machine pickersartboard and stateMachine. The first choice is the file's default.
InputsinputBindings, with the file's inputs suggested and hover and pressed offered.
Looploop: Loop, Once or Animation's own.
RatioaspectRatio. The placeholder shows the artboard's own ratio.
Heightheight.
ActionThe click action: none, one from the list, or one of its own.
Look at the inspector on the right: the Asset, the file summary and the controls in the table above. The animation itself does not draw in this capture, so the cell shows a placeholder.
The Cell tab for a Rive cell showing Asset, the summary line, Artboard, State machine, Inputs, Loop, Ratio, Height and Runs

Look at the inspector on the right: the Asset, the file summary and the controls in the table above. The animation itself does not draw in this capture, so the cell shows a placeholder.

Import... and Export... at the top of the Designer move a template with its animations as a bundle.

Copy it by hand#

Copy the file into ~/Library/Application Support/Herald/assets/<app>/ and reference it with a relative path:

JSON
{"type": "rive", "path": "spinner.riv", "height": 24}

Edit this page on GitHub

Esc
Getting started
Guides