goose icon indicating copy to clipboard operation
goose copied to clipboard

goose tui

Open tlongwell-block opened this issue 1 month ago • 20 comments

This PR introduces a terminal user interface for Goose, along with a first-party Rust client library for goose-server.

TUI Features

A lightweight, keyboard-driven interface for Goose that runs entirely in your terminal:

  • Embedded server: No separate processes—goose-server runs in-process
  • Rich rendering: Markdown support with syntax-highlighted code blocks
  • Tool inspection: View available tools and their schemas. Create slash commands to run tools
  • Vim-style navigation: Normal/Editing/Visual modes with familiar keybindings
  • Session management: Resume previous conversations or start fresh. Support conversation forking.
  • Live configuration: Switch providers, models, and extensions without restarting
  • Smart context: Automatic project analysis on new sessions
  • Copy mode: Select text to copy with keyboard+mouse or copy entire message/tool response to clipboard
  • Themes: Beautiful built-in themes and support for custom themes defined in your goose config
  • Multiple modes: Full TUI, lightweight CLI mode, server only, or headless for automation

The TUI provides a fast, distraction-free way to interact with Goose for developers who prefer staying in the terminal.

goose-client

A reusable Rust client library for goose-server that provides:

  • Type-safe API bindings for all goose-server endpoints
  • SSE streaming for real-time message events
  • Async/await support with tokio
  • Minimal dependencies (reqwest, serde)

Having a first-party Rust client offers several benefits:

  1. Type safety: Compile-time guarantees that client/server contracts match
  2. Reference implementation: Demonstrates best practices for building goose-server clients
  3. Ecosystem growth: Makes it easier for Rust developers to build custom goose interfaces

The client is designed to be lightweight and focused—it handles HTTP communication and serialization, while leaving UI concerns to consumers like goose-tui.

goose_logo_tui tui_screen2 retro

tlongwell-block avatar Nov 20 '25 22:11 tlongwell-block

I love this. We need this @DOsinga !

michaelneale avatar Nov 21 '25 07:11 michaelneale

love this too. my one question is, do we want to do this in rust? I have two reasons why we should consider typescript. one, I think the TUI support in typescript is better and it is just quicker to develop. the other is that from a platform perspective it would just be neat to have two client implementations that both use the goosed protocol and show to the community how that works and invite them to build more.

DOsinga avatar Nov 21 '25 15:11 DOsinga

love this too. my one question is, do we want to do this in rust? I have two reasons why we should consider typescript. one, I think the TUI support in typescript is better and it is just quicker to develop. the other is that from a platform perspective it would just be neat to have two client implementations that both use the goosed protocol and show to the community how that works and invite them to build more.

This does use the goosed protocol (check out crates/goose-tui/src/client.rs)

And... I did look at typescript, too. But it is slightly messier. By using rust, we get to reuse a lot from the rest of goose, and embed goose-server directly without having to ship it as a separate file

ratatui is definitely not as easy to make aesthetic and responsive, though

tlongwell-block avatar Nov 21 '25 16:11 tlongwell-block

yeah building on goosed makes sense, but I didn think about a non rust one, it does mean more distirbution hassle but then developers only are using this, so yeah https://github.com/sst/opentui or even using the codex (opensource) code as a client could be doable (or adapting/lifting) - thoughts @tlongwell-block ? rattatui I always found challenging. I guess downside is people need node installed?

michaelneale avatar Nov 24 '25 00:11 michaelneale

yeah building on goosed makes sense, but I didn think about a non rust one, it does mean more distirbution hassle but then developers only are using this, so yeah https://github.com/sst/opentui or even using the codex (opensource) code as a client could be doable (or adapting/lifting) - thoughts @tlongwell-block ? rattatui I always found challenging. I guess downside is people need node installed?

I'm still playing with it right now, but I'm surprised at how nice it is. Will have a more informed opinion by the end of the day, I think.

Also, I think there's a really good opportunity here wrt code reuse. I'm going to refactor this a little today to make this work more easily accessible to other projects.

And isn't there something kind of romantic about rust?

