Skip to content

add extensions settings page and context panel widget#8540

Merged
morgmart merged 8 commits intomainfrom
extensions
Apr 15, 2026
Merged

add extensions settings page and context panel widget#8540
morgmart merged 8 commits intomainfrom
extensions

Conversation

@morgmart
Copy link
Copy Markdown
Collaborator

@morgmart morgmart commented Apr 14, 2026

Category: new-feature
User Impact: Users can now view, search, add, edit, enable/disable, and delete MCP extensions directly from the Goose desktop app settings and see active extensions in the chat side panel.

Problem: The Tauri app had no way to manage extensions. Users had to manually edit config.yaml to add, remove, or configure MCP extensions — a workflow that's error-prone and invisible to non-technical users.

Solution: Built an end-to-end extensions management feature with a settings page for full CRUD operations and a lightweight chat widget showing active extensions. The backend reads/writes raw YAML mappings to preserve existing config structure, and the frontend uses config_key (the actual YAML key) for all operations to avoid lossy name-to-key conversions.

Note: Initial UI interface. May need logic redesign.

File changes

ui/goose2/src-tauri/src/commands/extensions.rs
New Tauri commands for listing, adding, removing, and toggling extensions. Includes YAML-to-JSON conversion utilities and a name_to_key function for generating config keys from display names.

ui/goose2/src-tauri/src/commands/mod.rs
Registers the new extensions command module.

ui/goose2/src-tauri/src/lib.rs
Wires up the four extension commands in the Tauri handler macro.

ui/goose2/src-tauri/src/services/goose_config.rs
Adds get_extensions_raw() and set_extensions_raw() methods to read/write the extensions section of config.yaml as raw YAML mappings.

ui/goose2/src/features/extensions/types.ts
Defines TypeScript types for all extension config variants (stdio, builtin, streamable_http, sse) and the shared getDisplayName helper.

ui/goose2/src/features/extensions/api/extensions.ts
Frontend API layer wrapping Tauri invoke() calls, plus a nameToKey utility aligned with the Rust backend.

ui/goose2/src/features/extensions/ui/ExtensionsSettings.tsx
Main settings page component with search, sorted extension lists (enabled/available), and handlers for toggle, add, edit, rename, and delete with toast error feedback and name collision detection.

ui/goose2/src/features/extensions/ui/ExtensionItem.tsx
Individual extension row component with toggle switch, type badge, and configure button for non-bundled extensions.

ui/goose2/src/features/extensions/ui/ExtensionModal.tsx
Add/edit modal for extensions supporting stdio and HTTP types, environment variables, timeout, and delete. Includes save-in-progress state to prevent double submissions.

ui/goose2/src/features/chat/ui/widgets/ExtensionsWidget.tsx
Chat context panel widget showing enabled extensions with inline search, auto-refresh on window focus, and scrollable list.

ui/goose2/src/features/chat/ui/ContextPanel.tsx
Swaps the placeholder McpServersWidget for the new ExtensionsWidget.

ui/goose2/src/features/chat/ui/widgets/McpServersWidget.tsx
Removed — replaced by ExtensionsWidget.

ui/goose2/src/features/settings/ui/SettingsModal.tsx
Adds "Extensions" to the settings navigation sidebar.

ui/goose2/src/shared/ui/input.tsx
Adds a ghost variant to the Input component for borderless, ring-free inline inputs.

ui/goose2/src/shared/i18n/locales/en/chat.json
New translation keys for the extensions widget (title, search, empty states).

ui/goose2/src/shared/i18n/locales/en/settings.json
New translation keys for the extensions settings page (fields, types, errors, nav).

ui/goose2/src/shared/i18n/locales/es/chat.json
Spanish translations for the extensions widget.

ui/goose2/src/shared/i18n/locales/es/settings.json
Spanish translations for the extensions settings page.

