Extend Bolt
User Apps.
A YAML file on your computer that adds an = key to Bolt. Personal, desktop app only. Tier 2 for a transform, tier 3 for anything that reads another program or runs a command.
Where they live.
Settings → Desktop App → User Apps. Open folder
shows the folder (user-utils inside Bolt's app-data folder);
put a .yaml file there and click Reload. A
file with a mistake is listed with the reason. Bolt also puts its own
sample Apps in this folder, such as =sys, and keeps them up
to date; a file you made with the same name is never overwritten.
Allow User Apps on this device turns them all off or on.
Off, they stop loading and cannot run, and the files stay where they are.
Today the person on the device can change this switch. From the next
release a company can turn User Apps off through device policy
(userAppsEnabled), and the person cannot switch them back.
To remove one, delete its file and click Reload. An App installed from
a Boltpack may also have placed a script in the scripts
folder beside it; delete that too. From the next release, removing an
App in Settings also removes the scripts its pack installed.
Fields.
| Field | Required | Meaning |
|---|---|---|
schema_version | yes | 1 |
runtime | yes | transform, http_local or bridge |
id | yes | Lowercase letters, digits and -, up to 64. Also the file name. |
chip | yes | The key you type after =. Same rule as id. |
title | yes | Row title in the launcher. |
emits | yes | Person, Issue, Document, Event, File, Incident, Account, Place or Generic. |
presentation | yes | widget: list, table, cards or detail; title_field, subtitle_field, searchable, right_widget. |
icon, description, placeholder_examples | no | Display only. |
args | no | Words from what you typed: { name, from: "query.word(N)", default }. |
inputs, submit | no | A form. Field type: text, number, date, select, toggle or secret. |
actions | no | Per-row actions of kind url, composer or utility (run another App). |
dispatch | no | Confirm-row text, or several choices. A bridge App always waits for Enter. |
detect | no | Show the key only when a program is installed: binary, version_min, auth_check, refresh. |
recognize | no | Claim pasted or typed text without the = key: up to 16 patterns (regex, 512 characters each), confidence ambient or high. |
transform | with runtime: transform | The pipe, see below. |
http | with runtime: http_local | See below. |
bridge | with runtime: bridge | See below. |
runtime: transform (tier 2).
A pipe of up to 32 steps that reshapes text on your device. No command,
no network. Pair it with recognize so pasting the right
text offers the App. Transform Apps rank below Bolt's own, so they
cannot hide a built-in result.
| Steps | Names |
|---|---|
| No argument | lines, sort, dedupe, reverse, trim, upper, lower, title, camel, snake, kebab, slug, table, markdown, csv, aligned, sql, json, yaml, toml, env, properties, transpose, flatten, redact_secrets, sanitize |
| With options | split, join, filter, head, tail, slice, replace, prefix, suffix, template, sortcol, dedupecol, rename_cols, pick, omit |
schema_version: 1
runtime: transform
id: vendor-csv-cleanup
chip: vendor-csv-cleanup
title: Clean vendor CSV
emits: Generic
recognize:
patterns:
- regex: 'name\s*,\s*amount'
flags: i
confidence: ambient
transform:
pipe:
- lines
- filter: { not_contains: "TOTAL" }
- table
- json
presentation:
widget: list
title_field: line
runtime: http_local (tier 3).
One GET or POST to a service on this computer. host can only
be 127.0.0.1, ::1 or localhost, so the
App cannot reach another machine. parse is json, lines or raw;
rows_path points at the list inside a JSON reply. Header values
may read an environment variable as ${env:NAME}.
schema_version: 1
runtime: http_local
id: ollama
chip: ollama
title: Ollama models
emits: Generic
http:
port: 11434
request: { method: GET, path: "/api/tags" }
parse: json
rows_path: models
timeout_seconds: 5
presentation:
widget: list
title_field: name
subtitle_field: model
runtime: bridge (tier 3).
Runs one program and turns its output into rows. bridge.command
has a line per system (macos, linux, windows);
parse is json, lines or raw; timeout_seconds is 1 to 60.
- Bolt splits the command into arguments and runs the program directly. There is no shell:
;,&&,||,|, backticks and$(are refused, and~is not expanded. Use{{home}}. - Variables:
{{query}}, yourargsandinputs,{{home}}and{{scripts_dir}}. Write them bare, never inside quotes; Bolt quotes each value. envvalues must be${env:NAME}; a secret written into the file is refused.- It waits for Enter, every time. It runs as you, with your rights, like your terminal. Bolt does not confine what the program reads, writes or calls.
- For more than one step, put the logic in a script in
scriptsand callsh {{scripts_dir}}/my-script.sh {{query}}.
See the quickstart for a complete bridge App.
User Apps and AI.
User Apps are not given to the AI as tools, and their rows are marked so they are never sent to a model on their own. A model cannot start a User App; a person types the key and presses Enter.
More.
Every field in depth: connector spec, section 19. Real examples: the User App samples. Share one: Boltpack format.