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.

FieldRequiredMeaning
schema_versionyes1
runtimeyestransform, http_local or bridge
idyesLowercase letters, digits and -, up to 64. Also the file name.
chipyesThe key you type after =. Same rule as id.
titleyesRow title in the launcher.
emitsyesPerson, Issue, Document, Event, File, Incident, Account, Place or Generic.
presentationyeswidget: list, table, cards or detail; title_field, subtitle_field, searchable, right_widget.
icon, description, placeholder_examplesnoDisplay only.
argsnoWords from what you typed: { name, from: "query.word(N)", default }.
inputs, submitnoA form. Field type: text, number, date, select, toggle or secret.
actionsnoPer-row actions of kind url, composer or utility (run another App).
dispatchnoConfirm-row text, or several choices. A bridge App always waits for Enter.
detectnoShow the key only when a program is installed: binary, version_min, auth_check, refresh.
recognizenoClaim pasted or typed text without the = key: up to 16 patterns (regex, 512 characters each), confidence ambient or high.
transformwith runtime: transformThe pipe, see below.
httpwith runtime: http_localSee below.
bridgewith runtime: bridgeSee 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.

StepsNames
No argumentlines, 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 optionssplit, join, filter, head, tail, slice, replace, prefix, suffix, template, sortcol, dedupecol, rename_cols, pick, omit
vendor-csv-cleanup.yaml (ships with Bolt)
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}.

ollama.yaml, shortened (ships with Bolt)
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}}, your args and inputs, {{home}} and {{scripts_dir}}. Write them bare, never inside quotes; Bolt quotes each value.
  • env values 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 scripts and call sh {{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.