tlongwell-block avatar Nov 24 '25 15:11 tlongwell-block

I broke the client bits into crates/goose-client

I think having a first party rust client that uses the actual structs/enums/etc from goose/goose-server adds a lot of value to the project. What do you think, @DOsinga?

tlongwell-block avatar Nov 24 '25 21:11 tlongwell-block

I am liking this more now - so the goose-client exists mostly to expose things, I wonder if we can simplify that (ie not have another module), also we could drop the main cli so that the goose-tui becomes the one goose binary (and perhaps we can unify the bianry so goose/goosed are same thing - just default is tui?)

Anyway, can dive into those details shortly - but so far looking good, and yeah, if we are to do a TUI, I think it makes sense to do it in rust @DOsinga for now, mostly as I looked around, didn't see any suitable ready to go TUIs in ts/js (certainly not that arent' really just libraries and would take a fair bit of work - but that may happen one day, but for now, its really just apis for TUIs no matter what, so ts, or rust, have to pick one?)

michaelneale avatar Dec 01 '25 06:12 michaelneale

using this as a daily:

image

not sure what causes it to keep that persistent message for "clippy" there? anytime it is working, the spinner is next to it (must be some most recent status message?)

(sorry for screen caps)

image

I guess that is showing a command, but not sure what is meant to be in body of the dev tool (is empty in that case)

michaelneale avatar Dec 01 '25 07:12 michaelneale

I am liking this more now - so the goose-client exists mostly to expose things, I wonder if we can simplify that (ie not have another module), also we could drop the main cli so that the goose-tui becomes the one goose binary (and perhaps we can unify the bianry so goose/goosed are same thing - just default is tui?)

