mirror of
https://github.com/coder/coder.git
synced 2026-10-25 17:53:46 +08:00
## Summary
Adds a way to get personal skills back out of Coder Agents as files, so
sharing a skill no longer means pasting `SKILL.md` by hand.
- **Per-skill Download**: a `Download` action on each row of the
*Personal
skills* settings page saves that skill's `SKILL.md` as `<name>.md`.
- **Export all**: a header button zips every personal skill (each as
`<name>/SKILL.md`) and downloads `personal-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}`)
already
returns full content, so the view fetches on demand and downloads with
`file-saver`, zipping with `jszip` (both existing deps, matching
`DownloadLogsDialog`).
## Changes
- `AgentSettingsPersonalSkillsPageView.tsx`: `Download` per-row button
(with
per-row spinner) and an `Export all` header button (disabled when empty
or
loading).
- `AgentSettingsPersonalSkillsPage.tsx`: container handlers that fetch
content via `queryClient.fetchQuery(userSkill(name))` and trigger the
download/zip, with `toast` error handling. Download logic is extracted
to
module-level helpers to stay React Compiler friendly.
- `AgentSettingsPersonalSkillsPageView.stories.tsx`: interaction stories
asserting `onDownload`/`onExportAll` fire, plus loading-state stories.
## Testing
- `pnpm check` (biome), `pnpm lint:types` (tsc), React Compiler check,
and
Storybook interaction tests (22 passed) all pass locally.
- `make pre-commit` passed.
Closes
[CODAGT-918](https://linear.app/codercom/issue/CODAGT-918/add-ability-to-download-and-export-skills-from-coder-agents).
<details>
<summary>Implementation plan</summary>
### 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.md` content by hand.
### Decisions (confirmed with requester)
1. Surface: download in the settings UI (Personal skills page).
2. Build both single-skill download and export-all (zip).
3. Personal skills only (workspace/filesystem skills out of scope).
### 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.
- Per-row Download button, placed before Edit in the actions cell; shows
a
spinner while its own row is downloading.
- Export all button in the section header, disabled when there are no
skills
or while loading.
- Container: single download fetches content and `saveAs(<name>.md)`;
export
all fetches every skill, adds each as `<name>/SKILL.md` to a `JSZip`,
generates a blob, and `saveAs(personal-skills.zip)`. Failures surface
via
`toast.error`.
- Stories cover the interactions and loading states (stories are the FE
test
surface).
### Out of scope
- Workspace skills download (filesystem source): different data path,
read-only in chat, not user-owned data.
- In-chat download button on the `read_skill` tool output: possible
follow-up, different surface and interaction model.
</details>
---
_Opened by Coder Agents on behalf of @Shelnutt2._