Skip to content

feat: show installed skills in UI#7910

Merged
DOsinga merged 9 commits intoblock:mainfrom
vincenzopalazzo:claude/elastic-kirch
Mar 26, 2026
Merged

feat: show installed skills in UI#7910
DOsinga merged 9 commits intoblock:mainfrom
vincenzopalazzo:claude/elastic-kirch

Conversation

@vincenzopalazzo
Copy link
Copy Markdown
Contributor

Summary

  • Adds a /skills builtin command that lists all installed skills with name and description in chat
  • Surfaces installed skills in the slash command popover (type /) with a purple Sparkles icon and Skill type
  • Selecting a skill from the popover inserts Use the <skill-name> skill to to prompt the user to describe their intent, since skills are activated via the LLM calling loadSkill

Changes

  • skills_extension.rs: Made SkillMetadata public, added list_installed_skills() public function
  • mod.rs: Changed skills_extension from pub(crate) to pub
  • execute_commands.rs: Added /skills builtin command definition and handler
  • config_management.rs: Added Skill variant to CommandType, included skills in GET /config/slash_commands
  • types.gen.ts: Added 'Skill' to CommandType union
  • MentionPopover.tsx: Added Skill to type ordering, unified selection logic via getSelectionText helper
  • ItemIcon.tsx: Added Sparkles icon for Skill type

Test plan

  • Type /skills in chat — should list installed skills or show directory help if none
  • Type / in chat input — skills should appear in the popover with purple sparkle icons
  • Click a skill in the popover — should insert Use the <skill-name> skill to in the input
  • Verify builtins and recipes still work correctly in the popover

🤖 Generated with Claude Code

Copy link
Copy Markdown

@chatgpt-codex-connector chatgpt-codex-connector bot left a comment

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: d80ed7a7fd

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Copy link
Copy Markdown

@chatgpt-codex-connector chatgpt-codex-connector bot left a comment

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: bdc45e341c

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Add ability to view installed skills from the desktop UI. Skills now
appear in the slash command popover (/) with a purple Sparkles icon,
and a new /skills builtin command lists all installed skills in chat.

Uses the summon extension's discover_filesystem_sources to find
skills. Also regenerated the OpenAPI schema to include the new
Skill variant in CommandType.

Signed-off-by: Vincenzo Palazzo <[email protected]>
Co-Authored-By: Claude Opus 4.6 <[email protected]>
Copy link
Copy Markdown

@chatgpt-codex-connector chatgpt-codex-connector bot left a comment

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 59b0fe206d

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

vincenzopalazzo and others added 2 commits March 16, 2026 00:50
- Accept optional working_dir param in /config/slash_commands endpoint
  so skills are discovered from the session directory, not server cwd
- Use unique React keys (itemType-name) instead of item.extra to avoid
  duplicate key issues when skills share descriptions
- Add currentWorkingDir to useEffect dependency array

Signed-off-by: Vincenzo Palazzo <[email protected]>

Co-Authored-By: Claude Opus 4.6 <[email protected]>
Signed-off-by: Vincenzo Palazzo <[email protected]>

Co-Authored-By: Claude Opus 4.6 <[email protected]>
Copy link
Copy Markdown

@chatgpt-codex-connector chatgpt-codex-connector bot left a comment

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 8550add8d2

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

