Generated: 2026-04-08
Last Updated: 2026-04-08
The MUXI CLI is a Go command-line client for local development, remote formation management, and interactive chat against the MUXI runtime and MUXI server. It has two distinct network surfaces: the server management API (HMAC-authenticated /rpc/* endpoints) and proxied formation APIs (client/admin key headers for /v1/* runtime endpoints). The codebase is organized around Cobra commands in src/cmd/ and thin service clients/helpers in src/pkg/.
CLI command (Cobra)
├─ pkg/server -> talks to muxi-server over HMAC `/rpc/*`
├─ pkg/formation -> talks to formation runtime `/v1/*`
├─ pkg/chat -> interactive Bubble Tea chat TUI
├─ pkg/ui -> shared terminal styling/output
├─ pkg/context -> formation/project detection
├─ pkg/defaults -> local defaults/config under ~/.muxi
└─ pkg/secrets -> encrypted local secret handling
src/cmd/— user-facing commands, flag parsing, command flow orchestrationsrc/pkg/server/— MUXI server client, HMAC signing, deploy/start/restart SSE handlingsrc/pkg/formation/— formation API client, chat/memory/MCP/session/runtime helperssrc/pkg/chat/— Bubble Tea TUI formuxi chat, streaming event handling, session UXsrc/pkg/ui/— error blocks, badges, formatting helpers, consistent terminal output
src/cmd/— Cobra command implementations (chat.go,deploy.go,profiles.go, etc.)src/pkg/chat/— interactive chat model and stream parsingsrc/pkg/formation/— runtime API client and response typessrc/pkg/server/— remote server client and deploy/start/restart SSE parsersrc/pkg/scaffold/,src/pkg/validate/— local project creation and validationcontributing/— CLI-specific architecture, API, and UX conventionsCHANGELOG.md— release history for shipped CLI behavior
cmd/* -> pkg/server.Client -> HMAC-authenticated /rpc/* request
-> optional SSE stream parser for deploy/start/restart/rollback
-> ui formatting / command result
cmd/chat.go -> pkg/formation.Client.ChatStream()
-> runtime /v1/chat SSE stream
-> pkg/chat.StreamChatEvents()
-> spinner / response rendering
cmd/chat.go -> pkg/chat.Run()
-> Bubble Tea model in pkg/chat/chat.go
-> pkg/formation.Client.ChatStream()
-> processStreamWithEvents()
-> StreamEvent channel -> TUI state updates
- Commands live in
src/cmd/; transport and shared logic live insrc/pkg/ - Use
ui.*helpers for terminal output instead of ad hoc printing where possible - Interactive chat intentionally runs inline (no alt screen) so scrollback is preserved
- The CLI uses two auth models:
- HMAC for server
/rpc/* X-MUXI-CLIENT-KEY/X-MUXI-ADMIN-KEY(+X-Muxi-User-ID) for formation APIs
- HMAC for server
- Build and test from
src/:go build ./...go test ./...
- Cobra for command structure
- Bubble Tea / Bubbles / Lip Gloss / Glamour for TUI and formatted chat output
- Standard
net/httpclients for both server and formation APIs - Local state under
~/.muxi/for profiles, defaults, server credentials, and related config
- The CLI has separate SSE implementations:
pkg/server/client.gofor deploy/start/restart flows- chat-specific parsing in
pkg/chat//cmd/chat.goThese paths can drift if not kept aligned.
- Formation chat streaming uses a dedicated
streamClientinpkg/formation/client.gowithTimeout: 0; if chat times out, the bug is often above the HTTP transport layer. - The interactive chat TUI waits on parsed
StreamEvents, not raw socket bytes. If the parser drops valid SSE traffic, the UI can show a timeout even while the connection is still alive. pkg/chat/chat.gostill contains older stream helpers (processStream) that are not the main interactive path; check actual call sites before changing parser behavior.
- Runtime
/v1/chatnow sends SSE comment frames like: keepaliveduring slow setup and between token gaps. muxi chatstill timed out because the TUI's 60-second wait was based on parsedStreamEvents, not on raw SSE activity.- Fix pattern:
- parse SSE by event blocks (preserve
event:until blank line) - treat comment frames as heartbeat/liveness
- surface route-level
event: errorpayloads - be tolerant of newer runtime token/event shapes instead of assuming a tiny allowlist
- parse SSE by event blocks (preserve
- The one-shot and interactive chat flows had duplicated SSE parsing logic with slightly different assumptions.
- A shared chat stream parser in
pkg/chat/is the safer place for runtime-specific SSE semantics, while command/TUI layers should focus on presentation.