DEV Community

Cover image for peektea v2: yesterday it peeked, today it actually opens things
Athreya aka Maneshwar
Athreya aka Maneshwar

Posted on

peektea v2: yesterday it peeked, today it actually opens things

Hello, I'm Maneshwar. I'm building git-lrc, a Micro AI code reviewer that runs on every commit. It is free and source-available on Github. Star git-lrc to help devs discover the project. Do give it a try and share your feedback.


Yesterday I shipped peektea, a tiny terminal file browser in Go.

It browsed.

It peeked.

And then it just... stood there, staring at your files, unable to do anything with them. All peek, no pour.

Like a golden retriever that fetches the ball and won't drop it.

Today that changes. peektea can now:

  • open files in your configured editor, image viewer, file manager, whatever you set up
  • detect your installed software and walk you through setup with peektea init
  • tell you what it can do with peektea -h
  • uninstall itself cleanly with peektea uninstall (and ask nicely if you want your config deleted too)

Here's the whole brew in action:

The demo GIF isn't rendering here on dev.to for some reason :(
You can watch it on GitHub instead: lovestaco/peektea#demo

The config problem (or: how do you take your tea?)

The moment you add "open files" to a file browser, you hit a question: open them how?

.md files want vim.

.png wants an image viewer.

A directory wants a file manager.

And everyone's machine is different, you might have thunar, I might have nautilus, someone else is running dolphin and judging us both.

So peektea reads ~/.peektea.toml.

The keys are derived straight from the file extension:

file.md        → _md_config
archive.tar.gz → _tar_gz_config
hello.xd.dd    → _xd_dd_config
directory      → _dir_config
Enter fullscreen mode Exit fullscreen mode

Dots become underscores, wrapped with _ and _config. The whole config is one flat file:

image

Unknown extension?

Falls through to _default_config.

Completely missing key?

Falls through to vim. The bag never comes up empty.

You can configure literally any extension, including made-up ones like _xd_dd_config for hello.xd.dd.

The lookup is fully generalised. No extension is too obscure to brew.

peektea init: it takes a peek at your system first

Writing that config by hand is annoying.

So peektea init does it for you.

It scans your $PATH, finds what's actually installed, and asks you to pick:

peektea init

If there's only one option for a category it auto-selects it and moves on.

If there are multiple, you get a picker — arrow keys or just type the number and it jumps immediately. Pick your poison, or your potion.

The whole wizard is a Bubble Tea program running inside a CLI command. (Yes, the puns write themselves here.)

That last part is the interesting bit.

The picker isn't a plain stdin readline, it's a full tea.Model:

type pickerModel struct {
    options []string
    cursor  int
}

func (m pickerModel) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
    switch msg := msg.(type) {
    case tea.KeyMsg:
        switch msg.String() {
        case "up", "k":
            if m.cursor > 0 { m.cursor-- }
        case "down", "j":
            if m.cursor < len(m.options)-1 { m.cursor++ }
        case "enter", " ":
            return m, tea.Quit
        default:
            // type a number → jump and confirm immediately
            if n, err := strconv.Atoi(msg.String()); err == nil && n >= 1 && n <= len(m.options) {
                m.cursor = n - 1
                return m, tea.Quit
            }
        }
    }
    return m, nil
}
Enter fullscreen mode Exit fullscreen mode

tea.NewProgram(pickerModel{options: found}).Run() — that's the whole pot.

You get a full keyboard-driven selector inside what looks like a plain terminal prompt.

Bubble Tea handles all the rendering and input, you just describe the model and let it steep.

Opening files: the terminal vs GUI problem

The o key opens whatever's under the cursor. One keystroke and you're peeking inside.

Simple enough, except there's a catch in the kettle.

For terminal editors like vim, you want to hand the terminal over completely.

Vim needs raw input, it needs to own the screen - the whole table, not just a saucer.

The right Bubble Tea API for this is tea.ExecProcess:

cmd := exec.Command(prog, path)
return m, tea.ExecProcess(cmd, func(err error) tea.Msg {
    return openResultMsg{err: err}
})
Enter fullscreen mode Exit fullscreen mode

tea.ExecProcess suspends the Bubble Tea event loop, gives the child process the full terminal, and resumes peektea when you quit.

It's the same trick that lets you run vim from inside ranger or lf.

For GUI apps like nautilus or feh, you do the opposite, launch them in the background and keep the TUI brewing:

cmd := exec.Command(prog, path)
cmd.Start()
go cmd.Wait() // reap the child so it doesn't become a zombie
Enter fullscreen mode Exit fullscreen mode

But how does peektea know which is which?

It keeps a set of known terminal programs like vim, nvim, nano, micro, helix, etc. and anything not in that set gets backgrounded.

You can extend it in your config:

terminal_programs = ["vim", "nvim", "nano", "hx"]
Enter fullscreen mode Exit fullscreen mode

peektea -h

Every proper CLI tool deserves a -h. Consider it the menu before you order.

Here's what it looks like now:

peektea help

And yes, peektea uninstall exists.

It finds the binary via os.Executable(), tells you exactly what it's about to delete, asks for confirmation, and then asks separately if you want the config gone too.

No silent nuke. No tea spilled without warning.

What's next

The original dream was ncdu-style navigation with inline image previews in the terminal. A proper sneak peek, right in the pane.

That's still where this is headed:

  • Image previews inline — render images in the terminal via Kitty/iTerm protocols or chafa
  • Split-pane file preview — selected file content on the right, so you can peek without leaving
  • Filter as you type — Bubble Tea ships a textinput component in bubbles for exactly this
  • Hidden file toggle — show/hide dotfiles for the leaves that like to lurk

The model grows, Update handles new keys, View renders the new state.

That's the whole Bubble Tea pattern. It scales surprisingly cleanly and the puns never run dry.


AI agents write code fast. They also silently remove logic, change behavior, and introduce bugs — without telling you. You often find out in production.

git-lrc fixes this. It hooks into git commit and reviews every diff before it lands. 60-second setup. Completely free.

Any feedback or contributors are welcome! It's online, source-available, and ready for anyone to use.

⭐ Star it on GitHub:

GitHub logo HexmosTech / git-lrc

Free, Micro AI Code Reviews That Run on Commit




AI agents write code fast. They also silently remove logic, change behavior, and introduce bugs -- without telling you. You often find out in production.

git-lrc fixes this. It hooks into git commit and reviews every diff before it lands. 60-second setup. Completely free.

See It In Action

See git-lrc catch serious security issues such as leaked credentials, expensive cloud operations, and sensitive material in log statements

git-lrc-intro-60s.mp4

Why

  • 🤖 AI agents silently break things. Code removed. Logic changed. Edge cases gone. You won't notice until production.
  • 🔍 Catch it before it ships. AI-powered inline comments show you exactly what changed and what looks wrong.
  • 🔁 Build a

Top comments (0)