Skip to content

feat(tui): add Bubble Tea interface with provider setup - #941

Open
kusonooyasumi wants to merge 54 commits into
usestrix:mainfrom
kusonooyasumi:feat/go-tui-provider-setup
Open

feat(tui): add Bubble Tea interface with provider setup#941
kusonooyasumi wants to merge 54 commits into
usestrix:mainfrom
kusonooyasumi:feat/go-tui-provider-setup

Conversation

@kusonooyasumi

@kusonooyasumi kusonooyasumi commented Jul 30, 2026

Copy link
Copy Markdown
Contributor

Summary

  • add a Bubble Tea TUI with protocol-v3 Python IPC for setup, live scan state, agent navigation, steering, findings, and completion views
  • add provider/model discovery and persisted setup for API-key, ambient-cloud, local, ChatGPT subscription, and custom OpenAI-compatible routes
  • add setup commands for budgets, turn limits, code scope, mounts, target-list files, and prompt files
  • route credentials, endpoints, and custom headers per model without exposing secrets to the Go sidecar or reusing them across providers
  • package platform-specific strix-tui sidecars in release wheels and frozen builds, with a safe Textual fallback for prepared scans
  • document the TUI protocol, provider configuration, build flow, and source-wheel behavior

Behavior

  • interactive scans prefer the Go TUI; STRIX_TEXTUAL_TUI=1 keeps the legacy Textual scan interface
  • targetless first-run provider/model/target setup requires the Go sidecar
  • source distributions and universal wheels remain sidecar-free and support prepared scans through Textual
  • provider credentials and selected models are persisted in the active Strix config with 0600 permissions
  • the model picker lists configured providers, passively detected AWS/Vertex credentials, and the explicitly selected ambient route; unselected implicit LiteLLM/local routes are hidden
  • /budget, /turns, /scope, /mount, /target-list, and /prompt-file configure fresh runs before scan preparation
  • current main support for custom request headers, non-streaming gateways, ChatGPT lookup safety, and structured provider refusals is preserved with route isolation
  • mouse interaction remains enabled for provider and model selection, scrolling, modals, and navigation

Scope

This PR is intentionally limited to the Go TUI, its Python backend, provider/model setup, startup integration, packaging, documentation, and directly required compatibility changes. It does not include the broader engine lifecycle, report transaction, compaction, dedupe, or workspace-hardening changes from the development branch.

Verification

  • uv run pytest (889 passed)
  • expanded scoped ruff check and ruff format --check
  • scoped mypy
  • go vet ./...
  • go test -race ./...
  • gofmt clean
  • built and inspected a sidecar-free source/universal wheel
  • built, installed, and protocol-smoke-tested a strict Linux platform wheel with the setup-run-controls capability

@kusonooyasumi
kusonooyasumi marked this pull request as ready for review July 30, 2026 21:47
@greptile-apps

greptile-apps Bot commented Jul 30, 2026

Copy link
Copy Markdown
Contributor

Greptile Summary

Adds a platform-packaged Bubble Tea interface and its Python protocol-v3 backend.

  • Adds interactive provider/model discovery, credential persistence, custom provider routes, and fresh-run setup controls.
  • Integrates the Go sidecar into CLI startup with pre-activation Textual fallback for prepared scans.
  • Adds platform-specific wheel and frozen-build packaging, release validation, and Python/Go CI coverage.
  • Documents provider configuration, TUI behavior and protocol, setup commands, and source-package limitations.

Confidence Score: 5/5

The PR appears safe to merge, with no concrete changed-code-triggered failures identified.

Provider mutations invalidate cached settings, setup validation and model preflight reroute credentials before scan startup, and the runner refreshes model configuration again before execution; the packaging and protocol paths also include platform and handshake validation.

Important Files Changed

