Extend Bolt
Your first Bolt App in 5 minutes.
Pick the track that fits you. A snippet needs nothing but Bolt. A User App needs the desktop app. A connector needs admin rights in your organization's Bolt.
Track A, anyone, tier 1
A snippet that cleans a list.
You have a messy list like pear, apple, kiwi, apple. You
want one item per line, sorted, no repeats.
-
Open Settings → Search & Commands → Snippets and click Add snippet.
-
Key:
cleanlist. Label:Clean a list. Content: the line below. Save. -
Copy a comma-separated list. Open Bolt, type
;cleanlist, press Enter. -
Paste. You get
apple,kiwi,pear, one per line.
{clipboard|splitcsv|sort|uniq}
{clipboard} is what you copied; each | is a
filter. More filters, fill-in fields and pipelines are on
the Snippets page.
Track B, anyone on the desktop app
A User App, in one YAML file.
A User App is a YAML file in a folder on your computer. Bolt reads it
and gives you a new = key. This one is tier 2: it only
reshapes text you paste, with no command and no network.
-
Open Settings → Desktop App → User Apps. Check that Allow User Apps on this device is on, then click Open folder.
-
Save the YAML below in that folder as
my-scrub.yaml. -
Back in Settings, click Reload. If the file has a mistake, the reason is shown under the list.
-
Paste text that holds an SSN or an email address into the Bolt launcher. A Scrub IDs row offers the masked version. You can also type
=my-scruband your text.
schema_version: 1
runtime: transform
id: my-scrub
chip: my-scrub
title: Scrub IDs
icon: shield-off
description: Mask SSNs and email addresses in pasted text, on this device
placeholder_examples: ["SSN 123-45-6789 email [email protected]"]
emits: Generic
recognize:
patterns:
- regex: '\b\d{3}-\d{2}-\d{4}\b'
- regex: '[\w.+-]+@[\w-]+\.[\w.-]+'
confidence: ambient
transform:
pipe:
- replace: { from: '\b\d{3}-\d{2}-\d{4}\b', to: '[SSN]' }
- replace: { from: '[\w.+-]+@[\w-]+\.[\w.-]+', to: '[email]' }
- sanitize
presentation:
widget: list
title_field: line
Next: run a command (tier 3)
A bridge App runs one command and shows each line of
output as a row. Bolt runs it as a single program call, never through
a shell, so pipes and ; are refused. It runs with your own
rights, the same as typing it in a terminal, and only after you press
Enter.
schema_version: 1
runtime: bridge
id: my-git-log
chip: my-git-log
title: Recent commits
icon: git-commit
description: Recent commits of a repo under ~/dev
placeholder_examples: ["my-app", "infra 30"]
emits: Generic
detect:
binary: git
bridge:
command:
macos: "git -C {{home}}/dev/{{repo}} log --oneline -{{limit}}"
linux: "git -C {{home}}/dev/{{repo}} log --oneline -{{limit}}"
windows: "git -C {{home}}/dev/{{repo}} log --oneline -{{limit}}"
parse: lines
timeout_seconds: 5
args:
- { name: repo, from: "query.word(0)" }
- { name: limit, from: "query.word(1)", default: 20 }
presentation:
widget: list
title_field: line
Type =my-git-log my-app 10. {{home}} is your
home folder; a ~ would not work, because no shell expands
it. detect hides the key on a computer without git. The
full field list is on the User Apps page.
Track C, admins
A connector for everyone in your organization.
A connector is a manifest your admin adds once, and everyone in the
organization gets the = key. It runs in Bolt's service (your
organization's server, or the one inside the desktop app), with each
person's own sign-in. These two call public APIs that need no sign-in.
-
Open Settings → Admin → Utilities and choose the Custom tab.
-
Paste the manifest. Click Preview to check it, then Save manifest.
-
In Bolt, type
=worldclock Asia/Kolkataand press Enter. You get one row with the current time.
schema_version: 1
id: worldclock
chip: =worldclock
title: World Clock
description: Current time for an IANA timezone.
emits: Generic
scopes:
- id: lookup
label: Lookup zone
default: true
flow:
- call:
kind: http
method: GET
url: "https://timeapi.io/api/Time/current/zone"
query:
timeZone: "{{query | default:'America/New_York'}}"
out: r
- emit: r
presentation:
widget: list
title_field: dateTime
subtitle_field: timeZone
placeholder: "Try America/New_York or Asia/Kolkata"
scopes are sub-commands; the default: true one
runs when someone types the key. A flow is a list of steps:
call fetches, emit returns the rows.
{{query}} is what the person typed after the key.
A five-vendor status board
This one calls five status feeds at once with parallel,
shapes them into one list with a jq transform, and puts the
vendor with open incidents first. Each row has an Open status page action.
schema_version: 1
id: status
chip: =status
title: SaaS status board
description: Live status of five vendors from their public Statuspage feeds.
emits: Generic
scopes:
- id: board
label: Status board
default: true
flow:
- parallel:
- call: { kind: http, method: GET, url: "https://www.githubstatus.com/api/v2/summary.json" }
out: github
- call: { kind: http, method: GET, url: "https://www.stripestatus.com/api/v2/summary.json" }
out: stripe
- call: { kind: http, method: GET, url: "https://www.cloudflarestatus.com/api/v2/summary.json" }
out: cloudflare
- call: { kind: http, method: GET, url: "https://discordstatus.com/api/v2/summary.json" }
out: discord
- call: { kind: http, method: GET, url: "https://status.openai.com/api/v2/summary.json" }
out: openai
- transform: |
[
{ vendor: "GitHub", description: .github.status.description, incidents: (.github.incidents | length), url: .github.page.url },
{ vendor: "Stripe", description: .stripe.status.description, incidents: (.stripe.incidents | length), url: .stripe.page.url },
{ vendor: "Cloudflare", description: .cloudflare.status.description, incidents: (.cloudflare.incidents | length), url: .cloudflare.page.url },
{ vendor: "Discord", description: .discord.status.description, incidents: (.discord.incidents | length), url: .discord.page.url },
{ vendor: "OpenAI", description: .openai.status.description, incidents: (.openai.incidents | length), url: .openai.page.url }
] | sort_by(.incidents) | reverse
out: rows
- emit: rows
actions:
- id: open
kind: url
target: row
label: "Open status page"
url_template: "{{row.url}}"
presentation:
widget: list
title_field: vendor
subtitle_field: description
list_fields: [vendor, description, incidents]
row_key_field: vendor
Next
Share it.
A User App can travel as a Boltpack. Skills and agents can be exported as one from Settings. The public gallery is coming; see Publishing.