quickrun-ts is a terminal utility for surfacing frequently used shell commands faster than searching shell history.
The current implementation is an incremental build toward a searchable TUI that:
- filters commands by the current working directory,
- lets you navigate the results with the keyboard, and
- prints the selected command so a shell wrapper can execute it in the current shell.
The CLI renders the interactive UI on the terminal stream and keeps the final selected command on stdout so shell wrappers can capture it cleanly.
bun installbun run index.tsOr, using the package scripts:
bun run startCurrent controls:
- type to filter commands and groups
- space-separated search terms are AND-matched, so
env easymatches entries containing both terms in any order ↑/↓to move the selectionEnterto emit the selected command, or open the selected groupBackspaceto edit the query, or leave the current group when the query is emptyCtrl-Cto clear the current search queryEsc/Ctrl-Dto leave the current group, or cancel from the root
Example terminal output:
Dev server bun run dev
Run tests bun test
cd open group
Build app bun run build
Quickrun now uses a two-layer config setup:
src/commands.example.ts— checked in example/default commands with generic pathssrc/commands.local.ts— optional local commands file, ignored by Git
src/commands.ts loads src/commands.local.ts when that file exists. If it does not exist, it falls back to the checked-in example config.
For personal customization, put your real machine-specific commands in src/commands.local.ts instead of editing the tracked example file.
A local config fully replaces the example config.
export interface QuickAction {
title: string;
command: string;
tags?: string[];
}
export interface QuickCommand extends QuickAction {
when: string | string[];
}
export interface QuickGroup {
title: string;
when: string | string[];
tags?: string[];
commands: QuickAction[];
}title: primary label shown in the selectorcommand: shell command emitted when the entry is selectedwhen: one or more cwd glob patterns that control visibility for top-level commands and groupstags: optional extra search keywords that are not already obvious from the title or commandcommands: commands inside a group; these do not need their ownwhenvalues because the group already controls visibility
Create src/commands.local.ts like this:
import { defineCommands, defineQuickrunConfig, type QuickrunConfig } from "./types.ts";
export const quickrunLocalConfig: QuickrunConfig = defineQuickrunConfig({
commands: defineCommands([
{
title: "Start frontend dev server",
command: "bun run dev",
when: ["~/Repos/personal/my-app", "~/Repos/personal/my-app/**"],
tags: ["frontend", "vite", "local"],
},
{
title: "cd",
when: ["~/Repos/**", "~/work/**"],
tags: ["directories", "jump"],
commands: [
{
title: "Personal repo",
command: "cd ~/Repos/personal/my-app",
},
{
title: "Downloads",
command: "cd ~/Downloads",
},
],
},
]),
});You can also export localCommands directly instead of quickrunLocalConfig if you prefer.
Using an array for when lets one top-level command or group appear in multiple project scopes.
Each visible command or group is rendered on a single line:
- aligned title column
- aligned command column
- white
title - gray command text, or
open groupfor groups - selected row shown with a light background and darker foreground
- when a group is open, a small
group-name/header is shown above its commands
- A top-level command or group is visible when any glob in
whenmatches the current working directory. - Matching is done against normalized absolute paths.
~is expanded to the current user's home directory.- Paths are normalized to use forward slashes.
- Matching is currently case-sensitive.
Examples:
~/Repos/personal/my-appmatches that exact project root.~/Repos/personal/my-app/**also matches nested directories inside the project.**matches every working directory.
Sample wrappers are included at:
examples/quickrun.zsh— expectsquickrun-tson yourPATHexamples/quickrun-bun.zsh— runs the repo source withbun runon every invocation
You can either copy a function into ~/.zshrc or source one of those files.
Examples:
source /absolute/path/to/quickrun-ts/examples/quickrun.zsh
source /absolute/path/to/quickrun-ts/examples/quickrun-bun.zshUse examples/quickrun-bun.zsh during development if you want source changes to be reflected the next time qr runs, without reinstalling or rebuilding anything.
If you prefer not to source the file and instead copy the function into ~/.zshrc, point it at this repo directly, for example:
export QUICKRUN_REPO_DIR=/absolute/path/to/quickrun-ts
cmd="$(bun run "$QUICKRUN_REPO_DIR/index.ts")" || returnWrapper behavior:
- captures the selected command from stdout
- does nothing when the selector is cancelled
- executes the selected command in the current shell with
eval
The zsh wrapper uses eval so the emitted command runs in your current shell context. That is necessary for shell-native behavior, but it also means you should only configure commands you trust.
index.tsis a thin executable entrypoint with a Bun shebangsrc/cli.tscontains the CLI contract and stdout/stderr behaviorsrc/app.tsexposes the testable selector runnersrc/selector.tsowns interactive search/navigation renderingsrc/commands.example.tscontains the checked-in example/default command configsrc/commands.tsloads the local config when present, otherwise falls back to the example configtest/virtual-terminal.tsvendors the upstream virtual terminal harness for integration tests
Run the full test suite with:
bun testOr:
bun run testType-check with:
bunx tsc --noEmitOr:
bun run typecheckThe automated test suite includes:
- unit tests for config, cwd matching, search, selector behavior, and CLI output contracts
- integration tests that drive the TUI through a virtual terminal based on
@xterm/headless