Skip to main content

A TUI command runner based on git changes

Project description

Fnug

[!WARNING] The main branch is currently undergoing a refactor to Rust. If you're looking for the latest Python version, see the python branch.

CI Crates.io image

Fnug is a TUI command runner that automatically selects and executes lint and test commands based on git changes or file watching. Think of it as a terminal multiplexer (like tmux), but purpose-built for running your dev commands side by side.

Fnug demo

Features

  • Git integration — automatically select commands based on uncommitted file changes
  • File watching — monitor the file system and re-select commands when files change
  • Terminal emulation with scrollback — full PTY support for interactive commands and long output
  • Headless mode (fnug check) — run selected commands without the TUI, useful for CI
  • Git hook integration (fnug init-hooks) — install a pre-commit hook that runs fnug check
  • Command dependencies — define depends_on to control execution order
  • Environment variables — set per-command or per-group env vars
  • Nested command groups — organize commands into a hierarchical tree with inherited settings
  • Workspace support — discover and merge .fnug.yaml files from subdirectories in mono-repos

Installation

From crates.io

cargo install fnug

From PyPI

# With uv
uv tool install fnug

# With pipx
pipx install fnug

From GitHub Releases

Download a prebuilt binary from GitHub Releases.

With Nix

# Run directly
nix run github:nickolaj-jepsen/fnug

# Or install to profile
nix profile install github:nickolaj-jepsen/fnug

From source

git clone https://github.com/nickolaj-jepsen/fnug.git
cd fnug
cargo install --path .

Usage

Run fnug in a directory with a .fnug.yaml configuration file (or pass -c path/to/config.yaml).

Subcommands

Command Description
fnug Launch the TUI
fnug check Run selected commands headlessly (exit code reflects pass/fail)
fnug init-hooks Install a git pre-commit hook that runs fnug check

Flags

