Skip to content

feat: platform extension migrator + code mode rename#6611

Merged
alexhancock merged 2 commits intomainfrom
alexhancock/code-mode-naming
Jan 29, 2026
Merged

feat: platform extension migrator + code mode rename#6611
alexhancock merged 2 commits intomainfrom
alexhancock/code-mode-naming

Conversation

@alexhancock
Copy link
Collaborator

@alexhancock alexhancock commented Jan 21, 2026

Summary

At present, it's impossible to rename or edit platform extensions in the stored config. For three reasons:

  1. We use the "name" as both the id and the display name
  2. We never update the values in config.yaml if the platform extension is already there
  3. We have no concept of versions for each extension

This PR introduces two new values that make it possible to update the config stored in a user's configuration file for platform extensions - display_name (shows in the UI, and is not coupled to the name identifier) and version which can be bumped when we have made config updates to an extension to have it take effect in the config file.

It also introduces the first migration which is to rename "Code Execution" to "Code Mode" per the request in #6581

This can also be used in the future to rename or edit other extension config (descriptions, default enabled value, etc)

Type of Change

  • Feature
  • Bug fix
  • Refactor / Code quality
  • Performance improvement
  • Documentation
  • Tests
  • Security fix
  • Build / Release
  • Other (specify below)

AI Assistance

Goose

Testing

Manually reset config file after changes to previous default state, then launched new version of goose and observed new config file and updated values in the UI

Related Issues

#6581

Screenshots/Demos (for UX changes)

Before:
config.yaml

DATABRICKS_HOST: https://block-lakehouse-production.cloud.databricks.com/
GOOSE_PROVIDER: databricks
GOOSE_MODEL: goose-claude-4-5-opus
extensions:
  developer:
    enabled: true
    type: builtin
    name: developer
    description: General development tools useful for software engineering.
    display_name: Developer
    timeout: 300
    bundled: true
    available_tools: []
  chatrecall:
    enabled: false
    type: platform
    name: chatrecall
    description: Search past conversations and load session summaries for contextual memory
    bundled: true
    available_tools: []
  todo:
    enabled: true
    type: platform
    name: todo
    description: Enable a todo list for goose so it can keep track of what it is doing
    bundled: true
    available_tools: []
  skills:
    enabled: true
    type: platform
    name: skills
    description: Load and use skills from relevant directories
    bundled: true
    available_tools: []
  code_execution:
    enabled: false
    type: platform
    name: code_execution
    description: Execute JavaScript code in a sandboxed environment
    bundled: true
    available_tools: []
  extensionmanager:
    enabled: true
    type: platform
    name: Extension Manager
    description: Enable extension management tools for discovering, enabling, and disabling extensions
    bundled: true
    available_tools: []
  computercontroller:
    enabled: false
    type: builtin
    name: computercontroller
    description: General computer control tools that don't require you to be a developer or engineer.
    display_name: Computer Controller
    timeout: 300
    bundled: true
    available_tools: []
  autovisualiser:
    enabled: false
    type: builtin
    name: autovisualiser
    description: Data visualization and UI generation tools
    display_name: Auto Visualiser
    timeout: 300
    bundled: true
    available_tools: []
  memory:
    enabled: false
    type: builtin
    name: memory
    description: Teach goose your preferences as you go.
    display_name: Memory
    timeout: 300
    bundled: true
    available_tools: []
  tutorial:
    enabled: false
    type: builtin
    name: tutorial
    description: Access interactive tutorials and guides
    display_name: Tutorial
    timeout: 300
    bundled: true
    available_tools: []

After:

config.yaml

