muffintui 0.1.12

A terminal workspace that combines a file tree, editor, shell, and embedded Codex pane
Documentation

muffintui

muffintui is the crates.io package for a Rust terminal workspace that runs as the muffin command. It is designed to keep file navigation, shell work, and AI-assisted workflows in one terminal UI.

muffin TUI screenshot

It gives you four panes inside a project directory:

  • Files
  • File Viewer / Diff Viewer
  • Terminal
  • Shell / Codex / Claude

It starts in the current working directory and uses that directory as:

  • the root of the file tree
  • the working directory for shell commands
  • the working directory for the right-hand interactive session

Requirements

  • Rust and Cargo
  • codex on PATH if you want --codex
  • claude on PATH if you want --claude
  • ngrok on PATH if you want remote share

Setup Prerequisites

1. Install Rust and Cargo

If rustc and cargo are not installed yet, install them with rustup:

curl https://sh.rustup.rs -sSf | sh

After installation, restart your shell or load Cargo's environment:

source "$HOME/.cargo/env"

Verify the installation:

rustc --version
cargo --version

2. Install optional right-pane CLIs

By default, muffin starts a shell in the right pane.

If you want to start directly in Codex mode, verify that codex is available:

codex --version

If needed, authenticate it:

codex login

If you want to start directly in Claude mode, verify that claude is available:

claude --version

3. Set up ngrok for remote share

Remote share uses ngrok to publish a temporary HTTPS URL for the local remote-control page.

Install ngrok first. On macOS with Homebrew:

brew install ngrok/ngrok/ngrok

Then authenticate it with your ngrok account authtoken:

ngrok config add-authtoken YOUR_AUTHTOKEN

Verify that the CLI is installed and the config is valid:

ngrok version
ngrok config check

Notes:

  • muffin starts ngrok http 127.0.0.1:<port> when you enable remote share.
  • The app also reads the local ngrok API on 127.0.0.1:4040 to discover the public URL.
  • If ngrok is installed but not authenticated, remote share will fail to start.

4. Sanity check

Before installing or running muffin, this should work:

cargo --version

Install

Install from crates.io:

cargo install muffintui

This installs the executable as:

muffin

Install from the local checkout:

cargo install --path .

That local install also provides the muffin executable.

Run

Launch in the current directory:

muffin

Use muffin --help to list available startup flags.

Launch with Codex in the right pane:

muffin --codex

Launch with Claude in the right pane:

muffin --claude

Launch against another project:

cd /path/to/project
muffin

Run without installing during local development:

cargo run

Pass startup flags through Cargo with an extra --:

cargo run -- --codex
cargo run -- --claude

What It Does

  • Shows a navigable file tree rooted at the current directory
  • Highlights updated files and changed directories in the Files pane using the active theme
  • Opens the selected file in a read-only file viewer
  • Highlights source code in normal file view with theme-aware colors
  • Toggles a diff viewer against HEAD~1
  • Runs shell commands inside the built-in terminal pane with sh -lc
  • Starts the right pane as a shell by default
  • Can start the right pane with codex or claude
  • Can expose the right pane through a temporary ngrok URL for phone viewing and limited remote control
  • Cycles between three built-in themes
  • Ships with integration tests under tests/

Notes:

  • .git and target are intentionally hidden from the file tree
  • The built-in terminal pane starts empty
  • Diff mode falls back to a message when the repository has no HEAD~1
  • If the initial right-pane launch fails, pressing Enter in that pane retries the same mode
  • If a codex or claude session exits, the app automatically switches that pane back to a shell
  • If codex or claude is not installed, the rest of the TUI still works and the right pane shows the startup error
  • Remote share mirrors only the right pane session, not the full TUI
  • Remote share depends on ngrok being installed, logged in, and able to publish a tunnel

Remote Share

Remote share lets you open the active right pane on your phone through a temporary ngrok URL. It is intended for lightweight approval and interruption flows while a shell, Codex, or Claude session is running.

How to start it

  1. Launch muffin.
  2. Move focus to the right pane.
  3. Press Ctrl+R.
  4. Scan the QR code overlay, or open the printed ngrok URL manually.

When remote share starts, muffin:

  • starts a local HTTP server on an ephemeral port
  • starts ngrok http 127.0.0.1:<port>
  • prints the public URL in the terminal pane
  • shows a QR overlay in the TUI
  • writes a QR SVG to your temp directory

The overlay can be dismissed with Esc. This only closes the overlay. The remote share session keeps running until you press Ctrl+R again in the right pane.

What the phone page can do

The mobile page polls the active right pane and shows:

  • the current session mode
  • the current right-pane status line
  • a recent text snapshot of the right pane output

It also exposes four actions:

  • Approve / Enter: sends Enter
  • Send y: sends y
  • Send n: sends n
  • Ctrl+C: interrupts the active right-pane session

This is enough for common remote approval prompts, continuing a command, rejecting a prompt, or interrupting a long-running session.

Limits and behavior

  • Remote share only works while there is a live right-pane session to control.
  • If no live session exists, remote actions are ignored.
  • The shared page is text-only and optimized for phone-sized screens.
  • The page refreshes automatically on an interval, so it is a near-live mirror rather than a full interactive terminal.
  • The shared URL includes a random token and is scoped to the current app session.
  • Stopping remote share kills the ngrok tunnel.

Troubleshooting

If Ctrl+R fails to start remote share, check the terminal pane for the exact error. Common causes:

  • ngrok is not installed
  • ngrok is installed but not authenticated
  • ngrok could not publish a public URL within the startup timeout
  • local access to the ngrok API on 127.0.0.1:4040 is unavailable

Keybindings

Global

  • Tab: move focus to the next pane
  • Shift+Tab: cycle the theme
  • Esc: quit
  • Ctrl+C: quit when focus is not in the Codex pane

Files Pane

  • Up or k: move selection up
  • Down or j: move selection down
  • Enter on a directory: expand or collapse it
  • Enter on a file: open it in the file viewer

Notes:

  • Files with git changes are highlighted
  • Directories are highlighted when they contain changed files

File Viewer / Diff Viewer

  • Ctrl+D: toggle between file view and diff view
  • PageUp: scroll up
  • PageDown: scroll down

Terminal Pane

  • Type directly into the prompt
  • Enter: run the current command
  • Backspace: delete one character
  • PageUp: scroll back
  • PageDown: scroll forward
  • Home: jump to the oldest visible terminal history
  • End: jump back to the live prompt

Right Pane

  • Regular typing: send input to the active shell, Codex, or Claude session
  • Enter: submit input, or retry the session if startup failed
  • Ctrl+C: send interrupt to the active right-pane session
  • Ctrl+R: start or stop remote share
  • Arrow keys, PageUp, PageDown, Home, End, Tab, Backspace: forwarded to the embedded session

Publish

Before publishing:

cargo package

Then publish:

cargo publish

Contributions and issue reports are welcome.

Test

Run the integration test suite with:

cargo test