Installations (End-User Flows)
Quick Answer
Use this guide to model, create, enable, and operate end-user flow installations with profile-scoped inputs and uploads.
An "end-user flow" is a flow intended to be used by others in the workspace.
The end-user tag gates public discover visibility and related install surfaces.
An "installation" is a per-user instance of an end-user flow, backed by an internal
runtime target owned by the subscribing user.
Public Discover Visibility
If an end-user flow should appear in discover/install surfaces, set public discover visibility explicitly.
Authoring options:
{:tags ["end-user" ...]
:discover {:public true}
...}
or after push:
breyta flows discover update <slug> --public=true
Requirements:
- the flow must be tagged
end-user - the flow must have an active released version
Checklist to make a flow show up in Discover:
- Tag the flow with
end-user. - Choose one visibility path:
- Source-first: add
:discover {:public true}to the flow definition before push. - Explicit after push: wait until after push, then run
breyta flows discover update <slug> --public=true.
- Source-first: add
- Push the flow.
- If you chose the explicit path, run
breyta flows discover update <slug> --public=trueafter push. - Release/promote it so there is an installable live version.
- Verify it in the web Discover UI. If you have another workspace, you can also confirm with
breyta flows discover listorbreyta flows discover search <query>.
Use breyta flows show <slug> --pretty to confirm stored metadata includes discover.public.
Use breyta flows discover list or breyta flows discover search <query> to browse the same public installable catalog the web app shows.
This is different from breyta flows search <query>, which only searches approved example flows to inspect and copy from.
Install Surface Copy
Installable flows can expose separate install-facing markdown copy from their normal flow description.
Use:
breyta flows update <slug> --publish-description-file ./publish-description.md
or:
breyta flows update <slug> --publish-description "## Install this flow"
Behavior:
| Surface | Copy source |
|---|---|
| Discover/install dialog | publishDescription when set |
| Discover/install dialog fallback | normal flow description when publishDescription is empty |
| Discover card/list preview | normal flow description |
This lets you keep a short catalog summary while showing richer installation guidance in the dialog itself.
Core Concepts
| Term | Meaning |
|---|---|
| End-user flow | Flow intended for subscribers. |
| Installation | Per-user runtime target instance for an end-user flow. |
| Activation inputs | Setup values the installer enters once and reuses on later runs until they change them. |
| Promote/release behavior | flows promote/flows release advance live and track-latest installations, but do not clear previously configured setup values. |
Creator: declare activation inputs (setup form)
Installation setup inputs are declared via :requires with a {:kind :form ...}
requirement. By default, form requirements use :collect :setup, which
means the installer fills them out once during setup and the values are reused
on later runs until the installation is reconfigured.
Use :collect :run when a form input must be provided on each manual run
instead of being saved on the installation. Run-collected form requirements do
not block /launch; they render directly in the launch/run form.
Use :provided-by :author on a requirement when it is satisfied by the flow
author/workspace owner instead of the installation user. Author-provided
requirements do not block end-user setup or /launch.
Example:
{:requires [{:kind :form
:label "Setup"
:fields [{:key :region
:label "Region"
:field-type :select
:required true
:options ["EU" "US"]}]}]}
{:requires [{:kind :form
:collect :run
:label "Run input"
:fields [{:key :question
:label "Question"
:field-type :text
:required true}]}]}
{:requires [{:slot :ai
:type :llm-provider
:label "AI Provider"
:auth {:type :api-key}
:provided-by :author}]}
Supported form field types:
:field-type | What the installer sees | Typical use |
|---|---|---|
:text | Single-line text input | IDs, names, short prompts |
:textarea | Multi-line text box | Longer instructions or prompts |
:select | Dropdown | Region, mode, model choice |
:boolean | Checkbox | Confirm/enable flags |
:number | Numeric input | Limits, counts, thresholds |
:date | Date picker | Scheduled/reporting dates |
:time | Time picker | Clock time inputs |
:datetime | Date-time picker | Combined schedule inputs |
:resource | Search/select workspace resources | Files or saved results chosen for a run |
Resource field notes:
- Use
:field-type :resourcewith:collect :run. - The picker is shown only when a resource field is declared.
- Use
:multiple truewhen the flow expects a collection of resources. - Resource fields default to
:file, which covers uploads and persisted blobs. - Use
:resource-typesand:acceptonly when you need to narrow what the user can select. :acceptsupports exact MIME types like"application/pdf"and wildcard prefixes like"text/*".- When both
:resource-typesand:acceptare present, the selected resource must satisfy both filters.
Example:
{:requires [{:kind :form
:collect :run
:label "Run input"
:fields [{:key :resources
:label "Resources"
:field-type :resource
:required true
:multiple true
:accept ["application/pdf" "text/plain"]}]}]}
Text-focused example:
{:requires [{:kind :form
:collect :run
:label "Run input"
:fields [{:key :resources
:label "Text resources"
:field-type :resource
:required true
:multiple true
:accept ["text/*"
"application/json"
"application/xml"
"application/edn"]}]}]}
Inside the flow: how form fields appear in input
Form fields become part of flow/input.
:collect :setupfields are available on every run after setup is saved.:collect :runfields are available only for the current run.- If both exist, the flow sees one combined input map.
Example:
{:requires [{:kind :form
:collect :setup
:fields [{:key :region
:field-type :select
:required true
:options ["EU" "US"]}]}
{:kind :form
:collect :run
:fields [{:key :question
:field-type :text
:required true}
{:key :resources
:field-type :resource
:required true
:multiple true}]}]
:flow
'(let [input (flow/input)
region (:region input)
question (:question input)
resources (:resources input)]
{:region region
:question question
:resource-count (count resources)})}
The run input seen by the flow looks like:
{:region "EU"
:question "What changed since last week?"
:resources [{:type :resource-ref
:uri "res://v1/ws/ws-1/file/report-a"}
{:type :resource-ref
:uri "res://v1/ws/ws-1/result/summary-b"}]}
Creator: declare per-run inputs for webhook/manual triggers
For triggers that should drive a generic UI/CLI (like an upload form), declare
optional trigger :config :fields.
For manual triggers, the trigger :label is also reused as the primary manual-run CTA
on flow, installation, launch, and setup surfaces. If you define multiple manual
triggers, Resource UI currently uses the first manual trigger label.
Fields are validated and coerced on receipt (for webhooks) and can be used to:
| Use | Details |
|---|---|
| Input UX hints | Tell UI/CLI which inputs to request. |
| File upload shape | Enable multi-file upload with :multiple true. |
Example (webhook upload):
{:triggers [{:type :event
:label "Upload"
:enabled true
:config {:source :webhook
:event-name "files.upload"
:auth {:type :hmac-sha256
:header "X-Signature"
:secret-ref :webhook-secret}
:fields [{:name :files
:type :file
:required true
:multiple true}]}}]}
Notes:
| Note | Behavior |
|---|---|
:file, :blob, and :blob-ref field types | Normalized as :blob-ref in validation. |
| Multipart ingestion | Flows-api persists file parts and passes blob-ref maps (for example {:path \"...\" :size-bytes 123 ...}). |
End user: subscribe + enable (CLI)
| Step | Command |
|---|---|
| 1. Create installation (disabled by default) | breyta flows installations create <flow-slug> --name "My setup" |
2. Provide activation inputs from :requires form fields | breyta flows installations configure <installation-id> --input '{"region":"EU"}' |
| 3. Enable installation | breyta flows installations enable <installation-id> |
End user: upload files (CLI)
| Step | Command |
|---|---|
| 1. Inspect installation triggers and webhook endpoints | breyta flows installations triggers <installation-id> |
| 2. Upload one or more files to webhook trigger | breyta flows installations upload <installation-id> --file ./a.pdf --file ./b.pdf |
If the trigger declares exactly one webhook field of type file/blob/blob-ref,
the CLI infers the multipart field name automatically; otherwise pass it:
breyta flows installations upload <installation-id> --file-field files --file ./a.pdf