Skip to content

Add UI for managing skills#2729

Draft
katinthehatsite wants to merge 35 commits intotrunkfrom
add/ui-for-managing-skills
Draft

Add UI for managing skills#2729
katinthehatsite wants to merge 35 commits intotrunkfrom
add/ui-for-managing-skills

Conversation

@katinthehatsite
Copy link
Contributor

@katinthehatsite katinthehatsite commented Mar 9, 2026

Related issues

How AI was used in this PR

I used it to get the basic idea and implementation from https://github.com/Automattic/studio/pull/2511/changes#diff-c69fa338d4e3c20084125a9fa7186cf40116a7460210922cfd4b4021935f4c18

Proposed Changes

This PR adds Skills tab to the AI Settings modal which allows to install and manage diffeent skills.

Testing Instructions

  • Pull the changes from this branch
  • Start Studio with npm start
  • Enable the feature flag for Agents Suite feature in the topbar menu under Electron > Feature Flags
  • Navigate to the Assistant tab
  • Click on the three dots in the chat input field
  • Open the AI Settings modal
Screenshot 2026-03-11 at 3 13 05 PM
  • Test different options in the Skills tab such as installing and removing skills and confirm it works as expected

Pre-merge Checklist

  • Have you checked for TypeScript, React or other console errors?

@katinthehatsite katinthehatsite marked this pull request as draft March 9, 2026 12:30
Base automatically changed from fix/add-ui-for-agents=md to trunk March 10, 2026 16:14
@katinthehatsite katinthehatsite requested a review from a team March 11, 2026 14:55
@katinthehatsite katinthehatsite marked this pull request as ready for review March 11, 2026 14:55
Copy link
Contributor

@nightnei nightnei left a comment

Choose a reason for hiding this comment

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

I tried a few times using Install All button and at some moment it fails always with:
Image

Does it work well for you?

</div>
</div>
<div className="flex items-center gap-2 flex-shrink-0">
<div className={ 'flex items-center gap-2 flex-shrink-0' }>
Copy link
Contributor

Choose a reason for hiding this comment

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

NIT - t seems it's leftover

Suggested change
<div className={ 'flex items-center gap-2 flex-shrink-0' }>
<div className="flex items-center gap-2 flex-shrink-0">

@@ -0,0 +1,54 @@
/**
Copy link
Contributor

Choose a reason for hiding this comment

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

We have many redundant comments or info in some comments, for example:

  1. Required: / Optional: - it's just a duplication of info which we already have with type definitions
  2. Or for example /** Skill name */ is redundant comment, sine name property inside AvailableSkill is self-explanatory.
    So I would remove some comments and adjusted other.

export const DEFAULT_SKILLS_REPO = 'WordPress/agent-skills';

/** Default branch to download from */
export const DEFAULT_BRANCH = 'trunk';
Copy link
Contributor

Choose a reason for hiding this comment

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

NIT - I would keep the name more specific instead of a generic name

Suggested change
export const DEFAULT_BRANCH = 'trunk';
export const DEFAULT_SKILLS_REPO_BRANCH = 'trunk';

<>
<span className="inline-flex items-center gap-1 text-[11px] text-green-700 bg-green-50 px-2 py-0.5 rounded-full">
<Icon icon={ check } size={ 12 } />
{ __( 'Installed' ) }
Copy link
Contributor

Choose a reason for hiding this comment

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

Personal feeling - we have different lists for already installed and not installed skills, so I find this "Installed" badge redundant. Especially when we have a few installed Skills.

Image

disabled={ isInstalling }
className="text-xs py-1 px-2"
>
{ isInstalling ? __( 'Installing...' ) : __( 'Install' ) }
Copy link
Contributor

Choose a reason for hiding this comment

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

Small bug - when you quickly click on the "Install" button and then immediately click on another "Install" button, the disabled state and "Installing" text disappear for the previous item, which was in progress.

const [ installingPath, setInstallingPath ] = useState< string | null >( null );

const installedNames = useMemo(
() => new Set( installedSkills.map( ( s ) => s.name ) ),
Copy link
Contributor

Choose a reason for hiding this comment

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

Just out of curiosity - is there some reason for using Set?

Copy link
Contributor

Choose a reason for hiding this comment

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

Also, map + Set is cheap for normal list sizes and the same for filter inside uninstalledSkills, so I see it just as unnecessary lines of code, but it's completely up to you, just sharing my thoughts.

}

export async function listAvailableSkills(
repo: string = DEFAULT_SKILLS_REPO,
Copy link
Contributor

Choose a reason for hiding this comment

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

I see that we use the repo property everywhere. I don't see an opportunity to provide a custom repo in UI, so I wonder - do we expect to provide an opportunity for different/custom repos? If no, then I would go with removing this property in all places, to keep code simple, at this point. The same with branch.

disabled={ isInstalling }
className="text-[11px] !py-0 !px-0 normal-case !font-medium"
>
{ isInstalling ? __( 'Installing...' ) : __( 'Install All' ) }
Copy link
Contributor

Choose a reason for hiding this comment

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

When we click "Install All' - let's disable all Install buttons.

@katinthehatsite
Copy link
Contributor Author

I tried a few times using Install All button and at some moment it fails always with:

@nightnei Let's hold off with this PR for now. I think we will implement #2741 first as the base for the backend and then rebase this one to the UI based on the discussion here #2741 (comment)

I will mark this as draft for now to avoid confusion.

@katinthehatsite katinthehatsite marked this pull request as draft March 12, 2026 14:35
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