launch apps and install plugins in full cli
| src | first commit | |
| tuipm | first commit | |
| .gitignore | first commit | |
| BUILD.md | first commit | |
| debug-codes.js | first commit | |
| demo-plugins.sh | first commit | |
| example-registry.json | first commit | |
| output_silent.mp4 | first commit | |
| package.json | first commit | |
| PLUGINS.md | first commit | |
| QUICK_START.md | first commit | |
| README.md | first commit | |
| test-calculator.js | first commit | |
| tsconfig.json | first commit | |
TUILaunch
TUI (Terminal User Interface) application launcher for Linux with plugin support.
Features
- Fast application search and launch
- Fuzzy search powered by Fuse.js
- Beautiful TUI interface using Ink + React
- Plugin system for extending functionality
- Launch history
- Lightweight and fast
Installation
Quick Start
# Install all dependencies (TUILaunch + TUIPM)
npm run install:deps
# Build everything (TypeScript compilation)
npm run build
# Or build with Bun (creates single executables)
npm run build:bun
Individual builds
# Build only TUILaunch
npm run build:tuilaunch
# Build only TUIPM
npm run build:tuipm
# Clean build directories
npm run clean
Usage
Launch the application
./tuilaunch
Or simply:
npm start
Manage plugins with TUIPM (recommended)
# Add plugin repository
./tuipm/tuipm repo add official https://github.com/USER/tuilaunch-plugins
# Search plugins
./tuipm/tuipm search emoji
# Install plugin
./tuipm/tuipm install emoji-picker
# Update plugins
./tuipm/tuipm update --all
# List installed
./tuipm/tuipm list
See TUIPM Documentation for more details.
Manage plugins (built-in commands)
# List plugins
./tuilaunch plugin list
# Create a new plugin
./tuilaunch plugin create my-plugin
# Enable/disable a plugin
./tuilaunch plugin enable my-plugin
./tuilaunch plugin disable my-plugin
# Remove a plugin
./tuilaunch plugin remove my-plugin
Navigation
↑/↓- Navigate through the listEnter- Launch selected applicationEscorCtrl+C- Exit- Just start typing to search
Plugin System
TUILaunch supports a powerful plugin system. See PLUGINS.md for more details.
Built-in plugins
Calculator - Built-in calculator
- Simply enter a mathematical expression (e.g.,
2+2,10*5) - Result can be copied to clipboard
Creating your own plugin
./tuilaunch plugin create awesome-plugin
Plugins are located in ~/.config/tuilaunch/plugins/
Each plugin can:
- Add its own entries to the list
- Handle search queries
- Intercept key presses
- Run its own commands
- Save configuration
Example plugin:
export default class MyPlugin {
async onQueryChange(query, ctx) {
if (query === 'hello') {
return [{
name: 'Hello World!',
description: 'My custom entry',
exec: 'echo "Hello!"',
path: 'plugin://my/hello',
plugin: 'my-plugin'
}];
}
return null;
}
}
Plugin Development Guide: Calculator Example
Let's walk through the Calculator plugin as a practical example:
Manifest (plugin.pg)
[metadata]
name = "calculator"
version = "1.0.0"
author = "tuilaunch"
license = "MIT"
description = "Simple calculator plugin"
[permissions]
access = ["input_query", "entries_list"]
modify = ["entries_modify"]
[entry]
source = "plugin.js"
[hooks]
on_load = true
on_query_change = true
[config]
enabled = true
Plugin Code (plugin.js)
Key concepts:
onLoad(ctx)- Initialize when plugin loads
async onLoad(_ctx) {
console.log('Calculator plugin loaded!');
}
onQueryChange(query, ctx)- React to user input
onQueryChange(query, _ctx) {
// Preprocess: add Math. prefix to functions
let processedQuery = query;
processedQuery = processedQuery.replace(/\b(sin|cos|tan)\s*\(/g, 'Math.1ドル(');
// Check if query matches math expression pattern
const mathPattern = /^[\d+\-*/().\s,a-zA-Z]+$/;
if (!mathPattern.test(processedQuery)) {
return null; // Not a math expression, ignore
}
try {
const result = eval(processedQuery);
if (typeof result === 'number' && !isNaN(result)) {
// Return custom entry that will be displayed
return [{
name: `= ${result}`,
description: `Calculator: ${query}`,
exec: `echo "${result}" | xclip -selection clipboard`,
path: 'plugin://calculator/result',
plugin: 'calculator'
}];
}
} catch {
return null;
}
return null;
}
onSelect(entry, ctx)- Handle selection
async onSelect(entry, ctx) {
if (entry.plugin === 'calculator') {
ctx.notify('Result copied to clipboard!');
return true; // We handled it, don't run default
}
return false; // Let default handler run
}
How it works:
- User types
2+2in search bar onQueryChangeis called with query"2+2"- Plugin validates it's a math expression
- Plugin evaluates and returns a custom entry
= 4 - Entry appears in results
- User selects and presses Enter
onSelectcopies result to clipboard
Supported operations:
- Basic:
2+2,10*5,100/4,50-20 - Trigonometry:
sin(0),cos(pi),tan(pi/4) - Functions:
sqrt(16),abs(-5),pow(2,3),log(10) - Constants:
pi,e
Project Structure
tuilaunch/
├── src/
│ ├── index.tsx # Main application
│ ├── cli.ts # CLI and entry point
│ └── plugins/
│ ├── types.ts # Plugin system types
│ ├── manager.ts # Plugin manager
│ ├── context.ts # Plugin Context API
│ └── manifest-parser.ts
├── PLUGINS.md # Plugin documentation
└── package.json
Technologies
- Ink - React for terminal
- Fuse.js - Fuzzy search
- TOML - Plugin manifest format
- TypeScript - Type safety
- Bun - Binary bundling
Development
# Development mode
npm start
# Build TypeScript
npm run build
# Build executable
npm run build:bun
# Test
npm test
Configuration
TUILaunch stores data in ~/.config/tuilaunch/:
~/.config/tuilaunch/
├── config.json # Main configuration
├── history.json # Launch history
└── plugins/ # Plugins directory
├── calculator/
├── bookmarks/
└── ...