Skip to content

fix(ui): show custom skills reliably on startup#2821

Open
ilgax wants to merge 1 commit intocharmbracelet:mainfrom
ilgax:fix/ui-missing-skills-v2
Open

fix(ui): show custom skills reliably on startup#2821
ilgax wants to merge 1 commit intocharmbracelet:mainfrom
ilgax:fix/ui-missing-skills-v2

Conversation

@ilgax
Copy link
Copy Markdown
Contributor

@ilgax ilgax commented May 6, 2026

Description

Resolves a race condition where custom skills were occasionally missing on initial launch. This happened because the backend's asynchronous skill discovery would sometimes fire its "Updated" event before the TUI had finished subscribing to the pubsub broker.

Solution

The fix was to add a thread-safe cache for discovered skills in the internal/skills package. Instead of just firing a "discovery finished" event and hoping the UI catches it in time, the backend now saves those results so the UI can grab them whenever it's ready. This means that even on the very first frame, the UI has the full list of builtins and user skills.

This also let us centralize how we merge and sort everything in the Coordinator, making the startup experience more deterministic.

Key Changes

  • Memory Safety: Implemented GetLatestStates and SetLatestStates in internal/skills with full deep-cloning of SkillState objects to prevent memory corruption across package boundaries.
  • UI Synchronization: Updated the TUI constructor (internal/ui/model/ui.go) to seed its initial skillStates from the discovery cache.
  • Deduplication: Added skills.DeduplicateStates to the coordinator logic. When a user skill overrides a builtin, the UI status sidebar now only displays the state of the active user-defined skill.
  • Determinism: Standardized on slices.SortStableFunc with case-insensitive path sorting for both the skills and states slices to ensure a stable UI layout.
  • Reliability: Decoupled state gathering from publication in the coordinator to ensure the UI receives a single, complete update containing both builtin and user-defined skills.
  • Testing: Added unit tests in diagnostics_test.go to verify memory isolation and cache health.

Visuals

Before (v0.66.0) After
Before After
Custom skills missing on startup Custom skills appear instantly

Tests

  • Custom skills appear immediately on startup.
  • All internal/skills tests pass, including new isolation checks.
  • Confirmed deterministic sorting of the skills sidebar.

Resolve race condition by implementing a package-level cache for skill discovery states. Includes deep-cloning for isolation and deterministic sorting.
@ilgax ilgax force-pushed the fix/ui-missing-skills-v2 branch from d501d25 to e0b6dc5 Compare May 6, 2026 22:06
@ilgax
Copy link
Copy Markdown
Contributor Author

ilgax commented May 6, 2026

Hey! Just wanted to add that I verified this also fixes the duplication issues from #2683 and #2694.
(Should have accepted the CLA smh)

I tested it with some symlinks and the new deduplication in the Coordinator handles it perfectly.
Since we’re now deduping by the skill's name in the YAML rather than just its file path, it automatically collapses
those duplicates into a single entry.

It feels like a much cleaner way to solve it since it handles both the symlink stuff and the startup race condition in
one go. This should basically supersede my old PR #2808 too.

@meowgorithm
Copy link
Copy Markdown
Member

I very much appreciate this! This likely does solve those two, but we'll verify!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants