Files
kit/internal/ui/block_renderer.go
Ed Zynda 78570d4188 remove dead code identified by audit
Removes ~600 lines of unreferenced code surfaced by deadcode + manual
audit (none of it reachable from production code paths or test setup):

- internal/models/pool.go: ProviderPool was never wired into kitsetup
  or the agent; the global pool singleton had zero callers.
- internal/ui/debug_logger.go: CLIDebugLogger was unreachable; debug
  routing goes through internal/tools/buffered_logger.go instead.
- internal/ui/tool_approval_input.go: tea.Model never instantiated;
  approvals are handled inline in model.go.
- internal/ui/cli.go: DisplayAssistantMessage / DisplayCancellation /
  GetDebugLogger had zero callers (the *WithModel variant is what
  event_handler.go uses).
- internal/ui/style/enhanced.go: Style{Card,Header,Subheader,Muted,
  Success,Error,Warning,Info} + Create{Separator,ProgressBar} — none
  used. CreateBadge stays (used by model.go).
- internal/ui/style/themes.go: RefreshThemeRegistry — never called.
- internal/ui/block_renderer.go: With{FullWidth,MarginTop,Padding{Left,
  Right},Background,Foreground,Width} — option helpers nobody calls.
- internal/ui/render/blocks.go: UserBlock, ToolBlock — replaced by
  inline rendering elsewhere; the test for UserBlock was rewritten to
  directly exercise HighlightFileTokens (which is what the test really
  cared about).
- internal/ui/commands/commands.go: GetAllCommandNames — no callers.
- internal/ui/message_items.go: NewTextMessageItem,
  NewSystemMessageItem + the entire SystemMessageItem type — model.go
  uses NewStyledMessageItem instead.
- internal/prompts/loader.go: Deduplicate — the loader does dedup
  internally; standalone helper was unused.
- internal/models/cache_options.go: mergeProviderOptions + its
  test-only consumer.
- internal/extensions/installer.go: Installer.GetInstalledPackages —
  intended for a 'kit ext list' command that was never built.
- internal/extensions/manifest.go: saveManifestToScope,
  saveManifestToPath, GetGlobalManifest, GetProjectManifest,
  addEntryToManifest, removeEntryFromManifest — package-level
  duplicates of *Installer methods. Tests rewritten to exercise the
  live Installer methods instead, which fixes a latent path-resolution
  inconsistency between manifestPathForScope and Installer.manifestPath
  (the former hard-coded paths, the latter respects projectGitRoot).
- internal/extensions/subagent.go: SpawnSubagent + helpers
  (generateSubagentID, findKitBinary, subagentJSONOutput). The
  subprocess-spawn implementation is unreachable; production code
  routes through kit.Kit.Subagent (in-process). Types
  (SubagentConfig/Result/Handle/etc.) and the SubagentHandle methods
  remain because they are exposed to extensions via Yaegi symbols and
  the Context.SpawnSubagent field.
- cmd/root.go: LoadConfigWithEnvSubstitution — one-line wrapper around
  kit.LoadConfigWithEnvSubstitution with zero callers.

go test -race ./... passes.
2026-05-07 12:20:08 +03:00

172 lines
4.3 KiB
Go

package ui
import (
"image/color"
"charm.land/lipgloss/v2"
"github.com/mark3labs/kit/internal/ui/style"
)
// blockRenderer handles rendering of content blocks with configurable options
type blockRenderer struct {
align *lipgloss.Position
borderColor *color.Color
background *color.Color
foreground *color.Color
fullWidth bool
noBorder bool
paddingTop int
paddingBottom int
paddingLeft int
paddingRight int
marginTop int
marginBottom int
width int
}
// renderingOption configures block rendering
type renderingOption func(*blockRenderer)
// WithNoBorder returns a renderingOption that disables all borders on the
// block, rendering content with only padding.
func WithNoBorder() renderingOption {
return func(c *blockRenderer) {
c.noBorder = true
}
}
// WithAlign returns a renderingOption that sets the horizontal alignment
// of the block content within its container. The align parameter accepts
// lipgloss.Left, lipgloss.Center, or lipgloss.Right positions.
func WithAlign(align lipgloss.Position) renderingOption {
return func(c *blockRenderer) {
c.align = &align
}
}
// WithBorderColor returns a renderingOption that sets the border color
// for the block. The color parameter uses lipgloss.AdaptiveColor to support
// both light and dark terminal themes automatically.
func WithBorderColor(c color.Color) renderingOption {
return func(br *blockRenderer) {
br.borderColor = &c
}
}
// WithMarginBottom returns a renderingOption that sets the bottom margin
// for the block. The margin is specified in number of lines and adds
// vertical space below the block.
func WithMarginBottom(margin int) renderingOption {
return func(c *blockRenderer) {
c.marginBottom = margin
}
}
// WithPaddingTop returns a renderingOption that sets the top padding
// for the block content. The padding is specified in number of lines
// and adds vertical space between the top border and the content.
func WithPaddingTop(padding int) renderingOption {
return func(c *blockRenderer) {
c.paddingTop = padding
}
}
// WithPaddingBottom returns a renderingOption that sets the bottom padding
// for the block content. The padding is specified in number of lines
// and adds vertical space between the content and the bottom border.
func WithPaddingBottom(padding int) renderingOption {
return func(c *blockRenderer) {
c.paddingBottom = padding
}
}
// renderContentBlock renders content with configurable styling options
func renderContentBlock(content string, containerWidth int, options ...renderingOption) string {
renderer := &blockRenderer{
fullWidth: true,
paddingTop: 1,
paddingBottom: 1,
paddingLeft: 2,
paddingRight: 0,
width: containerWidth,
}
for _, option := range options {
option(renderer)
}
// Resolve border configuration.
hasBorder := !renderer.noBorder
borderChars := 0
borderAlign := lipgloss.Left
if renderer.align != nil {
borderAlign = *renderer.align
}
var borderColor color.Color = lipgloss.NoColor{}
if renderer.borderColor != nil {
borderColor = *renderer.borderColor
}
if hasBorder {
borderChars = 1
}
theme := style.GetTheme()
// Resolve foreground color: caller override or theme default.
fgColor := theme.Text
if renderer.foreground != nil {
fgColor = *renderer.foreground
}
// Single-pass render: padding, border, and foreground in one style.
style := lipgloss.NewStyle().
PaddingLeft(renderer.paddingLeft).
PaddingRight(renderer.paddingRight).
PaddingTop(renderer.paddingTop).
PaddingBottom(renderer.paddingBottom).
Foreground(fgColor)
if hasBorder {
style = style.BorderStyle(lipgloss.ThickBorder())
switch borderAlign {
case lipgloss.Right:
style = style.
BorderRight(true).
BorderRightForeground(borderColor)
default:
style = style.
BorderLeft(true).
BorderLeftForeground(borderColor)
}
}
if renderer.background != nil {
style = style.Background(*renderer.background)
}
if renderer.fullWidth {
style = style.Width(renderer.width - borderChars)
}
content = style.Render(content)
// Add margins
if renderer.marginTop > 0 {
for range renderer.marginTop {
content = "\n" + content
}
}
if renderer.marginBottom > 0 {
for range renderer.marginBottom {
content = content + "\n"
}
}
return content
}