on main help sign in
feat(ui): indicate when skills are loaded
commitc1d294d161dbee0d1bd5061c3270050c980b8d98 authorChristian Rocha <christian@rocha.is> dateSat 21 Feb 2026, 10:23 (8 months ago) parentd6312f4
4 files changed+52−12
internal/agent/tools/view.go+27−6 internal/ui/chat/file.go+6 internal/ui/chat/tools.go+15−4 internal/ui/styles/styles.go+4−2
internal/agent/tools/view.go+27−6
@@ -17,6 +17,7 @@ import (
1717 "github.com/charmbracelet/crush/internal/filetracker"
1818 "github.com/charmbracelet/crush/internal/lsp"
1919 "github.com/charmbracelet/crush/internal/permission"
20+ "github.com/charmbracelet/crush/internal/skills"
2021)
2122
2223//go:embed view.md
@@ -34,9 +35,19 @@ type ViewPermissionsParams struct {
3435 Limit int `json:"limit"`
3536}
3637
38+type ViewResourceType string
39+
40+const (
41+ ViewResourceUnset ViewResourceType = ""
42+ ViewResourceSkill ViewResourceType = "skill"
43+)
44+
3745type ViewResponseMetadata struct {
38− FilePath string `json:"file_path"`
39− Content string `json:"content"`
46+ FilePath string `json:"file_path"`
47+ Content string `json:"content"`
48+ ResourceType ViewResourceType `json:"resource_type,omitempty"`
49+ ResourceName string `json:"resource_name,omitempty"`
50+ ResourceDescription string `json:"resource_description,omitempty"`
4051}
4152
4253const (
@@ -196,12 +207,22 @@ func NewViewTool(
196207 output += "\n</file>\n"
197208 output += getDiagnostics(filePath, lspManager)
198209 filetracker.RecordRead(ctx, sessionID, filePath)
210+
211+ meta := ViewResponseMetadata{
212+ FilePath: filePath,
213+ Content: content,
214+ }
215+ if isSkillFile {
216+ if skill, err := skills.Parse(filePath); err == nil {
217+ meta.ResourceType = ViewResourceSkill
218+ meta.ResourceName = skill.Name
219+ meta.ResourceDescription = skill.Description
220+ }
221+ }
222+
199223 return fantasy.WithResponseMetadata(
200224 fantasy.NewTextResponse(output),
201− ViewResponseMetadata{
202− FilePath: filePath,
203− Content: content,
204− },
225+ meta,
205226 ), nil
206227 })
207228}
internal/ui/chat/file.go+6
@@ -82,6 +82,12 @@ func (v *ViewToolRenderContext) RenderTool(sty *styles.Styles, width int, opts *
8282 content = meta.Content
8383 }
8484
85+ // Handle skill content.
86+ if meta.ResourceType == tools.ViewResourceSkill {
87+ body := toolOutputSkillContent(sty, meta.ResourceName, meta.ResourceDescription)
88+ return joinToolParts(header, body)
89+ }
90+
8591 if content == "" {
8692 return header
8793 }
internal/ui/chat/tools.go+15−4
@@ -625,10 +625,21 @@ func toolOutputImageContent(sty *styles.Styles, data, mediaType string) string {
625625
626626 return sty.Tool.Body.Render(fmt.Sprintf(
627627 "%s %s %s %s",
628− sty.Tool.ResourceLoadedText.String(),
629− sty.Tool.ResourceLoadedIndicator.String(),
630− sty.Base.Render(mediaType),
631− sty.Subtle.Render(sizeStr),
628+ sty.Tool.ResourceLoadedText.Render("Loaded Image"),
629+ sty.Tool.ResourceLoadedIndicator.Render(styles.ArrowRightIcon),
630+ sty.Tool.MediaType.Render(mediaType),
631+ sty.Tool.ResourceSize.Render(sizeStr),
632+ ))
633+}
634+
635+// toolOutputSkillContent renders a skill loaded indicator.
636+func toolOutputSkillContent(sty *styles.Styles, name, description string) string {
637+ return sty.Tool.Body.Render(fmt.Sprintf(
638+ "%s %s %s %s",
639+ sty.Tool.ResourceLoadedText.Render("Loaded Skill"),
640+ sty.Tool.ResourceLoadedIndicator.Render(styles.ArrowRightIcon),
641+ sty.Tool.ResourceName.Render(name),
642+ sty.Tool.ResourceSize.Render(description),
632643 ))
633644}
634645
internal/ui/styles/styles.go+4−2
@@ -325,6 +325,7 @@ type Styles struct {
325325 // Images and external resources
326326 ResourceLoadedText lipgloss.Style
327327 ResourceLoadedIndicator lipgloss.Style
328+ ResourceName lipgloss.Style
328329 ResourceSize lipgloss.Style
329330 MediaType lipgloss.Style
330331 }
@@ -1175,8 +1176,9 @@ func DefaultStyles() Styles {
11751176 s.Tool.MCPArrow = base.Foreground(blue).SetString(ArrowRightIcon)
11761177
11771178 // Loading indicators for images, skills
1178− s.Tool.ResourceLoadedText = base.Foreground(green).SetString("Loaded")
1179− s.Tool.ResourceLoadedIndicator = base.Foreground(greenDark).SetString(ArrowRightIcon)
1179+ s.Tool.ResourceLoadedText = base.Foreground(green)
1180+ s.Tool.ResourceLoadedIndicator = base.Foreground(greenDark)
1181+ s.Tool.ResourceName = base
11801182 s.Tool.MediaType = base
11811183 s.Tool.ResourceSize = base.Foreground(fgMuted)
11821184