Flag Description
-c <path> Path to config file
--no-workspace Disable workspace resolution (don't search for a parent root)
--log-file Write logs to a file

Configuration

Fnug searches for .fnug.yaml, .fnug.yml, or .fnug.json from the current directory upward.

Minimal example

fnug_version: 0.1.0
name: my-project
commands:
  - name: hello
    cmd: echo world

Git auto-selection

Select commands based on uncommitted changes. Re-trigger with g in the TUI.

fnug_version: 0.1.0
name: my-project
commands:
  - name: lint
    cmd: cargo clippy
    auto:
      git: true
      path:
        - "./src"
      regex:
        - "\\.rs$"

File watching

Monitor the file system and select commands when matching files change. Can be combined with git auto.

fnug_version: 0.1.0
name: my-project
commands:
  - name: test
    cmd: cargo test
    auto:
      watch: true
      path:
        - "./src"
      regex:
        - "\\.rs$"

Nested groups with inheritance

Groups inherit cwd, auto, and env settings from their parent.

fnug_version: 0.1.0
name: my-project
children:
  - name: backend
    auto:
      git: true
      watch: true
      path:
        - "./src"
      regex:
        - "\\.rs$"
    commands:
      - name: fmt
        cmd: cargo fmt
      - name: test
        cmd: cargo test
      - name: clippy
        cmd: cargo clippy

Workspace

Workspace mode discovers .fnug.yaml files in subdirectories and merges them as child groups. This is useful for mono-repos where each package has its own config.

When workspace: true, fnug walks the filesystem (skipping .gitignore'd and hidden directories) to find sub-configs. Files do not need to be git-tracked to be discovered.

# Auto-discover sub-configs (walks up to 5 levels deep)
fnug_version: 0.1.0
name: my-monorepo
workspace: true
commands:
  - name: root-lint
    cmd: echo "root"
# Custom max scan depth
workspace:
  max_depth: 2
# Explicit glob patterns
workspace:
  paths:
    - "./packages/*/"
    - "./apps/*/"

When run from a subdirectory that contains a .fnug.yaml, fnug automatically resolves upward to the nearest workspace root. Use --no-workspace to disable this behavior.

Advanced example

See this project's .fnug.yaml for a full example.

Keyboard Shortcuts

Key Context Action
j / Tree Move down
k / Tree Move up
h / Tree Collapse group / Deselect command
l / Tree Expand group / Select command
Space Tree Toggle expand/select
Enter Tree Run all selected commands
r Tree Run current command
s Tree Stop current command
c Tree Clear current command
g Tree Git auto-select
/ Tree Search/filter commands
Esc Search Clear search
L Tree Toggle log panel
Tab Tree Focus terminal
Esc Terminal Back to tree
Ctrl+R Global Toggle fullscreen
Ctrl+C Global Quit
q Tree Quit

Mouse

  • Click a tree item to select it
  • Double-click a command to run it, or a group to expand/collapse
  • Click the selection orb (●/○) or arrow (▼/▶) to toggle
  • Drag the separator between tree and terminal to resize
  • Scroll wheel in the terminal panel to scroll output
  • Right-click a command for a context menu with run/stop/clear options

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

fnug-0.1.0a8.tar.gz (748.0 kB view details)

Uploaded Source

Built Distributions

If you're not sure about the file name format, learn more about wheel file names.

fnug-0.1.0a8-py3-none-win_amd64.whl (3.6 MB view details)

Uploaded Python 3Windows x86-64

fnug-0.1.0a8-py3-none-manylinux_2_28_x86_64.whl (3.4 MB view details)

Uploaded Python 3manylinux: glibc 2.28+ x86-64

fnug-0.1.0a8-py3-none-manylinux_2_28_aarch64.whl (3.2 MB view details)

Uploaded Python 3manylinux: glibc 2.28+ ARM64

fnug-0.1.0a8-py3-none-macosx_11_0_arm64.whl (3.0 MB view details)

Uploaded Python 3macOS 11.0+ ARM64

fnug-0.1.0a8-py3-none-macosx_10_12_x86_64.whl (3.2 MB view details)

Uploaded Python 3macOS 10.12+ x86-64

File details

Details for the file fnug-0.1.0a8.tar.gz.

File metadata

  • Download URL: fnug-0.1.0a8.tar.gz
  • Upload date:
  • Size: 748.0 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: maturin/1.12.6

File hashes

Hashes for fnug-0.1.0a8.tar.gz
Algorithm Hash digest
SHA256 f53e0ea52040ede6b9a7977e5b3930fd7c5cd505c7b792061d94342106770fc5
MD5 0342d30ea6a9e6f9974554b57a9e6d65
BLAKE2b-256 dcf3461db9dd16b0482acb47176447d26517da005e684135c5b8e2b063d06447

See more details on using hashes here.

File details

Details for the file fnug-0.1.0a8-py3-none-win_amd64.whl.

File metadata

  • Download URL: fnug-0.1.0a8-py3-none-win_amd64.whl
  • Upload date:
  • Size: 3.6 MB
  • Tags: Python 3, Windows x86-64
  • Uploaded using Trusted Publishing? No
  • Uploaded via: maturin/1.12.6

File hashes

Hashes for fnug-0.1.0a8-py3-none-win_amd64.whl
Algorithm Hash digest
SHA256 a92fe40e00da0e752bacec1f1e7601c0cfe3f28e3dbcd787103cefd658e99ca4
MD5 eb28307b7dbd0a230b59b724cf806472
BLAKE2b-256 fc9b7b5043d37778d2131c6ad915d85bae957d6e5a9b117cfe10cb960a060a7f

See more details on using hashes here.

File details

Details for the file fnug-0.1.0a8-py3-none-manylinux_2_28_x86_64.whl.

File metadata

File hashes

Hashes for fnug-0.1.0a8-py3-none-manylinux_2_28_x86_64.whl
Algorithm Hash digest
SHA256 86a2b022f0015fce5d2fcc8cec04b0b406a579ca10bbeb3bfc6dfd69225a304c
MD5 97c70e3d7e754a62bf5df87c7bd79136
BLAKE2b-256 da9698fa87237cfc01941bad9808f6d68fe7dbfc9583c7a6782e0e969a371732

See more details on using hashes here.

File details

Details for the file fnug-0.1.0a8-py3-none-manylinux_2_28_aarch64.whl.

File metadata

File hashes

Hashes for fnug-0.1.0a8-py3-none-manylinux_2_28_aarch64.whl
Algorithm Hash digest
SHA256 1bbe7601d98fb408d44c308cdf17e492b114e8f2d3465ef364d28592f4261342
MD5 b0acff1758e477ea49dc4ca52a78387f
BLAKE2b-256 0b9858b5e741c372ab02a89422c9d3b243ef6b5a658b39f3b863eb2e07152e86

See more details on using hashes here.

File details

Details for the file fnug-0.1.0a8-py3-none-macosx_11_0_arm64.whl.

File metadata

File hashes

Hashes for fnug-0.1.0a8-py3-none-macosx_11_0_arm64.whl
Algorithm Hash digest
SHA256 b05901a2330d0b643d0d567f7f551d39a420b634841c9af5ef49498e19fe307c
MD5 1df3c59b66b5c0d96d257a1caff50bb6
BLAKE2b-256 8f4a99e059b49ba0998e632c7055831f55252e29d581d256136c22334be580c0

See more details on using hashes here.

File details

Details for the file fnug-0.1.0a8-py3-none-macosx_10_12_x86_64.whl.

File metadata

File hashes

Hashes for fnug-0.1.0a8-py3-none-macosx_10_12_x86_64.whl
Algorithm Hash digest
SHA256 ac80f29a58b9fc2792d9f543c01865fe13346b1d1a2e1d1ccf315f9ffd0def8a
MD5 74602dcb0f6bdf40d7b5509dc8e83092
BLAKE2b-256 8624ad2220a8fc4a70d5fa73f72973973d13de87e4ad294748630047001aaf47

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page