feat(site/src/pages/AgentsPage): add download and export for personal skills - #28032
Open
Shelnutt2 wants to merge 2 commits into
Open
feat(site/src/pages/AgentsPage): add download and export for personal skills#28032Shelnutt2 wants to merge 2 commits into
Shelnutt2 wants to merge 2 commits into
Conversation
Contributor
Documentation CheckUpdates Needed
Automated review via Coder Agents |
Comment on lines
+189
to
+220
| const handleDownload = async (skill: UserSkillMetadata) => { | ||
| if (downloadingSkillName) { | ||
| return; | ||
| } | ||
| setDownloadingSkillName(skill.name); | ||
| try { | ||
| await downloadPersonalSkillFile(skill.name, fetchSkillContent); | ||
| } catch (error) { | ||
| toast.error( | ||
| getErrorMessage(error, "Failed to download personal skill."), | ||
| { | ||
| description: getErrorDetail(error), | ||
| }, | ||
| ); | ||
| } | ||
| setDownloadingSkillName(undefined); | ||
| }; | ||
|
|
||
| const handleExportAll = async () => { | ||
| if (isExportingAll || skills.length === 0) { | ||
| return; | ||
| } | ||
| setIsExportingAll(true); | ||
| try { | ||
| await exportPersonalSkillsArchive(skills, fetchSkillContent); | ||
| } catch (error) { | ||
| toast.error(getErrorMessage(error, "Failed to export personal skills."), { | ||
| description: getErrorDetail(error), | ||
| }); | ||
| } | ||
| setIsExportingAll(false); | ||
| }; |
Contributor
There was a problem hiding this comment.
Can we not make use of TanStack Query's useMutation to avoid having to handle the setIsExportingAll(true/false) stuff we're doing here?
Contributor
Author
There was a problem hiding this comment.
Good call. Replaced the manual setIsExportingAll/setDownloadingSkillName state with two useMutations (downloadMutation, exportAllMutation). Loading state now comes from the mutations: isExportingAll is exportAllMutation.isPending, and the per-row spinner uses downloadMutation.isPending ? downloadMutation.variables : undefined. Errors are handled in each mutation's onError. Done in 66df791.
Posted by Coder Agents.
DanielleMaywood
approved these changes
Aug 11, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Adds a way to get personal skills back out of Coder Agents as files, so
sharing a skill no longer means pasting
SKILL.mdby hand.Downloadaction on each row of the Personalskills settings page saves that skill's
SKILL.mdas<name>.md.<name>/SKILL.md) and downloadspersonal-skills.zip.Scope is personal skills only (workspace/filesystem skills are read-only
in chat and out of scope). No backend changes: the single-skill content
endpoint (
GET /api/experimental/users/{user}/skills/{skillName}) alreadyreturns full content, so the view fetches on demand and downloads with
file-saver, zipping withjszip(both existing deps, matchingDownloadLogsDialog).Changes
AgentSettingsPersonalSkillsPageView.tsx:Downloadper-row button (withper-row spinner) and an
Export allheader button (disabled when empty orloading).
AgentSettingsPersonalSkillsPage.tsx: container handlers that fetchcontent via
queryClient.fetchQuery(userSkill(name))and trigger thedownload/zip, with
toasterror handling. Download logic is extracted tomodule-level helpers to stay React Compiler friendly.
AgentSettingsPersonalSkillsPageView.stories.tsx: interaction storiesasserting
onDownload/onExportAllfire, plus loading-state stories.Testing
pnpm check(biome),pnpm lint:types(tsc), React Compiler check, andStorybook interaction tests (22 passed) all pass locally.
make pre-commitpassed.Closes CODAGT-918.
Implementation plan
Problem
Users can create, edit, and delete personal skills in Agent settings, but
there is no way to get a skill back out as a file. The only workaround was to
paste the
SKILL.mdcontent by hand.Decisions (confirmed with requester)
Approach (frontend-only, additive)
No backend changes: the single-skill content endpoint already exists. The
view stays presentational and exposes new callbacks; the container fetches
content and performs the download, mirroring how Edit/Delete already split
between view and container.
spinner while its own row is downloading.
or while loading.
saveAs(<name>.md); exportall fetches every skill, adds each as
<name>/SKILL.mdto aJSZip,generates a blob, and
saveAs(personal-skills.zip). Failures surface viatoast.error.surface).
Out of scope
read-only in chat, not user-owned data.
read_skilltool output: possiblefollow-up, different surface and interaction model.
Opened by Coder Agents on behalf of @Shelnutt2.