Filename Overview
strix/interface/go_tui.py Implements sidecar activation, setup-to-scan handoff, protocol synchronization, and pre-activation fallback behavior.
strix/interface/tui_backend/controller.py Implements protocol command dispatch, setup validation, provider/model selection, run controls, and live collection updates.
strix/config/providers.py Adds provider discovery, isolated credential resolution, custom provider persistence, authentication status, and model selection.
strix/config/loader.py Adds atomic configuration mutation and cache invalidation while preserving environment-first resolution.
strix/config/models.py Adds model-specific provider routing and SDK configuration without retaining generic credentials across provider changes.
strix/interface/main.py Integrates targetless setup, Go-TUI dispatch, model preflight, and startup recovery into the CLI lifecycle.
strix/core/runner.py Threads selected model and setup controls into scan orchestration while refreshing runtime model configuration.
tui-go/internal/app/model.go Implements Bubble Tea application state, navigation, setup interactions, commands, and scan views.
tui-go/internal/app/client.go Implements authenticated protocol-v3 transport, handshake validation, framing, and command correlation.
hatch_build.py Builds and embeds the platform-native sidecar only for strict release wheels and assigns a platform wheel tag.
.github/workflows/build-release.yml Gates releases on Python and Go tests and validates installed-wheel and frozen sidecar protocol behavior.

Reviews (1): Last reviewed commit: "feat(tui): add fresh-run setup commands" | Re-trigger Greptile

5hy7xz92nd-oss

This comment was marked as spam.