Reproduction Steps

  1. Run the Tauri app (pnpm tauri dev from ui/goose2)
  2. Open Settings and click "Extensions" in the sidebar
  3. Verify you see your configured extensions split into Enabled and Available sections
  4. Search by name, description, or type — list should filter in real time
  5. Click the gear icon on a non-bundled extension to edit it, change the name, and save
  6. Click "Add Extension" to create a new stdio or HTTP extension
  7. Toggle an extension on/off and verify it persists after closing settings
  8. In a chat, open the context panel — the Extensions widget should show enabled extensions with a search bar
  9. Switch between settings and chat — the widget should auto-refresh on focus
Screenshot 2026-04-14 at 4 07 32 PM Screenshot 2026-04-14 at 4 07 41 PM

Replace the placeholder MCP Servers widget with a fully functional
Extensions system. Users can view, search, add, edit, enable/disable,
and delete extensions directly from Settings. The context panel shows
active extensions. Backend uses config_key from YAML for reliable
operations instead of re-deriving keys from display names.

Signed-off-by: morgmart <98432065+morgmart@users.noreply.github.com>
Add inline search filtering, max-height with overflow scroll, and
increased row spacing to the context panel extensions widget. Remove
focus ring from the search input.

Signed-off-by: morgmart <98432065+morgmart@users.noreply.github.com>
Address 11 edge cases from QA review:
- Toast notifications on toggle/save/delete failures
- Use config_key as React key to prevent wrong-item bugs
- Disable Save button when required fields are empty
- Prevent double-click duplicate submissions
- Guard against missing description in search filters
- Detect name collisions when adding extensions
- Show "no results" message for empty search
- Refresh widget on window focus after settings changes
- Stable IDs for env var rows to prevent value scrambling
- Handle SSE extensions gracefully in edit modal
- Backend remove_extension returns error if key not found

Signed-off-by: morgmart <98432065+morgmart@users.noreply.github.com>
Align nameToKey JS/Rust logic, extract shared getDisplayName helper,
replace raw HTML elements with design system components, add ghost
variant to Input, fix untranslated aria-label, and remove dead i18n key.

Signed-off-by: morgmart <98432065+morgmart@users.noreply.github.com>
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: d0089d592b

ℹ️ 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 thread ui/goose2/src/features/extensions/ui/ExtensionsSettings.tsx Outdated
Comment thread ui/goose2/src/features/extensions/ui/ExtensionModal.tsx Outdated
Always remove old entry by config_key on edit (not just rename) to
prevent duplicates when config_key diverges from nameToKey(name).
Make modal submit/delete async with try/finally to reset isSaving.

Signed-off-by: morgmart <98432065+morgmart@users.noreply.github.com>
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: 543d0d91bb

ℹ️ 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 thread ui/goose2/src/features/extensions/ui/ExtensionModal.tsx
Comment thread ui/goose2/src/features/extensions/ui/ExtensionsSettings.tsx Outdated
Comment thread ui/goose2/src-tauri/src/commands/extensions.rs Outdated
…ries

Spread original extension fields when saving edits to preserve headers,
env_keys, and other fields not exposed in the modal. Reverse save order
to add-then-remove so a failed write never deletes the original config.
Skip non-object YAML entries in list_extensions to prevent frontend crashes.

Signed-off-by: morgmart <98432065+morgmart@users.noreply.github.com>
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: 10331f1a5b

ℹ️ 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 thread ui/goose2/src-tauri/src/commands/extensions.rs
Comment thread ui/goose2/src/features/extensions/ui/ExtensionItem.tsx
Restrict the edit button to stdio and streamable_http extensions to
prevent corrupting unsupported types like frontend or inline_python.

Signed-off-by: morgmart <98432065+morgmart@users.noreply.github.com>
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: 139dc016c5

ℹ️ 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 thread ui/goose2/src-tauri/src/commands/extensions.rs
Filter out malformed extension entries that lack a type field to
prevent frontend crashes, and default enabled to false if absent.

Signed-off-by: morgmart <98432065+morgmart@users.noreply.github.com>
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: 08a599cc5f

ℹ️ 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 thread ui/goose2/src/features/extensions/ui/ExtensionModal.tsx
@morgmart morgmart added this pull request to the merge queue Apr 15, 2026
Merged via the queue into main with commit c9507ba Apr 15, 2026
37 of 39 checks passed
@morgmart morgmart deleted the extensions branch April 15, 2026 17:07
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