DATABRICKS_HOST: https://block-lakehouse-production.cloud.databricks.com/
GOOSE_PROVIDER: databricks
GOOSE_MODEL: goose-claude-4-5-opus
extensions:
  developer:
    enabled: true
    type: builtin
    name: developer
    description: General development tools useful for software engineering.
    display_name: Developer
    timeout: 300
    bundled: true
    available_tools: []
  chatrecall:
    enabled: false
    type: platform
    name: chatrecall
    description: Search past conversations and load session summaries for contextual memory
    display_name: null
    version: 0
    bundled: true
    available_tools: []
  todo:
    enabled: true
    type: platform
    name: todo
    description: Enable a todo list for goose so it can keep track of what it is doing
    display_name: null
    version: 0
    bundled: true
    available_tools: []
  skills:
    enabled: true
    type: platform
    name: skills
    description: Load and use skills from relevant directories
    display_name: null
    version: 0
    bundled: true
    available_tools: []
  code_execution:
    enabled: false
    type: platform
    name: code_execution
    description: Goose will make extension calls through code execution, saving tokens
    display_name: Code Mode
    version: 1
    bundled: true
    available_tools: []
  extensionmanager:
    enabled: true
    type: platform
    name: Extension Manager
    description: Enable extension management tools for discovering, enabling, and disabling extensions
    display_name: null
    version: 0
    bundled: true
    available_tools: []
  computercontroller:
    enabled: false
    type: builtin
    name: computercontroller
    description: General computer control tools that don't require you to be a developer or engineer.
    display_name: Computer Controller
    timeout: 300
    bundled: true
    available_tools: []
  autovisualiser:
    enabled: false
    type: builtin
    name: autovisualiser
    description: Data visualization and UI generation tools
    display_name: Auto Visualiser
    timeout: 300
    bundled: true
    available_tools: []
  memory:
    enabled: false
    type: builtin
    name: memory
    description: Teach goose your preferences as you go.
    display_name: Memory
    timeout: 300
    bundled: true
    available_tools: []
  tutorial:
    enabled: false
    type: builtin
    name: tutorial
    description: Access interactive tutorials and guides
    display_name: Tutorial
    timeout: 300
    bundled: true
    available_tools: []
GOOSE_TELEMETRY_ENABLED: true

Updated Name and Description for the Code Mode extension in Desktop:

Screenshot 2026-01-21 at 12 14 28 PM

Copilot AI review requested due to automatic review settings January 21, 2026 17:15
Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

This PR introduces versioning and migration support for platform extensions, enabling future updates to extension configurations. The primary changes include renaming "Code Execution" to "Code Mode" with an updated description, and adding display_name and version fields to platform extensions.

Changes:

  • Added display_name and version fields to platform extension configuration
  • Implemented migration logic that automatically updates platform extensions when version increases
  • Renamed "Code Execution" extension to "Code Mode" with improved description
  • Updated TypeScript types and OpenAPI schema to reflect new fields

Reviewed changes

Copilot reviewed 11 out of 11 changed files in this pull request and generated 1 comment.

Show a summary per file
File Description
crates/goose/src/agents/extension.rs Added display_name and version fields to PlatformExtensionDef and ExtensionConfig::Platform; updated all platform extensions with display names and versions
crates/goose/src/agents/code_execution_extension.rs Updated server title from "Code Execution" to "Code Mode"
crates/goose/src/config/extensions.rs Implemented migration logic that compares versions and updates platform extensions while preserving user's enabled state
crates/goose/src/recipe/recipe_extension_adapter.rs Added display_name and version fields to recipe deserialization for platform extensions
crates/goose/tests/agent.rs Updated test fixtures to include new display_name and version fields
crates/goose-cli/src/session/mod.rs Added new fields when creating platform extension configs in CLI
crates/goose-acp/src/server.rs Added new fields when creating platform extension configs in ACP server
ui/desktop/openapi.json Updated OpenAPI schema to include optional display_name and version for platform extensions
ui/desktop/src/api/types.gen.ts Generated TypeScript types reflecting schema changes
ui/desktop/src/components/settings/extensions/subcomponents/ExtensionList.tsx Updated getFriendlyTitle to use display_name for both builtin and platform extensions
ui/desktop/src/components/schedule/ScheduleModal.tsx Added 'platform' to extension type union and updated display_name handling

}