0xallam added 5 commits August 2, 2026 16:34
Resolves conflicts with the lazy-import startup (usestrix#920) and mounted local targets (usestrix#958): drops the redundant --mount plumbing (local directories are now always mounted), keeps main.py model imports lazy, and routes the TUI /mount command through mountable-dir validation.
The Go/Bubble Tea TUI is now the only interactive interface. Deletes the
Textual app, its renderers and stylesheet, drops the textual dependency,
and removes the PR-added ci.yml workflow. The shared Textual-free
TuiLiveView projection stays for the Go backend and viewer.
Keep only the Go sidecar wheel build, sidecar presence verification, and
wheel artifact upload in the release workflow.
First-principles layout: the Go/Bubble Tea source (cmd/, internal/, go.mod)
moves from top-level tui-go/ into strix/interface/tui/, the sidecar launcher
becomes strix.interface.tui.runtime (was go_tui.py), and tui_backend becomes
strix.interface.tui.backend. Go rendering is split out of the 1.9k-line
render.go into an internal/render package with one file per tool renderer
(terminal, file edit, report, dependency, notes, todo, agents graph, proxy,
simple tools, registry), mirroring the old Python renderers layout.
Wheel builds exclude the Go source; the compiled sidecar still ships as
strix/bin/strix-tui.
@0xallam
0xallam force-pushed the feat/go-tui-provider-setup branch from ad52570 to 03c6ab5 Compare August 2, 2026 17:31
devin-ai-integration Bot and others added 15 commits August 2, 2026 17:44
respond_to_user, wait_for_agents, list_reports, and get_report had dedicated
renderers in the old Textual UI but fell through to the generic dump in Go
(the agent-graph switch matched the nonexistent wait_for_message tool).
Also drops the unused width parameter from render.Chat/render.Tool and adds
table-driven coverage for every dispatch case.
Target resolution, run preparation, model preflight, and start telemetry
move from strix/interface/main.py into strix/interface/scan_setup.py, so
the TUI runtime no longer imports private helpers from the CLI entry
point (and the main -> interactive -> runtime -> main import cycle is
gone). clone_repository now raises ValueError instead of printing a
panel and calling sys.exit, so SystemExit is no longer used as control
flow in the setup path; main() renders the error panel itself.
…unts state

setup.select_provider, setup.save_api_key, and setup.add_custom_provider
now all return _provider_record() (the same shape as providers.list), and
the Go model folds them in through one applyProviderRecord helper.
The controller's parallel mounts list is gone: /mount just adds the
directory as an ordinary local target, matching the CLI's semantics, so
snapshots no longer carry mounts/mount_count.
parse_arguments now establishes the full startup-state schema
(needs_setup, setup_invalid_provider/guidance, targets_info,
local_sources, diff_scope, run_name) in one place, so the TUI
controller and runtime read attributes directly instead of probing
with getattr defaults. main()'s interleaved 'if not setup_mode'
blocks are folded into _detect_provider_setup_need() and
_bootstrap_scan(), leaving a single linear flow.
Parses the Go protocol declaration shipped in the tree and asserts the
version and capability list match the Python backend's constants, so
the duplicated wire declarations cannot drift silently.
model.go (3.6k lines) is now model.go (types/Model/Update loop entry),
update.go (key/mouse/modal input), wire.go (protocol envelope and
collection handling), picker.go, setup.go (setup wizard commands and
views), view.go (main/chat/sidebar/stats views), agents.go, and
vulnerabilities.go. Pure file moves; no logic changes.
- tui/backend/projection.py: wire-safe state/collection projections,
  provider record serializer, and size limits, out of controller.py
- tui/sidecar.py: sidecar process launch, credential-scrubbed child
  environment, and socket authentication, out of runtime.py
- interface/cli_args.py: argument parsing and resume-state loading,
  out of main.py
- interface/environment.py: environment validation and Docker image
  management, out of main.py
- config/provider_detection.py: pure credential/environment detection
  predicates, out of config/providers.py

Pure moves plus import updates; no behavior changes.
Sidecar resolution is now deterministic: a source checkout with Go runs
the TUI via 'go run'; otherwise the packaged wheel binary is used.
…v-binary lookup

The hidden --tui-protocol-smoke flag, Go --handshake-smoke mode, and
ProtocolSmoke client path existed only for the release smoke checks
that were removed from the release workflow. STRIX_TUI_LOG debug
redirection and the build/sidecar dev-binary lookup in binary_command
were optional escape hatches; sidecar resolution is now: go run in a
source checkout, else the packaged wheel binary.
Wheels are platform wheels with the compiled sidecar; the universal
sidecar-free wheel path and its STRIX_REQUIRE_TUI_SIDECAR gate are gone,
so a missing Go toolchain fails the build instead of shipping an install
without an interactive interface. Editable installs still need no Go.
The hook now lives in build_hooks/tui_sidecar.py, and the redundant
tui-run make target is removed.
Interactive launches now open the Bubble Tea UI first and run the model
preflight, run preparation and telemetry behind a visible 'Preparing scan'
state, so the agent loop can never start before the interface is up. A
rejected saved key drops the live session into setup instead of exiting.
Also moves the wheel build hook next to the other build scripts.
Dragging in the chat trace highlights text (reverse video) and copies the
plain-text selection to the clipboard on release, tmux-style, since terminal
mouse capture prevents native selection. Selection coordinates are anchored
to content lines so scrolling keeps the highlight in place.
0xallam added 28 commits August 2, 2026 21:52
Copying a selection now pops a bottom-right 'Copied to clipboard' toast,
matching the old Textual notify() behavior, and both the toast and the
highlight clear after two seconds.
Un-closed requests responses are finalized by the garbage collector at
interpreter exit, which surfaces as 'Exception ignored ... ValueError: I/O
operation on closed file' from urllib3 after the TUI exits. Every plain
requests call now runs in a context manager so connections are released
deterministically.
…ut selection

- Chat composer is a bubbles textarea: Enter submits, Shift+Enter /
  Alt+Enter / Ctrl+J insert a newline, and it grows with content up to
  8 lines (matching the old Textual ChatTextArea)
- Fenced code blocks and vulnerability PoC code are syntax-highlighted
  via chroma (terminal256, native style), mirroring the old pygments path
- Markdown tables render as aligned columns with a header rule
- Drag-select and clipboard copy now also work inside the composer
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants