Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 20 additions & 0 deletions cmd/mecatui/client/session.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,9 @@ type SessionSnapshot struct {
// Usage is the canonical cumulative main-session ledger. It is distinct from
// ContextOccupancy, which is only the latest context-meter display state.
Usage Usage
// AuxiliaryUsage is the sum of every non-main canonical usage bucket (title
// generation, compaction, reflection, routing, reviewers, guardrails, judges).
AuxiliaryUsage Usage
// ContextOccupancy is nil when a legacy or pre-turn snapshot has no known
// context-meter numerator.
ContextOccupancy *ContextOccupancy
Expand Down Expand Up @@ -54,6 +57,22 @@ func contextOccupancyFrom(occupancy *mecatlv1.ContextOccupancy) *ContextOccupanc
return &ContextOccupancy{InputTokens: occupancy.GetInputTokens(), Estimated: occupancy.GetEstimated()}
}

func auxiliaryUsageFrom(buckets map[string]*mecatlv1.TokenUsage) Usage {
var total Usage
for kind, bucket := range buckets {
if kind == "main" {
continue
}
u := usageFrom(bucket.GetTotal())
total.InputTokens += u.InputTokens
total.OutputTokens += u.OutputTokens
total.CacheReadTokens += u.CacheReadTokens
total.CacheWriteTokens += u.CacheWriteTokens
total.ReasoningTokens += u.ReasoningTokens
}
return total
}

