File size: 5,378 Bytes
6a7089a | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 | package report
import (
"fmt"
"io"
"os"
"strings"
"sync"
"github.com/pinchtab/pinchtab/internal/config"
"github.com/pinchtab/pinchtab/internal/termstyle"
)
var menuBannerOnce sync.Once
type StartupBannerOptions struct {
Mode string
ListenAddr string
ListenStatus string
PublicURL string
Strategy string
Allocation string
ProfileDir string
}
func PrintStartupBanner(cfg *config.RuntimeConfig, opts StartupBannerOptions) {
if opts.Mode == "menu" {
printed := false
menuBannerOnce.Do(func() {
printed = true
})
if !printed {
return
}
}
writeBannerLine(renderStartupLogo(blankIfEmpty(opts.Mode, "server")))
writeBannerf(" %s %s\n", styleLabel("listen"), formatListenValue(blankIfEmpty(opts.ListenAddr, cfg.ListenAddr()), defaultListenStatus(opts.Mode, opts.ListenStatus)))
if opts.PublicURL != "" {
writeBannerf(" %s %s\n", styleLabel("url"), styleValue(opts.PublicURL))
}
strat := blankIfEmpty(opts.Strategy, "manual")
alloc := blankIfEmpty(opts.Allocation, "none")
writeBannerf(" %s %s\n", styleLabel("str,plc"), styleValue(fmt.Sprintf("%s,%s", strat, alloc)))
daemonStatus := styleStdout(warningStyle, "not installed")
if IsDaemonInstalled() {
daemonStatus = styleStdout(successStyle, "ok")
}
writeBannerf(" %s %s\n", styleLabel("daemon"), daemonStatus)
posture := AssessSecurityPosture(cfg)
writeBannerf(" %s %s %s\n", styleLabel("security"), styleSecurityBar(posture.Level, posture.Bar), styleSecurityLevel(posture.Level))
if opts.ProfileDir != "" {
writeBannerf(" %s %s\n", styleLabel("profile"), styleValue(opts.ProfileDir))
}
writeBannerLine("")
}
func PrintSecuritySummary(w io.Writer, cfg *config.RuntimeConfig, prefix string, detailed bool) {
posture := AssessSecurityPosture(cfg)
if detailed {
writeSummaryf(w, "%s%s %s %s\n", prefix, styleHeading("Security"), styleSecurityBar(posture.Level, posture.Bar), styleSecurityLevel(posture.Level))
for _, check := range posture.Checks {
writeSummaryf(w, "%s %s %s %s\n", prefix, styleMarker(check.Passed), styleCheckLabel(check.Label), styleCheckDetail(check.Passed, check.Detail))
}
} else {
writeSummaryf(w, "%s%s %s %s\n", prefix, styleLabel("security"), styleSecurityBar(posture.Level, posture.Bar), styleSecurityLevel(posture.Level))
}
}
func blankIfEmpty(value, fallback string) string {
if strings.TrimSpace(value) == "" {
return fallback
}
return value
}
func renderStartupLogo(mode string) string {
if mode == "menu" || mode == "" {
return styleLogo(startupLogo)
}
return styleLogo(startupLogo) + " " + styleMode(mode)
}
func writeBannerLine(line string) {
_, _ = fmt.Fprintln(os.Stdout, line)
}
func writeBannerf(format string, args ...any) {
_, _ = fmt.Fprintf(os.Stdout, format, args...)
}
func writeSummaryf(w io.Writer, format string, args ...any) {
_, _ = fmt.Fprintf(w, format, args...)
}
func styleHeading(text string) string {
return applyStyle(text, headingStyle)
}
func styleLogo(text string) string {
return applyStyle(text, headingStyle)
}
func styleMode(text string) string {
return applyStyle(text, commandStyle)
}
func styleLabel(text string) string {
return applyStyle(fmt.Sprintf("%-8s", text), mutedStyle)
}
func styleValue(text string) string {
return applyStyle(text, valueStyle)
}
func styleListenStatus(status string) string {
switch status {
case "running":
return applyStyle(status, successStyle)
case "starting":
return applyStyle(status, warningStyle)
case "stopped":
return applyStyle(status, mutedStyle)
default:
return applyStyle(status, valueStyle)
}
}
func styleCheckLabel(text string) string {
return applyStyle(fmt.Sprintf("%-20s", text), mutedStyle)
}
func styleCheckDetail(passed bool, text string) string {
if passed {
return applyStyle(text, successStyle)
}
return applyStyle(text, warningStyle)
}
func styleMarker(passed bool) string {
if passed {
return applyStyle("ok", successStyle)
}
return applyStyle("!!", errorStyle)
}
func styleSecurityLevel(level string) string {
return applyStyle(level, termstyle.NewStyle().Foreground(termstyle.Color(SecurityLevelColor(level))).Bold(true))
}
func styleSecurityBar(level, bar string) string {
return applyStyle(bar, termstyle.NewStyle().Foreground(termstyle.Color(SecurityLevelColor(level))).Bold(true))
}
func SecurityLevelColor(level string) string {
switch level {
case "LOCKED":
return string(colorSuccess)
case "GUARDED":
return string(colorWarning)
case "ELEVATED":
return string(colorWarning)
default:
return string(colorDanger)
}
}
func applyStyle(text string, style termstyle.Style) string {
return styleStdout(style, text)
}
func formatListenValue(addr, status string) string {
status = strings.TrimSpace(status)
if status == "" {
return styleValue(addr)
}
return fmt.Sprintf("%-8s %s", styleListenStatus(status), styleValue(addr))
}
func defaultListenStatus(mode, explicit string) string {
if strings.TrimSpace(explicit) != "" {
return explicit
}
switch mode {
case "menu":
return "stopped"
case "server", "bridge", "mcp":
return "starting"
default:
return ""
}
}
const startupLogo = ` ____ _ _ _____ _
| _ \(_)_ __ ___| |__ |_ _|_ _| |__
| |_) | | '_ \ / __| '_ \ | |/ _ | '_ \
| __/| | | | | (__| | | | | | (_| | |_) |
|_| |_|_| |_|\___|_| |_| |_|\__,_|_.__/`
|