Web-first cross-platform application launcher with React-based plugins
[!WARNING] Launcher is being developed by single developer in their free time. Changes may be few and far between.
There will probably be breaking changes which will be documented in changelog.
https://github.com/user-attachments/assets/19964ed6-9cd9-48d4-9835-6be04de14b66
"main"
or "alternative"
kind so plugins do not need to specify shortcut separately for each OS
"main"
shortcut requires following modifiers
"alternative"
shortcut requires following modifiers
$
will require SHIFT to be pressed, while 4
will notgtk-launch
gtk-launch
assets
directory in root of plugin repository are accessible at plugin runtime using assetData
functionpluginPreferences
and entrypointPreferences
functionsClipboard
apishowHud
functionusePromise
AsyncState
object which contains isLoading
, error
and data
propertiesuseStorage
useState
built-in React HooklocalStorage
internallyuseCache
useState
built-in React HooksessionStorage
internallyuseCachedPromise
stale-while-revalidate
caching strategyusePromise
and useCache
Hooks internallyuseFetch
fetch()
with caching done automaticallystale-while-revalidate
caching strategyuseCachedPromise
Hook internallynpm run dev
to start dev server (requires running application server)
@project-gauntlet/api
and @project-gauntlet/deno
should helppublish
GitHub Actions workflow to publish plugin to gauntlet/release
branchPlugins are installed in Settings UI. Use Git repository url of the plugin to install it.
Although it is possible to install Gauntlet by using .dmg
directly, application doesn't have auto-update functionality so it is recommended to install using brew
package manager.
Brew package: link
To install run:
brew install --cask gauntlet
To start, manually open application.
Download .msi
at Releases page and open to install Gauntlet
Note: application doesn't have auto-update functionality, and has to be updated manually
To start, manually open application.
AUR package: link
To install run:
yay -S gauntlet-bin
To start systemd
service run:
systemctl --user enable --now gauntlet.service
The nix flake in this repository is community maintained. If you face a problem, please create an issue and hopefully somebody will work on it.
To install, you either know what to do, or you can read more here.
At the moment application is only available for Arch Linux and Nix. If you want to create a package for other distributions see Application packaging for Linux
Main window can be opened using global shortcut or CLI command:
gauntlet open
[gauntlet]
name = 'Plugin Name'
description = """
Plugin description
"""
[[preferences]] # plugin preference
name = 'testBool'
type = 'enum' # available values: 'number', 'string,' 'bool', 'enum', 'list_of_strings', 'list_of_numbers', 'list_of_enums'
default = 'item' # type of default depends on type field. Currently, list types have no default
description = "Some preference description"
enum_values = [{ label = 'Item', value = 'item'}] # defines list of available enum values, required for types "enum" and "list_of_enums"
[[entrypoint]]
id = 'ui-view' # id for entrypoint
name = 'UI view' # name of entrypoint
path = 'src/ui-view.tsx' # path to file, default export is expected to be function React Function Component
icon = 'icon.png' # optional, path to file inside assets dir
type = 'view'
description = 'Some entrypoint description'
[[entrypoint.preferences]] # entrypoint preference
name = 'boolPreference'
type = 'bool'
default = true
description = "bool preference description"
[[entrypoint.actions]]
id = 'someAction' # id of action, needs to align with value in <Action> "id" property
description = "demo action description"
shortcut = { key = ':', kind = 'main'} # key string only accepts lower and upper-case letters, numbers and symbols. kind can be "main" or "alternative"
[[entrypoint]]
id = 'command-a'
name = 'Command A'
path = 'src/command-a.ts' # path to file, the whole file is a js script
type = 'command'
description = 'Some entrypoint description'
[[entrypoint]]
id = 'entrypoint-generator'
name = 'Entrypoint generator'
path = 'src/entrypoint-generator.ts'
type = 'entrypoint-generator'
description = 'Some entrypoint description'
[[entrypoint]]
id = 'inline-view'
name = 'Inline view'
path = 'src/inline-view.tsx'
type = 'inline-view'
description = 'Some entrypoint description'
[permissions]
network = ["github.com", "example.com:8833"]
clipboard = ["read", "write", "clear"]
main_search_bar = ["read"]
# if specified requires supported_system to be specified as well
environment = ["ENV_VAR_NAME"]
# if specified requires supported_system to be specified as well
system = ["apiName"]
# if specified requires supported_system to be specified as well
[permissions.filesystem]
read = [
"C:\\ProgramFiles\\test",
"C:/ProgramFiles/test",
"{windows:user-home}\\test",
"{windows:user-home}/test",
"{linux:user-home}/test",
"/etc/test"
]
write = ["/home/exidex/.test"]
# if specified requires supported_system to be specified as well
[permissions.exec]
command = ["ls"]
executable = ["/usr/bin/ls"]
[[supported_system]]
os = 'linux' # 'linux', 'windows' or 'macos'
Located at $XDG_CONFIG_HOME/gauntlet/config.toml
for Linux. Not used at the moment.
The Application has a simple command line interface
gauntlet
- starts server
gauntlet --minimized
- starts server without opening main windowgauntlet open
- opens application window, can be used instead of global shortcutgauntlet settings
- settings, plugin installation and removal, preferences, etc@project-gauntlet/tools
contains separate CLI tool for plugin development purposes. It has following commands:
gauntlet dev
gauntlet build
gauntlet publish
build
publish
assumes some things about git repository, so it is recommended to publish plugin from GitHub Actions workflowPlugin template has nice npm run
wrappers for them.
See THEME.md
The Application consists of 4 parts: server, frontend, plugin runtime and settings. Each plugin runs in separate plugin runtime in separate OS process. Each plugin is its own sandboxed Deno Worker. In plugin manifest it is possible to configure permissions which will allow plugin to have access to filesystem, network, environment variables or subprocess execution. Server saves plugins themselves and state of plugins into SQLite database.
Frontend is GUI module that uses iced-rs as a GUI framework. It is run in the same process as a server.
Plugins can create UI using React. Plugin Runtime implements custom React Reconciler (similar to React Native) which renders GUI components to frontend. Plugin Runtime listens on signals from frontend, so when user opens view defined by plugin, frontend sends an open-view request. Plugin Runtime then receives it, runs React render and React Reconciler makes requests to the frontend containing information what actually should be rendered. When a user interacts with the UI by clicking button or entering text into form, frontend sends events to server to see whether any re-renders are needed.
Settings is a GUI application runs in separate process that communicates with server using a simple request-response approach.
Simplified communication:
Components:
Plugins (or rather its compiled state: manifest, js code and assets) are distributed via Git repository in gauntlet/release
branch (similar to GitHub Pages). Which means there is no one central place required for plugin distribution. And to install plugin all you need is Git repository url.
This section contains a list of things that could be useful for someone who wants to package application for Linux distribution. If something is missing, please create an issue.
Application is already packaged for Arch Linux and Nix so you can use them as examples.
Relevant CLI commands:
$ gauntlet --minimized
systemd
service$ gauntlet open
$ gauntlet settings
.desktop
sample file can be found here
systemd
service sample file can be found here
$XDG_DATA_HOME/gauntlet
or $HOME/.local/share/gauntlet
data.db
$XDG_CACHE_HOME/gauntlet
or $HOME/.cache/gauntlet
$XDG_CONFIG_HOME/gauntlet
or $HOME/.config/gauntlet
config.toml
$XDG_STATE_HOME/gauntlet
or $HOME/.local/state/gauntlet
.desktop
files at locations defined by Desktop Entry SpecificationClient and Setting applications have GUI and therefore use all the usual graphics-related stuff from X11. Wayland support requires LayerShell protocol zwlr_layer_shell_v1
.
You will need:
libxkbcommon-dev
(note: name may differ depending on used distribution)To build dev run:
npm ci
npm run build
npm run build-dev-plugin
cargo build
In dev (without "release" feature) application will use only directories inside project directory to store state or cache.
To build release run:
npm ci
npm run build
cargo build --release --features release
But the new version release needs to be done via GitHub Actions
If you'd like to help build Gauntlet you can do it in more ways than just contributing code:
If you are looking for things to do see pinned issues.
For simple problems feel free to open an issue or PR and tackle it yourself!
For more significant changes please contact creators on Discord (invite link on top of README) and discuss first.
All and any contributions are welcome.
Application uses simple incremental integers starting from 1
. It doesn't follow the SemVer versioning. Given application's reliance on plugins, once it is stable, introducing breaking changes will be done carefully (if at all) and will be given a reasonable grace period to migrate. SemVer is about a hard cutoff between major versions with breaking changes, which doesn't fit this kind of application. Before application is declared stable, breaking changes could be done without a grace period.
@project-gauntlet/tools
uses SemVer.
Plugins only have the latest published "version".