func snapshotFrom(s *mecatlv1.Session) SessionSnapshot {
return snapshotFromWithGlobalCapabilities(s, Capabilities{})
}
Expand All @@ -70,6 +89,7 @@ func snapshotFromWithGlobalCapabilities(s *mecatlv1.Session, global Capabilities
CreatedAt: s.GetCreatedAtUnix(),
ResolvedModel: resolvedModelFrom(s.GetResolvedModel()),
Usage: usageFrom(s.GetTokenUsage()["main"].GetTotal()),
AuxiliaryUsage: auxiliaryUsageFrom(s.GetTokenUsage()),
ContextOccupancy: contextOccupancyFrom(s.GetLatestContextOccupancy()),
Title: titleFromProto(s),
TitleProvenance: titleProvenanceFromProto(s),
Expand Down
9 changes: 7 additions & 2 deletions cmd/mecatui/client/session_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -157,18 +157,23 @@ func TestSnapshotFromReadsTitle(t *testing.T) {
func TestSnapshotFromProjectsMainUsageAndOptionalContextOccupancy(t *testing.T) {
snap := snapshotFrom(&mecatlv1.Session{
TokenUsage: map[string]*mecatlv1.TokenUsage{
"main": {Total: &mecatlv1.Usage{InputTokens: 120_000, OutputTokens: 4_000, CacheReadTokens: 90_000}},
"main": {Total: &mecatlv1.Usage{InputTokens: 120_000, OutputTokens: 4_000, CacheReadTokens: 90_000}},
"session_title": {Total: &mecatlv1.Usage{InputTokens: 300, OutputTokens: 10}},
"guardrail": {Total: &mecatlv1.Usage{InputTokens: 700, OutputTokens: 5, CacheReadTokens: 200}},
},
LatestContextOccupancy: &mecatlv1.ContextOccupancy{InputTokens: 40_000, Estimated: true},
})
if snap.Usage != (Usage{InputTokens: 120_000, OutputTokens: 4_000, CacheReadTokens: 90_000}) {
t.Fatalf("main usage = %+v", snap.Usage)
}
if snap.AuxiliaryUsage != (Usage{InputTokens: 1_000, OutputTokens: 15, CacheReadTokens: 200}) {
t.Fatalf("auxiliary usage = %+v", snap.AuxiliaryUsage)
}
if snap.ContextOccupancy == nil || *snap.ContextOccupancy != (ContextOccupancy{InputTokens: 40_000, Estimated: true}) {
t.Fatalf("context occupancy = %+v", snap.ContextOccupancy)
}
legacy := snapshotFrom(&mecatlv1.Session{TokenUsage: map[string]*mecatlv1.TokenUsage{"main": {Total: &mecatlv1.Usage{InputTokens: 120_000}}}})
if legacy.ContextOccupancy != nil || legacy.Usage.InputTokens != 120_000 {
if legacy.ContextOccupancy != nil || legacy.Usage.InputTokens != 120_000 || legacy.AuxiliaryUsage != (Usage{}) {
t.Fatalf("legacy snapshot = %+v", legacy)
}
}
50 changes: 37 additions & 13 deletions cmd/mecatui/exit_handoff.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import (
tea "charm.land/bubbletea/v2"

"github.com/stacklok/mecatl/cmd/mecatui/client"
"github.com/stacklok/mecatl/cmd/mecatui/internal/renderfmt"
"github.com/stacklok/mecatl/cmd/mecatui/internal/terminaltext"
)

Expand All @@ -39,31 +40,54 @@ func finishFinalSessionHandoff(w io.Writer, final tea.Model, runErr error, inter
cancel()
}
cleanup()
if !shouldWriteFinalSessionHandoff(final, runErr, interrupted) || !writeFinalSessionHandoff(w, final) || !embedded || !ok {
if !shouldWriteFinalSessionHandoff(final, runErr, interrupted) || !ok {
return
}
id := reporter.ActiveSessionID()
// Connected mode, and an ID unsafe to print as one terminal line, keep the
// JSON-quoted record; an embedded safe ID gets the aligned human summary instead.
if !embedded || id == "" || !utf8.ValidString(id) || !safeHandoffID(id) {
writeFinalSessionHandoff(w, final)
return
}
var human strings.Builder
human.WriteByte('\n')
writeHandoffField(&human, "Session ID:", id)
if available {
if title := strings.TrimSpace(terminaltext.SanitizeSingleLine(snapshot.Title)); title != "" {
_, _ = fmt.Fprintf(&human, "Session: %s\n", title)
}
_, _ = fmt.Fprintf(&human, "Model calls: %d\nTokens (main): %d input, %d output", snapshot.Turns, snapshot.Usage.InputTokens, snapshot.Usage.OutputTokens)
if snapshot.Usage.CacheReadTokens != 0 {
_, _ = fmt.Fprintf(&human, ", %d cache read", snapshot.Usage.CacheReadTokens)
writeHandoffField(&human, "Title:", title)
}
if snapshot.Usage.CacheWriteTokens != 0 {
_, _ = fmt.Fprintf(&human, ", %d cache write", snapshot.Usage.CacheWriteTokens)
writeHandoffField(&human, "Model calls:", fmt.Sprint(snapshot.Turns))
writeHandoffField(&human, "Tokens (main):", handoffTokens(snapshot.Usage))
if snapshot.AuxiliaryUsage != (client.Usage{}) {
writeHandoffField(&human, "Tokens (aux):", handoffTokens(snapshot.AuxiliaryUsage))
}
human.WriteByte('\n')
}
if safeHandoffID(id) {
_, _ = fmt.Fprintf(&human, "Resume: mecatui --resume '%s'\n", strings.ReplaceAll(id, "'", "'\"'\"'"))
human.WriteString("Or: mecatui --resume-latest (may select a different chat)\n")
}
writeHandoffField(&human, "Resume:", "mecatui --resume '"+strings.ReplaceAll(id, "'", "'\"'\"'")+"'")
writeHandoffField(&human, "", "mecatui --resume-latest (may select a different chat)")
_, _ = io.WriteString(w, human.String())
}

// handoffLabelWidth aligns values after the widest label, "Tokens (main): ".
const handoffLabelWidth = len("Tokens (main): ")

func writeHandoffField(b *strings.Builder, label, value string) {
_, _ = fmt.Fprintf(b, "%-*s%s\n", handoffLabelWidth, label, value)
}

// handoffTokens humanizes one usage value; cache counts are labelled
// components of input, never summed with it.
func handoffTokens(u client.Usage) string {
s := renderfmt.HumanizeTokens(u.InputTokens) + " input, " + renderfmt.HumanizeTokens(u.OutputTokens) + " output"
if u.CacheReadTokens != 0 {
s += ", " + renderfmt.HumanizeTokens(u.CacheReadTokens) + " cache read"
}
if u.CacheWriteTokens != 0 {
s += ", " + renderfmt.HumanizeTokens(u.CacheWriteTokens) + " cache write"
}
return s
}

func safeHandoffID(id string) bool {
for _, r := range id {
if !unicode.IsPrint(r) || unicode.Is(unicode.Cf, r) {
Expand Down
19 changes: 10 additions & 9 deletions cmd/mecatui/exit_handoff_composition_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -198,14 +198,15 @@ func checkEmbeddedCompositionChild(t *testing.T, scenario string) {
t.Fatalf("stdout changed by program: %q", stdout.String())
}
got := stderr.String()
line := strings.Index(got, finalSessionHandoffPrefix)
if line < 1 || got[line-1] != '\n' || strings.Contains(got, "hosting an embedded mecated at") || strings.Count(got, finalSessionHandoffPrefix) != 1 || strings.LastIndex(got[:line], "\x1b[?1049l") < 0 || !strings.Contains(got[line:], "handoff-child-cleaned\n") {
const idLabel = "Session ID: "
line := strings.Index(got, "\n"+idLabel)
if line < 0 || strings.Contains(got, "hosting an embedded mecated at") || strings.Contains(got, finalSessionHandoffPrefix) || strings.Count(got, idLabel) != 1 || strings.LastIndex(got[:line], "\x1b[?1049l") < 0 || !strings.Contains(got[line:], "handoff-child-cleaned\n") {
t.Fatalf("handoff must follow teardown with a separating line and no startup socket address: %q", got)
}
fields := strings.SplitN(got[line:], "\n", 2)
var id string
if err := json.Unmarshal([]byte(strings.TrimPrefix(fields[0], finalSessionHandoffPrefix)), &id); err != nil || id == "" {
t.Fatalf("invalid ID: %q: %v", fields[0], err)
line++
id := strings.SplitN(strings.TrimPrefix(got[line:], idLabel), "\n", 2)[0]
if id == "" {
t.Fatalf("missing session ID: %q", got[line:])
}
const finalIDPrefix = "handoff-child-final-id="
finalLine := strings.Index(got, finalIDPrefix)
Expand All @@ -219,14 +220,14 @@ func checkEmbeddedCompositionChild(t *testing.T, scenario string) {
if scenario != "missing" && id != finalID {
t.Fatalf("handoff ID = %q, want seeded final ID %q", id, finalID)
}
if !strings.Contains(got[line:], "Resume: mecatui --resume '"+id+"'\n") || !strings.Contains(got[line:], "Or: mecatui --resume-latest (may select a different chat)\n") {
if !strings.Contains(got[line:], "Resume: mecatui --resume '"+id+"'\n") || !strings.Contains(got[line:], " mecatui --resume-latest (may select a different chat)\n") {
t.Fatalf("final ID command missing: %q", got[line:])
}
if scenario == "missing" {
if id != "missing-final" || strings.Contains(got[line:], "Session:") || strings.Contains(got[line:], "Model calls:") || strings.Contains(got[line:], "Tokens (main):") {
if id != "missing-final" || strings.Contains(got[line:], "Title:") || strings.Contains(got[line:], "Model calls:") || strings.Contains(got[line:], "Tokens (main):") {
t.Fatalf("failed lookup retained stale summary: %q", got[line:])
}
} else if !strings.Contains(got[line:], "Session: final title\nModel calls: 1\nTokens (main): 0 input, 0 output\n") || strings.Contains(got[line:], "first title") {
} else if !strings.Contains(got[line:], "Title: final title\nModel calls: 1\nTokens (main): 0 input, 0 output\n") || strings.Contains(got[line:], "first title") {
t.Fatalf("wrong final session snapshot: %q", got[line:])
}
}
43 changes: 23 additions & 20 deletions cmd/mecatui/exit_handoff_scenarios_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -73,16 +73,11 @@ func TestMecatuiExitHandoff_Scenario1_EmbeddedResumeAfterTeardown(t *testing.T)
got := stderr.String()
teardown := strings.Index(got, "\x1b[?1049l")
cleanup := strings.Index(got, "cleanup-complete\n")
line := strings.Index(got, finalSessionHandoffPrefix)
if teardown < 0 || cleanup <= teardown || line <= cleanup || strings.Count(got, finalSessionHandoffPrefix) != 1 {
t.Fatalf("teardown/cleanup/ID record order = %q", got)
line := strings.Index(got, "\nSession ID: final chat\n")
if teardown < 0 || cleanup <= teardown || line <= cleanup || strings.Contains(got, finalSessionHandoffPrefix) {
t.Fatalf("teardown/cleanup/session ID order = %q", got)
}
lines := strings.Split(got[line:], "\n")
var decoded string
if err := json.Unmarshal([]byte(strings.TrimPrefix(lines[0], finalSessionHandoffPrefix)), &decoded); err != nil || decoded != "final chat" {
t.Fatalf("ID record = %q, decoded=%q, err=%v", lines[0], decoded, err)
}
if !strings.Contains(got, "Resume: mecatui --resume 'final chat'\n") || !strings.Contains(got, "Or: mecatui --resume-latest (may select a different chat)\n") {
if !strings.Contains(got, "Resume: mecatui --resume 'final chat'\n") || !strings.Contains(got, " mecatui --resume-latest (may select a different chat)\n") {
t.Fatalf("missing exact/qualified continuation: %q", got)
}
}
Expand All @@ -92,21 +87,29 @@ func TestMecatuiExitHandoff_Scenario1_AuthoritativeSummary(t *testing.T) {
if id != "final" {
t.Fatalf("requested session %q, want final", id)
}
return client.SessionSnapshot{Title: "Server display title", State: "completed", Turns: 7, Usage: client.Usage{InputTokens: 42, OutputTokens: 13, CacheReadTokens: 9, CacheWriteTokens: 3}, ContextOccupancy: &client.ContextOccupancy{InputTokens: 999}}, nil
return client.SessionSnapshot{Title: "Server display title", State: "completed", Turns: 7,
Usage: client.Usage{InputTokens: 1_234_567, OutputTokens: 13_400, CacheReadTokens: 9, CacheWriteTokens: 3},
AuxiliaryUsage: client.Usage{InputTokens: 2_500, OutputTokens: 40, CacheReadTokens: 1_000},
ContextOccupancy: &client.ContextOccupancy{InputTokens: 999}}, nil
})
got := handoffOutput(t, "final", true, get, nil, false)
for _, line := range []string{"Session: Server display title\n", "Model calls: 7\n", "Tokens (main): 42 input, 13 output, 9 cache read, 3 cache write\n"} {
if !strings.Contains(got, line) {
t.Fatalf("missing %q: %q", line, got)
}
want := "Session ID: final\n" +
"Title: Server display title\n" +
"Model calls: 7\n" +
"Tokens (main): 1.2M input, 13.4K output, 9 cache read, 3 cache write\n" +
"Tokens (aux): 2.5K input, 40 output, 1K cache read\n" +
"Resume: mecatui --resume 'final'\n" +
" mecatui --resume-latest (may select a different chat)\n"
if got != "\n"+want {
t.Fatalf("aligned summary = %q, want suffix %q", got, want)
}
if strings.Contains(got, "999") {
t.Fatalf("context meter leaked into lifetime totals: %q", got)
}
got = handoffOutput(t, "final", true, handoffSnapshotGetter(func(context.Context, string) (client.SessionSnapshot, error) {
return client.SessionSnapshot{State: "completed", Turns: 0}, nil
}), nil, false)
if strings.Contains(got, "Session:") || strings.Contains(got, "cache read") || !strings.Contains(got, "Model calls: 0\n") {
if strings.Contains(got, "Title:") || strings.Contains(got, "cache read") || strings.Contains(got, "Tokens (aux)") || !strings.Contains(got, "Model calls: 0\n") {
t.Fatalf("empty title/zero cache = %q", got)
}
}
Expand All @@ -116,8 +119,8 @@ func TestMecatuiExitHandoff_Scenario1_SafePresentation(t *testing.T) {
got := handoffOutput(t, id, true, nil, nil, false)
line := ""
for _, l := range strings.Split(got, "\n") {
if strings.HasPrefix(l, "Resume: ") {
line = strings.TrimPrefix(l, "Resume: ")
if strings.HasPrefix(l, "Resume:") {
line = strings.TrimSpace(strings.TrimPrefix(l, "Resume:"))
}
}
if line == "" {
Expand All @@ -131,14 +134,14 @@ func TestMecatuiExitHandoff_Scenario1_SafePresentation(t *testing.T) {
for _, unsafeID := range []string{"two\nlines", "escape\x1b[31m", "bidi\u202eright"} {
got := handoffOutput(t, unsafeID, true, nil, nil, false)
quoted, _ := json.Marshal(unsafeID)
if !strings.Contains(got, finalSessionHandoffPrefix+string(quoted)+"\n") || strings.Contains(got, "Resume:") || strings.Contains(got, "Or:") {
if !strings.Contains(got, finalSessionHandoffPrefix+string(quoted)+"\n") || strings.Contains(got, "Resume:") || strings.Contains(got, "--resume-latest") || strings.Contains(got, "Session ID:") {
t.Fatalf("unsafe ID %q: %q", unsafeID, got)
}
}
got = handoffOutput(t, "final", true, handoffSnapshotGetter(func(context.Context, string) (client.SessionSnapshot, error) {
return client.SessionSnapshot{State: "completed", Title: "ok\nFAKE LINE\x1b[31m\u202eevil", Turns: 1}, nil
}), nil, false)
if strings.Contains(got, "\x1b") || strings.Contains(got, "\u202e") || strings.Contains(got, "\nFAKE LINE") || strings.Count(got, "Session:") != 1 || !strings.Contains(got, "Session: okFAKE LINE[31mevil\n") {
if strings.Contains(got, "\x1b") || strings.Contains(got, "\u202e") || strings.Contains(got, "\nFAKE LINE") || strings.Count(got, "Title:") != 1 || !strings.Contains(got, "Title: okFAKE LINE[31mevil\n") {
t.Fatalf("untrusted title controls/lines: %q", got)
}
}
Expand All @@ -163,7 +166,7 @@ func TestMecatuiExitHandoff_Scenario2_SnapshotUnavailable(t *testing.T) {
if time.Since(start) > 2*time.Second {
t.Fatalf("snapshot blocked cleanup beyond deadline: %s", time.Since(start))
}
if !strings.Contains(got, finalSessionHandoffPrefix+`"final"`+"\n") || !strings.Contains(got, "Resume: mecatui --resume 'final'\n") || strings.Contains(got, "Session:") || strings.Contains(got, "Model calls:") || strings.Contains(got, "Tokens (main):") {
if got != "\nSession ID: final\nResume: mecatui --resume 'final'\n mecatui --resume-latest (may select a different chat)\n" || strings.Contains(got, "Title:") || strings.Contains(got, "Model calls:") || strings.Contains(got, "Tokens (main):") {
t.Fatalf("failed snapshot must retain only safe guidance: %q", got)
}
})
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import (
"testing"

"github.com/stacklok/mecatl/cmd/mecatui/client"
"github.com/stacklok/mecatl/cmd/mecatui/ui/internal/renderfmt"
"github.com/stacklok/mecatl/cmd/mecatui/internal/renderfmt"
)

func TestHumanizeTokens(t *testing.T) {
Expand Down
2 changes: 1 addition & 1 deletion cmd/mecatui/ui/agents_overlay.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,10 +12,10 @@ import (
"github.com/charmbracelet/x/ansi"

"github.com/stacklok/mecatl/cmd/mecatui/client"
"github.com/stacklok/mecatl/cmd/mecatui/internal/renderfmt"
"github.com/stacklok/mecatl/cmd/mecatui/internal/terminaltext"
"github.com/stacklok/mecatl/cmd/mecatui/theme"
"github.com/stacklok/mecatl/cmd/mecatui/ui/internal/bounded"
"github.com/stacklok/mecatl/cmd/mecatui/ui/internal/renderfmt"
"github.com/stacklok/mecatl/cmd/mecatui/ui/internal/scrollback"
)

Expand Down
2 changes: 1 addition & 1 deletion cmd/mecatui/ui/models_surface.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,9 +14,9 @@ import (
"github.com/charmbracelet/x/ansi"

"github.com/stacklok/mecatl/cmd/mecatui/client"
"github.com/stacklok/mecatl/cmd/mecatui/internal/renderfmt"
"github.com/stacklok/mecatl/cmd/mecatui/internal/terminaltext"
"github.com/stacklok/mecatl/cmd/mecatui/ui/internal/bounded"
"github.com/stacklok/mecatl/cmd/mecatui/ui/internal/renderfmt"
)

// modelsView is the active /models overlay.
Expand Down
2 changes: 1 addition & 1 deletion cmd/mecatui/ui/noprogress_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,8 @@ import (
"testing"

"github.com/stacklok/mecatl/cmd/mecatui/client"
"github.com/stacklok/mecatl/cmd/mecatui/internal/renderfmt"
"github.com/stacklok/mecatl/cmd/mecatui/theme"
"github.com/stacklok/mecatl/cmd/mecatui/ui/internal/renderfmt"
"github.com/stacklok/mecatl/cmd/mecatui/ui/internal/scrollback"
)

Expand Down
2 changes: 1 addition & 1 deletion cmd/mecatui/ui/plan_approval_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,8 @@ import (
tea "charm.land/bubbletea/v2"

"github.com/stacklok/mecatl/cmd/mecatui/client"
"github.com/stacklok/mecatl/cmd/mecatui/internal/renderfmt"
"github.com/stacklok/mecatl/cmd/mecatui/theme"
"github.com/stacklok/mecatl/cmd/mecatui/ui/internal/renderfmt"
mecatlv1 "github.com/stacklok/mecatl/contracts/gen/go/mecatl/v1"
)

Expand Down
2 changes: 1 addition & 1 deletion cmd/mecatui/ui/render.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,9 +16,9 @@ import (
"github.com/charmbracelet/x/ansi"

"github.com/stacklok/mecatl/cmd/mecatui/client"
"github.com/stacklok/mecatl/cmd/mecatui/internal/renderfmt"
"github.com/stacklok/mecatl/cmd/mecatui/internal/terminaltext"
"github.com/stacklok/mecatl/cmd/mecatui/theme"
"github.com/stacklok/mecatl/cmd/mecatui/ui/internal/renderfmt"
"github.com/stacklok/mecatl/cmd/mecatui/ui/internal/scrollback"
)

Expand Down
2 changes: 1 addition & 1 deletion cmd/mecatui/ui/sessions_surface.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,10 +16,10 @@ import (
tea "charm.land/bubbletea/v2"

"github.com/stacklok/mecatl/cmd/mecatui/client"
"github.com/stacklok/mecatl/cmd/mecatui/internal/renderfmt"
"github.com/stacklok/mecatl/cmd/mecatui/internal/terminaltext"
"github.com/stacklok/mecatl/cmd/mecatui/theme"
"github.com/stacklok/mecatl/cmd/mecatui/ui/internal/bounded"
"github.com/stacklok/mecatl/cmd/mecatui/ui/internal/renderfmt"
)

type sessionsTab int
Expand Down
2 changes: 1 addition & 1 deletion cmd/mecatui/ui/statusline_source.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import (

"github.com/stacklok/mecatl/cmd/mecatui/client"
customization "github.com/stacklok/mecatl/cmd/mecatui/customization"
"github.com/stacklok/mecatl/cmd/mecatui/ui/internal/renderfmt"
"github.com/stacklok/mecatl/cmd/mecatui/internal/renderfmt"
)

type statusLineChangedMsg struct {
Expand Down
2 changes: 1 addition & 1 deletion cmd/mecatui/ui/team.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,10 @@ import (
"charm.land/bubbles/v2/key"
tea "charm.land/bubbletea/v2"

"github.com/stacklok/mecatl/cmd/mecatui/internal/renderfmt"
"github.com/stacklok/mecatl/cmd/mecatui/internal/terminaltext"
"github.com/stacklok/mecatl/cmd/mecatui/theme"
"github.com/stacklok/mecatl/cmd/mecatui/ui/internal/bounded"
"github.com/stacklok/mecatl/cmd/mecatui/ui/internal/renderfmt"
)

// teamView is the active agent-team overlay (none = closed). The overlay is a
Expand Down
2 changes: 1 addition & 1 deletion cmd/mecatui/ui/tool_block.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,9 @@ import (
"strings"

"github.com/stacklok/mecatl/cmd/mecatui/client"
"github.com/stacklok/mecatl/cmd/mecatui/internal/renderfmt"
"github.com/stacklok/mecatl/cmd/mecatui/internal/terminaltext"
"github.com/stacklok/mecatl/cmd/mecatui/ui/internal/blocks"
"github.com/stacklok/mecatl/cmd/mecatui/ui/internal/renderfmt"
"github.com/stacklok/mecatl/cmd/mecatui/ui/internal/scrollback"
)

Expand Down
Loading
Loading