async fn handle_skills_command(&self) -> Result<Option<Message>> {
use super::platform_extensions::summon::{list_installed_sources, SourceKind};

let sources = list_installed_sources(None);
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P1 Badge Resolve /skills results from the active session directory

handle_skills_command always calls list_installed_sources(None), so /skills resolves local skills from the backend process cwd instead of the chat session’s working directory. In desktop/multi-session usage (for example after switching dirs per session), this can hide the active session’s .goose/skills and show unrelated skills from another path. Fresh evidence relative to the earlier thread: the new working_dir plumbing is only used in /config/slash_commands, while this command path still hardcodes None.

Useful? React with 👍 / 👎.

{displayItems.map((item, index) => (
<div
key={item.extra}
key={`${item.itemType}-${item.name}`}
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Use unique React keys for mention rows

Using ${item.itemType}-${item.name} as the row key is not unique in file browsing mode, because different files/directories often share the same basename (for example multiple README.md files under different folders). When that happens, React reuses the wrong list item instance and selection/highlight can drift during filtering or navigation. This regression was introduced by replacing the previous item.extra key, which is the full path for file entries.

Useful? React with 👍 / 👎.

Instead of adding external STT dependencies (Whisper, ElevenLabs),
voice messages are downloaded from Telegram, saved to a temp file, and
passed to Goose as a text prompt. Goose then uses its agent capabilities
(shell tools, CLI utilities) to discover and run whatever transcription
tool is available on the system.

Co-Authored-By: Claude Opus 4.6 <[email protected]>
Signed-off-by: Vincenzo Palazzo <[email protected]>
Copy link
Copy Markdown

@chatgpt-codex-connector chatgpt-codex-connector bot left a comment

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 271563e2e7

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

- Use actual MIME type from Telegram metadata in prompt and file
  extension instead of hardcoding OGG/Opus
- Add periodic cleanup of stale voice files (every 10 min, removes
  files older than 1 hour) to prevent disk space accumulation
- Derive file extension from MIME type (mp3, m4a, wav, etc.)
- Add tests for MIME-aware saving, prompt generation, and cleanup

Co-Authored-By: Claude Opus 4.6 <[email protected]>
Signed-off-by: Vincenzo Palazzo <[email protected]>
Copy link
Copy Markdown

@chatgpt-codex-connector chatgpt-codex-connector bot left a comment

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 6dfd8ed1cf

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

async fn handle_skills_command(&self) -> Result<Option<Message>> {
use super::platform_extensions::summon::{list_installed_sources, SourceKind};

let sources = list_installed_sources(None);
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P1 Badge Use session working dir when listing /skills

handle_skills_command calls list_installed_sources(None), which falls back to std::env::current_dir() instead of the active chat session directory. In desktop/multi-session flows where sessions switch directories, /skills will report skills from the backend process cwd, so local skills under the active session (e.g. .goose/skills) can be missed while unrelated skills are shown.

Useful? React with 👍 / 👎.

{displayItems.map((item, index) => (
<div
key={item.extra}
key={`${item.itemType}-${item.name}`}
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Restore unique keys for mention popover rows

Using ${item.itemType}-${item.name} as the React key is not unique for file/directory suggestions, because different paths commonly share the same basename (for example multiple README.md files). When this happens, React reuses the wrong row instance during filtering/navigation, which can cause highlight and selection to drift from the displayed item.

Useful? React with 👍 / 👎.

- Extract tuple return type into VoiceInfo struct to fix type-complexity
- Collapse nested if statements in cleanup_voice_files

Co-Authored-By: Claude Opus 4.6 <[email protected]>
Signed-off-by: Vincenzo Palazzo <[email protected]>
Copy link
Copy Markdown

@chatgpt-codex-connector chatgpt-codex-connector bot left a comment

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 5449ef341c

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

On Unix, set directory permissions to 0700 and file permissions to
0600 to prevent other local users from reading private voice content.

Co-Authored-By: Claude Opus 4.6 <[email protected]>
Signed-off-by: Vincenzo Palazzo <[email protected]>
Copy link
Copy Markdown

@chatgpt-codex-connector chatgpt-codex-connector bot left a comment

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: b54890f09a

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

async fn handle_skills_command(&self) -> Result<Option<Message>> {
use super::platform_extensions::summon::{list_installed_sources, SourceKind};

let sources = list_installed_sources(None);
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P1 Badge Use session working dir for /skills discovery

handle_skills_command resolves sources with list_installed_sources(None), which falls back to the backend process cwd instead of the active chat session directory. In multi-session desktop flows (after switching directories per session), /skills will list skills from the wrong project and omit the current session’s local .goose/.claude/.agents skills, so users get incorrect command output.

Useful? React with 👍 / 👎.

{displayItems.map((item, index) => (
<div
key={item.extra}
key={`${item.itemType}-${item.name}`}
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Restore unique keys for mention popover rows

Using ${item.itemType}-${item.name} as the React key is not unique for file/directory suggestions because different paths can share the same basename (for example multiple README.md entries). When that happens, React reuses the wrong row instance during filtering/navigation, which can desynchronize highlight/selection from the displayed item.

Useful? React with 👍 / 👎.

Copy link
Copy Markdown
Collaborator

@DOsinga DOsinga left a comment

Choose a reason for hiding this comment

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

Fix looks good — the one P1 codex flagged (resolving skills against the backend process cwd instead of the session's working directory) is now addressed: handle_skills_command passes the session's working_dir to list_installed_sources, consistent with how handle_compact_command already looks up session state. Everything else in the PR is clean.

Copy link
Copy Markdown

@chatgpt-codex-connector chatgpt-codex-connector bot left a comment

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: f6e371a123

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment on lines +147 to +150
let sources = list_installed_sources(working_dir.as_deref());
let skills: Vec<_> = sources
.iter()
.filter(|s| matches!(s.kind, SourceKind::Skill | SourceKind::BuiltinSkill))
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Enumerate skills without recipe/agent deduplication

handle_skills_command gets all sources via list_installed_sources(...) and only then filters to Skill/BuiltinSkill. That helper delegates to discover_filesystem_sources, which uses one shared seen set across recipes, agents, and skills and scans recipes first, so a same-named recipe/agent can suppress the skill before this filter runs. In that scenario, /skills (and the slash-command feed that uses the same helper) silently omits valid skills, so users cannot discover/select them.

Useful? React with 👍 / 👎.

"{}/file/bot{}/{}",
TELEGRAM_API_BASE, self.bot_token, file_path
);
let bytes = self.client.get(&download_url).send().await?.bytes().await?;
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Fail fast on non-2xx Telegram file downloads

The raw file download path reads response bytes without checking HTTP status. If Telegram returns a non-success code (for example transient 429 or missing-file 404), this will still persist the error payload as if it were audio and pass it to transcription, leading to confusing downstream failures instead of a clear download error. Add error_for_status() before reading bytes so failed downloads follow the existing error-handling path.

Useful? React with 👍 / 👎.

@vincenzopalazzo
Copy link
Copy Markdown
Contributor Author

Hello @DOsinga is this PR ready to go? or there is something left to do from my side?

@DOsinga DOsinga added this pull request to the merge queue Mar 26, 2026
Merged via the queue into block:main with commit 9feb3f3 Mar 26, 2026
21 checks passed
michaelneale added a commit that referenced this pull request Mar 26, 2026
* main: (337 commits)
  fix: replace panics with user-friendly errors in CLI session builder (#7901)
  fix: read GOOSE_CONTEXT_LIMIT from config.yaml, not just env vars (#7900)
  fix: deliver truncation notice as separate content block (#7899)
  fix: use platform-appropriate commands in developer extension instructions (#7898)
  fix: replace any with proper SVG types in icon components (#7873)
  chore: remove debug console.log statements, stale comments, and dead code (#8142)
  feat: Gemini OAuth provider (#8129)
  chore(deps): bump picomatch from 2.3.1 to 2.3.2 in /documentation (#8123)
  feat: show installed skills in UI (#7910)
  fix(deps): gate keyring platform features behind target-specific deps (#8039)
  chore(deps): bump yaml from 2.8.2 to 2.8.3 in /evals/open-model-gym/suite (#8124)
  fix: strip message wrapper in CLI session title generation (#7996)
  fix(providers): fall back to configured models when models endpoint fetch fails (#7530)
  chore(deps): bump brace-expansion from 5.0.3 to 5.0.5 in /evals/open-model-gym/suite (#8139)
  fix: prevent Ollama provider from hanging on tool-calling requests (#7723)
  fix: VMware Tanzu Platform provider - bug fixes, streaming, UI improvements (#8126)
  feat: allow GOOSE_CLI_SHOW_THINKING to be set in config.yaml (#8097)
  fix: GitHub Copilot auth fails to open browser in Desktop app (#6957) (#8019)
  fix(ci): produce .tar.gz archives for Zed ACP registry compatibility (#8054)
  feat: add GOOSE_SHOW_FULL_OUTPUT config to disable tool output truncation (#7919)
  ...

# Conflicts:
#	crates/goose/src/providers/formats/openai.rs
@vincenzopalazzo vincenzopalazzo deleted the claude/elastic-kirch branch March 27, 2026 08:25
hydrosquall pushed a commit to hydrosquall/goose that referenced this pull request Mar 31, 2026
Signed-off-by: Vincenzo Palazzo <[email protected]>
Signed-off-by: Douwe Osinga <[email protected]>
Co-authored-by: Claude Opus 4.6 <[email protected]>
Co-authored-by: Douwe Osinga <[email protected]>
Signed-off-by: Cameron Yick <[email protected]>
blackgirlbytes pushed a commit that referenced this pull request Apr 2, 2026
* main: (337 commits)
  fix: replace panics with user-friendly errors in CLI session builder (#7901)
  fix: read GOOSE_CONTEXT_LIMIT from config.yaml, not just env vars (#7900)
  fix: deliver truncation notice as separate content block (#7899)
  fix: use platform-appropriate commands in developer extension instructions (#7898)
  fix: replace any with proper SVG types in icon components (#7873)
  chore: remove debug console.log statements, stale comments, and dead code (#8142)
  feat: Gemini OAuth provider (#8129)
  chore(deps): bump picomatch from 2.3.1 to 2.3.2 in /documentation (#8123)
  feat: show installed skills in UI (#7910)
  fix(deps): gate keyring platform features behind target-specific deps (#8039)
  chore(deps): bump yaml from 2.8.2 to 2.8.3 in /evals/open-model-gym/suite (#8124)
  fix: strip message wrapper in CLI session title generation (#7996)
  fix(providers): fall back to configured models when models endpoint fetch fails (#7530)
  chore(deps): bump brace-expansion from 5.0.3 to 5.0.5 in /evals/open-model-gym/suite (#8139)
  fix: prevent Ollama provider from hanging on tool-calling requests (#7723)
  fix: VMware Tanzu Platform provider - bug fixes, streaming, UI improvements (#8126)
  feat: allow GOOSE_CLI_SHOW_THINKING to be set in config.yaml (#8097)
  fix: GitHub Copilot auth fails to open browser in Desktop app (#6957) (#8019)
  fix(ci): produce .tar.gz archives for Zed ACP registry compatibility (#8054)
  feat: add GOOSE_SHOW_FULL_OUTPUT config to disable tool output truncation (#7919)
  ...

# Conflicts:
#	crates/goose/src/providers/formats/openai.rs
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