Glint is a terminal-native workspace switcher and agent sidebar written in Go with Bubble Tea. It scans your local project roots, correlates them with tmux/Zellij sessions and agent lifecycle state, and gives you a fast keyboard UI for jumping between projects, worktrees, and running agent chats.
This is still a prototype. tmux and Zellij are both actionable backends; the tmux-only shelf remains the main feature not yet mirrored in Zellij.
# run from source
go run ./cmd/glint
# build a local binary
make build
./bin/glint
# or install to GOPATH/bin
go install ./cmd/glintUseful development commands:
make run # go run ./cmd/glint
make test # go test ./...
make fmt # gofmt -w .glint # full-screen workspace UI
glint sidebar # same UI, marked as the Glint sidebar pane inside tmux/Zellij
glint attach # create a tmux/Zellij sidebar split running `glint sidebar`
glint popup [options] # open the command palette in a tmux popup or Zellij floating pane
glint palette [options] # run only the command palette
glint hook ... # record an agent lifecycle event
glint events [limit] # print recent recorded hook events
glint hooks install pi # install the Pi extension that emits hook events
glint hooks uninstall pi # remove the Pi extension
glint pty start --id ID -- COMMAND ... # experimental native PTY session
glint pty attach ID # attach to an experimental native PTY session
glint pty detach ID # close attach clients without killing the PTY session
glint pty pane --name main # run a remotely switchable attach pane
glint pty switch --pane main ID # point that pane at a PTY session
glint pty list # list experimental native PTY sessions
glint debug data # dump scanned config/session/workspace data as JSONPalette options include --movement, --local, --global, --no-agents, --no-actions, --no-workspaces, --no-create, --no-cleanup, and --agents-only.
Glint works best from inside tmux or Zellij. Mouse support in tmux is optional, but if you want to use it enable:
tmux set -g mouse onStart a persistent sidebar:
glint attachOr manually split a pane:
tmux split-window -h -l 36 'glint sidebar'
zellij action new-pane --direction right --name glint-sidebar -- glint sidebarGlint includes an MVP native PTY daemon for detachable terminal-native agent processes without a tmux shelf session. It is not wired into the main UI yet.
# start a detached PTY session; the daemon autostarts on first use
glint pty start --id claude-demo --cwd "$PWD" -- claude
# attach from any terminal/tmux/zellij pane
glint pty attach claude-demo
# or run a pane that can be controlled from another terminal
# terminal A:
glint pty pane --name main --session claude-demo
# terminal B:
glint pty switch --pane main other-agent
# detach from the attach client without stopping the agent: Ctrl-]
glint pty list
glint pty detach claude-demo # close any current attach clients without killing it
glint pty kill claude-demoThe daemon listens on $GLINT_PTYD_SOCKET, or $XDG_RUNTIME_DIR/glint/ptyd.sock, or /tmp/glint-$UID/ptyd.sock.
In the tmux or Zellij sidebar, n starts the configured agent command in a native Glint PTY session and opens/reuses a remotely switchable glint pty pane. When the agent process exits, that viewer pane execs back into your login shell and stops being Glint-managed.
Glint reads JSON config from:
~/.config/glint/config.json
If the file is missing, defaults are:
{
"workspace_roots": ["."],
"theme": "auto",
"spinner": "points"
}Example:
{
"workspace_roots": [
"~/Documents/dev",
"~/work"
],
"theme": "kanagawa",
"spinner": "moon"
}Supported themes: auto, dark, light, dracula, catppuccin/mocha, and kanagawa/wave.
Supported spinners: points, dot, minidot, line, jump, pulse, meter, hamburger, ellipsis, globe, moon, and monkey.
Environment overrides:
GLINT_SPINNER=moon glint
GLINT_AGENT_COMMAND=claude glint attach # command used by the "new chat" action; default is pi
GLINT_OPENCODE_BIN=/path/to/opencode # optional fallback for OpenCode history discovery
GLINT_OPENCODE_DB=/path/to/opencode.db # optional override for the OpenCode SQLite database
GLINT_T3_DB=/path/to/state.sqlite # optional override for T3 Code thread-name lookup
GLINT_BIN=/path/to/glint glint hooks install piMain UI:
↑/↓orj/k: move selection/: search/filter workspaces and agentsEnter: switch to an existing tmux/Zellij session or create one for the selected workspacectrl+p: command palettectrl+w: create/switch VCS worktree or jj workspacectrl+r: cleanup/remove a worktree or jj workspacectrl+x: delete the matching tmux/Zellij session/workspace flow for the selectionn: start a new agent chat in the sidebar main pane (GLINT_AGENT_COMMAND, defaultpi)b: shelve the current main pane or selected live agent pane into Glint's tmux shelf (tmux only)c,space, ortab: collapse/expand visible agent entries[/]orh/l: jump between top-level projectss: cycle spinner styleq,esc, orctrl+c: quit
Palette:
- type to filter
↑/↓orj/k: moveEnter: run/open selected targetTab/h/l: toggle local/global orderingctrl+d/ctrl+x: cleanup selected workspaceEsc: close
Glint can record reliable agent lifecycle events from shell hooks, plugins, or extensions. Events are written to:
~/.local/state/glint/agents/events.jsonl
~/.local/state/glint/agents/latest.json
Manual examples:
# Mark an agent turn as running. JSON on stdin is optional but useful.
printf '{"session_id":"abc","cwd":"%s","prompt":"Refactor auth"}' "$PWD" \
| glint hook pi prompt-submit
# Mark that same turn as complete.
printf '{"session_id":"abc","cwd":"%s","last_assistant_message":"Done"}' "$PWD" \
| glint hook pi stop
# Inspect recent recorded lifecycle events.
glint events 20Supported event/status signals include session-start, prompt-submit, stop, session-end, notification, permissionrequest, busy, idle, and error.
glint hook claude notification \
--workspace "$PWD" \
--session claude-123 \
--status needs_attention \
--task "Approve shell command"Install the Pi extension after building/installing glint:
# install glint on PATH, then install the Pi extension
go install ./cmd/glint
glint hooks install pi
# or use an explicit binary path
go build -o ./bin/glint ./cmd/glint
./bin/glint hooks install pi --bin "$PWD/bin/glint"Then restart Pi or run /reload inside Pi. The installer writes glint-session.ts under Pi's extension directory ($PI_CODING_AGENT_DIR/extensions or ~/.pi/agent/extensions).
Currently only the Pi hook installer exists. Manual glint hook <agent> <event> calls can record other agent names.
- tmux, zellij, or plain terminal environment; tmux and Zellij support session/pane actions.
- Directories under configured workspace roots.
- Git repositories/worktrees and Jujutsu (
jj) repos/workspaces, grouped under their parent project. - tmux/Zellij sessions by name and current path where available, including sessions outside configured workspace roots.
- Live tmux/Zellij panes for known agent programs (Pi, Claude, Codex, Aider, OpenCode, Goose) when they can be matched to hook/history records.
- Pi persisted session history under
~/.pi/agent/sessions. - OpenCode persisted sessions from
~/.local/share/opencode/opencode.dboropencode session list --format json, with T3 Code thread titles resolved from~/.t3/userdata/state.sqlitewhen available. - Hook-recorded agent status, merged with multiplexer pane metadata when available.
Workspaces are sorted with active multiplexer sessions first, then by recent project/agent activity.
glint debug data --timing > glint-debug.json
go run ./cmd/glint-perf -n 5Use --debug or -d before a command to enable internal debug logging where available:
glint --debug- Zellij does not yet mirror the tmux shelf workflow.
- Automatic hook installers only exist for Pi.
- Agent command configuration is currently via
GLINT_AGENT_COMMAND, not the JSON config file. - Historical session scanning covers Pi and OpenCode; other agents need hooks or live multiplexer correlation for reliable status.