11package chat
22
33import (
4+ "encoding/xml"
45 "strings"
56
67 tea "charm.land/bubbletea/v2"
@@ -11,6 +12,14 @@ import (
1112 "github.com/charmbracelet/crush/internal/ui/styles"
1213)
1314
15+ // skillInvocation represents the XML structure for a loaded skill.
16+ type skillInvocation struct {
17+ Name string `xml:"name"`
18+ Description string `xml:"description"`
19+ Location string `xml:"location"`
20+ Instructions string `xml:"instructions"`
21+ }
22+
1423// UserMessageItem represents a user message in the chat UI.
1524type UserMessageItem struct {
1625 * highlightableMessageItem
@@ -44,9 +53,18 @@ func (m *UserMessageItem) RawRender(width int) string {
4453 return m .renderHighlighted (content , cappedWidth , height )
4554 }
4655
56+ msgContent := strings .TrimSpace (m .message .Content ().Text )
57+
58+ // Check if this is a skill invocation (loaded_skill XML)
59+ if strings .HasPrefix (msgContent , "<loaded_skill>" ) {
60+ content = m .renderSkillInvocation (msgContent , cappedWidth )
61+ height = lipgloss .Height (content )
62+ m .setCachedRender (content , cappedWidth , height )
63+ return m .renderHighlighted (content , cappedWidth , height )
64+ }
65+
4766 renderer := common .MarkdownRenderer (m .sty , cappedWidth )
4867
49- msgContent := strings .TrimSpace (m .message .Content ().Text )
5068 result , err := renderer .Render (msgContent )
5169 if err != nil {
5270 content = msgContent
@@ -68,6 +86,22 @@ func (m *UserMessageItem) RawRender(width int) string {
6886 return m .renderHighlighted (content , cappedWidth , height )
6987}
7088
89+ // renderSkillInvocation renders a loaded_skill XML as a special UI element.
90+ func (m * UserMessageItem ) renderSkillInvocation (content string , width int ) string {
91+ var skill skillInvocation
92+ if err := xml .Unmarshal ([]byte (content ), & skill ); err != nil {
93+ // If parsing fails, just render as markdown
94+ renderer := common .MarkdownRenderer (m .sty , width )
95+ result , err := renderer .Render (content )
96+ if err != nil {
97+ return content
98+ }
99+ return strings .TrimSuffix (result , "\n " )
100+ }
101+
102+ return toolOutputSkillContent (m .sty , skill .Name , skill .Description )
103+ }
104+
71105// Render implements MessageItem.
72106func (m * UserMessageItem ) Render (width int ) string {
73107 var prefix string
0 commit comments