We can absolutely move goose-client back into the tui crate. (That's how it was originally.)

Just a matter of taste. I thought it was independent enough to show a good example of a goose-server client, but it isn't particularly useful as its own crate.

tlongwell-block avatar Dec 01 '25 12:12 tlongwell-block

using this as a daily:

image not sure what causes it to keep that persistent message for "clippy" there? anytime it is working, the spinner is next to it (must be some most recent status message?)

That is the current item on the todo list goose is working on. Hit Ctrl+T to see the full list. I am going to improve its todo list usage a bit to make this status line more useful

image I guess that is showing a command, but not sure what is meant to be in body of the dev tool (is empty in that case)

The yellow line ( > developer__shell (args hidden)) is the tool call, which you can highlight and click (or hit Enter) on to view the full tool call.

The box below that is the tool response. In this case, it appears the tool didn't return any results

As a "goose power user", I wanted to be able to see both in full when I chose to

tlongwell-block avatar Dec 01 '25 12:12 tlongwell-block

@tlongwell-block ok that makes sense, as long as deliberate. I idd think it odd it kept that there, but that just means it is still in todo I guess? (which is odd itself, but not on the part of the TUI).

michaelneale avatar Dec 01 '25 22:12 michaelneale

I would love to see this in the goose-cli crate, vs goose-tui - if it was up to me? (I wouldn't want to keep old CLI as well as this, but maybe it is a cut over? but don't want to maintain 2)

michaelneale avatar Dec 01 '25 22:12 michaelneale

cc @jamadeo @DOsinga would love your take, would really like this to be default goose command vs goose-tui I think (and we still have to support recipes, run and all the other cli constructs somehow) and then eventually retire the old goose-cli code? (and could also perhaps combine some of this with goose-server?) but could be in a phased approach (the way it is now, is a new binary, which means people wont' really discover or use it)

michaelneale avatar Dec 02 '25 00:12 michaelneale

cc @jamadeo @DOsinga would love your take, would really like this to be default goose command vs goose-tui I think (and we still have to support recipes, run and all the other cli constructs somehow) and then eventually retire the old goose-cli code? (and could also perhaps combine some of this with goose-server?) but could be in a phased approach (the way it is now, is a new binary, which means people wont' really discover or use it)

yeah, I'm all for thinking ahead and the CLI is a bit old in tooth. but then again, I am not sure that doing product development by PR is the right way in this case. Personally I don't think Rust would be my first choice for a user interface, whether GUI or TUI. I know a lot of work went into this already, but would it be an idea to take a step back and post a discussion about where we want to go with this first?

DOsinga avatar Dec 02 '25 18:12 DOsinga

yeah, I'm all for thinking ahead and the CLI is a bit old in tooth. but then again, I am not sure that doing product development by PR is the right way in this case. Personally I don't think Rust would be my first choice for a user interface, whether GUI or TUI. I know a lot of work went into this already, but would it be an idea to take a step back and post a discussion about where we want to go with this first?

I thought the exact same thing wrt rust for frontend work. I did full working mockups in ink and ratatui. Besides some initial teething issues, I ended up greatly preferring ratatui and the ability to pull in from the goose codebase directly where needed.

I don't know how folks feel about a TUI for goose in general, though. It may not be the right direction.

I ended up working on this after spending a lot of time with gemini-cli TUI in order to test gemini 3 and found there were strong points that I wanted in my goose experience that I couldn't get with the goose cli.

tlongwell-block avatar Dec 02 '25 20:12 tlongwell-block

@DOsinga @tlongwell-block I'm not sure practically how a TUI which is not in rust would work with goose - would mean need to install goose via npm (for example) instead of a monolithic binary as of now (pros/cons?) - and doesn't there always need to be a "cli" like experience in goose (and the cli is getting a little dated) anyway? Disagree that this a bad way to explore "product by PR" in this specific case (well assuming it isn't backbraking manual! sorry if it was @tlongwell-block!) - I tried to find other TUIs I liked and other than actually driving it, it is hard to try them out. There really isn't a way to mock/design things like this other than trying it out IMO.

could move this to a discussion to continue?

  • do we want TUI at all - is it a passing fashion?
  • do it in rust, or bring along another dependency if people want cli
  • update cli in place
  • whether GUI or TUI: I wouldn't at all group those together for chosing rust or not (I am thinking just replacement for goose-cli but perhaps others have bigger things in mind?)

  • move to the @goose terminal enhancement and deprecate goose-cli crate (!)

many good options (I will open this as a discussion, seems mixed engagement there but it is picking up).

michaelneale avatar Dec 03 '25 05:12 michaelneale

Chatting in https://github.com/block/goose/discussions/5958

tlongwell-block avatar Dec 03 '25 12:12 tlongwell-block

Tested locally and works well! UI looks really good also.

I'm not too familiar with TUIs so a couple things that stick out to me:

  1. mouse support for highlighting and copying text would be nice
  2. it pops the message details everywhere I click with the mouse which feels a bit strange/annoying to me, maybe the click trigger could be localized to the message itself or an icon at the top for more details?

zanesq avatar Dec 15 '25 18:12 zanesq

Tested locally and works well! UI looks really good also.

I'm not too familiar with TUIs so a couple things that stick out to me:

  1. mouse support for highlighting and copying text would be nice
  2. it pops the message details everywhere I click with the mouse which feels a bit strange/annoying to me, maybe the click trigger could be localized to the message itself or an icon at the top for more details?

Thanks for testing this out!

Mouse support is there, but requires hitting Ctrl+S to shift into copy mode first. Aside from that, pressing 'c' when viewing the details popup on a message lets you copy the whole message. This setup is at par with other TUIs afaik, but I am still working on making this better. It should be easier.

Yes, I can see that clicking behavior not making sense. It's doing the same thing as enter and opening the highlighted message (which is normally the last one unless you scroll back). Let me fix this. No one would think clicking would open the highlighted message instead of whatever they're clicking on.

tlongwell-block avatar Dec 15 '25 19:12 tlongwell-block

Something else to think about here: since this is a pure rust implementation, we are able to bundle the actual goose-server for the TUI to use.

Which means we don't need to build a separate goose-server binary to ship with the desktop UI if we adopt the TUI.

The TUI binary can do goose-tui server already to run goose-server without a UI, which the desktop app can use.

So... anyone who would install the desktop UI gets a TUI for free, essentially. With very little added weight to the distribution.

tlongwell-block avatar Dec 17 '25 13:12 tlongwell-block