Stave is a Go UI framework for applications that people and agents can use through the same interface. Build a semantic tree of text, controls, and actions, then expose it through a terminal UI, plain output, or an agent API.
- Shared human and agent controls. Keyboard input and agent requests use the same semantic tree and typed action registry.
- Your application's identity. Supply your own model, theme, glyphs, labels, and keymaps without changing what the UI elements mean.
- Output for different environments. Support colour terminals, monochrome, ASCII, narrow layouts, and non-interactive output.
- Repeatable snapshots. Stable node identities and deterministic encodings make UI state available for tests and automation.
- Go-only core. The root module has no dependencies outside the standard library.
Use Stave when a Go application needs both an interactive interface and structured access for automation. Its primitives describe roles, values, state, and available actions; renderers turn that description into output. Your application owns its business logic and effects, while Stave supplies layout, rendering, sessions, and runtime contracts.
Stave is created by Ben Ranford and is MIT licensed.
Requires Go 1.22 or later. In your Go module, install the release candidate:
go get github.com/ben-ranford/stave@v1.0.0-rc.2Stave has not reached general availability. Promotion requires published, immutable Lopper proving-client evidence for parity and rollback. The SSH, Bubble Tea, and Lip Gloss adapters remain internal until they have independent module versions and tags; begin with the root module. See the compatibility policy and security contract before integrating consequential agent actions.
In an empty directory, run go mod init example.com/hello-stave, then use the
installation command above. Save the following as main.go and run go run ..
It creates a text node and reads its role and value from a semantic tree:
package main
import (
"fmt"
"github.com/ben-ranford/stave/primitive"
"github.com/ben-ranford/stave/semantic"
)
func main() {
node, err := primitive.Text(primitive.Options{
Namespace: "hello",
View: "main",
Entity: "welcome",
Name: "Welcome",
}, "Hello, Stave!")
if err != nil {
panic(err)
}
tree, err := semantic.NewTree(1, node)
if err != nil {
panic(err)
}
fmt.Printf("%s: %s\n", tree.Root().Role(), tree.Root().Value().Text)
}text: Hello, Stave!
This example needs no terminal renderer. To add application state, actions, and human or agent runtimes, continue with the adoption guide.
- Adoption guide: build an application and validate its integration.
- UI primitives: compose text, tables, forms, progress, and overlays.
- Accessibility and agent control: node metadata, keyboard paths, and action policies.
- Compatibility: versioned APIs, schemas, and breaking changes.
- Security: authority, confirmation, and secret handling.
- Go reference: package and API documentation.
Report bugs or propose features through GitHub issues. Include the Go version, Stave tag or commit, and a small reproduction for bugs. For security reports, follow SECURITY.md.
Start with CONTRIBUTING.md for development prerequisites and verification commands. See the support guide for request routing and the release runbook for maintainer procedures.