Syntropy
[!WARNING] Alpha Software: Syntropy is currently in alpha stage. Features may change, and bugs may be present. Use with caution and at your own responsibility. Always review plugin code before execution, especially for tasks that modify system state.
Syntropy is a TUI tool with a neovim-like Lua plugin framework. Build custom workflows for data management, maintenance tasks, and automation. Use it interactively or integrate with scripts and cron jobs. Think dmenu meets neovim, in your terminal.
Key Features:
- Plugin-based architecture - Lua plugins define tasks and actions
- Dual-mode operation - Interactive TUI or headless CLI execution with scripting support
- Fuzzy search - Quickly filter items with real-time fuzzy matching
- Multi-select - Select and execute multiple items in batch
- Preview pane - Preview items before executing actions (TUI and CLI)
- Scriptable - Output items, previews, and selections for integration with other tools
- Configurable - Keybindings, themes, and behavior via TOML config
- XDG compliant - Follows XDG Base Directory Specification
Demo

If you miss dmenu on macOS syntropy was designed to fill in the void. Quick launch plugins as drop down menus with hotkeys. See recipes for setup details.

Table of Contents
Quick Start
Installation
# Build from source (requires Rust 1.70+)
# Binary will be at: ./target/release/syntropy
# Optional: Move to PATH
or
Initialize Plugin Environment
# Generate plugin scaffold and example config
# This creates:
# ~/.config/syntropy/config.toml (configuration file)
# ~/.config/syntropy/plugins/ (user plugins directory)
# ~/.local/share/syntropy/plugins/ (managed plugins directory)
Next: See Discovering & Installing Plugins to browse and install community plugins.
Discovering & Installing Plugins
Start here: Browse the Available Plugins catalog to discover community plugins for common tasks like package management, backups, window switching, and more.
Quick workflow:
- Browse the Available Plugins catalog
- Copy the plugin config snippet from the catalog
- Add it to your
~/.config/syntropy/config.toml - Run
syntropy plugins --install
Plugin Types
| Type | Location | Managed By |
|---|---|---|
| User plugins | ~/.config/syntropy/plugins/ |
Manual (you) |
| Managed plugins | ~/.local/share/syntropy/plugins/ |
Plugin manager (git) |
| Orphan plugins | ~/.local/share/syntropy/plugins/ |
None (leftover from removed config) |
Plugin Manager Commands
# List all plugins and their status
# Install missing plugins declared in config
# Remove orphaned plugins (not in config)
# Upgrade all plugins to versions in config
# Upgrade specific plugin
Declaring Plugins in Config
Add plugins to config.toml:
[]
= "https://github.com/user/syntropy-plugin-packages"
= "v1.2.0" # or: branch = "main", rev = "abc123"
[]
= "https://github.com/user/syntropy-plugin-backups"
= "main"
Then install:
Plugin Discovery
Syntropy auto-discovers plugins from both directories:
~/.local/share/syntropy/plugins/(managed plugins)~/.config/syntropy/plugins/(user plugins)
Merge behavior:
- If same plugin exists in both, config version overrides data version
- Allows customizing managed plugins without editing source
Plugin Validation
# Validate plugin structure
# Common errors:
# - Missing metadata.name or metadata.version
# - Invalid semver format
# - Icon too wide (must be single char)
# - Task has neither execute nor item_sources
Run Interactive TUI
# Launch the TUI
# Navigate: arrow keys, fuzzy search, tab to select
# Execute: press enter on selected item(s)
Run Tasks from CLI
# Discover plugins and tasks
# Execute task directly (for scripts/cron)
# Pass specific items to execute (comma-separated)
# Scripting and automation
CLI Usage
Basic Syntax
Main Options
| Flag | Description | Example |
|---|---|---|
--config <PATH> |
Use custom config file | syntropy --config ~/my-config.toml |
--plugin <NAME> |
Select plugin to use | syntropy --plugin packages |
--task <NAME> |
Select task within plugin | syntropy --task export |
execute |
Execute task subcommand | syntropy execute --plugin pkg --task list |
--items <NAMES> |
Execute on specific items (comma-separated) | syntropy execute --plugin pkg --task install --items "curl,wget" |
Execute Subcommand Flags
The execute subcommand supports additional flags for scripting, debugging, and integration:
| Flag | Description | Example |
|---|---|---|
--items <NAMES> |
Execute on specific items (comma-separated; escape commas with \,) |
--items "git,npm,curl" |
--preview <ITEM> |
Generate preview for a single item; supports fuzzy matching (case-insensitive, tag-stripped fallback) | --preview "Safari" |
--produce-items |
Output all available items (one per line) | --produce-items > items.txt |
--produce-preselected-items |
Output items returned by the task's preselected_items() function |
--produce-preselected-items |
--produce-preselection-matches |
Output the intersection of available items and preselected items | --produce-preselection-matches |
Note: These flags are mutually exclusive - you can only use one at a time.
Streaming previews: The TUI's
preview_polling_intervalrefreshes the preview pane live as content changes. There is no CLI equivalent —--previewis a single-shot call. For polling behaviour in scripts, usewatch syntropy execute --plugin P --task T --preview ITEM.
Commands
| Command | Description |
|---|---|
list |
List all loaded plugins with version and description |
list --plugin <NAME> |
List all tasks for a plugin (key, description, mode, source count) |
list --plugin <NAME> --task <KEY> |
Show full detail for a specific task |
init |
Initialize plugin development environment |
completions <SHELL> |
Generate shell completions (zsh, bash, fish, powershell, elvish) |
validate --plugin <PATH> |
Validate plugin structure |
validate --config [PATH] |
Validate config file (defaults to ~/.config/syntropy/config.toml) |
plugins |
Manage plugins (install, remove, upgrade, list) - See Discovering & Installing Plugins |
Common Usage Patterns
Interactive TUI (default):
# Launch with default config
# Use custom config
# Start at specific plugin
# Start at specific task
Direct Execution (CLI mode):
# Execute task and exit
# Execute on specific items (comma-separated)
# Use in scripts
#!/bin/bash
result=
# Exit code handling
if [; then
else
fi
Scripting and Automation:
# Get list of available items for processing
# Preview item details before execution
# Get preselected items (useful for default selections)
# Find items that match preselection criteria
# Process items in a loop
| while ; do
done
# Integration with other tools
# Filter items with grep/awk before processing
| |
# Get preview for all items
for; do
done
Plugin Development:
# Initialize scaffold
# Validate plugin
# Validate config
Shell Completions
Syntropy supports completions for Zsh, Bash, Fish, PowerShell, and Elvish.
Zsh
# Generate completion script
# Add to ~/.zshrc (if not already present)
fpath=(/.zfunc )
# Reload shell
Oh My Zsh users:
Bash
# Generate completion script
# Reload shell
Alternative (direct sourcing):
# Add to ~/.bashrc
Fish
# Generate completion script
# Reload shell
PowerShell
# Generate and load completion
syntropy completions powershell | Out-String | Invoke-Expression
# To persist, add to profile:
syntropy completions powershell >> $PROFILE
Elvish
# Generate completion script
# Add to rc.elv:
# use syntropy
Environment Variables
| Variable | Purpose | Example |
|---|---|---|
XDG_CONFIG_HOME |
Override config directory | XDG_CONFIG_HOME=/tmp/test syntropy |
XDG_DATA_HOME |
Override data directory | XDG_DATA_HOME=/tmp/data syntropy |
Testing with temp directories:
XDG_CONFIG_HOME=/tmp/test XDG_DATA_HOME=/tmp/data
TUI Usage
Default Keybindings
| Action | Key | Description |
|---|---|---|
| Navigation | ||
| Previous item | ↑ |
Move selection up |
| Next item | ↓ |
Move selection down |
| Confirm | Enter |
Execute selected item(s) or navigate into selection |
| Back | Esc |
Go back to previous screen |
| Quit | Ctrl-c |
Exit syntropy (hardcoded, not customizable) |
| Selection | ||
| Toggle select | Tab |
Toggle item selection (multi-mode only) |
| Preview | ||
| Scroll up | Ctrl-↑ |
Scroll preview pane up |
| Scroll down | Ctrl-↓ |
Scroll preview pane down |
| Toggle preview | Ctrl-p |
Show/hide preview pane |
| Search | ||
| Type to search | Any char | Filter items with fuzzy search |
| Clear search | Backspace |
Delete characters from search |
| Move cursor | ← → Home End |
Edit search query |
Note: All keybindings are customizable in config.toml. See Configuration.
Navigation Flow
Plugin List → Task List → Item List → Execute
↓ ↓ ↓
[icon] name task name [tag] item
Workflow:
- Select Plugin - Choose from available plugins
- Select Task - Choose task within plugin
- Select Items - Choose item(s) to execute (fuzzy search available)
- Execute - Press Enter to run action
Navigation:
Enter- Move forward (select plugin → task → execute)Esc- Move backward (return to previous screen)
Fuzzy Search
The search bar appears at the bottom when enabled (search_bar = true in config).
How it works:
- Type to filter items in real-time
- Matching is fuzzy - "pkg" matches "packages", "package-lock", etc.
- Case-insensitive
- Clear with Backspace
Example:
Items: [homebrew, cargo, pip, npm, yarn, pipx]
Search: "crg" → Matches: [cargo]
Search: "pp" → Matches: [pip, npm]
Multi-Select Mode
Tasks with mode = "multi" allow selecting multiple items.
Workflow:
- Navigate to items with
↑↓ - Press
Tabto toggle selection (checkmark appears) - Select multiple items
- Press
Enterto execute all selected items
Visual indicator:
[x] item1 (selected)
[ ] item2 (not selected)
[x] item3 (selected)
Preview Pane
Shows additional information about the selected item.
Controls:
Ctrl-↑- Scroll preview upCtrl-↓- Scroll preview downCtrl-p- Toggle preview visibility
When preview appears:
- Plugin defines
preview(item)function - Task or item source provides preview
- Preview pane enabled in config (
show_preview_pane = true)
CLI access: Use syntropy execute --preview <ITEM> to get preview output from the command line (useful for scripting)
Status Bar
Shows current navigation context (breadcrumb) and keybinding hints.
Example:
packages > export_packages | ↑↓:Navigate Enter:Select Esc:Back Tab:Toggle
Toggle with status_bar = true/false in config.
Creating Plugins
Quick Example
Create a plugin in 30 seconds:
# 1. Create plugin directory
# 2. Create plugin.lua
# 3. Run syntropy (plugin auto-discovered)
Want to use existing plugins first? Check out Discovering & Installing Plugins to browse community plugins before building your own.
Note: This example keeps all code in plugin.lua for simplicity. For complex plugins with multiple modules, use the lua/pluginname/ directory structure with namespaced imports. See the "Organizing plugin code with modules" section in Common Patterns.
Plugin Structure
Every plugin is a Lua script returning a table:
---@type PluginDefinition
return
Plugin Directory Structure:
For plugins with multiple modules:
my-plugin/
├── plugin.lua # Main plugin definition
└── lua/
└── my-plugin/ # Namespace matches plugin name
├── module1.lua # require("my-plugin.module1")
├── module2.lua # require("my-plugin.module2")
└── subdir/
└── init.lua # require("my-plugin.subdir")
Modules must use namespaced imports: require("my-plugin.module1")
Available Lua APIs
Plugins have access to:
syntropy namespace:
-- Execute shell command
local output, exit_code = syntropy.
-- Launch external TUI applications with full terminal control
local exit_code = syntropy.
local exit_code = syntropy.
-- Expand paths (tilde, environment variables, plugin-relative paths)
local path = syntropy.
Module loading:
require("pluginname.module")- Load plugin-namespaced modules fromlua/pluginname/module.luarequire("module")- Load shared modules fromplugins/shared/module.lua- Modules are cached after first load (standard Lua behavior)
Standard Lua library:
- All standard modules (string, table, math, io, os)
- Except:
os.exit(),os.execute()(usesyntropy.shell())
Common Patterns
Reading files:
items =
Calling shell commands:
execute =
Previewing items:
preview =
Launching external TUI applications:
-- Open files in user's editor
execute =
-- Launch any TUI app (fzf, htop, ranger, etc.)
execute =
-- Tip: Suppress success notifications for cleaner workflows
tasks =
Organizing plugin code with modules:
For complex plugins with multiple files, use the Neovim-style lua/ directory structure:
-- Create module: ~/.config/syntropy/plugins/my-plugin/lua/my-plugin/utils.lua
local utils =
return utils
-- Use in plugin.lua with namespaced import:
local utils = require
execute =
Key points:
- Plugin modules MUST use namespaced imports:
require("pluginname.module") - Directory structure:
lua/pluginname/module.lua - Supports
lua/pluginname/module/init.luafor directory-style modules - Shared modules (in
plugins/shared/) use flat imports:require("module")
See Plugin Development Guide for full module organization details.
Next Steps
- Browse plugins: Available Plugins - See community plugins for inspiration
- Full tutorial: Plugin Development Guide
- API reference: Plugin API Reference
- Contributing: Contributor Guide
Configuration
Config location: ~/.config/syntropy/config.toml
For complete reference of all 88 config options, see Configuration Reference.
Example Config
# Default plugin to show on startup
= "packages"
# Default task within plugin
= "list"
# Default icon for plugins without icon
= "⚒"
# UI options
= true
= true
= true
= false
# Custom keybindings
[]
= "<esc>"
= "<up>"
= "<down>"
= "["
= "]"
= "<C-p>"
= "<tab>"
= "<enter>"
# Managed plugins (installed via plugin manager)
[]
= "https://github.com/user/syntropy-plugin-packages"
= "v1.0.0"
# Styling (optional)
[]
= 50
= 50
[]
= 70
= 30
[]
= 80
= 60
Key Binding Format
| Format | Example | Description |
|---|---|---|
<char> |
<a>, <b> |
Single character |
<key> |
<up>, <down>, <enter>, <esc>, <tab> |
Special keys |
<C-x> |
<C-p>, <C-n> |
Ctrl + key |
<S-x> |
<S-tab> |
Shift + key |
<A-x> |
<A-q> |
Alt + key |
Testing
Syntropy includes comprehensive unit and integration tests.
Running Tests
# Run all tests
# Run only unit tests (fast)
# Run only integration tests
# Run specific test
# Show output (println! statements)
# Run tests serially (not parallel)
Test Coverage
- Unit tests - Parsing, validation, keybindings, navigation
- Integration tests - Plugin loading, merging, CLI execution, config validation
Contributing
Contributions welcome! Please read the Contributor Guide for:
- Architecture overview with ASCII diagram
- Codebase navigation guide
- Testing philosophy (TDD approach)
- Code patterns and conventions
- Pull request process
Quick start for contributors:
# Clone and build
# Run tests
# Check linting
# Format code
License
Documentation:
- Available Plugins - Curated list of community plugins (start here!)
- Plugin Development Guide - Concepts and tutorial
- Plugin API Reference - Complete API documentation
- Configuration Reference - Complete config.toml reference
- Recipes - Integration examples and workflows
- Contributor Guide - Architecture and development guide