Ghost v3.3.0: TUI File Support
Ghost v3.3.0 adds file support to the TUI. :r <filepath> reads files into the conversation, vim-style.
A local, general-purpose AI assistant built in Go, powered by Ollama — inspired by cyberpunk worlds like Shadowrun, Cyberpunk 2077, and The Matrix.
Demo#

Handling Files In Command Mode#
Reading the file in isn’t much different than piping a file in the CLI. The trickier part was specifying the file to read from the TUI.
I updated the command handler to split on the first space to support arguments. :r /path/to/file loads file contents into the message history so the LLM has context. I’ll be able to add new commands that accept arguments easily.
case tea.KeyEnter:
parts := strings.SplitN(model.cmdBuffer, " ", 2)
cmd := parts[0]
var arg string
if len(parts) > 1 {
arg = strings.TrimSpace(parts[1])
}
switch cmd {
case "q":
model.logger.Info("disconnecting from ghost")
return model, tea.Quit
case "r":
if arg == "" {
model.chatHistory += fmt.Sprintf("\n[%s error: no file path provided]\n", theme.GlyphError)
model.viewport.SetContent(model.renderHistory())
model.mode = ModeNormal
model.cmdBuffer = ""
return model, nil
}
content, err := agent.ReadFileForContext(arg)
if err != nil {
model.logger.Error("file read failed", "path", arg, "error", err)
model.chatHistory += fmt.Sprintf("\n[%s error: %s]\n", theme.GlyphError, err.Error())
model.viewport.SetContent(model.renderHistory())
model.mode = ModeNormal
model.cmdBuffer = ""
return model, nil
}
model.messages = append(model.messages, llm.ChatMessage{Role: llm.RoleUser, Content: content})
model.logger.Info("file loaded into context", "path", arg)
model.chatHistory += fmt.Sprintf("\n[%s loaded: %s]\n", theme.GlyphInfo, arg)
model.viewport.SetContent(model.renderHistory())
}
model.mode = ModeNormal
model.cmdBuffer = ""
File contents get formatted as [FILE: path]\n{contents} and added as a user message. In the CLI I’m appending the contents to the user prompt which I want to go back and change it to this pattern to keep history clean.
What’s Next#
Image support in the TUI. The last piece needed for feature parity with non-interactive mode.
Check the release notes for the full changelog.