if needs_save {
save_extensions_map(extensions_map.clone());
Copy link

Copilot AI Jan 21, 2026

Choose a reason for hiding this comment

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

The clone operation is unnecessary here. Since extensions_map is returned at the end of the function, you could pass it by value to save_extensions_map instead of cloning it. Consider changing save_extensions_map to take ownership and return the map, or restructure the logic to avoid the clone.

Copilot uses AI. Check for mistakes.
Copy link
Collaborator

@jamadeo jamadeo left a comment

Choose a reason for hiding this comment

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

This makes sense to me. But what if we instead just had a "config migrator" that did anything necessary when it sees the config version doesn't match?

It could run any time we load the config file, and migrations could manipulate the document however necessary, including something like this

Copy link
Collaborator

@michaelneale michaelneale left a comment

Choose a reason for hiding this comment

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

I think this makes sense - maybe @jamadeo or @DOsinga could think over what the version of things means and if there are unexpected side effects, but I think this makes sense.

@alexhancock
Copy link
Collaborator Author

@jamadeo @michaelneale That's a good idea. A versionless generate-diff-and-maybe-update seems better than putting version fields in if it can work. I will attempt tomorrow morning and update this PR.

Normally I would just merge and try to improve but this is going to write version values to config files, so I will try to improve it in this way before merge.

@alexhancock alexhancock force-pushed the alexhancock/code-mode-naming branch from 26d851b to 40ccbee Compare January 23, 2026 19:17
@alexhancock
Copy link
Collaborator Author

@jamadeo updated to a versionless approach. good call!

Copilot AI review requested due to automatic review settings January 27, 2026 17:32
@alexhancock alexhancock force-pushed the alexhancock/code-mode-naming branch from 40ccbee to 0e994f7 Compare January 27, 2026 17:32
Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 11 out of 11 changed files in this pull request and generated 3 comments.

Comment on lines 86 to 90
name: def.name.to_string(),
description: def.description.to_string(),
display_name: Some(def.display_name.to_string()),
bundled: Some(true),
available_tools: Vec::new(),
Copy link

Copilot AI Jan 27, 2026

Choose a reason for hiding this comment

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

This migration overwrites any existing bundled/available_tools settings for platform extensions (resetting to Some(true) and an empty tool list), which can unintentionally broaden tool availability and discard user config; preserve the existing values when present and only update the fields you intend to migrate (e.g., description/display_name).

Copilot uses AI. Check for mistakes.
Comment on lines 166 to 170
pub struct PlatformExtensionDef {
pub name: &'static str,
pub display_name: &'static str,
pub description: &'static str,
pub default_enabled: bool,
Copy link

Copilot AI Jan 27, 2026

Choose a reason for hiding this comment

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

The PR description mentions adding per-extension version and version-driven migrations, but the platform extension definition/config only adds display_name (no version field), so migrations are currently based on field diffs; either implement the version field end-to-end (schema + config + migration logic) or update the PR description to match the actual behavior.

Copilot uses AI. Check for mistakes.
Comment on lines 99 to 101
if needs_save {
save_extensions_map(extensions_map.clone());
}
Copy link

Copilot AI Jan 27, 2026

Choose a reason for hiding this comment

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

get_extensions_map() now writes to disk during reads; if save_extensions_map fails, the migration silently won’t persist and callers still proceed with the in-memory map, so consider returning/propagating a Result (or at least surfacing a warning/error) so migration failures aren’t hidden.

Copilot uses AI. Check for mistakes.
@jamadeo
Copy link
Collaborator

jamadeo commented Jan 27, 2026

@alexhancock I was actually thinking that this could live in the config load itself. Then any time we need to change the config structure we can do it here.

WDYT?

Copilot AI review requested due to automatic review settings January 27, 2026 19:29
@alexhancock alexhancock force-pushed the alexhancock/code-mode-naming branch from 92f9e59 to 61cae9f Compare January 27, 2026 19:29
Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 14 out of 14 changed files in this pull request and generated 3 comments.

Comment on lines +298 to +299
if let Err(e) = self.save_values(values.clone()) {
tracing::warn!("Failed to save migrated config: {}", e);
Copy link

Copilot AI Jan 27, 2026

Choose a reason for hiding this comment

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

Config::load() may write the migrated config back to disk without taking self.guard, which can race with concurrent set_param/delete calls and cause lost updates; take the same mutex around the migration save (or route through a guarded write path).

Suggested change
if let Err(e) = self.save_values(values.clone()) {
tracing::warn!("Failed to save migrated config: {}", e);
// Persist migrated config under the same guard used by other writers
match self.guard.lock() {
Ok(_guard) => {
if let Err(e) = self.save_values(values.clone()) {
tracing::warn!("Failed to save migrated config: {}", e);
}
}
Err(e) => {
tracing::warn!("Failed to acquire config lock for migrated save: {}", e);
}

Copilot uses AI. Check for mistakes.
Comment on lines +8 to +12
pub fn run_migrations(config: &mut Mapping) -> bool {
let mut changed = false;
changed |= migrate_platform_extensions(config);
changed
}
Copy link

Copilot AI Jan 27, 2026

Choose a reason for hiding this comment

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

The PR description and example config show a per-extension version field used to drive migrations, but this PR only adds display_name (no version field in ExtensionConfig, OpenAPI, or the migration logic); either implement the versioned migration mechanism or update the PR description/screenshots to match the actual behavior.

Copilot uses AI. Check for mistakes.
@alexhancock alexhancock force-pushed the alexhancock/code-mode-naming branch from 61cae9f to 2f4a46d Compare January 27, 2026 21:53
Copilot AI review requested due to automatic review settings January 28, 2026 18:49
@alexhancock alexhancock force-pushed the alexhancock/code-mode-naming branch from 2f4a46d to ea693e8 Compare January 28, 2026 18:49
Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 14 out of 14 changed files in this pull request and generated no new comments.

@alexhancock alexhancock force-pushed the alexhancock/code-mode-naming branch from ea693e8 to d7fcf15 Compare January 29, 2026 15:47
Copilot AI review requested due to automatic review settings January 29, 2026 21:01
@alexhancock alexhancock force-pushed the alexhancock/code-mode-naming branch from d7fcf15 to d1979b1 Compare January 29, 2026 21:01
Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 14 out of 14 changed files in this pull request and generated no new comments.

@alexhancock alexhancock merged commit edd0109 into main Jan 29, 2026
24 checks passed
@alexhancock alexhancock deleted the alexhancock/code-mode-naming branch January 29, 2026 22:12
zanesq added a commit that referenced this pull request Jan 29, 2026
…sion-session

* 'main' of github.com:block/goose:
  feat: platform extension migrator + code mode rename (#6611)
  feat: CLI flag to skip loading profile extensions (#6780)
  Swap canonical model from openrouter to models.dev (#6625)
  Hook thinking status (#6815)
  Fetch new skills hourly (#6814)
lifeizhou-ap added a commit that referenced this pull request Jan 29, 2026
* main:
  docs: usage data collection (#6822)
  feat: platform extension migrator + code mode rename (#6611)
  feat: CLI flag to skip loading profile extensions (#6780)
  Swap canonical model from openrouter to models.dev (#6625)
  Hook thinking status (#6815)
  Fetch new skills hourly (#6814)
  copilot instructions: Update "No prerelease docs" instruction (#6795)
  refactor: centralize audience filtering before providers receive messages (#6728)
  update doc to remind contributors to activate hermit and document minimal npm and node version (#6727)
  nit: don't spit out compaction when in term mode as it fills up the screen (#6799)
  fix: correct tool support detection in Tetrate provider model fetching (#6808)
  Session manager fixes (#6809)
  fix(desktop): handle quoted paths with spaces in extension commands (#6430)
  fix: we can default gooseignore without writing it out (#6802)
  fix broken link (#6810)
  docs: add Beads MCP extension tutorial (#6792)
  feat(goose): add support for AWS_BEARER_TOKEN_BEDROCK environment variable (#6739)
zanesq added a commit that referenced this pull request Jan 30, 2026
* 'main' of github.com:block/goose:
  Fix: Small update UI settings prompt injection (#6830)
  Remove autogenerated .gooseignore files that don't belong in repo (#6824)
  Fix case-insensitive matching for builtin extension names (#6825)
  docs: cli newline keybinding (#6823)
  Update version to 1.22.0 (#6821)
  Refactor: move persisting extension to session outside of route (#6685)
  acp: load configured extensions and refactor tests (#6803)
  docs: usage data collection (#6822)
  feat: platform extension migrator + code mode rename (#6611)
  feat: CLI flag to skip loading profile extensions (#6780)
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.

3 participants