← back to jterrazz__jterrazz-configuration

Function bodies 209 total

All specs Real LLM only Function bodies
components.Item.Render method · go · L53-L72 (20 LOC)
src/internal/presentation/components/tui_item.go
func (i Item) Render(selected bool, labelWidth int, width int, spinnerFrame string) string {
	switch i.Kind {
	case KindHeader:
		return renderSection(i.Label, width)

	case KindNavigation:
		return i.renderNavigation(selected, labelWidth)

	case KindAction:
		return i.renderAction(selected)

	case KindToggle:
		return i.renderToggle(selected, labelWidth, spinnerFrame)

	case KindExpandable:
		return i.renderExpandable(selected, labelWidth)
	}

	return ""
}
components.Item.renderNavigation method · go · L79-L91 (13 LOC)
src/internal/presentation/components/tui_item.go
func (i Item) renderNavigation(selected bool, labelWidth int) string {
	prefix := i.buildPrefix(selected)

	paddedLabel := i.Label
	if labelWidth > 0 {
		paddedLabel = fmt.Sprintf("%-*s", labelWidth, i.Label)
	}

	if selected {
		return theme.Selected.Render(fmt.Sprintf("%s%s", prefix, paddedLabel)) + RenderDescription(i.Description)
	}
	return prefix + theme.Action.Render(paddedLabel) + RenderDescription(i.Description)
}
components.Item.renderAction method · go · L93-L100 (8 LOC)
src/internal/presentation/components/tui_item.go
func (i Item) renderAction(selected bool) string {
	prefix := i.buildPrefix(selected)
	style := theme.Normal
	if selected {
		style = theme.Selected
	}
	return style.Render(prefix + i.Label)
}
components.Item.renderToggle method · go · L102-L141 (40 LOC)
src/internal/presentation/components/tui_item.go
func (i Item) renderToggle(selected bool, labelWidth int, spinnerFrame string) string {
	var statusBadge string
	switch i.State {
	case StateChecked:
		statusBadge = BadgeOK()
	case StateUnchecked:
		statusBadge = BadgeError()
	case StateLoading:
		if spinnerFrame != "" {
			statusBadge = theme.SpinnerStyle.Render(spinnerFrame)
		} else {
			statusBadge = theme.BadgeLoading.Render(theme.IconLoading)
		}
	default:
		statusBadge = " "
	}

	prefix := i.buildPrefix(selected)
	style := theme.Normal
	if selected {
		style = theme.Selected
	}

	paddedLabel := i.Label
	if labelWidth > 0 {
		paddedLabel = fmt.Sprintf("%-*s", labelWidth, i.Label)
	}

	// Status on the right: label  description  status
	if i.Description != "" {
		desc := i.Description
		if i.DescWidth > 0 {
			desc = fmt.Sprintf("%-*s", i.DescWidth, i.Description)
		}
		return style.Render(fmt.Sprintf("%s%s", prefix, paddedLabel)) +
			RenderDescription(desc) + ColumnSeparator + statusBadge
	}

	return style.Render(fmt.Sprintf("%
components.Item.renderExpandable method · go · L143-L158 (16 LOC)
src/internal/presentation/components/tui_item.go
func (i Item) renderExpandable(selected bool, labelWidth int) string {
	prefix := i.buildPrefix(selected)

	paddedLabel := i.Label
	if labelWidth > 0 {
		paddedLabel = fmt.Sprintf("%-*s", labelWidth, i.Label)
	}

	style := theme.Normal
	if selected {
		style = theme.Selected
	}

	base := style.Render(fmt.Sprintf("%s%s", prefix, paddedLabel))
	return base + RenderDescription(i.Description)
}
components.Item.indentPrefix method · go · L160-L165 (6 LOC)
src/internal/presentation/components/tui_item.go
func (i Item) indentPrefix() string {
	if i.Indent <= 0 {
		return ""
	}
	return strings.Repeat(" ", i.Indent*IndentSpaces)
}
components.Item.buildPrefix method · go · L168-L174 (7 LOC)
src/internal/presentation/components/tui_item.go
func (i Item) buildPrefix(selected bool) string {
	indent := i.indentPrefix()
	if selected {
		return indent + " " + theme.IconSelected + " "
	}
	return indent + "   "
}
Powered by Repobility — scan your code at https://repobility.com
components.NewList function · go · L25-L35 (11 LOC)
src/internal/presentation/components/tui_list.go
func NewList(items []Item) *List {
	l := &List{
		Items:  items,
		Cursor: 0,
		Width:  DefaultTerminalWidth,
		Height: DefaultTerminalHeight,
	}
	// Start cursor on first selectable item
	l.skipToSelectable(1)
	return l
}
components.List.move method · go · L54-L65 (12 LOC)
src/internal/presentation/components/tui_list.go
func (l *List) move(delta int) {
	newCursor := l.Cursor + delta

	// Skip non-selectable items
	for newCursor >= 0 && newCursor < len(l.Items) && !l.Items[newCursor].Selectable() {
		newCursor += delta
	}

	if newCursor >= 0 && newCursor < len(l.Items) {
		l.Cursor = newCursor
	}
}
components.List.Selected method · go · L75-L80 (6 LOC)
src/internal/presentation/components/tui_list.go
func (l *List) Selected() *Item {
	if l.Cursor >= 0 && l.Cursor < len(l.Items) {
		return &l.Items[l.Cursor]
	}
	return nil
}
components.List.Render method · go · L102-L130 (29 LOC)
src/internal/presentation/components/tui_list.go
func (l *List) Render(visibleHeight int) string {
	if len(l.Items) == 0 {
		return ""
	}

	if visibleHeight <= 0 {
		visibleHeight = l.Height
	}

	// Calculate visible range with scrolling
	startIdx := 0
	if l.Cursor > visibleHeight-ScrollMargin {
		startIdx = l.Cursor - visibleHeight + ScrollMargin
	}
	endIdx := startIdx + visibleHeight
	if endIdx > len(l.Items) {
		endIdx = len(l.Items)
	}

	var b strings.Builder
	for i := startIdx; i < endIdx; i++ {
		item := l.Items[i]
		selected := i == l.Cursor
		line := item.Render(selected, l.LabelWidth, l.Width, l.SpinnerFrame)
		b.WriteString(line + "\n")
	}

	return b.String()
}
components.List.CalculateLabelWidth method · go · L133-L142 (10 LOC)
src/internal/presentation/components/tui_list.go
func (l *List) CalculateLabelWidth() int {
	maxLen := 0
	for _, item := range l.Items {
		if len(item.Label) > maxLen {
			maxLen = len(item.Label)
		}
	}
	l.LabelWidth = maxLen
	return maxLen
}
components.NewPage function · go · L22-L28 (7 LOC)
src/internal/presentation/components/tui_page.go
func NewPage(title string) *Page {
	return &Page{
		Title:  title,
		Width:  80,
		Height: 24,
	}
}
components.Page.ContentHeight method · go · L38-L44 (7 LOC)
src/internal/presentation/components/tui_page.go
func (p *Page) ContentHeight() int {
	h := p.Height - PageHeaderHeight(false) - 2 // header + help + message
	if h < 1 {
		h = 1
	}
	return h
}
components.Page.Render method · go · L47-L78 (32 LOC)
src/internal/presentation/components/tui_page.go
func (p *Page) Render() string {
	var b strings.Builder

	// Header
	title := p.Title
	if len(p.Breadcrumbs) > 0 {
		title = p.Breadcrumbs[len(p.Breadcrumbs)-1]
	}
	b.WriteString(PageHeader(title, ""))

	// Main content
	if p.Content != "" {
		b.WriteString(p.Content)
	}

	// Help text
	if p.Help != "" {
		b.WriteString(theme.Help.Render(p.Help))
	}

	// Status message
	if p.Message != "" {
		b.WriteString("\n")
		if p.Processing {
			b.WriteString(theme.Action.Render(p.Message))
		} else {
			b.WriteString(theme.Success.Render(p.Message))
		}
	}

	return b.String()
}
Same scanner, your repo: https://repobility.com — Repobility
components.Table function · go · L16-L41 (26 LOC)
src/internal/presentation/components/tui_table.go
func Table(rows [][]string, columns []TableColumn) string {
	if len(rows) == 0 {
		return ""
	}

	t := table.New().
		Border(lipgloss.RoundedBorder()).
		BorderStyle(lipgloss.NewStyle().Foreground(lipgloss.Color(theme.ColorBorder))).
		StyleFunc(func(row, col int) lipgloss.Style {
			style := lipgloss.NewStyle().PaddingLeft(1).PaddingRight(1)

			if col < len(columns) {
				if columns[col].Width > 0 {
					style = style.Width(columns[col].Width)
				}
				if columns[col].Color != "" {
					style = style.Foreground(lipgloss.Color(columns[col].Color))
				}
			}

			return style
		}).
		Rows(rows...)

	return t.Render()
}
components.SimpleTable function · go · L45-L67 (23 LOC)
src/internal/presentation/components/tui_table.go
func SimpleTable(rows [][]string, firstColWidth int) string {
	if len(rows) == 0 {
		return ""
	}

	t := table.New().
		Border(lipgloss.RoundedBorder()).
		BorderStyle(lipgloss.NewStyle().Foreground(lipgloss.Color(theme.ColorBorder))).
		StyleFunc(func(row, col int) lipgloss.Style {
			if col == 0 {
				return lipgloss.NewStyle().
					Foreground(lipgloss.Color(theme.ColorPrimary)).
					PaddingLeft(1).PaddingRight(1).
					Width(firstColWidth)
			}
			return lipgloss.NewStyle().
				Foreground(lipgloss.Color(theme.ColorMuted)).
				PaddingLeft(1).PaddingRight(1)
		}).
		Rows(rows...)

	return t.Render()
}
components.StatusTable function · go · L71-L102 (32 LOC)
src/internal/presentation/components/tui_table.go
func StatusTable(rows [][]string, nameWidth int) string {
	if len(rows) == 0 {
		return ""
	}

	t := table.New().
		Border(lipgloss.RoundedBorder()).
		BorderStyle(lipgloss.NewStyle().Foreground(lipgloss.Color(theme.ColorBorder))).
		StyleFunc(func(row, col int) lipgloss.Style {
			switch col {
			case 0:
				return lipgloss.NewStyle().
					Foreground(lipgloss.Color(theme.ColorPrimary)).
					PaddingLeft(1).PaddingRight(1).
					Width(nameWidth)
			case 1:
				return lipgloss.NewStyle().
					Foreground(lipgloss.Color(theme.ColorMuted)).
					PaddingLeft(1).PaddingRight(1).
					Width(30)
			case 2:
				return lipgloss.NewStyle().
					Foreground(lipgloss.Color(theme.ColorSecondary)).
					PaddingLeft(1).PaddingRight(1)
			default:
				return lipgloss.NewStyle().PaddingLeft(1).PaddingRight(1)
			}
		}).
		Rows(rows...)

	return t.Render()
}
components.NewViewport function · go · L15-L20 (6 LOC)
src/internal/presentation/components/tui_viewport.go
func NewViewport(width, height int) *Viewport {
	return &Viewport{
		Model:               viewport.New(width, height),
		ShowScrollIndicator: true,
	}
}
print.Row function · go · L113-L120 (8 LOC)
src/internal/presentation/print/print.go
func Row(ok bool, label, detail string) {
	icon := components.Badge(ok)
	if detail != "" {
		fmt.Printf(components.PageIndent+"%s %-14s %s\n", icon, label, theme.Muted.Render(detail))
	} else {
		fmt.Printf(components.PageIndent+"%s %s\n", icon, label)
	}
}
theme.Resolve function · go · L175-L192 (18 LOC)
src/internal/presentation/theme/styles.go
func Resolve(styleName string) lipgloss.Style {
	switch styleName {
	case "success":
		return Success
	case "warning":
		return Warning
	case "danger":
		return Danger
	case "special":
		return Special
	case "normal":
		return Normal
	case "muted":
		return Muted
	default:
		return Muted
	}
}
setup.InitRemoteState function · go · L41-L54 (14 LOC)
src/internal/presentation/views/setup/remote.go
func InitRemoteState() {
	settings, err := config.LoadRemoteSettings()
	if err != nil {
		settings = config.RemoteSettings{
			Mode:       config.RemoteModeUserspace,
			AuthMethod: config.RemoteAuthOAuth,
		}
	}

	remote = remoteState{
		settings: settings,
		itemData: nil,
	}
}
setup.BuildRemoteItems function · go · L57-L113 (57 LOC)
src/internal/presentation/views/setup/remote.go
func BuildRemoteItems() []components.Item {
	var items []components.Item
	remote.itemData = nil

	items = append(items, components.Item{Kind: components.KindHeader, Label: "Remote"})
	remote.itemData = append(remote.itemData, remoteItemData{})

	items = append(items, components.Item{
		Kind:        components.KindNavigation,
		Label:       "mode",
		Description: string(remote.settings.Mode),
	})
	remote.itemData = append(remote.itemData, remoteItemData{action: remoteActionMode})

	items = append(items, components.Item{
		Kind:        components.KindNavigation,
		Label:       "auth method",
		Description: string(remote.settings.AuthMethod),
	})
	remote.itemData = append(remote.itemData, remoteItemData{action: remoteActionAuth})

	hostDesc := remote.settings.Hostname
	if hostDesc == "" {
		hostDesc = "-"
	}
	items = append(items, components.Item{
		Kind:        components.KindNavigation,
		Label:       "hostname",
		Description: hostDesc,
	})
	remote.itemData = append(remote.itemData, re
Repobility's GitHub App fixes findings like these · https://github.com/apps/repobility-bot
setup.HandleRemoteSelect function · go · L116-L163 (48 LOC)
src/internal/presentation/views/setup/remote.go
func HandleRemoteSelect(index int, item components.Item) tea.Cmd {
	if index >= len(remote.itemData) {
		return nil
	}
	data := remote.itemData[index]

	switch data.action {
	case remoteActionMode:
		remote.settings.Mode = nextRemoteMode(remote.settings.Mode)
		return func() tea.Msg { return components.RefreshMsg{} }

	case remoteActionAuth:
		remote.settings.AuthMethod = nextRemoteAuthMethod(remote.settings.AuthMethod)
		if remote.settings.AuthMethod == config.RemoteAuthOAuth {
			remote.settings.Secret = ""
		}
		return func() tea.Msg { return components.RefreshMsg{} }

	case remoteActionHostname:
		return promptRemoteFieldCmd(
			"hostname",
			"Hostname (empty to clear): ",
			false,
		)

	case remoteActionSecret:
		if remote.settings.AuthMethod != config.RemoteAuthAuthKey {
			return func() tea.Msg {
				return components.ActionDoneMsg{Message: "Auth key is only used with auth method = authkey"}
			}
		}
		return promptRemoteFieldCmd(
			"secret",
			"Auth key (empty to clear): ",
setup.HandleRemoteMessage function · go · L166-L185 (20 LOC)
src/internal/presentation/views/setup/remote.go
func HandleRemoteMessage(msg tea.Msg) tea.Cmd {
	switch msg := msg.(type) {
	case remoteFieldUpdatedMsg:
		if msg.err != nil {
			return func() tea.Msg {
				return components.ActionDoneMsg{Message: "Error: " + msg.err.Error(), Err: msg.err}
			}
		}

		value := strings.TrimSpace(msg.value)
		switch msg.field {
		case "hostname":
			remote.settings.Hostname = value
		case "secret":
			remote.settings.Secret = value
		}
		return func() tea.Msg { return components.RefreshMsg{} }
	}
	return nil
}
setup.RemoteConfig function · go · L188-L195 (8 LOC)
src/internal/presentation/views/setup/remote.go
func RemoteConfig() components.AppConfig {
	return components.AppConfig{
		Title:      "Remote",
		BuildItems: BuildRemoteItems,
		OnSelect:   HandleRemoteSelect,
		OnMessage:  HandleRemoteMessage,
	}
}
setup.nextRemoteMode function · go · L197-L208 (12 LOC)
src/internal/presentation/views/setup/remote.go
func nextRemoteMode(mode config.RemoteMode) config.RemoteMode {
	order := []config.RemoteMode{
		config.RemoteModeAuto,
		config.RemoteModeUserspace,
	}
	for i := range order {
		if order[i] == mode {
			return order[(i+1)%len(order)]
		}
	}
	return config.RemoteModeUserspace
}
setup.nextRemoteAuthMethod function · go · L210-L221 (12 LOC)
src/internal/presentation/views/setup/remote.go
func nextRemoteAuthMethod(method config.RemoteAuthMethod) config.RemoteAuthMethod {
	order := []config.RemoteAuthMethod{
		config.RemoteAuthOAuth,
		config.RemoteAuthAuthKey,
	}
	for i := range order {
		if order[i] == method {
			return order[(i+1)%len(order)]
		}
	}
	return config.RemoteAuthOAuth
}
setup.promptRemoteFieldCmd function · go · L223-L252 (30 LOC)
src/internal/presentation/views/setup/remote.go
func promptRemoteFieldCmd(field, prompt string, hidden bool) tea.Cmd {
	tmpFile, err := os.CreateTemp("", "jremote-"+field+"-*")
	if err != nil {
		return func() tea.Msg {
			return remoteFieldUpdatedMsg{field: field, err: err}
		}
	}
	path := tmpFile.Name()
	tmpFile.Close()

	script := ""
	if hidden {
		script = "printf " + shellQuote(prompt) + "; stty -echo; IFS= read -r v; stty echo; printf '\\n'; printf '%s' \"$v\" > \"$1\""
	} else {
		script = "printf " + shellQuote(prompt) + "; IFS= read -r v; printf '%s' \"$v\" > \"$1\""
	}

	cmd := exec.Command("sh", "-c", script, "sh", path)
	return tea.ExecProcess(cmd, func(execErr error) tea.Msg {
		defer os.Remove(path)
		if execErr != nil {
			return remoteFieldUpdatedMsg{field: field, err: execErr}
		}
		data, readErr := os.ReadFile(path)
		if readErr != nil {
			return remoteFieldUpdatedMsg{field: field, err: readErr}
		}
		return remoteFieldUpdatedMsg{field: field, value: string(data)}
	})
}
setup.BuildItems function · go · L25-L135 (111 LOC)
src/internal/presentation/views/setup/setup.go
func BuildItems() []components.Item {
	var items []components.Item
	itemNames = []string{}

	// Navigation section
	items = append(items, components.Item{Kind: components.KindHeader, Label: "Navigation"})
	itemNames = append(itemNames, "")

	items = append(items, components.Item{Kind: components.KindNavigation, Label: "skills", Description: "Manage AI agent skills"})
	itemNames = append(itemNames, string(ActionSkills))

	items = append(items, components.Item{Kind: components.KindNavigation, Label: "remote", Description: "Configure remote SSH access"})
	itemNames = append(itemNames, string(ActionRemote))

	// Configuration section - from config.Scripts with CheckFn
	items = append(items, components.Item{Kind: components.KindHeader, Label: "Setup"})
	itemNames = append(itemNames, "")

	type scriptEntry struct {
		item components.Item
		name string
	}
	var configuredItems, notConfiguredItems []scriptEntry

	// Calculate max description width for alignment
	maxDescWidth := 0
	for _, script
setup.HandleSelect function · go · L138-L176 (39 LOC)
src/internal/presentation/views/setup/setup.go
func HandleSelect(index int, item components.Item, runScript func(string)) tea.Cmd {
	if index >= len(itemNames) {
		return nil
	}
	name := itemNames[index]

	switch Action(name) {
	case ActionSkills:
		return func() tea.Msg {
			return components.NavigateMsg{
				InitFunc: InitSkillsState,
				Config:   SkillsConfig(),
			}
		}
	case ActionRemote:
		return func() tea.Msg {
			return components.NavigateMsg{
				InitFunc: InitRemoteState,
				Config:   RemoteConfig(),
			}
		}

	default:
		// Check if script uses ExecArgs (needs full terminal control)
		if script := config.GetScriptByName(name); script != nil && len(script.ExecArgs) > 0 {
			c := exec.Command(script.ExecArgs[0], script.ExecArgs[1:]...)
			return tea.ExecProcess(c, func(err error) tea.Msg {
				return components.ActionDoneMsg{Message: "Completed " + name}
			})
		}

		loadingScript = name
		return func() tea.Msg {
			runScript(name)
			loadingScript = ""
			return components.ActionDoneMsg{Message: "Completed " + name}
		
All rows scored by the Repobility analyzer (https://repobility.com)
setup.RunOrExit function · go · L179-L187 (9 LOC)
src/internal/presentation/views/setup/setup.go
func RunOrExit(runScript func(string)) {
	components.RunOrExit(components.AppConfig{
		Title:      "Setup",
		BuildItems: BuildItems,
		OnSelect: func(index int, item components.Item) tea.Cmd {
			return HandleSelect(index, item, runScript)
		},
	})
}
setup.InitSkillsState function · go · L37-L44 (8 LOC)
src/internal/presentation/views/setup/skills.go
func InitSkillsState() {
	skills = skillsState{
		expanded:   make(map[string]bool),
		installed:  skill.ListInstalled(),
		repoSkills: make(map[string][]string),
		itemData:   nil,
	}
}
setup.BuildSkillsItems function · go · L47-L160 (114 LOC)
src/internal/presentation/views/setup/skills.go
func BuildSkillsItems() []components.Item {
	var items []components.Item
	skills.itemData = nil

	// Favorites section
	favorites := config.GetFavoriteSkills()
	if len(favorites) > 0 {
		items = append(items, components.Item{Kind: components.KindHeader, Label: "Pinned"})
		skills.itemData = append(skills.itemData, skillItemData{})

		for _, s := range favorites {
			state := components.StateUnchecked
			if skills.loadingSkill == s.Skill {
				state = components.StateLoading
			} else if isSkillInstalled(s.Skill) {
				state = components.StateChecked
			}
			items = append(items, components.Item{
				Kind:  components.KindToggle,
				Label: s.Skill,
				State: state,
			})
			skills.itemData = append(skills.itemData, skillItemData{repo: s.Repo, skill: s.Skill})
		}
	}

	// Installed section (skills not in Favorites)
	var otherInstalled []string
	for _, s := range skills.installed {
		if !config.IsFavoriteSkill("", s) {
			otherInstalled = append(otherInstalled, s)
		}
	}
	if len(otherIn
setup.isSkillInstalled function · go · L162-L169 (8 LOC)
src/internal/presentation/views/setup/skills.go
func isSkillInstalled(name string) bool {
	for _, s := range skills.installed {
		if s == name {
			return true
		}
	}
	return false
}
setup.findRepoForSkill function · go · L171-L185 (15 LOC)
src/internal/presentation/views/setup/skills.go
func findRepoForSkill(name string) string {
	for repoName, repoSkills := range skills.repoSkills {
		for _, s := range repoSkills {
			if s == name {
				return repoName
			}
		}
	}
	for _, s := range config.FavoriteSkills {
		if s.Skill == name {
			return s.Repo
		}
	}
	return ""
}
setup.HandleSkillsSelect function · go · L188-L222 (35 LOC)
src/internal/presentation/views/setup/skills.go
func HandleSkillsSelect(index int, item components.Item) tea.Cmd {
	if index >= len(skills.itemData) {
		return nil
	}
	data := skills.itemData[index]

	switch item.Kind {
	case components.KindExpandable:
		if skills.expanded[data.repo] {
			skills.expanded[data.repo] = false
			return func() tea.Msg { return components.RefreshMsg{} }
		} else {
			skills.expanded[data.repo] = true
			if skills.repoSkills[data.repo] == nil {
				skills.loadingRepo = data.repo
				return fetchSkillsCmd(data.repo)
			}
			return func() tea.Msg { return components.RefreshMsg{} }
		}

	case components.KindAction:
		if data.action == skillActionInstallRepo {
			return installRepoCmd(data.repo)
		}

	case components.KindToggle:
		skills.loadingSkill = data.skill
		if item.State == components.StateChecked {
			return removeSkillCmd(data.skill)
		}
		return installSkillCmd(data.repo, data.skill)
	}

	return nil
}
setup.HandleSkillsMessage function · go · L232-L249 (18 LOC)
src/internal/presentation/views/setup/skills.go
func HandleSkillsMessage(msg tea.Msg) tea.Cmd {
	switch msg := msg.(type) {
	case SkillsFetchedMsg:
		skills.loadingRepo = ""
		if msg.Err == nil {
			skills.repoSkills[msg.Repo] = msg.Skills
		} else {
			skills.repoSkills[msg.Repo] = []string{}
		}
		return nil

	case components.ActionDoneMsg:
		skills.loadingSkill = ""
		skills.installed = skill.ListInstalled()
		return nil
	}
	return nil
}
setup.fetchSkillsCmd function · go · L251-L256 (6 LOC)
src/internal/presentation/views/setup/skills.go
func fetchSkillsCmd(repo string) tea.Cmd {
	return func() tea.Msg {
		repoSkills, err := skill.ListFromRepo(repo)
		return SkillsFetchedMsg{Repo: repo, Skills: repoSkills, Err: err}
	}
}
Powered by Repobility — scan your code at https://repobility.com
setup.installSkillCmd function · go · L258-L265 (8 LOC)
src/internal/presentation/views/setup/skills.go
func installSkillCmd(repo, name string) tea.Cmd {
	return func() tea.Msg {
		if err := skill.Install(repo, name); err != nil {
			return components.ActionDoneMsg{Message: "Error: " + err.Error(), Err: err}
		}
		return components.ActionDoneMsg{Message: "Installed " + name}
	}
}
setup.installRepoCmd function · go · L267-L274 (8 LOC)
src/internal/presentation/views/setup/skills.go
func installRepoCmd(repo string) tea.Cmd {
	return func() tea.Msg {
		if err := skill.InstallAll(repo); err != nil {
			return components.ActionDoneMsg{Message: "Error: " + err.Error(), Err: err}
		}
		return components.ActionDoneMsg{Message: "Installed all from " + repo}
	}
}
setup.removeSkillCmd function · go · L276-L283 (8 LOC)
src/internal/presentation/views/setup/skills.go
func removeSkillCmd(name string) tea.Cmd {
	return func() tea.Msg {
		if err := skill.Remove(name); err != nil {
			return components.ActionDoneMsg{Message: "Error: " + err.Error(), Err: err}
		}
		return components.ActionDoneMsg{Message: "Removed " + name}
	}
}
setup.SkillsConfig function · go · L286-L293 (8 LOC)
src/internal/presentation/views/setup/skills.go
func SkillsConfig() components.AppConfig {
	return components.AppConfig{
		Title:      "Skills",
		BuildItems: BuildSkillsItems,
		OnSelect:   HandleSkillsSelect,
		OnMessage:  HandleSkillsMessage,
	}
}
status.New function · go · L42-L62 (21 LOC)
src/internal/presentation/views/status/model.go
func New() Model {
	loader := status.NewLoader()
	items := make(map[string]status.Item)
	itemOrder := loader.GetItems()

	total := 0
	for _, item := range itemOrder {
		items[item.ID] = item
		if !item.Loaded && item.Kind != status.KindHeader {
			total++
		}
	}

	return Model{
		loader:    loader,
		items:     items,
		itemOrder: itemOrder,
		spinner:   components.NewSpinnerModel(),
		total:     total,
	}
}
status.Model.Init method · go · L65-L72 (8 LOC)
src/internal/presentation/views/status/model.go
func (m Model) Init() tea.Cmd {
	m.loader.Start()
	return tea.Batch(
		m.spinner.Tick,
		m.loader.WaitForUpdate(),
		scheduleProcessRefresh(),
	)
}
status.refreshProcesses function · go · L82-L90 (9 LOC)
src/internal/presentation/views/status/model.go
func refreshProcesses() tea.Cmd {
	return func() tea.Msg {
		data := make(map[string][]config.ProcessInfo)
		for _, check := range config.ProcessChecks {
			data["process-"+check.Name] = check.CheckFn()
		}
		return ProcessDataMsg{Data: data}
	}
}
status.Model.Update method · go · L93-L183 (91 LOC)
src/internal/presentation/views/status/model.go
func (m Model) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
	var cmds []tea.Cmd

	switch msg := msg.(type) {
	case tea.KeyMsg:
		switch msg.String() {
		case "q", "ctrl+c", "esc":
			m.quitting = true
			return m, tea.Quit
		case "home", "g":
			m.viewport.GotoTop()
		case "end", "G":
			m.viewport.GotoBottom()
		}

	case tea.WindowSizeMsg:
		headerHeight := components.PageHeaderHeight(true) // title + subtitle
		footerHeight := 1

		if !m.ready {
			m.viewport = viewport.New(msg.Width, msg.Height-headerHeight-footerHeight)
			m.viewport.YPosition = headerHeight
			m.ready = true
		} else {
			m.viewport.Width = msg.Width
			m.viewport.Height = msg.Height - headerHeight - footerHeight
		}
		m.width = msg.Width
		m.height = msg.Height

	case status.UpdateMsg:
		if existing, ok := m.items[msg.ID]; ok {
			existing.Loaded = msg.Item.Loaded
			existing.Installed = msg.Item.Installed
			existing.Version = msg.Item.Version
			existing.Status = msg.Item.Status
			existing.Detail = msg.Item.Deta
Same scanner, your repo: https://repobility.com — Repobility
status.Model.View method · go · L186-L226 (41 LOC)
src/internal/presentation/views/status/model.go
func (m Model) View() string {
	if m.quitting {
		return ""
	}

	if !m.ready {
		return m.spinner.View() + " Initializing..."
	}

	var b strings.Builder

	// System info subtitle
	subtitle := ""
	if sysinfo, ok := m.items["sysinfo"]; ok && sysinfo.Loaded {
		subtitle = sysinfo.Detail
	} else {
		subtitle = m.spinner.View() + " Loading..."
	}

	// Header
	b.WriteString(components.PageHeader("STATUS", subtitle))

	// Content
	b.WriteString(m.viewport.View())
	b.WriteString("\n")

	// Footer
	scrollPercent := int(m.viewport.ScrollPercent() * 100)
	help := fmt.Sprintf("↑/↓ scroll • g/G top/bottom • %d%% • q quit", scrollPercent)

	if m.allLoaded {
		footer := theme.Help.Render(help) + components.ColumnSeparator + theme.Success.Render(theme.IconCheck+" All checks complete")
		b.WriteString(footer)
	} else {
		progressBar := m.renderProgressBar()
		footer := theme.Help.Render(help) + components.ColumnSeparator + progressBar
		b.WriteString(footer)
	}

	return b.String()
}
status.Model.renderProgressBar method · go · L228-L248 (21 LOC)
src/internal/presentation/views/status/model.go
func (m Model) renderProgressBar() string {
	if m.allLoaded {
		return theme.Success.Render(theme.IconCheck + " All checks complete")
	}

	width := 30
	filled := int(float64(m.loaded) / float64(m.total) * float64(width))
	if filled > width {
		filled = width
	}

	bar := theme.ProgressFilled.Render(strings.Repeat(theme.IconProgressFull, filled)) +
		theme.ProgressEmpty.Render(strings.Repeat(theme.IconProgressEmpty, width-filled))

	return fmt.Sprintf("%s %s %d/%d",
		m.spinner.View(),
		bar,
		m.loaded,
		m.total,
	)
}
status.Model.renderTableRow method · go · L9-L37 (29 LOC)
src/internal/presentation/views/status/rows.go
func (m Model) renderTableRow(item status.Item, colWidths ColumnWidths) string {
	if !item.Loaded {
		switch item.Kind {
		case status.KindSetup:
			return m.renderSetupRowLoading(item, colWidths)
		case status.KindSecurity, status.KindIdentity:
			return m.renderCheckRowLoading(item, colWidths)
		case status.KindTool:
			return m.renderToolRowLoading(item, colWidths)
		case status.KindNetwork, status.KindCache:
			return m.renderResourceRowLoading(item, colWidths)
		default:
			return components.RowPrefix + m.spinner.View() + components.ColumnSeparator + components.CellNormal(item.Name, colWidths.Name)
		}
	}

	switch item.Kind {
	case status.KindSetup:
		return m.renderSetupRow(item, colWidths)
	case status.KindSecurity, status.KindIdentity:
		return m.renderCheckRow(item, colWidths)
	case status.KindTool:
		return m.renderToolRow(item, colWidths)
	case status.KindNetwork, status.KindCache:
		return m.renderResourceRow(item, colWidths)
	}

	return ""
}
‹ prevpage 4 / 5next ›