Skip to content

feat(tui): add skills and MCP server count indicator in status bar - #399

Open
alecuba16 wants to merge 1 commit into
Kuberwastaken:mainfrom
alecuba16:feat/skills-mcp-count
Open

alecuba16 wants to merge 1 commit into
Kuberwastaken:mainfrom
alecuba16:feat/skills-mcp-count

Conversation

@alecuba16

Copy link
Copy Markdown

Summary

Adds skills and MCP server count indicator in the status bar, showing active skills and connected MCP servers.

  • Status bar shows skills count and MCP server count
  • Clean indicator rendering with dim styling

Clean branch from current main, no shared payload. 24 lines, 2 files.

@Kuberwastaken Kuberwastaken left a comment

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks! The wiring itself is correct — the fields land on App, App::new populates them, and the footer segment renders in the right place between the token-budget and rate-limit blocks.

The blocker is where the count is computed. App::new is a synchronous constructor called from crates/cli/src/main.rs:1876 inside the async runtime, and discover_skills is not cheap:

  • it walks from cwd to the filesystem root, scanning .claurst/skills and .agents/skills at every level (crates/core/src/skill_discovery.rs:161-172);
  • for every entry in skills.urls it calls fetch_git_skills, which shells out to git clone on a cache miss (skill_discovery.rs:214-231).

So for anyone with a skills.urls entry, this puts a blocking network fetch on the TUI startup path just to render a number. It also fires in every test that builds an App (crates/tui/src/lib.rs:431, crates/tui/src/render.rs:3510 and :3539), which both slows the suite and lets the developer's real ~/.claurst/skills leak into test state.

Two other things:

  • The counts go stale. They're computed once at startup and never refreshed, so connecting or removing an MCP server leaves the indicator wrong for the rest of the session.
  • 0 is rendered. The || guard means a user with skills but no MCP servers sees 3 skills · 0 mcp. Worth emitting only the non-zero halves.
  • Nit: the new // Skills + MCP count indicator. comment sits at column 0 inside an indented block in render.rs.

The shape I'd suggest: pass the already-discovered skill count in from the caller rather than re-running discovery inside App::new, and update mcp_server_count wherever the MCP server list changes. Also heads-up that #401 is adding a discovered_skills field on App as part of its skill-discovery fix — once that lands you can just read .len() off it, which deletes most of this PR.

Sequencing note: I'm landing #403 (the app.rs → app/ module split) ahead of the feature queue, so please rebase before your next push — the App fields and App::new body will live in app/mod.rs. For a diff this small that should be quick.

Rework per review on Kuberwastaken#399, rebased on the app/ module split:
- discovery no longer runs inside App::new: the count is computed on a
  spawn_blocking background task (discover_skills can shell out to git
  clone via skills.urls) and drained through a one-shot channel,
  mirroring recent_sessions_pending
- mcp count reads McpManager::server_count() (connected servers), set
  by the CLI at startup and on every reconnect, not the configured list
- footer emits only the non-zero halves: 3 skills / 2 mcp instead of
  '3 skills 0 mcp'
- comment indentation fixed
@alecuba16
alecuba16 force-pushed the feat/skills-mcp-count branch from 968142c to 61485c6 Compare September 3, 2026 07:46
@alecuba16

Copy link
Copy Markdown
Author

Reworked per review, rebased onto main (post app/ split).

  1. Discovery off the startup path. App::new no longer calls discover_skills. The count is computed on a spawn_blocking background task and drained through a one-shot channel (skill_count_pending / skill_count_rx), mirroring the existing recent_sessions pattern. skills.urls git clones can no longer block TUI startup, and App::new in tests stays cheap.
  2. Connected, not configured. mcp_server_count reads McpManager::server_count() and is set by the CLI at startup and after every MCP reconnect, so it tracks live connections.
  3. Non-zero halves only. Footer renders 3 skills, 2 mcp, or 3 skills · 2 mcp — never a 0 half.
  4. Comment indent nit fixed.

Happy to rebase onto #401's discovered_skills field once it lands to just read .len() off it.

cargo check --workspace and clippy --workspace --all-targets -D warnings clean.

@alecuba16

Copy link
Copy Markdown
Author

All review points addressed in 61485c6:

Skill discovery moved off App::new. discover_skills no longer runs inside the constructor. Instead:

  • skill_count_pending: true is set on App::new, and skill_count_rx is None.
  • On the first run-loop iteration in app/run.rs, a one-shot tokio::spawn + spawn_blocking task runs discover_skills in the background and sends the count over an mpsc channel.
  • The loop drains try_recv() each frame and updates skill_count when the result arrives.
  • No blocking network fetch on the TUI startup path.

MCP count tracks connected servers, not configured list. mcp_server_count is set from McpManager::server_count() at startup in main.rs, and updated on every MCP reconnect (the same site that rebuilds tools_arc). So connecting or removing an MCP server refreshes the indicator.

Counts go stale less. MCP count is refreshed on reconnect. Skill count is a one-shot (discovery is expensive), which matches the review's suggestion. Once #401's discovered_skills field lands, the count can be read from .len() for live tracking.

0 is not rendered. The indicator only emits non-zero halves: 3 skills (no + 0 mcp), 2 mcp (no 0 skills +), or nothing at all when both are zero. Uses · as separator.

Comment indentation fixed. The // 3c. Skills + MCP count indicator comment is now properly indented inside the block.

cargo check --workspace clean. cargo clippy --workspace --all-targets clean. cargo test -p claurst-tui --lib — 657 passed, 1 pre-existing failure (settings_screen::tests::all_entries_returns_expected_settings, unrelated to this PR — fails at HEAD on main too).

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