Files
coder/site
Seth Shelnutt 6765731ea9 feat(site/src/pages/AgentsPage): add download and export for personal skills (#28032)
## 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._
2026-08-12 09:20:30 -04:00
..
…
…
…
…